[lld][WebAssembly] Initial support for stub libraries

See the docs in lld/docs/WebAssembly.rst for more on this.

This feature unlocks a lot of simplification in the emscripten toolchain
since we can represent the JS libraries to wasm-ld as stub libraries.

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

Differential Revision: https://reviews.llvm.org/D145308
This commit is contained in:
Sam Clegg
2022-12-06 16:49:13 -08:00
parent 1c9173365a
commit 3111784ff7
14 changed files with 224 additions and 5 deletions

View File

@@ -12,6 +12,7 @@
#include "InputElement.h"
#include "OutputSegment.h"
#include "SymbolTable.h"
#include "lld/Common/Args.h"
#include "lld/Common/CommonLinkerContext.h"
#include "lld/Common/Reproduce.h"
#include "llvm/Object/Binary.h"
@@ -678,6 +679,48 @@ Symbol *ObjFile::createUndefined(const WasmSymbol &sym, bool isCalledDirectly) {
llvm_unreachable("unknown symbol kind");
}
StringRef strip(StringRef s) {
while (s.starts_with(" ")) {
s = s.drop_front();
}
while (s.ends_with(" ")) {
s = s.drop_back();
}
return s;
}
void StubFile::parse() {
bool first = false;
for (StringRef line : args::getLines(mb)) {
// File must begin with #STUB
if (first) {
assert(line == "#STUB\n");
first = false;
}
// Lines starting with # are considered comments
if (line.startswith("#"))
continue;
StringRef sym;
StringRef rest;
std::tie(sym, rest) = line.split(':');
sym = strip(sym);
rest = strip(rest);
symbolDependencies[sym] = {};
while (rest.size()) {
StringRef first;
std::tie(first, rest) = rest.split(',');
first = strip(first);
symbolDependencies[sym].push_back(first);
}
}
}
void ArchiveFile::parse() {
// Parse a MemoryBufferRef as an archive file.
LLVM_DEBUG(dbgs() << "Parsing library: " << toString(this) << "\n");