Issue 150071
Summary Missing Linker Relaxation Relocations after Assembly Relocation
Labels backend:RISC-V, mc
Assignees
Reporter lenary
    The following example, when assembled with `llvm-mc --triple=riscv32 -mattr=+relax,+experimental-xqcilb` seems to have a bug:

```
.global foo

bar:
  jal x1, foo
  bne a0, a1, bar
  ret
```

Looking at the `llvm-objdump -dr` output (this has not been truncated)

```
jal.o:  file format elf32-littleriscv

Disassembly of section .text:

00000000 <bar>:
       0: c01f 0000 0000        qc.e.jal        0x0 <bar>
 00000000:  R_RISCV_VENDOR       QUALCOMM
 00000000:  R_RISCV_CUSTOM195    foo
                        00000000: R_RISCV_RELAX        *ABS*
       6: feb51de3      bne     a0, a1, 0x0 <bar>
       a: 8082          ret
```

The `bne` is branching over a relaxable instruction, but has been resolved instead of having a relocation on it. This means that if the linker relaxes the `qc.e.jal` instruction, the `bne` will be incorrect.

I think the sequence of what is happening is:
- `jal x1, foo` is parsed as `JAL`, as would be expected.
- `JAL` is compressed to `C_JAL` in `RISCVAsmParser::emitToStreamer`
- `C_JAL` is emitted, with a `RISCV::fixup_riscv_rvc_jump` fixup, which is not marked as linker relaxable.
- `C_JAL` is jumping to an undefined symbol, so will be changed with `relaxInstruction`
- `relaxInstruction` first relaxes to `JAL` and then the second time to `QC_E_JAL`
- `QC_E_JAL` has a `RISCV::fixup_riscv_qc_e_call_plt` fixup, which is marked as linker relaxable!
- nothing now marks the fragment and the section as linker relaxable.
- When it comes time to apply the fixup to `bne`, I think `RISCVAsmBackend::isPCRelFixupResolved` is returning that the fixup is fully resolved, when it shouldn't be.

I think the relaxation of `JAL` to `QC_E_JAL` might be the only one we have right now which changes the fixup from being non-linker-relaxable to being linker-relaxable. (This is not going to be the case indefinitely, as there are now linker relaxations for `R_RISCV_JAL`, so the `C_JAL` to `JAL` relaxation will have the same bug once we update `RISCVMCCodeEmitter::getImmOpValue` for new relaxations in the psABI since we did this last time)

I think this is still violating invariants of the code, that fragments (and their parent sections) with linker relaxable fixups should be marked as linker relaxable.

_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to