[lld][WebAssembly] Preserve symbol flags in --relocatable output
Fixes https://github.com/emscripten-core/emscripten/issues/8879
Differential Revision: https://reviews.llvm.org/D67729
git-svn-id: https://llvm.org/svn/llvm-project/lld/trunk@372660 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/wasm/relocatable.ll b/test/wasm/relocatable.ll
index aba4279..5ccaadf 100644
--- a/test/wasm/relocatable.ll
+++ b/test/wasm/relocatable.ll
@@ -34,6 +34,9 @@
ret i32 ptrtoint ([3 x i8]* @data_comdat to i32)
}
+; Test that __attribute__(used) (i.e NO_STRIP) is preserved in the relocated symbol table
+@llvm.used = appending global [1 x i8*] [i8* bitcast (i32 ()* @my_func to i8*)], section "llvm.metadata"
+
; CHECK: --- !WASM
; CHECK-NEXT: FileHeader:
; CHECK-NEXT: Version: 0x00000001
@@ -188,7 +191,7 @@
; NORMAL-NEXT: - Index: 3
; NORMAL-NEXT: Kind: FUNCTION
; NORMAL-NEXT: Name: my_func
-; NORMAL-NEXT: Flags: [ VISIBILITY_HIDDEN ]
+; NORMAL-NEXT: Flags: [ VISIBILITY_HIDDEN, NO_STRIP ]
; NORMAL-NEXT: Function: 4
; NORMAL-NEXT: - Index: 4
; NORMAL-NEXT: Kind: FUNCTION
diff --git a/wasm/Driver.cpp b/wasm/Driver.cpp
index 9a42fa1..34801c1 100644
--- a/wasm/Driver.cpp
+++ b/wasm/Driver.cpp
@@ -441,10 +441,8 @@
static UndefinedGlobal *
createUndefinedGlobal(StringRef name, llvm::wasm::WasmGlobalType *type) {
- auto *sym =
- cast<UndefinedGlobal>(symtab->addUndefinedGlobal(name, name,
- defaultModule, 0,
- nullptr, type));
+ auto *sym = cast<UndefinedGlobal>(symtab->addUndefinedGlobal(
+ name, name, defaultModule, WASM_SYMBOL_UNDEFINED, nullptr, type));
config->allowUndefinedSymbols.insert(sym->getName());
sym->isUsedInRegularObj = true;
return sym;
@@ -582,7 +580,8 @@
};
static Symbol *addUndefined(StringRef name) {
- return symtab->addUndefinedFunction(name, "", "", 0, nullptr, nullptr, false);
+ return symtab->addUndefinedFunction(name, "", "", WASM_SYMBOL_UNDEFINED,
+ nullptr, nullptr, false);
}
// Handles -wrap option.
diff --git a/wasm/InputFiles.cpp b/wasm/InputFiles.cpp
index 6ec4b9d..ed9378c 100644
--- a/wasm/InputFiles.cpp
+++ b/wasm/InputFiles.cpp
@@ -421,7 +421,7 @@
Symbol *ObjFile::createUndefined(const WasmSymbol &sym, bool isCalledDirectly) {
StringRef name = sym.Info.Name;
- uint32_t flags = sym.Info.Flags;
+ uint32_t flags = sym.Info.Flags | WASM_SYMBOL_UNDEFINED;
switch (sym.Info.Kind) {
case WASM_SYMBOL_TYPE_FUNCTION:
@@ -509,6 +509,7 @@
bool excludedByComdat = c != -1 && !keptComdats[c];
if (objSym.isUndefined() || excludedByComdat) {
+ flags |= WASM_SYMBOL_UNDEFINED;
if (objSym.isExecutable())
return symtab->addUndefinedFunction(name, name, defaultModule, flags, &f,
nullptr, true);
diff --git a/wasm/SymbolTable.cpp b/wasm/SymbolTable.cpp
index 44417b0..b53ddaf 100644
--- a/wasm/SymbolTable.cpp
+++ b/wasm/SymbolTable.cpp
@@ -401,6 +401,7 @@
LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << name << " ["
<< (sig ? toString(*sig) : "none")
<< "] IsCalledDirectly:" << isCalledDirectly << "\n");
+ assert(flags & WASM_SYMBOL_UNDEFINED);
Symbol *s;
bool wasInserted;
@@ -443,6 +444,7 @@
Symbol *SymbolTable::addUndefinedData(StringRef name, uint32_t flags,
InputFile *file) {
LLVM_DEBUG(dbgs() << "addUndefinedData: " << name << "\n");
+ assert(flags & WASM_SYMBOL_UNDEFINED);
Symbol *s;
bool wasInserted;
@@ -464,6 +466,7 @@
InputFile *file,
const WasmGlobalType *type) {
LLVM_DEBUG(dbgs() << "addUndefinedGlobal: " << name << "\n");
+ assert(flags & WASM_SYMBOL_UNDEFINED);
Symbol *s;
bool wasInserted;
diff --git a/wasm/SyntheticSections.cpp b/wasm/SyntheticSections.cpp
index f2d4c2e..c3dd32a 100644
--- a/wasm/SyntheticSections.cpp
+++ b/wasm/SyntheticSections.cpp
@@ -362,26 +362,6 @@
return numSegments && config->sharedMemory;
}
-static uint32_t getWasmFlags(const Symbol *sym) {
- uint32_t flags = 0;
- if (sym->isLocal())
- flags |= WASM_SYMBOL_BINDING_LOCAL;
- if (sym->isWeak())
- flags |= WASM_SYMBOL_BINDING_WEAK;
- if (sym->isHidden())
- flags |= WASM_SYMBOL_VISIBILITY_HIDDEN;
- if (sym->isUndefined())
- flags |= WASM_SYMBOL_UNDEFINED;
- if (auto *f = dyn_cast<UndefinedFunction>(sym)) {
- if (f->getName() != f->importName)
- flags |= WASM_SYMBOL_EXPLICIT_NAME;
- } else if (auto *g = dyn_cast<UndefinedGlobal>(sym)) {
- if (g->getName() != g->importName)
- flags |= WASM_SYMBOL_EXPLICIT_NAME;
- }
- return flags;
-}
-
void LinkingSection::writeBody() {
raw_ostream &os = bodyOutputStream;
@@ -394,7 +374,7 @@
for (const Symbol *sym : symtabEntries) {
assert(sym->isDefined() || sym->isUndefined());
WasmSymbolType kind = sym->getWasmType();
- uint32_t flags = getWasmFlags(sym);
+ uint32_t flags = sym->getFlags();
writeU8(sub.os, kind, "sym kind");
writeUleb128(sub.os, flags, "sym flags");