[RFC] : Sframe support for LoongArch
Commit Message
Hi, Indu,
Patch 1-3: add Sframe support for LoongArch
Patch 4: fix warning of ld when link time relaxation enabled
These patches passed check-ld and check-gas, and (cross) passed on arm64
and s390x.
LoongArch gas enables -mrelax by default, which breaks the assumption
of current implementation, so sframe-simple-1.d failed.
Even with this patch, I do not know how to apply the updated func_size into
sfd_ctx without breaking current API, and whether it should be appled into
sfd_ctx (see _bfd_elf_merge_section_sframe, the sframe-simple-1 hit on
sframe_assert at line 1339 of libsframe/sframe.c), because the same issue
hit fre_start_addr if we add relocs to fre_start_addr.
@@ -153,7 +153,7 @@ sframe_decoder_init_func_bfdinfo (bfd *abfd,
/* Read the value from CONTENTS at the specified OFFSET for the given ABFD. */
static bfd_vma
-sframe_read_value (bfd *abfd, bfd_byte *contents, unsigned int offset,
+sframe_read_value_s32 (bfd *abfd, bfd_byte *contents, unsigned int offset,
unsigned int width)
{
BFD_ASSERT (contents && offset);
@@ -166,6 +166,19 @@ sframe_read_value (bfd *abfd, bfd_byte *contents, unsigned int offset,
return value;
}
+static bfd_vma
+sframe_read_value_u32 (bfd *abfd, bfd_byte *contents, unsigned int offset,
+ unsigned int width)
+{
+ BFD_ASSERT (contents && offset);
+ /* Supporting the usecase of reading only the 4-byte relocated
+ value (signed offset for func start addr) for now. */
+ BFD_ASSERT (width == 4);
+ /* FIXME endianness ?? */
+ unsigned char *buf = contents + offset;
+ bfd_vma value = bfd_get_32 (abfd, buf);
+ return value;
+}
/* Return true if there is at least one non-empty .sframe section in
input files. Can only be called after ld has mapped input to
output sections, and before sections are stripped. */
@@ -531,9 +544,9 @@ _bfd_elf_merge_section_sframe (bfd *abfd,
}
/* Get the SFrame FDE function start address after relocation. */
- address = sframe_read_value (abfd, contents, r_offset, 4);
+ address = sframe_read_value_s32 (abfd, contents, r_offset, 4);
if (pltn_reloc_by_hand)
- address += sframe_read_value (abfd, contents,
+ address += sframe_read_value_s32 (abfd, contents,
pltn_r_offset, 4);
address += (sec->output_offset + r_offset);
/* SFrame FDE function start address is an offset from the
@@ -550,6 +563,16 @@ _bfd_elf_merge_section_sframe (bfd *abfd,
// address += (sec->output_section->vma);
func_start_addr = address;
+
+ /* Get the SFrame FDE function size after relocation. worked for
+ arch with link time relaxation */
+ if (!func_size)
+ {
+ /* func size field just 4 byte behind func start field */
+ func_size = sframe_read_value_u32 (abfd, contents,
+ r_offset + 4, 4);
+ BFD_ASSERT(!func_size);
+ }
}
/* Update the encoder context with updated content. */