[PATCH] D157657: [RISCV] Support R_RISCV_SET_ULEB128/R_RISCV_SUB_ULEB128 for .uleb128 directives

Fangrui Song via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 10 14:47:00 PDT 2023


MaskRay created this revision.
MaskRay added reviewers: asb, jrtc27, kito-cheng.
Herald added subscribers: jobnoorman, luke, VincentWu, vkmr, frasercrmck, luismarques, apazos, sameer.abuasal, s.egerton, Jim, benna, psnobl, jocewei, PkmX, the_o, brucehoult, MartinMosbeck, rogfer01, edward-jones, zzheng, shiva0217, niosHD, sabuasal, simoncook, johnrusso, rbar, hiraditya, arichardson, emaste.
Herald added a project: All.
MaskRay requested review of this revision.
Herald added subscribers: llvm-commits, wangpc, eopXD.
Herald added a project: LLVM.

For a label difference like `.uleb128 A-B`, MC folds A-B even if A and B
are separated by a RISC-V linker-relaxable instruction. This incorrect
behavior is currently abused by DWARF v5 .debug_loclists/.debug_rnglists
(DW_LLE_offset_pair/DW_RLE_offset_pair entry kinds) implemented in
Clang/LLVM (see https://github.com/ClangBuiltLinux/linux/issues/1719 for
an instance).

https://github.com/riscv-non-isa/riscv-elf-psabi-doc/commit/96d6e190e9fc04a8517f9ff7fb9aed3e9876cbd6
defined R_RISCV_SET_ULEB128/R_RISCV_SUB_ULEB128. This patch generates such
a pair of relocations to represent A-B that should not be folded.
GNU assembler computes the directive size by ignoring shrinkable section
content, therefore after linking the value of A-B cannot use more bytes
than the reserved number (`final size of uleb128 value at offset ... exceeds available space`).
We make the same assumption.

  w1:
    call foo
  w2:
    .space 120
  w3:
  .uleb128 w2-w1  # 1 byte, 0x08
  .uleb128 w3-w1  # 2 bytes, 0x80 0x01

We do not conservatively reserve 10 bytes (maximum size of an uleb128
for uint64_t) as that would pessimize DWARF v5
DW_LLE_offset_pair/DW_RLE_offset_pair, nullifying the benefits of
introducing R_RISCV_SET_ULEB128/R_RISCV_SUB_ULEB128 relocations.

The supported expressions are limited. For example,

- non-subtraction `.uleb128 A` is not allowed
- `.uleb128 A-B`: report an error unless A and B are both defined and in the same section

The new cl::opt `-riscv-uleb128-reloc` can be used to suppress the
relocations.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D157657

Files:
  llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def
  llvm/include/llvm/MC/MCAsmBackend.h
  llvm/include/llvm/MC/MCFixup.h
  llvm/include/llvm/MC/MCFragment.h
  llvm/lib/MC/MCAsmBackend.cpp
  llvm/lib/MC/MCAssembler.cpp
  llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
  llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
  llvm/test/MC/ELF/RISCV/gen-dwarf.s
  llvm/test/MC/RISCV/leb128.s

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D157657.549178.patch
Type: text/x-patch
Size: 15161 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230810/c8483724/attachment.bin>


More information about the llvm-commits mailing list