Commit Graph

1224 Commits

Author SHA1 Message Date
Vy Nguyen
a992999a00 [lld-macho]Define a flag for adjusting slop scale (#164295)
Co-authored-by: Ellis Hoag <ellis.sparky.hoag@gmail.com>
2025-12-04 23:42:53 +00:00
Fangrui Song
87d37956b3 [lld-macho] Remove cuIndices indirection in UnwindInfoSection. NFC (#170252)
cuEntries was sorted indirectly through a separate `cuIndices`.
Eliminate cuIndices for simplicity.

Linking chromium_framework from `#48001` with `-no_uuid` gives identical
executable using this patch.
2025-12-02 00:18:09 -08:00
John Holdsworth
36bed4d0cd [lld][MachO] Follow-up to use madvise() for threaded file page-in. (#157917)
Further to
https://github.com/llvm/llvm-project/pull/147134#discussion_r2337246489,
switch to use the madvise() api to page in mmap'd files and

1) All new code compiled in #if LLVM_ENABLE_THREADS is set so it can be
seen where the changes were from this PR.
2) The new PR moves to use madvise() instead of the ad-hoc page
referencing code I wrote which should avoid SIGSEGVs if the buffer is
deallocated.
3) A new property SerialBackgroundQueue().stopAllWork to be used to stop
background workers when there is no further call for them. Usually the
background "page-in" threads have completed first but it seems with this
troublesome test this is not always the case and buffers stored in the
static input file cache are being deallocated while being referenced.

---------

Co-authored-by: James Henderson <James.Henderson@sony.com>
2025-11-26 15:14:15 -08:00
Jez Ng
20ca85b69f [lld] macho: Support section branch relocations, including the 1-byte form (#169062)
I noticed that we had a hardcoded value of 4 for the pcrel section
relocations, which seems like an issue given that we recently added
support for 1-byte branch relocations in
https://github.com/llvm/llvm-project/pull/164439. The code included an
assert that the relevant relocation had the BYTE4 attribute, but that is
actually not enough to use a hardcoded value of 4: we need to assert
that the *other* `BYTE<n>` attributes are not set either.

However, since we did not support local branch relocations, that doesn't
seem to have mattered in practice. That said, local branch relocations
can be emitted by compilers, and ld64 does handle the 4-byte version of
them, so I've added support for it here.

ld64 actually seems to reject 1-byte section relocations, so the
questionable code is actually probably fine (minus the incorrect
assert). So we have two options: add an equivalent check in LLD, or just
support 1-byte local branch relocations. Supporting it actually requires
less code, so I've gone with that option here.
2025-11-25 13:54:46 -05:00
Joshua Haberman
58e2dde45f [lld:MachO] Allow independent override of weak symbols aliased via .set (#167825)
Currently, if multiple external weak symbols are defined at the same
address in an object file (e.g., by using the .set assembler directive
to alias them to a single weak variable), ld64.lld treats them as a
single unit. When any one of these symbols is overridden by a strong
definition, all of the original weak symbols resolve to the strong
definition.

This patch changes the behavior in `transplantSymbolsAtOffset`. When a
weak symbol is being replaced by a strong one, only non-external (local)
symbols at the same offset are moved to the new symbol's section. Other
*external* symbols are no longer transplanted.

This allows each external weak symbol to be overridden independently.
This behavior is consistent with Apple's ld-classic, but diverges from
ld-prime in one case, as noted on
https://github.com/llvm/llvm-project/issues/167262 (this discrepancy has
recently been reported to Apple).

### Backward Compatibility

This change alters linker behavior for a specific scenario. The creation
of multiple external weak symbols aliased to the same address via
assembler directives is primarily an advanced technique. It's unlikely
that existing builds rely on the current behavior of all aliases being
overridden together.

If there are concerns, this could be put behind a linker option, but the
new default seems more correct, less surprising, and is consistent with
ld-classic.

### Testing

The new lit test `test/MachO/weak-alias-override.s` verifies this
behavior using llvm-nm.

Fixes #167262
2025-11-21 20:03:40 -05:00
Ellis Hoag
a9a4515b0a [lld][MachO] Read cstring order for non deduped sections (#161879)
https://github.com/llvm/llvm-project/pull/140307 added support for
cstring hashes in the orderfile to layout cstrings in a specific order,
but only when `--deduplicate-strings` is used. This PR supports cstring
ordering when `--no-deduplicate-strings` is used.

1. Create `cStringPriorities`, separate from `priorities`, to hold only
priorities for cstring pieces. This allows us to lookup by hash
directly, instead of first converting to a string. It also fixes a
contrived bug where we want to order a symbol named `CSTR;12345` rather
than a cstring.

2. Rather than calling `buildCStringPriorities()` which always
constructs and returns a vector, we use `forEachStringPiece()` to
efficiently iterate over cstring pieces without creating a new vector if
no cstring is ordered.

3. Create `SymbolPriorityEntry::{get,set}Priority()` helper functions to
simplify code.
2025-11-17 09:38:02 -08:00
Prabhu Rajasekaran
abb8c4ba60 [lld][macho] Fix segfault while processing malformed object file. (#167025)
Ran into a use case where we had a MachO object file with a section
symbol which did not have a section associated with it segfaults during
linking. This patch aims to handle such cases gracefully and avoid the
linker from crashing.

---------

Co-authored-by: Ellis Hoag <ellis.sparky.hoag@gmail.com>
2025-11-11 14:27:03 -08:00
Jez Ng
accec8b92d [lld][macho] Move unwind logic from equalsVariable to equalsConstant (#165325)
Since equalsVariable runs a lot more times, we want to minimize the work
it
needs to do. Anything not dependent on the icfEqClass values should get
hoisted
out.

With this change, ICF runs ~1.7% faster when linking clang.

Benchmarking approach:

cbdr sample -b ~/extract-icf-time.sh ~/old/ld64.lld bin/ld64.lld
--timeout=300s | cbdr analyze -s 95

`extract-icf-time.sh` runs the clang link command with the `--icf=all
--time-trace` flags, then parses out the ICF duration from the resulting
time
trace using `jq`:

jq '{ICF: (.traceEvents[] | select(.name == "Fold Identical Code
Sections") | .dur)}'

Output:

</Users/jezng/extract-icf-time.sh ["/Users/jezng/old/ld64.lld"]>
</Users/jezng/extract-icf-time.sh ["bin/ld64.lld"]> difference (95% CI)
ICF 83678.207 ± 1502.778 82234.751 ± 1290.984 [ -2.0% .. -1.4%]
samples 208 225
2025-11-07 18:56:44 -05:00
Jakub Kuderski
4c21d0cb14 [ADT] Prepare to deprecate variadic StringSwitch::Cases. NFC. (#166020)
Update all uses of variadic `.Cases` to use the initializer list
overload instead. I plan to mark variadic `.Cases` as deprecated in a
followup PR.

For more context, see https://github.com/llvm/llvm-project/pull/163117.
2025-11-02 00:12:33 +00:00
Alexandre Ganea
0b939de1e0 [LLD][MachO] Fix warning when building with latest MSVC
This fixes:
```
[3902/4335] Building CXX object tools\lld\MachO\CMakeFiles\lldMachO.dir\Arch\X86_64.cpp.obj
C:\git\llvm-project\lld\MachO\Arch\X86_64.cpp(107): warning C4334: '<<': result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)
```
2025-11-01 14:58:56 -04:00
Jez Ng
c3bc30bd28 [lld][macho] Error out gracefully when offset is outside literal section (#164660)
We typically shouldn't get this, but when we do (e.g. in #139439) we
should error out gracefully instead of crashing.

Note that we are stricter than ld64 here; ld64 appears to be able to
handle section offsets that point outside literal sections if the end
result is a valid pointer to another section in the input object file.
Supporting this would probably be a pain given our current design, and
it seems like enough of an edge case that it's onot worth it.
2025-11-01 13:44:21 -04:00
Ellis Hoag
fdf4899523 [lld][macho] Ignore cstrings in bp orderer (#165757) 2025-10-31 09:02:05 -07:00
Sertonix
31417ba0de [lld-macho] Link against libatomic when necessary (#144259)
In `Driver.cpp` `std::atomic<uint64_t>` is used which may need
libatomic.

Build failure (if that is of interest):
```
[127/135] Linking CXX shared library lib/liblldMachO.so.20.1
ninja: job failed: : && /usr/lib/ccache/bin/clang++-20 -fPIC -Os -fstack-clash-protection -Wformat -Werror=format-security -D_GLIBCXX_ASSERTIONS=1 -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS=1 -D_LIBCPP_ENABLE_HARDENED_MODE=1 -g -O2 -DNDEBUG -g1 -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections  -Wl,--as-needed,-O1,--sort-common -Wl,-z,defs -Wl,-z,nodelete   -Wl,-rpath-link,/home/user/aports/main/lld20/src/lld-20.1.5.src/build/./lib  -Wl,--gc-sections -shared -Wl,-soname,liblldMachO.so.20.1 -o lib/liblldMachO.so.20.1 MachO/CMakeFiles/lldMachO.dir/Arch/ARM64.cpp.o MachO/CMakeFiles/lldMachO.dir/Arch/ARM64Common.cpp.o MachO/CMakeFiles/lldMachO.dir/Arch/ARM64_32.cpp.o MachO/CMakeFiles/lldMachO.dir/Arch/X86_64.cpp.o MachO/CMakeFiles/lldMachO.dir/ConcatOutputSection.cpp.o MachO/CMakeFiles/lldMachO.dir/Driver.cpp.o MachO/CMakeFiles/lldMachO.dir/DriverUtils.cpp.o MachO/CMakeFiles/lldMachO.dir/Dwarf.cpp.o MachO/CMakeFiles/lldMachO.dir/EhFrame.cpp.o MachO/CMakeFiles/lldMachO.dir/ExportTrie.cpp.o MachO/CMakeFiles/lldMachO.dir/ICF.cpp.o MachO/CMakeFiles/lldMachO.dir/InputFiles.cpp.o MachO/CMakeFiles/lldMachO.dir/InputSection.cpp.o MachO/CMakeFiles/lldMachO.dir/LTO.cpp.o MachO/CMakeFiles/lldMachO.dir/MapFile.cpp.o MachO/CMakeFiles/lldMachO.dir/MarkLive.cpp.o MachO/CMakeFiles/lldMachO.dir/ObjC.cpp.o MachO/CMakeFiles/lldMachO.dir/OutputSection.cpp.o MachO/CMakeFiles/lldMachO.dir/OutputSegment.cpp.o MachO/CMakeFiles/lldMachO.dir/Relocations.cpp.o MachO/CMakeFiles/lldMachO.dir/BPSectionOrderer.cpp.o MachO/CMakeFiles/lldMachO.dir/SectionPriorities.cpp.o MachO/CMakeFiles/lldMachO.dir/Sections.cpp.o MachO/CMakeFiles/lldMachO.dir/SymbolTable.cpp.o MachO/CMakeFiles/lldMachO.dir/Symbols.cpp.o MachO/CMakeFiles/lldMachO.dir/SyntheticSections.cpp.o MachO/CMakeFiles/lldMachO.dir/Target.cpp.o MachO/CMakeFiles/lldMachO.dir/UnwindInfoSection.cpp.o MachO/CMakeFiles/lldMachO.dir/Writer.cpp.o -L/usr/lib/llvm20/lib -Wl,-rpath,"\$ORIGIN/../lib:/usr/lib/llvm20/lib:/home/user/aports/main/lld20/src/lld-20.1.5.src/build/lib:"  lib/liblldCommon.so.20.1  /usr/lib/llvm20/lib/libLLVM.so.20.1 && :
/usr/lib/gcc/powerpc-alpine-linux-musl/14.3.0/../../../../powerpc-alpine-linux-musl/bin/ld: MachO/CMakeFiles/lldMachO.dir/Driver.cpp.o: in function `handleExplicitExports()':
/usr/lib/gcc/powerpc-alpine-linux-musl/14.3.0/../../../../include/c++/14.3.0/bits/atomic_base.h:501:(.text._ZL21handleExplicitExportsv+0xb8): undefined reference to `__atomic_load_8'
/usr/lib/gcc/powerpc-alpine-linux-musl/14.3.0/../../../../powerpc-alpine-linux-musl/bin/ld: /usr/lib/gcc/powerpc-alpine-linux-musl/14.3.0/../../../../include/c++/14.3.0/bits/atomic_base.h:501:(.text._ZL21handleExplicitExportsv+0x180): undefined reference to `__atomic_load_8'
/usr/lib/gcc/powerpc-alpine-linux-musl/14.3.0/../../../../powerpc-alpine-linux-musl/bin/ld: MachO/CMakeFiles/lldMachO.dir/Driver.cpp.o: in function `void llvm::function_ref<void (unsigned int)>::callback_fn<llvm::parallelForEach<lld::macho::Symbol* const*, handleExplicitExports()::$_0>(lld::macho::Symbol* const*, lld::macho::Symbol* const*, handleExplicitExports()::$_0)::{lambda(unsigned int)#1}>(int, unsigned int)':
/usr/lib/gcc/powerpc-alpine-linux-musl/14.3.0/../../../../include/c++/14.3.0/bits/atomic_base.h:631:(.text._ZN4llvm12function_refIFvjEE11callback_fnIZNS_15parallelForEachIPKPN3lld5macho6SymbolEZL21handleExplicitExportsvE3$_0EEvT_SC_T0_EUljE_EEvij+0xd4): undefined reference to `__atomic_fetch_add_8'
clang++-20: error: linker command failed with exit code 1 (use -v to see invocation)
```

CC @int3 @gkmhub @smeenai

Similar to
f0b451c77f
2025-10-27 23:19:29 +00:00
Ellis Hoag
60ab8c8967 [lld][macho] Use reloc length correctly in hash computation (#165287)
`Reloc::length` actually encodes the log2 of the length. Thanks @int3
for pointing this out in
https://github.com/llvm/llvm-project/issues/160894#issuecomment-3416250179.

This code computes hashes of relocations. With the correct length, the
hashes should more accurately represent the relocation. In my testing of
some large binaries, the compressed size change is negligable.
2025-10-27 14:48:04 -07:00
Jez Ng
eb7386033a [lld][macho] Support 1-byte branch relocs for x86_64 (#164439) 2025-10-27 08:55:05 -07:00
David Spickett
f5885de2cd [lld] Reject --read-workers when lld is built without thread support (#163925)
Also expand the #ifdef to remove unused code in this configuration. As
suggested in
https://github.com/llvm/llvm-project/pull/147134#issuecomment-3328612158.

I have also:
* Expanded the error message to explain why it's not allowed.
* Added a test for the error.
* Marked the original test as unsupported when threads are disabled.

Fixes issues we have had on Armv8 with threading disabled where this
test would crash every so often.

This change will hopefully be superseded by #157917, but that has been
in review a long time and I want to make the bot stable again.

I could just disable the test, but I'd like lld to function properly in
general in the meantime too.

Co-authored-by: John Holdsworth <github@johnholdsworth.com>
2025-10-17 08:35:23 +00:00
Kazu Hirata
ffca377c66 [lld] Replace LLVM_ATTRIBUTE_UNUSED with [[maybe_unused]] (NFC) (#163701)
This patch replaces LLVM_ATTRIBUTE_UNUSED with [[maybe_unused]],
introduced as part of C++17.
2025-10-16 06:52:20 -07:00
Prabhu Rajasekaran
fdbd17d1fb [llvm] Add subcommand support for OptTable (#155026)
Implement support for `subcommands` in OptTable to attain feature parity
with `cl`.

Design overview:
https://discourse.llvm.org/t/subcommand-feature-support-in-llvm-opttable/88098

Issue: https://github.com/llvm/llvm-project/issues/108307
2025-10-06 12:11:00 -07:00
Ellis Hoag
d0e98909d2 [lld][MachO] Tail merge strings (#161262)
Add the flag `--tail-merge-strings` to enable tail merging of cstrings.
For example, if we have strings `mystring\0` and `ring\0`, we could
place `mystring\0` at address `0x1000` and `ring\0` at address `0x1004`
and have them share the same underlying data.

It turns out that many ObjC method names can be tail merged. For
example, `error:` and `doFoo:error:`. On a large iOS binary, we saw
nearly a 15% size improvement in the `__TEXT__objc_methname` section and
negligible impact on link time.
```
$ bloaty --domain=vm merged.o.stripped -- base.o.stripped
     VM SIZE
 --------------
   +95% +5.85Ki    [__TEXT]
  -2.4%  -239Ki    __TEXT,__cstring
 -14.5%  -710Ki    __TEXT,__objc_methname
  -1.0%  -944Ki    TOTAL
```

Tail merging for MachO was originally removed in
7c269db779.
The previous implementation used `StringTableBuilder`, but that was
removed in
4308f031cd
to ensure deduplicated strings are aligned correctly. This
implementation ensures that tail merged strings are also aligned
correctly.

Special thanks to nocchijiang for pointing this out in
https://github.com/llvm/llvm-project/pull/158720#issuecomment-3310416030.

Depends on https://github.com/llvm/llvm-project/pull/161253.
2025-10-03 16:38:10 +00:00
Ellis Hoag
dd43a79ed0 [lld][MachO] Use llvm::Align and remove StringOffset type (#161253)
Use `llvm::Align` instead of directly storing the shift amount for
clarity. Also remove the `DeduplicatedCStringSection::StringOffset` in
favor of simply storing the `uint64_t` offset since `trailingZeros` is
not used outside of `finalizeContents()`. These two changes allow us to
refactor `finalizeContents()`.


No function change intended.

Depends on https://github.com/llvm/llvm-project/pull/161241.
2025-09-30 16:57:07 +00:00
Ellis Hoag
ccf1fb00fe [lld][macho][NFC] Factor count zeros into helper function (#161241)
Move `llvm::countr_zero()` into a helper function to reduce code
duplication between `CStringSection` and `DeduplicatedCStringSection`.
More importantly, this moves a giant comment to that helper function
since it pertains to both classes.
2025-09-30 09:44:23 -07:00
Ellis Hoag
727ce02653 [lld][macho] Rename test to fix spelling (#160938)
The test name had a typo from
https://github.com/llvm/llvm-project/pull/140307. Fix it.

I realized cstring ordering is not supported when string deduplication
is turned off. We could easily call `buildCStringPriorities()` in
`CStringSection::finalizeContents()`, but I worry it might harm build
performance since it creates multiple vectors and searches though maps.
If users are not deduplicating strings, they probably won't care to
order them, but it would be good to support this.
2025-09-26 17:21:21 -07:00
Ellis Hoag
fc8f54d496 [LLD][MachO] Option to emit separate cstring sections (#158720)
Add the `--{no-}separate-cstring-literal-sections` option to emit
cstring literals into sections defined by their section name. This
allows for changes like https://github.com/swiftlang/swift/pull/84300
and https://github.com/swiftlang/swift/pull/84236 to actually have an
affect. The default behavior has not changed.

The reason this is useful is because strings in different sections might
have different access patterns at runtime. By splitting these strings
into separate sections, we may reduce the number of page faults during
startup. For example, the ObjC runtime accesses all strings in
`__objc_classname` before main.
2025-09-22 11:23:58 -07:00
Alexandre Ganea
105fc90b6b [LLD][MachO] Silence warning when building with MSVC
Silence the following warning with latest MSVC:
```
C:\git\llvm-project\lld\MachO\Driver.cpp(358): warning C4189: 't': local variable is initialized but not referenced
```
2025-09-21 11:05:50 -04:00
Nico Weber
ddb2e34334 [lld/mac] Fix comment typos to cycle bots 2025-09-11 13:51:00 -04:00
Kazu Hirata
ae78957112 [Support] Rename CTLog2 to ConstantLog2 in MathExtras.h (#158006)
This patch renames CTLog2 to ConstantLog2 for readability.

This patch provides a forwarder under LLVM_DEPRECATED because CTLog2
is used downstream.
2025-09-11 07:54:27 -07:00
Frederik Harwath
e75f054d18 [lld][MachO] Silence warnings about --read-workers parsing (#156608)
The parsing of the --read-workers argument v is implemented like this:

  unsigned threads = 0
  if (!llvm::to_integer(v, threads, 0) || threads < 0) {
  ...

As reported by a compiler warning, the value of the "threads < 0"
expession is never going to be true. It could only evaluate to true if v
represents a negative number, but in this case llvm::to_integer returns
false since threads is unsigned and hence the second operand of the ||
operator will not be evaluated.

This patch removes the useless || operand to silence compiler warnings.
Since I had to first find out if --read-workers=0 is valid or not (it is),
I also added a test to document the valid values for the option and I adjusted
the error message on invalid values to clearly state that 0 is valid.
2025-09-03 18:02:12 +02:00
Daniel Rodríguez Troitiño
cbf10bcbb3 [lld-macho] Avoid infinite recursion when parsing corrupted export tries (#152569)
If an export trie is encoded incorrectly, and one of the children
offsets points back to one of the nodes earlier in the serialization,
the current code will end up in an infinite recursion, and eventually
fail exhausting the available memory.

The failure can be avoided if, before recursing, one checks that the
offset is valid, that is, that the offset is beyond the current
position. This is similar to a check done by llvm-objdump which reports
the trie being corrupted.
2025-08-29 17:08:35 -07:00
John Holdsworth
2b2428794c [lld][MachO] Multi-threaded preload of input files into memory (#147134)
This PR adds a new option to lld `--read-workers=20` that defers all
disk I/o then performs it multithreaded so the process is never stalled
waiting for the I/o of the page-in of mapped input files. This results
in a saving of elapsed time. For a large link (iterating on Chromium)
these are the baseline linkage times saving a single file and rebuilding
(seconds inside Xcode):

26.01, 25.84, 26.15, 26.03, 27.10, 25.90, 25.86, 25.81, 25.80, 25.87

With the proposed code change, and using the `--read-workers=20` option,
the linking times reduce to the following:

21.13, 20.35, 20.01, 20.01, 20.30, 20.39, 19.97, 20.23, 20.17, 20.23

The secret sauce is in the new function `multiThreadedPageIn()` in
Driver.cpp. Without the option lld behaves as before.

Edit: with subsequent commits I've taken this novel i/o approach to its
full potential. Latest linking times are now:

13.2, 11.9, 12.12, 12.01, 11.99, 13.11, 11.93, 11.95, 12.18, 11.97

Chrome is still linking and running so it doesn't look like anything is
broken. Despite being multi-threaded all memory access is readonly and
the original code paths are not changed. All that is happening is the
system is being asked to proactively page in files rather than waiting
for processing to page fault which would otherwise stall the process.

---------

Co-authored-by: Daniel Rodríguez Troitiño <drodrigueztroitino@gmail.com>
Co-authored-by: Ellis Hoag <ellis.sparky.hoag@gmail.com>
2025-08-27 11:11:22 -07:00
Daniel Rodríguez Troitiño
9234066476 [lld-macho] Process OSO prefix only textually in both input and output (#152063)
The processing of `-oso_prefix` uses `llvm::sys::fs::real_path` from the
user value, but it is later tried to be matched with the result of
`make_absolute`. While `real_path` resolves special symbols like `.`,
`..` and `~`, and resolves symlinks along the path, `make_absolute` does
neither, causing an incompatibility in some situations.

In macOS, temporary directories would normally be reported as
`/var/folders/<random>`, but `/var` is in fact a symlink to
`private/var`. If own is working on a temporary directory and uses
`-oso_prefix .`, it will be expanded to `/private/var/folder/<random>`,
while `make_absolute` will expand to `/var/folder/<random>` instead, and
`-oso_prefix` will fail to remove the prefix from the `N_OSO` entries,
leaving absolute paths to the temporary directory in the resulting file.
This would happen in any situation in which the working directory
includes a symlink, not only in temporary directories.

One can change the usage of `make_absolute` to use `real_path` as well,
but `real_path` will mean checking the file system for each `N_OSO`
entry. The other solution is stop using `real_path` when processing
`-oso_prefix` and manually expand an input of `.` like `make_absolute`
will do.

This second option is the one implemented here, since it is the closest
to the visible behaviour of ld64 (like the removed comment notes), so it
is the better one for compatibility. This means that a test that checked
the usage of the tilde as `-oso_prefix` needs to be removed (since it
was done by using `real_path`), and two new tests are provided checking
that symlinks do not affect the result. The second test checks a change
in behaviour, in which if one provides the input files with a prefix of
`./`, even when using `-oso_prefix .` because the matching is textual,
the `./` prefix will stay in the `N_OSO` entries. This matches the
observed behaviour of ld64.
2025-08-07 13:11:18 -07:00
Daniel Bertalan
43f10639a1 [lld-macho] Enable Linker Optimization Hints pass for arm64_32 (#148964)
The backend emits `.loh` directives for arm64_32 as well. Our pass
already handles 32-bit pointer loads correctly (there was an extraneous
sanity check for 8-byte pointer sizes, I removed that here), so we can
enable them for all arm64 subtargets, including our upcoming arm64e
support.
2025-07-16 21:29:48 +02:00
Daniel Bertalan
fb3972dd06 [lld-macho] Move Linker Optimization Hints pass to a separate file
Moving it away from the arm64 `TargetInfo` class will let us enable it
more easily for arm64_32 and the soon-to-be-added arm64e target as well.

This is the NFC part of #148964
2025-07-16 21:13:54 +02:00
Richard Howell
35f6d91720 [lld] check cache in loadDylib before real_path (#143595) 2025-06-17 07:18:50 -07:00
Kazu Hirata
d78eec864c [lld] Use range-based for loops (NFC) (#144251) 2025-06-15 10:32:45 -07:00
Kazu Hirata
c1d21f4434 [lld] Use std::tie to implement comparison operators (NFC) (#143726)
std::tie facilitates lexicographical comparisons through std::tuple's
built-in operator< and operator>.
2025-06-11 12:50:19 -07:00
Hans Wennborg
c34351c92a Revert "[lld] check cache before real_path in loadDylib (#140791)"
This is causing use-after-frees due to references getting invalidating
after the loadedDylibs map grows, see comments on the PR.

This reverts commit 475a8a47ea.
2025-06-10 15:29:18 +02:00
SharonXSharon
40933fd410 [lld][macho] Support order cstrings with -order_file (#140307)
Expand the `-order_file` also accept cstrings to order.
The purpose is to order hot cstrings for performance (implemented in
this diff), and then later on we can also order cold cstrings for
compression size win.

Due to the speciality of cstrings, there's no way to pass in symbol
names in the order file as the existing -order_file, so we expect `<hash
of cstring literal content>` to represent/identify each cstring.

```
// An order file has one entry per line, in the following format:
  //
  //   <cpu>:<object file>:[<symbol name> | CStringEntryPrefix <cstring hash>]
  //
  // <cpu> and <object file> are optional.
  // If not specified, then that entry tries to match either,
  //
  // 1) any symbol of the <symbol name>;
  // Parsing this format is not quite straightforward because the symbol name
  // itself can contain colons, so when encountering a colon, we consider the
  // preceding characters to decide if it can be a valid CPU type or file path.
  // If a symbol is matched by multiple entries, then it takes the
  // lowest-ordered entry (the one nearest to the front of the list.)
  //
  // or 2) any cstring literal with the given hash, if the entry has the
  // CStringEntryPrefix prefix defined below in the file. <cstring hash> is the
  // hash of cstring literal content.
  //
  // Cstring literals are not symbolized, we can't identify them by name
  // However, cstrings are deduplicated, hence unique, so we use the hash of
  // the content of cstring literals to identify them and assign priority to it.
  // We use the same hash as used in StringPiece, i.e. 31 bit:
  // xxh3_64bits(string) & 0x7fffffff
  //
```

The ordering of cstring has to happen during/before the finalizing of
the cstring section content in the `finalizeContents()` function, which
happens before the writer is run

---------

Co-authored-by: Sharon Xu <sharonxu@fb.com>
2025-06-05 10:24:54 -07:00
SharonXSharon
79cc728b77 [lld][macho] Strip .__uniq. and .llvm. hashes in -order_file (#140670)
```
/// Symbols can be appended with "(.__uniq.xxxx)?.llvm.yyyy" where "xxxx" and
/// "yyyy" are numbers that could change between builds. We need to use the root
/// symbol name before this suffix so these symbols can be matched with profiles
/// which may have different suffixes.
```
Just like what we are doing in BP,
https://github.com/llvm/llvm-project/blob/main/lld/MachO/BPSectionOrderer.cpp#L127

the patch removes the suffixes when parsing the order file and getting
the symbol priority to have a better symbol match.

---------

Co-authored-by: Sharon Xu <sharonxu@fb.com>
Co-authored-by: Ellis Hoag <ellis.sparky.hoag@gmail.com>
2025-06-03 10:12:36 -07:00
Richard Howell
475a8a47ea [lld] check cache before real_path in loadDylib (#140791) 2025-05-29 09:26:07 -07:00
Teresa Johnson
892bfa9366 [lld-macho] Qualify Reloc with macho namespace (NFC) (#141692)
With an upcoming change to llvm/ProfileData headers, this file ends up
with both llvm::Reloc in scope as well as the lld::macho::Reloc type
intended for use here. Qualify the use in this file with the intended
namespace to avoid compilation errors.
2025-05-27 17:05:21 -07:00
Ellis Hoag
b5588ce746 [LLD][MachO][NFC] Refactor LOH code (#141153)
In `applyAdrpAddLdr()` we make a transformation that is identical to the
one in `applyAdrpAdd()`, so lets reuse that code. Also refactor
`forEachHint()` to use more `ArrayRef` and move around some lines for
consistancy.
2025-05-27 08:24:25 -07:00
Kazu Hirata
19f00c0570 [lld] Remove unused includes (NFC) (#141421) 2025-05-25 10:55:39 -07:00
Kazu Hirata
1f3b6d851d [lld] Use llvm::less_second (NFC) (#141349) 2025-05-24 09:37:23 -07:00
Kazu Hirata
407df069ec [lld] Use llvm::any_of (NFC) (#141316) 2025-05-23 23:59:45 -07:00
Max Graey
8aaac80ddd [NFC] Use more isa and isa_and_nonnull instead dyn_cast for predicates (#137393)
Also fix some typos in comments

---------

Co-authored-by: Mehdi Amini <joker.eph@gmail.com>
2025-05-13 22:34:42 +08:00
Richard Howell
58addfbbcc [lld] handle re-exports for full framework paths (#137989)
Framework load paths can be either the top level framework name, or
subpaths of the framework bundle pointing to specific framework binary
versions. Extend the framework lookup logic to handle the latter case.
2025-05-02 09:15:53 -07:00
alx32
deae5eef71 [lld-macho] Fix branch extension logic compatibility with __objc_stubs (#137913)
Enhance branch extension logic to handle __objc_stubs identically to
__stubs

The branch extension algorithm currently has specific handling for the
`__stubs` section:
1. It ensures all `__stubs` content is directly reachable via branches
from the text section.
2. It calculates the latest text section address that might require
thunks to reach the end of `__stubs`.

The `__objc_stubs` section requires precisely the same handling due to
its similar nature, but this was not implemented.

This commit generalizes the existing logic so it applies consistently to
both the `__stubs` and `__objc_stubs` sections, ensuring correct
reachability and thunk placement for both. Without this change it's
possible to get relocation errors during linking in scenarios where the
`__objc_stubs` section is large enough.
2025-05-01 10:29:07 -07:00
Ellis Hoag
efef83e11d [lld][InstrProf] Skip BP ordering input sections with null data (#137906)
In MachO, `.bss` `isec`s have a length, but point to null. This causes
Balanced Partitioning to crash on these inputs.

This code was in the original implementation, but was removed in
https://github.com/llvm/llvm-project/pull/124482/files#diff-b2aac8833d29d297ae5ada1b36eb4e88f53691fd91df954c24e0c264f3131d4aL27
2025-04-29 17:15:55 -07:00
Richard Howell
e07307b534 [lld] resolve dylib paths before caching (#137649)
When loading frameworks it is possible to have load commands for the
same framework through symlinks and the real path. To avoid loading
these multiple times find the real path before checking the dylib cache.
2025-04-29 11:21:04 -07:00
Vy Nguyen
c5f61908a7 [lld-macho]Fix bug in finding "chained" re-exported libs. (#135241)
Details:
When we have the following scenario:

- lib_a re-exports lib_b
- lib_b re-exports @rpath/lib_c
  + lib_b contains LC_RPATH

Previously, lld-macho cannot find lib_c because it was attempting to
resolve the '@rpath' from lib_b (which had no LC_RPATH defined). The
change here is to also consider all the LC_RPATH rom lib_b when trying
to find lib_c.

Inspired by real-life example when linking with
libXCTestSwiftSupport.dylib (which re-exports XCTest, which re-exports
XCTestCore)
2025-04-28 13:16:07 -04:00