[Lldb-commits] [lldb] [lldb] Use the source name when the linkage name is not mangled (PR #205701)
Jonas Devlieghere via lldb-commits
lldb-commits at lists.llvm.org
Thu Jun 25 09:17:25 PDT 2026
https://github.com/JDevlieghere updated https://github.com/llvm/llvm-project/pull/205701
>From 18676f2f394b643fc45e197044cda9f1aacbd6b2 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jonas at devlieghere.com>
Date: Wed, 24 Jun 2026 17:38:34 -0700
Subject: [PATCH 1/2] [lldb] Use the source name when the linkage name is not
mangled
When a DW_TAG_subprogram has a DW_AT_linkage_name that is not actually a
mangled name and differs from DW_AT_name, lldb used the linkage name as
the function's display name. For C++ the linkage name demangles back to
the source name, but a plain symbol such as __main_argc_argv does not, so
the function showed up under its raw linkage name in backtraces, breakpoint
locations and `image lookup`, and was not findable by its source name.
This happens on WebAssembly: wasi-libc renames `int main(int, char**)` to
its __main_argc_argv argv-passing wrapper, keeping DW_AT_name "main" but
recording DW_AT_linkage_name "__main_argc_argv".
When the linkage name has no recognized mangling scheme, use DW_AT_name as
the display name and keep the linkage name as the symbol, so lookups by
either name still resolve.
---
.../SymbolFile/DWARF/DWARFASTParserClang.cpp | 10 ++-
.../DWARF/wasm-function-display-name.yaml | 81 +++++++++++++++++++
2 files changed, 90 insertions(+), 1 deletion(-)
create mode 100644 lldb/test/Shell/SymbolFile/DWARF/wasm-function-display-name.yaml
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index b2a363231237f..a33e7c276867d 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -2478,7 +2478,15 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(
decl_line, decl_column, call_file, call_line,
call_column, &frame_base)) {
Mangled func_name;
- if (mangled)
+ if (mangled && name &&
+ Mangled::GetManglingScheme(mangled) == Mangled::eManglingSchemeNone) {
+ // The linkage name is present but is not actually a mangled name (e.g.
+ // wasi-libc renames `main` to its `__main_argc_argv` argv-passing
+ // wrapper). Display the source name (DW_AT_name) and keep the linkage
+ // name as the symbol so lookups by either name still resolve.
+ func_name.SetDemangledName(ConstString(name));
+ func_name.SetMangledName(ConstString(mangled));
+ } else if (mangled)
func_name.SetValue(ConstString(mangled));
else if ((die.GetParent().Tag() == DW_TAG_compile_unit ||
die.GetParent().Tag() == DW_TAG_partial_unit) &&
diff --git a/lldb/test/Shell/SymbolFile/DWARF/wasm-function-display-name.yaml b/lldb/test/Shell/SymbolFile/DWARF/wasm-function-display-name.yaml
new file mode 100644
index 0000000000000..9a0df8642403f
--- /dev/null
+++ b/lldb/test/Shell/SymbolFile/DWARF/wasm-function-display-name.yaml
@@ -0,0 +1,81 @@
+# A function whose DWARF DW_AT_linkage_name is present but is NOT a mangled
+# name -- it differs from DW_AT_name. This happens on WebAssembly, where
+# wasi-libc renames `main` to its `__main_argc_argv` argv-passing wrapper:
+# the DWARF keeps DW_AT_name "main" but records DW_AT_linkage_name
+# "__main_argc_argv". Here the same shape is produced with an asm() rename.
+#
+# LLDB must display the source name (DW_AT_name, "impl") rather than the raw,
+# un-demanglable linkage name, while still keeping the linkage name as the
+# symbol so a breakpoint set by either name resolves.
+
+# RUN: yaml2obj %s -o %t
+# RUN: %lldb %t \
+# RUN: -o "image lookup -v -n impl" \
+# RUN: -o "breakpoint set -n impl" \
+# RUN: -o exit 2>&1 | FileCheck %s
+
+# The function is displayed by its source name, with the linkage name kept as
+# the symbol; a breakpoint set by the source name resolves and displays it too.
+# CHECK: Function: {{.*}}name = "impl", mangled = "renamed_export"
+# CHECK: Breakpoint 1: where = {{.*}}`impl
+
+--- !WASM
+FileHeader:
+ Version: 0x1
+Sections:
+ - Type: TYPE
+ Signatures:
+ - Index: 0
+ ParamTypes:
+ - I32
+ ReturnTypes:
+ - I32
+ - Type: FUNCTION
+ FunctionTypes: [ 0 ]
+ - Type: MEMORY
+ Memories:
+ - Minimum: 0x1
+ - Type: GLOBAL
+ Globals:
+ - Index: 0
+ Type: I32
+ Mutable: true
+ InitExpr:
+ Opcode: I32_CONST
+ Value: 65536
+ - Type: EXPORT
+ Exports:
+ - Name: memory
+ Kind: MEMORY
+ Index: 0
+ - Name: renamed_export
+ Kind: FUNCTION
+ Index: 0
+ - Type: CODE
+ Functions:
+ - Index: 0
+ Locals:
+ - Type: I32
+ Count: 1
+ Body: 23808080800041106B21012001200036020C200128020C41016A0F0B
+ - Type: CUSTOM
+ Name: .debug_abbrev
+ Payload: 011101250E1305030E10171B0E110112060000022E011101120640186E0E030E3A0B3B0B271949133F1900000305000218030E3A0B3B0B49130000042400030E3E0B0B0B000000
+ - Type: CUSTOM
+ Name: .debug_info
+ Payload: 5500000004000000000004012D0000001D001F0000000000000015000000020000001F00000002020000001F00000004ED00019F020000001A0000000104510000000302910C00000000010451000000000411000000050400
+ - Type: CUSTOM
+ Name: .debug_str
+ Payload: 780072656E616D65645F6578706F727400696E74002F746D7000696D706C002F746D702F72656E616D652E6300636C616E672076657273696F6E2032322E312E302D776173692D73646B202868747470733A2F2F6769746875622E636F6D2F6C6C766D2F6C6C766D2D70726F6A65637420343433346461626236393931363835366238323466363861363462303239633637313735653533322900
+ - Type: CUSTOM
+ Name: .debug_line
+ Payload: 3F000000040020000000010101FB0E0D0001010101000000010000010072656E616D652E6300000000000005020200000015051A0A084A051C065805133C0202000101
+ - Type: CUSTOM
+ Name: name
+ FunctionNames:
+ - Index: 0
+ Name: renamed_export
+ GlobalNames:
+ - Index: 0
+ Name: __stack_pointer
+...
>From d7b0cb543ea6c89b55ee8030c34ab3db2c2c924b Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jonas at devlieghere.com>
Date: Thu, 25 Jun 2026 09:17:15 -0700
Subject: [PATCH 2/2] Braces
Co-authored-by: Michael Buch <michaelbuch12 at gmail.com>
---
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index a33e7c276867d..f4d3f87331a88 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -2486,9 +2486,9 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(
// name as the symbol so lookups by either name still resolve.
func_name.SetDemangledName(ConstString(name));
func_name.SetMangledName(ConstString(mangled));
- } else if (mangled)
+ } else if (mangled) {
func_name.SetValue(ConstString(mangled));
- else if ((die.GetParent().Tag() == DW_TAG_compile_unit ||
+ } else if ((die.GetParent().Tag() == DW_TAG_compile_unit ||
die.GetParent().Tag() == DW_TAG_partial_unit) &&
Language::LanguageIsCPlusPlus(
SymbolFileDWARF::GetLanguage(*die.GetCU())) &&
More information about the lldb-commits
mailing list