diff --git a/llvm/include/llvm/BinaryFormat/Wasm.h b/llvm/include/llvm/BinaryFormat/Wasm.h index aec6ea0b75779..bd70747e583cb 100644 --- a/llvm/include/llvm/BinaryFormat/Wasm.h +++ b/llvm/include/llvm/BinaryFormat/Wasm.h @@ -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 { diff --git a/llvm/include/llvm/Object/Wasm.h b/llvm/include/llvm/Object/Wasm.h index b8f7bb45d73a4..cda896b2b7805 100644 --- a/llvm/include/llvm/Object/Wasm.h +++ b/llvm/include/llvm/Object/Wasm.h @@ -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; diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp index 04e2b809c0149..6507a0e5950eb 100644 --- a/llvm/lib/Object/WasmObjectFile.cpp +++ b/llvm/lib/Object/WasmObjectFile.cpp @@ -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(GlobalStart - SectionStart); auto GlobalOpcode = readVaruint32(Ctx); - auto GlobalType = parseValType(Ctx, GlobalOpcode); - // assert(GlobalType <= std::numeric_limits::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(Ctx.Ptr - GlobalStart); Globals.push_back(Global); } if (Ctx.Ptr != Ctx.End) @@ -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]; } @@ -1815,18 +1817,22 @@ Expected WasmObjectFile::getSymbolName(DataRefImpl Symb) const { Expected WasmObjectFile::getSymbolAddress(DataRefImpl Symb) const { auto &Sym = getWasmSymbol(Symb); + if (!Sym.isDefined()) + return 0; + Expected 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); } @@ -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()) diff --git a/llvm/test/tools/llvm-nm/wasm/exports.yaml b/llvm/test/tools/llvm-nm/wasm/exports.yaml index 15c98ae2bf4a2..27edb052203aa 100644 --- a/llvm/test/tools/llvm-nm/wasm/exports.yaml +++ b/llvm/test/tools/llvm-nm/wasm/exports.yaml @@ -64,4 +64,4 @@ Sections: # CHECK: 00000000 D dexport # CHECK-NEXT: 00000001 T fexport -# CHECK-NEXT: 00000000 D gexport +# CHECK-NEXT: 00000001 D gexport diff --git a/llvm/test/tools/llvm-nm/wasm/weak-symbols.yaml b/llvm/test/tools/llvm-nm/wasm/weak-symbols.yaml index d8e4cece0fef7..41297044794cd 100644 --- a/llvm/test/tools/llvm-nm/wasm/weak-symbols.yaml +++ b/llvm/test/tools/llvm-nm/wasm/weak-symbols.yaml @@ -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 diff --git a/llvm/test/tools/llvm-objdump/wasm/linked-symbol-table-namesec.yaml b/llvm/test/tools/llvm-objdump/wasm/linked-symbol-table-namesec.yaml index dc87e62bcaac3..147175f713a83 100644 --- a/llvm/test/tools/llvm-objdump/wasm/linked-symbol-table-namesec.yaml +++ b/llvm/test/tools/llvm-objdump/wasm/linked-symbol-table-namesec.yaml @@ -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 @@ -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 @@ -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