[all-commits] [llvm/llvm-project] 6611d5: [ELF] Relax R_RISCV_ALIGN

Fangrui Song via All-commits all-commits at lists.llvm.org
Thu Jul 7 10:16:22 PDT 2022


  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: 6611d58f5bbcbec77262d392e2923e1d680f6985
      https://github.com/llvm/llvm-project/commit/6611d58f5bbcbec77262d392e2923e1d680f6985
  Author: Fangrui Song <i at maskray.me>
  Date:   2022-07-07 (Thu, 07 Jul 2022)

  Changed paths:
    M lld/ELF/Arch/RISCV.cpp
    M lld/ELF/InputSection.cpp
    M lld/ELF/InputSection.h
    M lld/ELF/Relocations.cpp
    M lld/ELF/Relocations.h
    M lld/ELF/Target.h
    M lld/ELF/Writer.cpp
    A lld/test/ELF/riscv-relax-align-rvc.s
    A lld/test/ELF/riscv-relax-align.s
    R lld/test/ELF/riscv-reloc-align.s

  Log Message:
  -----------
  [ELF] Relax R_RISCV_ALIGN

Alternative to D125036. Implement R_RISCV_ALIGN relaxation so that we can handle
-mrelax object files (i.e. -mno-relax is no longer needed) and creates a
framework for future relaxation.

`relaxAux` is placed in a union with InputSectionBase::jumpInstrMod, storing
auxiliary information for relaxation. In the first pass, `relaxAux` is allocated.
The main data structure is `relocDeltas`: when referencing `relocations[i]`, the
actual offset is `r_offset - (i ? relocDeltas[i-1] : 0)`.

`relaxOnce` performs one relaxation pass. It computes `relocDeltas` for all text
section. Then, adjust st_value/st_size for symbols relative to this section
based on `SymbolAnchor`. `bytesDropped` is set so that `assignAddresses` knows
that the size has changed.

Run `relaxOnce` in the `finalizeAddressDependentContent` loop to wait for
convergence of text sections and other address dependent sections (e.g.
SHT_RELR). Note: extrating `relaxOnce` into a separate loop works for many cases
but has issues in some linker script edge cases.

After convergence, compute section contents: shrink the NOP sequence of each
R_RISCV_ALIGN as appropriate. Instead of deleting bytes, we run a sequence of
memcpy on the content delimitered by relocation locations. For R_RISCV_ALIGN let
the next memcpy skip the desired number of bytes. Section content computation is
parallelizable, but let's ensure the implementation is mature before
optimizations. Technically we can save a copy if we interleave some code with
`OutputSection::writeTo`, but let's not pollute the generic code (we don't have
templated relocation resolving, so using conditions can impose overhead to
non-RISCV.)

Tested:
`make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- LLVM=1 defconfig all` built Linux kernel using -mrelax is bootable.
FreeBSD RISCV64 system using -mrelax is bootable.
bash/curl/firefox/libevent/vim/tmux using -mrelax works.

Differential Revision: https://reviews.llvm.org/D127581




More information about the All-commits mailing list