303 Commits

Author SHA1 Message Date
Kazu Hirata
d78eec864c
[lld] Use range-based for loops (NFC) (#144251) 2025-06-15 10:32:45 -07:00
Kazu Hirata
19f00c0570
[lld] Remove unused includes (NFC) (#141421) 2025-05-25 10:55:39 -07:00
Sam Clegg
afdc4b1526
[lld][WebAssembly] Don't mark --start-lib/--end-lib files as live (#137714)
Without this change files in `--start-lib`/`--end-lib` groups were being
marked as live, which means there static constructors were being
included in the link.
2025-04-28 15:30:35 -07:00
Anutosh Bhat
9cbbb74d37
[wasm-ld] Refactor WasmSym from static globals to per-link context (#134970)
Towards
#https://github.com/llvm/llvm-project/issues/134809#issuecomment-2787206873

This change moves WasmSym from a static global struct to an instance
owned by Ctx, allowing it to be reset cleanly between linker runs. This
enables safe support for multiple invocations of wasm-ld within the same
process

Changes done 

- Converted WasmSym from a static struct to a regular struct with
instance members.

- Added a std::unique_ptr<WasmSym> wasmSym field inside Ctx.

- Reset wasmSym in Ctx::reset() to clear state between links.

- Replaced all WasmSym:: references with ctx.wasmSym->.

- Removed global symbol definitions from Symbols.cpp that are no longer
needed.

Clearing wasmSym in ctx.reset() ensures a clean slate for each link
invocation, preventing symbol leakage across runs—critical when using
wasm-ld/lld as a reentrant library where global state can cause subtle,
hard-to-debug errors.

---------

Co-authored-by: Vassil Vassilev <v.g.vassilev@gmail.com>
2025-04-25 07:35:00 -07:00
Nick Fitzgerald
6018930ef1
[lld][WebAssembly] Support for the custom-page-sizes WebAssembly proposal (#128942)
This commit adds support for WebAssembly's custom-page-sizes proposal to
`wasm-ld`. An overview of the proposal can be found
[here](https://github.com/WebAssembly/custom-page-sizes/blob/main/proposals/custom-page-sizes/Overview.md).
In a sentence, it allows customizing a Wasm memory's page size, enabling
Wasm to target environments with less than 64KiB of memory (the default
Wasm page size) available for Wasm memories.

This commit contains the following:

* Adds a `--page-size=N` CLI flag to `wasm-ld` for configuring the
linked Wasm binary's linear memory's page size.

* When the page size is configured to a non-default value, then the
final Wasm binary will use the encodings defined in the
custom-page-sizes proposal to declare the linear memory's page size.

* Defines a `__wasm_first_page_end` symbol, whose address points to the
first page in the Wasm linear memory, a.k.a. is the Wasm memory's page
size. This allows writing code that is compatible with any page size,
and doesn't require re-compiling its object code. At the same time,
because it just lowers to a constant rather than a memory access or
something, it enables link-time optimization.

* Adds tests for these new features.

r? @sbc100 

cc @sunfishcode
2025-03-04 09:39:30 -08:00
Hood Chatham
80ea31ccd7
[lld][WebAssembly] Add RUNTIME_PATH support to wasm-ld (#129050)
This finishes adding RPATH support for WebAssembly.

See my previous PR which added RPATH support to yaml2obj and obj2yaml:
https://github.com/llvm/llvm-project/pull/126080
See corresponding update to the WebAssembly/tool-conventions repo on
dynamic linking:
https://github.com/WebAssembly/tool-conventions/pull/246
2025-02-28 11:12:52 -08:00
Fangrui Song
3792b36234
[lld][WebAssembly] Replace config-> with ctx.arg.
Change the global variable reference to a member access of another
variable `ctx`. In the future, we may pass through `ctx` to functions to
eliminate global variables.

Pull Request: https://github.com/llvm/llvm-project/pull/119835
2025-01-02 17:08:18 -08:00
Fangrui Song
a222d00c66
[lld][WebAssembly] Introduce Ctx::arg
and forward it to LinkerDriver's ctor so that some uses of the global
`config` can be dropped. This is similar to how the ELF port
migrates away from the global `config`.

Pull Request: https://github.com/llvm/llvm-project/pull/119829
2024-12-13 19:14:32 -08:00
Chandler Carruth
dd647e3e60
Rework the Option library to reduce dynamic relocations (#119198)
Apologies for the large change, I looked for ways to break this up and
all of the ones I saw added real complexity. This change focuses on the
option's prefixed names and the array of prefixes. These are present in
every option and the dominant source of dynamic relocations for PIE or
PIC users of LLVM and Clang tooling. In some cases, 100s or 1000s of
them for the Clang driver which has a huge number of options.

This PR addresses this by building a string table and a prefixes table
that can be referenced with indices rather than pointers that require
dynamic relocations. This removes almost 7k dynmaic relocations from the
`clang` binary, roughly 8% of the remaining dynmaic relocations outside
of vtables. For busy-boxing use cases where many different option tables
are linked into the same binary, the savings add up a bit more.

The string table is a straightforward mechanism, but the prefixes
required some subtlety. They are encoded in a Pascal-string fashion with
a size followed by a sequence of offsets. This works relatively well for
the small realistic prefixes arrays in use.

Lots of code has to change in order to land this though: both all the
option library code has to be updated to use the string table and
prefixes table, and all the users of the options library have to be
updated to correctly instantiate the objects.

Some follow-up patches in the works to provide an abstraction for this
style of code, and to start using the same technique for some of the
other strings here now that the infrastructure is in place.
2024-12-11 15:44:44 -08:00
Anutosh Bhat
52aff97f40
[lld][wasm] Clear lazyBitcodeFiles while resetting context (#118440)
Hi @sbc100 

I was looking into a use case involving the link function (which got my
attention to reset).

I see that `lazyBitcodeFiles` variable was introduced here
https://github.com/llvm/llvm-project/pull/114327 but I don't see it
being reset while destroying the context eventually. Hopefully this
should be the correct way to address it.
2024-12-03 22:18:43 -08:00
Fangrui Song
fcb6b132fa [lld] Use context-aware outs() and errs()
For COFF and ELF that are mostly free of global states, lld::errs() and
lld::outs() should not be used. This migration change allows us to
remove lld::errs, which uses the global errorHandler().
2024-11-16 21:37:34 -08:00
Sam Clegg
b70eb86313
[lld][WebAssemlby] Implement --thinlto-object-suffix-replace/--thinlto-prefix-replace (#114625)
Fixes: #79604
2024-11-08 16:48:30 -08:00
Sam Clegg
9a450a0096
[lld][WebAssembly] Implement various thinlto flags (#114327)
The changes in this PR (both in the code and the tests) are largely
copied directly from the ELF linker.

Partial fix for #79604.
2024-11-01 16:34:06 -07:00
Sam Clegg
0764e55c91
[lld][WebAssembly] Improve -v/-V/--version flag compat (#113204)
Fixes: #112836
2024-10-22 10:47:57 -07:00
YAMAMOTO Takashi
a5cd5d351d
[lld][WebAssembly] Avoid emitting empty __wasm_apply_data_relocs function (#109249)
Instead of always generating __wasm_apply_data_relocs when relevant
options like -pie and -shared are specified, generate it only when the
relevant relocations are actually necessary.

Note: omitting empty __wasm_apply_data_relocs is not a problem because
the export is optional in the spec (DynamicLinking.md) and all runtime
linker implementations I'm aware of implement it that way. (emscripten,
toywasm, wasm-tools)

Motivations:

* This possibly reduces the module size

* This is also a preparation to fix
https://github.com/llvm/llvm-project/issues/107387, for which it isn't
obvious if we need these relocations at the time of
createSyntheticSymbols. (unless we introduce a new explicit option like
--non-pie-dynamic-link.)
2024-09-30 17:17:58 -07:00
Sam Clegg
be770edee5
[lld][WebAssembly] Reject shared libraries when -static/-Bstatic is used (#108263)
This matches the behaviour of GNU ld and the ELF version of lld.
2024-09-11 11:22:46 -07:00
mzukovec
0367305af8
[lld][WebAssembly] Add allow-multiple-definition flag (#97699)
Add `allow-multiple-definition` flag to `wasm-ld`. This follows the ELF
linker logic. In case of duplication, the first symbol met is used.

This PR resolves the #97543
2024-09-04 08:50:10 -07:00
Sam Clegg
e7efa323be
[lld][WebAssembly] Fix stub library deps causing LTO archive members to be required post-LTO (#101894)
Fixes: https://github.com/emscripten-core/emscripten/issues/16836
2024-08-06 15:12:13 -07:00
Joseph Huber
615b7eeaa9 Reapply "[LLVM][LTO] Factor out RTLib calls and allow them to be dropped (#98512)"
This reverts commit 740161a9b98c9920dedf1852b5f1c94d0a683af5.

I moved the `ISD` dependencies into the CodeGen portion of the handling,
it's a little awkward but it's the easiest solution I can think of for
now.
2024-07-20 09:29:31 -05:00
NAKAMURA Takumi
740161a9b9 Revert "[LLVM][LTO] Factor out RTLib calls and allow them to be dropped (#98512)"
This reverts commit c05126bdfc3b02daa37d11056fa43db1a6cdef69.
(llvmorg-19-init-17714-gc05126bdfc3b)
See #99610
2024-07-20 12:36:57 +09:00
Joseph Huber
c05126bdfc
[LLVM][LTO] Factor out RTLib calls and allow them to be dropped (#98512)
Summary:
The LTO pass and LLD linker have logic in them that forces extraction
and prevent internalization of needed runtime calls. However, these
currently take all RTLibcalls into account, even if the target does not
support them. The target opts-out of a libcall if it sets its name to
nullptr. This patch pulls this logic out into a class in the header so
that LTO / lld can use it to determine if a symbol actually needs to be
kept.

This is important for targets like AMDGPU that want to be able to use
`lld` to perform the final link step, but does not want the overhead of
uncalled functions. (This adds like a second to the link time trivially)
2024-07-16 06:22:09 -05:00
Sam Clegg
22b7b84860
[lld][WebAssembly] Report undefined symbols in -shared/-pie builds (#75242)
Previously we would ignore all undefined symbols when using
`-shared` or `-pie`. All undefined symbols would be treated as imports
regardless of whether those symbols we defined in any shared library.
With this change we now track symbol in shared libraries and report
undefined symbols in the main program by default.
The old behavior is still available via the
`--unresolved-symbols=import-dynamic` command line flag.

This rationale for allowing this type of breaking change is that `-pie`
and `-shared` are both still experimental will warn as such, unless
`--experimental-pic` is passed.

As part of this change the linker now models shared library symbols
via new SharedFunctionSymbol and SharedDataSymbol types.

I've also added a new `--no-shlib-sigcheck` option that bypassed the
checking of functions signature in shared libraries. This is
specifically required by emscripten the case where the imports/exports
of shared libraries have been modified by via JS type legalization (this
is only needed when targeting old JS engines where bigint is not yet
available                                         

See https://github.com/emscripten-core/emscripten/issues/18198
2024-07-12 13:26:52 -07:00
Sam Clegg
afb3f7e0b7
[lld][WebAssembly] Handle stub symbol dependencies when an explicit import name is used (#80169) 2024-06-20 09:48:25 -07:00
YAMAMOTO Takashi
2b6c6bb498
[lld][WebAssembly] Always search *.so for -Bdynamic (#84288)
Search *.so libraries regardless of -pie to make it a bit more
straightforward to build non-pie dynamic-linked executables.

Flip the default to -Bstatic (unless -pie or -shared is specified) as I
think it's what most users expect for the default as of today.
The assumption here is that, because dynamic-linking is not widely used
for WebAssembly, the most users do not specify -Bdynamic or -Bstatic,
expecting static link.
Although the recent wasi-sdk ships *.so files, there are not many wasm
runtimes providing the support of dynamic-linking. (only emscripten and
toywasm as far as i know.)
2024-06-11 16:45:53 -07:00
Sam Clegg
39d32b238d
[WebAssembly] Use 64-bit table when targeting wasm64 (#92042)
See https://github.com/WebAssembly/memory64/issues/51
2024-05-23 18:25:58 -07:00
David Spickett
aff197ff21 Reland "[flang][clang] Add Visibility specific help text for options (#81869)"
This reverts commit 67d20412b448533c77f54ac7a1e5d0775d273729.

This includes fixes for clanginstallapi.
2024-04-05 08:27:59 +00:00
David Spickett
67d20412b4 Revert "[flang][clang] Add Visibility specific help text for options (#81869)"
This reverts commit 7e958f64efea6cb824e96ace51e021afbc150922.

Failing on multiple bots.
2024-04-05 08:15:35 +00:00
David Spickett
7e958f64ef
[flang][clang] Add Visibility specific help text for options (#81869)
And use it to print the correct default OpenMP version for flang and
flang -fc1.

This change adds an optional `HelpTextsForVariants` to options. This
allows you to change the help text that gets shown in documentation and
`--help` based on the program its being generated for.

As `OptTable` needs to be constexpr compatible, I have used a std::array
of help text variants. Each entry is:
(list of visibilities) - > help text string

So for the OpenMP version we have (flang, fc1) -> "OpenMP version for
flang is...".

So you can have multiple visibilities use the same string. The number of
entries is currently set to 1, and the number of visibilities per entry
is 2, because that's the maximum we need for now. The code is written so
we can increase these numbers later, and the unused elements will be initialised.

I have not applied this to group descriptions just because I don't know
of one that needs changing. It could easily be enabled for those too if
needed. There are minor changes to them just to get it all to compile.

This approach of storing many help strings per option in the 1 driver
library seemed preferable to making a whole new library for Flang (even
if that would mostly be including stuff from Clang).
2024-04-05 09:03:16 +01:00
SingleAccretion
cb4f94db83
[lld][WebAssembly] Add --no-growable-memory (#82890)
We recently added `--initial-heap` - an option that allows one to up the
initial memory size without the burden of having to know exactly how
much is needed.

However, in the process of implementing support for this in Emscripten
(https://github.com/emscripten-core/emscripten/pull/21071), we have
realized that `--initial-heap` cannot support the use-case of
non-growable memories by itself, since with it we don't know what to set
`--max-memory` to.

We have thus agreed to move the above work forward by introducing
another option to the linker (see
https://github.com/emscripten-core/emscripten/pull/21071#discussion_r1491755616),
one that would allow users to explicitly specify they want a
non-growable memory.

This change does this by introducing `--no-growable-memory`: an option
that is mutally exclusive with `--max-memory` (for simplicity - we can
also decide that it should override or be overridable by `--max-memory`.
In Emscripten a similar mix of options results in `--no-growable-memory`
taking precedence). The option specifies that the maximum memory size
should be set to the initial memory size, effectively disallowing memory
growth.

Closes #81932.
2024-02-25 08:43:11 -08:00
Sam Clegg
19261390cc
[lld][WebAssembly] Implement --start-lib/--end-lib (#78821)
Fixes: #77960
2024-01-22 10:04:26 -08:00
Kazu Hirata
21730eb49b [lld] Use SmallString::operator std::string (NFC) 2024-01-22 00:13:23 -08:00
Sam Clegg
bcc9b9d80c
[lld][WebAssembly] Match the ELF linker in transitioning away from archive indexes. (#78658)
The ELF linker transitioned away from archive indexes in
https://reviews.llvm.org/D117284.

This paves the way for supporting `--start-lib`/`--end-lib` (See #77960)

The ELF linker unified library handling with `--start-lib`/`--end-lib` and removed
the ArchiveFile class in https://reviews.llvm.org/D119074.
2024-01-19 16:20:29 -08:00
Sam Clegg
39e024d9e2
[lld][WebAssembly] Use the archive offset with --whole-archive (#78791)
This essentially ports 0b1413a8 from the ELF linker.
2024-01-19 14:42:03 -08:00
Sam Clegg
2bfa5ca927
[lld][WebAssembly] Reset context object after each link (#78770)
This mirrors how the ELF linker works. I wasn't able to find anywhere
where this is currently tested.

Followup to #78640, which triggered a regression.
2024-01-19 13:51:35 -08:00
Sam Clegg
3c5845703c
[lld][WebAssembly] Move input vectors from symtab to ctx. NFC (#78640)
Also convert from std::vector to SmallVector.

This matches the ELF linker where these were moved into the ctx object
in 9a572164d592e and converted to SmallVector in ba948c5a9c524b.
2024-01-18 15:53:13 -08:00
Sam Clegg
184c22dd3a
[lld][WebAssembly] Move linker global state in to context object. NFC (#78629)
See lld/ELF/Config.h
2024-01-18 15:01:21 -08:00
Sam Clegg
f268495914
[lld][WebAssembly] Rename fetch() to extract() to match ELF linker. NFC (#78625) 2024-01-18 14:39:38 -08:00
SingleAccretion
b2cdf3cc4c
[lld][WebAssembly] Add an --initial-heap option (#75594)
It is beneficial to preallocate a certain number of pages in the linear
memory (i. e. use the "minimum" field of WASM memories) so that fewer
"memory.grow"s are needed at startup.

So far, the way to do that has been to pass the "--initial-memory"
option to the linker. It works, but has the very significant downside of
requiring the user to know the size of static data beforehand, as it
must not exceed the number of bytes passed-in as "--initial-memory".

The new "--initial-heap" option avoids this downside by simply appending
the specified number of pages to static data (and stack), regardless of
how large they already are.

Ref: https://github.com/emscripten-core/emscripten/issues/20888.
2023-12-15 10:16:38 -08:00
Sam Clegg
97b25d91df
[lld][WebAssembly] Don't set importUndefined when -shared is used. NFC (#75241)
`importUndefined` is only used a couple of places and both of those
already handle `isPIC` separately.
2023-12-12 13:19:42 -08:00
Sam Clegg
89d5635f0a [lld][WebAssembly] Add --keep-section flag
This flag causes wasm-ld preserve a section even in the face of
`--strip-all`.  This is useful, for example, to preserve the
target_features section in the ase of clang (which can run wasm-opt
after linking), and emcc (which performs a bunch of post-link work).

Fixes: https://github.com/llvm/llvm-project/issues/60613
Fixes: https://github.com/llvm/llvm-project/issues/55781

Differential Revision: https://reviews.llvm.org/D149917
2023-11-02 14:23:45 -07:00
Sam Clegg
93adcb770b [lld][WebAssembly] Add --table-base setting
This is similar to `--global-base` but determines where to place the
table segments rather than that data segments.

See https://github.com/emscripten-core/emscripten/issues/20097

Differential Revision: https://reviews.llvm.org/D158892
2023-08-25 16:10:38 -07:00
Sam Clegg
8e44f037dc [lld][WebAssembly] Add support for -soname
This change writes the module name to the name section of the wasm
binary.  We use the `-soname` argument to determine the name and we
default the output file basename if this option is not specified.

In the future we will likely want to embed the soname in the dylink
section too, but this the first step in supporting `-soname`.

Differential Revision: https://reviews.llvm.org/D158001
2023-08-15 18:33:45 -07:00
Justin Bogner
dcb6d212fd Reapply "[Option] Add "Visibility" field and clone the OptTable APIs to use it"
This reverts commit 4e3b89483a6922d3f48670bb1c50a37f342918c6, with
fixes for places I'd missed updating in lld and lldb. I've also
renamed OptionVisibility::Default to "DefaultVis" to avoid ambiguity
since the undecorated name has to be available anywhere Options.inc is
included.

Original message follows:

This splits OptTable's "Flags" field into "Flags" and "Visibility",
updates the places where we instantiate Option tables, and adds
variants of the OptTable APIs that use Visibility mask instead of
Include/Exclude flags.

We need to do this to clean up a bunch of complexity in the clang
driver's option handling - there's a whole slew of flags like
CoreOption, NoDriverOption, and FlangOnlyOption there today to try to
handle all of the permutations of flags that the various drivers need,
but it really doesn't scale well, as can be seen by things like the
somewhat recently introduced CLDXCOption.

Instead, we'll provide an additive model for visibility that's
separate from the other flags. For things like "HelpHidden", which is
used as a "subtractive" modifier for option visibility, we leave that
in "Flags" and handle it as a special case.

Note that we don't actually update the users of the Include/Exclude
APIs here or change the flags that exist in clang at all - that will
come in a follow up that refactors clang's Options.td to use the
increased flexibility this change allows.

Differential Revision: https://reviews.llvm.org/D157149
2023-08-15 01:16:58 -07:00
Justin Bogner
4e3b89483a Revert "[Option] Add "Visibility" field and clone the OptTable APIs to use it"
this is failing on bots, reverting to investigate.

This reverts commit a16104e6da6f36f3d72dbf53d10ba56495a0d65a.
2023-08-14 13:31:02 -07:00
Justin Bogner
a16104e6da [Option] Add "Visibility" field and clone the OptTable APIs to use it
This splits OptTable's "Flags" field into "Flags" and "Visibility",
updates the places where we instantiate Option tables, and adds
variants of the OptTable APIs that use Visibility mask instead of
Include/Exclude flags.

We need to do this to clean up a bunch of complexity in the clang
driver's option handling - there's a whole slew of flags like
CoreOption, NoDriverOption, and FlangOnlyOption there today to try to
handle all of the permutations of flags that the various drivers need,
but it really doesn't scale well, as can be seen by things like the
somewhat recently introduced CLDXCOption.

Instead, we'll provide an additive model for visibility that's
separate from the other flags. For things like "HelpHidden", which is
used as a "subtractive" modifier for option visibility, we leave that
in "Flags" and handle it as a special case.

Note that we don't actually update the users of the Include/Exclude
APIs here or change the flags that exist in clang at all - that will
come in a follow up that refactors clang's Options.td to use the
increased flexibility this change allows.

Differential Revision: https://reviews.llvm.org/D157149
2023-08-14 13:24:54 -07:00
Sam Clegg
7a8ee92fa8 [lld][WebAssembly] Process stub libraries in a loop
When stub libraries trigger the fetching of new object files we can
potentially introduce new undefined symbols so process the stub in
loop until no new objects are pulled in.

Differential Revision: https://reviews.llvm.org/D153466
2023-08-11 11:07:40 -07:00
Jan Svoboda
3f092f37b7 [llvm] Extract common OptTable bits into macros
All command-line tools using `llvm::opt` create an enum of option IDs and a table of `OptTable::Info` object. Most of the tools use the same ID (`OPT_##ID`), kind (`Option::KIND##Class`), group ID (`OPT_##GROUP`) and alias ID (`OPT_##ALIAS`). This patch extracts that common code into canonical macros. This results in fewer changes when tweaking the `OPTION` macros emitted by the TableGen backend.

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D157028
2023-08-04 13:57:13 -07:00
Alexandre Ganea
6f2e92c10c Re-land [LLD] Allow usage of LLD as a library
This reverts commit aa495214b39d475bab24b468de7a7c676ce9e366.

As discussed in https://github.com/llvm/llvm-project/issues/53475 this patch
allows for using LLD-as-a-lib. It also lets clients link only the drivers that
they want (see unit tests).

This also adds the unit test infra as in the other LLVM projects. Among the
test coverage, I've added the original issue from @krzysz00, see:
https://github.com/ROCmSoftwarePlatform/D108850-lld-bug-reproduction

Important note: this doesn't allow (yet) linking in parallel. This will come a
bit later hopefully, in subsequent patches, for COFF at least.

Differential revision: https://reviews.llvm.org/D119049
2023-06-19 07:35:11 -04:00
Leonard Chan
aa495214b3 Revert "[LLD] Allow usage of LLD as a library"
This reverts commit 2700da5fe28d8b17c66e5c960d2188276a6ced39.

Reverting since this causes some test failures on our builders: https://ci.chromium.org/ui/p/fuchsia/builders/toolchain.ci/clang-linux-x64/b8778372807208184913/overview
2023-06-14 20:36:27 +00:00
Alexandre Ganea
2700da5fe2 [LLD] Allow usage of LLD as a library
As discussed in https://github.com/llvm/llvm-project/issues/53475 this patch allows using LLD-as-a-lib. It also lets clients link only the drivers that they want (see unit tests).

This also adds the unit test infra as in the other LLVM projects. Among the test coverage, I've added the original issue from @krzysz00, see: https://github.com/ROCmSoftwarePlatform/D108850-lld-bug-reproduction

Important note: this doesn't allow (yet) linking in parallel. This will come a bit later, in subsequent patches, for COFF at last.

Differential revision: https://reviews.llvm.org/D119049
2023-06-13 16:22:59 -04:00