diff options
author | Sam Clegg <sbc@chromium.org> | 2018-06-28 16:53:53 +0000 |
---|---|---|
committer | Sam Clegg <sbc@chromium.org> | 2018-06-28 16:53:53 +0000 |
commit | cefbf9aca1d52505ecd0a4a526f5b914ae760078 (patch) | |
tree | ea37b7da299bf317a63795e9ff418ece49f80d21 | |
parent | cdc5f6ad5c79a175c959f0dfb1a27f55e53892c5 (diff) | |
download | bcm5719-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.ll | 20 | ||||
-rw-r--r-- | lld/wasm/Driver.cpp | 4 | ||||
-rw-r--r-- | lld/wasm/SymbolTable.cpp | 18 | ||||
-rw-r--r-- | lld/wasm/Symbols.h | 6 | ||||
-rw-r--r-- | lld/wasm/Writer.cpp | 6 |
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}); } |