1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

[WebAssembly] Fix types for address taken functions

Differential Revision: https://reviews.llvm.org/D34966

llvm-svn: 307198
This commit is contained in:
Sam Clegg 2017-07-05 20:25:08 +00:00
parent f216b66f0e
commit d6548e35b2
7 changed files with 70 additions and 40 deletions

View File

@ -21,6 +21,8 @@ private:
std::string ModuleName; std::string ModuleName;
SmallVector<wasm::ValType, 1> Returns; SmallVector<wasm::ValType, 1> Returns;
SmallVector<wasm::ValType, 4> Params; SmallVector<wasm::ValType, 4> Params;
bool ParamsSet = false;
bool ReturnsSet = false;
/// An expression describing how to calculate the size of a symbol. If a /// An expression describing how to calculate the size of a symbol. If a
/// symbol has no size this field will be NULL. /// symbol has no size this field will be NULL.
@ -45,15 +47,23 @@ public:
const StringRef getModuleName() const { return ModuleName; } const StringRef getModuleName() const { return ModuleName; }
const SmallVector<wasm::ValType, 1> &getReturns() const { return Returns; } const SmallVector<wasm::ValType, 1> &getReturns() const {
assert(ReturnsSet);
return Returns;
}
void setReturns(SmallVectorImpl<wasm::ValType> &&Rets) { void setReturns(SmallVectorImpl<wasm::ValType> &&Rets) {
ReturnsSet = true;
Returns = std::move(Rets); Returns = std::move(Rets);
} }
const SmallVector<wasm::ValType, 4> &getParams() const { return Params; } const SmallVector<wasm::ValType, 4> &getParams() const {
assert(ParamsSet);
return Params;
}
void setParams(SmallVectorImpl<wasm::ValType> &&Pars) { void setParams(SmallVectorImpl<wasm::ValType> &&Pars) {
ParamsSet = true;
Params = std::move(Pars); Params = std::move(Pars);
} }
}; };

View File

@ -153,7 +153,7 @@ struct WasmRelocationEntry {
} }
void print(raw_ostream &Out) const { void print(raw_ostream &Out) const {
Out << "Off=" << Offset << ", Sym=" << Symbol << ", Addend=" << Addend Out << "Off=" << Offset << ", Sym=" << *Symbol << ", Addend=" << Addend
<< ", Type=" << Type << ", FixupSection=" << FixupSection; << ", Type=" << Type << ", FixupSection=" << FixupSection;
} }

View File

@ -115,8 +115,8 @@ void WebAssemblyTargetAsmStreamer::emitStackPointer(uint32_t Index) {
void WebAssemblyTargetAsmStreamer::emitEndFunc() { OS << "\t.endfunc\n"; } void WebAssemblyTargetAsmStreamer::emitEndFunc() { OS << "\t.endfunc\n"; }
void WebAssemblyTargetAsmStreamer::emitIndirectFunctionType( void WebAssemblyTargetAsmStreamer::emitIndirectFunctionType(
StringRef name, SmallVectorImpl<MVT> &Params, SmallVectorImpl<MVT> &Results) { MCSymbol *Symbol, SmallVectorImpl<MVT> &Params, SmallVectorImpl<MVT> &Results) {
OS << "\t.functype\t" << name; OS << "\t.functype\t" << Symbol->getName();
if (Results.empty()) if (Results.empty())
OS << ", void"; OS << ", void";
else { else {
@ -171,7 +171,7 @@ void WebAssemblyTargetELFStreamer::emitIndIdx(const MCExpr *Value) {
} }
void WebAssemblyTargetELFStreamer::emitIndirectFunctionType( void WebAssemblyTargetELFStreamer::emitIndirectFunctionType(
StringRef name, SmallVectorImpl<MVT> &Params, SmallVectorImpl<MVT> &Results) { MCSymbol *Symbol, SmallVectorImpl<MVT> &Params, SmallVectorImpl<MVT> &Results) {
// Nothing to emit here. TODO: Re-design how linking works and re-evaluate // Nothing to emit here. TODO: Re-design how linking works and re-evaluate
// whether it's necessary for .o files to declare indirect function types. // whether it's necessary for .o files to declare indirect function types.
} }
@ -255,9 +255,25 @@ void WebAssemblyTargetWasmStreamer::emitIndIdx(const MCExpr *Value) {
} }
void WebAssemblyTargetWasmStreamer::emitIndirectFunctionType( void WebAssemblyTargetWasmStreamer::emitIndirectFunctionType(
StringRef name, SmallVectorImpl<MVT> &Params, SmallVectorImpl<MVT> &Results) { MCSymbol *Symbol, SmallVectorImpl<MVT> &Params,
// Nothing to emit here. TODO: Re-design how linking works and re-evaluate SmallVectorImpl<MVT> &Results) {
// whether it's necessary for .o files to declare indirect function types. MCSymbolWasm *WasmSym = cast<MCSymbolWasm>(Symbol);
if (WasmSym->isFunction()) {
// Symbol already has its arguments and result set.
return;
}
SmallVector<wasm::ValType, 4> ValParams;
for (MVT Ty : Params)
ValParams.push_back(WebAssembly::toValType(Ty));
SmallVector<wasm::ValType, 1> ValResults;
for (MVT Ty : Results)
ValResults.push_back(WebAssembly::toValType(Ty));
WasmSym->setParams(std::move(ValParams));
WasmSym->setReturns(std::move(ValResults));
WasmSym->setIsFunction(true);
} }
void WebAssemblyTargetWasmStreamer::emitGlobalImport(StringRef name) { void WebAssemblyTargetWasmStreamer::emitGlobalImport(StringRef name) {

View File

@ -44,7 +44,7 @@ public:
/// .endfunc /// .endfunc
virtual void emitEndFunc() = 0; virtual void emitEndFunc() = 0;
/// .functype /// .functype
virtual void emitIndirectFunctionType(StringRef name, virtual void emitIndirectFunctionType(MCSymbol *Symbol,
SmallVectorImpl<MVT> &Params, SmallVectorImpl<MVT> &Params,
SmallVectorImpl<MVT> &Results) = 0; SmallVectorImpl<MVT> &Results) = 0;
/// .indidx /// .indidx
@ -69,7 +69,7 @@ public:
void emitGlobal(ArrayRef<wasm::Global> Globals) override; void emitGlobal(ArrayRef<wasm::Global> Globals) override;
void emitStackPointer(uint32_t Index) override; void emitStackPointer(uint32_t Index) override;
void emitEndFunc() override; void emitEndFunc() override;
void emitIndirectFunctionType(StringRef name, void emitIndirectFunctionType(MCSymbol *Symbol,
SmallVectorImpl<MVT> &Params, SmallVectorImpl<MVT> &Params,
SmallVectorImpl<MVT> &Results) override; SmallVectorImpl<MVT> &Results) override;
void emitIndIdx(const MCExpr *Value) override; void emitIndIdx(const MCExpr *Value) override;
@ -87,7 +87,7 @@ public:
void emitGlobal(ArrayRef<wasm::Global> Globals) override; void emitGlobal(ArrayRef<wasm::Global> Globals) override;
void emitStackPointer(uint32_t Index) override; void emitStackPointer(uint32_t Index) override;
void emitEndFunc() override; void emitEndFunc() override;
void emitIndirectFunctionType(StringRef name, void emitIndirectFunctionType(MCSymbol *Symbol,
SmallVectorImpl<MVT> &Params, SmallVectorImpl<MVT> &Params,
SmallVectorImpl<MVT> &Results) override; SmallVectorImpl<MVT> &Results) override;
void emitIndIdx(const MCExpr *Value) override; void emitIndIdx(const MCExpr *Value) override;
@ -105,7 +105,7 @@ public:
void emitGlobal(ArrayRef<wasm::Global> Globals) override; void emitGlobal(ArrayRef<wasm::Global> Globals) override;
void emitStackPointer(uint32_t Index) override; void emitStackPointer(uint32_t Index) override;
void emitEndFunc() override; void emitEndFunc() override;
void emitIndirectFunctionType(StringRef name, void emitIndirectFunctionType(MCSymbol *Symbol,
SmallVectorImpl<MVT> &Params, SmallVectorImpl<MVT> &Params,
SmallVectorImpl<MVT> &Results) override; SmallVectorImpl<MVT> &Results) override;
void emitIndIdx(const MCExpr *Value) override; void emitIndIdx(const MCExpr *Value) override;

View File

@ -84,7 +84,7 @@ void WebAssemblyAsmPrinter::EmitEndOfAsmFile(Module &M) {
SmallVector<MVT, 4> Results; SmallVector<MVT, 4> Results;
SmallVector<MVT, 4> Params; SmallVector<MVT, 4> Params;
ComputeSignatureVTs(F, TM, Params, Results); ComputeSignatureVTs(F, TM, Params, Results);
getTargetStreamer()->emitIndirectFunctionType(F.getName(), Params, getTargetStreamer()->emitIndirectFunctionType(getSymbol(&F), Params,
Results); Results);
} }
} }
@ -214,11 +214,8 @@ void WebAssemblyAsmPrinter::EmitInstruction(const MachineInstr *MI) {
const MCExpr *WebAssemblyAsmPrinter::lowerConstant(const Constant *CV) { const MCExpr *WebAssemblyAsmPrinter::lowerConstant(const Constant *CV) {
if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV)) if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV))
if (GV->getValueType()->isFunctionTy()) { if (GV->getValueType()->isFunctionTy()) {
MCSymbol* Sym = getSymbol(GV);
if (!isa<MCSymbolELF>(Sym))
cast<MCSymbolWasm>(Sym)->setIsFunction(true);
return MCSymbolRefExpr::create( return MCSymbolRefExpr::create(
Sym, MCSymbolRefExpr::VK_WebAssembly_FUNCTION, OutContext); getSymbol(GV), MCSymbolRefExpr::VK_WebAssembly_FUNCTION, OutContext);
} }
return AsmPrinter::lowerConstant(CV); return AsmPrinter::lowerConstant(CV);
} }

View File

@ -112,8 +112,6 @@ MCOperand WebAssemblyMCInstLower::LowerSymbolOperand(MCSymbol *Sym,
MCSymbolRefExpr::VariantKind VK = MCSymbolRefExpr::VariantKind VK =
IsFunc ? MCSymbolRefExpr::VK_WebAssembly_FUNCTION IsFunc ? MCSymbolRefExpr::VK_WebAssembly_FUNCTION
: MCSymbolRefExpr::VK_None; : MCSymbolRefExpr::VK_None;
if (!isa<MCSymbolELF>(Sym))
cast<MCSymbolWasm>(Sym)->setIsFunction(IsFunc);
const MCExpr *Expr = MCSymbolRefExpr::create(Sym, VK, Ctx); const MCExpr *Expr = MCSymbolRefExpr::create(Sym, VK, Ctx);

View File

@ -2,24 +2,33 @@
; Verify that addresses of external functions generate correctly typed ; Verify that addresses of external functions generate correctly typed
; imports and relocations or type R_TABLE_INDEX_I32. ; imports and relocations or type R_TABLE_INDEX_I32.
declare void @f1() #1 declare void @f1(i32) #1
@ptr_to_f1 = hidden global void ()* @f1, align 4 @ptr_to_f1 = hidden global void (i32)* @f1, align 4
; CHECK: --- !WASM
; CHECK: - Type: IMPORT ; CHECK-NEXT: FileHeader:
; CHECK: Imports: ; CHECK-NEXT: Version: 0x00000001
; CHECK: - Module: env ; CHECK-NEXT: Sections:
; CHECK: Field: f1 ; CHECK-NEXT: - Type: TYPE
; CHECK: Kind: FUNCTION ; CHECK-NEXT: Signatures:
; CHECK: SigIndex: 0 ; CHECK-NEXT: - Index: 0
; CHECK: - Type: ELEM ; CHECK-NEXT: ReturnType: NORESULT
; CHECK: Segments: ; CHECK-NEXT: ParamTypes:
; CHECK: - Offset: ; CHECK-NEXT: - I32
; CHECK: Opcode: I32_CONST ; CHECK: - Type: IMPORT
; CHECK: Value: 0 ; CHECK-NEXT: Imports:
; CHECK: Functions: [ 0 ] ; CHECK-NEXT: - Module: env
; CHECK: - Type: DATA ; CHECK-NEXT: Field: f1
; CHECK: Relocations: ; CHECK-NEXT: Kind: FUNCTION
; CHECK: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32 ; CHECK-NEXT: SigIndex: 0
; CHECK: Index: 0 ; CHECK: - Type: ELEM
; CHECK: Offset: 0x00000006 ; CHECK-NEXT: Segments:
; CHECK-NEXT: - Offset:
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 0
; CHECK-NEXT: Functions: [ 0 ]
; CHECK: - Type: DATA
; CHECK-NEXT: Relocations:
; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32
; CHECK-NEXT: Index: 0
; CHECK-NEXT: Offset: 0x00000006