bfd: correct relocation handling for objcopy COFF -> ELF
authorJan Beulich <jbeulich@suse.com>
Fri, 25 Aug 2023 12:56:44 +0000 (14:56 +0200)
committerJan Beulich <jbeulich@suse.com>
Fri, 25 Aug 2023 12:56:44 +0000 (14:56 +0200)
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).

bfd/coff-i386.c
bfd/coff-sh.c
bfd/coff-x86_64.c
bfd/coffcode.h
gas/testsuite/gas/arm/wince.d

index 24a05d3aa65b5a79eb38f0cea24908ca6234a267..71516066da8898a4d2f72868ce96465ceadebacd 100644 (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                       \
index 14f502e363818877c5939a722d4133d4faa0ded1..a20c01127b6d2c333c78c9825c2d197c96dc33a6 100644 (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                         \
index 9a3f85cd1e5f33694a3675152ffe41514954a147..57b975c2eed897d2576e7f2e6cfd4a15e8793739 100644 (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                       \
index e3f4afd389f5bfe3ca53807fa22af21e849ea013..27927039a3444dbe052671f8f2bb1fb321caebb9 100644 (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;                                   \
   }
index e5bac1de9c6ac0842d8ab71ac0a1ded5f1c393f4..e7afbedbbf5809598c62c8606895172474bad005 100644 (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>