aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Object/WasmObjectFile.cpp
diff options
context:
space:
mode:
authorDerek Schuff <dschuff@chromium.org>2024-02-15 09:36:44 -0800
committerGitHub <noreply@github.com>2024-02-15 09:36:44 -0800
commit2eaeae7e9a298b8a4c9a313f914c42f1e0b82c39 (patch)
tree95b372f37f6d58454ae517c69a941509fa513418 /llvm/lib/Object/WasmObjectFile.cpp
parenta1d4c69344f5a2c55043fdc0e43ebf76459eda95 (diff)
downloadllvm-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.cpp32
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())