Commit Graph

626 Commits

Author SHA1 Message Date
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 fad05465c1 [lld][WebAssembly] Handle TLS variables in Symbol::getVA. NFC
In the shared memory case we can always assume that TLS addresses
are relative to __tls_base.  In the non-shared memory case TLS
variables are absolute, just like normal data addresses.

This simplifies the code in calcNewValue so that TLS relocations
no longer need special handling.

Differential Revision: https://reviews.llvm.org/D112831
2021-10-29 10:45:30 -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 50bfc45109 [lld][WebAssemlby] Always enable mutable-globals feature in PIC mode
This works around an issue where the feature can be forgotten
in the case of LTO + object file with no functions.

See: https://bugs.llvm.org/show_bug.cgi?id=52339

Differential Revision: https://reviews.llvm.org/D112769
2021-10-28 16:24:54 -07:00
Sam Clegg 28848e9e1b [lld][WebAssembly] Handle duplicate archive member names in ThinLTO
This entire change, including the test case, comes almost verbatim
from the ELF driver.

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

Differential Revision: https://reviews.llvm.org/D112723
2021-10-28 11:48:04 -07:00
Sam Clegg 4da38c14d0 [lld] Rename addCombinedLTOObjects to match ELF driver. NFC
This function was renamed in https://reviews.llvm.org/D62291.
The new name seems more accurate and also its good to maintain
some consistency between these methods in the different drivers.

Differential Revision: https://reviews.llvm.org/D112719
2021-10-28 11:46:19 -07:00
Nico Weber 9f90347588 fix comment typos to cycle bots 2021-10-27 09:53:08 -04:00
Kazu Hirata 4bd46501c3 Use llvm::any_of and llvm::none_of (NFC) 2021-10-24 17:35:33 -07:00
Noah Shutty e678c51177 [Support][ThinLTO] Move ThinLTO caching to LLVM Support library
We would like to move ThinLTO’s battle-tested file caching mechanism to
the LLVM Support library so that we can use it elsewhere in LLVM.

Patch By: noajshu

Differential Revision: https://reviews.llvm.org/D111371
2021-10-18 18:57:25 -07:00
Petr Hosek 8e46e34d24 Revert "[Support][ThinLTO] Move ThinLTO caching to LLVM Support library"
This reverts commit 92b8cc52bb since
it broke the gold plugin.
2021-10-18 12:24:05 -07:00
Noah Shutty 92b8cc52bb [Support][ThinLTO] Move ThinLTO caching to LLVM Support library
We would like to move ThinLTO’s battle-tested file caching mechanism to
the LLVM Support library so that we can use it elsewhere in LLVM.

Patch By: noajshu

Differential Revision: https://reviews.llvm.org/D111371
2021-10-18 12:08:49 -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
Heejin Ahn 9a9ec8e04b [lld][WebAssembly] Remove redundant check for undefined global (NFC)
Also does some refactoring.

Reviewed By: sbc100

Differential Revision: https://reviews.llvm.org/D111101
2021-10-05 15:11:27 -07:00
Sam Clegg 8fe128476e [lld][WebAssembly] Create optional internal symbols only after LTO object as been added
This is important for the cases where new symbols can be introduced
during LTO.   Specifically this happens for during TLS-lowering where
references to `__tls_base` can be introduced.

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

Differential Revision: https://reviews.llvm.org/D111171
2021-10-05 13:31:09 -07:00
Sam Clegg c0039de295 [Object][WebAssemlby] Report function types (signatures). NFC
This simplifies the code in a number of ways and avoids
having to track functions and their types separately.

Differential Revision: https://reviews.llvm.org/D111104
2021-10-04 17:33:56 -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
Thomas Lively b2032f18c9 [lld][WebAssembly] Relax limitations on multithreaded instantiation
For multithreaded modules (i.e. modules with a shared memory), lld injects a
synthetic Wasm start function that is automatically called during instantiation
to initialize memory from passive data segments. Even though the module will be
instantiated separately on each thread, memory initialization should happen only
once. Furthermore, memory initialization should be finished by the time each
thread finishes instantiation. Since multiple threads may be instantiating their
modules at the same time, the synthetic function must synchronize them.

The current synchronization tries to atomically increment a flag from 0 to 1 in
memory then enters one of two cases. First, if the increment was successful, the
current thread is responsible for initializing memory. It does so, increments
the flag to 2 to signify that memory has been initialized, then notifies all
threads waiting on the flag. Otherwise, the thread atomically waits on the flag
with an expected value of 1 until memory has been initialized. Either the
initializer thread finishes initializing memory (i.e. sets the flag to 2) first
and the waiter threads do not end up blocking, or the waiter threads succesfully
start waiting before memory is initialized so they will be woken by the
initializer thread once it has finished.

One complication with this scheme is that there are various contexts on the Web,
most notably on the main browser thread, that cannot successfully execute a
wait. Executing a wait in these contexts causes a trap, and in this case would
cause instantiation to fail. The embedder must therefore ensure that these
contexts win the race and become responsible for initializing memory, since that
is the only code path that does not execute a wait.

Unfortunately, since only one thread can win the race and initialize memory,
this scheme makes it impossible to have multiple threads in contexts that cannot
wait. For example, it is not currently possible to instantiate the module on
both the main browser thread as well as in an AudioWorklet. To loosen this
restriction, this commit inserts an extra check so that the wait will not be
executed at all when memory has already been initialized, i.e. when the flag
value is 2. After this change, the module can be instantiated on threads in
non-waiting contexts as long as the embedder can guarantee either that the
thread will win the race and initialize memory (as before) or that memory has
already been initialized when instantiation begins. Threads in contexts that can
wait can continue racing to initialize memory.

Fixes (or at least improves) PR51702.

Reviewed By: dschuff

Differential Revision: https://reviews.llvm.org/D109722
2021-09-13 15:03:51 -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 3a7bcba34b [lld][WebAssembly] Cleanup output of --verbose
Remove some unnecessary logging from wasm-ld when running under
`--verbose`.  Unlike `-debug` this logging is available in release
builds.  This change makes it little more minimal/readable.

Also, avoid compiling the `debugWrite` function in releaase builds
where it does nothing.  This should remove a lot debug strings from
the binary, and avoid having to construct unused debug strings at
runtime.

Differential Revision: https://reviews.llvm.org/D109583
2021-09-10 11:35:50 -04:00
Sam Clegg 6355234660 [lld][WebAssembly] Fix crash on un-used __tls_base symbol
In the case that TLS is used in the single-threaded program, and
therefore effectively lowered away, we still optionally create a
`__tls_base` symbols, but the code for setting it was assuming it was
always created.

Differential Revision: https://reviews.llvm.org/D109518
2021-09-09 12:45:58 -04:00
Sam Clegg 44177e5fb2 [WebAssembly] Add explict TLS symbol flag
As before we maintain backwards compat with older object files
by also infering the TLS flag based on the name of the segment.

This change is was split out from https://reviews.llvm.org/D108877.

Differential Revision: https://reviews.llvm.org/D109426
2021-09-09 10:03:30 -04:00
Nico Weber 9d22754389 Fix lld build after 5881dcff7e 2021-09-02 15:07:10 -04: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
Sam Clegg e4888be74e [WebAssembly] Avoid unused function imports in PIC mode
In PIC mode we import function address via `GOT.mem` imports but for
direct function calls we still import the first class function.
However, if the function is never directly called we can avoid the first
class import completely.

Differential Revision: https://reviews.llvm.org/D108345
2021-08-18 22:31:04 -04:00
Pan, Tao c70fa6da9a Fix gcc build error after D105519
Same as 3bec7ed59e

Reviewed By: sbc100

Differential Revision: https://reviews.llvm.org/D107422
2021-08-09 14:32:34 +08:00
Derek Schuff cf54424a46 [lld][WebAssembly] Do not remove name section with --strip-debug
Leave the name section in the output when using the --strip-debug
flag. This treats it more like ELF symbol tables, as the name
section has similar uses at runtime (e.g. wasm engines understand
it and it can be used for symbolization at runtime).

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

Differential Revision: https://reviews.llvm.org/D106728
2021-07-26 11:06:52 -07:00
Ayke van Laethem 13ca0c87ed
[lld][WebAssembly] Align __heap_base
__heap_base was not aligned. In practice, it will often be aligned
simply because it follows the stack, but when the stack is placed at the
beginning (with the --stack-first option), the __heap_base might be
unaligned. It could even be byte-aligned.

At least wasi-libc appears to expect that __heap_base is aligned:
659ff41456/dlmalloc/src/malloc.c (L5224)

While WebAssembly itself does not appear to require any alignment for
memory accesses, it is sometimes required when sharing a pointer
externally. For example, WASI might expect alignment up to 8:
https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md#-timestamp-u64

This issue got introduced with the addition of the --stack-first flag:
https://reviews.llvm.org/D46141
I suspect the lack of alignment wasn't intentional here.

Differential Revision: https://reviews.llvm.org/D106499
2021-07-24 14:03:26 +02: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: 16aac493e5.

Reviewed By: sbc100

Differential Revision: https://reviews.llvm.org/D105519
2021-07-22 14:16:05 -07:00
Fangrui Song db5e078690 [LTO] Add SelectionKind to IRSymtab and use it in ld.lld/LLVMgold
In PGO, a C++ external linkage function `foo` has a private counter
`__profc_foo` and a private `__profd_foo` in a `comdat nodeduplicate`.

A `__attribute__((weak))` function `foo` has a weak hidden counter `__profc_foo`
and a private `__profd_foo` in a `comdat nodeduplicate`.

In `ld.lld a.o b.o`, say a.o defines an external linkage `foo` and b.o
defines a weak `foo`. Currently we treat `comdat nodeduplicate` as `comdat any`,
ld.lld will incorrectly consider `b.o:__profc_foo` non-prevailing.  In the worst
case when `b.o:__profd_foo` is retained and `b.o:__profc_foo` isn't, there will
be dangling reference causing an `undefined hidden symbol` error.

Add SelectionKind to `Comdat` in IRSymtab and let linkers ignore nodeduplicate comdat.

Differential Revision: https://reviews.llvm.org/D106228
2021-07-20 13:22:00 -07:00
Sam Clegg d51f74acdf [lld][WebAssembly] Error on import of TLS symbols in shared libraries
In https://reviews.llvm.org/D102044 we made exporting a TLS symbol
into an error, but we also want to error on import.

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

Differential Revision: https://reviews.llvm.org/D106385
2021-07-20 12:36:03 -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: 9b965b37c7
Reverted in: 16aac493e5.

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 4ae575b999 and 9b965b37c7.

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 670944fb20 [WebAssembly] Support R_WASM_MEMORY_ADDR_TLS_SLEB64 for wasm64
Also fixed TLS tests swapping addr & value in store op
Differential Revision: https://reviews.llvm.org/D106096
2021-07-19 10:22:43 -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
Wouter van Oortmerssen b568c11b40 [WebAssembly] Fixed LLD generation of 64-bit __wasm_init_memory
Differential Revision: https://reviews.llvm.org/D105849
2021-07-12 15:26:11 -07:00
Thomas Lively 0fd5e7b2d8 [WebAssembly][lld] Fix segfault on .bss sections in mapfile
When memory is declared in the Wasm module, we rely on the implicit zero
initialization behavior and do not explicitly output .bss sections. The means
that they do not have associated `outputSec` entries, which was causing
segfaults in the mapfile support. Fix the issue by guarding against null
`outputSec` and falling back to using a zero offset.

Differential Revision: https://reviews.llvm.org/D102951
2021-07-07 23:31:48 -07:00
Fangrui Song f1e2d5851b [OptTable] Rename PrintHelp to printHelp
To be consistent with other member functions and match the coding standard.
2021-06-24 14:47:03 -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
Sam Clegg d01e673a9f [lld][WebAssembly] Fix crash calling weakly undefined function in PIC code
Differential Revision: https://reviews.llvm.org/D104495
2021-06-17 16:49:02 -07:00
Sam Clegg 758633f922 [lld][WebAssembly] Add new `--import-undefined` option
This change revisits https://reviews.llvm.org/D79248 which originally
added support for the --unresolved-symbols flag.

At the time I thought it would make sense to add a third option to this
flag called `import-functions` but it turns out (as was suspects by on
the reviewers IIRC) that this option can be authoganal.

Instead I've added a new option called `--import-undefined` that only
operates on symbols that can be imported (for example, function symbols
can always be imported as opposed to data symbols we can only be
imported when compiling with PIC).

This option gives us the full expresivitiy that emscripten needs to be
able allow reporting of undefined data symbols as well as the option to
disable that.

This change does remove the `--unresolved-symbols=import-functions`
option, which is been in the codebase now for about a year but I would
be extremely surprised if anyone was using it.

Differential Revision: https://reviews.llvm.org/D103290
2021-06-17 11:44:21 -07:00
Sam Clegg c1a59fa550 [lld][WebAssemlby] Fix for string merging of -dwarf-5 sections
We were mistakenly treating `.debug_str_offsets` as a string mergable
section when it is not (it contains integers not strings).  This is an
indication that we really should find a way to store flags for custom
sections.

Fixes: https://bugs.llvm.org/show_bug.cgi?id=48828
Fixes: https://bugs.chromium.org/p/chromium/issues/detail?id=1172217

Differential Revision: https://reviews.llvm.org/D103486
2021-06-01 14:33:56 -07:00
Sam Clegg 8544b40b6e [lld][WebAssembly] Fix for PIC output + TLS + non-shared-memory
Prior to this change build with `-shared/-pie` and using TLS (but
without -shared-memory) would hit this assert:

  "Currenly only a single data segment is supported in PIC mode"

This is because we were not including TLS data when merging data
segments.  However, when we build without shared-memory (i.e.  without
threads) we effectively lower away TLS into a normal active data
segment.. so we were ending up with two active data segments: the merged
data, and the lowered TLS data.

To fix this problem we can instead avoid combining data segments at
all when running in shared memory mode (because in this case all
segment initialization is passive).  And then in non-shared memory
mode we know that TLS has been lowered and therefore we can can
and should combine all segments.

So with this new behavior we have two different modes:

1. With shared memory / mutli-threaded: Never combine data segments
   since it is not necessary.  (All data segments as passive already).

2. Wihout shared memory / single-threaded: Combine *all* data segments
   since we treat TLS as normal data.  (We end up with a single
   active data segment).

Differential Revision: https://reviews.llvm.org/D102937
2021-05-21 15:16:47 -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 356b85edd7 [lld][WebAssembly] Fix for string tail merging and -r/--relocatable
Ensure that both SyntheticMergedChunk and all MergeInfoChunks that it
comprises are assigned the correct output section.  Without this we
would crash when outputting relocations in --relocatable mode.

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

Differential Revision: https://reviews.llvm.org/D102806
2021-05-19 15:25:58 -07:00
Sam Clegg 45b7cf9955 [lld][WebAssembly] Enable string tail merging in debug sections
This is a followup to https://reviews.llvm.org/D97657 which
applied string tail merging to data segments.

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

Differential Revision: https://reviews.llvm.org/D102436
2021-05-18 12:25:39 -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