This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] RISC-V: Fix symbol size bug when relaxation deletes bytes.


I noticed some symbols have (unsigned) negative sizes, and tracked it down to
a problem where we would sometimes decrease the start address, and then get
confused by the change to the start address into thinking that the size needed
to change also.  This patch fixes the problem.

There is a testcase in PR 22756, but I haven't had a chance to make a ld
testcase yet.  The testcase works correctly with the patch.

This was tested with riscv{32,64}-{elf,linux} binutils/gas/ld testsuites,
and with riscv64-linux gcc make check.  There were no regressions.

Committed.

Jim

	bfd/
	PR 22756
	* elfnn-riscv.c (riscv_relax_delete_bytes): When adjust st_size, use
	else if instead of if.
---
 bfd/elfnn-riscv.c | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 6b2d80c379..582c8d1748 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -2665,10 +2665,16 @@ riscv_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, size_t count,
 
 	  /* If the symbol *spans* the bytes we just deleted (i.e. its
 	     *end* is in the moved bytes but its *start* isn't), then we
-	     must adjust its size.  */
-	  if (sym->st_value <= addr
-	      && sym->st_value + sym->st_size > addr
-	      && sym->st_value + sym->st_size <= toaddr)
+	     must adjust its size.
+
+	     This test needs to use the original value of st_value, otherwise
+	     we might accidentally decrease size when deleting bytes right
+	     before the symbol.  But since deleted relocs can't span across
+	     symbols, we can't have both a st_value and a st_size decrease,
+	     so it is simpler to just use an else.  */
+	  else if (sym->st_value <= addr
+		   && sym->st_value + sym->st_size > addr
+		   && sym->st_value + sym->st_size <= toaddr)
 	    sym->st_size -= count;
 	}
     }
@@ -2716,9 +2722,9 @@ riscv_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, size_t count,
 	    sym_hash->root.u.def.value -= count;
 
 	  /* As above, adjust the size if needed.  */
-	  if (sym_hash->root.u.def.value <= addr
-	      && sym_hash->root.u.def.value + sym_hash->size > addr
-	      && sym_hash->root.u.def.value + sym_hash->size <= toaddr)
+	  else if (sym_hash->root.u.def.value <= addr
+		   && sym_hash->root.u.def.value + sym_hash->size > addr
+		   && sym_hash->root.u.def.value + sym_hash->size <= toaddr)
 	    sym_hash->size -= count;
 	}
     }
-- 
2.14.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]