Skip to content

Commit c94d393

Browse files
committed
[WebAssembly] Initial wasm linker implementation
This linker backend is still a work in progress but is enough to link simple programs including linking against library archives. Differential Revision: https://reviews.llvm.org/D34851 llvm-svn: 318539
1 parent ae304b0 commit c94d393

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+5791
-16
lines changed

lld/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,4 +223,4 @@ add_subdirectory(docs)
223223
add_subdirectory(COFF)
224224
add_subdirectory(ELF)
225225
add_subdirectory(MinGW)
226-
226+
add_subdirectory(wasm)

lld/CODE_OWNERS.TXT

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,6 @@ N: Lang Hames, Nick Kledzik
1717
E: lhames@gmail.com, kledzik@apple.com
1818
D: Mach-O backend
1919

20+
N: Sam Clegg
21+
E: sbc@chromium.org
22+
D: WebAssembly backend (wasm/*)

lld/docs/NewLLD.rst

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
The ELF and COFF Linkers
2-
========================
1+
The ELF, COFF and Wasm Linkers
2+
==============================
33

44
The ELF Linker as a Library
55
---------------------------
@@ -33,11 +33,12 @@ between speed, simplicity and extensibility.
3333

3434
We implemented the linkers as native linkers for each file format.
3535

36-
The two linkers share the same design but do not share code.
36+
The linkers share the same design but share very little code.
3737
Sharing code makes sense if the benefit is worth its cost.
38-
In our case, ELF and COFF are different enough that we thought the layer to
39-
abstract the differences wouldn't worth its complexity and run-time cost.
40-
Elimination of the abstract layer has greatly simplified the implementation.
38+
In our case, the object formats are different enough that we thought the layer
39+
to abstract the differences wouldn't be worth its complexity and run-time
40+
cost. Elimination of the abstract layer has greatly simplified the
41+
implementation.
4142

4243
* Speed by design
4344

lld/docs/WebAssembly.rst

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
WebAssembly lld port
2+
====================
3+
4+
Note: The WebAssembly port is still a work in progress and is be lacking
5+
certain features.
6+
7+
The WebAssembly version of lld takes WebAssembly binaries as inputs and produces
8+
a WebAssembly binary as its output. For the most part this port tried to mimic
9+
the behaviour of traditional ELF linkers and specifically the ELF lld port.
10+
Where possible that command line flags and the semantics should be the same.
11+
12+
13+
Object file format
14+
------------------
15+
16+
The format the input object files that lld expects is specified as part of the
17+
the WebAssembly tool conventions
18+
https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md.
19+
20+
This is object format that the llvm will produce when run with the
21+
``wasm32-unknown-unknown-wasm`` target. To build llvm with WebAssembly support
22+
currently requires enabling the experimental backed using
23+
``-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly``.
24+
25+
26+
Missing features
27+
----------------
28+
29+
There are several key features that are not yet implement in the WebAssembly
30+
ports:
31+
32+
- COMDAT support. This means that support for C++ is still very limited.
33+
- Function stripping. Currently there is no support for ``--gc-sections`` so
34+
functions and data from a given object will linked as a unit.
35+
- Section start/end symbols. The synthetic symbols that mark the start and
36+
of data regions are not yet created in the output file.

lld/docs/index.rst

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ LLD is a linker from the LLVM project. That is a drop-in replacement
55
for system linkers and runs much faster than them. It also provides
66
features that are useful for toolchain developers.
77

8-
The linker supports ELF (Unix), PE/COFF (Windows) and Mach-O (macOS)
9-
in descending order of completeness. Internally, LLD consists of three
10-
different linkers. The ELF port is the one that will be described in
11-
this document. The PE/COFF port is almost complete except the lack of
12-
the Windows debug info (PDB) support. The Mach-O port is built based
13-
on a different architecture than the ELF or COFF ports. For the
14-
details about Mach-O, please read :doc:`AtomLLD`.
8+
The linker supports ELF (Unix), PE/COFF (Windows), Mach-O (macOS) and
9+
WebAssembly in descending order of completeness. Internally, LLD consists of
10+
several different linkers. The ELF port is the one that will be described in
11+
this document. The PE/COFF port is almost complete except the lack of the
12+
Windows debug info (PDB) support. The WebAssembly port is still a work in
13+
progress (See :doc:`WebAssembly`). The Mach-O port is built based on a
14+
different architecture than the others. For the details about Mach-O, please
15+
read :doc:`AtomLLD`.
1516

1617
Features
1718
--------
@@ -172,5 +173,6 @@ document soon.
172173

173174
NewLLD
174175
AtomLLD
176+
WebAssembly
175177
windows_support
176178
ReleaseNotes

lld/include/lld/Common/Driver.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ namespace mach_o {
3333
bool link(llvm::ArrayRef<const char *> Args,
3434
llvm::raw_ostream &Diag = llvm::errs());
3535
}
36+
37+
namespace wasm {
38+
bool link(llvm::ArrayRef<const char *> Args, bool CanExitEarly,
39+
llvm::raw_ostream &Diag = llvm::errs());
40+
}
3641
}
3742

3843
#endif

lld/test/lit.cfg.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
llvm_config.use_lld()
4040

4141
tool_patterns = [
42-
'llvm-as', 'llvm-mc', 'llvm-nm',
42+
'llc', 'llvm-as', 'llvm-mc', 'llvm-nm',
4343
'llvm-objdump', 'llvm-pdbutil', 'llvm-readobj', 'obj2yaml', 'yaml2obj']
4444

4545
llvm_config.add_tool_substitutions(tool_patterns)
@@ -67,6 +67,7 @@
6767
'Mips': 'mips',
6868
'PowerPC': 'ppc',
6969
'Sparc': 'sparc',
70+
'WebAssembly': 'wasm',
7071
'X86': 'x86'})
7172
])
7273

lld/test/wasm/Inputs/archive1.ll

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
declare i32 @bar() local_unnamed_addr #1
2+
3+
define i32 @foo() local_unnamed_addr #0 {
4+
entry:
5+
%call = tail call i32 @bar() #2
6+
ret i32 %call
7+
}

lld/test/wasm/Inputs/archive2.ll

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
declare i32 @foo() local_unnamed_addr #1
2+
3+
define i32 @bar() local_unnamed_addr #0 {
4+
entry:
5+
%call = tail call i32 @foo() #2
6+
ret i32 %call
7+
}

lld/test/wasm/Inputs/call-indirect.ll

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
2+
target triple = "wasm32-unknown-unknown-wasm"
3+
4+
@indirect_bar = hidden local_unnamed_addr global i32 ()* @bar, align 4
5+
6+
; Function Attrs: norecurse nounwind readnone
7+
define hidden i32 @bar() #0 {
8+
entry:
9+
ret i32 1
10+
}
11+
12+
; Function Attrs: nounwind
13+
define hidden void @call_bar_indirect() local_unnamed_addr #1 {
14+
entry:
15+
%0 = load i32 ()*, i32 ()** @indirect_bar, align 4
16+
%call = tail call i32 %0() #2
17+
ret void
18+
}

lld/test/wasm/Inputs/hello.ll

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
; Wasm module generated from the following C code:
2+
; void puts(const char*);
3+
; void hello() { puts("hello\n"); }
4+
5+
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
6+
target triple = "wasm32-unknown-unknown-wasm"
7+
8+
@hello_str = unnamed_addr constant [7 x i8] c"hello\0A\00", align 1
9+
10+
; Function Attrs: nounwind
11+
define hidden void @hello() local_unnamed_addr #0 {
12+
entry:
13+
tail call void @puts(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @hello_str, i32 0, i32 0))
14+
ret void
15+
}
16+
17+
; Function Attrs: nounwind
18+
declare void @puts(i8* nocapture readonly) local_unnamed_addr #1

0 commit comments

Comments
 (0)