]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commit
ld: bfd: sframe: fix incorrect r_offset in RELA entries
authorIndu Bhagat <indu.bhagat@oracle.com>
Thu, 6 Feb 2025 21:38:04 +0000 (13:38 -0800)
committerIndu Bhagat <indu.bhagat@oracle.com>
Sat, 8 Mar 2025 04:46:43 +0000 (20:46 -0800)
commit141e6079582d2f8834674c76c5db7c762ab2ad1b
treeb915247fe5cf6ed39e5f35718a14d0284495bd97
parentdca22098cc6d99975facb72f5e9932ab8e9d64e8
ld: bfd: sframe: fix incorrect r_offset in RELA entries

PR/32666  Incorrect .rela.sframe when using ld -r

Input SFrame sections are merged using _bfd_elf_merge_section_sframe (),
which clubs all SFrame FDEs together in one blob and all SFrame FREs in
another.  This, of course, means the offset of an SFrame FDE in the output
section cannot be simply derived from the output_offset of the sections.

Fix this by providing _bfd_elf_sframe_section_offset () which returns
the new offset of the SFrame FDE in the merged SFrame section.

Unlike EH_Frame sections, which also use the _bfd_elf_section_offset (),
to update the r_offset, SFrame sections additionally need :

          if (o->sec_info_type != SEC_INFO_TYPE_SFRAME)
            irela->r_offset += o->output_offset;

because information in SFrame and EH_Frame sections is organised
differently.  In case of SFrame, the SFrame FDE will not simply sit at
location "o->output_offset + offset of SFrame FDE in o".  Recall that
information layout in an SFrame section is as follows:
   SFrame Header
   SFrame FDE 1
   SFrame FDE 2
   ...
   SFrame FDEn
   SFrame FREs (Frame Row Entries)
Note how the SFrame FDEs and SFrame FREs are clubber together in groups
of their own.

Taking the above into account, the correct offset has already been
calculated via _bfd_elf_section_offset ().  So for SFrame sections, the
r_offset of the RELA should not be offset further by the
o->output_offset (offset of the input SFrame section in the output
SFrame section).

Add a new enum to track the current state of the SFrame input section
during the linking process (SFRAME_SEC_DECODED, SFRAME_SEC_MERGED) for
each input SFrame section.  This is then used to assert an assumption
that _bfd_elf_sframe_section_offset () is being used on an input SFrame
sections which have not been merged (via
_bfd_elf_merge_section_sframe ()) yet.

bfd/
        * elf-bfd.h: New declaration.
        * elf-sframe.c (_bfd_elf_sframe_section_offset): New definition.
        * elf.c (_bfd_elf_section_offset): Adjust offset if SFrame
section.
        * elflink.c (elf_link_input_bfd): RELA offset adjust be done
conditionally.

ld/testsuite/
        * ld-x86-64/x86-64.exp: New test.
        * ld-x86-64/sframe-reloc-1.d: New test.
bfd/elf-bfd.h
bfd/elf-sframe.c
bfd/elf.c
bfd/elflink.c
ld/testsuite/ld-x86-64/sframe-reloc-1.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/x86-64.exp