forked from OSchip/llvm-project
Revert "[WebAssembly] call_indirect issues table number relocs"
This reverts commit 861dbe1a02
. It broke
emscripten -- see https://reviews.llvm.org/D90948#2578843.
This commit is contained in:
parent
dd68f3cf28
commit
7dc98adbb0
|
@ -1,5 +1,5 @@
|
||||||
; RUN: llc -filetype=obj %s -o %t.o
|
; RUN: llc -filetype=obj %s -o %t.o
|
||||||
; RUN: llvm-mc -mattr=+reference-types -filetype=obj -triple=wasm32-unknown-unknown %p/Inputs/call-indirect.s -o %t2.o
|
; RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %p/Inputs/call-indirect.s -o %t2.o
|
||||||
; RUN: wasm-ld --export-dynamic -o %t.wasm %t2.o %t.o
|
; RUN: wasm-ld --export-dynamic -o %t.wasm %t2.o %t.o
|
||||||
; RUN: obj2yaml %t.wasm | FileCheck %s
|
; RUN: obj2yaml %t.wasm | FileCheck %s
|
||||||
; RUN: wasm-ld --export-dynamic -O2 -o %t-opt.wasm %t2.o %t.o
|
; RUN: wasm-ld --export-dynamic -O2 -o %t-opt.wasm %t2.o %t.o
|
||||||
|
@ -22,5 +22,5 @@ entry:
|
||||||
|
|
||||||
; ERROR: wasm-ld: error: --compress-relocations is incompatible with output debug information. Please pass --strip-debug or --strip-all
|
; ERROR: wasm-ld: error: --compress-relocations is incompatible with output debug information. Please pass --strip-debug or --strip-all
|
||||||
|
|
||||||
; CHECK: Body: 41002802808880800011808080800080808080001A41002802848880800011818080800080808080001A0B
|
; CHECK: Body: 410028028088808000118080808000001A410028028488808000118180808000001A0B
|
||||||
; COMPRESS: Body: 4100280280081100001A4100280284081101001A0B
|
; COMPRESS: Body: 4100280280081100001A4100280284081101001A0B
|
||||||
|
|
|
@ -18,7 +18,6 @@ class MCSymbolWasm : public MCSymbol {
|
||||||
bool IsWeak = false;
|
bool IsWeak = false;
|
||||||
bool IsHidden = false;
|
bool IsHidden = false;
|
||||||
bool IsComdat = false;
|
bool IsComdat = false;
|
||||||
bool OmitFromLinkingSection = false;
|
|
||||||
mutable bool IsUsedInInitArray = false;
|
mutable bool IsUsedInInitArray = false;
|
||||||
mutable bool IsUsedInGOT = false;
|
mutable bool IsUsedInGOT = false;
|
||||||
Optional<StringRef> ImportModule;
|
Optional<StringRef> ImportModule;
|
||||||
|
@ -76,12 +75,6 @@ public:
|
||||||
bool isComdat() const { return IsComdat; }
|
bool isComdat() const { return IsComdat; }
|
||||||
void setComdat(bool isComdat) { IsComdat = isComdat; }
|
void setComdat(bool isComdat) { IsComdat = isComdat; }
|
||||||
|
|
||||||
// wasm-ld understands a finite set of symbol types. This flag allows the
|
|
||||||
// compiler to avoid emitting symbol table entries that would confuse the
|
|
||||||
// linker, unless the user specifically requests the feature.
|
|
||||||
bool omitFromLinkingSection() const { return OmitFromLinkingSection; }
|
|
||||||
void setOmitFromLinkingSection() { OmitFromLinkingSection = true; }
|
|
||||||
|
|
||||||
bool hasImportModule() const { return ImportModule.hasValue(); }
|
bool hasImportModule() const { return ImportModule.hasValue(); }
|
||||||
StringRef getImportModule() const {
|
StringRef getImportModule() const {
|
||||||
if (ImportModule.hasValue())
|
if (ImportModule.hasValue())
|
||||||
|
|
|
@ -405,17 +405,12 @@ void WasmObjectWriter::writeHeader(const MCAssembler &Asm) {
|
||||||
|
|
||||||
void WasmObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
|
void WasmObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
|
||||||
const MCAsmLayout &Layout) {
|
const MCAsmLayout &Layout) {
|
||||||
// Some compilation units require the indirect function table to be present
|
// As a stopgap measure until call_indirect instructions start explicitly
|
||||||
// but don't explicitly reference it. This is the case for call_indirect
|
// referencing the indirect function table via TABLE_NUMBER relocs, ensure
|
||||||
// without the reference-types feature, and also function bitcasts in all
|
// that the indirect function table import makes it to the output if anything
|
||||||
// cases. In those cases the __indirect_function_table has the
|
// in the compilation unit has caused it to be present.
|
||||||
// WASM_SYMBOL_NO_STRIP attribute. Here we make sure this symbol makes it to
|
if (auto *Sym = Asm.getContext().lookupSymbol("__indirect_function_table"))
|
||||||
// the assembler, if needed.
|
Asm.registerSymbol(*Sym);
|
||||||
if (auto *Sym = Asm.getContext().lookupSymbol("__indirect_function_table")) {
|
|
||||||
const auto *WasmSym = static_cast<const MCSymbolWasm *>(Sym);
|
|
||||||
if (WasmSym->isNoStrip())
|
|
||||||
Asm.registerSymbol(*Sym);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build a map of sections to the function that defines them, for use
|
// Build a map of sections to the function that defines them, for use
|
||||||
// in recordRelocation.
|
// in recordRelocation.
|
||||||
|
@ -514,18 +509,21 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm,
|
||||||
Type == wasm::R_WASM_TABLE_INDEX_I32 ||
|
Type == wasm::R_WASM_TABLE_INDEX_I32 ||
|
||||||
Type == wasm::R_WASM_TABLE_INDEX_I64) {
|
Type == wasm::R_WASM_TABLE_INDEX_I64) {
|
||||||
// TABLE_INDEX relocs implicitly use the default indirect function table.
|
// TABLE_INDEX relocs implicitly use the default indirect function table.
|
||||||
// We require the function table to have already been defined.
|
|
||||||
auto TableName = "__indirect_function_table";
|
auto TableName = "__indirect_function_table";
|
||||||
MCSymbolWasm *Sym = cast_or_null<MCSymbolWasm>(Ctx.lookupSymbol(TableName));
|
MCSymbolWasm *Sym = cast_or_null<MCSymbolWasm>(Ctx.lookupSymbol(TableName));
|
||||||
if (!Sym || !Sym->isFunctionTable()) {
|
if (Sym) {
|
||||||
Ctx.reportError(
|
if (!Sym->isFunctionTable())
|
||||||
Fixup.getLoc(),
|
Ctx.reportError(
|
||||||
"symbol '__indirect_function_table' is not a function table");
|
Fixup.getLoc(),
|
||||||
|
"symbol '__indirect_function_table' is not a function table");
|
||||||
} else {
|
} else {
|
||||||
// Ensure that __indirect_function_table reaches the output.
|
Sym = cast<MCSymbolWasm>(Ctx.getOrCreateSymbol(TableName));
|
||||||
Sym->setNoStrip();
|
Sym->setFunctionTable();
|
||||||
Asm.registerSymbol(*Sym);
|
// The default function table is synthesized by the linker.
|
||||||
|
Sym->setUndefined();
|
||||||
}
|
}
|
||||||
|
Sym->setUsedInReloc();
|
||||||
|
Asm.registerSymbol(*Sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Relocation other than R_WASM_TYPE_INDEX_LEB are required to be
|
// Relocation other than R_WASM_TYPE_INDEX_LEB are required to be
|
||||||
|
@ -1213,9 +1211,6 @@ static bool isInSymtab(const MCSymbolWasm &Sym) {
|
||||||
if (Sym.isSection())
|
if (Sym.isSection())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (Sym.omitFromLinkingSection())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1679,6 +1674,10 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
|
||||||
WS.setIndex(InvalidIndex);
|
WS.setIndex(InvalidIndex);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (WS.isTable() && WS.getName() == "__indirect_function_table") {
|
||||||
|
// For the moment, don't emit table symbols -- wasm-ld can't handle them.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
LLVM_DEBUG(dbgs() << "adding to symtab: " << WS << "\n");
|
LLVM_DEBUG(dbgs() << "adding to symtab: " << WS << "\n");
|
||||||
|
|
||||||
uint32_t Flags = 0;
|
uint32_t Flags = 0;
|
||||||
|
|
|
@ -171,6 +171,9 @@ struct WebAssemblyOperand : public MCParsedAsmOperand {
|
||||||
|
|
||||||
static MCSymbolWasm *GetOrCreateFunctionTableSymbol(MCContext &Ctx,
|
static MCSymbolWasm *GetOrCreateFunctionTableSymbol(MCContext &Ctx,
|
||||||
const StringRef &Name) {
|
const StringRef &Name) {
|
||||||
|
// FIXME: Duplicates functionality from
|
||||||
|
// MC/WasmObjectWriter::recordRelocation, as well as WebAssemblyCodegen's
|
||||||
|
// WebAssembly:getOrCreateFunctionTableSymbol.
|
||||||
MCSymbolWasm *Sym = cast_or_null<MCSymbolWasm>(Ctx.lookupSymbol(Name));
|
MCSymbolWasm *Sym = cast_or_null<MCSymbolWasm>(Ctx.lookupSymbol(Name));
|
||||||
if (Sym) {
|
if (Sym) {
|
||||||
if (!Sym->isFunctionTable())
|
if (!Sym->isFunctionTable())
|
||||||
|
@ -220,7 +223,6 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
|
||||||
};
|
};
|
||||||
std::vector<NestingType> NestingStack;
|
std::vector<NestingType> NestingStack;
|
||||||
|
|
||||||
MCSymbolWasm *DefaultFunctionTable = nullptr;
|
|
||||||
MCSymbol *LastFunctionLabel = nullptr;
|
MCSymbol *LastFunctionLabel = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -231,15 +233,6 @@ public:
|
||||||
setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
|
setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Initialize(MCAsmParser &Parser) override {
|
|
||||||
MCAsmParserExtension::Initialize(Parser);
|
|
||||||
|
|
||||||
DefaultFunctionTable = GetOrCreateFunctionTableSymbol(
|
|
||||||
getContext(), "__indirect_function_table");
|
|
||||||
if (!STI->checkFeatures("+reference-types"))
|
|
||||||
DefaultFunctionTable->setOmitFromLinkingSection();
|
|
||||||
}
|
|
||||||
|
|
||||||
#define GET_ASSEMBLER_HEADER
|
#define GET_ASSEMBLER_HEADER
|
||||||
#include "WebAssemblyGenAsmMatcher.inc"
|
#include "WebAssemblyGenAsmMatcher.inc"
|
||||||
|
|
||||||
|
@ -487,39 +480,6 @@ public:
|
||||||
WebAssemblyOperand::IntOp{static_cast<int64_t>(BT)}));
|
WebAssemblyOperand::IntOp{static_cast<int64_t>(BT)}));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool addFunctionTableOperand(OperandVector &Operands, MCSymbolWasm *Sym,
|
|
||||||
SMLoc StartLoc, SMLoc EndLoc) {
|
|
||||||
const auto *Val = MCSymbolRefExpr::create(Sym, getContext());
|
|
||||||
Operands.push_back(std::make_unique<WebAssemblyOperand>(
|
|
||||||
WebAssemblyOperand::Symbol, StartLoc, EndLoc,
|
|
||||||
WebAssemblyOperand::SymOp{Val}));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool addFunctionTableOperand(OperandVector &Operands, StringRef TableName,
|
|
||||||
SMLoc StartLoc, SMLoc EndLoc) {
|
|
||||||
return addFunctionTableOperand(
|
|
||||||
Operands, GetOrCreateFunctionTableSymbol(getContext(), TableName),
|
|
||||||
StartLoc, EndLoc);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool addDefaultFunctionTableOperand(OperandVector &Operands, SMLoc StartLoc,
|
|
||||||
SMLoc EndLoc) {
|
|
||||||
if (STI->checkFeatures("+reference-types")) {
|
|
||||||
return addFunctionTableOperand(Operands, DefaultFunctionTable, StartLoc,
|
|
||||||
EndLoc);
|
|
||||||
} else {
|
|
||||||
// For the MVP there is at most one table whose number is 0, but we can't
|
|
||||||
// write a table symbol or issue relocations. Instead we just ensure the
|
|
||||||
// table is live and write a zero.
|
|
||||||
getStreamer().emitSymbolAttribute(DefaultFunctionTable, MCSA_NoDeadStrip);
|
|
||||||
Operands.push_back(std::make_unique<WebAssemblyOperand>(
|
|
||||||
WebAssemblyOperand::Integer, StartLoc, EndLoc,
|
|
||||||
WebAssemblyOperand::IntOp{0}));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ParseInstruction(ParseInstructionInfo & /*Info*/, StringRef Name,
|
bool ParseInstruction(ParseInstructionInfo & /*Info*/, StringRef Name,
|
||||||
SMLoc NameLoc, OperandVector &Operands) override {
|
SMLoc NameLoc, OperandVector &Operands) override {
|
||||||
// Note: Name does NOT point into the sourcecode, but to a local, so
|
// Note: Name does NOT point into the sourcecode, but to a local, so
|
||||||
|
@ -556,7 +516,6 @@ public:
|
||||||
bool ExpectBlockType = false;
|
bool ExpectBlockType = false;
|
||||||
bool ExpectFuncType = false;
|
bool ExpectFuncType = false;
|
||||||
bool ExpectHeapType = false;
|
bool ExpectHeapType = false;
|
||||||
bool ExpectFunctionTable = false;
|
|
||||||
if (Name == "block") {
|
if (Name == "block") {
|
||||||
push(Block);
|
push(Block);
|
||||||
ExpectBlockType = true;
|
ExpectBlockType = true;
|
||||||
|
@ -603,7 +562,15 @@ public:
|
||||||
return true;
|
return true;
|
||||||
} else if (Name == "call_indirect" || Name == "return_call_indirect") {
|
} else if (Name == "call_indirect" || Name == "return_call_indirect") {
|
||||||
ExpectFuncType = true;
|
ExpectFuncType = true;
|
||||||
ExpectFunctionTable = true;
|
// Ensure that the object file has a __indirect_function_table import, as
|
||||||
|
// we call_indirect against it.
|
||||||
|
auto &Ctx = getStreamer().getContext();
|
||||||
|
MCSymbolWasm *Sym =
|
||||||
|
GetOrCreateFunctionTableSymbol(Ctx, "__indirect_function_table");
|
||||||
|
// Until call_indirect emits TABLE_NUMBER relocs against this symbol, mark
|
||||||
|
// it as NO_STRIP so as to ensure that the indirect function table makes
|
||||||
|
// it to linked output.
|
||||||
|
Sym->setNoStrip();
|
||||||
} else if (Name == "ref.null") {
|
} else if (Name == "ref.null") {
|
||||||
ExpectHeapType = true;
|
ExpectHeapType = true;
|
||||||
}
|
}
|
||||||
|
@ -619,7 +586,7 @@ public:
|
||||||
return true;
|
return true;
|
||||||
// Got signature as block type, don't need more
|
// Got signature as block type, don't need more
|
||||||
ExpectBlockType = false;
|
ExpectBlockType = false;
|
||||||
auto &Ctx = getContext();
|
auto &Ctx = getStreamer().getContext();
|
||||||
// The "true" here will cause this to be a nameless symbol.
|
// The "true" here will cause this to be a nameless symbol.
|
||||||
MCSymbol *Sym = Ctx.createTempSymbol("typeindex", true);
|
MCSymbol *Sym = Ctx.createTempSymbol("typeindex", true);
|
||||||
auto *WasmSym = cast<MCSymbolWasm>(Sym);
|
auto *WasmSym = cast<MCSymbolWasm>(Sym);
|
||||||
|
@ -631,16 +598,6 @@ public:
|
||||||
Operands.push_back(std::make_unique<WebAssemblyOperand>(
|
Operands.push_back(std::make_unique<WebAssemblyOperand>(
|
||||||
WebAssemblyOperand::Symbol, Loc.getLoc(), Loc.getEndLoc(),
|
WebAssemblyOperand::Symbol, Loc.getLoc(), Loc.getEndLoc(),
|
||||||
WebAssemblyOperand::SymOp{Expr}));
|
WebAssemblyOperand::SymOp{Expr}));
|
||||||
|
|
||||||
// Allow additional operands after the signature, notably for
|
|
||||||
// call_indirect against a named table.
|
|
||||||
if (Lexer.isNot(AsmToken::EndOfStatement)) {
|
|
||||||
if (expect(AsmToken::Comma, ","))
|
|
||||||
return true;
|
|
||||||
if (Lexer.is(AsmToken::EndOfStatement)) {
|
|
||||||
return error("Unexpected trailing comma");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (Lexer.isNot(AsmToken::EndOfStatement)) {
|
while (Lexer.isNot(AsmToken::EndOfStatement)) {
|
||||||
|
@ -666,11 +623,6 @@ public:
|
||||||
WebAssemblyOperand::Integer, Id.getLoc(), Id.getEndLoc(),
|
WebAssemblyOperand::Integer, Id.getLoc(), Id.getEndLoc(),
|
||||||
WebAssemblyOperand::IntOp{static_cast<int64_t>(HeapType)}));
|
WebAssemblyOperand::IntOp{static_cast<int64_t>(HeapType)}));
|
||||||
Parser.Lex();
|
Parser.Lex();
|
||||||
} else if (ExpectFunctionTable) {
|
|
||||||
if (addFunctionTableOperand(Operands, Id.getString(), Id.getLoc(),
|
|
||||||
Id.getEndLoc()))
|
|
||||||
return true;
|
|
||||||
Parser.Lex();
|
|
||||||
} else {
|
} else {
|
||||||
// Assume this identifier is a label.
|
// Assume this identifier is a label.
|
||||||
const MCExpr *Val;
|
const MCExpr *Val;
|
||||||
|
@ -737,12 +689,6 @@ public:
|
||||||
// Support blocks with no operands as default to void.
|
// Support blocks with no operands as default to void.
|
||||||
addBlockTypeOperand(Operands, NameLoc, WebAssembly::BlockType::Void);
|
addBlockTypeOperand(Operands, NameLoc, WebAssembly::BlockType::Void);
|
||||||
}
|
}
|
||||||
if (ExpectFunctionTable && Operands.size() == 2) {
|
|
||||||
// If call_indirect doesn't specify a target table, supply one.
|
|
||||||
if (addDefaultFunctionTableOperand(Operands, NameLoc,
|
|
||||||
SMLoc::getFromPointer(Name.end())))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
Parser.Lex();
|
Parser.Lex();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, uint64_t Address,
|
||||||
for (auto I = Start, E = MI->getNumOperands(); I < E; ++I) {
|
for (auto I = Start, E = MI->getNumOperands(); I < E; ++I) {
|
||||||
if (MI->getOpcode() == WebAssembly::CALL_INDIRECT &&
|
if (MI->getOpcode() == WebAssembly::CALL_INDIRECT &&
|
||||||
I - Start == NumVariadicDefs) {
|
I - Start == NumVariadicDefs) {
|
||||||
// Skip type and table arguments when printing for tests.
|
// Skip type and flags arguments when printing for tests
|
||||||
++I;
|
++I;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
#include "WebAssemblyMachineFunctionInfo.h"
|
#include "WebAssemblyMachineFunctionInfo.h"
|
||||||
#include "WebAssemblyRegisterInfo.h"
|
#include "WebAssemblyRegisterInfo.h"
|
||||||
#include "WebAssemblyTargetMachine.h"
|
#include "WebAssemblyTargetMachine.h"
|
||||||
#include "WebAssemblyUtilities.h"
|
|
||||||
#include "llvm/ADT/SmallSet.h"
|
#include "llvm/ADT/SmallSet.h"
|
||||||
#include "llvm/ADT/StringExtras.h"
|
#include "llvm/ADT/StringExtras.h"
|
||||||
#include "llvm/BinaryFormat/Wasm.h"
|
#include "llvm/BinaryFormat/Wasm.h"
|
||||||
|
@ -172,25 +171,19 @@ MCSymbolWasm *WebAssemblyAsmPrinter::getMCSymbolForFunction(
|
||||||
|
|
||||||
void WebAssemblyAsmPrinter::emitEndOfAsmFile(Module &M) {
|
void WebAssemblyAsmPrinter::emitEndOfAsmFile(Module &M) {
|
||||||
for (auto &It : OutContext.getSymbols()) {
|
for (auto &It : OutContext.getSymbols()) {
|
||||||
// Emit .globaltype, .eventtype, or .tabletype declarations.
|
// Emit a .globaltype and .eventtype declaration.
|
||||||
auto Sym = cast<MCSymbolWasm>(It.getValue());
|
auto Sym = cast<MCSymbolWasm>(It.getValue());
|
||||||
if (Sym->getType() == wasm::WASM_SYMBOL_TYPE_GLOBAL)
|
if (Sym->getType() == wasm::WASM_SYMBOL_TYPE_GLOBAL)
|
||||||
getTargetStreamer()->emitGlobalType(Sym);
|
getTargetStreamer()->emitGlobalType(Sym);
|
||||||
else if (Sym->getType() == wasm::WASM_SYMBOL_TYPE_EVENT)
|
else if (Sym->getType() == wasm::WASM_SYMBOL_TYPE_EVENT)
|
||||||
getTargetStreamer()->emitEventType(Sym);
|
getTargetStreamer()->emitEventType(Sym);
|
||||||
else if (Sym->getType() == wasm::WASM_SYMBOL_TYPE_TABLE)
|
|
||||||
getTargetStreamer()->emitTableType(Sym);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DenseSet<MCSymbol *> InvokeSymbols;
|
DenseSet<MCSymbol *> InvokeSymbols;
|
||||||
bool HasAddressTakenFunction = false;
|
|
||||||
for (const auto &F : M) {
|
for (const auto &F : M) {
|
||||||
if (F.isIntrinsic())
|
if (F.isIntrinsic())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (F.hasAddressTaken())
|
|
||||||
HasAddressTakenFunction = true;
|
|
||||||
|
|
||||||
// Emit function type info for all undefined functions
|
// Emit function type info for all undefined functions
|
||||||
if (F.isDeclarationForLinker()) {
|
if (F.isDeclarationForLinker()) {
|
||||||
SmallVector<MVT, 4> Results;
|
SmallVector<MVT, 4> Results;
|
||||||
|
@ -249,18 +242,6 @@ void WebAssemblyAsmPrinter::emitEndOfAsmFile(Module &M) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// When a function's address is taken, a TABLE_INDEX relocation is emitted
|
|
||||||
// against the function symbol at the use site. However the relocation
|
|
||||||
// doesn't explicitly refer to the table. In the future we may want to
|
|
||||||
// define a new kind of reloc against both the function and the table, so
|
|
||||||
// that the linker can see that the function symbol keeps the table alive,
|
|
||||||
// but for now manually mark the table as live.
|
|
||||||
if (HasAddressTakenFunction) {
|
|
||||||
MCSymbolWasm *FunctionTable =
|
|
||||||
WebAssembly::getOrCreateFunctionTableSymbol(OutContext, Subtarget);
|
|
||||||
OutStreamer->emitSymbolAttribute(FunctionTable, MCSA_NoDeadStrip);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto &G : M.globals()) {
|
for (const auto &G : M.globals()) {
|
||||||
if (!G.hasInitializer() && G.hasExternalLinkage()) {
|
if (!G.hasInitializer() && G.hasExternalLinkage()) {
|
||||||
if (G.getValueType()->isSized()) {
|
if (G.getValueType()->isSized()) {
|
||||||
|
|
|
@ -869,20 +869,19 @@ bool WebAssemblyFastISel::selectCall(const Instruction *I) {
|
||||||
if (IsDirect) {
|
if (IsDirect) {
|
||||||
MIB.addGlobalAddress(Func);
|
MIB.addGlobalAddress(Func);
|
||||||
} else {
|
} else {
|
||||||
// Placehoder for the type index.
|
// Add placeholders for the type index and immediate flags
|
||||||
MIB.addImm(0);
|
MIB.addImm(0);
|
||||||
// The table into which this call_indirect indexes.
|
MIB.addImm(0);
|
||||||
MCSymbolWasm *Table = WebAssembly::getOrCreateFunctionTableSymbol(
|
|
||||||
MF->getMMI().getContext(), Subtarget);
|
// Ensure that the object file has a __indirect_function_table import, as we
|
||||||
if (Subtarget->hasReferenceTypes()) {
|
// call_indirect against it.
|
||||||
MIB.addSym(Table);
|
MCSymbolWasm *Sym = WebAssembly::getOrCreateFunctionTableSymbol(
|
||||||
} else {
|
MF->getMMI().getContext(), "__indirect_function_table");
|
||||||
// Otherwise for the MVP there is at most one table whose number is 0, but
|
// Until call_indirect emits TABLE_NUMBER relocs against this symbol, mark
|
||||||
// we can't write a table symbol or issue relocations. Instead we just
|
// it as NO_STRIP so as to ensure that the indirect function table makes it
|
||||||
// ensure the table is live.
|
// to linked output.
|
||||||
Table->setNoStrip();
|
Sym->setNoStrip();
|
||||||
MIB.addImm(0);
|
|
||||||
}
|
|
||||||
// See if we must truncate the function pointer.
|
// See if we must truncate the function pointer.
|
||||||
// CALL_INDIRECT takes an i32, but in wasm64 we represent function pointers
|
// CALL_INDIRECT takes an i32, but in wasm64 we represent function pointers
|
||||||
// as 64-bit for uniformity with other pointer types.
|
// as 64-bit for uniformity with other pointer types.
|
||||||
|
|
|
@ -426,10 +426,9 @@ static MachineBasicBlock *LowerFPToInt(MachineInstr &MI, DebugLoc DL,
|
||||||
return DoneMBB;
|
return DoneMBB;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MachineBasicBlock *
|
static MachineBasicBlock *LowerCallResults(MachineInstr &CallResults,
|
||||||
LowerCallResults(MachineInstr &CallResults, DebugLoc DL, MachineBasicBlock *BB,
|
DebugLoc DL, MachineBasicBlock *BB,
|
||||||
const WebAssemblySubtarget *Subtarget,
|
const TargetInstrInfo &TII) {
|
||||||
const TargetInstrInfo &TII) {
|
|
||||||
MachineInstr &CallParams = *CallResults.getPrevNode();
|
MachineInstr &CallParams = *CallResults.getPrevNode();
|
||||||
assert(CallParams.getOpcode() == WebAssembly::CALL_PARAMS);
|
assert(CallParams.getOpcode() == WebAssembly::CALL_PARAMS);
|
||||||
assert(CallResults.getOpcode() == WebAssembly::CALL_RESULTS ||
|
assert(CallResults.getOpcode() == WebAssembly::CALL_RESULTS ||
|
||||||
|
@ -477,21 +476,19 @@ LowerCallResults(MachineInstr &CallResults, DebugLoc DL, MachineBasicBlock *BB,
|
||||||
for (auto Def : CallResults.defs())
|
for (auto Def : CallResults.defs())
|
||||||
MIB.add(Def);
|
MIB.add(Def);
|
||||||
|
|
||||||
|
// Add placeholders for the type index and immediate flags
|
||||||
if (IsIndirect) {
|
if (IsIndirect) {
|
||||||
// Placeholder for the type index.
|
|
||||||
MIB.addImm(0);
|
MIB.addImm(0);
|
||||||
// The table into which this call_indirect indexes.
|
MIB.addImm(0);
|
||||||
MCSymbolWasm *Table =
|
|
||||||
WebAssembly::getOrCreateFunctionTableSymbol(MF.getContext(), Subtarget);
|
// Ensure that the object file has a __indirect_function_table import, as we
|
||||||
if (Subtarget->hasReferenceTypes()) {
|
// call_indirect against it.
|
||||||
MIB.addSym(Table);
|
MCSymbolWasm *Sym = WebAssembly::getOrCreateFunctionTableSymbol(
|
||||||
} else {
|
MF.getContext(), "__indirect_function_table");
|
||||||
// For the MVP there is at most one table whose number is 0, but we can't
|
// Until call_indirect emits TABLE_NUMBER relocs against this symbol, mark
|
||||||
// write a table symbol or issue relocations. Instead we just ensure the
|
// it as NO_STRIP so as to ensure that the indirect function table makes it
|
||||||
// table is live and write a zero.
|
// to linked output.
|
||||||
Table->setNoStrip();
|
Sym->setNoStrip();
|
||||||
MIB.addImm(0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto Use : CallParams.uses())
|
for (auto Use : CallParams.uses())
|
||||||
|
@ -538,7 +535,7 @@ MachineBasicBlock *WebAssemblyTargetLowering::EmitInstrWithCustomInserter(
|
||||||
WebAssembly::I64_TRUNC_U_F64);
|
WebAssembly::I64_TRUNC_U_F64);
|
||||||
case WebAssembly::CALL_RESULTS:
|
case WebAssembly::CALL_RESULTS:
|
||||||
case WebAssembly::RET_CALL_RESULTS:
|
case WebAssembly::RET_CALL_RESULTS:
|
||||||
return LowerCallResults(MI, DL, BB, Subtarget, TII);
|
return LowerCallResults(MI, DL, BB, TII);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,9 +48,6 @@ defm RET_CALL_RESULTS :
|
||||||
I<(outs), (ins variable_ops), (outs), (ins), [],
|
I<(outs), (ins variable_ops), (outs), (ins), [],
|
||||||
"return_call_results", "return_call_results", -1>;
|
"return_call_results", "return_call_results", -1>;
|
||||||
|
|
||||||
// Note that instructions with variable_ops have custom printers in
|
|
||||||
// WebAssemblyInstPrinter.cpp.
|
|
||||||
|
|
||||||
let variadicOpsAreDefs = 1 in
|
let variadicOpsAreDefs = 1 in
|
||||||
defm CALL :
|
defm CALL :
|
||||||
I<(outs), (ins function32_op:$callee, variable_ops),
|
I<(outs), (ins function32_op:$callee, variable_ops),
|
||||||
|
@ -59,12 +56,9 @@ defm CALL :
|
||||||
|
|
||||||
let variadicOpsAreDefs = 1 in
|
let variadicOpsAreDefs = 1 in
|
||||||
defm CALL_INDIRECT :
|
defm CALL_INDIRECT :
|
||||||
I<(outs),
|
I<(outs), (ins TypeIndex:$type, i32imm:$flags, variable_ops),
|
||||||
(ins TypeIndex:$type, table32_op:$table, variable_ops),
|
(outs), (ins TypeIndex:$type, i32imm:$flags), [],
|
||||||
(outs),
|
"call_indirect", "call_indirect\t$type", 0x11>;
|
||||||
(ins TypeIndex:$type, table32_op:$table),
|
|
||||||
[],
|
|
||||||
"call_indirect", "call_indirect\t$type, $table", 0x11>;
|
|
||||||
|
|
||||||
let isReturn = 1, isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in
|
let isReturn = 1, isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in
|
||||||
defm RET_CALL :
|
defm RET_CALL :
|
||||||
|
@ -75,9 +69,9 @@ defm RET_CALL :
|
||||||
|
|
||||||
let isReturn = 1 in
|
let isReturn = 1 in
|
||||||
defm RET_CALL_INDIRECT :
|
defm RET_CALL_INDIRECT :
|
||||||
I<(outs), (ins TypeIndex:$type, table32_op:$table, variable_ops),
|
I<(outs), (ins TypeIndex:$type, i32imm:$flags, variable_ops),
|
||||||
(outs), (ins TypeIndex:$type, table32_op:$table), [],
|
(outs), (ins TypeIndex:$type, i32imm:$flags), [],
|
||||||
"return_call_indirect\t", "return_call_indirect\t$type, $table",
|
"return_call_indirect\t", "return_call_indirect\t$type",
|
||||||
0x13>,
|
0x13>,
|
||||||
Requires<[HasTailCall]>;
|
Requires<[HasTailCall]>;
|
||||||
|
|
||||||
|
|
|
@ -161,8 +161,6 @@ MCOperand WebAssemblyMCInstLower::lowerSymbolOperand(const MachineOperand &MO,
|
||||||
report_fatal_error("Global indexes with offsets not supported");
|
report_fatal_error("Global indexes with offsets not supported");
|
||||||
if (WasmSym->isEvent())
|
if (WasmSym->isEvent())
|
||||||
report_fatal_error("Event indexes with offsets not supported");
|
report_fatal_error("Event indexes with offsets not supported");
|
||||||
if (WasmSym->isTable())
|
|
||||||
report_fatal_error("Table indexes with offsets not supported");
|
|
||||||
|
|
||||||
Expr = MCBinaryExpr::createAdd(
|
Expr = MCBinaryExpr::createAdd(
|
||||||
Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
|
Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
|
||||||
|
|
|
@ -98,9 +98,11 @@ const MachineOperand &WebAssembly::getCalleeOp(const MachineInstr &MI) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MCSymbolWasm *WebAssembly::getOrCreateFunctionTableSymbol(
|
MCSymbolWasm *
|
||||||
MCContext &Ctx, const WebAssemblySubtarget *Subtarget) {
|
WebAssembly::getOrCreateFunctionTableSymbol(MCContext &Ctx,
|
||||||
StringRef Name = "__indirect_function_table";
|
const StringRef &Name) {
|
||||||
|
// FIXME: Duplicates functionality from
|
||||||
|
// MC/WasmObjectWriter::recordRelocation.
|
||||||
MCSymbolWasm *Sym = cast_or_null<MCSymbolWasm>(Ctx.lookupSymbol(Name));
|
MCSymbolWasm *Sym = cast_or_null<MCSymbolWasm>(Ctx.lookupSymbol(Name));
|
||||||
if (Sym) {
|
if (Sym) {
|
||||||
if (!Sym->isFunctionTable())
|
if (!Sym->isFunctionTable())
|
||||||
|
@ -111,9 +113,6 @@ MCSymbolWasm *WebAssembly::getOrCreateFunctionTableSymbol(
|
||||||
// The default function table is synthesized by the linker.
|
// The default function table is synthesized by the linker.
|
||||||
Sym->setUndefined();
|
Sym->setUndefined();
|
||||||
}
|
}
|
||||||
// MVP object files can't have symtab entries for tables.
|
|
||||||
if (!Subtarget->hasReferenceTypes())
|
|
||||||
Sym->setOmitFromLinkingSection();
|
|
||||||
return Sym;
|
return Sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,6 @@ class MCContext;
|
||||||
class MCSymbolWasm;
|
class MCSymbolWasm;
|
||||||
class StringRef;
|
class StringRef;
|
||||||
class WebAssemblyFunctionInfo;
|
class WebAssemblyFunctionInfo;
|
||||||
class WebAssemblySubtarget;
|
|
||||||
|
|
||||||
namespace WebAssembly {
|
namespace WebAssembly {
|
||||||
|
|
||||||
|
@ -42,11 +41,10 @@ extern const char *const PersonalityWrapperFn;
|
||||||
/// instruction.
|
/// instruction.
|
||||||
const MachineOperand &getCalleeOp(const MachineInstr &MI);
|
const MachineOperand &getCalleeOp(const MachineInstr &MI);
|
||||||
|
|
||||||
/// Returns the __indirect_function_table, for use in call_indirect and in
|
/// Returns the operand number of a callee, assuming the argument is a call
|
||||||
/// function bitcasts.
|
/// instruction.
|
||||||
MCSymbolWasm *
|
MCSymbolWasm *getOrCreateFunctionTableSymbol(MCContext &Ctx,
|
||||||
getOrCreateFunctionTableSymbol(MCContext &Ctx,
|
const StringRef &Name);
|
||||||
const WebAssemblySubtarget *Subtarget);
|
|
||||||
|
|
||||||
/// Find a catch instruction from an EH pad. Returns null if no catch
|
/// Find a catch instruction from an EH pad. Returns null if no catch
|
||||||
/// instruction found or the catch is in an invalid location.
|
/// instruction found or the catch is in an invalid location.
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
; RUN: llc < %s -asm-verbose=false -O2 | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -O2 | FileCheck %s
|
||||||
; RUN: llc < %s -asm-verbose=false -mattr=+reference-types -O2 | FileCheck --check-prefix=REF %s
|
|
||||||
; RUN: llc < %s -asm-verbose=false -O2 --filetype=obj | obj2yaml | FileCheck --check-prefix=YAML %s
|
; RUN: llc < %s -asm-verbose=false -O2 --filetype=obj | obj2yaml | FileCheck --check-prefix=YAML %s
|
||||||
|
|
||||||
; This tests pointer features that may codegen differently in wasm64.
|
; This tests pointer features that may codegen differently in wasm64.
|
||||||
|
@ -35,16 +34,14 @@ entry:
|
||||||
; CHECK-NEXT: i32.const 1
|
; CHECK-NEXT: i32.const 1
|
||||||
; CHECK-NEXT: local.get 0
|
; CHECK-NEXT: local.get 0
|
||||||
; CHECK-NEXT: i32.wrap_i64
|
; CHECK-NEXT: i32.wrap_i64
|
||||||
; CHECK-NEXT: call_indirect (i32) -> (), 0
|
; CHECK-NEXT: call_indirect (i32) -> ()
|
||||||
; REF: call_indirect (i32) -> (), __indirect_function_table
|
|
||||||
|
|
||||||
; CHECK: .functype test () -> ()
|
; CHECK: .functype test () -> ()
|
||||||
; CHECK-NEXT: i64.const bar
|
; CHECK-NEXT: i64.const bar
|
||||||
; CHECK-NEXT: call foo
|
; CHECK-NEXT: call foo
|
||||||
|
|
||||||
|
|
||||||
; Check we're emitting a 64-bit relocs for the call_indirect, the
|
; Check we're emitting a 64-bit reloc for `i64.const bar` and the global.
|
||||||
; `i64.const bar` reference in code, and the global.
|
|
||||||
|
|
||||||
; YAML: Memory:
|
; YAML: Memory:
|
||||||
; YAML-NEXT: Flags: [ IS_64 ]
|
; YAML-NEXT: Flags: [ IS_64 ]
|
||||||
|
@ -54,9 +51,6 @@ entry:
|
||||||
; YAML: - Type: R_WASM_TABLE_INDEX_SLEB64
|
; YAML: - Type: R_WASM_TABLE_INDEX_SLEB64
|
||||||
; YAML-NEXT: Index: 0
|
; YAML-NEXT: Index: 0
|
||||||
; YAML-NEXT: Offset: 0x16
|
; YAML-NEXT: Offset: 0x16
|
||||||
; YAML: - Type: R_WASM_TABLE_INDEX_SLEB64
|
|
||||||
; YAML-NEXT: Index: 0
|
|
||||||
; YAML-NEXT: Offset: 0x29
|
|
||||||
|
|
||||||
; YAML: - Type: DATA
|
; YAML: - Type: DATA
|
||||||
; YAML: - Type: R_WASM_TABLE_INDEX_I64
|
; YAML: - Type: R_WASM_TABLE_INDEX_I64
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -mattr=+multivalue,+tail-call | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -mattr=+multivalue,+tail-call | FileCheck %s
|
||||||
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -mattr=+reference-types,+multivalue,+tail-call | FileCheck --check-prefix REF %s
|
|
||||||
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+multivalue,+tail-call | FileCheck %s --check-prefix REGS
|
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+multivalue,+tail-call | FileCheck %s --check-prefix REGS
|
||||||
; RUN: llc < %s --filetype=obj -mattr=+multivalue,+tail-call | obj2yaml | FileCheck %s --check-prefix OBJ
|
; RUN: llc < %s --filetype=obj -mattr=+multivalue,+tail-call | obj2yaml | FileCheck %s --check-prefix OBJ
|
||||||
|
|
||||||
|
@ -58,8 +57,7 @@ define %pair @pair_call_return() {
|
||||||
; CHECK-LABEL: pair_call_indirect:
|
; CHECK-LABEL: pair_call_indirect:
|
||||||
; CHECK-NEXT: .functype pair_call_indirect (i32) -> (i32, i64)
|
; CHECK-NEXT: .functype pair_call_indirect (i32) -> (i32, i64)
|
||||||
; CHECK-NEXT: local.get 0{{$}}
|
; CHECK-NEXT: local.get 0{{$}}
|
||||||
; CHECK-NEXT: call_indirect () -> (i32, i64), 0{{$}}
|
; CHECK-NEXT: call_indirect () -> (i32, i64){{$}}
|
||||||
; REF: call_indirect () -> (i32, i64), __indirect_function_table{{$}}
|
|
||||||
; CHECK-NEXT: end_function{{$}}
|
; CHECK-NEXT: end_function{{$}}
|
||||||
; REGS: call_indirect $push{{[0-9]+}}=, $push{{[0-9]+}}=, $0{{$}}
|
; REGS: call_indirect $push{{[0-9]+}}=, $push{{[0-9]+}}=, $0{{$}}
|
||||||
define %pair @pair_call_indirect(%pair()* %f) {
|
define %pair @pair_call_indirect(%pair()* %f) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# RUN: llvm-mc -triple=wasm32-unknown-unknown -mattr=+reference-types,atomics,+unimplemented-simd128,+nontrapping-fptoint,+exception-handling < %s | FileCheck %s
|
# RUN: llvm-mc -triple=wasm32-unknown-unknown -mattr=+atomics,+unimplemented-simd128,+nontrapping-fptoint,+exception-handling < %s | FileCheck %s
|
||||||
# Check that it converts to .o without errors, but don't check any output:
|
# Check that it converts to .o without errors, but don't check any output:
|
||||||
# RUN: llvm-mc -triple=wasm32-unknown-unknown -filetype=obj -mattr=+reference-types,+atomics,+unimplemented-simd128,+nontrapping-fptoint,+exception-handling -o %t.o < %s
|
# RUN: llvm-mc -triple=wasm32-unknown-unknown -filetype=obj -mattr=+atomics,+unimplemented-simd128,+nontrapping-fptoint,+exception-handling -o %t.o < %s
|
||||||
|
|
||||||
|
|
||||||
empty_func:
|
empty_func:
|
||||||
|
@ -156,7 +156,7 @@ empty_fref_table:
|
||||||
# CHECK-NEXT: i64.const 1234
|
# CHECK-NEXT: i64.const 1234
|
||||||
# CHECK-NEXT: call something2
|
# CHECK-NEXT: call something2
|
||||||
# CHECK-NEXT: i32.const 0
|
# CHECK-NEXT: i32.const 0
|
||||||
# CHECK-NEXT: call_indirect (i32, f64) -> (), __indirect_function_table
|
# CHECK-NEXT: call_indirect (i32, f64) -> ()
|
||||||
# CHECK-NEXT: i32.const 1
|
# CHECK-NEXT: i32.const 1
|
||||||
# CHECK-NEXT: i32.add
|
# CHECK-NEXT: i32.add
|
||||||
# CHECK-NEXT: local.tee 0
|
# CHECK-NEXT: local.tee 0
|
||||||
|
|
|
@ -1,83 +0,0 @@
|
||||||
# RUN: llvm-mc -triple=wasm32-unknown-unknown -mattr=+reference-types < %s | FileCheck --check-prefix=CHECK %s
|
|
||||||
# RUN: llvm-mc -triple=wasm32-unknown-unknown -mattr=+reference-types -filetype=obj < %s | obj2yaml | FileCheck -check-prefix=BIN %s
|
|
||||||
|
|
||||||
test0:
|
|
||||||
.functype test0 () -> ()
|
|
||||||
i32.const 42
|
|
||||||
f64.const 2.5
|
|
||||||
i32.const 0
|
|
||||||
call_indirect (i32, f64) -> (), empty_fref_table
|
|
||||||
end_function
|
|
||||||
|
|
||||||
.tabletype empty_fref_table, funcref
|
|
||||||
empty_fref_table:
|
|
||||||
|
|
||||||
|
|
||||||
# CHECK: .text
|
|
||||||
# CHECK-LABEL: test0:
|
|
||||||
# CHECK-NEXT: .functype test0 () -> ()
|
|
||||||
# CHECK-NEXT: i32.const 42
|
|
||||||
# CHECK-NEXT: f64.const 0x1.4p1
|
|
||||||
# CHECK-NEXT: i32.const 0
|
|
||||||
# CHECK-NEXT: call_indirect (i32, f64) -> (), empty_fref_table
|
|
||||||
# CHECK-NEXT: end_function
|
|
||||||
|
|
||||||
# CHECK: .tabletype empty_fref_table, funcref
|
|
||||||
# CHECK: empty_fref_table:
|
|
||||||
|
|
||||||
# BIN: --- !WASM
|
|
||||||
# BIN-NEXT: FileHeader:
|
|
||||||
# BIN-NEXT: Version: 0x1
|
|
||||||
# BIN-NEXT: Sections:
|
|
||||||
# BIN-NEXT: - Type: TYPE
|
|
||||||
# BIN-NEXT: Signatures:
|
|
||||||
# BIN-NEXT: - Index: 0
|
|
||||||
# BIN-NEXT: ParamTypes: []
|
|
||||||
# BIN-NEXT: ReturnTypes: []
|
|
||||||
# BIN-NEXT: - Index: 1
|
|
||||||
# BIN-NEXT: ParamTypes:
|
|
||||||
# BIN-NEXT: - I32
|
|
||||||
# BIN-NEXT: - F64
|
|
||||||
# BIN-NEXT: ReturnTypes: []
|
|
||||||
# BIN-NEXT: - Type: IMPORT
|
|
||||||
# BIN-NEXT: Imports:
|
|
||||||
# BIN-NEXT: - Module: env
|
|
||||||
# BIN-NEXT: Field: __linear_memory
|
|
||||||
# BIN-NEXT: Kind: MEMORY
|
|
||||||
# BIN-NEXT: Memory:
|
|
||||||
# BIN-NEXT: Initial: 0x0
|
|
||||||
# BIN-NEXT: - Type: FUNCTION
|
|
||||||
# BIN-NEXT: FunctionTypes: [ 0 ]
|
|
||||||
# BIN-NEXT: - Type: TABLE
|
|
||||||
# BIN-NEXT: Tables:
|
|
||||||
# BIN-NEXT: - Index: 0
|
|
||||||
# BIN-NEXT: ElemType: FUNCREF
|
|
||||||
# BIN-NEXT: Limits:
|
|
||||||
# BIN-NEXT: Initial: 0x0
|
|
||||||
# BIN-NEXT: - Type: CODE
|
|
||||||
# BIN-NEXT: Relocations:
|
|
||||||
# BIN-NEXT: - Type: R_WASM_TYPE_INDEX_LEB
|
|
||||||
# BIN-NEXT: Index: 1
|
|
||||||
# BIN-NEXT: Offset: 0x11
|
|
||||||
# BIN-NEXT: - Type: R_WASM_TABLE_NUMBER_LEB
|
|
||||||
# BIN-NEXT: Index: 1
|
|
||||||
# BIN-NEXT: Offset: 0x16
|
|
||||||
# BIN-NEXT: Functions:
|
|
||||||
# BIN-NEXT: - Index: 0
|
|
||||||
# BIN-NEXT: Locals: []
|
|
||||||
# BIN-NEXT: Body: 412A440000000000000440410011818080800080808080000B
|
|
||||||
# BIN-NEXT: - Type: CUSTOM
|
|
||||||
# BIN-NEXT: Name: linking
|
|
||||||
# BIN-NEXT: Version: 2
|
|
||||||
# BIN-NEXT: SymbolTable:
|
|
||||||
# BIN-NEXT: - Index: 0
|
|
||||||
# BIN-NEXT: Kind: FUNCTION
|
|
||||||
# BIN-NEXT: Name: test0
|
|
||||||
# BIN-NEXT: Flags: [ BINDING_LOCAL ]
|
|
||||||
# BIN-NEXT: Function: 0
|
|
||||||
# BIN-NEXT: - Index: 1
|
|
||||||
# BIN-NEXT: Kind: TABLE
|
|
||||||
# BIN-NEXT: Name: empty_fref_table
|
|
||||||
# BIN-NEXT: Flags: [ BINDING_LOCAL ]
|
|
||||||
# BIN-NEXT: Table: 0
|
|
||||||
# BIN-NEXT: ...
|
|
|
@ -1,5 +1,4 @@
|
||||||
; RUN: llc -filetype=obj %s -o - | llvm-readobj --symbols - | FileCheck %s
|
; RUN: llc -filetype=obj %s -o - | llvm-readobj --symbols - | FileCheck %s
|
||||||
; RUN: llc -filetype=obj %s -mattr=+reference-types -o - | llvm-readobj --symbols - | FileCheck --check-prefix=REF %s
|
|
||||||
|
|
||||||
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
||||||
target triple = "wasm32-unknown-unknown-wasm"
|
target triple = "wasm32-unknown-unknown-wasm"
|
||||||
|
@ -43,44 +42,3 @@ define i8* @func() {
|
||||||
; CHECK-NEXT: ElementIndex: 0x0
|
; CHECK-NEXT: ElementIndex: 0x0
|
||||||
; CHECK-NEXT: }
|
; CHECK-NEXT: }
|
||||||
; CHECK-NEXT: ]
|
; CHECK-NEXT: ]
|
||||||
|
|
||||||
; REF: Symbols [
|
|
||||||
; REF-NEXT: Symbol {
|
|
||||||
; REF-NEXT: Name: func
|
|
||||||
; REF-NEXT: Type: FUNCTION (0x0)
|
|
||||||
; REF-NEXT: Flags [ (0x0)
|
|
||||||
; REF-NEXT: ]
|
|
||||||
; REF-NEXT: ElementIndex: 0x0
|
|
||||||
; REF-NEXT: }
|
|
||||||
; REF-NEXT: Symbol {
|
|
||||||
; REF-NEXT: Name: bar2
|
|
||||||
; REF-NEXT: Type: FUNCTION (0x0)
|
|
||||||
; REF-NEXT: Flags [ (0x0)
|
|
||||||
; REF-NEXT: ]
|
|
||||||
; REF-NEXT: ElementIndex: 0x0
|
|
||||||
; REF-NEXT: }
|
|
||||||
; REF-NEXT: Symbol {
|
|
||||||
; REF-NEXT: Name: foo
|
|
||||||
; REF-NEXT: Type: FUNCTION (0x0)
|
|
||||||
; REF-NEXT: Flags [ (0x0)
|
|
||||||
; REF-NEXT: ]
|
|
||||||
; REF-NEXT: ElementIndex: 0x0
|
|
||||||
; REF-NEXT: }
|
|
||||||
; REF-NEXT: Symbol {
|
|
||||||
; REF-NEXT: Name: bar
|
|
||||||
; REF-NEXT: Type: FUNCTION (0x0)
|
|
||||||
; REF-NEXT: Flags [ (0x0)
|
|
||||||
; REF-NEXT: ]
|
|
||||||
; REF-NEXT: ElementIndex: 0x0
|
|
||||||
; REF-NEXT: }
|
|
||||||
; REF-NEXT: Symbol {
|
|
||||||
; REF-NEXT: Name: __indirect_function_table
|
|
||||||
; REF-NEXT: Type: TABLE (0x5)
|
|
||||||
; REF-NEXT: Flags [ (0x90)
|
|
||||||
; REF-NEXT: NO_STRIP (0x80)
|
|
||||||
; REF-NEXT: UNDEFINED (0x10)
|
|
||||||
; REF-NEXT: ]
|
|
||||||
; REF-NEXT: ImportModule: env
|
|
||||||
; REF-NEXT: ElementIndex: 0x0
|
|
||||||
; REF-NEXT: }
|
|
||||||
; REF-NEXT: ]
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
; RUN: llc -filetype=obj %s -o - | llvm-readobj -r --expand-relocs - | FileCheck %s
|
; RUN: llc -filetype=obj %s -o - | llvm-readobj -r --expand-relocs - | FileCheck %s
|
||||||
; RUN: llc -filetype=obj -mattr=+reference-types %s -o - | llvm-readobj -r --expand-relocs - | FileCheck --check-prefix=REF %s
|
|
||||||
|
|
||||||
target triple = "wasm32-unknown-unknown"
|
target triple = "wasm32-unknown-unknown"
|
||||||
|
|
||||||
|
@ -60,51 +59,3 @@ entry:
|
||||||
; CHECK-NEXT: }
|
; CHECK-NEXT: }
|
||||||
; CHECK-NEXT: }
|
; CHECK-NEXT: }
|
||||||
; CHECK-NEXT: ]
|
; CHECK-NEXT: ]
|
||||||
|
|
||||||
; REF: Format: WASM
|
|
||||||
; REF: Relocations [
|
|
||||||
; REF-NEXT: Section (5) CODE {
|
|
||||||
; REF-NEXT: Relocation {
|
|
||||||
; REF-NEXT: Type: R_WASM_MEMORY_ADDR_LEB (3)
|
|
||||||
; REF-NEXT: Offset: 0x9
|
|
||||||
; REF-NEXT: Symbol: b
|
|
||||||
; REF-NEXT: Addend: 0
|
|
||||||
; REF-NEXT: }
|
|
||||||
; REF-NEXT: Relocation {
|
|
||||||
; REF-NEXT: Type: R_WASM_MEMORY_ADDR_LEB (3)
|
|
||||||
; REF-NEXT: Offset: 0x14
|
|
||||||
; REF-NEXT: Symbol: a
|
|
||||||
; REF-NEXT: Addend: 0
|
|
||||||
; REF-NEXT: }
|
|
||||||
; REF-NEXT: Relocation {
|
|
||||||
; REF-NEXT: Type: R_WASM_TYPE_INDEX_LEB (6)
|
|
||||||
; REF-NEXT: Offset: 0x1A
|
|
||||||
; REF-NEXT: Index: 0x1
|
|
||||||
; REF-NEXT: }
|
|
||||||
; REF-NEXT: Relocation {
|
|
||||||
; REF-NEXT: Type: R_WASM_TABLE_NUMBER_LEB (20)
|
|
||||||
; REF-NEXT: Offset: 0x1F
|
|
||||||
; REF-NEXT: Symbol: __indirect_function_table
|
|
||||||
; REF-NEXT: }
|
|
||||||
; REF-NEXT: Relocation {
|
|
||||||
; REF-NEXT: Type: R_WASM_TYPE_INDEX_LEB (6)
|
|
||||||
; REF-NEXT: Offset: 0x28
|
|
||||||
; REF-NEXT: Index: 0x0
|
|
||||||
; REF-NEXT: }
|
|
||||||
; REF-NEXT: Relocation {
|
|
||||||
; REF-NEXT: Type: R_WASM_TABLE_NUMBER_LEB (20)
|
|
||||||
; REF-NEXT: Offset: 0x2D
|
|
||||||
; REF-NEXT: Symbol: __indirect_function_table
|
|
||||||
; REF-NEXT: }
|
|
||||||
; REF-NEXT: Relocation {
|
|
||||||
; REF-NEXT: Type: R_WASM_FUNCTION_INDEX_LEB (0)
|
|
||||||
; REF-NEXT: Offset: 0x35
|
|
||||||
; REF-NEXT: Symbol: c
|
|
||||||
; REF-NEXT: }
|
|
||||||
; REF-NEXT: Relocation {
|
|
||||||
; REF-NEXT: Type: R_WASM_FUNCTION_INDEX_LEB (0)
|
|
||||||
; REF-NEXT: Offset: 0x3C
|
|
||||||
; REF-NEXT: Symbol: d
|
|
||||||
; REF-NEXT: }
|
|
||||||
; REF-NEXT: }
|
|
||||||
; REF-NEXT: ]
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# RUN: llvm-mc -triple=wasm32-unknown-unknown -filetype=obj < %s | obj2yaml | FileCheck %s
|
# RUN: llvm-mc -triple=wasm32-unknown-unknown -filetype=obj < %s | obj2yaml | FileCheck %s
|
||||||
# RUN: llvm-mc -triple=wasm32-unknown-unknown -mattr=+reference-types -filetype=obj < %s | obj2yaml | FileCheck --check-prefix=REF %s
|
|
||||||
|
|
||||||
# Verify that @GOT relocation entryes result in R_WASM_GLOBAL_INDEX_LEB against
|
# Verify that @GOT relocation entryes result in R_WASM_GLOBAL_INDEX_LEB against
|
||||||
# against the corrsponding function or data symbol and that the corresponding
|
# against the corrsponding function or data symbol and that the corresponding
|
||||||
|
@ -191,11 +190,6 @@ hidden_func:
|
||||||
# CHECK-NEXT: Name: hidden_func
|
# CHECK-NEXT: Name: hidden_func
|
||||||
# CHECK-NEXT: Flags: [ BINDING_LOCAL ]
|
# CHECK-NEXT: Flags: [ BINDING_LOCAL ]
|
||||||
# CHECK-NEXT: Function: 5
|
# CHECK-NEXT: Function: 5
|
||||||
# REF: - Index: 10
|
|
||||||
# REF-NEXT: Kind: TABLE
|
|
||||||
# REF-NEXT: Name: __indirect_function_table
|
|
||||||
# REF-NEXT: Flags: [ UNDEFINED, NO_STRIP ]
|
|
||||||
# REF-NEXT: Table: 0
|
|
||||||
# CHECK-NEXT: SegmentInfo:
|
# CHECK-NEXT: SegmentInfo:
|
||||||
# CHECK-NEXT: - Index: 0
|
# CHECK-NEXT: - Index: 0
|
||||||
# CHECK-NEXT: Name: .rodata.hidden_data
|
# CHECK-NEXT: Name: .rodata.hidden_data
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# RUN: llvm-mc -show-encoding -triple=wasm32-unknown-unknown -mattr=+tail-call < %s | FileCheck %s
|
# RUN: llvm-mc -show-encoding -triple=wasm32-unknown-unknown -mattr=+tail-call < %s | FileCheck %s
|
||||||
# RUN: llvm-mc -show-encoding -triple=wasm32-unknown-unknown -mattr=+reference-types,+tail-call < %s | FileCheck --check-prefix=REF %s
|
|
||||||
|
|
||||||
bar1:
|
bar1:
|
||||||
.functype bar1 () -> ()
|
.functype bar1 () -> ()
|
||||||
|
@ -17,8 +16,7 @@ foo1:
|
||||||
foo2:
|
foo2:
|
||||||
.functype foo2 () -> ()
|
.functype foo2 () -> ()
|
||||||
|
|
||||||
# REF: return_call_indirect (i32) -> (i32), __indirect_function_table # encoding: [0x13,
|
# CHECK: return_call_indirect (i32) -> (i32) # encoding: [0x13,
|
||||||
# CHECK: return_call_indirect (i32) -> (i32), 0 # encoding: [0x13,
|
|
||||||
# CHECK-NEXT: fixup A - offset: 1, value: .Ltypeindex0@TYPEINDEX, kind: fixup_uleb128_i32
|
# CHECK-NEXT: fixup A - offset: 1, value: .Ltypeindex0@TYPEINDEX, kind: fixup_uleb128_i32
|
||||||
return_call_indirect (i32) -> (i32)
|
return_call_indirect (i32) -> (i32)
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# RUN: llvm-mc -triple=wasm32-unknown-unknown -mattr=+reference-types,+unimplemented-simd128,+nontrapping-fptoint,+exception-handling < %s | FileCheck %s
|
# RUN: llvm-mc -triple=wasm32-unknown-unknown -mattr=+unimplemented-simd128,+nontrapping-fptoint,+exception-handling < %s | FileCheck %s
|
||||||
# Check that it converts to .o without errors:
|
# Check that it converts to .o without errors:
|
||||||
# RUN: llvm-mc -triple=wasm32-unknown-unknown -filetype=obj -mattr=+reference-types,+unimplemented-simd128,+nontrapping-fptoint,+exception-handling < %s | obj2yaml | FileCheck -check-prefix=BIN %s
|
# RUN: llvm-mc -triple=wasm32-unknown-unknown -filetype=obj -mattr=+unimplemented-simd128,+nontrapping-fptoint,+exception-handling < %s | obj2yaml | FileCheck -check-prefix=BIN %s
|
||||||
|
|
||||||
# Minimal test for type indices and table references in call_indirect.
|
# Minimal test for type indices in call_indirect.
|
||||||
|
|
||||||
test0:
|
test0:
|
||||||
.functype test0 (i32) -> (i32)
|
.functype test0 (i32) -> (i32)
|
||||||
|
@ -53,13 +53,10 @@ test0:
|
||||||
# BIN-NEXT: - Type: R_WASM_TYPE_INDEX_LEB
|
# BIN-NEXT: - Type: R_WASM_TYPE_INDEX_LEB
|
||||||
# BIN-NEXT: Index: 1
|
# BIN-NEXT: Index: 1
|
||||||
# BIN-NEXT: Offset: 0x4
|
# BIN-NEXT: Offset: 0x4
|
||||||
# BIN-NEXT: - Type: R_WASM_TABLE_NUMBER_LEB
|
|
||||||
# BIN-NEXT: Index: 1
|
|
||||||
# BIN-NEXT: Offset: 0x9
|
|
||||||
# BIN-NEXT: Functions:
|
# BIN-NEXT: Functions:
|
||||||
# BIN-NEXT: - Index: 0
|
# BIN-NEXT: - Index: 0
|
||||||
# BIN-NEXT: Locals: []
|
# BIN-NEXT: Locals: []
|
||||||
# BIN-NEXT: Body: 11818080800080808080000B
|
# BIN-NEXT: Body: 118180808000000B
|
||||||
# BIN-NEXT: - Type: CUSTOM
|
# BIN-NEXT: - Type: CUSTOM
|
||||||
# BIN-NEXT: Name: linking
|
# BIN-NEXT: Name: linking
|
||||||
# BIN-NEXT: Version: 2
|
# BIN-NEXT: Version: 2
|
||||||
|
@ -69,9 +66,4 @@ test0:
|
||||||
# BIN-NEXT: Name: test0
|
# BIN-NEXT: Name: test0
|
||||||
# BIN-NEXT: Flags: [ BINDING_LOCAL ]
|
# BIN-NEXT: Flags: [ BINDING_LOCAL ]
|
||||||
# BIN-NEXT: Function: 0
|
# BIN-NEXT: Function: 0
|
||||||
# BIN-NEXT: - Index: 1
|
|
||||||
# BIN-NEXT: Kind: TABLE
|
|
||||||
# BIN-NEXT: Name: __indirect_function_table
|
|
||||||
# BIN-NEXT: Flags: [ UNDEFINED ]
|
|
||||||
# BIN-NEXT: Table: 0
|
|
||||||
# BIN-NEXT: ...
|
# BIN-NEXT: ...
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# RUN: llvm-mc -triple=wasm32-unknown-unknown -filetype=obj < %s | obj2yaml | FileCheck --check-prefix=CHECK %s
|
# RUN: llvm-mc -triple=wasm32-unknown-unknown -filetype=obj -o %t.o < %s
|
||||||
# RUN: llvm-mc -triple=wasm32-unknown-unknown -mattr=+reference-types -filetype=obj < %s | obj2yaml | FileCheck --check-prefix=REF %s
|
# RUN: obj2yaml %t.o | FileCheck %s
|
||||||
|
|
||||||
# 'foo_alias()' is weak alias of function 'foo()'
|
# 'foo_alias()' is weak alias of function 'foo()'
|
||||||
# 'bar_alias' is weak alias of global variable 'bar'
|
# 'bar_alias' is weak alias of global variable 'bar'
|
||||||
|
@ -78,7 +78,7 @@ alias_address:
|
||||||
# CHECK: - Type: TYPE
|
# CHECK: - Type: TYPE
|
||||||
# CHECK-NEXT: Signatures:
|
# CHECK-NEXT: Signatures:
|
||||||
# CHECK-NEXT: - Index: 0
|
# CHECK-NEXT: - Index: 0
|
||||||
# CHECK-NEXT: ParamTypes: []
|
# CHECK-NEXT: ParamTypes:
|
||||||
# CHECK-NEXT: ReturnTypes:
|
# CHECK-NEXT: ReturnTypes:
|
||||||
# CHECK-NEXT: - I32
|
# CHECK-NEXT: - I32
|
||||||
# CHECK-NEXT: - Type: IMPORT
|
# CHECK-NEXT: - Type: IMPORT
|
||||||
|
@ -128,19 +128,19 @@ alias_address:
|
||||||
# CHECK-NEXT: Offset: 0x37
|
# CHECK-NEXT: Offset: 0x37
|
||||||
# CHECK-NEXT: Functions:
|
# CHECK-NEXT: Functions:
|
||||||
# CHECK-NEXT: - Index: 0
|
# CHECK-NEXT: - Index: 0
|
||||||
# CHECK-NEXT: Locals: []
|
# CHECK-NEXT: Locals:
|
||||||
# CHECK-NEXT: Body: 41000B
|
# CHECK-NEXT: Body: 41000B
|
||||||
# CHECK-NEXT: - Index: 1
|
# CHECK-NEXT: - Index: 1
|
||||||
# CHECK-NEXT: Locals: []
|
# CHECK-NEXT: Locals:
|
||||||
# CHECK-NEXT: Body: 1080808080000B
|
# CHECK-NEXT: Body: 1080808080000B
|
||||||
# CHECK-NEXT: - Index: 2
|
# CHECK-NEXT: - Index: 2
|
||||||
# CHECK-NEXT: Locals: []
|
# CHECK-NEXT: Locals:
|
||||||
# CHECK-NEXT: Body: 1080808080000B
|
# CHECK-NEXT: Body: 1080808080000B
|
||||||
# CHECK-NEXT: - Index: 3
|
# CHECK-NEXT: - Index: 3
|
||||||
# CHECK-NEXT: Locals: []
|
# CHECK-NEXT: Locals:
|
||||||
# CHECK-NEXT: Body: 410028028880808000118080808000000B
|
# CHECK-NEXT: Body: 410028028880808000118080808000000B
|
||||||
# CHECK-NEXT: - Index: 4
|
# CHECK-NEXT: - Index: 4
|
||||||
# CHECK-NEXT: Locals: []
|
# CHECK-NEXT: Locals:
|
||||||
# CHECK-NEXT: Body: 410028029080808000118080808000000B
|
# CHECK-NEXT: Body: 410028029080808000118080808000000B
|
||||||
# CHECK-NEXT: - Type: DATA
|
# CHECK-NEXT: - Type: DATA
|
||||||
# CHECK-NEXT: Relocations:
|
# CHECK-NEXT: Relocations:
|
||||||
|
@ -231,195 +231,17 @@ alias_address:
|
||||||
# CHECK-NEXT: - Index: 0
|
# CHECK-NEXT: - Index: 0
|
||||||
# CHECK-NEXT: Name: .data.bar
|
# CHECK-NEXT: Name: .data.bar
|
||||||
# CHECK-NEXT: Alignment: 3
|
# CHECK-NEXT: Alignment: 3
|
||||||
# CHECK-NEXT: Flags: [ ]
|
# CHECK-NEXT: Flags: [ ]
|
||||||
# CHECK-NEXT: - Index: 1
|
# CHECK-NEXT: - Index: 1
|
||||||
# CHECK-NEXT: Name: .data.direct_address
|
# CHECK-NEXT: Name: .data.direct_address
|
||||||
# CHECK-NEXT: Alignment: 3
|
# CHECK-NEXT: Alignment: 3
|
||||||
# CHECK-NEXT: Flags: [ ]
|
# CHECK-NEXT: Flags: [ ]
|
||||||
# CHECK-NEXT: - Index: 2
|
# CHECK-NEXT: - Index: 2
|
||||||
# CHECK-NEXT: Name: .data.alias_address
|
# CHECK-NEXT: Name: .data.alias_address
|
||||||
# CHECK-NEXT: Alignment: 3
|
# CHECK-NEXT: Alignment: 3
|
||||||
# CHECK-NEXT: Flags: [ ]
|
# CHECK-NEXT: Flags: [ ]
|
||||||
# CHECK-NEXT: ...
|
# CHECK-NEXT: ...
|
||||||
|
|
||||||
# REF: - Type: TYPE
|
|
||||||
# REF-NEXT: Signatures:
|
|
||||||
# REF-NEXT: - Index: 0
|
|
||||||
# REF-NEXT: ParamTypes: []
|
|
||||||
# REF-NEXT: ReturnTypes:
|
|
||||||
# REF-NEXT: - I32
|
|
||||||
# REF-NEXT: - Type: IMPORT
|
|
||||||
# REF-NEXT: Imports:
|
|
||||||
# REF-NEXT: - Module: env
|
|
||||||
# REF-NEXT: Field: __linear_memory
|
|
||||||
# REF-NEXT: Kind: MEMORY
|
|
||||||
# REF-NEXT: Memory:
|
|
||||||
# REF-NEXT: Initial: 0x1
|
|
||||||
# REF-NEXT: - Module: env
|
|
||||||
# REF-NEXT: Field: __indirect_function_table
|
|
||||||
# REF-NEXT: Kind: TABLE
|
|
||||||
# REF-NEXT: Table:
|
|
||||||
# REF-NEXT: Index: 0
|
|
||||||
# REF-NEXT: ElemType: FUNCREF
|
|
||||||
# REF-NEXT: Limits:
|
|
||||||
# REF-NEXT: Initial: 0x1
|
|
||||||
# REF-NEXT: - Type: FUNCTION
|
|
||||||
# REF-NEXT: FunctionTypes: [ 0, 0, 0, 0, 0 ]
|
|
||||||
# REF-NEXT: - Type: ELEM
|
|
||||||
# REF-NEXT: Segments:
|
|
||||||
# REF-NEXT: - Offset:
|
|
||||||
# REF-NEXT: Opcode: I32_CONST
|
|
||||||
# REF-NEXT: Value: 1
|
|
||||||
# REF-NEXT: Functions: [ 0 ]
|
|
||||||
# REF-NEXT: - Type: DATACOUNT
|
|
||||||
# REF-NEXT: Count: 3
|
|
||||||
# REF-NEXT: - Type: CODE
|
|
||||||
# REF-NEXT: Relocations:
|
|
||||||
# REF-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
|
|
||||||
# REF-NEXT: Index: 0
|
|
||||||
# REF-NEXT: Offset: 0x9
|
|
||||||
# REF-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
|
|
||||||
# REF-NEXT: Index: 3
|
|
||||||
# REF-NEXT: Offset: 0x12
|
|
||||||
# REF-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
|
|
||||||
# REF-NEXT: Index: 5
|
|
||||||
# REF-NEXT: Offset: 0x1E
|
|
||||||
# REF-NEXT: - Type: R_WASM_TYPE_INDEX_LEB
|
|
||||||
# REF-NEXT: Index: 0
|
|
||||||
# REF-NEXT: Offset: 0x24
|
|
||||||
# REF-NEXT: - Type: R_WASM_TABLE_NUMBER_LEB
|
|
||||||
# REF-NEXT: Index: 6
|
|
||||||
# REF-NEXT: Offset: 0x29
|
|
||||||
# REF-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
|
|
||||||
# REF-NEXT: Index: 8
|
|
||||||
# REF-NEXT: Offset: 0x35
|
|
||||||
# REF-NEXT: - Type: R_WASM_TYPE_INDEX_LEB
|
|
||||||
# REF-NEXT: Index: 0
|
|
||||||
# REF-NEXT: Offset: 0x3B
|
|
||||||
# REF-NEXT: - Type: R_WASM_TABLE_NUMBER_LEB
|
|
||||||
# REF-NEXT: Index: 6
|
|
||||||
# REF-NEXT: Offset: 0x40
|
|
||||||
# REF-NEXT: Functions:
|
|
||||||
# REF-NEXT: - Index: 0
|
|
||||||
# REF-NEXT: Locals: []
|
|
||||||
# REF-NEXT: Body: 41000B
|
|
||||||
# REF-NEXT: - Index: 1
|
|
||||||
# REF-NEXT: Locals: []
|
|
||||||
# REF-NEXT: Body: 1080808080000B
|
|
||||||
# REF-NEXT: - Index: 2
|
|
||||||
# REF-NEXT: Locals: []
|
|
||||||
# REF-NEXT: Body: 1080808080000B
|
|
||||||
# REF-NEXT: - Index: 3
|
|
||||||
# REF-NEXT: Locals: []
|
|
||||||
# REF-NEXT: Body: 41002802888080800011808080800080808080000B
|
|
||||||
# REF-NEXT: - Index: 4
|
|
||||||
# REF-NEXT: Locals: []
|
|
||||||
# REF-NEXT: Body: 41002802908080800011808080800080808080000B
|
|
||||||
# REF-NEXT: - Type: DATA
|
|
||||||
# REF-NEXT: Relocations:
|
|
||||||
# REF-NEXT: - Type: R_WASM_TABLE_INDEX_I32
|
|
||||||
# REF-NEXT: Index: 0
|
|
||||||
# REF-NEXT: Offset: 0x13
|
|
||||||
# REF-NEXT: - Type: R_WASM_TABLE_INDEX_I32
|
|
||||||
# REF-NEXT: Index: 3
|
|
||||||
# REF-NEXT: Offset: 0x20
|
|
||||||
# REF-NEXT: Segments:
|
|
||||||
# REF-NEXT: - SectionOffset: 6
|
|
||||||
# REF-NEXT: InitFlags: 0
|
|
||||||
# REF-NEXT: Offset:
|
|
||||||
# REF-NEXT: Opcode: I32_CONST
|
|
||||||
# REF-NEXT: Value: 0
|
|
||||||
# REF-NEXT: Content: '0700000000000000'
|
|
||||||
# REF-NEXT: - SectionOffset: 19
|
|
||||||
# REF-NEXT: InitFlags: 0
|
|
||||||
# REF-NEXT: Offset:
|
|
||||||
# REF-NEXT: Opcode: I32_CONST
|
|
||||||
# REF-NEXT: Value: 8
|
|
||||||
# REF-NEXT: Content: '0100000000000000'
|
|
||||||
# REF-NEXT: - SectionOffset: 32
|
|
||||||
# REF-NEXT: InitFlags: 0
|
|
||||||
# REF-NEXT: Offset:
|
|
||||||
# REF-NEXT: Opcode: I32_CONST
|
|
||||||
# REF-NEXT: Value: 16
|
|
||||||
# REF-NEXT: Content: '0100000000000000'
|
|
||||||
# REF-NEXT: - Type: CUSTOM
|
|
||||||
# REF-NEXT: Name: linking
|
|
||||||
# REF-NEXT: Version: 2
|
|
||||||
# REF-NEXT: SymbolTable:
|
|
||||||
# REF-NEXT: - Index: 0
|
|
||||||
# REF-NEXT: Kind: FUNCTION
|
|
||||||
# REF-NEXT: Name: foo
|
|
||||||
# REF-NEXT: Flags: [ VISIBILITY_HIDDEN ]
|
|
||||||
# REF-NEXT: Function: 0
|
|
||||||
# REF-NEXT: - Index: 1
|
|
||||||
# REF-NEXT: Kind: FUNCTION
|
|
||||||
# REF-NEXT: Name: call_direct
|
|
||||||
# REF-NEXT: Flags: [ VISIBILITY_HIDDEN ]
|
|
||||||
# REF-NEXT: Function: 1
|
|
||||||
# REF-NEXT: - Index: 2
|
|
||||||
# REF-NEXT: Kind: FUNCTION
|
|
||||||
# REF-NEXT: Name: call_alias
|
|
||||||
# REF-NEXT: Flags: [ VISIBILITY_HIDDEN ]
|
|
||||||
# REF-NEXT: Function: 2
|
|
||||||
# REF-NEXT: - Index: 3
|
|
||||||
# REF-NEXT: Kind: FUNCTION
|
|
||||||
# REF-NEXT: Name: foo_alias
|
|
||||||
# REF-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN, NO_STRIP ]
|
|
||||||
# REF-NEXT: Function: 0
|
|
||||||
# REF-NEXT: - Index: 4
|
|
||||||
# REF-NEXT: Kind: FUNCTION
|
|
||||||
# REF-NEXT: Name: call_direct_ptr
|
|
||||||
# REF-NEXT: Flags: [ VISIBILITY_HIDDEN ]
|
|
||||||
# REF-NEXT: Function: 3
|
|
||||||
# REF-NEXT: - Index: 5
|
|
||||||
# REF-NEXT: Kind: DATA
|
|
||||||
# REF-NEXT: Name: direct_address
|
|
||||||
# REF-NEXT: Flags: [ ]
|
|
||||||
# REF-NEXT: Segment: 1
|
|
||||||
# REF-NEXT: Size: 4
|
|
||||||
# REF-NEXT: - Index: 6
|
|
||||||
# REF-NEXT: Kind: TABLE
|
|
||||||
# REF-NEXT: Name: __indirect_function_table
|
|
||||||
# REF-NEXT: Flags: [ UNDEFINED, NO_STRIP ]
|
|
||||||
# REF-NEXT: Table: 0
|
|
||||||
# REF-NEXT: - Index: 7
|
|
||||||
# REF-NEXT: Kind: FUNCTION
|
|
||||||
# REF-NEXT: Name: call_alias_ptr
|
|
||||||
# REF-NEXT: Flags: [ VISIBILITY_HIDDEN ]
|
|
||||||
# REF-NEXT: Function: 4
|
|
||||||
# REF-NEXT: - Index: 8
|
|
||||||
# REF-NEXT: Kind: DATA
|
|
||||||
# REF-NEXT: Name: alias_address
|
|
||||||
# REF-NEXT: Flags: [ ]
|
|
||||||
# REF-NEXT: Segment: 2
|
|
||||||
# REF-NEXT: Size: 4
|
|
||||||
# REF-NEXT: - Index: 9
|
|
||||||
# REF-NEXT: Kind: DATA
|
|
||||||
# REF-NEXT: Name: bar
|
|
||||||
# REF-NEXT: Flags: [ ]
|
|
||||||
# REF-NEXT: Segment: 0
|
|
||||||
# REF-NEXT: Size: 4
|
|
||||||
# REF-NEXT: - Index: 10
|
|
||||||
# REF-NEXT: Kind: DATA
|
|
||||||
# REF-NEXT: Name: bar_alias
|
|
||||||
# REF-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN, NO_STRIP ]
|
|
||||||
# REF-NEXT: Segment: 0
|
|
||||||
# REF-NEXT: Size: 4
|
|
||||||
# REF-NEXT: SegmentInfo:
|
|
||||||
# REF-NEXT: - Index: 0
|
|
||||||
# REF-NEXT: Name: .data.bar
|
|
||||||
# REF-NEXT: Alignment: 3
|
|
||||||
# REF-NEXT: Flags: [ ]
|
|
||||||
# REF-NEXT: - Index: 1
|
|
||||||
# REF-NEXT: Name: .data.direct_address
|
|
||||||
# REF-NEXT: Alignment: 3
|
|
||||||
# REF-NEXT: Flags: [ ]
|
|
||||||
# REF-NEXT: - Index: 2
|
|
||||||
# REF-NEXT: Name: .data.alias_address
|
|
||||||
# REF-NEXT: Alignment: 3
|
|
||||||
# REF-NEXT: Flags: [ ]
|
|
||||||
# REF-NEXT: ...
|
|
||||||
|
|
||||||
# CHECK-SYMS: SYMBOL TABLE:
|
# CHECK-SYMS: SYMBOL TABLE:
|
||||||
# CHECK-SYMS-NEXT: 00000001 g F CODE .hidden foo
|
# CHECK-SYMS-NEXT: 00000001 g F CODE .hidden foo
|
||||||
# CHECK-SYMS-NEXT: 00000006 g F CODE .hidden call_direct
|
# CHECK-SYMS-NEXT: 00000006 g F CODE .hidden call_direct
|
||||||
|
|
Loading…
Reference in New Issue