Skip to content

Commit f5b3a58

Browse files
committed
[lld][WebAssembly] Implement --start-lib/--end-lib
Fixes: llvm#77960
1 parent 02f95b7 commit f5b3a58

File tree

8 files changed

+71
-9
lines changed

8 files changed

+71
-9
lines changed

lld/ELF/InputFiles.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,8 @@ class InputFile {
129129
uint8_t osabi = 0;
130130
uint8_t abiVersion = 0;
131131

132-
// True if this is a relocatable object file/bitcode file between --start-lib
133-
// and --end-lib.
132+
// True if this is a relocatable object file/bitcode file in an ar archive
133+
// or between --start-lib and --end-lib.
134134
bool lazy = false;
135135

136136
// True if this is an argument for --just-symbols. Usually false.

lld/test/wasm/Inputs/start-lib1.s

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.functype bar () -> ()
2+
3+
.globl foo
4+
foo:
5+
.functype foo () -> ()
6+
call bar
7+
end_function

lld/test/wasm/Inputs/start-lib2.s

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.globl bar
2+
bar:
3+
.functype bar () -> ()
4+
end_function

lld/test/wasm/start-lib.s

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Based on lld/test/ELF/start-lib.s
2+
3+
// RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %s -o %t1.o
4+
// RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown \
5+
// RUN: %p/Inputs/start-lib1.s -o %t2.o
6+
// RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown \
7+
// RUN: %p/Inputs/start-lib2.s -o %t3.o
8+
9+
// RUN: wasm-ld --no-gc-sections -o %t3 %t1.o %t2.o %t3.o
10+
// RUN: obj2yaml %t3 | FileCheck --check-prefix=TEST1 %s
11+
// TEST1: Name: foo
12+
// TEST1: Name: bar
13+
14+
// RUN: wasm-ld --no-gc-sections -o %t3 %t1.o -u bar --start-lib %t2.o %t3.o
15+
// RUN: obj2yaml %t3 | FileCheck --check-prefix=TEST2 %s
16+
// TEST2-NOT: Name: foo
17+
// TEST2: Name: bar
18+
19+
// RUN: wasm-ld --no-gc-sections -o %t3 %t1.o --start-lib %t2.o %t3.o
20+
// RUN: obj2yaml %t3 | FileCheck --check-prefix=TEST3 %s
21+
// TEST3-NOT: Name: foo
22+
// TEST3-NOT: Name: bar
23+
24+
// RUN: not wasm-ld %t1.o --start-lib --start-lib 2>&1 | FileCheck -check-prefix=NESTED-LIB %s
25+
// NESTED-LIB: nested --start-lib
26+
27+
// RUN: not wasm-ld --end-lib 2>&1 | FileCheck -check-prefix=END %s
28+
// END: stray --end-lib
29+
30+
.globl _start
31+
_start:
32+
.functype _start () -> ()
33+
end_function

lld/wasm/Driver.cpp

+14-1
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ class LinkerDriver {
9494
// True if we are in --whole-archive and --no-whole-archive.
9595
bool inWholeArchive = false;
9696

97+
// True if we are in --start-lib and --end-lib.
98+
bool inLib = false;
99+
97100
std::vector<InputFile *> files;
98101
};
99102
} // anonymous namespace
@@ -304,7 +307,7 @@ void LinkerDriver::addFile(StringRef path) {
304307
}
305308
case file_magic::bitcode:
306309
case file_magic::wasm_object:
307-
files.push_back(createObjectFile(mbref));
310+
files.push_back(createObjectFile(mbref, "", 0, inLib));
308311
break;
309312
case file_magic::unknown:
310313
if (mbref.getBuffer().starts_with("#STUB")) {
@@ -375,6 +378,16 @@ void LinkerDriver::createFiles(opt::InputArgList &args) {
375378
case OPT_no_whole_archive:
376379
inWholeArchive = false;
377380
break;
381+
case OPT_start_lib:
382+
if (inLib)
383+
error("nested --start-lib");
384+
inLib = true;
385+
break;
386+
case OPT_end_lib:
387+
if (!inLib)
388+
error("stray --end-lib");
389+
inLib = false;
390+
break;
378391
}
379392
}
380393
if (files.empty() && errorCount() == 0)

lld/wasm/InputFiles.h

+2-3
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,8 @@ class InputFile {
6767
void markLive() { live = true; }
6868
bool isLive() const { return live; }
6969

70-
// True if this file is exists as in an archive file and has not yet been
71-
// extracted.
72-
// TODO(sbc): Use this to implement --start-lib/--end-lib.
70+
// True if this is a relocatable object file/bitcode file in an ar archive
71+
// or between --start-lib and --end-lib.
7372
bool lazy = false;
7473

7574
protected:

lld/wasm/Options.td

+6
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ defm export_dynamic: B<"export-dynamic",
7070
"Put symbols in the dynamic symbol table",
7171
"Do not put symbols in the dynamic symbol table (default)">;
7272

73+
def end_lib: F<"end-lib">,
74+
HelpText<"End a grouping of objects that should be treated as if they were together in an archive">;
75+
7376
def entry: S<"entry">, MetaVarName<"<entry>">,
7477
HelpText<"Name of entry point symbol">;
7578

@@ -128,6 +131,9 @@ defm rsp_quoting: Eq<"rsp-quoting", "Quoting style for response files">,
128131

129132
def shared: F<"shared">, HelpText<"Build a shared object">;
130133

134+
def start_lib: F<"start-lib">,
135+
HelpText<"Start a grouping of objects that should be treated as if they were together in an archive">;
136+
131137
def strip_all: F<"strip-all">, HelpText<"Strip all symbols">;
132138

133139
def strip_debug: F<"strip-debug">, HelpText<"Strip debugging information">;

lld/wasm/Symbols.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -486,9 +486,9 @@ class UndefinedTag : public TagSymbol {
486486
static bool classof(const Symbol *s) { return s->kind() == UndefinedTagKind; }
487487
};
488488

489-
// LazySymbol represents a symbol that is not yet in the link, but we know where
490-
// to find it if needed. If the resolver finds both Undefined and Lazy for the
491-
// same name, it will ask the Lazy to load a file.
489+
// LazySymbol symbols represent symbols in object files between --start-lib and
490+
// --end-lib options. LLD also handles traditional archives as if all the files
491+
// in the archive are surrounded by --start-lib and --end-lib.
492492
//
493493
// A special complication is the handling of weak undefined symbols. They should
494494
// not load a file, but we have to remember we have seen both the weak undefined

0 commit comments

Comments
 (0)