[lldb] Recover a WebAssembly function's mangled name from its declaration (#211707)
The Wasm "name" section stores only demangled names, so SymbolFileWasm recovers each function's mangled name from the DWARF and attaches it to the code symbol. Currently, it only does so from a defining DIE, matched by address. When we only have a declaration DIE (e.g. TU compiled without debug info), it still carries the linkage name, but wouldn't get associated without the address. Match a declaration-only DIE to its code symbol by the demangled name that the name section already carries, and attach the linkage name that way. Assisted-by: Claude
This commit is contained in:
parent
eedb658af3
commit
044a1d9743
2 changed files with 131 additions and 3 deletions
|
|
@ -13,11 +13,15 @@
|
|||
#include "Utility/WasmVirtualRegisters.h"
|
||||
#include "lldb/Core/Address.h"
|
||||
#include "lldb/Core/AddressRange.h"
|
||||
#include "lldb/Core/Mangled.h"
|
||||
#include "lldb/Core/Module.h"
|
||||
#include "lldb/Expression/DWARFExpression.h"
|
||||
#include "lldb/Symbol/Symbol.h"
|
||||
#include "lldb/Symbol/Symtab.h"
|
||||
#include "lldb/Utility/ConstString.h"
|
||||
#include "lldb/Utility/LLDBLog.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include <optional>
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
|
@ -30,6 +34,25 @@ SymbolFileWasm::SymbolFileWasm(ObjectFileSP objfile_sp,
|
|||
|
||||
SymbolFileWasm::~SymbolFileWasm() = default;
|
||||
|
||||
/// Index the code symbols that carry no mangled name by their demangled name.
|
||||
/// The value is a symbol table index rather than a Symbol pointer because
|
||||
/// pointers do not survive symbols being appended to the table.
|
||||
static llvm::DenseMap<ConstString, uint32_t>
|
||||
BuildDemangledCodeSymbolIndex(Symtab &symtab) {
|
||||
llvm::DenseMap<ConstString, uint32_t> index;
|
||||
for (size_t i = 0, n = symtab.GetNumSymbols(); i < n; ++i) {
|
||||
Symbol *symbol = symtab.SymbolAtIndex(i);
|
||||
if (!symbol || symbol->GetType() != eSymbolTypeCode)
|
||||
continue;
|
||||
Mangled &mangled = symbol->GetMangled();
|
||||
if (mangled.GetMangledName())
|
||||
continue;
|
||||
if (ConstString demangled = mangled.GetDemangledName())
|
||||
index.try_emplace(demangled, static_cast<uint32_t>(i));
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
void SymbolFileWasm::AddSymbols(Symtab &symtab) {
|
||||
SymbolFileDWARF::AddSymbols(symtab);
|
||||
|
||||
|
|
@ -43,6 +66,9 @@ void SymbolFileWasm::AddSymbols(Symtab &symtab) {
|
|||
ModuleSP module_sp = GetObjectFile()->GetModule();
|
||||
SectionList *section_list = module_sp ? module_sp->GetSectionList() : nullptr;
|
||||
|
||||
// Built on demand to recover a mangled name from a declaration-only DIE.
|
||||
std::optional<llvm::DenseMap<ConstString, uint32_t>> demangled_index;
|
||||
|
||||
DWARFDebugInfo &debug_info = DebugInfo();
|
||||
const size_t num_units = debug_info.GetNumUnits();
|
||||
for (size_t i = 0; i < num_units; ++i) {
|
||||
|
|
@ -64,11 +90,24 @@ void SymbolFileWasm::AddSymbols(Symtab &symtab) {
|
|||
die.GetMangledName(/*substitute_name_allowed=*/false);
|
||||
if (!mangled)
|
||||
continue;
|
||||
|
||||
// A defining DIE names its symbol by address. A function defined in a
|
||||
// translation unit compiled without debug info has only a declaration
|
||||
// DIE with no address, so match its symbol by the demangled name that
|
||||
// the Wasm name section carries.
|
||||
const addr_t file_addr =
|
||||
die.GetAttributeValueAsAddress(DW_AT_low_pc, LLDB_INVALID_ADDRESS);
|
||||
if (file_addr == LLDB_INVALID_ADDRESS)
|
||||
continue;
|
||||
Symbol *symbol = symtab.FindSymbolAtFileAddress(file_addr);
|
||||
Symbol *symbol = nullptr;
|
||||
if (file_addr != LLDB_INVALID_ADDRESS) {
|
||||
symbol = symtab.FindSymbolAtFileAddress(file_addr);
|
||||
} else if (ConstString demangled =
|
||||
Mangled(ConstString(mangled)).GetDemangledName()) {
|
||||
if (!demangled_index)
|
||||
demangled_index = BuildDemangledCodeSymbolIndex(symtab);
|
||||
auto it = demangled_index->find(demangled);
|
||||
if (it != demangled_index->end())
|
||||
symbol = symtab.SymbolAtIndex(it->second);
|
||||
}
|
||||
if (symbol && !symbol->GetMangled().GetMangledName())
|
||||
symbol->GetMangled().SetMangledName(ConstString(mangled));
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,89 @@
|
|||
# A C++ function defined in a translation unit compiled without debug info has
|
||||
# no defining DWARF DIE, only a declaration DIE (DW_AT_declaration, no
|
||||
# DW_AT_low_pc) that carries its DW_AT_linkage_name. The Wasm "name" section
|
||||
# stores only the demangled name, so unless the linkage name is recovered from
|
||||
# that declaration the code symbol has no mangled name and cannot be found by
|
||||
# it, which also defeats guessing a language from the symbol name.
|
||||
#
|
||||
# `S::fn()` below is such a function: its symbol comes from the name section
|
||||
# (demangled) and its only DIE is the declaration. LLDB must attach the linkage
|
||||
# name to the symbol so it resolves by the mangled name.
|
||||
|
||||
# REQUIRES: webassembly
|
||||
# RUN: yaml2obj %s -o %t.wasm
|
||||
# RUN: %lldb %t.wasm -o "image lookup -s _ZN1S2fnEv" -o exit 2>&1 | FileCheck %s
|
||||
|
||||
# CHECK: 1 symbols match '_ZN1S2fnEv'
|
||||
# CHECK: S::fn()
|
||||
|
||||
--- !WASM
|
||||
FileHeader:
|
||||
Version: 0x1
|
||||
Sections:
|
||||
- Type: TYPE
|
||||
Signatures:
|
||||
- Index: 0
|
||||
ParamTypes: []
|
||||
ReturnTypes: []
|
||||
- Index: 1
|
||||
ParamTypes: []
|
||||
ReturnTypes:
|
||||
- I32
|
||||
- Type: FUNCTION
|
||||
FunctionTypes: [ 0, 1, 1 ]
|
||||
- Type: MEMORY
|
||||
Memories:
|
||||
- Minimum: 0x2
|
||||
- Type: GLOBAL
|
||||
Globals:
|
||||
- Index: 0
|
||||
Type: I32
|
||||
Mutable: true
|
||||
InitExpr:
|
||||
Opcode: I32_CONST
|
||||
Value: 65536
|
||||
- Type: EXPORT
|
||||
Exports:
|
||||
- Name: _Z6callerv
|
||||
Kind: FUNCTION
|
||||
Index: 1
|
||||
- Name: _ZN1S2fnEv
|
||||
Kind: FUNCTION
|
||||
Index: 2
|
||||
- Type: CODE
|
||||
Functions:
|
||||
- Index: 0
|
||||
Locals: []
|
||||
Body: 0B
|
||||
- Index: 1
|
||||
Locals: []
|
||||
Body: 1082808080000F0B
|
||||
- Index: 2
|
||||
Locals: []
|
||||
Body: 412A0F0B
|
||||
- Type: CUSTOM
|
||||
Name: .debug_abbrev
|
||||
Payload: 011101250E1305030E10171B0E110112060000023400030E49133F193A0B3B0B02180000031301360B030E0B0B3A0B3B0B0000042E006E0E030E3A0B3B0B49133C193F190000052400030E3E0B0B0B0000062E001101120640186E0E030E3A0B3B0B49133F19000000
|
||||
- Type: CUSTOM
|
||||
HeaderSecSizeEncodingLen: 2
|
||||
Name: .debug_info
|
||||
Payload: 7300000004000000000004014300000021002A00000000000000350000000500000009000000021A000000370000000202050300000100030541000000010101040B00000032000000010150000000000516000000050406050000000900000007ED03000000009F000000002300000002035000000000
|
||||
- Type: CUSTOM
|
||||
Name: .debug_str
|
||||
Payload: 5F5A3663616C6C657276005F5A4E315332666E457600696E7400676C6F62616C5F730063616C6C6572007573652E63707000666E002F746D702F676C6865726D005300636C616E672076657273696F6E2032322E312E302D776173692D73646B202868747470733A2F2F6769746875622E636F6D2F6C6C766D2F6C6C766D2D70726F6A65637420343433346461626236393931363835366238323466363861363462303239633637313735653533322900
|
||||
- Type: CUSTOM
|
||||
Name: .debug_line
|
||||
Payload: 4600000004002A000000010101FB0E0D0001010101000000010000012E00006864722E68000100007573652E6370700000000000040205170A0005020600000014051006660202000101
|
||||
- Type: CUSTOM
|
||||
Name: name
|
||||
FunctionNames:
|
||||
- Index: 0
|
||||
Name: __wasm_call_ctors
|
||||
- Index: 1
|
||||
Name: 'caller()'
|
||||
- Index: 2
|
||||
Name: 'S::fn()'
|
||||
GlobalNames:
|
||||
- Index: 0
|
||||
Name: __stack_pointer
|
||||
...
|
||||
Loading…
Reference in a new issue