[llvm] 2eaeae7 - [Object][Wasm] Use offset instead of index for Global address and store size (#81781)

via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 15 09:36:49 PST 2024


Author: Derek Schuff
Date: 2024-02-15T09:36:44-08:00
New Revision: 2eaeae7e9a298b8a4c9a313f914c42f1e0b82c39

URL: https://github.com/llvm/llvm-project/commit/2eaeae7e9a298b8a4c9a313f914c42f1e0b82c39
DIFF: https://github.com/llvm/llvm-project/commit/2eaeae7e9a298b8a4c9a313f914c42f1e0b82c39.diff

LOG: [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).

Added: 
    

Modified: 
    llvm/include/llvm/BinaryFormat/Wasm.h
    llvm/include/llvm/Object/Wasm.h
    llvm/lib/Object/WasmObjectFile.cpp
    llvm/test/tools/llvm-nm/wasm/exports.yaml
    llvm/test/tools/llvm-nm/wasm/weak-symbols.yaml
    llvm/test/tools/llvm-objdump/wasm/linked-symbol-table-namesec.yaml

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/BinaryFormat/Wasm.h b/llvm/include/llvm/BinaryFormat/Wasm.h
index aec6ea0b757799..bd70747e583cb8 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 b8f7bb45d73a4b..cda896b2b7805b 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 04e2b809c01493..6507a0e5950ebe 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())

diff  --git a/llvm/test/tools/llvm-nm/wasm/exports.yaml b/llvm/test/tools/llvm-nm/wasm/exports.yaml
index 15c98ae2bf4a22..27edb052203aa0 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 d8e4cece0fef77..41297044794cd3 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 dc87e62bcaac37..147175f713a831 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


        


More information about the llvm-commits mailing list