summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSam Clegg <sbc@chromium.org>2018-06-28 16:53:53 +0000
committerSam Clegg <sbc@chromium.org>2018-06-28 16:53:53 +0000
commitcefbf9aca1d52505ecd0a4a526f5b914ae760078 (patch)
treeea37b7da299bf317a63795e9ff418ece49f80d21
parentcdc5f6ad5c79a175c959f0dfb1a27f55e53892c5 (diff)
downloadbcm5719-llvm-cefbf9aca1d52505ecd0a4a526f5b914ae760078.tar.gz
bcm5719-llvm-cefbf9aca1d52505ecd0a4a526f5b914ae760078.zip
[WebAssembly] LTO: Fix signatures of undefined functions in bitcode
Function symbols that come from bitcode have not signatures. After LTO when the real symbols are read in we need to make sure that we set the signature on the existing symbol. the signature-less undefined functions. Differential Revision: https://reviews.llvm.org/D48693 llvm-svn: 335875
-rw-r--r--lld/test/wasm/lto/undef.ll20
-rw-r--r--lld/wasm/Driver.cpp4
-rw-r--r--lld/wasm/SymbolTable.cpp18
-rw-r--r--lld/wasm/Symbols.h6
-rw-r--r--lld/wasm/Writer.cpp6
5 files changed, 40 insertions, 14 deletions
diff --git a/lld/test/wasm/lto/undef.ll b/lld/test/wasm/lto/undef.ll
new file mode 100644
index 00000000000..729007b50c0
--- /dev/null
+++ b/lld/test/wasm/lto/undef.ll
@@ -0,0 +1,20 @@
+; RUN: llvm-as %s -o %t.o
+; RUN: wasm-ld %t.o -o %t.wasm --allow-undefined
+; RUN: obj2yaml %t.wasm | FileCheck %s
+
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown"
+
+declare void @bar()
+
+define void @_start() {
+ call void @bar()
+ ret void
+}
+
+; CHECK: - Type: IMPORT
+; CHECK-NEXT: Imports:
+; CHECK-NEXT: - Module: env
+; CHECK-NEXT: Field: bar
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: SigIndex: 0
diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
index 70a36046ad9..f77f20f4232 100644
--- a/lld/wasm/Driver.cpp
+++ b/lld/wasm/Driver.cpp
@@ -257,8 +257,8 @@ static void handleWeakUndefines() {
// It is possible for undefined functions not to have a signature (eg. if
// added via "--undefined"), but weak undefined ones do have a signature.
- assert(FuncSym->getFunctionType());
- const WasmSignature &Sig = *FuncSym->getFunctionType();
+ assert(FuncSym->FunctionType);
+ const WasmSignature &Sig = *FuncSym->FunctionType;
// Add a synthetic dummy for weak undefined functions. These dummies will
// be GC'd if not used as the target of any "call" instructions.
diff --git a/lld/wasm/SymbolTable.cpp b/lld/wasm/SymbolTable.cpp
index 1180cfc6759..6541ddcdb87 100644
--- a/lld/wasm/SymbolTable.cpp
+++ b/lld/wasm/SymbolTable.cpp
@@ -106,7 +106,7 @@ static void reportTypeError(const Symbol *Existing, const InputFile *File,
" in " + toString(File));
}
-static void checkFunctionType(const Symbol *Existing, const InputFile *File,
+static void checkFunctionType(Symbol *Existing, const InputFile *File,
const WasmSignature *NewSig) {
auto ExistingFunction = dyn_cast<FunctionSymbol>(Existing);
if (!ExistingFunction) {
@@ -114,13 +114,20 @@ static void checkFunctionType(const Symbol *Existing, const InputFile *File,
return;
}
- const WasmSignature *OldSig = ExistingFunction->getFunctionType();
- if (OldSig && NewSig && *NewSig != *OldSig) {
+ if (!NewSig)
+ return;
+
+ const WasmSignature *OldSig = ExistingFunction->FunctionType;
+ if (!OldSig) {
+ ExistingFunction->FunctionType = NewSig;
+ return;
+ }
+
+ if (*NewSig != *OldSig)
warn("function signature mismatch: " + Existing->getName() +
"\n>>> defined as " + toString(*OldSig) + " in " +
toString(Existing->getFile()) + "\n>>> defined as " +
toString(*NewSig) + " in " + toString(File));
- }
}
// Check the type of new symbol matches that of the symbol is replacing.
@@ -286,8 +293,9 @@ Symbol *SymbolTable::addUndefinedFunction(StringRef Name, uint32_t Flags,
replaceSymbol<UndefinedFunction>(S, Name, Flags, File, Sig);
else if (auto *Lazy = dyn_cast<LazySymbol>(S))
Lazy->fetch();
- else if (S->isDefined())
+ else
checkFunctionType(S, File, Sig);
+
return S;
}
diff --git a/lld/wasm/Symbols.h b/lld/wasm/Symbols.h
index a1a41bea9dc..a4d6e0bbf0f 100644
--- a/lld/wasm/Symbols.h
+++ b/lld/wasm/Symbols.h
@@ -114,8 +114,6 @@ public:
S->kind() == UndefinedFunctionKind;
}
- const WasmSignature *getFunctionType() const { return FunctionType; }
-
// Get/set the table index
void setTableIndex(uint32_t Index);
uint32_t getTableIndex() const;
@@ -126,6 +124,8 @@ public:
void setFunctionIndex(uint32_t Index);
bool hasFunctionIndex() const;
+ const WasmSignature *FunctionType;
+
protected:
FunctionSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F,
const WasmSignature *Type)
@@ -133,8 +133,6 @@ protected:
uint32_t TableIndex = INVALID_INDEX;
uint32_t FunctionIndex = INVALID_INDEX;
-
- const WasmSignature *FunctionType;
};
class DefinedFunction : public FunctionSymbol {
diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp
index 70d52bdb72d..41562e3c532 100644
--- a/lld/wasm/Writer.cpp
+++ b/lld/wasm/Writer.cpp
@@ -175,7 +175,7 @@ void Writer::createImportSection() {
Import.Field = Sym->getName();
if (auto *FunctionSym = dyn_cast<FunctionSymbol>(Sym)) {
Import.Kind = WASM_EXTERNAL_FUNCTION;
- Import.SigIndex = lookupType(*FunctionSym->getFunctionType());
+ Import.SigIndex = lookupType(*FunctionSym->FunctionType);
} else {
auto *GlobalSym = cast<GlobalSymbol>(Sym);
Import.Kind = WASM_EXTERNAL_GLOBAL;
@@ -850,7 +850,7 @@ void Writer::calculateTypes() {
for (const Symbol *Sym : ImportedSymbols)
if (auto *F = dyn_cast<FunctionSymbol>(Sym))
- registerType(*F->getFunctionType());
+ registerType(*F->FunctionType);
for (const InputFunction *F : InputFunctions)
registerType(F->Signature);
@@ -993,7 +993,7 @@ void Writer::calculateInitFunctions() {
const WasmLinkingData &L = File->getWasmObj()->linkingData();
for (const WasmInitFunc &F : L.InitFunctions) {
FunctionSymbol *Sym = File->getFunctionSymbol(F.Symbol);
- if (*Sym->getFunctionType() != WasmSignature{{}, WASM_TYPE_NORESULT})
+ if (*Sym->FunctionType != WasmSignature{{}, WASM_TYPE_NORESULT})
error("invalid signature for init func: " + toString(*Sym));
InitFunctions.emplace_back(WasmInitEntry{Sym, F.Priority});
}
OpenPOWER on IntegriCloud