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).
This commit is contained in:
Jan Beulich
2023-08-25 14:56:44 +02:00
parent 183440b0aa
commit 67694446f7
5 changed files with 17 additions and 7 deletions

View File

@@ -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 \

View File

@@ -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 \

View File

@@ -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 \

View File

@@ -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; \
}

View File

@@ -15,11 +15,11 @@ Disassembly of section .text:
0+008 <global_sym\+0x4> e1a00000 nop @ \(mov r0, r0\)
0+00c <global_sym\+0x8> e1a00000 nop @ \(mov r0, r0\)
0+010 <global_sym\+0xc> eafffffb b f+ff8 <global_sym\+0xf+ff4>
10: ARM_26D global_sym-0x4
10: ARM_26D global_sym
0+014 <global_sym\+0x10> ebfffffa bl f+ff4 <global_sym\+0xf+ff0>
14: ARM_26D global_sym-0x4
14: ARM_26D global_sym
0+018 <global_sym\+0x14> 0afffff9 beq f+ff0 <global_sym\+0xf+fec>
18: ARM_26D global_sym-0x4
18: ARM_26D global_sym
0+01c <global_sym\+0x18> eafffff8 b 0+004 <global_sym>
0+020 <global_sym\+0x1c> ebfffff7 bl 0+004 <global_sym>
0+024 <global_sym\+0x20> 0afffff6 beq 0+004 <global_sym>