[lld] [llvm] [Object][Wasm] Generate symbol info from name section names (PR #81063)

Derek Schuff via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 7 16:39:53 PST 2024


https://github.com/dschuff created https://github.com/llvm/llvm-project/pull/81063

Currently symbol info is generated from a linking section or from export names. This PR generates
symbols in a WasmObjectFile from the name section as well, which allows tools like objdump and
nm to show useful information for more linked binaryes. There are some limitations: most notably
that we don't assume any particular ABI, so we don't get detailed information about data symbols
if the segments are merged (which is the default).

>From a137a63b3d26fba44e312f86405a6b263342d717 Mon Sep 17 00:00:00 2001
From: Derek Schuff <dschuff at chromium.org>
Date: Fri, 2 Feb 2024 10:37:51 -0800
Subject: [PATCH 1/7] Create symbols for elements in name section

---
 llvm/lib/Object/WasmObjectFile.cpp            | 38 +++++++-
 .../wasm/linked-symbol-table-namesec.yaml     | 87 +++++++++++++++++++
 2 files changed, 123 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/tools/llvm-objdump/wasm/linked-symbol-table-namesec.yaml

diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp
index 4778562779bb7..6d26aeb3b33eb 100644
--- a/llvm/lib/Object/WasmObjectFile.cpp
+++ b/llvm/lib/Object/WasmObjectFile.cpp
@@ -508,10 +508,21 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
   llvm::DenseSet<uint64_t> SeenGlobals;
   llvm::DenseSet<uint64_t> SeenSegments;
 
+  // If there is symbol info from the export section, this info will supersede
+  // it, but not info from a linking section
+  if (!HasLinkingSection) {
+    Symbols.clear();
+  }
+
   while (Ctx.Ptr < Ctx.End) {
     uint8_t Type = readUint8(Ctx);
     uint32_t Size = readVaruint32(Ctx);
     const uint8_t *SubSectionEnd = Ctx.Ptr + Size;
+
+    const wasm::WasmSignature *Signature = nullptr;
+    const wasm::WasmGlobalType *GlobalType = nullptr;
+    const wasm::WasmTableType *TableType = nullptr;
+
     switch (Type) {
     case wasm::WASM_NAMES_FUNCTION:
     case wasm::WASM_NAMES_GLOBAL:
@@ -521,6 +532,11 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
         uint32_t Index = readVaruint32(Ctx);
         StringRef Name = readString(Ctx);
         wasm::NameType nameType = wasm::NameType::FUNCTION;
+        wasm::WasmSymbolInfo Info;
+        Info.Name = Name;
+        Info.Kind = wasm::WASM_SYMBOL_TYPE_FUNCTION;
+        Info.Flags = 0;
+        Info.ElementIndex = Index;
         if (Type == wasm::WASM_NAMES_FUNCTION) {
           if (!SeenFunctions.insert(Index).second)
             return make_error<GenericBinaryError>(
@@ -529,8 +545,19 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
             return make_error<GenericBinaryError>("invalid function name entry",
                                                   object_error::parse_failed);
 
-          if (isDefinedFunctionIndex(Index))
-            getDefinedFunction(Index).DebugName = Name;
+          if (isDefinedFunctionIndex(Index)) {
+            wasm::WasmFunction &F = getDefinedFunction(Index);
+            F.DebugName = Name;
+            if (F.ExportName) {
+              Info.ExportName = F.ExportName;
+              Info.Flags |= wasm::WASM_SYMBOL_BINDING_GLOBAL;
+              Signature = &Signatures[F.SigIndex];
+            } else {
+              Info.Flags |= wasm::WASM_SYMBOL_BINDING_LOCAL;
+            }
+          } else {
+            Info.Flags |= wasm::WASM_SYMBOL_UNDEFINED;
+          }
         } else if (Type == wasm::WASM_NAMES_GLOBAL) {
           nameType = wasm::NameType::GLOBAL;
           if (!SeenGlobals.insert(Index).second)
@@ -541,6 +568,11 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
                                                   object_error::parse_failed);
         } else {
           nameType = wasm::NameType::DATA_SEGMENT;
+          Info.Kind = wasm::WASM_SYMBOL_TYPE_DATA;
+          Info.Flags |= wasm::WASM_SYMBOL_BINDING_LOCAL;
+          assert(Index < DataSegments.size());
+          Info.DataRef = wasm::WasmDataReference{Index, 0,
+            DataSegments[Index].Data.Content.size()};
           if (!SeenSegments.insert(Index).second)
             return make_error<GenericBinaryError>(
                 "segment named more than once", object_error::parse_failed);
@@ -549,6 +581,8 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
                                                   object_error::parse_failed);
         }
         DebugNames.push_back(wasm::WasmDebugName{nameType, Index, Name});
+        if (!HasLinkingSection)
+          Symbols.emplace_back(Info, GlobalType, TableType, Signature);
       }
       break;
     }
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
new file mode 100644
index 0000000000000..e1bfd6fa0cda5
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/wasm/linked-symbol-table-namesec.yaml
@@ -0,0 +1,87 @@
+# RUN: yaml2obj %s -o %t.wasm
+# RUN: llvm-objdump -t %t.wasm | FileCheck %s
+#
+# CHECK:      SYMBOL TABLE:
+# CHECK-NEXT: 0000009f g F CODE my_func_export
+# CHECK-NEXT: 0000002a g O DATA my_global_export
+# CHECK-NEXT: 00000000 g   TABLE my_table_export
+
+--- !WASM
+FileHeader:
+  Version:         0x1
+Sections:
+  - Type:            TYPE
+    Signatures:
+      - Index:           0
+        ParamTypes:      []
+        ReturnTypes:     []
+  - Type:            IMPORT
+    Imports:
+      - Module:          env
+        Field:           foo
+        Kind:            FUNCTION
+        SigIndex:        0
+      - Module:          env
+        Field:           bar
+        Kind:            GLOBAL
+        GlobalType:      I32
+        GlobalMutable:   true
+      - Module:          env
+        Field:           memory
+        Kind:            MEMORY
+        Memory:
+          Minimum:         0x1
+  - Type:            FUNCTION
+    FunctionTypes:   [ 0, 0 ]
+  - Type:            TABLE
+    Tables:
+      - Index:           0
+        ElemType:        FUNCREF
+        Limits:
+          Flags:           [ HAS_MAX ]
+          Minimum:         0x1
+          Maximum:         0x1
+  - Type:            GLOBAL
+    Globals:
+      - Index:           1
+        Mutable:         false
+        Type:            I32
+        InitExpr:
+          Opcode:          I32_CONST
+          Value:           42
+  - Type:            EXPORT
+    Exports:
+      - Name:            my_func_export
+        Kind:            FUNCTION
+        Index:           1
+      - Name:            my_global_export
+        Kind:            GLOBAL
+        Index:           1
+      - Name:            my_table_export
+        Kind:            TABLE
+        Index:           0
+  - Type:            CODE
+    Functions:
+      - Index:           1
+        Locals:
+        Body:            00
+      - Index:           2
+        Locals:
+        Body:            00
+  - Type:            DATA
+    Segments:
+      - SectionOffset:   0
+        InitFlags:       0
+        Offset:
+          Opcode:          I32_CONST
+          Value:           0
+        Content:         ''
+  - Type:            CUSTOM
+    Name:            name
+    FunctionNames:
+     - Index:        0
+       Name:         my_func_import_name
+     - Index:        1
+       Name:         my_func_export_name
+     - Index:        2
+       Name:         my_func_local_name
\ No newline at end of file

>From 9f11853965a144679f62ee88832e8533f375a205 Mon Sep 17 00:00:00 2001
From: Derek Schuff <dschuff at chromium.org>
Date: Fri, 2 Feb 2024 17:18:52 -0800
Subject: [PATCH 2/7] fix section addresses and adjust disassembly tests

---
 llvm/lib/Object/WasmObjectFile.cpp            | 13 +++++++++-
 .../Disassembler/WebAssemblyDisassembler.cpp  |  4 +++-
 ...executable-without-symbols-debugnames.test | 12 +++++-----
 .../wasm/executable-without-symbols.test      | 12 +++++-----
 .../wasm/linked-symbol-table-namesec.yaml     | 16 +++++++++----
 .../tools/llvm-objdump/wasm/no-codesec.test   |  6 ++---
 llvm/tools/llvm-objdump/llvm-objdump.cpp      | 24 +++++++++++++------
 7 files changed, 59 insertions(+), 28 deletions(-)

diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp
index 6d26aeb3b33eb..b20cad0feecb2 100644
--- a/llvm/lib/Object/WasmObjectFile.cpp
+++ b/llvm/lib/Object/WasmObjectFile.cpp
@@ -560,6 +560,13 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
           }
         } else if (Type == wasm::WASM_NAMES_GLOBAL) {
           nameType = wasm::NameType::GLOBAL;
+          if (isDefinedGlobalIndex(Index)) {
+            wasm::WasmGlobal &G = getDefinedGlobal(Index);
+            Info.Flags |= wasm::WASM_SYMBOL_TYPE_GLOBAL;
+          } else {
+            Info.Flags |= wasm::WASM_SYMBOL_UNDEFINED;
+          }
+
           if (!SeenGlobals.insert(Index).second)
             return make_error<GenericBinaryError>("global named more than once",
                                                   object_error::parse_failed);
@@ -1940,7 +1947,11 @@ Expected<StringRef> WasmObjectFile::getSectionName(DataRefImpl Sec) const {
   return wasm::sectionTypeToString(S.Type);
 }
 
-uint64_t WasmObjectFile::getSectionAddress(DataRefImpl Sec) const { return 0; }
+uint64_t WasmObjectFile::getSectionAddress(DataRefImpl Sec) const { 
+      return isRelocatableObject() || isSharedObject()
+                              ? 0
+                              :  Sections[Sec.d.a].Offset;
+   }
 
 uint64_t WasmObjectFile::getSectionIndex(DataRefImpl Sec) const {
   return Sec.d.a;
diff --git a/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp b/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp
index ed7757be66158..5fcdb200b6305 100644
--- a/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp
+++ b/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp
@@ -16,6 +16,7 @@
 
 #include "MCTargetDesc/WebAssemblyMCTypeUtilities.h"
 #include "TargetInfo/WebAssemblyTargetInfo.h"
+#include "llvm/BinaryFormat/Wasm.h"
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCDecoderOps.h"
 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
@@ -127,7 +128,8 @@ WebAssemblyDisassembler::onSymbolStart(SymbolInfoTy &Symbol, uint64_t &Size,
                                        uint64_t Address,
                                        raw_ostream &CStream) const {
   Size = 0;
-  if (Address == 0) {
+  llvm::errs() << llvm::format("start %d\n", Symbol.Type);
+  if (Symbol.Type == wasm::WASM_SYMBOL_TYPE_SECTION) {
     // Start of a code section: we're parsing only the function count.
     int64_t FunctionCount;
     if (!nextLEB(FunctionCount, Bytes, Size, false))
diff --git a/llvm/test/tools/llvm-objdump/wasm/executable-without-symbols-debugnames.test b/llvm/test/tools/llvm-objdump/wasm/executable-without-symbols-debugnames.test
index 646891700b866..3f26838002373 100644
--- a/llvm/test/tools/llvm-objdump/wasm/executable-without-symbols-debugnames.test
+++ b/llvm/test/tools/llvm-objdump/wasm/executable-without-symbols-debugnames.test
@@ -36,14 +36,14 @@ Sections:
 
 # CHECK:       Disassembly of section CODE:
 # CHECK-EMPTY:
-# CHECK-NEXT:  00000000 <CODE>:
+# CHECK-NEXT:  00000026 <CODE>:
 # CHECK-NEXT:          # 2 functions in section.
 # CHECK-EMPTY:
-# CHECK-NEXT:  00000001 <f>:
+# CHECK-NEXT:  00000027 <f>:
 # CHECK-EMPTY:
-# CHECK-NEXT:         3: 0b           	end
+# CHECK-NEXT:         29: 0b           	end
 # CHECK-EMPTY:
-# CHECK-NEXT:  00000004 <g>:
+# CHECK-NEXT:  0000002a <g>:
 # CHECK-EMPTY:
-# CHECK-NEXT:         6: 20 00        	local.get	0
-# CHECK-NEXT:         8: 0b           	end
+# CHECK-NEXT:         2c: 20 00        	local.get	0
+# CHECK-NEXT:         2e: 0b           	end
diff --git a/llvm/test/tools/llvm-objdump/wasm/executable-without-symbols.test b/llvm/test/tools/llvm-objdump/wasm/executable-without-symbols.test
index 633991eecfbf3..ad0822e0d4a53 100644
--- a/llvm/test/tools/llvm-objdump/wasm/executable-without-symbols.test
+++ b/llvm/test/tools/llvm-objdump/wasm/executable-without-symbols.test
@@ -29,14 +29,14 @@ Sections:
 
 # CHECK:       Disassembly of section CODE:
 # CHECK-EMPTY:
-# CHECK-NEXT:  00000000 <CODE>:
+# CHECK-NEXT:  00000026 <CODE>:
 # CHECK-NEXT:          # 2 functions in section.
 # CHECK-EMPTY:
-# CHECK-NEXT:  00000001 <>:
+# CHECK-NEXT:  00000027 <>:
 # CHECK-EMPTY:
-# CHECK-NEXT:         3: 0b           	end
+# CHECK-NEXT:         29: 0b           	end
 # CHECK-EMPTY:
-# CHECK-NEXT:  00000004 <>:
+# CHECK-NEXT:  0000002a <>:
 # CHECK-EMPTY:
-# CHECK-NEXT:         6: 20 00        	local.get	0
-# CHECK-NEXT:         8: 0b           	end
+# CHECK-NEXT:         2c: 20 00        	local.get	0
+# CHECK-NEXT:         2e: 0b           	end
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 e1bfd6fa0cda5..aa74b36f8bd30 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
@@ -2,9 +2,11 @@
 # RUN: llvm-objdump -t %t.wasm | FileCheck %s
 #
 # CHECK:      SYMBOL TABLE:
-# CHECK-NEXT: 0000009f g F CODE my_func_export
-# CHECK-NEXT: 0000002a g O DATA my_global_export
-# CHECK-NEXT: 00000000 g   TABLE my_table_export
+# CHECK-NEXT: 00000000   F *UND* my_func_import_name
+# CHECK-NEXT: 000000a0 g F CODE my_func_export_name
+# CHECK-NEXT: 000000a3 l F CODE my_func_local_name
+# C HECK-NEXT: 0000002a g O DATA my_global_export
+# C HECK-NEXT: 00000000 g   TABLE my_table_export
 
 --- !WASM
 FileHeader:
@@ -84,4 +86,10 @@ Sections:
      - Index:        1
        Name:         my_func_export_name
      - Index:        2
-       Name:         my_func_local_name
\ No newline at end of file
+       Name:         my_func_local_name
+    GlobalNames:
+     - Index:        1
+       Name:         my_global_name_export_name
+    DataSegmentNames:
+     - Index:        0
+       Name:         my_datasegment_name
\ No newline at end of file
diff --git a/llvm/test/tools/llvm-objdump/wasm/no-codesec.test b/llvm/test/tools/llvm-objdump/wasm/no-codesec.test
index e66a8ddd8a066..330191b03a0b6 100644
--- a/llvm/test/tools/llvm-objdump/wasm/no-codesec.test
+++ b/llvm/test/tools/llvm-objdump/wasm/no-codesec.test
@@ -4,9 +4,9 @@
 
 # CHECK: Sections:
 # CHECK-NEXT: Idx Name          Size     VMA      Type
-# CHECK-NEXT:   0 TYPE          00000004 00000000 
-# CHECK-NEXT:   1 FUNCTION      00000002 00000000 
-# CHECK-NEXT:   2 name          00000008 00000000
+# CHECK-NEXT:   0 TYPE          00000004 0000000e 
+# CHECK-NEXT:   1 FUNCTION      00000002 00000018 
+# CHECK-NEXT:   2 name          00000008 00000020
   
 --- !WASM
 FileHeader:
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index b4467ec163c34..32a31e661c4f2 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -29,6 +29,7 @@
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringSet.h"
 #include "llvm/ADT/Twine.h"
+#include "llvm/BinaryFormat/Wasm.h"
 #include "llvm/DebugInfo/BTF/BTFParser.h"
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/DebugInfo/Symbolize/SymbolizableModule.h"
@@ -1145,15 +1146,18 @@ addMissingWasmCodeSymbols(const WasmObjectFile &Obj,
   SectionSymbolsTy &Symbols = AllSymbols[*Section];
 
   std::set<uint64_t> SymbolAddresses;
-  for (const auto &Sym : Symbols)
-    SymbolAddresses.insert(Sym.Addr);
+  for (const auto &Sym : Symbols) { 
+    // llvm::errs() << llvm::format("sym %x\n", Sym.Addr);
+    SymbolAddresses.insert(Sym.Addr);}
 
   for (const wasm::WasmFunction &Function : Obj.functions()) {
-    uint64_t Address = Function.CodeSectionOffset;
+    uint32_t Adjustment = Obj.isRelocatableObject() || Obj.isSharedObject() ? 0 : Section->getAddress();
+    uint64_t Address = Function.CodeSectionOffset + Adjustment;
     // Only add fallback symbols for functions not already present in the symbol
     // table.
     if (SymbolAddresses.count(Address))
       continue;
+    // llvm::errs() << llvm::format(" adding addr %lx name \n", Address) << Function.SymbolName;
     // This function has no symbol, so it should have no SymbolName.
     assert(Function.SymbolName.empty());
     // We use DebugName for the name, though it may be empty if there is no
@@ -1354,6 +1358,9 @@ SymbolInfoTy objdump::createSymbolInfo(const ObjectFile &Obj,
     const SymbolRef::Type SymType = unwrapOrError(Symbol.getType(), FileName);
     return SymbolInfoTy(Addr, Name, SymType, /*IsMappingSymbol=*/false,
                         /*IsXCOFF=*/true);
+  } else if (Obj.isWasm()) {
+    uint8_t SymType = cast<WasmObjectFile>(&Obj)->getWasmSymbol(Symbol).Info.Kind;
+    return SymbolInfoTy(Addr, Name, SymType, false);
   } else {
     uint8_t Type =
         Obj.isELF() ? getElfSymbolType(Obj, Symbol) : (uint8_t)ELF::STT_NOTYPE;
@@ -1366,8 +1373,9 @@ static SymbolInfoTy createDummySymbolInfo(const ObjectFile &Obj,
                                           uint8_t Type) {
   if (Obj.isXCOFF() && (SymbolDescription || TracebackTable))
     return SymbolInfoTy(std::nullopt, Addr, Name, std::nullopt, false);
-  else
-    return SymbolInfoTy(Addr, Name, Type);
+  if (Obj.isWasm())
+    return SymbolInfoTy(Addr, Name, wasm::WASM_SYMBOL_TYPE_SECTION);
+  return SymbolInfoTy(Addr, Name, Type);
 }
 
 static void collectBBAddrMapLabels(
@@ -1704,8 +1712,10 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
   // before same-addressed non-empty sections so that symbol lookups prefer the
   // non-empty section.
   std::vector<std::pair<uint64_t, SectionRef>> SectionAddresses;
-  for (SectionRef Sec : Obj.sections())
-    SectionAddresses.emplace_back(Sec.getAddress(), Sec);
+  for (SectionRef Sec : Obj.sections()) {
+    std::string name = cantFail(Sec.getName()).str();
+    // llvm::errs() << llvm::format("section %s, addr %lx\n", name.c_str(), Sec.getAddress());
+    SectionAddresses.emplace_back(Sec.getAddress(), Sec);}
   llvm::stable_sort(SectionAddresses, [](const auto &LHS, const auto &RHS) {
     if (LHS.first != RHS.first)
       return LHS.first < RHS.first;

>From c179039dce622b35fdaf696ba4330c96cf399e30 Mon Sep 17 00:00:00 2001
From: Derek Schuff <dschuff at chromium.org>
Date: Fri, 2 Feb 2024 18:09:05 -0800
Subject: [PATCH 3/7] test working

---
 llvm/lib/Object/WasmObjectFile.cpp            | 25 ++++++++++---------
 .../wasm/linked-symbol-table-namesec.yaml     | 25 ++++++-------------
 2 files changed, 21 insertions(+), 29 deletions(-)

diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp
index b20cad0feecb2..92894c1974210 100644
--- a/llvm/lib/Object/WasmObjectFile.cpp
+++ b/llvm/lib/Object/WasmObjectFile.cpp
@@ -519,10 +519,6 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
     uint32_t Size = readVaruint32(Ctx);
     const uint8_t *SubSectionEnd = Ctx.Ptr + Size;
 
-    const wasm::WasmSignature *Signature = nullptr;
-    const wasm::WasmGlobalType *GlobalType = nullptr;
-    const wasm::WasmTableType *TableType = nullptr;
-
     switch (Type) {
     case wasm::WASM_NAMES_FUNCTION:
     case wasm::WASM_NAMES_GLOBAL:
@@ -532,11 +528,16 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
         uint32_t Index = readVaruint32(Ctx);
         StringRef Name = readString(Ctx);
         wasm::NameType nameType = wasm::NameType::FUNCTION;
-        wasm::WasmSymbolInfo Info;
-        Info.Name = Name;
-        Info.Kind = wasm::WASM_SYMBOL_TYPE_FUNCTION;
-        Info.Flags = 0;
-        Info.ElementIndex = Index;
+        wasm::WasmSymbolInfo Info{Name,
+                                  /*Kind */ wasm::WASM_SYMBOL_TYPE_FUNCTION,
+                                  /* Flags */0,
+                                  /* ImportModule */ std::nullopt,
+                                  /* ImportName */ std::nullopt,
+                                  /* ExportName */ std::nullopt,
+                                  {/* ElementIndex */ Index}};
+        const wasm::WasmSignature *Signature = nullptr;
+        const wasm::WasmGlobalType *GlobalType = nullptr;
+        const wasm::WasmTableType *TableType = nullptr;
         if (Type == wasm::WASM_NAMES_FUNCTION) {
           if (!SeenFunctions.insert(Index).second)
             return make_error<GenericBinaryError>(
@@ -548,10 +549,10 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
           if (isDefinedFunctionIndex(Index)) {
             wasm::WasmFunction &F = getDefinedFunction(Index);
             F.DebugName = Name;
+            Signature = &Signatures[F.SigIndex];
             if (F.ExportName) {
               Info.ExportName = F.ExportName;
               Info.Flags |= wasm::WASM_SYMBOL_BINDING_GLOBAL;
-              Signature = &Signatures[F.SigIndex];
             } else {
               Info.Flags |= wasm::WASM_SYMBOL_BINDING_LOCAL;
             }
@@ -560,9 +561,9 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
           }
         } else if (Type == wasm::WASM_NAMES_GLOBAL) {
           nameType = wasm::NameType::GLOBAL;
+          Info.Kind = wasm::WASM_SYMBOL_TYPE_GLOBAL;
           if (isDefinedGlobalIndex(Index)) {
-            wasm::WasmGlobal &G = getDefinedGlobal(Index);
-            Info.Flags |= wasm::WASM_SYMBOL_TYPE_GLOBAL;
+            GlobalType = &getDefinedGlobal(Index).Type;
           } else {
             Info.Flags |= wasm::WASM_SYMBOL_UNDEFINED;
           }
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 aa74b36f8bd30..324dab4847849 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,10 @@
 #
 # CHECK:      SYMBOL TABLE:
 # CHECK-NEXT: 00000000   F *UND* my_func_import_name
-# CHECK-NEXT: 000000a0 g F CODE my_func_export_name
-# CHECK-NEXT: 000000a3 l F CODE my_func_local_name
-# C HECK-NEXT: 0000002a g O DATA my_global_export
-# C HECK-NEXT: 00000000 g   TABLE my_table_export
+# CHECK-NEXT: 00000083 g F CODE my_func_export_name
+# CHECK-NEXT: 00000086 l F CODE my_func_local_name
+# CHECK-NEXT: 00000000    *UND* my_global_import_name
+# CHECK-NEXT: 00000001 g  GLOBAL my_global_export_name
 
 --- !WASM
 FileHeader:
@@ -35,14 +35,6 @@ Sections:
           Minimum:         0x1
   - Type:            FUNCTION
     FunctionTypes:   [ 0, 0 ]
-  - Type:            TABLE
-    Tables:
-      - Index:           0
-        ElemType:        FUNCREF
-        Limits:
-          Flags:           [ HAS_MAX ]
-          Minimum:         0x1
-          Maximum:         0x1
   - Type:            GLOBAL
     Globals:
       - Index:           1
@@ -59,9 +51,6 @@ Sections:
       - Name:            my_global_export
         Kind:            GLOBAL
         Index:           1
-      - Name:            my_table_export
-        Kind:            TABLE
-        Index:           0
   - Type:            CODE
     Functions:
       - Index:           1
@@ -88,8 +77,10 @@ Sections:
      - Index:        2
        Name:         my_func_local_name
     GlobalNames:
+     - Index:        0
+       Name:         my_global_import_name
      - Index:        1
-       Name:         my_global_name_export_name
+       Name:         my_global_export_name
     DataSegmentNames:
      - Index:        0
-       Name:         my_datasegment_name
\ No newline at end of file
+       Name:         my_datasegment_name

>From 77c1e0051a43bbfc629eaaf966ad9667d0c15608 Mon Sep 17 00:00:00 2001
From: Derek Schuff <dschuff at chromium.org>
Date: Fri, 2 Feb 2024 18:10:05 -0800
Subject: [PATCH 4/7] format, cleanup

---
 llvm/lib/Object/WasmObjectFile.cpp | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp
index 92894c1974210..de5611a4f8b22 100644
--- a/llvm/lib/Object/WasmObjectFile.cpp
+++ b/llvm/lib/Object/WasmObjectFile.cpp
@@ -1948,7 +1948,10 @@ Expected<StringRef> WasmObjectFile::getSectionName(DataRefImpl Sec) const {
   return wasm::sectionTypeToString(S.Type);
 }
 
-uint64_t WasmObjectFile::getSectionAddress(DataRefImpl Sec) const { 
+uint64_t WasmObjectFile::getSectionAddress(DataRefImpl Sec) const {
+    // For object files, use 0 for section addresses, and section offsets for
+    // symbol addresses. For linked files, use file offsets.
+    // See also getSymbolAddress.
       return isRelocatableObject() || isSharedObject()
                               ? 0
                               :  Sections[Sec.d.a].Offset;

>From e20dbef0550c256c35769f83ff99bfd743c145d6 Mon Sep 17 00:00:00 2001
From: Derek Schuff <dschuff at chromium.org>
Date: Fri, 2 Feb 2024 19:53:55 -0800
Subject: [PATCH 5/7] fix lld tests

---
 lld/test/wasm/build-id.test        | 12 ++++++------
 lld/test/wasm/merge-string-debug.s | 14 +++++++-------
 lld/test/wasm/startstop.ll         | 12 ++++++------
 3 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/lld/test/wasm/build-id.test b/lld/test/wasm/build-id.test
index b767d8de4a423..dd6e2237108f3 100644
--- a/lld/test/wasm/build-id.test
+++ b/lld/test/wasm/build-id.test
@@ -43,18 +43,18 @@ foo:
 
 
 # DEFAULT:      Contents of section build_id:
-# DEFAULT-NEXT: 0000 10299168 1e3c845a 3c8f80ae 2f16cc22  .).h.<.Z<.../.."
-# DEFAULT-NEXT: 0010 2d
+# DEFAULT-NEXT: 0079 10299168 1e3c845a 3c8f80ae 2f16cc22  .).h.<.Z<.../.."
+# DEFAULT-NEXT: 0089 2d
 
 # SHA1:      Contents of section build_id:
-# SHA1-NEXT: 0000 145abdda 387a9bc4 e3aed3c3 3319cd37  .Z..8z......3..7
-# SHA1-NEXT: 0010 0212237c e4                          ..#|.
+# SHA1-NEXT: 0079 145abdda 387a9bc4 e3aed3c3 3319cd37  .Z..8z......3..7
+# SHA1-NEXT: 0089 0212237c e4                          ..#|.
 
 # UUID:      Contents of section build_id:
-# UUID-NEXT: 0000 10
+# UUID-NEXT: 0079 10
 
 # HEX:      Contents of section build_id:
-# HEX-NEXT:  0000 04123456 78                          ..4Vx
+# HEX-NEXT:  0079 04123456 78                          ..4Vx
 
 
 # NONE-NOT: Contents of section build_id:
diff --git a/lld/test/wasm/merge-string-debug.s b/lld/test/wasm/merge-string-debug.s
index 73e31d5361f41..0075a834e0647 100644
--- a/lld/test/wasm/merge-string-debug.s
+++ b/lld/test/wasm/merge-string-debug.s
@@ -29,13 +29,13 @@
 
 # CHECK: Hex dump of section '.debug_str':
 
-# CHECK-O0: 0x00000000 636c616e 67207665 7273696f 6e203133 clang version 13
-# CHECK-O0: 0x00000010 2e302e30 00666f6f 62617200 636c616e .0.0.foobar.clan
-# CHECK-O0: 0x00000020 67207665 7273696f 6e203133 2e302e30 g version 13.0.0
-# CHECK-O0: 0x00000030 00626172 00666f6f 00                .bar.foo.
+# CHECK-O0: 0x00000025 636c616e 67207665 7273696f 6e203133 clang version 13
+# CHECK-O0: 0x00000035 2e302e30 00666f6f 62617200 636c616e .0.0.foobar.clan
+# CHECK-O0: 0x00000045 67207665 7273696f 6e203133 2e302e30 g version 13.0.0
+# CHECK-O0: 0x00000055 00626172 00666f6f 00                .bar.foo.
 
-# CHECK-O1: 0x00000000 666f6f62 61720066 6f6f0063 6c616e67 foobar.foo.clang
-# CHECK-O1: 0x00000010 20766572 73696f6e 2031332e 302e3000  version 13.0.0.
+# CHECK-O1: 0x00000025 666f6f62 61720066 6f6f0063 6c616e67 foobar.foo.clang
+# CHECK-O1: 0x00000035 20766572 73696f6e 2031332e 302e3000  version 13.0.0.
 
 # CHECK-OFFSETS: Hex dump of section '.debug_str_offsets':
-# CHECK-OFFSETS: 0x00000000 00000000 00000000 00000000          ............
+# CHECK-OFFSETS: 0x0000007e 00000000 00000000 00000000          ............
diff --git a/lld/test/wasm/startstop.ll b/lld/test/wasm/startstop.ll
index 4341d371f8e65..e7a5c80f91f28 100644
--- a/lld/test/wasm/startstop.ll
+++ b/lld/test/wasm/startstop.ll
@@ -34,12 +34,12 @@ entry:
 ; CHECK-NEXT:           Value:           1024
 ; CHECK-NEXT:         Content:         03000000040000002A0000002B000000
 
-;       ASM: 00000001 <get_start>:
+;       ASM: 0000006e <get_start>:
 ; ASM-EMPTY:
-;  ASM-NEXT:        3:     i32.const 1024
-;  ASM-NEXT:        9:     end
+;  ASM-NEXT:        70:     i32.const 1024
+;  ASM-NEXT:        76:     end
 
-;       ASM: 0000000a <get_end>:
+;       ASM: 00000077 <get_end>:
 ; ASM-EMPTY:
-;  ASM-NEXT:        c:     i32.const 1040
-;  ASM-NEXT:       12:     end
+;  ASM-NEXT:        79:     i32.const 1040
+;  ASM-NEXT:       7f:     end

>From 3ba55ba06df9af43f2752dd79f773ab3a882c3a2 Mon Sep 17 00:00:00 2001
From: Derek Schuff <dschuff at chromium.org>
Date: Fri, 2 Feb 2024 20:02:36 -0800
Subject: [PATCH 6/7] clean up and format

---
 .../Disassembler/WebAssemblyDisassembler.cpp  |  1 -
 ...executable-without-symbols-debugnames.test |  6 ++---
 .../wasm/executable-without-symbols.test      |  6 ++---
 .../tools/llvm-objdump/wasm/no-codesec.test   |  4 ++--
 llvm/tools/llvm-objdump/llvm-objdump.cpp      | 22 +++++++++----------
 5 files changed, 19 insertions(+), 20 deletions(-)

diff --git a/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp b/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp
index 5fcdb200b6305..861f9f8b5b1ba 100644
--- a/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp
+++ b/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp
@@ -128,7 +128,6 @@ WebAssemblyDisassembler::onSymbolStart(SymbolInfoTy &Symbol, uint64_t &Size,
                                        uint64_t Address,
                                        raw_ostream &CStream) const {
   Size = 0;
-  llvm::errs() << llvm::format("start %d\n", Symbol.Type);
   if (Symbol.Type == wasm::WASM_SYMBOL_TYPE_SECTION) {
     // Start of a code section: we're parsing only the function count.
     int64_t FunctionCount;
diff --git a/llvm/test/tools/llvm-objdump/wasm/executable-without-symbols-debugnames.test b/llvm/test/tools/llvm-objdump/wasm/executable-without-symbols-debugnames.test
index 3f26838002373..0c7a438f2752e 100644
--- a/llvm/test/tools/llvm-objdump/wasm/executable-without-symbols-debugnames.test
+++ b/llvm/test/tools/llvm-objdump/wasm/executable-without-symbols-debugnames.test
@@ -41,9 +41,9 @@ Sections:
 # CHECK-EMPTY:
 # CHECK-NEXT:  00000027 <f>:
 # CHECK-EMPTY:
-# CHECK-NEXT:         29: 0b           	end
+# CHECK-NEXT:         29: 0b       	end
 # CHECK-EMPTY:
 # CHECK-NEXT:  0000002a <g>:
 # CHECK-EMPTY:
-# CHECK-NEXT:         2c: 20 00        	local.get	0
-# CHECK-NEXT:         2e: 0b           	end
+# CHECK-NEXT:         2c: 20 00    	local.get	0
+# CHECK-NEXT:         2e: 0b       	end
diff --git a/llvm/test/tools/llvm-objdump/wasm/executable-without-symbols.test b/llvm/test/tools/llvm-objdump/wasm/executable-without-symbols.test
index ad0822e0d4a53..58643cac90147 100644
--- a/llvm/test/tools/llvm-objdump/wasm/executable-without-symbols.test
+++ b/llvm/test/tools/llvm-objdump/wasm/executable-without-symbols.test
@@ -34,9 +34,9 @@ Sections:
 # CHECK-EMPTY:
 # CHECK-NEXT:  00000027 <>:
 # CHECK-EMPTY:
-# CHECK-NEXT:         29: 0b           	end
+# CHECK-NEXT:         29: 0b       	end
 # CHECK-EMPTY:
 # CHECK-NEXT:  0000002a <>:
 # CHECK-EMPTY:
-# CHECK-NEXT:         2c: 20 00        	local.get	0
-# CHECK-NEXT:         2e: 0b           	end
+# CHECK-NEXT:         2c: 20 00    	local.get	0
+# CHECK-NEXT:         2e: 0b       	end
diff --git a/llvm/test/tools/llvm-objdump/wasm/no-codesec.test b/llvm/test/tools/llvm-objdump/wasm/no-codesec.test
index 330191b03a0b6..03fd1495066ce 100644
--- a/llvm/test/tools/llvm-objdump/wasm/no-codesec.test
+++ b/llvm/test/tools/llvm-objdump/wasm/no-codesec.test
@@ -4,8 +4,8 @@
 
 # CHECK: Sections:
 # CHECK-NEXT: Idx Name          Size     VMA      Type
-# CHECK-NEXT:   0 TYPE          00000004 0000000e 
-# CHECK-NEXT:   1 FUNCTION      00000002 00000018 
+# CHECK-NEXT:   0 TYPE          00000004 0000000e
+# CHECK-NEXT:   1 FUNCTION      00000002 00000018
 # CHECK-NEXT:   2 name          00000008 00000020
   
 --- !WASM
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index 32a31e661c4f2..cb93d030f0750 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -1146,18 +1146,19 @@ addMissingWasmCodeSymbols(const WasmObjectFile &Obj,
   SectionSymbolsTy &Symbols = AllSymbols[*Section];
 
   std::set<uint64_t> SymbolAddresses;
-  for (const auto &Sym : Symbols) { 
-    // llvm::errs() << llvm::format("sym %x\n", Sym.Addr);
-    SymbolAddresses.insert(Sym.Addr);}
+  for (const auto &Sym : Symbols)
+    SymbolAddresses.insert(Sym.Addr);
 
   for (const wasm::WasmFunction &Function : Obj.functions()) {
-    uint32_t Adjustment = Obj.isRelocatableObject() || Obj.isSharedObject() ? 0 : Section->getAddress();
-    uint64_t Address = Function.CodeSectionOffset + Adjustment;
+    // This adjustment mirrors the one in WasmObjectFile::getSymbolAddress.
+    uint32_t Adjustment = Obj.isRelocatableObject() || Obj.isSharedObject()
+                              ? 0
+                              : Section->getAddress();
+    uint64_t Addqress = Function.CodeSectionOffset + Adjustment;
     // Only add fallback symbols for functions not already present in the symbol
     // table.
     if (SymbolAddresses.count(Address))
       continue;
-    // llvm::errs() << llvm::format(" adding addr %lx name \n", Address) << Function.SymbolName;
     // This function has no symbol, so it should have no SymbolName.
     assert(Function.SymbolName.empty());
     // We use DebugName for the name, though it may be empty if there is no
@@ -1359,7 +1360,8 @@ SymbolInfoTy objdump::createSymbolInfo(const ObjectFile &Obj,
     return SymbolInfoTy(Addr, Name, SymType, /*IsMappingSymbol=*/false,
                         /*IsXCOFF=*/true);
   } else if (Obj.isWasm()) {
-    uint8_t SymType = cast<WasmObjectFile>(&Obj)->getWasmSymbol(Symbol).Info.Kind;
+    uint8_t SymType =
+        cast<WasmObjectFile>(&Obj)->getWasmSymbol(Symbol).Info.Kind;
     return SymbolInfoTy(Addr, Name, SymType, false);
   } else {
     uint8_t Type =
@@ -1712,10 +1714,8 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
   // before same-addressed non-empty sections so that symbol lookups prefer the
   // non-empty section.
   std::vector<std::pair<uint64_t, SectionRef>> SectionAddresses;
-  for (SectionRef Sec : Obj.sections()) {
-    std::string name = cantFail(Sec.getName()).str();
-    // llvm::errs() << llvm::format("section %s, addr %lx\n", name.c_str(), Sec.getAddress());
-    SectionAddresses.emplace_back(Sec.getAddress(), Sec);}
+  for (SectionRef Sec : Obj.sections())
+    SectionAddresses.emplace_back(Sec.getAddress(), Sec);
   llvm::stable_sort(SectionAddresses, [](const auto &LHS, const auto &RHS) {
     if (LHS.first != RHS.first)
       return LHS.first < RHS.first;

>From e597bdab617e092a2738a84a96c7be2109f43ad6 Mon Sep 17 00:00:00 2001
From: Derek Schuff <dschuff at chromium.org>
Date: Wed, 7 Feb 2024 16:25:45 -0800
Subject: [PATCH 7/7] cleanup

---
 llvm/lib/Object/WasmObjectFile.cpp            | 40 +++++++++----------
 .../wasm/linked-symbol-table-namesec.yaml     |  3 +-
 2 files changed, 21 insertions(+), 22 deletions(-)

diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp
index de5611a4f8b22..ea1715446d9d9 100644
--- a/llvm/lib/Object/WasmObjectFile.cpp
+++ b/llvm/lib/Object/WasmObjectFile.cpp
@@ -530,7 +530,7 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
         wasm::NameType nameType = wasm::NameType::FUNCTION;
         wasm::WasmSymbolInfo Info{Name,
                                   /*Kind */ wasm::WASM_SYMBOL_TYPE_FUNCTION,
-                                  /* Flags */0,
+                                  /* Flags */ 0,
                                   /* ImportModule */ std::nullopt,
                                   /* ImportName */ std::nullopt,
                                   /* ExportName */ std::nullopt,
@@ -560,6 +560,12 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
             Info.Flags |= wasm::WASM_SYMBOL_UNDEFINED;
           }
         } else if (Type == wasm::WASM_NAMES_GLOBAL) {
+          if (!SeenGlobals.insert(Index).second)
+            return make_error<GenericBinaryError>("global named more than once",
+                                                  object_error::parse_failed);
+          if (!isValidGlobalIndex(Index) || Name.empty())
+            return make_error<GenericBinaryError>("invalid global name entry",
+                                                  object_error::parse_failed);
           nameType = wasm::NameType::GLOBAL;
           Info.Kind = wasm::WASM_SYMBOL_TYPE_GLOBAL;
           if (isDefinedGlobalIndex(Index)) {
@@ -567,26 +573,19 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
           } else {
             Info.Flags |= wasm::WASM_SYMBOL_UNDEFINED;
           }
-
-          if (!SeenGlobals.insert(Index).second)
-            return make_error<GenericBinaryError>("global named more than once",
-                                                  object_error::parse_failed);
-          if (!isValidGlobalIndex(Index) || Name.empty())
-            return make_error<GenericBinaryError>("invalid global name entry",
-                                                  object_error::parse_failed);
         } else {
-          nameType = wasm::NameType::DATA_SEGMENT;
-          Info.Kind = wasm::WASM_SYMBOL_TYPE_DATA;
-          Info.Flags |= wasm::WASM_SYMBOL_BINDING_LOCAL;
-          assert(Index < DataSegments.size());
-          Info.DataRef = wasm::WasmDataReference{Index, 0,
-            DataSegments[Index].Data.Content.size()};
           if (!SeenSegments.insert(Index).second)
             return make_error<GenericBinaryError>(
                 "segment named more than once", object_error::parse_failed);
           if (Index > DataSegments.size())
             return make_error<GenericBinaryError>("invalid data segment name entry",
                                                   object_error::parse_failed);
+          nameType = wasm::NameType::DATA_SEGMENT;
+          Info.Kind = wasm::WASM_SYMBOL_TYPE_DATA;
+          Info.Flags |= wasm::WASM_SYMBOL_BINDING_LOCAL;
+          assert(Index < DataSegments.size());
+          Info.DataRef = wasm::WasmDataReference{
+              Index, 0, DataSegments[Index].Data.Content.size()};
         }
         DebugNames.push_back(wasm::WasmDebugName{nameType, Index, Name});
         if (!HasLinkingSection)
@@ -1949,13 +1948,12 @@ Expected<StringRef> WasmObjectFile::getSectionName(DataRefImpl Sec) const {
 }
 
 uint64_t WasmObjectFile::getSectionAddress(DataRefImpl Sec) const {
-    // For object files, use 0 for section addresses, and section offsets for
-    // symbol addresses. For linked files, use file offsets.
-    // See also getSymbolAddress.
-      return isRelocatableObject() || isSharedObject()
-                              ? 0
-                              :  Sections[Sec.d.a].Offset;
-   }
+  // For object files, use 0 for section addresses, and section offsets for
+  // symbol addresses. For linked files, use file offsets.
+  // See also getSymbolAddress.
+  return isRelocatableObject() || isSharedObject() ? 0
+                                                   : Sections[Sec.d.a].Offset;
+}
 
 uint64_t WasmObjectFile::getSectionIndex(DataRefImpl Sec) const {
   return Sec.d.a;
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 324dab4847849..622a6060b902a 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
@@ -7,6 +7,7 @@
 # CHECK-NEXT: 00000086 l F CODE my_func_local_name
 # CHECK-NEXT: 00000000    *UND* my_global_import_name
 # CHECK-NEXT: 00000001 g  GLOBAL my_global_export_name
+# CHECK-NEXT: 00000000 l O DATA my_datasegment_name
 
 --- !WASM
 FileHeader:
@@ -66,7 +67,7 @@ Sections:
         Offset:
           Opcode:          I32_CONST
           Value:           0
-        Content:         ''
+        Content:         'abcd1234'
   - Type:            CUSTOM
     Name:            name
     FunctionNames:



More information about the llvm-commits mailing list