| Index: third_party/yasm/patched-yasm/modules/objfmts/elf/elf-x86-x86.c
|
| ===================================================================
|
| --- third_party/yasm/patched-yasm/modules/objfmts/elf/elf-x86-x86.c (revision 71129)
|
| +++ third_party/yasm/patched-yasm/modules/objfmts/elf/elf-x86-x86.c (working copy)
|
| @@ -26,7 +26,7 @@
|
| */
|
|
|
| #include <util.h>
|
| -/*@unused@*/ RCSID("$Id: elf-x86-x86.c 2040 2008-02-21 08:57:23Z peter $");
|
| +/*@unused@*/ RCSID("$Id: elf-x86-x86.c 2321 2010-05-15 07:45:48Z peter $");
|
|
|
| #include <libyasm.h>
|
| #define YASM_OBJFMT_ELF_INTERNAL
|
| @@ -54,19 +54,22 @@
|
| R_386_TLS_GOTIE, 32},
|
| {"indntpoff", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL,
|
| R_386_TLS_IE, 32},
|
| - {"got", ELF_SSYM_SYM_RELATIVE, R_386_GOT32, 32}
|
| + {"got", ELF_SSYM_SYM_RELATIVE, R_386_GOT32, 32},
|
| + {"tlsdesc", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL,
|
| + R_386_TLS_GOTDESC, 32},
|
| + {"tlscall", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL,
|
| + R_386_TLS_DESC_CALL, 32}
|
| };
|
|
|
| static int
|
| -elf_x86_x86_accepts_reloc(size_t val, yasm_symrec *wrt, yasm_symrec **ssyms)
|
| +elf_x86_x86_accepts_reloc(size_t val, yasm_symrec *wrt)
|
| {
|
| if (wrt) {
|
| - size_t i;
|
| - for (i=0; i<NELEMS(elf_x86_x86_ssyms); i++) {
|
| - if (wrt == ssyms[i] && val == elf_x86_x86_ssyms[i].size)
|
| - return 1;
|
| - }
|
| - return 0;
|
| + const elf_machine_ssym *ssym = (elf_machine_ssym *)
|
| + yasm_symrec_get_data(wrt, &elf_ssym_symrec_data);
|
| + if (!ssym || val != ssym->size)
|
| + return 0;
|
| + return 1;
|
| }
|
| return (val&(val-1)) ? 0 : ((val & (8|16|32)) != 0);
|
| }
|
| @@ -133,33 +136,39 @@
|
| }
|
|
|
| static void
|
| -elf_x86_x86_handle_reloc_addend(yasm_intnum *intn, elf_reloc_entry *reloc)
|
| +elf_x86_x86_handle_reloc_addend(yasm_intnum *intn,
|
| + elf_reloc_entry *reloc,
|
| + unsigned long offset)
|
| {
|
| + if (!reloc->wrt && reloc->is_GOT_sym && reloc->valsize == 32 && offset != 0)
|
| + {
|
| + yasm_intnum *off_intn = yasm_intnum_create_uint(offset);
|
| + yasm_intnum_calc(intn, YASM_EXPR_ADD, off_intn);
|
| + yasm_intnum_destroy(off_intn);
|
| + }
|
| return; /* .rel: Leave addend in intn */
|
| }
|
|
|
| static unsigned int
|
| -elf_x86_x86_map_reloc_info_to_type(elf_reloc_entry *reloc,
|
| - yasm_symrec **ssyms)
|
| +elf_x86_x86_map_reloc_info_to_type(elf_reloc_entry *reloc)
|
| {
|
| if (reloc->wrt) {
|
| - size_t i;
|
| - for (i=0; i<NELEMS(elf_x86_x86_ssyms); i++) {
|
| - if (reloc->wrt == ssyms[i] &&
|
| - reloc->valsize == elf_x86_x86_ssyms[i].size) {
|
| - /* Force TLS type; this is required by the linker. */
|
| - if (elf_x86_x86_ssyms[i].sym_rel & ELF_SSYM_THREAD_LOCAL) {
|
| - elf_symtab_entry *esym;
|
| + const elf_machine_ssym *ssym = (elf_machine_ssym *)
|
| + yasm_symrec_get_data(reloc->wrt, &elf_ssym_symrec_data);
|
| + if (!ssym || reloc->valsize != ssym->size)
|
| + yasm_internal_error(N_("Unsupported WRT"));
|
|
|
| - esym = yasm_symrec_get_data(reloc->reloc.sym,
|
| - &elf_symrec_data);
|
| - if (esym)
|
| - esym->type = STT_TLS;
|
| - }
|
| - return (unsigned char) elf_x86_x86_ssyms[i].reloc;
|
| - }
|
| + /* Force TLS type; this is required by the linker. */
|
| + if (ssym->sym_rel & ELF_SSYM_THREAD_LOCAL) {
|
| + elf_symtab_entry *esym;
|
| +
|
| + esym = yasm_symrec_get_data(reloc->reloc.sym, &elf_symrec_data);
|
| + if (esym)
|
| + esym->type = STT_TLS;
|
| }
|
| - yasm_internal_error(N_("Unsupported WRT"));
|
| + return (unsigned char) ssym->reloc;
|
| + } else if (reloc->is_GOT_sym && reloc->valsize == 32) {
|
| + return (unsigned char) R_386_GOTPC;
|
| } else if (reloc->rtype_rel) {
|
| switch (reloc->valsize) {
|
| case 8: return (unsigned char) R_386_PC8;
|
|
|