`.option (no)?relax` and label differences
MaskRay opened this issue · 1 comments
GNU assembler emits a pair of R_RISCV_ADD32
and R_RISCV_SUB32
for 32-bit label differences. This assembler construct is useful for metadata and the desired behavior should be documented somewhere.
.option push
.option norelax
.section .text,"ax",@progbits
lo:
ret
hi:
.option pop
.data
.long hi - lo
Currently both GNU assembler and LLVM integrated assembler emit R_RISCV_ADD32
R_RISCV_SUB32
regardless of the relax/norelax state. I think it will be useful to have a way to emit a constant in the norelax case to make relocatable object files smaller. This will help clang -g
:
.section .debug_info,"",@progbits
...
.word .Lfunc_end0-.Lfunc_begin0
If 32-bit label differences always lead to R_RISCV_ADD32
R_RISCV_SUB32
, it will be cumbersome to get rid of the relocations in -mno-relax
mode. An object file producer can do some hard work emitting a constant but this isn't feasible for an assembly file producer.
The documentation may specify:
- the symbols must be STB_LOCAL. Currently the assemblers don't report an error even if this output may not make sense as linked output.
- the behavior when the labels are not in a
SHF_EXECINSTR
section.
I have a much better understanding of label differences now and think this is probably out of the scope of an assembler manual. https://maskray.me/blog/2021-03-14-the-dark-side-of-riscv-linker-relaxation#label-differences-related-to-text-section-symbols
When my https://reviews.llvm.org/D155357 ([RISCV] Allow delayed decision for ADD/SUB relocations
) lands, .long hi - lo
in the case will generate no relocation.
GNU assembler conservatively generates relocations because lo and hi are in a text section (TC_FORCE_RELOCATION_SUB_SAME
in gas/write.c:fix_segment
returns true).