forked from OSchip/llvm-project
[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:
parent
cdc5f6ad5c
commit
cefbf9aca1
|
@ -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
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue