mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
[WebAssembly] call_indirect issues table number relocs
This patch changes to make call_indirect explicitly refer to the corresponding function table, residualizing TABLE_NUMBER relocs against it. With this change, wasm-ld now sees all references to tables, and can link multiple tables. Differential Revision: https://reviews.llvm.org/D90948
This commit is contained in:
parent
2b1fcde239
commit
6ddb7e7525
@ -405,13 +405,6 @@ void WasmObjectWriter::writeHeader(const MCAssembler &Asm) {
|
||||
|
||||
void WasmObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
|
||||
const MCAsmLayout &Layout) {
|
||||
// As a stopgap measure until call_indirect instructions start explicitly
|
||||
// referencing the indirect function table via TABLE_NUMBER relocs, ensure
|
||||
// that the indirect function table import makes it to the output if anything
|
||||
// in the compilation unit has caused it to be present.
|
||||
if (auto *Sym = Asm.getContext().lookupSymbol("__indirect_function_table"))
|
||||
Asm.registerSymbol(*Sym);
|
||||
|
||||
// Build a map of sections to the function that defines them, for use
|
||||
// in recordRelocation.
|
||||
for (const MCSymbol &S : Asm.symbols()) {
|
||||
|
@ -472,6 +472,15 @@ public:
|
||||
WebAssemblyOperand::IntOp{static_cast<int64_t>(BT)}));
|
||||
}
|
||||
|
||||
void addFunctionTableOperand(OperandVector &Operands, StringRef TableName,
|
||||
SMLoc StartLoc, SMLoc EndLoc) {
|
||||
MCSymbolWasm *Sym = GetOrCreateFunctionTableSymbol(getContext(), TableName);
|
||||
auto *Val = MCSymbolRefExpr::create(Sym, getContext());
|
||||
Operands.push_back(std::make_unique<WebAssemblyOperand>(
|
||||
WebAssemblyOperand::Symbol, StartLoc, EndLoc,
|
||||
WebAssemblyOperand::SymOp{Val}));
|
||||
}
|
||||
|
||||
bool ParseInstruction(ParseInstructionInfo & /*Info*/, StringRef Name,
|
||||
SMLoc NameLoc, OperandVector &Operands) override {
|
||||
// Note: Name does NOT point into the sourcecode, but to a local, so
|
||||
@ -508,6 +517,7 @@ public:
|
||||
bool ExpectBlockType = false;
|
||||
bool ExpectFuncType = false;
|
||||
bool ExpectHeapType = false;
|
||||
bool ExpectFunctionTable = false;
|
||||
if (Name == "block") {
|
||||
push(Block);
|
||||
ExpectBlockType = true;
|
||||
@ -547,15 +557,7 @@ public:
|
||||
return true;
|
||||
} else if (Name == "call_indirect" || Name == "return_call_indirect") {
|
||||
ExpectFuncType = 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();
|
||||
ExpectFunctionTable = true;
|
||||
} else if (Name == "ref.null") {
|
||||
ExpectHeapType = true;
|
||||
}
|
||||
@ -571,7 +573,7 @@ public:
|
||||
return true;
|
||||
// Got signature as block type, don't need more
|
||||
ExpectBlockType = false;
|
||||
auto &Ctx = getStreamer().getContext();
|
||||
auto &Ctx = getContext();
|
||||
// The "true" here will cause this to be a nameless symbol.
|
||||
MCSymbol *Sym = Ctx.createTempSymbol("typeindex", true);
|
||||
auto *WasmSym = cast<MCSymbolWasm>(Sym);
|
||||
@ -583,6 +585,16 @@ public:
|
||||
Operands.push_back(std::make_unique<WebAssemblyOperand>(
|
||||
WebAssemblyOperand::Symbol, Loc.getLoc(), Loc.getEndLoc(),
|
||||
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)) {
|
||||
@ -608,8 +620,11 @@ public:
|
||||
WebAssemblyOperand::Integer, Id.getLoc(), Id.getEndLoc(),
|
||||
WebAssemblyOperand::IntOp{static_cast<int64_t>(HeapType)}));
|
||||
Parser.Lex();
|
||||
} else if (ExpectFunctionTable) {
|
||||
addFunctionTableOperand(Operands, Id.getString(), Id.getLoc(),
|
||||
Id.getEndLoc());
|
||||
Parser.Lex();
|
||||
} else {
|
||||
// Assume this identifier is a label.
|
||||
const MCExpr *Val;
|
||||
SMLoc End;
|
||||
if (Parser.parseExpression(Val, End))
|
||||
@ -674,6 +689,11 @@ public:
|
||||
// Support blocks with no operands as default to void.
|
||||
addBlockTypeOperand(Operands, NameLoc, WebAssembly::BlockType::Void);
|
||||
}
|
||||
if (ExpectFunctionTable && Operands.size() == 2) {
|
||||
// If call_indirect doesn't specify a target table, supply one.
|
||||
addFunctionTableOperand(Operands, "__indirect_function_table", NameLoc,
|
||||
SMLoc::getFromPointer(Name.end()));
|
||||
}
|
||||
Parser.Lex();
|
||||
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) {
|
||||
if (MI->getOpcode() == WebAssembly::CALL_INDIRECT &&
|
||||
I - Start == NumVariadicDefs) {
|
||||
// Skip type and flags arguments when printing for tests
|
||||
// Skip type and table arguments when printing for tests.
|
||||
++I;
|
||||
continue;
|
||||
}
|
||||
|
@ -401,6 +401,16 @@ inline bool isCallIndirect(unsigned Opc) {
|
||||
}
|
||||
}
|
||||
|
||||
inline bool isRetCallIndirect(unsigned Opc) {
|
||||
switch (Opc) {
|
||||
case WebAssembly::RET_CALL_INDIRECT:
|
||||
case WebAssembly::RET_CALL_INDIRECT_S:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool isBrTable(const MachineInstr &MI) {
|
||||
switch (MI.getOpcode()) {
|
||||
case WebAssembly::BR_TABLE_I32:
|
||||
|
@ -869,18 +869,11 @@ bool WebAssemblyFastISel::selectCall(const Instruction *I) {
|
||||
if (IsDirect) {
|
||||
MIB.addGlobalAddress(Func);
|
||||
} else {
|
||||
// Add placeholders for the type index and immediate flags
|
||||
// Placehoder for the type index.
|
||||
MIB.addImm(0);
|
||||
MIB.addImm(0);
|
||||
|
||||
// Ensure that the object file has a __indirect_function_table import, as we
|
||||
// call_indirect against it.
|
||||
MCSymbolWasm *Sym = WebAssembly::getOrCreateFunctionTableSymbol(
|
||||
MF->getMMI().getContext(), "__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();
|
||||
// The table into which this call_indirect indexes.
|
||||
MIB.addSym(WebAssembly::getOrCreateFunctionTableSymbol(
|
||||
MF->getMMI().getContext(), "__indirect_function_table"));
|
||||
}
|
||||
|
||||
for (unsigned ArgReg : Args)
|
||||
|
@ -475,19 +475,12 @@ static MachineBasicBlock *LowerCallResults(MachineInstr &CallResults,
|
||||
for (auto Def : CallResults.defs())
|
||||
MIB.add(Def);
|
||||
|
||||
// Add placeholders for the type index and immediate flags
|
||||
if (IsIndirect) {
|
||||
// Placehoder for the type index.
|
||||
MIB.addImm(0);
|
||||
MIB.addImm(0);
|
||||
|
||||
// Ensure that the object file has a __indirect_function_table import, as we
|
||||
// call_indirect against it.
|
||||
MCSymbolWasm *Sym = WebAssembly::getOrCreateFunctionTableSymbol(
|
||||
MF.getContext(), "__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();
|
||||
// The table into which this call_indirect indexes.
|
||||
MIB.addSym(WebAssembly::getOrCreateFunctionTableSymbol(
|
||||
MF.getContext(), "__indirect_function_table"));
|
||||
}
|
||||
|
||||
for (auto Use : CallParams.uses())
|
||||
|
@ -48,6 +48,9 @@ defm RET_CALL_RESULTS :
|
||||
I<(outs), (ins variable_ops), (outs), (ins), [],
|
||||
"return_call_results", "return_call_results", -1>;
|
||||
|
||||
// Note that instructions with variable_ops have custom printers in
|
||||
// WebAssemblyInstPrinter.cpp.
|
||||
|
||||
let variadicOpsAreDefs = 1 in
|
||||
defm CALL :
|
||||
I<(outs), (ins function32_op:$callee, variable_ops),
|
||||
@ -56,9 +59,12 @@ defm CALL :
|
||||
|
||||
let variadicOpsAreDefs = 1 in
|
||||
defm CALL_INDIRECT :
|
||||
I<(outs), (ins TypeIndex:$type, i32imm:$flags, variable_ops),
|
||||
(outs), (ins TypeIndex:$type, i32imm:$flags), [],
|
||||
"call_indirect", "call_indirect\t$type", 0x11>;
|
||||
I<(outs),
|
||||
(ins TypeIndex:$type, table32_op:$table, variable_ops),
|
||||
(outs),
|
||||
(ins TypeIndex:$type, table32_op:$table),
|
||||
[],
|
||||
"call_indirect", "call_indirect\t$type, $table", 0x11>;
|
||||
|
||||
let isReturn = 1, isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in
|
||||
defm RET_CALL :
|
||||
@ -69,9 +75,9 @@ defm RET_CALL :
|
||||
|
||||
let isReturn = 1 in
|
||||
defm RET_CALL_INDIRECT :
|
||||
I<(outs), (ins TypeIndex:$type, i32imm:$flags, variable_ops),
|
||||
(outs), (ins TypeIndex:$type, i32imm:$flags), [],
|
||||
"return_call_indirect\t", "return_call_indirect\t$type",
|
||||
I<(outs), (ins TypeIndex:$type, table32_op:$table, variable_ops),
|
||||
(outs), (ins TypeIndex:$type, table32_op:$table), [],
|
||||
"return_call_indirect\t", "return_call_indirect\t$type, $table",
|
||||
0x13>,
|
||||
Requires<[HasTailCall]>;
|
||||
|
||||
|
@ -161,6 +161,8 @@ MCOperand WebAssemblyMCInstLower::lowerSymbolOperand(const MachineOperand &MO,
|
||||
report_fatal_error("Global indexes with offsets not supported");
|
||||
if (WasmSym->isEvent())
|
||||
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, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
|
||||
@ -259,7 +261,7 @@ void WebAssemblyMCInstLower::lower(const MachineInstr *MI,
|
||||
|
||||
// return_call_indirect instructions have the return type of the
|
||||
// caller
|
||||
if (MI->getOpcode() == WebAssembly::RET_CALL_INDIRECT)
|
||||
if (WebAssembly::isRetCallIndirect(MI->getOpcode()))
|
||||
getFunctionReturns(MI, Returns);
|
||||
|
||||
MCOp = lowerTypeIndexOperand(std::move(Returns), std::move(Params));
|
||||
|
@ -34,14 +34,15 @@ entry:
|
||||
; CHECK-NEXT: i32.const 1
|
||||
; CHECK-NEXT: local.get 0
|
||||
; CHECK-NEXT: i32.wrap_i64
|
||||
; CHECK-NEXT: call_indirect (i32) -> ()
|
||||
; CHECK-NEXT: call_indirect (i32) -> (), __indirect_function_table
|
||||
|
||||
; CHECK: .functype test () -> ()
|
||||
; CHECK-NEXT: i64.const bar
|
||||
; CHECK-NEXT: call foo
|
||||
|
||||
|
||||
; Check we're emitting a 64-bit reloc for `i64.const bar` and the global.
|
||||
; Check we're emitting a 64-bit relocs for the call_indirect, the
|
||||
; `i64.const bar` reference in code, and the global.
|
||||
|
||||
; YAML: Memory:
|
||||
; YAML-NEXT: Flags: [ IS_64 ]
|
||||
@ -50,7 +51,10 @@ entry:
|
||||
; YAML: - Type: CODE
|
||||
; YAML: - Type: R_WASM_TABLE_INDEX_SLEB64
|
||||
; YAML-NEXT: Index: 0
|
||||
; YAML-NEXT: Offset: 0x16
|
||||
; YAML-NEXT: Offset: 0x1A
|
||||
; YAML: - Type: R_WASM_TABLE_INDEX_SLEB64
|
||||
; YAML-NEXT: Index: 0
|
||||
; YAML-NEXT: Offset: 0x2D
|
||||
|
||||
; YAML: - Type: DATA
|
||||
; YAML: - Type: R_WASM_TABLE_INDEX_I64
|
||||
|
@ -57,7 +57,7 @@ define %pair @pair_call_return() {
|
||||
; CHECK-LABEL: pair_call_indirect:
|
||||
; CHECK-NEXT: .functype pair_call_indirect (i32) -> (i32, i64)
|
||||
; CHECK-NEXT: local.get 0{{$}}
|
||||
; CHECK-NEXT: call_indirect () -> (i32, i64){{$}}
|
||||
; CHECK-NEXT: call_indirect () -> (i32, i64), __indirect_function_table{{$}}
|
||||
; CHECK-NEXT: end_function{{$}}
|
||||
; REGS: call_indirect $push{{[0-9]+}}=, $push{{[0-9]+}}=, $0{{$}}
|
||||
define %pair @pair_call_indirect(%pair()* %f) {
|
||||
|
@ -153,7 +153,7 @@ empty_fref_table:
|
||||
# CHECK-NEXT: i64.const 1234
|
||||
# CHECK-NEXT: call something2
|
||||
# CHECK-NEXT: i32.const 0
|
||||
# CHECK-NEXT: call_indirect (i32, f64) -> ()
|
||||
# CHECK-NEXT: call_indirect (i32, f64) -> (), __indirect_function_table
|
||||
# CHECK-NEXT: i32.const 1
|
||||
# CHECK-NEXT: i32.add
|
||||
# CHECK-NEXT: local.tee 0
|
||||
|
83
test/MC/WebAssembly/call-indirect-relocs.s
Normal file
83
test/MC/WebAssembly/call-indirect-relocs.s
Normal file
@ -0,0 +1,83 @@
|
||||
# RUN: llvm-mc -triple=wasm32-unknown-unknown < %s | FileCheck %s
|
||||
# RUN: llvm-mc -triple=wasm32-unknown-unknown -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: ...
|
@ -43,18 +43,28 @@ entry:
|
||||
; CHECK-NEXT: Index: 0x1
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Relocation {
|
||||
; CHECK-NEXT: Type: R_WASM_TABLE_NUMBER_LEB (20)
|
||||
; CHECK-NEXT: Offset: 0x1F
|
||||
; CHECK-NEXT: Symbol: __indirect_function_table
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Relocation {
|
||||
; CHECK-NEXT: Type: R_WASM_TYPE_INDEX_LEB (6)
|
||||
; CHECK-NEXT: Offset: 0x24
|
||||
; CHECK-NEXT: Offset: 0x28
|
||||
; CHECK-NEXT: Index: 0x0
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Relocation {
|
||||
; CHECK-NEXT: Type: R_WASM_FUNCTION_INDEX_LEB (0)
|
||||
; CHECK-NEXT: Type: R_WASM_TABLE_NUMBER_LEB (20)
|
||||
; CHECK-NEXT: Offset: 0x2D
|
||||
; CHECK-NEXT: Symbol: __indirect_function_table
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Relocation {
|
||||
; CHECK-NEXT: Type: R_WASM_FUNCTION_INDEX_LEB (0)
|
||||
; CHECK-NEXT: Offset: 0x35
|
||||
; CHECK-NEXT: Symbol: c
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Relocation {
|
||||
; CHECK-NEXT: Type: R_WASM_FUNCTION_INDEX_LEB (0)
|
||||
; CHECK-NEXT: Offset: 0x34
|
||||
; CHECK-NEXT: Offset: 0x3C
|
||||
; CHECK-NEXT: Symbol: d
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: }
|
||||
|
@ -16,7 +16,7 @@ foo1:
|
||||
foo2:
|
||||
.functype foo2 () -> ()
|
||||
|
||||
# CHECK: return_call_indirect (i32) -> (i32) # encoding: [0x13,
|
||||
# CHECK: return_call_indirect (i32) -> (i32), __indirect_function_table # encoding: [0x13,
|
||||
# CHECK-NEXT: fixup A - offset: 1, value: .Ltypeindex0@TYPEINDEX, kind: fixup_uleb128_i32
|
||||
return_call_indirect (i32) -> (i32)
|
||||
|
||||
|
@ -53,10 +53,13 @@ test0:
|
||||
# BIN-NEXT: - Type: R_WASM_TYPE_INDEX_LEB
|
||||
# BIN-NEXT: Index: 1
|
||||
# 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: - Index: 0
|
||||
# BIN-NEXT: Locals: []
|
||||
# BIN-NEXT: Body: 118180808000000B
|
||||
# BIN-NEXT: Body: 11818080800080808080000B
|
||||
# BIN-NEXT: - Type: CUSTOM
|
||||
# BIN-NEXT: Name: linking
|
||||
# BIN-NEXT: Version: 2
|
||||
@ -69,6 +72,6 @@ test0:
|
||||
# BIN-NEXT: - Index: 1
|
||||
# BIN-NEXT: Kind: TABLE
|
||||
# BIN-NEXT: Name: __indirect_function_table
|
||||
# BIN-NEXT: Flags: [ UNDEFINED, NO_STRIP ]
|
||||
# BIN-NEXT: Flags: [ UNDEFINED ]
|
||||
# BIN-NEXT: Table: 0
|
||||
# BIN-NEXT: ...
|
||||
|
@ -78,7 +78,7 @@ alias_address:
|
||||
# CHECK: - Type: TYPE
|
||||
# CHECK-NEXT: Signatures:
|
||||
# CHECK-NEXT: - Index: 0
|
||||
# CHECK-NEXT: ParamTypes:
|
||||
# CHECK-NEXT: ParamTypes: []
|
||||
# CHECK-NEXT: ReturnTypes:
|
||||
# CHECK-NEXT: - I32
|
||||
# CHECK-NEXT: - Type: IMPORT
|
||||
@ -120,28 +120,34 @@ alias_address:
|
||||
# CHECK-NEXT: - Type: R_WASM_TYPE_INDEX_LEB
|
||||
# CHECK-NEXT: Index: 0
|
||||
# CHECK-NEXT: Offset: 0x24
|
||||
# CHECK-NEXT: - Type: R_WASM_TABLE_NUMBER_LEB
|
||||
# CHECK-NEXT: Index: 6
|
||||
# CHECK-NEXT: Offset: 0x29
|
||||
# CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
|
||||
# CHECK-NEXT: Index: 7
|
||||
# CHECK-NEXT: Offset: 0x31
|
||||
# CHECK-NEXT: Index: 8
|
||||
# CHECK-NEXT: Offset: 0x35
|
||||
# CHECK-NEXT: - Type: R_WASM_TYPE_INDEX_LEB
|
||||
# CHECK-NEXT: Index: 0
|
||||
# CHECK-NEXT: Offset: 0x37
|
||||
# CHECK-NEXT: Offset: 0x3B
|
||||
# CHECK-NEXT: - Type: R_WASM_TABLE_NUMBER_LEB
|
||||
# CHECK-NEXT: Index: 6
|
||||
# CHECK-NEXT: Offset: 0x40
|
||||
# CHECK-NEXT: Functions:
|
||||
# CHECK-NEXT: - Index: 0
|
||||
# CHECK-NEXT: Locals:
|
||||
# CHECK-NEXT: Locals: []
|
||||
# CHECK-NEXT: Body: 41000B
|
||||
# CHECK-NEXT: - Index: 1
|
||||
# CHECK-NEXT: Locals:
|
||||
# CHECK-NEXT: Locals: []
|
||||
# CHECK-NEXT: Body: 1080808080000B
|
||||
# CHECK-NEXT: - Index: 2
|
||||
# CHECK-NEXT: Locals:
|
||||
# CHECK-NEXT: Locals: []
|
||||
# CHECK-NEXT: Body: 1080808080000B
|
||||
# CHECK-NEXT: - Index: 3
|
||||
# CHECK-NEXT: Locals:
|
||||
# CHECK-NEXT: Body: 410028028880808000118080808000000B
|
||||
# CHECK-NEXT: Locals: []
|
||||
# CHECK-NEXT: Body: 41002802888080800011808080800080808080000B
|
||||
# CHECK-NEXT: - Index: 4
|
||||
# CHECK-NEXT: Locals:
|
||||
# CHECK-NEXT: Body: 410028029080808000118080808000000B
|
||||
# CHECK-NEXT: Locals: []
|
||||
# CHECK-NEXT: Body: 41002802908080800011808080800080808080000B
|
||||
# CHECK-NEXT: - Type: DATA
|
||||
# CHECK-NEXT: Relocations:
|
||||
# CHECK-NEXT: - Type: R_WASM_TABLE_INDEX_I32
|
||||
@ -205,46 +211,46 @@ alias_address:
|
||||
# CHECK-NEXT: Segment: 1
|
||||
# CHECK-NEXT: Size: 4
|
||||
# CHECK-NEXT: - Index: 6
|
||||
# CHECK-NEXT: Kind: TABLE
|
||||
# CHECK-NEXT: Name: __indirect_function_table
|
||||
# CHECK-NEXT: Flags: [ UNDEFINED, NO_STRIP ]
|
||||
# CHECK-NEXT: Table: 0
|
||||
# CHECK-NEXT: - Index: 7
|
||||
# CHECK-NEXT: Kind: FUNCTION
|
||||
# CHECK-NEXT: Name: call_alias_ptr
|
||||
# CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ]
|
||||
# CHECK-NEXT: Function: 4
|
||||
# CHECK-NEXT: - Index: 7
|
||||
# CHECK-NEXT: - Index: 8
|
||||
# CHECK-NEXT: Kind: DATA
|
||||
# CHECK-NEXT: Name: alias_address
|
||||
# CHECK-NEXT: Flags: [ ]
|
||||
# CHECK-NEXT: Segment: 2
|
||||
# CHECK-NEXT: Size: 4
|
||||
# CHECK-NEXT: - Index: 8
|
||||
# CHECK-NEXT: - Index: 9
|
||||
# CHECK-NEXT: Kind: DATA
|
||||
# CHECK-NEXT: Name: bar
|
||||
# CHECK-NEXT: Flags: [ ]
|
||||
# CHECK-NEXT: Segment: 0
|
||||
# CHECK-NEXT: Size: 4
|
||||
# CHECK-NEXT: - Index: 9
|
||||
# CHECK-NEXT: - Index: 10
|
||||
# CHECK-NEXT: Kind: DATA
|
||||
# CHECK-NEXT: Name: bar_alias
|
||||
# CHECK-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN, NO_STRIP ]
|
||||
# CHECK-NEXT: Segment: 0
|
||||
# CHECK-NEXT: Size: 4
|
||||
# CHECK-NEXT: - Index: 10
|
||||
# CHECK-NEXT: Kind: TABLE
|
||||
# CHECK-NEXT: Name: __indirect_function_table
|
||||
# CHECK-NEXT: Flags: [ UNDEFINED, NO_STRIP ]
|
||||
# CHECK-NEXT: Table: 0
|
||||
# CHECK-NEXT: SegmentInfo:
|
||||
# CHECK-NEXT: - Index: 0
|
||||
# CHECK-NEXT: Name: .data.bar
|
||||
# CHECK-NEXT: Alignment: 3
|
||||
# CHECK-NEXT: Flags: [ ]
|
||||
# CHECK-NEXT: Flags: [ ]
|
||||
# CHECK-NEXT: - Index: 1
|
||||
# CHECK-NEXT: Name: .data.direct_address
|
||||
# CHECK-NEXT: Alignment: 3
|
||||
# CHECK-NEXT: Flags: [ ]
|
||||
# CHECK-NEXT: Flags: [ ]
|
||||
# CHECK-NEXT: - Index: 2
|
||||
# CHECK-NEXT: Name: .data.alias_address
|
||||
# CHECK-NEXT: Alignment: 3
|
||||
# CHECK-NEXT: Flags: [ ]
|
||||
# CHECK-NEXT: Flags: [ ]
|
||||
# CHECK-NEXT: ...
|
||||
|
||||
# CHECK-SYMS: SYMBOL TABLE:
|
||||
|
Loading…
Reference in New Issue
Block a user