From 21da3006b5bdbe002eaa849b1fb3af2bb10d367d Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Sat, 18 Oct 2008 11:29:11 -0700 Subject: [PATCH] ELF64: once again, fix generation of "naked" OUT_REL*ADR It is unclear if we will ever see any "naked" (absolute bytes) OUT_REL*ADR coming from the assembler, but if we do, we should generate them correctly. Signed-off-by: H. Peter Anvin --- output/outelf64.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/output/outelf64.c b/output/outelf64.c index dcb16756..74a8ed5e 100644 --- a/output/outelf64.c +++ b/output/outelf64.c @@ -1067,7 +1067,7 @@ static void elf_out(int32_t segto, const void *data, } elf_sect_writeaddr(s, addr, size); } else if (type == OUT_REL2ADR) { - addr = *(int64_t *)data; + addr = *(int64_t *)data - size; if (segment == segto) error(ERR_PANIC, "intra-segment OUT_REL2ADR"); if (segment == NO_SEG) { @@ -1077,7 +1077,7 @@ static void elf_out(int32_t segto, const void *data, " segment base references"); } else { if (wrt == NO_SEG) { - elf_add_reloc(s, segment, addr-size, R_X86_64_PC16); + elf_add_reloc(s, segment, addr, R_X86_64_PC16); addr = 0; } else { error(ERR_NONFATAL, @@ -1086,7 +1086,7 @@ static void elf_out(int32_t segto, const void *data, } elf_sect_writeaddr(s, addr, 2); } else if (type == OUT_REL4ADR) { - addr = *(int64_t *)data; + addr = *(int64_t *)data - size; if (segment == segto) error(ERR_PANIC, "intra-segment OUT_REL4ADR"); if (segment == NO_SEG) { @@ -1096,16 +1096,15 @@ static void elf_out(int32_t segto, const void *data, " segment base references"); } else { if (wrt == NO_SEG) { - elf_add_reloc(s, segment, addr-size, R_X86_64_PC32); + elf_add_reloc(s, segment, addr, R_X86_64_PC32); addr = 0; } else if (wrt == elf_plt_sect + 1) { - elf_add_gsym_reloc(s, segment, addr, size, + elf_add_gsym_reloc(s, segment, addr+size, size, R_X86_64_PLT32, true); addr = 0; } else if (wrt == elf_gotpc_sect + 1 || wrt == elf_got_sect + 1) { - printf("addr = %ld, pcrel = %ld\n", addr, size); - elf_add_gsym_reloc(s, segment, addr, size, + elf_add_gsym_reloc(s, segment, addr+size, size, R_X86_64_GOTPCREL, true); addr = 0; } else if (wrt == elf_gotoff_sect + 1 || @@ -1119,7 +1118,7 @@ static void elf_out(int32_t segto, const void *data, } elf_sect_writeaddr(s, addr, 4); } else if (type == OUT_REL8ADR) { - addr = *(int64_t *)data; + addr = *(int64_t *)data - size; if (segment == segto) error(ERR_PANIC, "intra-segment OUT_REL8ADR"); if (segment == NO_SEG) { @@ -1129,11 +1128,11 @@ static void elf_out(int32_t segto, const void *data, " segment base references"); } else { if (wrt == NO_SEG) { - elf_add_reloc(s, segment, addr-size, R_X86_64_PC64); + elf_add_reloc(s, segment, addr, R_X86_64_PC64); addr = 0; } else if (wrt == elf_gotpc_sect + 1 || wrt == elf_got_sect + 1) { - elf_add_gsym_reloc(s, segment, addr, size, + elf_add_gsym_reloc(s, segment, addr+size, size, R_X86_64_GOTPCREL64, true); addr = 0; } else if (wrt == elf_gotoff_sect + 1 || -- 2.11.4.GIT