88 Commits

Author SHA1 Message Date
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
afe957ea95
[WebAssembly] Allow absolute symbols in the linking section (symbol table) (#67493)
Fixes a crash in `-Wl,-emit-relocs` where the linker was not able to
write linker-synthetic absolute symbols to the symbol table.

This change adds a new symbol flag (`WASM_SYMBOL_ABS`), which means that
the symbol's offset is absolute and not relative to a given segment.
Such symbols include `__stack_low` and `__stack_low`.

Note that wasm object files never contains such symbols, only binaries
linked with `-Wl,-emit-relocs`.

Fixes: #67111
2023-10-03 13:16:16 -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
YAMAMOTO Takashi
47ba908a5e [lld][WebAssembly] Fix func reloc for internal GOT with extended-const
Differential Revision: https://reviews.llvm.org/D155542
2023-07-27 00:46:00 -07:00
Alexandre Ganea
7adaefbaa8 [wasm] Silence 'not all control paths return a value' warning when
building with MSVC on Windows
2023-03-15 14:20:18 -04:00
Sam Clegg
d32f71a91a [lld][WebAssembly] Use C++17 nested namespace syntax in most places. NFC
Like D131405, but for wasm-ld.

Differential Revision: https://reviews.llvm.org/D145399
2023-03-09 18:37:32 -08:00
Derek Schuff
c7af9ae577 Reapply: [WebAssembly] Implement build-id feature
Implement the --build-id flag similarly to ELF, and generate a
build_id section according to the WebAssembly tool convention
specified in https://github.com/WebAssembly/tool-conventions/pull/183

The default style ("fast" aka "tree") hashes the contents of the
output and (unlike ELF) generates a v5 UUID based on the hash (using a
random namespace). It also supports generating a random v4 UUID, a
sha1 hash, and a user-specified string (as ELF does).

Differential Revision: https://reviews.llvm.org/D107662

Fix MSVC build by std::copy on the underying buffer rather than
directly from std::array to llvm::MutableArrayRef
2023-03-03 17:15:55 -08:00
Derek Schuff
c8e5354f00 Revert "[WebAssembly] Implement build-id feature"
This reverts commit 41e31466af6a7feab82742bb01af43f4f3ae4ede
due to a build failure on Windows.
2023-03-02 15:28:56 -08:00
Derek Schuff
41e31466af [WebAssembly] Implement build-id feature
Implement the --build-id flag similarly to ELF, and generate a build_id
section according to the WebAssembly tool convention specified in
https://github.com/WebAssembly/tool-conventions/pull/183

The default style ("fast" aka "tree") hashes the contents of the output
and (unlike ELF) generates a v5 UUID based on the hash (using a random
namespace).
It also supports generating a random v4 UUID, a sha1 hash,
and a user-specified string (as ELF does).

Differential Revision: https://reviews.llvm.org/D107662
2023-03-02 14:19:06 -08:00
Kazu Hirata
b9ef5648b5 [lld] Use std::optional instead of llvm::Optional (NFC)
This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2023-01-02 18:29:04 -08:00
Guillaume Chatelet
1565317287 Revert D139181 "[lld][Alignment][NFC] Use Align instead of log2 of alignment in Wasm Sections"
As discussed on the patch the Align type is probably not a good fit for
linkers.
This reverts commit cfe77f23d6f190d54763a7575cee95aceb9216bc.
2022-12-20 10:58:56 +00:00
Fangrui Song
d88e8dcc72 [lld] llvm::Optional::value => operator*/operator->
std::optional::value() has undesired exception checking semantics and is
unavailable in some older Xcode. The call sites block std::optional migration.
2022-12-17 05:03:57 +00:00
Guillaume Chatelet
cfe77f23d6 [lld][Alignment][NFC] Use Align instead of log2 of alignment in Wasm Sections
I intend to slowly upgrade all alignments to the Align type in lld as well.
Some places talk about alignment in Bytes while other specify them as Log2(Bytes).
Let's make sure all of this is coherent.

Differential Revision: https://reviews.llvm.org/D139181
2022-12-02 12:47:41 +00:00
Florian Mayer
2390bb2347 [NFC] use has_value instead of hasValue 2022-10-31 16:43:14 -07:00
Dan Gohman
d4c8a0edca [wasm-ld] Allow importing/exporting the output module's memory with arbitrary names
This adds an `--export-memory` option to wasm-ld which allows passing
a name to give to the exported memory, and extends `--import-memory` to
allow passing a <module>,<name> pair specifying where the memory should
be imported from.

This is based on https://reviews.llvm.org/D131376, with the main
difference being that it only supports exporting memory by one name.

Differential Revision: https://reviews.llvm.org/D135898
2022-10-31 13:59:46 -07:00
Kazu Hirata
3850edd9e0 Use llvm::count_if (NFC) 2022-09-03 11:17:35 -07:00
Sam Clegg
113b568829 [lld][WebAssembly] Rename SymbolTable::getSymbols to match ELF backend. NFC
The ELF backend originally used `getSymbols()` but went though a
sequence of changes that resulted in this method being called
`symbols()`.

d8f8abbd4a2823f223bd7bc56445541fb221b512 replaced `getSymbols()` with
`forEachSymbol`.

a2fc96441788fba1e4709d63677f34ed8e321dae replaced `forEachSymbol` with
`llvm::iterator_range`.

e9262edf0d11a907763098d8e101219ccd9c43e9 replaced `llvm::iterator_range`
with `symbols()`.

Differential Revision: https://reviews.llvm.org/D131284
2022-08-31 14:33:45 -07:00
Kazu Hirata
f5a68feab3 Use llvm::none_of (NFC) 2022-08-14 16:25:39 -07:00
Kazu Hirata
757d9d22cd [lld] Use value_or instead of getValueOr (NFC) 2022-06-19 00:29:41 -07:00
Sam Clegg
87099a0438 [lld][WebAssembly] Remove unnecessary accessor methods. NFC
This is less code, and matches more closely the ELF linker.

Differential Revision: https://reviews.llvm.org/D126979
2022-06-03 11:43:44 -07:00
Martin Storsjö
46776f7556 Fix warnings about variables that are set but only used in debug mode
Add void casts to mark the variables used, next to the places where
they are used in assert or `LLVM_DEBUG()` expressions.

Differential Revision: https://reviews.llvm.org/D123117
2022-04-06 10:01:46 +03:00
Sam Clegg
4690bf2ed3 [lld][WebAssembly] Take advantage of extended const expressions when available
In particular we use these in two places:

1. When building PIC code we no longer need to combine output segments
   into a single segment that can be initialized at `__memory_base`.
   Instead each segment can encode its offset from `__memory_base` in
   its initializer.  e.g.

```
(i32.add (global.get __memory_base) (i32.const offset)
```

2. When building PIC code we no longer need to relocation internalized
   global addresses.  We can just initialize them with their correct
   offsets.

Differential Revision: https://reviews.llvm.org/D121420
2022-03-15 17:50:05 -07:00
Sam Clegg
86c90f9bfd [lld][WebAssembly] Add --unresolved-symbols=import-dynamic
This is a new mode for handling unresolved symbols that allows all
symbols to be imported in the same that they would be in the case of
`-fpie` or `-shared`, but generting an otherwise fixed/non-relocatable
binary.

Code linked in this way should still be compiled with `-fPIC` so that
data symbols can be resolved via imports.

This essentially allows the building of static binaries that have
dynamic imports.  See:
https://github.com/emscripten-core/emscripten/issues/12682

As with other uses of the experimental dynamic linking ABI, this
behaviour will produce a warning unless run with `--experimental-pic`.

Differential Revision: https://reviews.llvm.org/D91577
2022-03-15 15:10:21 -07:00
Sam Clegg
9504ab32b7 [WebAssembly] Second phase of implemented extended const proposal
This change continues to lay the ground work for supporting extended
const expressions in the linker.

The included test covers object file reading and writing and the YAML
representation.

Differential Revision: https://reviews.llvm.org/D121349
2022-03-14 08:55:47 -07:00
Sam Clegg
d2a0ef9844 [lld][WebAssembly] Don't force the export symbols assiged internal/dummy GOT entries
Symbols with regular GOT entries do need to be exported, but those that
are internalized (and have dymmy/internal GOT entries) need not be
exported.

This happens to fix the failures on the emscripten waterfall where extra
symbols were being exported by the linker (and then later removed by
wasm-opt).

Differential Revision: https://reviews.llvm.org/D119902
2022-02-15 17:29:45 -08:00
Sam Clegg
182b72aa48 [lld][WebAssembly] Generate TLS relocation code also when linking statically
Previously relocations were only generated for PIC output, but
relocations for TLS GOT entries are always needed when shared
memory is enabled, not just in PIC mode.

This means that the `__wasm_apply_global_tls_relocs` is now
generated even for statically linked (non-PIC) output.  Without
this the globals that hold the addresses of TLS symbols are
not set correctly.

Differential Revision: https://reviews.llvm.org/D112833
2021-10-29 13:26:35 -07:00
Sam Clegg
1eb79e732c [lld][WebAssembly] Initialize bss segments using memory.fill
Previously we were relying on the dynamic loader to take care of this
but it simple and correct for us to do it here instead.

Now we initialize bss segments as part of `__wasm_init_memory` at the
same time we initialize passive segments.

In addition we extent the us of `__wasm_init_memory` outside of shared
memory situations.  Specifically it is now used to initialize bss
segments when the memory is imported.

Differential Revision: https://reviews.llvm.org/D112667
2021-10-28 17:15:08 -07:00
Sam Clegg
659a08399a [WebAssembly] Add import info to dylink section of shared libraries
See https://github.com/WebAssembly/tool-conventions/pull/175

Differential Revision: https://reviews.llvm.org/D111345
2021-10-15 11:49:16 -07:00
Heejin Ahn
9261ee32dc [WebAssembly] Make EH work with dynamic linking
This makes Wasm EH work with dynamic linking. So far we were only able
to handle destructors, which do not use any tags or LSDA info.

1. This uses `TargetExternalSymbol` for `GCC_except_tableN` symbols,
   which points to the address of per-function LSDA info. It is more
   convenient to use than `MCSymbol` because it can take additional
   target flags.

2. When lowering `wasm_lsda` intrinsic, if PIC is enabled, make the
   symbol relative to `__memory_base` and generate the `add` node. If
   PIC is disabled, continue to use the absolute address.

3. Make tag symbols (`__cpp_exception` and `__c_longjmp`) undefined in
   the backend, because it is hard to make it work with dynamic
   linking's loading order. Instead, we make all tag symbols undefined
   in the LLVM backend and import it from JS.

4. Add support for undefined tags to the linker.

Companion patches:
- https://github.com/WebAssembly/binaryen/pull/4223
- https://github.com/emscripten-core/emscripten/pull/15266

Reviewed By: sbc100

Differential Revision: https://reviews.llvm.org/D111388
2021-10-12 23:28:27 -07:00
Heejin Ahn
3ec1760d91 [WebAssembly] Remove WasmTagType
This removes `WasmTagType`. `WasmTagType` contained an attribute and a
signature index:
```
struct WasmTagType {
  uint8_t Attribute;
  uint32_t SigIndex;
};
```

Currently the attribute field is not used and reserved for future use,
and always 0. And that this class contains `SigIndex` as its property is
a little weird in the place, because the tag type's signature index is
not an inherent property of a tag but rather a reference to another
section that changes after linking. This makes tag handling in the
linker also weird that tag-related methods are taking both `WasmTagType`
and `WasmSignature` even though `WasmTagType` contains a signature
index. This is because the signature index changes in linking so it
doesn't have any info at this point. This instead moves `SigIndex` to
`struct WasmTag` itself, as we did for `struct WasmFunction` in D111104.

In this CL, in lib/MC and lib/Object, this now treats tag types in the
same way as function types. Also in YAML, this removes `struct Tag`,
because now it only contains the tag index. Also tags set `SigIndex` in
`WasmImport` union, as functions do.

I think this makes things simpler and makes tag handling more in line
with function handling. These two shares similar properties in that both
of them have signatures, but they are kind of nominal so having the same
signature doesn't mean they are the same element.

Also a drive-by fix: the reserved 'attirubute' part's encoding changed
from uleb32 to uint8 a while ago. This was fixed in lib/MC and
lib/Object but not in YAML. This doesn't change object files because the
field's value is always 0 and its encoding is the same for the both
encoding.

This is effectively NFC; I didn't mark it as such just because it
changed YAML test results.

Reviewed By: sbc100, tlively

Differential Revision: https://reviews.llvm.org/D111086
2021-10-05 17:11:22 -07:00
Sam Clegg
ef8c9135ef [WebAssembly] Allow import and export of TLS symbols between DSOs
We previously had a limitation that TLS variables could not
be exported (and therefore could also not be imported).  This
change removed that limitation.

Differential Revision: https://reviews.llvm.org/D108877
2021-09-14 06:47:37 -07:00
Sam Clegg
b78c85a44a [WebAssembly] Convert to new "dylink.0" section format
This format is based on sub-sections (like the "linking" and "name"
sections) and is therefore easier to extend going forward.

spec change: https://github.com/WebAssembly/tool-conventions/pull/170
binaryen change: https://github.com/WebAssembly/binaryen/pull/4141
wabt change:  https://github.com/WebAssembly/wabt/pull/1707
emscripten change: https://github.com/emscripten-core/emscripten/pull/15019

Differential Revision: https://reviews.llvm.org/D109595
2021-09-12 05:30:38 -07:00
Sam Clegg
c468dc1b12 [lld][WebAssembly] Handle weakly defined symbols in shared libraries.
In the case of weakly defined symbols in shared libraries we now
generate both an import and an export.  The dynamic linker can then
choose how a winner from among all the shared libraries that define a
given symbol.

Previously any direct usage of a weakly defined symbol would use the
DSO-local definition (For example, even through there would be single
address for a weakly defined function, each DSO could end up directly
calling its local version).

Fixes: https://github.com/emscripten-core/emscripten/issues/13773

Differential Revision: https://reviews.llvm.org/D108413
2021-08-19 19:25:49 -04:00
Nick Fitzgerald
1d445a6e76 Reland: "[WebAssembly] Deduplicate imports of the same module name, field name, and type"
When two symbols import the same thing, only one import should be
emitted in the Wasm file.

Fixes https://bugs.llvm.org/show_bug.cgi?id=50938

Reverted in: 16aac493e59519377071e900d119ba2e7e5b525d.

Reviewed By: sbc100

Differential Revision: https://reviews.llvm.org/D105519
2021-07-22 14:16:05 -07:00
Sam Clegg
f428693de0 Reland "[lld][WebAssembly] Cleanup duplicate fields in Symbols.h. NFC"
This avoids duplication and simplifies the code in several places
without increasing the size of the symbol union (at least not
above the assert'd limit of 120 bytes).

Originally commit: 9b965b37c75d626c01951184088314590e38d299
Reverted in: 16aac493e59519377071e900d119ba2e7e5b525d.

Differential Revision: https://reviews.llvm.org/D106026
2021-07-20 12:13:08 -07:00
Fangrui Song
16aac493e5 Revert D105519 "[WebAssembly] Deduplicate imports of the same module name, field name, and type" and its followup
This reverts commit 4ae575b9997e0903d1c2ec01a43e3f3f2db5df16 and 9b965b37c75d626c01951184088314590e38d299.

There is an use-of-uninitialized-value bug in the `else` branch in ImportSection::addImport.
2021-07-19 17:09:01 -07:00
Sam Clegg
9b965b37c7 [lld][WebAssembly] Cleanup duplicate fields in Symbols.h. NFC
This avoids duplication and simplifies the code in several places
without increasing the size of the symbol union (at least not
above the assert'd limit of 120 bytes).

Differential Revision: https://reviews.llvm.org/D106026
2021-07-19 14:31:09 -07:00
Nick Fitzgerald
4ae575b999 [WebAssembly] Deduplicate imports of the same module name, field name, and type
When two symbols import the same thing, only one import should be emitted in the Wasm file.

Fixes https://bugs.llvm.org/show_bug.cgi?id=50938

Reviewed By: sbc100

Differential Revision: https://reviews.llvm.org/D105519
2021-07-19 13:59:02 -07:00
Wouter van Oortmerssen
4157b6033d [WebAssembly] Fixed LLD generation of 64-bit __wasm_apply_data_relocs
Differential Revision: https://reviews.llvm.org/D105863
2021-07-15 10:02:02 -07:00
Heejin Ahn
1d891d44f3 [WebAssembly] Rename event to tag
We recently decided to change 'event' to 'tag', and 'event section' to
'tag section', out of the rationale that the section contains a
generalized tag that references a type, which may be used for something
other than exceptions, and the name 'event' can be confusing in the web
context.

See
- https://github.com/WebAssembly/exception-handling/issues/159#issuecomment-857910130
- https://github.com/WebAssembly/exception-handling/pull/161

Reviewed By: tlively

Differential Revision: https://reviews.llvm.org/D104423
2021-06-17 20:34:19 -07:00
Wouter van Oortmerssen
3a293cbf13 [WebAssembly] Fix PIC/GOT codegen for wasm64
__table_base is know 64-bit, since in LLVM it represents a function pointer offset
__table_base32 is a copy in wasm32 for use in elem init expr, since no truncation may be used there.
New reloc R_WASM_TABLE_INDEX_REL_SLEB64 added

Differential Revision: https://reviews.llvm.org/D101784
2021-05-20 09:59:31 -07:00
Sam Clegg
5a9b25e15b [lld][WebAssembly] Refactor input chunk class hierarchy. NFC
The main motivation for this refactor is to remove the subclass
relationship between the InputSegment and MergeInputSegment and
SyntenticMergedInputSegment so that we can use the merging classes for
debug sections which are not data segments.

In the process of refactoring I also remove all the virtual functions
from the class hierarchy and try to reuse techniques used in the ELF
linker (see `lld/ELF/InputSections.h`).

Differential Revision: https://reviews.llvm.org/D102546
2021-05-17 21:01:17 -07:00
Sam Clegg
3b8d2be527 Reland: "[lld][WebAssembly] Initial support merging string data"
This change was originally landed in: 5000a1b4b9edeb9e994f2a5b36da8d48599bea49
It was reverted in: 061e071d8c9b98526f35cad55a918a4f1615afd4

This change adds support for a new WASM_SEG_FLAG_STRINGS flag in
the object format which works in a similar fashion to SHF_STRINGS
in the ELF world.

Unlike the ELF linker this support is currently limited:
- No support for SHF_MERGE (non-string merging)
- Always do full tail merging ("lo" can be merged with "hello")
- Only support single byte strings (p2align 0)

Like the ELF linker merging is only performed at `-O1` and above.

This fixes part of https://bugs.llvm.org/show_bug.cgi?id=48828,
although crucially it doesn't not currently support debug sections
because they are not represented by data segments (they are custom
sections)

Differential Revision: https://reviews.llvm.org/D97657
2021-05-10 16:03:38 -07:00
Nico Weber
061e071d8c Revert "[lld][WebAssembly] Initial support merging string data"
This reverts commit 5000a1b4b9edeb9e994f2a5b36da8d48599bea49.
Breaks tests, see https://reviews.llvm.org/D97657#2749151

Easily repros locally with `ninja check-llvm-mc-webassembly`.
2021-05-10 18:28:28 -04:00
Sam Clegg
5000a1b4b9 [lld][WebAssembly] Initial support merging string data
This change adds support for a new WASM_SEG_FLAG_STRINGS flag in
the object format which works in a similar fashion to SHF_STRINGS
in the ELF world.

Unlike the ELF linker this support is currently limited:
- No support for SHF_MERGE (non-string merging)
- Always do full tail merging ("lo" can be merged with "hello")
- Only support single byte strings (p2align 0)

Like the ELF linker merging is only performed at `-O1` and above.

This fixes part of https://bugs.llvm.org/show_bug.cgi?id=48828,
although crucially it doesn't not currently support debug sections
because they are not represented by data segments (they are custom
sections)

Differential Revision: https://reviews.llvm.org/D97657
2021-05-10 13:15:12 -07:00
Andy Wingo
9ac5620cb8 [WebAssembly] Rename WasmLimits::Initial to ::Minimum. NFC.
This patch renames the "Initial" member of WasmLimits to the name used
in the spec, "Minimum".

In the core WebAssembly specification, the Limits data type has one
required "min" member and one optional "max" member, indicating the
minimum required size of the corresponding table or memory, and the
maximum size, if any.

Although the WebAssembly spec does instantiate locally-defined tables
and memories with the initial size being equal to the minimum size, it
can't impose such a requirement for imports.  It doesn't make sense to
require an initial size for a memory import, for example.  The compiler
can only sensibly express the minimum and maximum sizes.

See
https://github.com/WebAssembly/js-types/blob/master/proposals/js-types/Overview.md#naming-of-size-limits
for a related discussion that agrees that the right name of "initial" is
"minimum" when querying the type of a table or memory from JavaScript.
(Of course it still makes sense for JS to speak in terms of an initial
size when it explicitly instantiates memories and tables.)

Differential Revision: https://reviews.llvm.org/D99186
2021-03-24 09:10:11 +01:00
Andy Wingo
51f1ddf8cb [lld][WebAssembly] Allow element sections for nonzero table numbers
This patch fixes LLD to allow element sections for tables whose number
is nonzero.  We also add a test for linking multiple tables, showing
that nonzero table numbers for the indirect function table,
user-declared imported tables, and local user table definitions work.

Differential Revision: https://reviews.llvm.org/D92321
2021-03-05 11:52:28 +01:00
Andy Wingo
e638d8b2bc [lld][WebAssembly] -Bsymbolic creates indirect function table if needed
It can be that while processing relocations, we realize that in the end
we need an indirect function table.  Ensure that one is present, in that
case, to avoid writing invalid object files.

Fixes https://bugs.llvm.org/show_bug.cgi?id=49397.

Differential Revision: https://reviews.llvm.org/D97843
2021-03-04 09:28:21 +01:00
Sam Clegg
14ffbb84aa [lld][WebAssembly] Rename methods/members to match ELF backend. NFC.
Specifically:

- InputChunk::outputOffset -> outSecOffset
- Symbol::get/setVirtualAddress -> get/setVA
- add InputChunk::getOffset helper that takes an offset

These are mostly in preparation for adding support for
SHF_MERGE/SHF_STRINGS but its also good to align with ELF where
possible.

Differential Revision: https://reviews.llvm.org/D97595
2021-02-26 17:05:59 -08:00