From: Jan Beulich Date: Fri, 25 Aug 2023 12:56:44 +0000 (+0200) Subject: bfd: correct relocation handling for objcopy COFF -> ELF X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=67694446f772ae95d330419eb6d01e38e6d24612;p=binutils-gdb.git bfd: correct relocation handling for objcopy COFF -> ELF While documented to not be reliable, it is still odd for objcopy to silently produce bad output when converting COFF/PE object files to ELF ones. The issue there is that relocation addends all are screwed up by subtracting the symbol's section offset. In the COFF/PE world, to my knowledge, section contents stores the addends alone, not the result of symbol value plus addend. Hence the compensation talked about in a comment ahead of the sole use site of CALC_ADDEND() may need to account for the VMA (which is always zero for object files anyway), but not for the symbol value. The coff-sh.c adjustment is based upon guessing that behavior there is the same. Note also how coff-aarch64.c short-circuits CALC_ADDEND() altogether, which may suggest that a much simpler macro might do for the COFF_WITH_PE case in the three arch-specific files touched here. For (at least) Arm/WinCE this actually results in more appropriate objdump output as well, as can be seen in the one testcase which has its expectations adjusted (the generated binary doesn't change). --- diff --git a/bfd/coff-i386.c b/bfd/coff-i386.c index 24a05d3aa65..71516066da8 100644 --- a/bfd/coff-i386.c +++ b/bfd/coff-i386.c @@ -405,7 +405,8 @@ static reloc_howto_type howto_table[] = cache_ptr->addend = - coffsym->native->u.syment.n_value; \ else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ && ptr->section != (asection *) NULL) \ - cache_ptr->addend = - (ptr->section->vma + ptr->value); \ + cache_ptr->addend = - (ptr->section->vma \ + + COFF_PE_ADDEND_BIAS (ptr)); \ else \ cache_ptr->addend = 0; \ if (ptr && reloc.r_type < NUM_HOWTOS \ diff --git a/bfd/coff-sh.c b/bfd/coff-sh.c index 14f502e3638..a20c01127b6 100644 --- a/bfd/coff-sh.c +++ b/bfd/coff-sh.c @@ -544,7 +544,8 @@ sh_coff_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, cache_ptr->addend = 0; \ else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ && ptr->section != (asection *) NULL) \ - cache_ptr->addend = - (ptr->section->vma + ptr->value); \ + cache_ptr->addend = - (ptr->section->vma \ + + COFF_PE_ADDEND_BIAS (ptr)); \ else \ cache_ptr->addend = 0; \ if ((reloc).r_type == R_SH_SWITCH8 \ diff --git a/bfd/coff-x86_64.c b/bfd/coff-x86_64.c index 9a3f85cd1e5..57b975c2eed 100644 --- a/bfd/coff-x86_64.c +++ b/bfd/coff-x86_64.c @@ -542,7 +542,8 @@ static reloc_howto_type howto_table[] = cache_ptr->addend = - coffsym->native->u.syment.n_value; \ else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ && ptr->section != NULL) \ - cache_ptr->addend = - (ptr->section->vma + ptr->value); \ + cache_ptr->addend = - (ptr->section->vma \ + + COFF_PE_ADDEND_BIAS (ptr)); \ else \ cache_ptr->addend = 0; \ if (ptr && reloc.r_type < NUM_HOWTOS \ diff --git a/bfd/coffcode.h b/bfd/coffcode.h index e3f4afd389f..27927039a34 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -5192,6 +5192,12 @@ SUBSUBSECTION final-linked object. See @code{CALC_ADDEND}. */ +#ifdef COFF_WITH_PE +#define COFF_PE_ADDEND_BIAS(ptr) 0 /* Symbol value not stored in raw data. */ +#else +#define COFF_PE_ADDEND_BIAS(ptr) ((ptr)->value) +#endif + #ifndef CALC_ADDEND #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ { \ @@ -5208,7 +5214,8 @@ SUBSUBSECTION cache_ptr->addend = 0; \ else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ && ptr->section != NULL) \ - cache_ptr->addend = - (ptr->section->vma + ptr->value); \ + cache_ptr->addend = - (ptr->section->vma \ + + COFF_PE_ADDEND_BIAS (ptr)); \ else \ cache_ptr->addend = 0; \ } diff --git a/gas/testsuite/gas/arm/wince.d b/gas/testsuite/gas/arm/wince.d index e5bac1de9c6..e7afbedbbf5 100644 --- a/gas/testsuite/gas/arm/wince.d +++ b/gas/testsuite/gas/arm/wince.d @@ -15,11 +15,11 @@ Disassembly of section .text: 0+008 e1a00000 nop @ \(mov r0, r0\) 0+00c e1a00000 nop @ \(mov r0, r0\) 0+010 eafffffb b f+ff8 - 10: ARM_26D global_sym-0x4 + 10: ARM_26D global_sym 0+014 ebfffffa bl f+ff4 - 14: ARM_26D global_sym-0x4 + 14: ARM_26D global_sym 0+018 0afffff9 beq f+ff0 - 18: ARM_26D global_sym-0x4 + 18: ARM_26D global_sym 0+01c eafffff8 b 0+004 0+020 ebfffff7 bl 0+004 0+024 0afffff6 beq 0+004