OLD | NEW |
1 /* | 1 /* |
2 * ELF object format helpers - x86:x86 | 2 * ELF object format helpers - x86:x86 |
3 * | 3 * |
4 * Copyright (C) 2004-2007 Michael Urman | 4 * Copyright (C) 2004-2007 Michael Urman |
5 * | 5 * |
6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
8 * are met: | 8 * are met: |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
11 * 2. Redistributions in binary form must reproduce the above copyright | 11 * 2. Redistributions in binary form must reproduce the above copyright |
12 * notice, this list of conditions and the following disclaimer in the | 12 * notice, this list of conditions and the following disclaimer in the |
13 * documentation and/or other materials provided with the distribution. | 13 * documentation and/or other materials provided with the distribution. |
14 * | 14 * |
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' | 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' |
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE | 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE |
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
25 * POSSIBILITY OF SUCH DAMAGE. | 25 * POSSIBILITY OF SUCH DAMAGE. |
26 */ | 26 */ |
27 | 27 |
28 #include <util.h> | 28 #include <util.h> |
29 /*@unused@*/ RCSID("$Id: elf-x86-x86.c 2040 2008-02-21 08:57:23Z peter $"); | 29 /*@unused@*/ RCSID("$Id: elf-x86-x86.c 2321 2010-05-15 07:45:48Z peter $"); |
30 | 30 |
31 #include <libyasm.h> | 31 #include <libyasm.h> |
32 #define YASM_OBJFMT_ELF_INTERNAL | 32 #define YASM_OBJFMT_ELF_INTERNAL |
33 #include "elf.h" | 33 #include "elf.h" |
34 #include "elf-machine.h" | 34 #include "elf-machine.h" |
35 | 35 |
36 static const elf_machine_ssym elf_x86_x86_ssyms[] = { | 36 static const elf_machine_ssym elf_x86_x86_ssyms[] = { |
37 {"plt", ELF_SSYM_SYM_RELATIVE, R_386_PLT32, 32}, | 37 {"plt", ELF_SSYM_SYM_RELATIVE, R_386_PLT32, 32}, |
38 {"gotoff", 0, R_386_GOTOFF, 32}, | 38 {"gotoff", 0, R_386_GOTOFF, 32}, |
39 /* special one for NASM */ | 39 /* special one for NASM */ |
40 {"gotpc", ELF_SSYM_CURPOS_ADJUST, R_386_GOTPC, 32}, | 40 {"gotpc", ELF_SSYM_CURPOS_ADJUST, R_386_GOTPC, 32}, |
41 {"tlsgd", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL, | 41 {"tlsgd", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL, |
42 R_386_TLS_GD, 32}, | 42 R_386_TLS_GD, 32}, |
43 {"tlsldm", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL, | 43 {"tlsldm", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL, |
44 R_386_TLS_LDM, 32}, | 44 R_386_TLS_LDM, 32}, |
45 {"gottpoff", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL, | 45 {"gottpoff", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL, |
46 R_386_TLS_IE_32, 32}, | 46 R_386_TLS_IE_32, 32}, |
47 {"tpoff", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL, | 47 {"tpoff", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL, |
48 R_386_TLS_LE_32, 32}, | 48 R_386_TLS_LE_32, 32}, |
49 {"ntpoff", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL, | 49 {"ntpoff", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL, |
50 R_386_TLS_LE, 32}, | 50 R_386_TLS_LE, 32}, |
51 {"dtpoff", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL, | 51 {"dtpoff", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL, |
52 R_386_TLS_LDO_32, 32}, | 52 R_386_TLS_LDO_32, 32}, |
53 {"gotntpoff", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL, | 53 {"gotntpoff", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL, |
54 R_386_TLS_GOTIE, 32}, | 54 R_386_TLS_GOTIE, 32}, |
55 {"indntpoff", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL, | 55 {"indntpoff", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL, |
56 R_386_TLS_IE, 32}, | 56 R_386_TLS_IE, 32}, |
57 {"got", ELF_SSYM_SYM_RELATIVE, R_386_GOT32, 32} | 57 {"got", ELF_SSYM_SYM_RELATIVE, R_386_GOT32, 32}, |
| 58 {"tlsdesc", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL, |
| 59 R_386_TLS_GOTDESC, 32}, |
| 60 {"tlscall", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL, |
| 61 R_386_TLS_DESC_CALL, 32} |
58 }; | 62 }; |
59 | 63 |
60 static int | 64 static int |
61 elf_x86_x86_accepts_reloc(size_t val, yasm_symrec *wrt, yasm_symrec **ssyms) | 65 elf_x86_x86_accepts_reloc(size_t val, yasm_symrec *wrt) |
62 { | 66 { |
63 if (wrt) { | 67 if (wrt) { |
64 size_t i; | 68 const elf_machine_ssym *ssym = (elf_machine_ssym *) |
65 for (i=0; i<NELEMS(elf_x86_x86_ssyms); i++) { | 69 yasm_symrec_get_data(wrt, &elf_ssym_symrec_data); |
66 if (wrt == ssyms[i] && val == elf_x86_x86_ssyms[i].size) | 70 if (!ssym || val != ssym->size) |
67 return 1; | 71 return 0; |
68 } | 72 return 1; |
69 return 0; | |
70 } | 73 } |
71 return (val&(val-1)) ? 0 : ((val & (8|16|32)) != 0); | 74 return (val&(val-1)) ? 0 : ((val & (8|16|32)) != 0); |
72 } | 75 } |
73 | 76 |
74 static void | 77 static void |
75 elf_x86_x86_write_symtab_entry(unsigned char *bufp, | 78 elf_x86_x86_write_symtab_entry(unsigned char *bufp, |
76 elf_symtab_entry *entry, | 79 elf_symtab_entry *entry, |
77 yasm_intnum *value_intn, | 80 yasm_intnum *value_intn, |
78 yasm_intnum *size_intn) | 81 yasm_intnum *size_intn) |
79 { | 82 { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 YASM_WRITE_32_L(bufp, shead->rel_offset); | 129 YASM_WRITE_32_L(bufp, shead->rel_offset); |
127 YASM_WRITE_32_L(bufp, RELOC32_SIZE * shead->nreloc);/* size */ | 130 YASM_WRITE_32_L(bufp, RELOC32_SIZE * shead->nreloc);/* size */ |
128 YASM_WRITE_32_L(bufp, symtab_idx); /* link: symtab index */ | 131 YASM_WRITE_32_L(bufp, symtab_idx); /* link: symtab index */ |
129 YASM_WRITE_32_L(bufp, shead->index); /* info: relocated's index */ | 132 YASM_WRITE_32_L(bufp, shead->index); /* info: relocated's index */ |
130 | 133 |
131 YASM_WRITE_32_L(bufp, RELOC32_ALIGN); /* align */ | 134 YASM_WRITE_32_L(bufp, RELOC32_ALIGN); /* align */ |
132 YASM_WRITE_32_L(bufp, RELOC32_SIZE); /* entity size */ | 135 YASM_WRITE_32_L(bufp, RELOC32_SIZE); /* entity size */ |
133 } | 136 } |
134 | 137 |
135 static void | 138 static void |
136 elf_x86_x86_handle_reloc_addend(yasm_intnum *intn, elf_reloc_entry *reloc) | 139 elf_x86_x86_handle_reloc_addend(yasm_intnum *intn, |
| 140 elf_reloc_entry *reloc, |
| 141 unsigned long offset) |
137 { | 142 { |
| 143 if (!reloc->wrt && reloc->is_GOT_sym && reloc->valsize == 32 && offset != 0) |
| 144 { |
| 145 yasm_intnum *off_intn = yasm_intnum_create_uint(offset); |
| 146 yasm_intnum_calc(intn, YASM_EXPR_ADD, off_intn); |
| 147 yasm_intnum_destroy(off_intn); |
| 148 } |
138 return; /* .rel: Leave addend in intn */ | 149 return; /* .rel: Leave addend in intn */ |
139 } | 150 } |
140 | 151 |
141 static unsigned int | 152 static unsigned int |
142 elf_x86_x86_map_reloc_info_to_type(elf_reloc_entry *reloc, | 153 elf_x86_x86_map_reloc_info_to_type(elf_reloc_entry *reloc) |
143 yasm_symrec **ssyms) | |
144 { | 154 { |
145 if (reloc->wrt) { | 155 if (reloc->wrt) { |
146 size_t i; | 156 const elf_machine_ssym *ssym = (elf_machine_ssym *) |
147 for (i=0; i<NELEMS(elf_x86_x86_ssyms); i++) { | 157 yasm_symrec_get_data(reloc->wrt, &elf_ssym_symrec_data); |
148 if (reloc->wrt == ssyms[i] && | 158 if (!ssym || reloc->valsize != ssym->size) |
149 reloc->valsize == elf_x86_x86_ssyms[i].size) { | 159 yasm_internal_error(N_("Unsupported WRT")); |
150 /* Force TLS type; this is required by the linker. */ | |
151 if (elf_x86_x86_ssyms[i].sym_rel & ELF_SSYM_THREAD_LOCAL) { | |
152 elf_symtab_entry *esym; | |
153 | 160 |
154 esym = yasm_symrec_get_data(reloc->reloc.sym, | 161 /* Force TLS type; this is required by the linker. */ |
155 &elf_symrec_data); | 162 if (ssym->sym_rel & ELF_SSYM_THREAD_LOCAL) { |
156 if (esym) | 163 elf_symtab_entry *esym; |
157 esym->type = STT_TLS; | 164 |
158 } | 165 esym = yasm_symrec_get_data(reloc->reloc.sym, &elf_symrec_data); |
159 return (unsigned char) elf_x86_x86_ssyms[i].reloc; | 166 if (esym) |
160 } | 167 esym->type = STT_TLS; |
161 } | 168 } |
162 yasm_internal_error(N_("Unsupported WRT")); | 169 return (unsigned char) ssym->reloc; |
| 170 } else if (reloc->is_GOT_sym && reloc->valsize == 32) { |
| 171 return (unsigned char) R_386_GOTPC; |
163 } else if (reloc->rtype_rel) { | 172 } else if (reloc->rtype_rel) { |
164 switch (reloc->valsize) { | 173 switch (reloc->valsize) { |
165 case 8: return (unsigned char) R_386_PC8; | 174 case 8: return (unsigned char) R_386_PC8; |
166 case 16: return (unsigned char) R_386_PC16; | 175 case 16: return (unsigned char) R_386_PC16; |
167 case 32: return (unsigned char) R_386_PC32; | 176 case 32: return (unsigned char) R_386_PC32; |
168 default: yasm_internal_error(N_("Unsupported relocation size")); | 177 default: yasm_internal_error(N_("Unsupported relocation size")); |
169 } | 178 } |
170 } else { | 179 } else { |
171 switch (reloc->valsize) { | 180 switch (reloc->valsize) { |
172 case 8: return (unsigned char) R_386_8; | 181 case 8: return (unsigned char) R_386_8; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
225 elf_x86_x86_write_secthead, | 234 elf_x86_x86_write_secthead, |
226 elf_x86_x86_write_secthead_rel, | 235 elf_x86_x86_write_secthead_rel, |
227 elf_x86_x86_handle_reloc_addend, | 236 elf_x86_x86_handle_reloc_addend, |
228 elf_x86_x86_map_reloc_info_to_type, | 237 elf_x86_x86_map_reloc_info_to_type, |
229 elf_x86_x86_write_reloc, | 238 elf_x86_x86_write_reloc, |
230 elf_x86_x86_write_proghead, | 239 elf_x86_x86_write_proghead, |
231 elf_x86_x86_ssyms, | 240 elf_x86_x86_ssyms, |
232 sizeof(elf_x86_x86_ssyms)/sizeof(elf_x86_x86_ssyms[0]), | 241 sizeof(elf_x86_x86_ssyms)/sizeof(elf_x86_x86_ssyms[0]), |
233 32 | 242 32 |
234 }; | 243 }; |
OLD | NEW |