Skip to content

[Object][Wasm] Use offset instead of index for Global address and store size #81781

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Feb 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions llvm/include/llvm/BinaryFormat/Wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,8 @@ struct WasmGlobal {
WasmGlobalType Type;
WasmInitExpr InitExpr;
StringRef SymbolName; // from the "linking" section
uint32_t Offset; // Offset of the definition in the binary's Global section
uint32_t Size; // Size of the definition in the binary's Global section
};

struct WasmTag {
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/Object/Wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ class WasmObjectFile : public ObjectFile {
bool isValidSectionSymbol(uint32_t Index) const;
wasm::WasmFunction &getDefinedFunction(uint32_t Index);
const wasm::WasmFunction &getDefinedFunction(uint32_t Index) const;
wasm::WasmGlobal &getDefinedGlobal(uint32_t Index);
const wasm::WasmGlobal &getDefinedGlobal(uint32_t Index) const;
wasm::WasmTag &getDefinedTag(uint32_t Index);

const WasmSection &getWasmSection(DataRefImpl Ref) const;
Expand Down
32 changes: 20 additions & 12 deletions llvm/lib/Object/WasmObjectFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1400,18 +1400,20 @@ Error WasmObjectFile::parseTagSection(ReadContext &Ctx) {

Error WasmObjectFile::parseGlobalSection(ReadContext &Ctx) {
GlobalSection = Sections.size();
const uint8_t *SectionStart = Ctx.Ptr;
uint32_t Count = readVaruint32(Ctx);
Globals.reserve(Count);
while (Count--) {
wasm::WasmGlobal Global;
Global.Index = NumImportedGlobals + Globals.size();
const uint8_t *GlobalStart = Ctx.Ptr;
Global.Offset = static_cast<uint32_t>(GlobalStart - SectionStart);
auto GlobalOpcode = readVaruint32(Ctx);
auto GlobalType = parseValType(Ctx, GlobalOpcode);
// assert(GlobalType <= std::numeric_limits<wasm::ValType>::max());
Global.Type.Type = (uint8_t)GlobalType;
Global.Type.Type = (uint8_t)parseValType(Ctx, GlobalOpcode);
Global.Type.Mutable = readVaruint1(Ctx);
if (Error Err = readInitExpr(Global.InitExpr, Ctx))
return Err;
Global.Size = static_cast<uint32_t>(Ctx.Ptr - GlobalStart);
Globals.push_back(Global);
}
if (Ctx.Ptr != Ctx.End)
Expand Down Expand Up @@ -1564,7 +1566,7 @@ WasmObjectFile::getDefinedFunction(uint32_t Index) const {
return Functions[Index - NumImportedFunctions];
}

wasm::WasmGlobal &WasmObjectFile::getDefinedGlobal(uint32_t Index) {
const wasm::WasmGlobal &WasmObjectFile::getDefinedGlobal(uint32_t Index) const {
assert(isDefinedGlobalIndex(Index));
return Globals[Index - NumImportedGlobals];
}
Expand Down Expand Up @@ -1815,18 +1817,22 @@ Expected<StringRef> WasmObjectFile::getSymbolName(DataRefImpl Symb) const {

Expected<uint64_t> WasmObjectFile::getSymbolAddress(DataRefImpl Symb) const {
auto &Sym = getWasmSymbol(Symb);
if (!Sym.isDefined())
return 0;
Expected<section_iterator> Sec = getSymbolSection(Symb);
if (!Sec)
return Sec.takeError();
uint32_t SectionAddress = getSectionAddress(Sec.get()->getRawDataRefImpl());
if (Sym.Info.Kind == wasm::WASM_SYMBOL_TYPE_FUNCTION &&
isDefinedFunctionIndex(Sym.Info.ElementIndex)) {
// For object files, use the section offset. The linker relies on this.
// For linked files, use the file offset. This behavior matches the way
// browsers print stack traces and is useful for binary size analysis.
// (see https://webassembly.github.io/spec/web-api/index.html#conventions)
uint32_t Adjustment = isRelocatableObject() || isSharedObject()
? 0
: Sections[CodeSection].Offset;
return getDefinedFunction(Sym.Info.ElementIndex).CodeSectionOffset +
Adjustment;
SectionAddress;
}
if (Sym.Info.Kind == wasm::WASM_SYMBOL_TYPE_GLOBAL &&
isDefinedGlobalIndex(Sym.Info.ElementIndex)) {
return getDefinedGlobal(Sym.Info.ElementIndex).Offset + SectionAddress;
}

return getSymbolValue(Symb);
}

Expand Down Expand Up @@ -1936,6 +1942,8 @@ uint32_t WasmObjectFile::getSymbolSize(SymbolRef Symb) const {
const WasmSymbol &Sym = getWasmSymbol(Symb);
if (!Sym.isDefined())
return 0;
if (Sym.isTypeGlobal())
return getDefinedGlobal(Sym.Info.ElementIndex).Size;
if (Sym.isTypeData())
return Sym.Info.DataRef.Size;
if (Sym.isTypeFunction())
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/tools/llvm-nm/wasm/exports.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,4 @@ Sections:

# CHECK: 00000000 D dexport
# CHECK-NEXT: 00000001 T fexport
# CHECK-NEXT: 00000000 D gexport
# CHECK-NEXT: 00000001 D gexport
2 changes: 1 addition & 1 deletion llvm/test/tools/llvm-nm/wasm/weak-symbols.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,6 @@ Sections:

# CHECK: 00000000 W weak_defined_data
# CHECK-NEXT: 00000001 W weak_defined_func
# CHECK-NEXT: 00000000 W weak_defined_global
# CHECK-NEXT: 00000001 W weak_defined_global
# CHECK-NEXT: w weak_import_data
# CHECK-NEXT: w weak_import_func
15 changes: 12 additions & 3 deletions llvm/test/tools/llvm-objdump/wasm/linked-symbol-table-namesec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
#
# CHECK: SYMBOL TABLE:
# CHECK-NEXT: 00000000 F *UND* 00000000 my_func_import_name
# CHECK-NEXT: 00000083 g F CODE 00000003 my_func_export_name
# CHECK-NEXT: 00000086 l F CODE 00000003 my_func_local_name
# CHECK-NEXT: 0000008c g F CODE 00000003 my_func_export_name
# CHECK-NEXT: 0000008f l F CODE 00000003 my_func_local_name
# CHECK-NEXT: 00000000 *UND* 00000000 my_global_import_name
# CHECK-NEXT: 00000001 g GLOBAL 00000000 my_global_export_name
# CHECK-NEXT: 0000004c g GLOBAL 00000005 my_global_export_name
# CHECK-NEXT: 00000051 g GLOBAL 00000009 my_global_local_name
# CHECK-NEXT: 00000000 l O DATA 00000004 my_datasegment_name

--- !WASM
Expand Down Expand Up @@ -44,6 +45,12 @@ Sections:
InitExpr:
Opcode: I32_CONST
Value: 42
- Index: 2
Mutable: true
Type: I64
InitExpr:
Opcode: I64_CONST
Value: 5000000000
- Type: EXPORT
Exports:
- Name: my_func_export
Expand Down Expand Up @@ -82,6 +89,8 @@ Sections:
Name: my_global_import_name
- Index: 1
Name: my_global_export_name
- Index: 2
Name: my_global_local_name
DataSegmentNames:
- Index: 0
Name: my_datasegment_name