[PATCH] RISC-V: Segment fault in riscv_elf_append_rela.

Nelson Chu nelson@rivosinc.com
Thu Mar 9 08:04:46 GMT 2023


I seem to remember someone had sent a pacth for this before, but I cannot
find where it is for now.  So I just send it by myself.

======

% cat tmp.s
foo:
	lui	a0, %hi(_end)     # R_RISCV_HI20
	addi	a0, a0, %lo(_end) # R_RISCV_LO12
	.8byte foo                # R_RISCV_64
% riscv64-unknown-linux-gnu-as tmp.s -o tmp.o
% riscv64-unknown-linux-gnu-ld -shared tmp.o
.* tmp.o: relocation R_RISCV_HI20 against `_end' can not be used when making a shared object; recompile with -fPIC
zsh: segmentation fault

I accidently meet this segment fault from the above case.  Since we don't
allow the absolute access (R_RISCV_HI20) when building shared object, the
riscv_elf_check_relocs should return false directly when analyzing the lui,
so there won't have rel.dyn section.  But linker still try to emit the
dynamic relocation for R_RISCV_64 in the riscv_elf_relocate_section, which
cause the segmant fault in the riscv_elf_append_rela.  Refer to other targets,
Loongarch use BFD_ASSERT, and AARCH64 call abort(), to check if the dynamic
section exsits before emiting.  Since BFD_ASSERT still meet the segmant fault,
I think just call abort here is a better chosen.

bfd/
    * elfnn-riscv.c (riscv_elf_append_rela): Abort when the dynamic section
    doesn't exist.
---
 bfd/elfnn-riscv.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 1200e6b11b5..36cdd629aa2 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -182,6 +182,9 @@ riscv_elf_append_rela (bfd *abfd, asection *s, Elf_Internal_Rela *rel)
   const struct elf_backend_data *bed;
   bfd_byte *loc;
 
+  if (!s || !s->contents)
+    abort ();
+
   bed = get_elf_backend_data (abfd);
   loc = s->contents + (s->reloc_count++ * bed->s->sizeof_rela);
   bed->s->swap_reloca_out (abfd, rel, loc);
-- 
2.37.1 (Apple Git-137.1)



More information about the Binutils mailing list