diff options
Diffstat (limited to 'lldb/source/Plugins/SymbolFile')
14 files changed, 177 insertions, 34 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt b/lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt index 212cc36..c3f1bb5 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt +++ b/lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt @@ -35,6 +35,7 @@ add_lldb_library(lldbPluginSymbolFileDWARF PLUGIN SymbolFileDWARF.cpp SymbolFileDWARFDwo.cpp SymbolFileDWARFDebugMap.cpp + SymbolFileWasm.cpp UniqueDWARFASTType.cpp LINK_COMPONENTS diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index ba65f50..e58e28a 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -249,6 +249,14 @@ static unsigned GetCXXMethodCVQuals(const DWARFDIE &subprogram, return cv_quals; } +static std::string MakeLLDBFuncAsmLabel(const DWARFDIE &die) { + char const *name = die.GetMangledName(/*substitute_name_allowed*/ false); + if (!name) + return {}; + + return name; +} + TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc, const DWARFDIE &die, Log *log) { @@ -1231,7 +1239,7 @@ std::pair<bool, TypeSP> DWARFASTParserClang::ParseCXXMethod( clang::CXXMethodDecl *cxx_method_decl = m_ast.AddMethodToCXXRecordType( class_opaque_type.GetOpaqueQualType(), attrs.name.GetCString(), - attrs.mangled_name, clang_type, accessibility, attrs.is_virtual, + MakeLLDBFuncAsmLabel(die), clang_type, accessibility, attrs.is_virtual, is_static, attrs.is_inline, attrs.is_explicit, is_attr_used, attrs.is_artificial); @@ -1384,7 +1392,7 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, ignore_containing_context ? m_ast.GetTranslationUnitDecl() : containing_decl_ctx, GetOwningClangModule(die), name, clang_type, attrs.storage, - attrs.is_inline); + attrs.is_inline, MakeLLDBFuncAsmLabel(die)); std::free(name_buf); if (has_template_params) { @@ -1394,7 +1402,7 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, ignore_containing_context ? m_ast.GetTranslationUnitDecl() : containing_decl_ctx, GetOwningClangModule(die), attrs.name.GetStringRef(), clang_type, - attrs.storage, attrs.is_inline); + attrs.storage, attrs.is_inline, /*asm_label=*/{}); clang::FunctionTemplateDecl *func_template_decl = m_ast.CreateFunctionTemplateDecl( containing_decl_ctx, GetOwningClangModule(die), @@ -1406,20 +1414,6 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, lldbassert(function_decl); if (function_decl) { - // Attach an asm(<mangled_name>) label to the FunctionDecl. - // This ensures that clang::CodeGen emits function calls - // using symbols that are mangled according to the DW_AT_linkage_name. - // If we didn't do this, the external symbols wouldn't exactly - // match the mangled name LLDB knows about and the IRExecutionUnit - // would have to fall back to searching object files for - // approximately matching function names. The motivating - // example is generating calls to ABI-tagged template functions. - // This is done separately for member functions in - // AddMethodToCXXRecordType. - if (attrs.mangled_name) - function_decl->addAttr(clang::AsmLabelAttr::CreateImplicit( - m_ast.getASTContext(), attrs.mangled_name, /*literal=*/false)); - LinkDeclContextToDIE(function_decl, die); const clang::FunctionProtoType *function_prototype( diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp index a66af5b..94fc2e83 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -736,9 +736,11 @@ DWARFUnit::GetVendorDWARFOpcodeSize(const DataExtractor &data, bool DWARFUnit::ParseVendorDWARFOpcode(uint8_t op, const DataExtractor &opcodes, lldb::offset_t &offset, + RegisterContext *reg_ctx, + lldb::RegisterKind reg_kind, std::vector<Value> &stack) const { return GetSymbolFileDWARF().ParseVendorDWARFOpcode(op, opcodes, offset, - stack); + reg_ctx, reg_kind, stack); } bool DWARFUnit::ParseDWARFLocationList( diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h index f55400e..91a6938 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -164,9 +164,11 @@ public: const lldb::offset_t data_offset, const uint8_t op) const override; - bool ParseVendorDWARFOpcode(uint8_t op, const DataExtractor &opcodes, - lldb::offset_t &offset, - std::vector<Value> &stack) const override; + virtual bool ParseVendorDWARFOpcode(uint8_t op, const DataExtractor &opcodes, + lldb::offset_t &offset, + RegisterContext *reg_ctx, + lldb::RegisterKind reg_kind, + std::vector<Value> &stack) const override; bool ParseDWARFLocationList(const DataExtractor &data, DWARFExpressionList &loc_list) const; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 4b4a582..41ab8d1 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -41,6 +41,7 @@ #include "Plugins/ExpressionParser/Clang/ClangUtil.h" #include "Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h" +#include "Plugins/SymbolFile/DWARF/SymbolFileWasm.h" #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Symbol/Block.h" #include "lldb/Symbol/CompileUnit.h" @@ -327,6 +328,9 @@ llvm::StringRef SymbolFileDWARF::GetPluginDescriptionStatic() { } SymbolFile *SymbolFileDWARF::CreateInstance(ObjectFileSP objfile_sp) { + if (objfile_sp->GetArchitecture().GetTriple().isWasm()) + return new SymbolFileWasm(std::move(objfile_sp), + /*dwo_section_list*/ nullptr); return new SymbolFileDWARF(std::move(objfile_sp), /*dwo_section_list*/ nullptr); } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index 2dc862c..56d8ccb 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -329,6 +329,8 @@ public: virtual bool ParseVendorDWARFOpcode(uint8_t op, const DataExtractor &opcodes, lldb::offset_t &offset, + RegisterContext *reg_ctx, + lldb::RegisterKind reg_kind, std::vector<Value> &stack) const { return false; } @@ -556,6 +558,7 @@ protected: /// an index that identifies the .DWO or .o file. std::optional<uint64_t> m_file_index; }; + } // namespace dwarf } // namespace lldb_private::plugin diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp index c1829ab..52de3ab 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp @@ -97,9 +97,11 @@ uint64_t SymbolFileDWARFDwo::GetDebugInfoSize(bool load_all_debug_info) { } bool SymbolFileDWARFDwo::ParseVendorDWARFOpcode( - uint8_t op, const lldb_private::DataExtractor &opcodes, - lldb::offset_t &offset, std::vector<lldb_private::Value> &stack) const { - return GetBaseSymbolFile().ParseVendorDWARFOpcode(op, opcodes, offset, stack); + uint8_t op, const DataExtractor &opcodes, lldb::offset_t &offset, + RegisterContext *reg_ctx, lldb::RegisterKind reg_kind, + std::vector<Value> &stack) const { + return GetBaseSymbolFile().ParseVendorDWARFOpcode(op, opcodes, offset, + reg_ctx, reg_kind, stack); } llvm::DenseMap<const DWARFDebugInfoEntry *, Type *> & diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h index 75f5986..1ab6494 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h @@ -50,7 +50,8 @@ public: uint64_t GetDebugInfoSize(bool load_all_debug_info = false) override; bool ParseVendorDWARFOpcode(uint8_t op, const DataExtractor &opcodes, - lldb::offset_t &offset, + lldb::offset_t &offset, RegisterContext *reg_ctx, + lldb::RegisterKind reg_kind, std::vector<Value> &stack) const override; void FindGlobalVariables(ConstString name, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileWasm.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileWasm.cpp new file mode 100644 index 0000000..e25a89c --- /dev/null +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileWasm.cpp @@ -0,0 +1,100 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "SymbolFileWasm.h" +#include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h" +#include "Utility/WasmVirtualRegisters.h" +#include "lldb/Utility/LLDBLog.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::plugin::dwarf; + +SymbolFileWasm::SymbolFileWasm(ObjectFileSP objfile_sp, + SectionList *dwo_section_list) + : SymbolFileDWARF(objfile_sp, dwo_section_list) {} + +SymbolFileWasm::~SymbolFileWasm() = default; + +lldb::offset_t +SymbolFileWasm::GetVendorDWARFOpcodeSize(const DataExtractor &data, + const lldb::offset_t data_offset, + const uint8_t op) const { + if (op != llvm::dwarf::DW_OP_WASM_location) + return LLDB_INVALID_OFFSET; + + lldb::offset_t offset = data_offset; + const uint8_t wasm_op = data.GetU8(&offset); + switch (wasm_op) { + case 0: // LOCAL + case 1: // GLOBAL_FIXED + case 2: // OPERAND_STACK + data.GetULEB128(&offset); + break; + case 3: // GLOBAL_RELOC + data.GetU32(&offset); + break; + default: + return LLDB_INVALID_OFFSET; + } + + return offset - data_offset; +} + +bool SymbolFileWasm::ParseVendorDWARFOpcode(uint8_t op, + const DataExtractor &opcodes, + lldb::offset_t &offset, + RegisterContext *reg_ctx, + lldb::RegisterKind reg_kind, + std::vector<Value> &stack) const { + if (op != llvm::dwarf::DW_OP_WASM_location) + return false; + + uint32_t index = 0; + uint8_t tag = eWasmTagNotAWasmLocation; + + /// |DWARF Location Index | WebAssembly Construct | + /// |---------------------|-----------------------| + /// |0 | Local | + /// |1 or 3 | Global | + /// |2 | Operand Stack | + const uint8_t wasm_op = opcodes.GetU8(&offset); + switch (wasm_op) { + case 0: // LOCAL + index = opcodes.GetULEB128(&offset); + tag = eWasmTagLocal; + break; + case 1: // GLOBAL_FIXED + index = opcodes.GetULEB128(&offset); + tag = eWasmTagGlobal; + break; + case 2: // OPERAND_STACK + index = opcodes.GetULEB128(&offset); + tag = eWasmTagOperandStack; + break; + case 3: // GLOBAL_RELOC + index = opcodes.GetU32(&offset); + tag = eWasmTagGlobal; + break; + default: + return false; + } + + const uint32_t reg_num = GetWasmRegister(tag, index); + + Value tmp; + llvm::Error error = DWARFExpression::ReadRegisterValueAsScalar( + reg_ctx, reg_kind, reg_num, tmp); + if (error) { + LLDB_LOG_ERROR(GetLog(DWARFLog::DebugInfo), std::move(error), "{0}"); + return false; + } + + stack.push_back(tmp); + return true; +} diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileWasm.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileWasm.h new file mode 100644 index 0000000..0e0b742 --- /dev/null +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileWasm.h @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEWASM_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEWASM_H + +#include "SymbolFileDWARF.h" + +namespace lldb_private::plugin { +namespace dwarf { +class SymbolFileWasm : public SymbolFileDWARF { +public: + SymbolFileWasm(lldb::ObjectFileSP objfile_sp, SectionList *dwo_section_list); + + ~SymbolFileWasm() override; + + lldb::offset_t GetVendorDWARFOpcodeSize(const DataExtractor &data, + const lldb::offset_t data_offset, + const uint8_t op) const override; + + bool ParseVendorDWARFOpcode(uint8_t op, const DataExtractor &opcodes, + lldb::offset_t &offset, RegisterContext *reg_ctx, + lldb::RegisterKind reg_kind, + std::vector<Value> &stack) const override; +}; +} // namespace dwarf +} // namespace lldb_private::plugin + +#endif diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp index 702ec5e..8137622 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp @@ -88,7 +88,7 @@ struct CreateMethodDecl : public TypeVisitorCallbacks { MethodOptions::CompilerGenerated; function_decl = m_clang.AddMethodToCXXRecordType( parent_ty, proc_name, - /*mangled_name=*/nullptr, func_ct, /*access=*/access_type, + /*asm_label=*/{}, func_ct, /*access=*/access_type, /*is_virtual=*/is_virtual, /*is_static=*/is_static, /*is_inline=*/false, /*is_explicit=*/false, /*is_attr_used=*/false, /*is_artificial=*/is_artificial); @@ -903,7 +903,7 @@ PdbAstBuilder::CreateFunctionDecl(PdbCompilandSymId func_id, if (!function_decl) { function_decl = m_clang.AddMethodToCXXRecordType( parent_opaque_ty, func_name, - /*mangled_name=*/nullptr, func_ct, + /*asm_label=*/{}, func_ct, /*access=*/lldb::AccessType::eAccessPublic, /*is_virtual=*/false, /*is_static=*/false, /*is_inline=*/false, /*is_explicit=*/false, @@ -913,7 +913,7 @@ PdbAstBuilder::CreateFunctionDecl(PdbCompilandSymId func_id, } else { function_decl = m_clang.CreateFunctionDeclaration( parent, OptionalClangModuleID(), func_name, func_ct, func_storage, - is_inline); + is_inline, /*asm_label=*/{}); CreateFunctionParameters(func_id, *function_decl, param_count); } return function_decl; diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h index 1f888f4..98b965c 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h @@ -65,7 +65,7 @@ struct CVTagRecord { } llvm::StringRef name() const { - if (m_kind == Struct || m_kind == Union) + if (m_kind == Struct || m_kind == Class) return cvclass.Name; if (m_kind == Enum) return cvenum.Name; diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp index 807ee5b..1c575e9 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp @@ -111,9 +111,8 @@ void UdtRecordCompleter::AddMethod(llvm::StringRef name, TypeIndex type_idx, bool is_artificial = (options & MethodOptions::CompilerGenerated) == MethodOptions::CompilerGenerated; m_ast_builder.clang().AddMethodToCXXRecordType( - derived_opaque_ty, name.data(), nullptr, method_ct, - access_type, attrs.isVirtual(), attrs.isStatic(), false, false, false, - is_artificial); + derived_opaque_ty, name.data(), /*asm_label=*/{}, method_ct, access_type, + attrs.isVirtual(), attrs.isStatic(), false, false, false, is_artificial); m_cxx_record_map[derived_opaque_ty].insert({name, method_ct}); } diff --git a/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp index 0090d8f..8b8eac6e 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp +++ b/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp @@ -954,7 +954,8 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) { auto decl = m_ast.CreateFunctionDeclaration( decl_context, OptionalClangModuleID(), name, - type->GetForwardCompilerType(), storage, func->hasInlineAttribute()); + type->GetForwardCompilerType(), storage, func->hasInlineAttribute(), + /*asm_label=*/{}); std::vector<clang::ParmVarDecl *> params; if (std::unique_ptr<PDBSymbolTypeFunctionSig> sig = func->getSignature()) { @@ -1446,7 +1447,7 @@ PDBASTParser::AddRecordMethod(lldb_private::SymbolFile &symbol_file, // TODO: get mangled name for the method. return m_ast.AddMethodToCXXRecordType( record_type.GetOpaqueQualType(), name.c_str(), - /*mangled_name*/ nullptr, method_comp_type, access, method.isVirtual(), + /*asm_label=*/{}, method_comp_type, access, method.isVirtual(), method.isStatic(), method.hasInlineAttribute(), /*is_explicit*/ false, // FIXME: Need this field in CodeView. /*is_attr_used*/ false, |