[RFC] : Sframe support for LoongArch

Message ID 20250925124831.29563-1-huangpei@loongson.cn
State New
Headers
Series [RFC] : Sframe support for LoongArch |

Commit Message

Huang Pei Sept. 25, 2025, 12:48 p.m. UTC
  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.
  

Patch

diff --git a/bfd/elf-sframe.c b/bfd/elf-sframe.c
index f84c51fbf56..5409f476c7c 100644
--- a/bfd/elf-sframe.c
+++ b/bfd/elf-sframe.c
@@ -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.  */