summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/test/wasm/shared-needed.ll38
-rw-r--r--lld/test/wasm/shared.ll2
-rw-r--r--lld/wasm/InputFiles.cpp7
-rw-r--r--lld/wasm/InputFiles.h11
-rw-r--r--lld/wasm/SymbolTable.cpp2
-rw-r--r--lld/wasm/SymbolTable.h1
-rw-r--r--lld/wasm/Writer.cpp5
-rw-r--r--llvm/lib/Object/WasmObjectFile.cpp1
8 files changed, 65 insertions, 2 deletions
diff --git a/lld/test/wasm/shared-needed.ll b/lld/test/wasm/shared-needed.ll
new file mode 100644
index 00000000000..f0afb109850
--- /dev/null
+++ b/lld/test/wasm/shared-needed.ll
@@ -0,0 +1,38 @@
+; RUN: llc -filetype=obj %s -o %t.o
+; RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o
+
+; RUN: wasm-ld -shared -o %t1.so %t.o
+; RUN: obj2yaml %t1.so | FileCheck %s -check-prefix=SO1
+
+; RUN: wasm-ld -shared -o %t2.so %t1.so %t.ret32.o
+; RUN: obj2yaml %t2.so | FileCheck %s -check-prefix=SO2
+
+target triple = "wasm32-unknown-unknown"
+
+@data = global i32 2, align 4
+
+define default void @foo() {
+entry:
+ ret void
+}
+
+; SO1: Sections:
+; SO1-NEXT: - Type: CUSTOM
+; SO1-NEXT: Name: dylink
+; SO1-NEXT: MemorySize: 4
+; SO1-NEXT: MemoryAlignment: 2
+; SO1-NEXT: TableSize: 0
+; SO1-NEXT: TableAlignment: 0
+; SO1-NEXT: Needed: []
+; SO1-NEXT: - Type: TYPE
+
+; SO2: Sections:
+; SO2-NEXT: - Type: CUSTOM
+; SO2-NEXT: Name: dylink
+; SO2-NEXT: MemorySize: 0
+; SO2-NEXT: MemoryAlignment: 0
+; SO2-NEXT: TableSize: 0
+; SO2-NEXT: TableAlignment: 0
+; SO2-NEXT: Needed:
+; SO2-NEXT: - shared-needed.ll.tmp1.so
+; SO2-NEXT: - Type: TYPE
diff --git a/lld/test/wasm/shared.ll b/lld/test/wasm/shared.ll
index 21fd8550b87..b83e61ed1a8 100644
--- a/lld/test/wasm/shared.ll
+++ b/lld/test/wasm/shared.ll
@@ -33,6 +33,8 @@ declare void @func_external()
; CHECK-NEXT: MemoryAlignment: 2
; CHECK-NEXT: TableSize: 2
; CHECK-NEXT: TableAlignment: 0
+; CHECK-NEXT: Needed: []
+; CHECK-NEXT: - Type: TYPE
; check for import of __table_base and __memory_base globals
diff --git a/lld/wasm/InputFiles.cpp b/lld/wasm/InputFiles.cpp
index 2a5c10e3909..5c9ae60e543 100644
--- a/lld/wasm/InputFiles.cpp
+++ b/lld/wasm/InputFiles.cpp
@@ -44,8 +44,13 @@ Optional<MemoryBufferRef> lld::wasm::readFile(StringRef Path) {
InputFile *lld::wasm::createObjectFile(MemoryBufferRef MB) {
file_magic Magic = identify_magic(MB.getBuffer());
- if (Magic == file_magic::wasm_object)
+ if (Magic == file_magic::wasm_object) {
+ std::unique_ptr<Binary> Bin = check(createBinary(MB));
+ auto *Obj = cast<WasmObjectFile>(Bin.get());
+ if (Obj->isSharedObject())
+ return make<SharedFile>(MB);
return make<ObjFile>(MB);
+ }
if (Magic == file_magic::bitcode)
return make<BitcodeFile>(MB);
diff --git a/lld/wasm/InputFiles.h b/lld/wasm/InputFiles.h
index 07d72de09d8..1f44f5b5ec3 100644
--- a/lld/wasm/InputFiles.h
+++ b/lld/wasm/InputFiles.h
@@ -33,6 +33,7 @@ class InputFile {
public:
enum Kind {
ObjectKind,
+ SharedKind,
ArchiveKind,
BitcodeKind,
};
@@ -129,6 +130,16 @@ private:
std::unique_ptr<WasmObjectFile> WasmObj;
};
+// .so file.
+class SharedFile : public InputFile {
+public:
+ explicit SharedFile(MemoryBufferRef M) : InputFile(SharedKind, M) {}
+ static bool classof(const InputFile *F) { return F->kind() == SharedKind; }
+
+ void parse() override {}
+};
+
+// .bc file
class BitcodeFile : public InputFile {
public:
explicit BitcodeFile(MemoryBufferRef M) : InputFile(BitcodeKind, M) {}
diff --git a/lld/wasm/SymbolTable.cpp b/lld/wasm/SymbolTable.cpp
index 1e7357d5d60..5d7ed8c1bc0 100644
--- a/lld/wasm/SymbolTable.cpp
+++ b/lld/wasm/SymbolTable.cpp
@@ -37,6 +37,8 @@ void SymbolTable::addFile(InputFile *File) {
BitcodeFiles.push_back(F);
else if (auto *F = dyn_cast<ObjFile>(File))
ObjectFiles.push_back(F);
+ else if (auto *F = dyn_cast<SharedFile>(File))
+ SharedFiles.push_back(F);
}
// This function is where all the optimizations of link-time
diff --git a/lld/wasm/SymbolTable.h b/lld/wasm/SymbolTable.h
index 3d0529af41d..afb1bb97d44 100644
--- a/lld/wasm/SymbolTable.h
+++ b/lld/wasm/SymbolTable.h
@@ -39,6 +39,7 @@ public:
void addCombinedLTOObject();
std::vector<ObjFile *> ObjectFiles;
+ std::vector<InputFile *> SharedFiles;
std::vector<BitcodeFile *> BitcodeFiles;
std::vector<InputFunction *> SyntheticFunctions;
std::vector<InputGlobal *> SyntheticGlobals;
diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp
index 12b526d3777..42affb4168a 100644
--- a/lld/wasm/Writer.cpp
+++ b/lld/wasm/Writer.cpp
@@ -28,6 +28,7 @@
#include "llvm/Support/Format.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/LEB128.h"
+#include "llvm/Support/Path.h"
#include <cstdarg>
#include <map>
@@ -502,7 +503,9 @@ void Writer::createDylinkSection() {
writeUleb128(OS, MemAlign, "MemAlign");
writeUleb128(OS, IndirectFunctions.size(), "TableSize");
writeUleb128(OS, 0, "TableAlign");
- writeUleb128(OS, 0, "Needed"); // TODO: Support "needed" shared libraries
+ writeUleb128(OS, Symtab->SharedFiles.size(), "Needed");
+ for (auto *SO : Symtab->SharedFiles)
+ writeStr(OS, llvm::sys::path::filename(SO->getName()), "so name");
}
// Create the custom "linking" section containing linker metadata.
diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp
index 9d084bf4753..2ff2c555d5e 100644
--- a/llvm/lib/Object/WasmObjectFile.cpp
+++ b/llvm/lib/Object/WasmObjectFile.cpp
@@ -324,6 +324,7 @@ Error WasmObjectFile::parseSection(WasmSection &Sec) {
Error WasmObjectFile::parseDylinkSection(ReadContext &Ctx) {
// See https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md
+ HasDylinkSection = true;
DylinkInfo.MemorySize = readVaruint32(Ctx);
DylinkInfo.MemoryAlignment = readVaruint32(Ctx);
DylinkInfo.TableSize = readVaruint32(Ctx);
OpenPOWER on IntegriCloud