Skip to content

Commit c2244f8

Browse files
authored
[WebAssembly] Set IS_64 flag correctly on __indirect_function_table in object files (#94487)
Follow up to #92042
1 parent 86dddbe commit c2244f8

File tree

5 files changed

+19
-10
lines changed

5 files changed

+19
-10
lines changed

llvm/include/llvm/MC/MCSymbolWasm.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,11 @@ class MCSymbolWasm : public MCSymbol {
114114
return isTable() && hasTableType() &&
115115
getTableType().ElemType == wasm::ValType::FUNCREF;
116116
}
117-
void setFunctionTable() {
117+
void setFunctionTable(bool is64) {
118118
setType(wasm::WASM_SYMBOL_TYPE_TABLE);
119-
setTableType(wasm::ValType::FUNCREF);
119+
uint8_t flags =
120+
is64 ? wasm::WASM_LIMITS_FLAG_IS_64 : wasm::WASM_LIMITS_FLAG_NONE;
121+
setTableType(wasm::ValType::FUNCREF, flags);
120122
}
121123

122124
void setUsedInGOT() const { IsUsedInGOT = true; }
@@ -140,10 +142,11 @@ class MCSymbolWasm : public MCSymbol {
140142
return *TableType;
141143
}
142144
void setTableType(wasm::WasmTableType TT) { TableType = TT; }
143-
void setTableType(wasm::ValType VT) {
145+
void setTableType(wasm::ValType VT,
146+
uint8_t flags = wasm::WASM_LIMITS_FLAG_NONE) {
144147
// Declare a table with element type VT and no limits (min size 0, no max
145148
// size).
146-
wasm::WasmLimits Limits = {wasm::WASM_LIMITS_FLAG_NONE, 0, 0};
149+
wasm::WasmLimits Limits = {flags, 0, 0};
147150
setTableType({VT, Limits});
148151
}
149152
};

llvm/lib/MC/WasmObjectWriter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -877,7 +877,7 @@ void WasmObjectWriter::writeImportSection(ArrayRef<wasm::WasmImport> Imports,
877877
break;
878878
case wasm::WASM_EXTERNAL_TABLE:
879879
W->OS << char(Import.Table.ElemType);
880-
encodeULEB128(0, W->OS); // flags
880+
encodeULEB128(Import.Table.Limits.Flags, W->OS);
881881
encodeULEB128(NumElements, W->OS); // initial
882882
break;
883883
case wasm::WASM_EXTERNAL_TAG:

llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,14 +178,15 @@ static wasm::WasmLimits DefaultLimits() {
178178
}
179179

180180
static MCSymbolWasm *GetOrCreateFunctionTableSymbol(MCContext &Ctx,
181-
const StringRef &Name) {
181+
const StringRef &Name,
182+
bool is64) {
182183
MCSymbolWasm *Sym = cast_or_null<MCSymbolWasm>(Ctx.lookupSymbol(Name));
183184
if (Sym) {
184185
if (!Sym->isFunctionTable())
185186
Ctx.reportError(SMLoc(), "symbol is not a wasm funcref table");
186187
} else {
187188
Sym = cast<MCSymbolWasm>(Ctx.getOrCreateSymbol(Name));
188-
Sym->setFunctionTable();
189+
Sym->setFunctionTable(is64);
189190
// The default function table is synthesized by the linker.
190191
Sym->setUndefined();
191192
}
@@ -258,7 +259,7 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
258259
MCAsmParserExtension::Initialize(Parser);
259260

260261
DefaultFunctionTable = GetOrCreateFunctionTableSymbol(
261-
getContext(), "__indirect_function_table");
262+
getContext(), "__indirect_function_table", is64);
262263
if (!STI->checkFeatures("+reference-types"))
263264
DefaultFunctionTable->setOmitFromLinkingSection();
264265
}
@@ -508,7 +509,7 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
508509
auto &Tok = Lexer.getTok();
509510
if (Tok.is(AsmToken::Identifier)) {
510511
auto *Sym =
511-
GetOrCreateFunctionTableSymbol(getContext(), Tok.getString());
512+
GetOrCreateFunctionTableSymbol(getContext(), Tok.getString(), is64);
512513
const auto *Val = MCSymbolRefExpr::create(Sym, getContext());
513514
*Op = std::make_unique<WebAssemblyOperand>(
514515
WebAssemblyOperand::Symbol, Tok.getLoc(), Tok.getEndLoc(),
@@ -836,6 +837,9 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
836837
// symbol
837838
auto WasmSym = cast<MCSymbolWasm>(Ctx.getOrCreateSymbol(SymName));
838839
WasmSym->setType(wasm::WASM_SYMBOL_TYPE_TABLE);
840+
if (is64) {
841+
Limits.Flags |= wasm::WASM_LIMITS_FLAG_IS_64;
842+
}
839843
wasm::WasmTableType Type = {*ElemType, Limits};
840844
WasmSym->setTableType(Type);
841845
TOut.emitTableType(WasmSym);

llvm/lib/Target/WebAssembly/WebAssemblyUtilities.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,9 @@ MCSymbolWasm *WebAssembly::getOrCreateFunctionTableSymbol(
108108
if (!Sym->isFunctionTable())
109109
Ctx.reportError(SMLoc(), "symbol is not a wasm funcref table");
110110
} else {
111+
bool is64 = Subtarget && Subtarget->getTargetTriple().isArch64Bit();
111112
Sym = cast<MCSymbolWasm>(Ctx.getOrCreateSymbol(Name));
112-
Sym->setFunctionTable();
113+
Sym->setFunctionTable(is64);
113114
// The default function table is synthesized by the linker.
114115
Sym->setUndefined();
115116
}

llvm/test/MC/WebAssembly/reloc-pic64.s

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ hidden_func:
9393
# CHECK-NEXT: Index: 0
9494
# CHECK-NEXT: ElemType: FUNCREF
9595
# CHECK-NEXT: Limits:
96+
# CHECK-NEXT: Flags: [ IS_64 ]
9697
# CHECK-NEXT: Minimum: 0x1
9798
# CHECK-NEXT: - Module: GOT.mem
9899
# CHECK-NEXT: Field: default_data

0 commit comments

Comments
 (0)