Index: third_party/yasm/patched-yasm/modules/objfmts/elf/elf-x86-amd64.c |
=================================================================== |
--- third_party/yasm/patched-yasm/modules/objfmts/elf/elf-x86-amd64.c (revision 71129) |
+++ third_party/yasm/patched-yasm/modules/objfmts/elf/elf-x86-amd64.c (working copy) |
@@ -26,7 +26,7 @@ |
*/ |
#include <util.h> |
-/*@unused@*/ RCSID("$Id: elf-x86-amd64.c 2126 2008-10-03 08:13:00Z peter $"); |
+/*@unused@*/ RCSID("$Id: elf-x86-amd64.c 2210 2009-07-22 05:51:35Z peter $"); |
#include <libyasm.h> |
#define YASM_OBJFMT_ELF_INTERNAL |
@@ -34,7 +34,10 @@ |
#include "elf-machine.h" |
static elf_machine_ssym elf_x86_amd64_ssyms[] = { |
+ {"pltoff", ELF_SSYM_SYM_RELATIVE, R_X86_64_PLTOFF64, 64}, |
{"plt", ELF_SSYM_SYM_RELATIVE, R_X86_64_PLT32, 32}, |
+ {"gotplt", ELF_SSYM_SYM_RELATIVE, R_X86_64_GOTPLT64, 64}, |
+ {"gotoff", ELF_SSYM_SYM_RELATIVE, R_X86_64_GOTOFF64, 64}, |
{"gotpcrel", ELF_SSYM_SYM_RELATIVE, R_X86_64_GOTPCREL, 32}, |
{"tlsgd", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL, |
R_X86_64_TLSGD, 32}, |
@@ -46,19 +49,22 @@ |
R_X86_64_TPOFF32, 32}, |
{"dtpoff", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL, |
R_X86_64_DTPOFF32, 32}, |
- {"got", ELF_SSYM_SYM_RELATIVE, R_X86_64_GOT32, 32} |
+ {"got", ELF_SSYM_SYM_RELATIVE, R_X86_64_GOT32, 32}, |
+ {"tlsdesc", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL, |
+ R_X86_64_GOTPC32_TLSDESC, 32}, |
+ {"tlscall", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL, |
+ R_X86_64_TLSDESC_CALL, 32} |
}; |
static int |
-elf_x86_amd64_accepts_reloc(size_t val, yasm_symrec *wrt, yasm_symrec **ssyms) |
+elf_x86_amd64_accepts_reloc(size_t val, yasm_symrec *wrt) |
{ |
if (wrt) { |
- size_t i; |
- for (i=0; i<NELEMS(elf_x86_amd64_ssyms); i++) { |
- if (wrt == ssyms[i] && val == elf_x86_amd64_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|64)) != 0); |
} |
@@ -131,7 +137,9 @@ |
} |
static void |
-elf_x86_amd64_handle_reloc_addend(yasm_intnum *intn, elf_reloc_entry *reloc) |
+elf_x86_amd64_handle_reloc_addend(yasm_intnum *intn, |
+ elf_reloc_entry *reloc, |
+ unsigned long offset) |
{ |
/* .rela: copy value out as addend, replace original with 0 */ |
reloc->addend = yasm_intnum_copy(intn); |
@@ -139,36 +147,36 @@ |
} |
static unsigned int |
-elf_x86_amd64_map_reloc_info_to_type(elf_reloc_entry *reloc, |
- yasm_symrec **ssyms) |
+elf_x86_amd64_map_reloc_info_to_type(elf_reloc_entry *reloc) |
{ |
if (reloc->wrt) { |
- size_t i; |
- for (i=0; i<NELEMS(elf_x86_amd64_ssyms); i++) { |
- if (reloc->wrt == ssyms[i] && |
- reloc->valsize == elf_x86_amd64_ssyms[i].size) { |
- /* Force TLS type; this is required by the linker. */ |
- if (elf_x86_amd64_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; |
- } |
- /* Map PC-relative GOT to appropriate relocation */ |
- if (reloc->rtype_rel && |
- elf_x86_amd64_ssyms[i].reloc == R_X86_64_GOT32) |
- return (unsigned char) R_X86_64_GOTPCREL; |
- return (unsigned char) elf_x86_amd64_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")); |
+ /* Map PC-relative GOT to appropriate relocation */ |
+ if (reloc->rtype_rel && ssym->reloc == R_X86_64_GOT32) |
+ return (unsigned char) R_X86_64_GOTPCREL; |
+ return (unsigned char) ssym->reloc; |
+ } else if (reloc->is_GOT_sym && reloc->valsize == 32) { |
+ return (unsigned char) R_X86_64_GOTPC32; |
+ } else if (reloc->is_GOT_sym && reloc->valsize == 64) { |
+ return (unsigned char) R_X86_64_GOTPC64; |
} else if (reloc->rtype_rel) { |
switch (reloc->valsize) { |
case 8: return (unsigned char) R_X86_64_PC8; |
case 16: return (unsigned char) R_X86_64_PC16; |
case 32: return (unsigned char) R_X86_64_PC32; |
+ case 64: return (unsigned char) R_X86_64_PC64; |
default: yasm_internal_error(N_("Unsupported relocation size")); |
} |
} else { |