[lld] [ELF] Optimize binary search in getSectionPiece (PR #187916)

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 25 23:18:15 PDT 2026


MaskRay wrote:

> I've made a couple of suggestions that I think might protect against some edge cases (section symbol + giant addend). Probably unlikely to happen in practice, but famous last words.
> 
> As an aside:
> 
> The ARM and AArch64 ABIs treat references to section symbol + offset and to symbol differently [ARM-software/abi-aa@`main`/aaelf32/aaelf32.rst#5331merging-of-objects-in-sections-with-shf_merge](https://github.com/ARM-software/abi-aa/blob/main/aaelf32/aaelf32.rst#5331merging-of-objects-in-sections-with-shf_merge)
> 
> From memory this was to allow an object producer to distinguish between the start of a string, and the start of a string + offset (in C). I think these rules permit a linker to be a bit more aggressive about removing strings, or substrings, that are not accessed by the program. From what I can tell lld identifies strings via scanning for null-terminators rather than tracing relocations.

Thanks for the info. I think lld already performs GC according to the ARM ABI.

* In MarkLive.cpp `resolveReloc` , `addend` is added to offset only for `isSection()` symbol. 
* In Symbols.cpp `getSymVA`, `addend` is added to offset only for `isSection()` symbol. 

A relocation to `symbol + giant_addend` that crosses a piece boundary resolves to the same piece.

The following example correctly retains all of a1, a2, and a3.

```
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
# RUN: ld.lld --gc-sections %t.o -o %t.elf
# RUN: llvm-readelf %t.elf --sections --syms | FileCheck %s

.section .rodata.merge,"aM", at progbits,2
a1:
    .short 1
a2:
    .short 2
a3:
    .short 3

.data
.global _start
_start:
    .quad a1+0xff
    .quad a2+0xff
    .quad .rodata.merge+4
```

However, if we emit a dynamic relocation referencing a symbol in a merge section, we call `Symbols.cpp:getSymVA`.
`uint64_t va = isec->getVA(offset);` may pass a non-zero `offset` for a relocation referencing a non-section symbol.

The current patch mistreats the following dynamic relocation
```
.data
.quad .rodata.merge + 0x100000000
```


https://github.com/llvm/llvm-project/pull/187916


More information about the llvm-commits mailing list