From: Peter Johnson Date: Sat, 9 Feb 2008 04:06:47 +0000 (-0000) Subject: Add support for ELF32 and ELF64 TLS (thread local storage) relocations. X-Git-Tag: v0.7.0~21 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a3e30bc39f4f84156622dee7314ea264468b60ca;p=yasm Add support for ELF32 and ELF64 TLS (thread local storage) relocations. While here, simplify how special relocations are handled inside ELF. Requested by: Nils Weller svn path=/trunk/yasm/; revision=2036 --- diff --git a/modules/objfmts/elf/elf-machine.h b/modules/objfmts/elf/elf-machine.h index f2bb8db7..46cce2db 100644 --- a/modules/objfmts/elf/elf-machine.h +++ b/modules/objfmts/elf/elf-machine.h @@ -77,6 +77,8 @@ enum { typedef struct { const char *name; /* should be something like ..name */ const int sym_rel; /* symbol or section-relative? */ + const unsigned int reloc; /* relocation type */ + const unsigned int size; /* legal data size */ } elf_machine_ssym; struct elf_machine_handler { diff --git a/modules/objfmts/elf/elf-x86-amd64.c b/modules/objfmts/elf/elf-x86-amd64.c index 4bc53b21..d9588284 100644 --- a/modules/objfmts/elf/elf-x86-amd64.c +++ b/modules/objfmts/elf/elf-x86-amd64.c @@ -33,22 +33,27 @@ #include "elf.h" #include "elf-machine.h" -enum ssym_index { - SSYM_GOTPCREL = 0, - SSYM_GOT, - SSYM_PLT +static elf_machine_ssym elf_x86_amd64_ssyms[] = { + {"plt", ELF_SSYM_SYM_RELATIVE, R_X86_64_PLT32, 32}, + {"gotpcrel", ELF_SSYM_SYM_RELATIVE, R_X86_64_GOTPCREL, 32}, + {"tlsgd", ELF_SSYM_SYM_RELATIVE, R_X86_64_TLSGD, 32}, + {"tlsld", ELF_SSYM_SYM_RELATIVE, R_X86_64_TLSLD, 32}, + {"gottpoff", ELF_SSYM_SYM_RELATIVE, R_X86_64_GOTTPOFF, 32}, + {"tpoff", ELF_SSYM_SYM_RELATIVE, R_X86_64_TPOFF32, 32}, + {"dtpoff", ELF_SSYM_SYM_RELATIVE, R_X86_64_DTPOFF32, 32}, + {"got", ELF_SSYM_SYM_RELATIVE, R_X86_64_GOT32, 32} }; static int elf_x86_amd64_accepts_reloc(size_t val, yasm_symrec *wrt, yasm_symrec **ssyms) { if (wrt) { - if ((wrt == ssyms[SSYM_GOTPCREL] && val == 32) - || (wrt == ssyms[SSYM_GOT] && val == 32) - || (wrt == ssyms[SSYM_PLT] && val == 32)) - return 1; - else - return 0; + size_t i; + for (i=0; iwrt) { - if (reloc->wrt == ssyms[SSYM_GOTPCREL] && reloc->valsize == 32) - return (unsigned char) R_X86_64_GOTPCREL; - else if (reloc->wrt == ssyms[SSYM_GOT] && reloc->valsize == 32) - return (unsigned char) R_X86_64_GOT32; - else if (reloc->wrt == ssyms[SSYM_PLT] && reloc->valsize == 32) - return (unsigned char) R_X86_64_PLT32; - else - yasm_internal_error(N_("Unsupported WRT")); + size_t i; + for (i=0; iwrt == ssyms[i] && + reloc->valsize == elf_x86_amd64_ssyms[i].size) + return (unsigned char) elf_x86_amd64_ssyms[i].reloc; + } + yasm_internal_error(N_("Unsupported WRT")); } else if (reloc->rtype_rel) { switch (reloc->valsize) { case 8: return (unsigned char) R_X86_64_PC8; @@ -208,12 +212,6 @@ elf_x86_amd64_write_proghead(unsigned char **bufpp, *bufpp = bufp; } -static elf_machine_ssym elf_x86_amd64_ssyms[] = { - {"..gotpcrel", ELF_SSYM_SYM_RELATIVE}, - {"..got", ELF_SSYM_SYM_RELATIVE}, - {"..plt", 0} -}; - const elf_machine_handler elf_machine_handler_x86_amd64 = { "x86", "amd64", ".rela", diff --git a/modules/objfmts/elf/elf-x86-x86.c b/modules/objfmts/elf/elf-x86-x86.c index 67a23d0a..2a1ba14f 100644 --- a/modules/objfmts/elf/elf-x86-x86.c +++ b/modules/objfmts/elf/elf-x86-x86.c @@ -33,24 +33,32 @@ #include "elf.h" #include "elf-machine.h" -enum ssym_index { - SSYM_GOTPC = 0, - SSYM_GOTOFF, - SSYM_GOT, - SSYM_PLT +static const elf_machine_ssym elf_x86_x86_ssyms[] = { + {"plt", ELF_SSYM_SYM_RELATIVE, R_386_PLT32, 32}, + {"gotoff", 0, R_386_GOTOFF, 32}, + /* special one for NASM */ + {"gotpc", ELF_SSYM_CURPOS_ADJUST, R_386_GOTPC, 32}, + {"tlsgd", ELF_SSYM_SYM_RELATIVE, R_386_TLS_GD, 32}, + {"tlsldm", ELF_SSYM_SYM_RELATIVE, R_386_TLS_LDM, 32}, + {"gottpoff", ELF_SSYM_SYM_RELATIVE, R_386_TLS_IE_32, 32}, + {"tpoff", ELF_SSYM_SYM_RELATIVE, R_386_TLS_LE_32, 32}, + {"ntpoff", ELF_SSYM_SYM_RELATIVE, R_386_TLS_LE, 32}, + {"dtpoff", ELF_SSYM_SYM_RELATIVE, R_386_TLS_LDO_32, 32}, + {"gotntpoff", ELF_SSYM_SYM_RELATIVE, R_386_TLS_GOTIE, 32}, + {"indntpoff", ELF_SSYM_SYM_RELATIVE, R_386_TLS_IE, 32}, + {"got", ELF_SSYM_SYM_RELATIVE, R_386_GOT32, 32} }; static int elf_x86_x86_accepts_reloc(size_t val, yasm_symrec *wrt, yasm_symrec **ssyms) { if (wrt) { - if ((wrt == ssyms[SSYM_GOTPC] && val == 32) - || (wrt == ssyms[SSYM_GOTOFF] && val == 32) - || (wrt == ssyms[SSYM_GOT] && val == 32) - || (wrt == ssyms[SSYM_PLT] && val == 32)) - return 1; - else - return 0; + size_t i; + for (i=0; iwrt) { - if (reloc->wrt == ssyms[SSYM_GOTPC] && reloc->valsize == 32) - return (unsigned char) R_386_GOTPC; - else if (reloc->wrt == ssyms[SSYM_GOTOFF] && reloc->valsize == 32) - return (unsigned char) R_386_GOTOFF; - else if (reloc->wrt == ssyms[SSYM_GOT] && reloc->valsize == 32) - return (unsigned char) R_386_GOT32; - else if (reloc->wrt == ssyms[SSYM_PLT] && reloc->valsize == 32) - return (unsigned char) R_386_PLT32; - else - yasm_internal_error(N_("Unsupported WRT")); + size_t i; + for (i=0; iwrt == ssyms[i] && + reloc->valsize == elf_x86_x86_ssyms[i].size) + return (unsigned char) elf_x86_x86_ssyms[i].reloc; + } + yasm_internal_error(N_("Unsupported WRT")); } else if (reloc->rtype_rel) { switch (reloc->valsize) { case 8: return (unsigned char) R_386_PC8; @@ -193,13 +198,6 @@ elf_x86_x86_write_proghead(unsigned char **bufpp, *bufpp = bufp; } -static elf_machine_ssym elf_x86_x86_ssyms[] = { - {"..gotpc", ELF_SSYM_CURPOS_ADJUST}, - {"..gotoff", 0}, - {"..got", ELF_SSYM_SYM_RELATIVE}, - {"..plt", 0} -}; - const elf_machine_handler elf_machine_handler_x86_x86 = { "x86", "x86", ".rel", diff --git a/modules/objfmts/elf/tests/Makefile.inc b/modules/objfmts/elf/tests/Makefile.inc index bf112037..6ed13e72 100644 --- a/modules/objfmts/elf/tests/Makefile.inc +++ b/modules/objfmts/elf/tests/Makefile.inc @@ -49,7 +49,9 @@ EXTRA_DIST += modules/objfmts/elf/tests/nasm-forceident.asm EXTRA_DIST += modules/objfmts/elf/tests/nasm-forceident.hex EXTRA_DIST += modules/objfmts/elf/tests/amd64/Makefile.inc +EXTRA_DIST += modules/objfmts/elf/tests/gas32/Makefile.inc EXTRA_DIST += modules/objfmts/elf/tests/gas64/Makefile.inc include modules/objfmts/elf/tests/amd64/Makefile.inc +include modules/objfmts/elf/tests/gas32/Makefile.inc include modules/objfmts/elf/tests/gas64/Makefile.inc diff --git a/modules/objfmts/elf/tests/gas32/Makefile.inc b/modules/objfmts/elf/tests/gas32/Makefile.inc new file mode 100644 index 00000000..f9e7d114 --- /dev/null +++ b/modules/objfmts/elf/tests/gas32/Makefile.inc @@ -0,0 +1,7 @@ +# $Id$ + +TESTS += modules/objfmts/elf/tests/gas32/elf_gas32_test.sh + +EXTRA_DIST += modules/objfmts/elf/tests/gas32/elf_gas32_test.sh +EXTRA_DIST += modules/objfmts/elf/tests/gas32/elf_gas32_ssym.asm +EXTRA_DIST += modules/objfmts/elf/tests/gas32/elf_gas32_ssym.hex diff --git a/modules/objfmts/elf/tests/gas32/elf_gas32_ssym.asm b/modules/objfmts/elf/tests/gas32/elf_gas32_ssym.asm new file mode 100644 index 00000000..9bd042d0 --- /dev/null +++ b/modules/objfmts/elf/tests/gas32/elf_gas32_ssym.asm @@ -0,0 +1,14 @@ +.text +foo: +movl %eax, foo@PLT +movl %eax, foo@GOTOFF +#movl %eax, foo@GOTPC +movl %eax, bar@TLSGD +movl %eax, bar@TLSLDM +movl %eax, bar@GOTTPOFF +movl %eax, bar@TPOFF +movl %eax, bar@NTPOFF +movl %eax, bar@DTPOFF +movl %eax, bar@GOTNTPOFF +movl %eax, bar@INDNTPOFF +movl %eax, foo@GOT diff --git a/modules/objfmts/elf/tests/gas32/elf_gas32_ssym.hex b/modules/objfmts/elf/tests/gas32/elf_gas32_ssym.hex new file mode 100644 index 00000000..a6fcecc4 --- /dev/null +++ b/modules/objfmts/elf/tests/gas32/elf_gas32_ssym.hex @@ -0,0 +1,592 @@ +7f +45 +4c +46 +01 +01 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +01 +00 +03 +00 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +60 +01 +00 +00 +00 +00 +00 +00 +34 +00 +00 +00 +00 +00 +28 +00 +06 +00 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +a3 +00 +00 +00 +00 +a3 +00 +00 +00 +00 +a3 +00 +00 +00 +00 +a3 +00 +00 +00 +00 +a3 +00 +00 +00 +00 +a3 +00 +00 +00 +00 +a3 +00 +00 +00 +00 +a3 +00 +00 +00 +00 +a3 +00 +00 +00 +00 +a3 +00 +00 +00 +00 +a3 +00 +00 +00 +00 +00 +01 +00 +00 +00 +04 +02 +00 +00 +06 +00 +00 +00 +09 +03 +00 +00 +0b +00 +00 +00 +12 +04 +00 +00 +10 +00 +00 +00 +13 +04 +00 +00 +15 +00 +00 +00 +21 +04 +00 +00 +1a +00 +00 +00 +22 +04 +00 +00 +1f +00 +00 +00 +11 +04 +00 +00 +24 +00 +00 +00 +20 +04 +00 +00 +29 +00 +00 +00 +10 +04 +00 +00 +2e +00 +00 +00 +0f +04 +00 +00 +33 +00 +00 +00 +03 +02 +00 +00 +00 +2e +74 +65 +78 +74 +00 +2e +72 +65 +6c +2e +74 +65 +78 +74 +00 +2e +73 +74 +72 +74 +61 +62 +00 +2e +73 +79 +6d +74 +61 +62 +00 +2e +73 +68 +73 +74 +72 +74 +61 +62 +00 +00 +00 +2d +00 +62 +61 +72 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +04 +00 +f1 +ff +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +04 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +03 +00 +04 +00 +03 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +10 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +21 +00 +00 +00 +03 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +d0 +00 +00 +00 +2b +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +11 +00 +00 +00 +03 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +fc +00 +00 +00 +07 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +19 +00 +00 +00 +02 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +04 +01 +00 +00 +50 +00 +00 +00 +02 +00 +00 +00 +04 +00 +00 +00 +04 +00 +00 +00 +10 +00 +00 +00 +01 +00 +00 +00 +01 +00 +00 +00 +06 +00 +00 +00 +00 +00 +00 +00 +40 +00 +00 +00 +37 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +10 +00 +00 +00 +00 +00 +00 +00 +07 +00 +00 +00 +09 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +78 +00 +00 +00 +58 +00 +00 +00 +03 +00 +00 +00 +04 +00 +00 +00 +04 +00 +00 +00 +08 +00 +00 +00 diff --git a/modules/objfmts/elf/tests/gas32/elf_gas32_test.sh b/modules/objfmts/elf/tests/gas32/elf_gas32_test.sh new file mode 100755 index 00000000..ca0df39a --- /dev/null +++ b/modules/objfmts/elf/tests/gas32/elf_gas32_test.sh @@ -0,0 +1,4 @@ +#! /bin/sh +# $Id$ +${srcdir}/out_test.sh elf_gas32_test modules/objfmts/elf/tests/gas32 "GAS elf-x86 objfmt" "-f elf32 -p gas" ".o" +exit $? diff --git a/modules/objfmts/elf/tests/gas64/Makefile.inc b/modules/objfmts/elf/tests/gas64/Makefile.inc index 9be81625..8cedf046 100644 --- a/modules/objfmts/elf/tests/gas64/Makefile.inc +++ b/modules/objfmts/elf/tests/gas64/Makefile.inc @@ -9,3 +9,5 @@ EXTRA_DIST += modules/objfmts/elf/tests/gas64/elf_gas64_curpos.asm EXTRA_DIST += modules/objfmts/elf/tests/gas64/elf_gas64_curpos.hex EXTRA_DIST += modules/objfmts/elf/tests/gas64/elf_gas64_reloc.asm EXTRA_DIST += modules/objfmts/elf/tests/gas64/elf_gas64_reloc.hex +EXTRA_DIST += modules/objfmts/elf/tests/gas64/elf_gas64_ssym.asm +EXTRA_DIST += modules/objfmts/elf/tests/gas64/elf_gas64_ssym.hex diff --git a/modules/objfmts/elf/tests/gas64/elf_gas64_ssym.asm b/modules/objfmts/elf/tests/gas64/elf_gas64_ssym.asm new file mode 100644 index 00000000..b7203f62 --- /dev/null +++ b/modules/objfmts/elf/tests/gas64/elf_gas64_ssym.asm @@ -0,0 +1,10 @@ +.text +foo: +movl %eax, foo@PLT +movl %eax, foo@GOTPCREL +movl %eax, bar@TLSGD +movl %eax, bar@TLSLD +movl %eax, bar@GOTTPOFF +movl %eax, bar@TPOFF +movl %eax, bar@DTPOFF +movl %eax, foo@GOT diff --git a/modules/objfmts/elf/tests/gas64/elf_gas64_ssym.hex b/modules/objfmts/elf/tests/gas64/elf_gas64_ssym.hex new file mode 100644 index 00000000..698890fa --- /dev/null +++ b/modules/objfmts/elf/tests/gas64/elf_gas64_ssym.hex @@ -0,0 +1,880 @@ +7f +45 +4c +46 +02 +01 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +01 +00 +3e +00 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +f0 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +40 +00 +00 +00 +00 +00 +40 +00 +06 +00 +01 +00 +89 +04 +25 +00 +00 +00 +00 +89 +04 +25 +00 +00 +00 +00 +89 +04 +25 +00 +00 +00 +00 +89 +04 +25 +00 +00 +00 +00 +89 +04 +25 +00 +00 +00 +00 +89 +04 +25 +00 +00 +00 +00 +89 +04 +25 +00 +00 +00 +00 +89 +04 +25 +00 +00 +00 +00 +03 +00 +00 +00 +00 +00 +00 +00 +04 +00 +00 +00 +02 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +0a +00 +00 +00 +00 +00 +00 +00 +09 +00 +00 +00 +02 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +11 +00 +00 +00 +00 +00 +00 +00 +13 +00 +00 +00 +04 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +18 +00 +00 +00 +00 +00 +00 +00 +14 +00 +00 +00 +04 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +1f +00 +00 +00 +00 +00 +00 +00 +16 +00 +00 +00 +04 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +26 +00 +00 +00 +00 +00 +00 +00 +17 +00 +00 +00 +04 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +2d +00 +00 +00 +00 +00 +00 +00 +15 +00 +00 +00 +04 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +34 +00 +00 +00 +00 +00 +00 +00 +03 +00 +00 +00 +02 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +2e +74 +65 +78 +74 +00 +2e +72 +65 +6c +61 +2e +74 +65 +78 +74 +00 +2e +73 +74 +72 +74 +61 +62 +00 +2e +73 +79 +6d +74 +61 +62 +00 +2e +73 +68 +73 +74 +72 +74 +61 +62 +00 +00 +2d +00 +62 +61 +72 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +01 +00 +00 +00 +04 +00 +f1 +ff +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +04 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +03 +00 +04 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +03 +00 +00 +00 +10 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +22 +00 +00 +00 +03 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +38 +01 +00 +00 +00 +00 +00 +00 +2c +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +12 +00 +00 +00 +03 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +64 +01 +00 +00 +00 +00 +00 +00 +07 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +1a +00 +00 +00 +02 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +6c +01 +00 +00 +00 +00 +00 +00 +78 +00 +00 +00 +00 +00 +00 +00 +02 +00 +00 +00 +04 +00 +00 +00 +08 +00 +00 +00 +00 +00 +00 +00 +18 +00 +00 +00 +00 +00 +00 +00 +01 +00 +00 +00 +01 +00 +00 +00 +06 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +40 +00 +00 +00 +00 +00 +00 +00 +38 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +10 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +07 +00 +00 +00 +04 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +78 +00 +00 +00 +00 +00 +00 +00 +c0 +00 +00 +00 +00 +00 +00 +00 +03 +00 +00 +00 +04 +00 +00 +00 +08 +00 +00 +00 +00 +00 +00 +00 +18 +00 +00 +00 +00 +00 +00 +00