https://github.com/JDevlieghere created 
https://github.com/llvm/llvm-project/pull/213554

A Wasm module carries the identifier its linker gave it in a `build_id` custom 
section, whose payload is the length of the identifier followed by its bytes. 
That identifier is the only thing that tells one build of a module from another.

`wasm-ld` emits the section only when asked, so the API test build asks for it. 
A module linked without one still has no UUID.

>From f8a60be6caeec393b1dac715ad2d04599adda96c Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <[email protected]>
Date: Sat, 1 Aug 2026 23:45:01 -0700
Subject: [PATCH] [lldb] Identify a WebAssembly module by its build id

A Wasm module carries the identifier its linker gave it in a build_id custom
section, whose payload is the length of the identifier followed by its bytes.
That identifier is the only thing that tells one build of a module from
another, and ObjectFileWasm never read it: it declared a UUID and returned it
without ever assigning one, so every Wasm module came back unidentified and
anything keyed on module identity had nothing to work with.

wasm-ld emits the section only when asked, so the API test build asks for it.
A module linked without one still has no UUID, since there is nothing to read.

(cherry picked from commit 0cc09feac1a57c994d326a6573452f1127bba23e)
---
 .../Python/lldbsuite/test/make/WASI.rules     |  5 ++
 .../ObjectFile/wasm/ObjectFileWasm.cpp        | 35 ++++++++++++
 .../Plugins/ObjectFile/wasm/ObjectFileWasm.h  |  2 +-
 lldb/test/Shell/ObjectFile/wasm/build-id.yaml | 55 +++++++++++++++++++
 4 files changed, 96 insertions(+), 1 deletion(-)
 create mode 100644 lldb/test/Shell/ObjectFile/wasm/build-id.yaml

diff --git a/lldb/packages/Python/lldbsuite/test/make/WASI.rules 
b/lldb/packages/Python/lldbsuite/test/make/WASI.rules
index 32e5656c41c4f..a99dd3c85c877 100644
--- a/lldb/packages/Python/lldbsuite/test/make/WASI.rules
+++ b/lldb/packages/Python/lldbsuite/test/make/WASI.rules
@@ -14,3 +14,8 @@ ARCH_LDFLAGS += \
 # Unlike most native linkers, wasm-ld garbage-collects unreferenced sections by
 # default, which strips globals and functions that a test wants to inspect.
 LDFLAGS += -Wl,--no-gc-sections
+
+# A debugger tells one build of a module from another by its build id, and
+# wasm-ld emits one only when asked, so a module linked without this carries
+# nothing that identifies it.
+LDFLAGS += -Wl,--build-id
diff --git a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp 
b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
index 3f73e239afe47..2e98fd91432db 100644
--- a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
+++ b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
@@ -1136,6 +1136,41 @@ DataExtractor ObjectFileWasm::ReadImageData(offset_t 
offset, uint32_t size) {
   return data;
 }
 
+UUID ObjectFileWasm::GetUUID() {
+  if (m_uuid)
+    return m_uuid;
+
+  // A Wasm module carries the identifier a linker gave it in a custom section,
+  // as a vector of bytes. It is the only thing that tells one build of a 
module
+  // from another, so a module linked without one cannot be identified at all.
+  static ConstString g_sect_name_build_id("build_id");
+  for (const section_info &sect_info : m_sect_infos) {
+    if (g_sect_name_build_id != sect_info.name)
+      continue;
+
+    DataExtractor section_data = ReadImageData(sect_info.offset, 
sect_info.size);
+    llvm::DataExtractor data = section_data.GetAsLLVM();
+    llvm::DataExtractor::Cursor c(0);
+    llvm::Expected<uint32_t> length = GetULEB32(data, c);
+    if (!length) {
+      LLDB_LOG_ERROR(GetLog(LLDBLog::Object), length.takeError(),
+                     "failed to parse the build id length: {0}");
+      return m_uuid;
+    }
+    llvm::SmallVector<uint8_t, 32> id(*length, 0);
+    data.getU8(c, id.data(), id.size());
+    if (!c) {
+      LLDB_LOG_ERROR(GetLog(LLDBLog::Object), c.takeError(),
+                     "failed to parse the build id: {0}");
+      return m_uuid;
+    }
+    m_uuid = UUID(id);
+    break;
+  }
+
+  return m_uuid;
+}
+
 std::optional<FileSpec> ObjectFileWasm::GetExternalDebugInfoFileSpec() {
   static ConstString g_sect_name_external_debug_info("external_debug_info");
 
diff --git a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h 
b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
index 80a955211ebb2..f70ae4e6a6d32 100644
--- a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
+++ b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
@@ -103,7 +103,7 @@ class ObjectFileWasm : public ObjectFile {
 
   ArchSpec GetArchitecture() override { return m_arch; }
 
-  UUID GetUUID() override { return m_uuid; }
+  UUID GetUUID() override;
 
   uint32_t GetDependentModules(FileSpecList &files) override { return 0; }
 
diff --git a/lldb/test/Shell/ObjectFile/wasm/build-id.yaml 
b/lldb/test/Shell/ObjectFile/wasm/build-id.yaml
new file mode 100644
index 0000000000000..84f539da4c182
--- /dev/null
+++ b/lldb/test/Shell/ObjectFile/wasm/build-id.yaml
@@ -0,0 +1,55 @@
+# A Wasm module carries the identifier its linker gave it in a build_id custom
+# section, whose payload is the length of the identifier followed by its bytes.
+
+# RUN: yaml2obj %s --docnum=1 -o %t.16
+# RUN: lldb-test object-file %t.16 | FileCheck %s --check-prefix=UUID16
+
+# UUID16: Plugin name: wasm
+# UUID16: UUID: 01020304-0506-0708-090A-0B0C0D0E0F10
+
+# An identifier of any other length is just as good, since it is only ever
+# compared with another.
+# RUN: yaml2obj %s --docnum=2 -o %t.20
+# RUN: lldb-test object-file %t.20 | FileCheck %s --check-prefix=UUID20
+
+# UUID20: UUID: 01020304-0506-0708-090A-0B0C0D0E0F10-11121314
+
+# A module linked without the section has nothing that identifies it.
+# RUN: yaml2obj %s --docnum=3 -o %t.none
+# RUN: lldb-test object-file %t.none | FileCheck %s --check-prefix=NOUUID
+
+# NOUUID: UUID:{{ *$}}
+
+--- !WASM
+FileHeader:
+  Version:         0x00000001
+Sections:
+  - Type:            CUSTOM
+    Name:            build_id
+    Payload:         100102030405060708090A0B0C0D0E0F10
+  - Type:            CODE
+    Functions:
+      - Index:           0
+        Locals:
+        Body:            0B
+--- !WASM
+FileHeader:
+  Version:         0x00000001
+Sections:
+  - Type:            CUSTOM
+    Name:            build_id
+    Payload:         140102030405060708090A0B0C0D0E0F1011121314
+  - Type:            CODE
+    Functions:
+      - Index:           0
+        Locals:
+        Body:            0B
+--- !WASM
+FileHeader:
+  Version:         0x00000001
+Sections:
+  - Type:            CODE
+    Functions:
+      - Index:           0
+        Locals:
+        Body:            0B

_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to