-
Notifications
You must be signed in to change notification settings - Fork 14.6k
Description
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 asJAL
, as would be expected.JAL
is compressed toC_JAL
inRISCVAsmParser::emitToStreamer
C_JAL
is emitted, with aRISCV::fixup_riscv_rvc_jump
fixup, which is not marked as linker relaxable.C_JAL
is jumping to an undefined symbol, so will be changed withrelaxInstruction
relaxInstruction
first relaxes toJAL
and then the second time toQC_E_JAL
QC_E_JAL
has aRISCV::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 thinkRISCVAsmBackend::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.