1269 Commits

Author SHA1 Message Date
Jessica Clarke
58e6bc87b7
[ELF] Add a dummySym member to Ctx
This ensures subsequent calls to elf::postScanRelocations with a new Ctx
will correctly use an instance with the right internalFile (with the old
one presumably deleted, even). It also avoids having to create a new
instance in elf::getErrorPlace, and will allow more uses of such a dummy
symbol in future commits.

Reviewers: MaskRay

Reviewed By: MaskRay

Pull Request: https://github.com/llvm/llvm-project/pull/150796
2025-07-30 17:03:34 +01:00
Mingming Liu
7dcd90df45
[lld][ELF] Allow data.rel.ro.hot and .data.rel.ro.unlikely to be RELRO (#148920)
https://discourse.llvm.org/t/rfc-profile-guided-static-data-partitioning/83744
proposes to partition a static data section (like `.data.rel.ro`) into
two sections, one grouping the cold ones and the other grouping the
rest.

lld requires all relro sections to be contiguous. To place
`.data.rel.ro.unlikely` in the middle of all relro sections, this change
proposes to add `.data.rel.ro.unlikely` explicitly as RELRO section.

---------

Co-authored-by: Sam Elliott <quic_aelliott@quicinc.com>
2025-07-23 08:29:17 -07:00
Brian Cain
d2bcc51a5a
[LLD] Merge .hexagon.attributes sections (#148098)
Merge the attributes of object files being linked together. The
`.hexagon.attributes` section can be used by loaders and analysis tools.
This is similar to the .riscv.attributes, introduced in
8a900f2438b4a167b98404565ad4da2645cc9330 /
https://reviews.llvm.org/D138550.
2025-07-14 22:36:05 -05:00
bd1976bris
3b4e79398d
[DTLTO][LLD][ELF] Add support for Integrated Distributed ThinLTO (#142757)
This patch introduces support for Integrated Distributed ThinLTO (DTLTO)
in ELF LLD.

DTLTO enables the distribution of ThinLTO backend compilations via
external distribution systems, such as Incredibuild, during the
traditional link step: https://llvm.org/docs/DTLTO.html.

It is expected that users will invoke DTLTO through the compiler driver
(e.g., Clang) rather than calling LLD directly. A Clang-side interface
for DTLTO will be added in a follow-up patch.

Note: Bitcode members of archives (thin or non-thin) are not currently
supported. This will be addressed in a future change. As a consequence
of this lack of support, this patch is not sufficient to allow for
self-hosting an LLVM build with DTLTO. Theoretically,
--start-lib/--end-lib could be used instead of archives in a self-host
build. However, it's unclear how --start-lib/--end-lib can be easily
used with the LLVM build system.

Testing:
- ELF LLD `lit` test coverage has been added, using a mock distributor
  to avoid requiring Clang.
- Cross-project `lit` tests cover integration with Clang.

For the design discussion of the DTLTO feature, see: #126654.
2025-07-02 16:12:27 +01:00
Peter Collingbourne
494a74882b
Reapply "ELF: Add branch-to-branch optimization."
Fixed assertion failure when reading .eh_frame sections, and added
.eh_frame sections to tests.

This reverts commit 1e95349dbe329938d2962a78baa0ec421e9cd7d1.

Original commit message follows:

When code calls a function which then immediately tail calls another
function there is no need to go via the intermediate function. By
branching directly to the target function we reduce the program's working
set for a slight increase in runtime performance.

Normally it is relatively uncommon to have functions that just tail call
another function, but with LLVM control flow integrity we have jump tables
that replace the function itself as the canonical address. As a result,
when a function address is taken and called directly, for example after
a compiler optimization resolves the indirect call, or if code built
without control flow integrity calls the function, the call will go via
the jump table.

The impact of this optimization was measured using a large internal
Google benchmark. The results were as follows:

CFI enabled:  +0.1% ± 0.05% queries per second
CFI disabled: +0.01% queries per second [not statistically significant]

The optimization is enabled by default at -O2 but may also be enabled
or disabled individually with --{,no-}branch-to-branch.

This optimization is implemented for AArch64 and X86_64 only.

lld's runtime performance (real execution time) after adding this
optimization was measured using firefox-x64 from lld-speed-test [1]
with ldflags "-O2 -S" on an Apple M2 Ultra. The results are as follows:

```
    N           Min           Max        Median           Avg        Stddev
x 512     1.2264546     1.3481076     1.2970261     1.2965788   0.018620888
+ 512     1.2561196     1.3839965     1.3214632     1.3209327   0.019443971
Difference at 95.0% confidence
        0.0243538 +/- 0.00233202
        1.87831% +/- 0.179859%
        (Student's t, pooled s = 0.0190369)
```

[1] https://discourse.llvm.org/t/improving-the-reproducibility-of-linker-benchmarking/86057

Reviewers: zmodem, MaskRay

Reviewed By: MaskRay

Pull Request: https://github.com/llvm/llvm-project/pull/145579
2025-06-24 22:16:18 -07:00
Hans Wennborg
1e95349dbe Revert "ELF: Add branch-to-branch optimization."
This caused assertion failures in applyBranchToBranchOpt():

  llvm/include/llvm/Support/Casting.h:578:
  decltype(auto) llvm::cast(From*)
  [with To = lld:🧝:InputSection; From = lld:🧝:InputSectionBase]:
  Assertion `isa<To>(Val) && "cast<Ty>() argument of incompatible type!"' failed.

See comment on the PR (https://github.com/llvm/llvm-project/pull/138366)

This reverts commit 491b82a5ec1add78d2c93370580a2f1897b6a364.

This also reverts the follow-up "[lld] Use llvm::partition_point (NFC) (#145209)"

This reverts commit 2ac293f5ac4cf65c0c038bf75a88f1d6715e467d.
2025-06-23 13:26:02 +02:00
Peter Collingbourne
491b82a5ec ELF: Add branch-to-branch optimization.
When code calls a function which then immediately tail calls another
function there is no need to go via the intermediate function. By
branching directly to the target function we reduce the program's working
set for a slight increase in runtime performance.

Normally it is relatively uncommon to have functions that just tail call
another function, but with LLVM control flow integrity we have jump tables
that replace the function itself as the canonical address. As a result,
when a function address is taken and called directly, for example after
a compiler optimization resolves the indirect call, or if code built
without control flow integrity calls the function, the call will go via
the jump table.

The impact of this optimization was measured using a large internal
Google benchmark. The results were as follows:

CFI enabled:  +0.1% ± 0.05% queries per second
CFI disabled: +0.01% queries per second [not statistically significant]

The optimization is enabled by default at -O2 but may also be enabled
or disabled individually with --{,no-}branch-to-branch.

This optimization is implemented for AArch64 and X86_64 only.

lld's runtime performance (real execution time) after adding this
optimization was measured using firefox-x64 from lld-speed-test [1]
with ldflags "-O2 -S" on an Apple M2 Ultra. The results are as follows:

```
    N           Min           Max        Median           Avg        Stddev
x 512     1.2264546     1.3481076     1.2970261     1.2965788   0.018620888
+ 512     1.2561196     1.3839965     1.3214632     1.3209327   0.019443971
Difference at 95.0% confidence
	0.0243538 +/- 0.00233202
	1.87831% +/- 0.179859%
	(Student's t, pooled s = 0.0190369)
```

[1] https://discourse.llvm.org/t/improving-the-reproducibility-of-linker-benchmarking/86057

Pull Request: https://github.com/llvm/llvm-project/pull/138366
2025-06-20 13:16:24 -07:00
Ming-Yi Lai
9adde28df7
[LLD][ELF][RISCV][Zicfilp][Zicfiss] Support -z zicfilp= and -z zicfiss= to force enable/disable features (#143114)
+ If `-z zicfilp=implicit` or option not specified, the output would
have the ZICFILP feature enabled/disabled based on input objects
+ If `-z zicfilp=<never|unlabeled|func-sig>`, the output would have
ZICFILP feature forced <off|on to the "unlabeled" scheme|on to the
"func-sig" scheme>
+ If `-z zicfiss=implicit` or option not specified, the output would
have the ZICFISS feature enabled/disabled based on input objects
+ If `-z zicfiss=<never|always>`, the output would have the ZICFISS
feature forced <off|on>
2025-06-16 11:18:41 +08:00
SivanShani-Arm
5762491e2a
[lld] Refactor storage of PAuth ABI core info (#141920)
Previously, the AArch64 PAuth ABI core values were stored as an
ArrayRef<uint8_t>, introducing unnecessary indirection.

This patch replaces the ArrayRef with two explicit uint64_t fields:
aarch64PauthAbiPlatform and aarch64PauthAbiVersion. This simplifies the
representation and improves readability.

No functional change intended, aside from improved error messages.
2025-06-13 11:02:33 +01:00
Fangrui Song
07dad4ecba
[ELF] Implement -z dynamic-undefined-weak
The behavior of an undefined weak reference is implementation defined.
For static -no-pie linking, dynamic relocations are generally avoided (except
IRELATIVE). -shared linking generally emits dynamic relocations.

Dynamic -no-pie linking and -pie allow flexibility. Changes adjust the
behavior for better consistency and simpler internal representation,
e.g. https://reviews.llvm.org/D63003 https://reviews.llvm.org/D105164
(generalized to undefined non-weak in
2fcaa00d1e2317a90c9071b735eb0e758b5dd58b).

GNU ld introduced -z [no]dynamic-undefined-weak option to fine-tune the
behavior. (The option is not very effective with -no-pie, e.g. on
x86-64, `ld.bfd a.o s.so -z dynamic-undefined-weak` generates
R_X86_64_NONE relocations instead of GLOB_DAT/JUMP_SLOT)

This patch implements -z [no]dynamic-undefined-weak option.
The effects are summarized as follows:

* Static -no-pie: no-op
* Dynamic -no-pie: nodynamic-undefined-weak suppresses GLOB_DAT/JUMP_SLOT
* Static -pie: dynamic-undefined-weak generates ABS/GLOB_DAT/JUMP_SLOT.
  https://discourse.llvm.org/t/lld-weak-undefined-symbols-in-vdso-only/86749
* Dynamic -pie: nodynamic-undefined-weak suppresses ABS/GLOB_DAT/JUMP_SLOT

The -pie behavior likely stays stable while -no-pie (`!ctx.arg.isPic` in
`isStaticLinkTimeConstant`) behavior will likely change in the future.
The current default value of ctx.arg.zDynamicUndefined is selected to
prevent behavior changes.

Pull Request: https://github.com/llvm/llvm-project/pull/143831
2025-06-12 19:50:41 -07:00
Ming-Yi Lai
1728405b13
[LLD][ELF][RISCV][Zicfilp] Handle .note.gnu.property sections for Zicfilp/Zicfiss features (#127193)
+ When all relocatable files contain a `.note.gnu.property` section
(with `NT_GNU_PROPERTY_TYPE_0` notes) which contains a
`GNU_PROPERTY_RISCV_FEATURE_1_AND` property in which the
`GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED`/`GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_FUNC_SIG`/`GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_SS`
bit is set:
  + The output file will contain a `.note.gnu.property` section with the
bit set
  + A `PT_GNU_PROPERTY` program header is created to encompass the
`.note.gnu.property` section
+ If `-z zicfilp-unlabeled-report=[warning|error]`/`-z
zicfilp-func-sig-report=[warning|error]`/`-z
zicfiss-report=[warning|error]` is specified, the linker will report a
warning or error for any relocatable file lacking the feature bit

RISC-V Zicfilp/Zicfiss features indicate their adoptions as bits in the
`.note.gnu.property` section of ELF files. This patch enables LLD to
process the information correctly by parsing, checking and merging the
bits from all input ELF files and writing the merged result to the
output ELF file.

These feature bits are encoded as a mask in each input ELF files and
intended to be "and"-ed together to check that all input files support a
particular feature.

For RISC-V Zicfilp features, there are 2 conflicting bits allocated:
`GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED` and
`GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_FUNC_SIG`. They represent the
adoption of the forward edge protection of control-flow integrity with
the "unlabeled" or "func-sig" policy. Since these 2 policies conflicts
with each other, these 2 bits also conflict with each other. This patch
adds the `-z zicfilp-unlabeled-report=[none|warning|error]` and `-z
zicfilp-func-sig-report=[none|warning|error]` commandline options to
make LLD report files that do not have the expected bits toggled on.

For RISC-V Zicfiss feature, there's only one bit allocated:
`GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS`. This bit indicates that the ELF
file supports Zicfiss-based shadow stack. This patch adds the `-z
zicfiss-report=[none|warning|error]` commandline option to make LLD
report files that do not have the expected bit toggled on.

The adoption of the `.note.gnu.property` section for RISC-V targets can
be found in the psABI PR
<https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/417>
(`CFI_LP_UNLABELED` and `CFI_SS`) and PR
<https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/434>
(`CFI_LP_FUNC_SIG`).
2025-06-06 10:32:17 +08:00
Kazu Hirata
19f00c0570
[lld] Remove unused includes (NFC) (#141421) 2025-05-25 10:55:39 -07:00
Fangrui Song
369c409348
Support,lld: Rename misnamed F_no_mmap to F_mmap
`F_no_mmap` introduced by https://reviews.llvm.org/D69294 is misnamed.
It oughts to be `F_mmap`

When the output is a regular file or do not exist,
`--no-mmap-output-file` is the default. Relands #134787 by fixing the
lld option default. Note: changing the default to --map-output-file
would likely fail on llvm-clang-x86_64-sie-win
(https://lab.llvm.org/buildbot/#/builders/46/builds/14847)

Pull Request: https://github.com/llvm/llvm-project/pull/139836
2025-05-14 21:00:49 -07:00
Kazu Hirata
d3e792cec1
[lld] Remove unused local variables (NFC) (#138470) 2025-05-04 14:14:34 -07:00
Daniil Kovalev
8fdebff69d
[PAC][ThinLTO] Fix auth key for GOT entries of function symbols (#131467)
Symtab is first filled with the data from the bitcode file, and all
undefined symbols except TLS ones are `STT_NOTYPE`. Since auth key for a
signed GOT entry depends on the symbol type being `STT_FUNC` or not, we
need to update the symtab after the bitcode is compiled to an ELF object
and update symbol types for function symbols. This patch implements the
described behavior.
2025-04-19 17:40:50 +03:00
Csanád Hajdú
2c1bdd4a08
[LLD][ELF] Allow merging XO and RX sections, and add --[no-]xosegment flag (#132412)
Following from the discussion in #132224, this seems like the best
approach to deal with a mix of XO and RX output sections in the same
binary. This change will also simplify the implementation of the
PURECODE section flag for AArch64.

To control this behaviour, the `--[no-]xosegment` flag is added to LLD
(similarly to `--[no-]rosegment`), which determines whether to allow
merging XO and RX sections in the same segment. The default value is
`--no-xosegment`, which is a breaking change compared to the previous
behaviour.

Release notes are also added, since this will be a breaking change.
2025-04-08 08:47:51 +02:00
Kazu Hirata
1ff74917b5
[lld] Use *Set::insert_range (NFC) (#133565) 2025-03-29 10:29:45 -07:00
Daniil Kovalev
e3f1c464f7
[PAC][lld] Support -z nopac-plt flag (#132973)
Support `-z nopac-plt` so it's possible to cancel previous `-z pac-plt`.
2025-03-28 10:32:56 +03:00
Daniel Thornburgh
074af0f30f
[lld][ELF] Add --why-live flag (inspired by Mach-O) (#127112)
This prints a stack of reasons that symbols that match the given glob(s)
survived GC. It has no effect unless section GC occurs.

This implementation does not require -ffunction-sections or
-fdata-sections to produce readable results, althought it does tend to
work better (as does GC).

Details about the semantics:
- Some chain of liveness reasons is reported; it isn't specified which
chain.
 - A symbol or section may be live:
   - Intrisically (e.g., entry point)
   - Because needed by a live symbol or section
   - (Symbols only) Because part of a section live for another reason
   - (Sections only) Because they contain a live symbol
 - Both global and local symbols (`STB_LOCAL`) are supported.
 - References to symbol + offset are considered to point to:
   - If the referenced symbol is a section (`STT_SECTION`):
- If a sized symbol encloses the referenced offset, the enclosing
symbol.
     - Otherwise, the section itself, generically.
   - Otherwise, the referenced symbol.
2025-03-26 09:56:33 -07:00
Jack Styles
4286f4dcce
[AArch64][GCS][LLD] Introduce -zgcs-report-dynamic Command Line Option (#127787)
When GCS was introduced to LLD, the gcs-report option allowed for a user
to gain information relating to if their relocatable objects supported
the feature. For an executable or shared-library to support GCS, all
relocatable objects must declare that they support GCS.

The gcs-report checks were only done on relocatable object files,
however for a program to enable GCS, the executable and all shared
libraries that it loads must enable GCS. gcs-report-dynamic enables
checks to be performed on all shared objects loaded by LLD, and in cases
where GCS is not supported, a warning or error will be emitted.

It should be noted that only shared files directly passed to LLD are
checked for GCS support. Files that are noted in the `DT_NEEDED` tags
are assumed to have had their GCS support checked when they were
created.

The behaviour of the -zgcs-dynamic-report option matches that of GNU ld.
The behaviour is as follows unless the user explicitly sets the value:
* -zgcs-report=warning or -zgcs-report=error implies
-zgcs-report-dynamic=warning.

This approach avoids inheriting an error level if the user wishes to
continue building a module without rebuilding all the shared libraries.
The same approach was taken for the GNU ld linker, so behaviour is
identical across the toolchains.

This implementation matches the error message and command line interface
used within the GNU ld Linker. See here:

724a8341f6

To support this option being introduced, two other changes are included
as part of this PR. The first converts the -zgcs-report option to
utilise an Enum, opposed to StringRef values. This enables easier
tracking of the value the user defines when inheriting the value for the
gas-report-dynamic option. The second is to parse the Dynamic Objects
program headers to locate the GNU Attribute flag that shows GCS is
supported. This is needed so, when using the gcs-report-dynamic option,
LLD can correctly determine if a dynamic object supports GCS.

---------

Co-authored-by: Fangrui Song <i@maskray.me>
2025-03-15 18:15:05 -07:00
Fangrui Song
90c11ad46f
[ELF] Introduce ReportPolicy to handle -z *-report options. NFC
Use an enum to replace string comparison.

Pull Request: https://github.com/llvm/llvm-project/pull/130715
2025-03-11 09:22:09 -07:00
Csanád Hajdú
9b7b7d6075
[LLD][ELF] Add -z execute-only-report that checks PURECODE section flags (#128883)
`-z execute-only-report` checks that all executable sections have either
the SHF_AARCH64_PURECODE or SHF_ARM_PURECODE section flag set on AArch64
and ARM respectively.
2025-03-01 12:36:56 -08:00
Fangrui Song
7e8a06cfa4 [ELF] Make -z *-report=unknown error message conventional 2025-02-28 23:53:28 -08:00
Fangrui Song
c22d84f7bb [ELF] Refine ctx.arg.exportDynamic condition
--export-dynamic should be a no-op when ctx.hasDynsym is false.

* Drop unneeded ctx.hasDynsym checks.
* Static linking with --export-dynamic does not prevent devirtualization.
2025-02-16 12:12:00 -08:00
Fangrui Song
0a470a9264
[ELF] --package-metadata: support %[0-9a-fA-F][0-9a-fA-F]
(This application-specific option is probably not appropriate as a
linker option (.o file offers more flexibility and decouples JSON
verification from linkers). However, the option has gained some traction
in Linux distributions, with support in GNU ld, gold, and mold.)

GNU ld has supported percent-encoded bytes and extensions like
`%[comma]` since November 2024.  mold supports just percent-encoded
bytes.  To prepare for potential adoption by Ubuntu, let's support
percent-encoded bytes.

Link: https://sourceware.org/bugzilla/show_bug.cgi?id=32003
Link: https://bugs.launchpad.net/ubuntu/+source/dpkg/+bug/2071468

Pull Request: https://github.com/llvm/llvm-project/pull/126396
2025-02-10 09:21:31 -08:00
Fangrui Song
10ed0e4065 [ELF] Reorder target-specific error messaes 2025-02-08 16:36:46 -08:00
Fangrui Song
52fc6ffcda [ELF] Refine isExported/isPreemptible condition
Reland 994cea3f0a2d0caf4d66321ad5a06ab330144d89 after bolt tests no
longer rely on -pie --unresolved-symbols=ignore-all with no input DSO
generating PLT entries.

---

Commit f10441ad003236ef3b9e5415a571d2be0c0ce5ce , while dropping a
special case for isUndefWeak and --no-dynamic-linking, made
--export-dynamic ineffective when -pie is used without any input DSO.

This change restores --export-dynamic and unifies -pie and -pie
--no-dynamic-linker when there is no input DSO.

* -pie with no input DSO suppresses undefined symbols in .dynsym.
  Previously this only appied to -pie --no-dynamic-linker.
* As a side effect, -pie with no input DSO suppresses PLT.
2025-02-05 21:16:00 -08:00
Fangrui Song
6ab034b828
[ELF] Add BPSectionOrderer options (#125559)
Reland #120514 after 2f6e3df08a8b7cd29273980e47310cf09c6fdbd8 fixed
iteration order issue and libstdc++/libc++ differences.

---

Both options instruct the linker to optimize section layout with the
following goals:

* `--bp-compression-sort=[data|function|both]`: Improve Lempel-Ziv
compression by grouping similar sections together, resulting in a
smaller compressed app size.
* `--bp-startup-sort=function --irpgo-profile=<file>`: Utilize a
temporal profile file to reduce page faults during program startup.

The linker determines the section order by considering three groups:

* Function sections ordered according to the temporal profile
(`--irpgo-profile=`), prioritizing early-accessed and frequently
accessed functions.
* Function sections. Sections containing similar functions are placed
together, maximizing compression opportunities.
* Data sections. Similar data sections are placed together.

Within each group, the sections are ordered using the Balanced
Partitioning algorithm.

The linker constructs a bipartite graph with two sets of vertices:
sections and utility vertices.

* For profile-guided function sections:
  + The number of utility vertices is determined by the symbol order
within the profile file.
  + If `--bp-compression-sort-startup-functions` is specified, extra
utility vertices are allocated to prioritize nearby function similarity.
* For sections ordered for compression: Utility vertices are determined
by analyzing k-mers of the section content and relocations.

The call graph profile is disabled during this optimization.

When `--symbol-ordering-file=` is specified, sections described in that
file are placed earlier.

Co-authored-by: Pengying Xu <xpy66swsry@gmail.com>
2025-02-04 09:12:32 -08:00
Hans Wennborg
f3c4b58f4b Revert "[ELF] Add BPSectionOrderer options (#120514)"
The ELF/bp-section-orderer.s test is failing on some buildbots due to
what seems like non-determinism issues, see comments on the original PR
and #125450

Reverting to green the build.

This reverts commit 0154dce8d39d2688b09f4e073fe601099a399365 and
follow-up commits 046dd4b28b9c1a75a96cf63465021ffa9fe1a979 and
c92f20416e6dbbde9790067b80e75ef1ef5d0fa4.
2025-02-03 11:41:23 +01:00
Nikita Popov
b84f7d17f8 Revert "[ELF] Refine isExported/isPreemptible condition"
This reverts commit 994cea3f0a2d0caf4d66321ad5a06ab330144d89.

Try to fix the bolt test failures in pre-merge checks.
2025-02-03 10:01:53 +01:00
Pengying Xu
0154dce8d3
[ELF] Add BPSectionOrderer options (#120514)
Add new ELF linker options for profile-guided section ordering
optimizations:

- `--irpgo-profile=<file>`: Read IRPGO profile data for use with startup
and compression optimizations
- `--bp-startup-sort={none,function}`: Order sections based on profile
data to improve star tup time
- `--bp-compression-sort={none,function,data,both}`: Order sections
using balanced partitioning to improve compressed size
- `--bp-compression-sort-startup-functions`: Additionally optimize
startup functions for compression
- `--verbose-bp-section-orderer`: Print statistics about balanced
partitioning section ordering

Thanks to the @ellishg, @thevinster, and their team's work.

---------

Co-authored-by: Fangrui Song <i@maskray.me>
2025-02-02 17:33:19 -08:00
Fangrui Song
994cea3f0a [ELF] Refine isExported/isPreemptible condition
Commit f10441ad003236ef3b9e5415a571d2be0c0ce5ce dropped a special case
for isUndefWeak and --no-dynamic-linking but also made --export-dynamic
ineffective for static PIE.

This change restores the --export-dynamic behavior and entirely drops
special handling of --no-dynamic-linker:

* -pie with no input DSO, similar to --no-dynamic-linker, suppresses
  undefined symbols in .dynsym

The new behaviors resemble GNU ld more.
2025-01-31 20:37:18 -08:00
Fangrui Song
d6fa74ab3d [ELF] Merge exportDynamic/isExported and remove Symbol::includeInDynsym
Commit 3733ed6f1c6b0eef1e13e175ac81ad309fc0b080 introduced isExported to
cache includeInDynsym. If we don't unnecessarily set isExported for
undefined symbols, exportDynamic/includeInDynsym can be replaced with
isExported.
2025-01-30 22:24:04 -08:00
Fangrui Song
45f538ecba [ELF] ICF: replace includeInDynsym with isExported
Similar to the change to MarkLive.cpp when isExported was introduced.
includeInDynsym might return true even when isExported is false for
statically linked executables.
2025-01-30 19:03:38 -08:00
Fangrui Song
f10441ad00 [ELF] Refine includeInDynsym condition
`includeInDynsym` has a special case for isUndefWeak and
--no-dynamic-linker, which can be removed if we simplify disallow
dynamic symbols for static-pie.

The partition feature reports errors only when a symbol `isExported`.
We need to link in a DSO to trigger the mips error.
2025-01-27 22:02:27 -08:00
Fangrui Song
2a26292388 [ELF] Make isExported accurate early
LTO compilation might define symbols not in the symbol table (e.g.
__emutls_v.x in test/ELF/lto/wrap-unreferenced-before-codegen.test).
These symbols have a false `isExported` until
`demoteSymbolsAndComputeIsPreemptible`. This is usually benign as we do
not reference `isExported` that early.

Ensure that `isExported` is correct early. This helps remove a redundant
`isExported` computation in `demoteSymbolsAndComputeIsPreemptible`.
2025-01-26 20:32:43 -08:00
Fangrui Song
18335f4800 [ELF] Ignore --time-trace if disableOutput
To avoid prevent generating two JSON for LLD_IN_TEST=2 ld.lld
--time-trace.
2025-01-25 18:06:22 -08:00
Fangrui Song
f21c35d54f [ELF] Replace some Fatal with Err
In LLD_IN_TEST=2 mode, when a thread calls Fatal, there will be no
output even if the process exits with code 1. Change a few Fatal to
recoverable Err.
2025-01-25 17:29:28 -08:00
Fangrui Song
a9e92beb25 [ELF] openAuxiliaryFile: open /dev/null if disableOutput and filename is "-"
So that LLD_IN_TEST=2 ld.lld --print-archive-stats=- a.o (and -Map -)
only writes the output once.
2025-01-25 16:54:19 -08:00
Fangrui Song
bcc1e58448 [ELF] Allow --symbol-ordering-file and call graph profile to be used together
Port https://reviews.llvm.org/D117354 from the MachO port.

If both --symbol-ordering-file and call graph profile are present, the
--symbol-ordering-file takes precedence, but the call graph profile is
still used for symbols that don't appear in the order file.

In addition, call graph profile described sections are now ordered
before other sections.
2025-01-05 17:13:23 -08:00
Haohai Wen
2d9d291da0
[LLD] Do not combine cg_profile from obj and ordering file (#121325)
cg_profile in object is from CGProfilePass and it is often inaccurate.
While call-graph-ordering-file is provided by user. It is weird to
aggregate them together especially when call-graph-ordering-file is
accurate enough.
2025-01-05 10:38:14 +08:00
Brad Smith
1b9805c14d
[ELF] Move PT_OPENBSD_NOBTCFI check to readConfigs() (#120678) 2024-12-22 06:11:50 -05:00
Brad Smith
52574b5f40
[ELF] Add support for PT_OPENBSD_NOBTCFI (#120005) 2024-12-19 19:41:42 -05:00
Peter Collingbourne
64da33a589
ELF: Introduce --randomize-section-padding option.
The --randomize-section-padding option randomly inserts padding between
input sections using the given seed. It is intended to be used in A/B
experiments to determine the average effect of a change on program
performance, while controlling for effects such as false sharing in
the cache which may introduce measurement bias. For more details,
see the RFC:

https://discourse.llvm.org/t/rfc-lld-feature-for-controlling-for-code-size-dependent-measurement-bias/83334

Reviewers: smithp35, MaskRay

Reviewed By: MaskRay, smithp35

Pull Request: https://github.com/llvm/llvm-project/pull/117653
2024-12-13 11:52:09 -08:00
Fangrui Song
3733ed6f1c [ELF] Introduce Symbol::isExported to cache includeInDynsym
isExported, intended to replace exportDynamic, is primarily set in two
locations, (a) after parseSymbolVersion and (b) during demoteSymbols.

In the future, we should try removing exportDynamic. Currently,
merging exportDynamic/isExported would cause
riscv-gp.s to fail:

* The first isExported computation considers the undefined symbol exported
* Defined as a linker-synthesized symbol
* isExported remains true, while it should be false
2024-12-08 22:40:14 -08:00
Fangrui Song
712264b83c [ELF] Merge parseSymbolVersion and computeIspreemptible
ICF needs isPreemptible, which can be combined with parseSymbolVersion.
2024-12-08 17:50:17 -08:00
Fangrui Song
1cd627562b [ELF] Remove unneeded Twine in ELFSyncStream 2024-11-24 12:13:02 -08:00
Fangrui Song
eb4d2f24a7 [ELF] Simplify reportMissingFeature. NFC 2024-11-23 22:49:28 -08:00
Fangrui Song
099a52fd2f [ELF] Reorder SectionBase/InputSectionBase members
Move `sectionKind` outside the bitfield and move bss/keepUnique to
InputSectionBase.

* sizeof(InputSection) decreases from 160 to 152 on 64-bit systems.
* The numerous `sectionKind` accesses are faster.
2024-11-23 16:34:21 -08:00
Fangrui Song
5b1b6a62b8 [ELF] Make elfHeader/programHeaders unique_ptr
This removes some SpecificAlloc instantiations, makes lld smaller, and
drops the small memory waste due to the separate BumpPtrAllocator.
2024-11-17 00:25:42 -08:00