[lld] [ELF] Make start/stop symbols retain associated discardable output sections (PR #96343)
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 24 10:46:09 PDT 2024
================
@@ -2028,42 +2028,33 @@ template <class ELFT> void Writer<ELFT>::checkExecuteOnly() {
// The linker is expected to define SECNAME_start and SECNAME_end
// symbols for a few sections. This function defines them.
template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {
- // If a section does not exist, there's ambiguity as to how we
- // define _start and _end symbols for an init/fini section. Since
- // the loader assume that the symbols are always defined, we need to
- // always define them. But what value? The loader iterates over all
- // pointers between _start and _end to run global ctors/dtors, so if
- // the section is empty, their symbol values don't actually matter
- // as long as _start and _end point to the same location.
- //
- // That said, we don't want to set the symbols to 0 (which is
- // probably the simplest value) because that could cause some
- // program to fail to link due to relocation overflow, if their
- // program text is above 2 GiB. We use the address of the .text
- // section instead to prevent that failure.
- //
- // In rare situations, the .text section may not exist. If that's the
- // case, use the image base address as a last resort.
- OutputSection *Default = findSection(".text");
- if (!Default)
- Default = Out::elfHeader;
-
- auto define = [=](StringRef start, StringRef end, OutputSection *os) {
- if (os && !script->isDiscarded(os)) {
+ // If the associated output section does not exist, there is ambiguity as to
+ // how we define _start and _end symbols for an init/fini section. Users
+ // expect no "undefined symbol" linker errors and loaders expect equal
+ // st_value but do not particularly care whether the symbols are defined or
+ // not. We retain the output section so that the section indexes will be
+ // correct.
+ auto define = [=](StringRef start, StringRef end, OutputSection *os,
+ bool exidx = false) {
----------------
MaskRay wrote:
> I expect that would reduce the number of tests that would need updating if exidx sections weren't a special case. I would expect in practice that the exidx start and exidx end symbol references would come from libunwind which would contain .ARM.exidx sections.
Yes, the .ARM.exidx special case is to avoid updating ~40 `lld/test/ELF/arm-*` files. I think in practice when `.ARM.exidx` is used, it's always going to be non-empty...
https://github.com/llvm/llvm-project/pull/96343
More information about the llvm-commits
mailing list