[PATCH 4/4] sframe: fix the index for r_offset with link relaxation enabled

Huang Pei huangpei@loongson.cn
Thu Sep 25 12:48:31 GMT 2025


With link relaxation enabled, there are at least two relocs for one
func desc entry(one for start addr, one for func size). Skip relocs
belonging to the same func desc entry by the size of struct
sframe_func_desc_entry.

Signed-off-by: Huang Pei <huangpei@loongson.cn>
---
 bfd/elf-sframe.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/bfd/elf-sframe.c b/bfd/elf-sframe.c
index 2cb732c3016..f84c51fbf56 100644
--- a/bfd/elf-sframe.c
+++ b/bfd/elf-sframe.c
@@ -104,7 +104,8 @@ sframe_decoder_init_func_bfdinfo (bfd *abfd,
 				  const struct elf_reloc_cookie *cookie)
 {
   unsigned int fde_count;
-  unsigned int func_bfdinfo_size, i;
+  unsigned int func_bfdinfo_size, i, j;
+  unsigned int rel_range;
   const Elf_Internal_Rela *rel;
 
   fde_count = sframe_decoder_get_num_fidx (sfd_info->sfd_ctx);
@@ -121,14 +122,21 @@ sframe_decoder_init_func_bfdinfo (bfd *abfd,
     return true;
 
   rel = cookie->rels;
-  for (i = 0; i < fde_count; i++)
+  for (i = 0, j = 0; i < fde_count; i++)
     {
       /* Bookkeep the relocation offset and relocation index of each function
 	 for later use.  */
       sframe_decoder_set_func_r_offset (sfd_info, i, rel->r_offset);
-      sframe_decoder_set_func_reloc_index (sfd_info, i, i);
-
-      rel++;
+      sframe_decoder_set_func_reloc_index (sfd_info, i, j);
+      /* we can not assume that 1:1 relation between relocs and func desc.
+         With link relaxation enabled, at least two relocs for one func
+	 desc, so skip relocs within the same func desc. */
+      rel_range = rel->r_offset + sizeof(struct sframe_func_desc_entry);
+      while ((rel < cookie->relend) && (rel->r_offset < rel_range))
+        {
+          rel++;
+	  j++;
+        }
     }
 
   /* If there are more relocation entries, they must be R_*_NONE which
-- 
2.45.2



More information about the Binutils mailing list