bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug ld/31318] New: RISC-V 32-bit relocations truncated silently


From: Joseph.Faulls at imgtec dot com
Subject: [Bug ld/31318] New: RISC-V 32-bit relocations truncated silently
Date: Tue, 30 Jan 2024 16:43:05 +0000

https://sourceware.org/bugzilla/show_bug.cgi?id=31318

            Bug ID: 31318
           Summary: RISC-V 32-bit relocations truncated silently
           Product: binutils
           Version: 2.43 (HEAD)
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: ld
          Assignee: unassigned at sourceware dot org
          Reporter: Joseph.Faulls at imgtec dot com
  Target Milestone: ---

Hi,

It seems handling relocations of type R_RISCV_32 does not error if there is a
truncation. This does not seem right to me.

This was discovered when placing a program at very high addresses (> max_int),
and the relocations emitted by the (clang) compiler in a jump table (from an
optimised switch-case) in the data section were truncated. This resulted in a
run-time failure. Supplying -mcmodel=medany solves this.

Reproducing test case:

test.s:
        .macro  DATA symbol
        .word   \symbol
        .endm
        DATA    abs

$ as test.s -march=rv64i -mabi=lp64 -defsym __abs__=1 -o test.o
$ ld -melf64lriscv -Ttext 0x8000 --defsym _start=0x0 --defsym abs=0xc00005000
--defsym abs_local=0x200 test.o -o test.elf
$ objdump -dr test.elf

Disassembly of section .text:

0000000000008000 <__DATA_BEGIN__-0x1004>:
    8000:       00005000                .word   0x00005000

Should this not error as we're truncating the address?


I've spent a while debugging, but this is the best fix I can come up with:

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 8b27e3b8d6a..91a552a3dc2 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -1866,6 +1866,9 @@ perform_relocation (const reloc_howto_type *howto,

     case R_RISCV_32:
     case R_RISCV_64:
+      if (value & ~howto->dst_mask)
+        return bfd_reloc_overflow;
+      break;
     case R_RISCV_ADD8:
     case R_RISCV_ADD16:
     case R_RISCV_ADD32:

However, I don't really know if this is a reasonable fix. What do people think?

Thanks,
Joe

-- 
You are receiving this mail because:
You are on the CC list for the bug.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]