While here, simplify how special relocations are handled inside ELF.
Requested by: Nils Weller <nils@gnulinux.nl>
svn path=/trunk/yasm/; revision=2036
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 {
#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; i<NELEMS(elf_x86_amd64_ssyms); i++) {
+ if (wrt == ssyms[i] && val == elf_x86_amd64_ssyms[i].size)
+ return 1;
+ }
+ return 0;
}
return (val&(val-1)) ? 0 : ((val & (8|16|32|64)) != 0);
}
yasm_symrec **ssyms)
{
if (reloc->wrt) {
- 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; i<NELEMS(elf_x86_amd64_ssyms); i++) {
+ if (reloc->wrt == 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;
*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",
#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; i<NELEMS(elf_x86_x86_ssyms); i++) {
+ if (wrt == ssyms[i] && val == elf_x86_x86_ssyms[i].size)
+ return 1;
+ }
+ return 0;
}
return (val&(val-1)) ? 0 : ((val & (8|16|32)) != 0);
}
yasm_symrec **ssyms)
{
if (reloc->wrt) {
- 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; i<NELEMS(elf_x86_x86_ssyms); i++) {
+ if (reloc->wrt == 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;
*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",
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
--- /dev/null
+# $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
--- /dev/null
+.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
--- /dev/null
+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
--- /dev/null
+#! /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 $?
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
--- /dev/null
+.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
--- /dev/null
+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