diff options
author | Derek Schuff <dschuff@chromium.org> | 2024-02-15 09:36:44 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-15 09:36:44 -0800 |
commit | 2eaeae7e9a298b8a4c9a313f914c42f1e0b82c39 (patch) | |
tree | 95b372f37f6d58454ae517c69a941509fa513418 /llvm/lib/Object/WasmObjectFile.cpp | |
parent | a1d4c69344f5a2c55043fdc0e43ebf76459eda95 (diff) | |
download | llvm-2eaeae7e9a298b8a4c9a313f914c42f1e0b82c39.zip llvm-2eaeae7e9a298b8a4c9a313f914c42f1e0b82c39.tar.gz llvm-2eaeae7e9a298b8a4c9a313f914c42f1e0b82c39.tar.bz2 |
[Object][Wasm] Use offset instead of index for Global address and store size (#81781)
Currently the address reported by binutils for a global is its index;
but its offset (in the file or section) is more useful for binary size
attribution.
This PR treats globals similarly to functions, and tracks their offset
and size. It also centralizes the logic differentiating linked from object
and dylib files (where section addresses are 0).
Diffstat (limited to 'llvm/lib/Object/WasmObjectFile.cpp')
-rw-r--r-- | llvm/lib/Object/WasmObjectFile.cpp | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp index 04e2b80..6507a0e 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<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) @@ -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<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); } @@ -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()) |