[binutils-gdb] RISC-V: hash with segment id and pcrel_hi address while recording pcrel_hi

Nelson Chu nelsonc1225@sourceware.org
Thu Jul 4 13:47:16 GMT 2024


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=f9d218de5c7b2eeeca9b32c9222a63c7376a8ddd

commit f9d218de5c7b2eeeca9b32c9222a63c7376a8ddd
Author: Lifang Xia <lifang_xia@linux.alibaba.com>
Date:   Thu Jul 4 09:56:07 2024 +0800

    RISC-V: hash with segment id and pcrel_hi address while recording pcrel_hi
    
    When the same address across different segments (sections) needs to be
    recorded, it will overwrite the slot, leading to a memory leak. To ensure
    uniqueness, the segment (section) ID needs to be included in the hash key
    calculation.
    
    gas/
            * config/tc-riscv.c (riscv_pcrel_hi_fixup): New "const asection *sec".
            (riscv_pcrel_fixup_hash): make sec->id and e->adrsess as the
            hash key.
            (riscv_pcrel_fixup_eq): Check sec->id at first.
            (riscv_record_pcrel_fixup): New member "sec".
            (md_apply_fix) <case BFD_RELOC_RISCV_PCREL_HI20>: Likewise.
            (md_apply_fix) <case BFD_RELOC_RISCV_PCREL_LO12_I>: Likewise.

Diff:
---
 gas/config/tc-riscv.c | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index e0083702fbd..5b9bfbdfa68 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -1784,6 +1784,7 @@ init_opcode_hash (const struct riscv_opcode *opcodes,
    help us resolve the corresponding low-part relocation later.  */
 typedef struct
 {
+  const asection *sec;
   bfd_vma address;
   symbolS *symbol;
   bfd_vma target;
@@ -1798,7 +1799,13 @@ static hashval_t
 riscv_pcrel_fixup_hash (const void *entry)
 {
   const riscv_pcrel_hi_fixup *e = entry;
-  return (hashval_t) (e->address);
+
+  /* the pcrel_hi with same address may reside in different segments,
+     to ensure uniqueness, the segment ID needs to be included in the
+     hash key calculation.
+     Temporarily using the prime number 499 as a multiplier, but it
+     might not be large enough.  */
+  return e->address + 499 * e->sec->id;
 }
 
 /* Compare the keys between two entries fo the pcrel_hi hash table.  */
@@ -1807,16 +1814,17 @@ static int
 riscv_pcrel_fixup_eq (const void *entry1, const void *entry2)
 {
   const riscv_pcrel_hi_fixup *e1 = entry1, *e2 = entry2;
-  return e1->address == e2->address;
+  return e1->sec->id == e2->sec->id
+	  && e1->address == e2->address;
 }
 
 /* Record the pcrel_hi relocation.  */
 
 static bool
-riscv_record_pcrel_fixup (htab_t p, bfd_vma address, symbolS *symbol,
-			  bfd_vma target)
+riscv_record_pcrel_fixup (htab_t p, const asection *sec, bfd_vma address,
+			  symbolS *symbol, bfd_vma target)
 {
-  riscv_pcrel_hi_fixup entry = {address, symbol, target};
+  riscv_pcrel_hi_fixup entry = {sec, address, symbol, target};
   riscv_pcrel_hi_fixup **slot =
 	(riscv_pcrel_hi_fixup **) htab_find_slot (p, &entry, INSERT);
   if (slot == NULL)
@@ -4426,7 +4434,7 @@ md_pcrel_from (fixS *fixP)
 /* Apply a fixup to the object file.  */
 
 void
-md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
+md_apply_fix (fixS *fixP, valueT *valP, segT seg)
 {
   unsigned int subtype;
   bfd_byte *buf = (bfd_byte *) (fixP->fx_frag->fr_literal + fixP->fx_where);
@@ -4677,6 +4685,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 
 	  /* Record PCREL_HI20.  */
 	  if (!riscv_record_pcrel_fixup (riscv_pcrel_hi_fixup_hash,
+					 (const asection *) seg,
 					 md_pcrel_from (fixP),
 					 fixP->fx_addsy,
 					 target))
@@ -4698,7 +4707,8 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 	 and set fx_done for -mno-relax.  */
       {
 	bfd_vma location_pcrel_hi = S_GET_VALUE (fixP->fx_addsy) + *valP;
-	riscv_pcrel_hi_fixup search = {location_pcrel_hi, 0, 0};
+	riscv_pcrel_hi_fixup search =
+		{(const asection *) seg, location_pcrel_hi, 0, 0};
 	riscv_pcrel_hi_fixup *entry = htab_find (riscv_pcrel_hi_fixup_hash,
 						 &search);
 	if (entry && entry->symbol


More information about the Binutils-cvs mailing list