[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
This commit is contained in:
Sam Clegg 2018-06-28 16:53:53 +00:00
parent cdc5f6ad5c
commit cefbf9aca1
5 changed files with 40 additions and 14 deletions

View File

@ -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

View File

@ -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.

View File

@ -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;
}

View File

@ -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 {

View File

@ -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});
}