| 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 |