Skip to content

[lld][WebAssembly] Implement --start-lib/--end-lib #78821

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lld/ELF/InputFiles.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,8 @@ class InputFile {
uint8_t osabi = 0;
uint8_t abiVersion = 0;

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

// True if this is an argument for --just-symbols. Usually false.
Expand Down
7 changes: 7 additions & 0 deletions lld/test/wasm/Inputs/start-lib1.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.functype bar () -> ()

.globl foo
foo:
.functype foo () -> ()
call bar
end_function
4 changes: 4 additions & 0 deletions lld/test/wasm/Inputs/start-lib2.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.globl bar
bar:
.functype bar () -> ()
end_function
33 changes: 33 additions & 0 deletions lld/test/wasm/start-lib.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Based on lld/test/ELF/start-lib.s

// RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %s -o %t1.o
// RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown \
// RUN: %p/Inputs/start-lib1.s -o %t2.o
// RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown \
// RUN: %p/Inputs/start-lib2.s -o %t3.o

// RUN: wasm-ld --no-gc-sections -o %t3 %t1.o %t2.o %t3.o
// RUN: obj2yaml %t3 | FileCheck --check-prefix=TEST1 %s
// TEST1: Name: foo
// TEST1: Name: bar

// RUN: wasm-ld --no-gc-sections -o %t3 %t1.o -u bar --start-lib %t2.o %t3.o
// RUN: obj2yaml %t3 | FileCheck --check-prefix=TEST2 %s
// TEST2-NOT: Name: foo
// TEST2: Name: bar

// RUN: wasm-ld --no-gc-sections -o %t3 %t1.o --start-lib %t2.o %t3.o
// RUN: obj2yaml %t3 | FileCheck --check-prefix=TEST3 %s
// TEST3-NOT: Name: foo
// TEST3-NOT: Name: bar

// RUN: not wasm-ld %t1.o --start-lib --start-lib 2>&1 | FileCheck -check-prefix=NESTED-LIB %s
// NESTED-LIB: nested --start-lib

// RUN: not wasm-ld --end-lib 2>&1 | FileCheck -check-prefix=END %s
// END: stray --end-lib

.globl _start
_start:
.functype _start () -> ()
end_function
15 changes: 14 additions & 1 deletion lld/wasm/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ class LinkerDriver {
// True if we are in --whole-archive and --no-whole-archive.
bool inWholeArchive = false;

// True if we are in --start-lib and --end-lib.
bool inLib = false;

std::vector<InputFile *> files;
};
} // anonymous namespace
Expand Down Expand Up @@ -304,7 +307,7 @@ void LinkerDriver::addFile(StringRef path) {
}
case file_magic::bitcode:
case file_magic::wasm_object:
files.push_back(createObjectFile(mbref));
files.push_back(createObjectFile(mbref, "", 0, inLib));
break;
case file_magic::unknown:
if (mbref.getBuffer().starts_with("#STUB")) {
Expand Down Expand Up @@ -375,6 +378,16 @@ void LinkerDriver::createFiles(opt::InputArgList &args) {
case OPT_no_whole_archive:
inWholeArchive = false;
break;
case OPT_start_lib:
if (inLib)
error("nested --start-lib");
inLib = true;
break;
case OPT_end_lib:
if (!inLib)
error("stray --end-lib");
inLib = false;
break;
}
}
if (files.empty() && errorCount() == 0)
Expand Down
5 changes: 2 additions & 3 deletions lld/wasm/InputFiles.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,8 @@ class InputFile {
void markLive() { live = true; }
bool isLive() const { return live; }

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

protected:
Expand Down
6 changes: 6 additions & 0 deletions lld/wasm/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ defm export_dynamic: B<"export-dynamic",
"Put symbols in the dynamic symbol table",
"Do not put symbols in the dynamic symbol table (default)">;

def end_lib: F<"end-lib">,
HelpText<"End a grouping of objects that should be treated as if they were together in an archive">;

def entry: S<"entry">, MetaVarName<"<entry>">,
HelpText<"Name of entry point symbol">;

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

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

def start_lib: F<"start-lib">,
HelpText<"Start a grouping of objects that should be treated as if they were together in an archive">;

def strip_all: F<"strip-all">, HelpText<"Strip all symbols">;

def strip_debug: F<"strip-debug">, HelpText<"Strip debugging information">;
Expand Down
6 changes: 3 additions & 3 deletions lld/wasm/Symbols.h
Original file line number Diff line number Diff line change
Expand Up @@ -486,9 +486,9 @@ class UndefinedTag : public TagSymbol {
static bool classof(const Symbol *s) { return s->kind() == UndefinedTagKind; }
};

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