summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Crayne <chuck@thor.crayne.org>2008-10-12 14:00:11 -0700
committerCharles Crayne <chuck@thor.crayne.org>2008-10-12 14:00:11 -0700
commitcff8dc6d6b089bcfc3daefc33762b92c5a38af19 (patch)
treea6fc56d5322cda2ea8876baa2a18dedae81075bb
parent507ae03bd1541bf62850da0e624827da4ae6ed44 (diff)
downloadnasm-cff8dc6d6b089bcfc3daefc33762b92c5a38af19.tar.gz
RIP rel relocations for PIC released for testing.
Expressions like mov r15,[rel integer wrt ..got] lea rax,[rel integer wrt ..gotoff] now assemble correctly. In addition, a fix has been made to the corresponding abs relocations. Both of these areas still need additional testing.
-rw-r--r--output/outelf64.c57
1 files changed, 45 insertions, 12 deletions
diff --git a/output/outelf64.c b/output/outelf64.c
index f483393c..1ff136df 100644
--- a/output/outelf64.c
+++ b/output/outelf64.c
@@ -32,15 +32,46 @@
#define SHN_ABS 0xfff1 /* Associated symbol is absolute */
#define SHN_COMMON 0xfff2 /* Associated symbol is common */
#define R_X86_64_NONE 0 /* No reloc */
-#define R_X86_64_64 1 /* Direct 64 bit address */
+#define R_X86_64_64 1 /* Direct 64 bit */
#define R_X86_64_PC32 2 /* PC relative 32 bit signed */
#define R_X86_64_GOT32 3 /* 32 bit GOT entry */
#define R_X86_64_PLT32 4 /* 32 bit PLT address */
-#define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative */
+#define R_X86_64_COPY 5 /* Copy symbol at runtime */
+#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */
+#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */
+#define R_X86_64_RELATIVE 8 /* Adjust by program base */
+#define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative
+ offset to GOT */
#define R_X86_64_32 10 /* Direct 32 bit zero extended */
+#define R_X86_64_32S 11 /* Direct 32 bit sign extended */
#define R_X86_64_16 12 /* Direct 16 bit zero extended */
#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */
-#define R_X86_64_GOTTPOFF 22 /* 32 bit signed PC relative offset */
+#define R_X86_64_8 14 /* Direct 8 bit sign extended */
+#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */
+#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */
+#define R_X86_64_DTPOFF64 17 /* Offset in module's TLS block */
+#define R_X86_64_TPOFF64 18 /* Offset in initial TLS block */
+#define R_X86_64_TLSGD 19 /* 32 bit signed PC relative offset
+ to two GOT entries for GD symbol */
+#define R_X86_64_TLSLD 20 /* 32 bit signed PC relative offset
+ to two GOT entries for LD symbol */
+#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */
+#define R_X86_64_GOTTPOFF 22 /* 32 bit signed PC relative offset
+ to GOT entry for IE symbol */
+#define R_X86_64_TPOFF32 23 /* Offset in initial TLS block */
+#define R_X86_64_PC64 24 /* word64 S + A - P */
+#define R_X86_64_GOTOFF64 25 /* word64 S + A - GOT */
+#define R_X86_64_GOTPC32 26 /* word32 GOT + A - P */
+#define R_X86_64_GOT64 27 /* word64 G + A */
+#define R_X86_64_GOTPCREL64 28 /* word64 G + GOT - P + A */
+#define R_X86_64_GOTPC64 29 /* word64 GOT - P + A */
+#define R_X86_64_GOTPLT64 30 /* word64 G + A */
+#define R_X86_64_PLTOFF64 31 /* word64 L - GOT + A */
+#define R_X86_64_SIZE32 32 /* word32 Z + A */
+#define R_X86_64_SIZE64 33 /* word64 Z + A */
+#define R_X86_64_GOTPC32_TLSDESC 34 /* word32 */
+#define R_X86_64_TLSDESC_CALL 35 /* none */
+#define R_X86_64_TLSDESC 36 /* word64×2 */
#define ET_REL 1 /* Relocatable file */
#define EM_X86_64 62 /* AMD x86-64 architecture */
#define STT_NOTYPE 0 /* Symbol type is unspecified */
@@ -958,10 +989,11 @@ static void elf_out(int32_t segto, const void *data,
* need to fix up the data item by $-$$.
*/
addr += s->len;
- elf_add_reloc(s, segment, R_X86_64_GOTPCREL);
+ elf_add_reloc(s, segment, R_X86_64_GOTPC32);
} else if (wrt == elf_gotoff_sect + 1) {
- elf_add_reloc(s, segment, R_X86_64_GOTTPOFF);
+ elf_add_reloc(s, segment, R_X86_64_GOTOFF64);
} else if (wrt == elf_got_sect + 1) {
+ s->len,segment, addr);
addr = elf_add_gsym_reloc(s, segment, addr,
R_X86_64_GOT32, true);
} else if (wrt == elf_sym_sect + 1) {
@@ -1026,20 +1058,21 @@ static void elf_out(int32_t segto, const void *data,
if (segment == segto)
error(ERR_PANIC, "intra-segment OUT_REL4ADR");
if (segment != NO_SEG && segment % 2) {
- error(ERR_NONFATAL, "ELF format does not support"
+ error(ERR_NONFATAL, "ELF64 format does not support"
" segment base references");
} else {
if (wrt == NO_SEG) {
elf_add_reloc(s, segment, R_X86_64_PC32);
} else if (wrt == elf_plt_sect + 1) {
elf_add_reloc(s, segment, R_X86_64_PLT32);
- } else if (wrt == elf_gotpc_sect + 1 ||
- wrt == elf_gotoff_sect + 1 ||
- wrt == elf_got_sect + 1) {
- error(ERR_NONFATAL, "ELF format cannot produce PC-"
- "relative GOT references");
+ } else if (wrt == elf_gotpc_sect + 1) {
+ elf_add_reloc(s, segment, R_X86_64_GOTPCREL);
+ } else if (wrt == elf_gotoff_sect + 1) {
+ elf_add_reloc(s, segment, R_X86_64_GOTOFF64);
+ } else if (wrt == elf_got_sect + 1) {
+ elf_add_reloc(s, segment, R_X86_64_GOTPCREL);
} else {
- error(ERR_NONFATAL, "ELF format does not support this"
+ error(ERR_NONFATAL, "ELF64 format does not support this"
" use of WRT");
wrt = NO_SEG; /* we can at least _try_ to continue */
}