From 39913f32de3b9b7afe06cdf560ce42d1cc49be53 Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Sat, 15 Sep 2007 06:40:27 +0000 Subject: [PATCH] Fix #114: Incorrect ELF32 ..gotpc address calculation. Reported by: Loren Merritt Fix by: mu@ We already had a testcase for this, but it had an incorrect "golden" result. svn path=/trunk/yasm/; revision=1952 --- modules/objfmts/elf/elf-machine.h | 5 +++++ modules/objfmts/elf/elf-objfmt.c | 2 ++ modules/objfmts/elf/elf-x86-amd64.c | 4 ++-- modules/objfmts/elf/elf-x86-x86.c | 4 ++-- modules/objfmts/elf/elf.c | 16 +++++++++++++++- modules/objfmts/elf/elf.h | 1 + modules/objfmts/elf/tests/elfso.hex | 8 ++++---- 7 files changed, 31 insertions(+), 9 deletions(-) diff --git a/modules/objfmts/elf/elf-machine.h b/modules/objfmts/elf/elf-machine.h index 562e098c..f2bb8db7 100644 --- a/modules/objfmts/elf/elf-machine.h +++ b/modules/objfmts/elf/elf-machine.h @@ -69,6 +69,11 @@ typedef void (*func_write_proghead)(unsigned char **bufpp, unsigned long secthead_count, elf_section_index shstrtab_index); +enum { + ELF_SSYM_SYM_RELATIVE = 1 << 0, + ELF_SSYM_CURPOS_ADJUST = 1 << 1 +}; + typedef struct { const char *name; /* should be something like ..name */ const int sym_rel; /* symbol or section-relative? */ diff --git a/modules/objfmts/elf/elf-objfmt.c b/modules/objfmts/elf/elf-objfmt.c index 664d1351..5ec17b7c 100644 --- a/modules/objfmts/elf/elf-objfmt.c +++ b/modules/objfmts/elf/elf-objfmt.c @@ -514,6 +514,8 @@ elf_objfmt_output_value(yasm_value *value, unsigned char *buf, wrt = NULL; else if (wrt && elf_is_wrt_sym_relative(wrt)) ; + else if (wrt && elf_is_wrt_pos_adjusted(wrt)) + intn_val = offset + bc->offset; else if (vis == YASM_SYM_LOCAL) { yasm_bytecode *sym_precbc; /* Local symbols need relocation to their section's start, and diff --git a/modules/objfmts/elf/elf-x86-amd64.c b/modules/objfmts/elf/elf-x86-amd64.c index ce0cdda1..4bc53b21 100644 --- a/modules/objfmts/elf/elf-x86-amd64.c +++ b/modules/objfmts/elf/elf-x86-amd64.c @@ -209,8 +209,8 @@ elf_x86_amd64_write_proghead(unsigned char **bufpp, } static elf_machine_ssym elf_x86_amd64_ssyms[] = { - {"..gotpcrel", 1}, - {"..got", 1}, + {"..gotpcrel", ELF_SSYM_SYM_RELATIVE}, + {"..got", ELF_SSYM_SYM_RELATIVE}, {"..plt", 0} }; diff --git a/modules/objfmts/elf/elf-x86-x86.c b/modules/objfmts/elf/elf-x86-x86.c index 827c861e..67a23d0a 100644 --- a/modules/objfmts/elf/elf-x86-x86.c +++ b/modules/objfmts/elf/elf-x86-x86.c @@ -194,9 +194,9 @@ elf_x86_x86_write_proghead(unsigned char **bufpp, } static elf_machine_ssym elf_x86_x86_ssyms[] = { - {"..gotpc", 0}, + {"..gotpc", ELF_SSYM_CURPOS_ADJUST}, {"..gotoff", 0}, - {"..got", 1}, + {"..got", ELF_SSYM_SYM_RELATIVE}, {"..plt", 0} }; diff --git a/modules/objfmts/elf/elf.c b/modules/objfmts/elf/elf.c index f187b9e7..87ee9828 100644 --- a/modules/objfmts/elf/elf.c +++ b/modules/objfmts/elf/elf.c @@ -99,13 +99,27 @@ elf_set_arch(yasm_arch *arch, yasm_symtab *symtab, int bits_pref) } /* reloc functions */ +int elf_ssym_has_flag(yasm_symrec *wrt, int flag); + int elf_is_wrt_sym_relative(yasm_symrec *wrt) +{ + return elf_ssym_has_flag(wrt, ELF_SSYM_SYM_RELATIVE); +} + +int +elf_is_wrt_pos_adjusted(yasm_symrec *wrt) +{ + return elf_ssym_has_flag(wrt, ELF_SSYM_CURPOS_ADJUST); +} + +int +elf_ssym_has_flag(yasm_symrec *wrt, int flag) { int i; for (i=0; (unsigned int)inum_ssyms; i++) { if (elf_ssyms[i] == wrt) - return elf_march->ssyms[i].sym_rel; + return (elf_march->ssyms[i].sym_rel & flag) != 0; } return 0; } diff --git a/modules/objfmts/elf/elf.h b/modules/objfmts/elf/elf.h index b876a75e..954e052e 100644 --- a/modules/objfmts/elf/elf.h +++ b/modules/objfmts/elf/elf.h @@ -412,6 +412,7 @@ const elf_machine_handler *elf_set_arch(struct yasm_arch *arch, /* reloc functions */ int elf_is_wrt_sym_relative(yasm_symrec *wrt); +int elf_is_wrt_pos_adjusted(yasm_symrec *wrt); elf_reloc_entry *elf_reloc_entry_create(yasm_symrec *sym, /*@null@*/ yasm_symrec *wrt, yasm_intnum *addr, diff --git a/modules/objfmts/elf/tests/elfso.hex b/modules/objfmts/elf/tests/elfso.hex index 9d99c0f8..206cce9c 100644 --- a/modules/objfmts/elf/tests/elfso.hex +++ b/modules/objfmts/elf/tests/elfso.hex @@ -88,10 +88,10 @@ e8 5b 81 c3 -e9 -ff -ff -ff +03 +00 +00 +00 8b 83 00 -- 2.40.0