[WebAssembly] Set IS_64 flag correctly on __indirect_function_table in object files (#94487)

Follow up to #92042
This commit is contained in:
Sam Clegg 2024-06-05 20:28:51 -07:00 committed by GitHub
parent 86dddbe3b5
commit c2244f8284
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 19 additions and 10 deletions

View File

@ -114,9 +114,11 @@ public:
return isTable() && hasTableType() &&
getTableType().ElemType == wasm::ValType::FUNCREF;
}
void setFunctionTable() {
void setFunctionTable(bool is64) {
setType(wasm::WASM_SYMBOL_TYPE_TABLE);
setTableType(wasm::ValType::FUNCREF);
uint8_t flags =
is64 ? wasm::WASM_LIMITS_FLAG_IS_64 : wasm::WASM_LIMITS_FLAG_NONE;
setTableType(wasm::ValType::FUNCREF, flags);
}
void setUsedInGOT() const { IsUsedInGOT = true; }
@ -140,10 +142,11 @@ public:
return *TableType;
}
void setTableType(wasm::WasmTableType TT) { TableType = TT; }
void setTableType(wasm::ValType VT) {
void setTableType(wasm::ValType VT,
uint8_t flags = wasm::WASM_LIMITS_FLAG_NONE) {
// Declare a table with element type VT and no limits (min size 0, no max
// size).
wasm::WasmLimits Limits = {wasm::WASM_LIMITS_FLAG_NONE, 0, 0};
wasm::WasmLimits Limits = {flags, 0, 0};
setTableType({VT, Limits});
}
};

View File

@ -877,7 +877,7 @@ void WasmObjectWriter::writeImportSection(ArrayRef<wasm::WasmImport> Imports,
break;
case wasm::WASM_EXTERNAL_TABLE:
W->OS << char(Import.Table.ElemType);
encodeULEB128(0, W->OS); // flags
encodeULEB128(Import.Table.Limits.Flags, W->OS);
encodeULEB128(NumElements, W->OS); // initial
break;
case wasm::WASM_EXTERNAL_TAG:

View File

@ -178,14 +178,15 @@ static wasm::WasmLimits DefaultLimits() {
}
static MCSymbolWasm *GetOrCreateFunctionTableSymbol(MCContext &Ctx,
const StringRef &Name) {
const StringRef &Name,
bool is64) {
MCSymbolWasm *Sym = cast_or_null<MCSymbolWasm>(Ctx.lookupSymbol(Name));
if (Sym) {
if (!Sym->isFunctionTable())
Ctx.reportError(SMLoc(), "symbol is not a wasm funcref table");
} else {
Sym = cast<MCSymbolWasm>(Ctx.getOrCreateSymbol(Name));
Sym->setFunctionTable();
Sym->setFunctionTable(is64);
// The default function table is synthesized by the linker.
Sym->setUndefined();
}
@ -258,7 +259,7 @@ public:
MCAsmParserExtension::Initialize(Parser);
DefaultFunctionTable = GetOrCreateFunctionTableSymbol(
getContext(), "__indirect_function_table");
getContext(), "__indirect_function_table", is64);
if (!STI->checkFeatures("+reference-types"))
DefaultFunctionTable->setOmitFromLinkingSection();
}
@ -508,7 +509,7 @@ public:
auto &Tok = Lexer.getTok();
if (Tok.is(AsmToken::Identifier)) {
auto *Sym =
GetOrCreateFunctionTableSymbol(getContext(), Tok.getString());
GetOrCreateFunctionTableSymbol(getContext(), Tok.getString(), is64);
const auto *Val = MCSymbolRefExpr::create(Sym, getContext());
*Op = std::make_unique<WebAssemblyOperand>(
WebAssemblyOperand::Symbol, Tok.getLoc(), Tok.getEndLoc(),
@ -836,6 +837,9 @@ public:
// symbol
auto WasmSym = cast<MCSymbolWasm>(Ctx.getOrCreateSymbol(SymName));
WasmSym->setType(wasm::WASM_SYMBOL_TYPE_TABLE);
if (is64) {
Limits.Flags |= wasm::WASM_LIMITS_FLAG_IS_64;
}
wasm::WasmTableType Type = {*ElemType, Limits};
WasmSym->setTableType(Type);
TOut.emitTableType(WasmSym);

View File

@ -108,8 +108,9 @@ MCSymbolWasm *WebAssembly::getOrCreateFunctionTableSymbol(
if (!Sym->isFunctionTable())
Ctx.reportError(SMLoc(), "symbol is not a wasm funcref table");
} else {
bool is64 = Subtarget && Subtarget->getTargetTriple().isArch64Bit();
Sym = cast<MCSymbolWasm>(Ctx.getOrCreateSymbol(Name));
Sym->setFunctionTable();
Sym->setFunctionTable(is64);
// The default function table is synthesized by the linker.
Sym->setUndefined();
}

View File

@ -93,6 +93,7 @@ hidden_func:
# CHECK-NEXT: Index: 0
# CHECK-NEXT: ElemType: FUNCREF
# CHECK-NEXT: Limits:
# CHECK-NEXT: Flags: [ IS_64 ]
# CHECK-NEXT: Minimum: 0x1
# CHECK-NEXT: - Module: GOT.mem
# CHECK-NEXT: Field: default_data