Skip to content

[RISCV] GP relaxation broken if accesses straddle the boundary #72405

@nemanjai

Description

@nemanjai

If we have more than one memory access (with a R_RISCV_LO12_I relocation on it) that depends on the same LUI with a R_RISCV_HI20 relocation and one of them can be reached from the GP while the other(s) can't, the linker will relax and get rid of the LUI. The memory access that is reachable will be fine, but the one(s) that aren't will be relocated off of an undefined register.
To illustrate the issue:

$ cat a.s
.global _start
_start:
        lui     a1, %hi(Var0)
        lw      a0, %lo(Var0)(a1)
        lw      a1, %lo(Var0+4)(a1)

.section .sdata,"aw"
foo:
  .word 0
  .space 4091
Var0:
  .quad 0
  .size   Var0, 8

Produce object file:
llvm-mc -filetype=obj -triple=riscv32-unknown-elf -mattr=+relax a.s -o a.o

Link it:
ld.lld --relax-gp --undefined=__global_pointer$ a.o

Disassemble:

llvm-objdump -dr a.out

a.out:  file format elf32-littleriscv

Disassembly of section .text:

000110d4 <_start>:
   110d4: 03 a5 f1 7f   lw      a0, 2047(gp)
   110d8: 83 a5 f5 0d   lw      a1, 223(a1)

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions