diff options
Diffstat (limited to 'source/Plugins/SymbolFile/DWARF')
48 files changed, 1357 insertions, 2571 deletions
diff --git a/source/Plugins/SymbolFile/DWARF/CMakeLists.txt b/source/Plugins/SymbolFile/DWARF/CMakeLists.txt index f62a496f808a..0e47ee34fe51 100644 --- a/source/Plugins/SymbolFile/DWARF/CMakeLists.txt +++ b/source/Plugins/SymbolFile/DWARF/CMakeLists.txt @@ -4,9 +4,6 @@ add_lldb_library(lldbPluginSymbolFileDWARF PLUGIN DIERef.cpp DWARFAbbreviationDeclaration.cpp DWARFASTParserClang.cpp - DWARFASTParserGo.cpp - DWARFASTParserJava.cpp - DWARFASTParserOCaml.cpp DWARFAttribute.cpp DWARFBaseDIE.cpp DWARFCompileUnit.cpp diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h b/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h index ae7c770d6ef7..24d5f26745dc 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h +++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h @@ -12,10 +12,16 @@ #include "DWARFDefines.h" #include "lldb/Core/PluginInterface.h" +#include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/CompilerDecl.h" #include "lldb/Symbol/CompilerDeclContext.h" class DWARFDIE; +namespace lldb_private { +class CompileUnit; +class ExecutionContext; +} +class SymbolFileDWARF; class DWARFASTParser { public: @@ -27,7 +33,7 @@ public: bool *type_is_new_ptr) = 0; virtual lldb_private::Function * - ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc, + ParseFunctionFromDWARF(lldb_private::CompileUnit &comp_unit, const DWARFDIE &die) = 0; virtual bool @@ -45,6 +51,10 @@ public: virtual std::vector<DWARFDIE> GetDIEForDeclContext(lldb_private::CompilerDeclContext decl_context) = 0; + + static llvm::Optional<lldb_private::SymbolFile::ArrayInfo> + ParseChildArrayInfo(const DWARFDIE &parent_die, + const lldb_private::ExecutionContext *exe_ctx = nullptr); }; #endif // SymbolFileDWARF_DWARFASTParser_h_ diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index fe6f1be3ca48..70d48e5f1dfa 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -125,7 +125,7 @@ ClangASTImporter &DWARFASTParserClang::GetClangASTImporter() { } /// Detect a forward declaration that is nested in a DW_TAG_module. -static bool isClangModuleFwdDecl(const DWARFDIE &Die) { +static bool IsClangModuleFwdDecl(const DWARFDIE &Die) { if (!Die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0)) return false; auto Parent = Die.GetParent(); @@ -142,30 +142,31 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWO(const DWARFDIE &die, Log *log) { if (!dwo_module_sp) return TypeSP(); - // This type comes from an external DWO module. - std::vector<CompilerContext> dwo_context; - die.GetDWOContext(dwo_context); + // If this type comes from a Clang module, look in the DWARF section + // of the pcm file in the module cache. Clang generates DWO skeleton + // units as breadcrumbs to find them. + std::vector<CompilerContext> decl_context; + die.GetDeclContext(decl_context); TypeMap dwo_types; - if (!dwo_module_sp->GetSymbolVendor()->FindTypes(dwo_context, true, + if (!dwo_module_sp->GetSymbolVendor()->FindTypes(decl_context, true, dwo_types)) { - if (!isClangModuleFwdDecl(die)) + if (!IsClangModuleFwdDecl(die)) return TypeSP(); // Since this this type is defined in one of the Clang modules imported by // this symbol file, search all of them. - auto *SymFile = die.GetCU()->GetSymbolFileDWARF(); - for (const auto &NameModule : SymFile->getExternalTypeModules()) { - if (!NameModule.second) + auto *sym_file = die.GetCU()->GetSymbolFileDWARF(); + for (const auto &name_module : sym_file->getExternalTypeModules()) { + if (!name_module.second) continue; - SymbolVendor *SymVendor = NameModule.second->GetSymbolVendor(); - if (SymVendor->FindTypes(dwo_context, true, dwo_types)) + SymbolVendor *sym_vendor = name_module.second->GetSymbolVendor(); + if (sym_vendor->FindTypes(decl_context, true, dwo_types)) break; } } - const size_t num_dwo_types = dwo_types.GetSize(); - if (num_dwo_types != 1) + if (dwo_types.GetSize() != 1) return TypeSP(); // We found a real definition for this type in the Clang module, so lets use @@ -307,14 +308,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, decl.SetColumn(form_value.Unsigned()); break; case DW_AT_name: - type_name_cstr = form_value.AsCString(); - // Work around a bug in llvm-gcc where they give a name to a - // reference type which doesn't include the "&"... - if (tag == DW_TAG_reference_type) { - if (strchr(type_name_cstr, '&') == NULL) - type_name_cstr = NULL; - } if (type_name_cstr) type_name_const_str.SetCString(type_name_cstr); break; @@ -421,8 +415,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, if (!clang_type && (encoding_data_type == Type::eEncodingIsPointerUID || - encoding_data_type == Type::eEncodingIsTypedefUID) && - sc.comp_unit != NULL) { + encoding_data_type == Type::eEncodingIsTypedefUID)) { if (tag == DW_TAG_pointer_type) { DWARFDIE target_die = die.GetReferencedDIE(DW_AT_type); @@ -558,16 +551,8 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, if (attributes.ExtractFormValueAtIndex(i, form_value)) { switch (attr) { case DW_AT_decl_file: - if (die.GetCU()->DW_AT_decl_file_attributes_are_invalid()) { - // llvm-gcc outputs invalid DW_AT_decl_file attributes that - // always point to the compile unit file, so we clear this - // invalid value so that we can still unique types - // efficiently. - decl.SetFile(FileSpec("<invalid>", false)); - } else - decl.SetFile( - sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex( - form_value.Unsigned())); + decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex( + form_value.Unsigned())); break; case DW_AT_decl_line: @@ -671,7 +656,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, } if (byte_size_valid && byte_size == 0 && type_name_cstr && - die.HasChildren() == false && + !die.HasChildren() && sc.comp_unit->GetLanguage() == eLanguageTypeObjC) { // Work around an issue with clang at the moment where forward // declarations for objective C classes are emitted as: @@ -909,7 +894,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, // has child classes or types that require the class to be created // for use as their decl contexts the class will be ready to accept // these child definitions. - if (die.HasChildren() == false) { + if (!die.HasChildren()) { // No children for this struct/union/class, lets finish it if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) { ClangASTContext::CompleteTagDeclarationDefinition(clang_type); @@ -1308,10 +1293,10 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, if (die.HasChildren()) { bool skip_artificial = true; - ParseChildParameters(sc, containing_decl_ctx, die, skip_artificial, - is_static, is_variadic, has_template_params, - function_param_types, function_param_decls, - type_quals); + ParseChildParameters(*sc.comp_unit, containing_decl_ctx, die, + skip_artificial, is_static, is_variadic, + has_template_params, function_param_types, + function_param_decls, type_quals); } bool ignore_containing_context = false; @@ -1748,16 +1733,19 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, Type *element_type = dwarf->ResolveTypeUID(type_die_ref); if (element_type) { - std::vector<uint64_t> element_orders; - ParseChildArrayInfo(sc, die, first_index, element_orders, - byte_stride, bit_stride); + auto array_info = ParseChildArrayInfo(die); + if (array_info) { + first_index = array_info->first_index; + byte_stride = array_info->byte_stride; + bit_stride = array_info->bit_stride; + } if (byte_stride == 0 && bit_stride == 0) byte_stride = element_type->GetByteSize(); CompilerType array_element_type = element_type->GetForwardCompilerType(); if (ClangASTContext::IsCXXClassType(array_element_type) && - array_element_type.GetCompleteType() == false) { + !array_element_type.GetCompleteType()) { ModuleSP module_sp = die.GetModule(); if (module_sp) { if (die.GetCU()->GetProducer() == eProducerClang) @@ -1800,12 +1788,11 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, } uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride; - if (element_orders.size() > 0) { + if (array_info && array_info->element_orders.size() > 0) { uint64_t num_elements = 0; - std::vector<uint64_t>::const_reverse_iterator pos; - std::vector<uint64_t>::const_reverse_iterator end = - element_orders.rend(); - for (pos = element_orders.rbegin(); pos != end; ++pos) { + auto end = array_info->element_orders.rend(); + for (auto pos = array_info->element_orders.rbegin(); pos != end; + ++pos) { num_elements = *pos; clang_type = m_ast.CreateArrayType(array_element_type, num_elements, is_vector); @@ -1824,6 +1811,8 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, NULL, DIERef(type_die_form).GetUID(dwarf), Type::eEncodingIsUID, &decl, clang_type, Type::eResolveStateFull)); type_sp->SetEncodingType(element_type); + m_ast.SetMetadataAsUserID(clang_type.GetOpaqueQualType(), + die.GetID()); } } } break; @@ -1861,12 +1850,14 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, clang_type = ClangASTContext::CreateMemberPointerType( class_clang_type, pointee_clang_type); - byte_size = clang_type.GetByteSize(nullptr); - - type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, - byte_size, NULL, LLDB_INVALID_UID, - Type::eEncodingIsUID, NULL, clang_type, - Type::eResolveStateForward)); + if (llvm::Optional<uint64_t> clang_type_size = + clang_type.GetByteSize(nullptr)) { + byte_size = *clang_type_size; + type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, + byte_size, NULL, LLDB_INVALID_UID, + Type::eEncodingIsUID, NULL, clang_type, + Type::eResolveStateForward)); + } } break; @@ -2056,7 +2047,10 @@ bool DWARFASTParserClang::ParseTemplateDIE( clang_type.IsIntegerOrEnumerationType(is_signed); if (tag == DW_TAG_template_value_parameter && uval64_valid) { - llvm::APInt apint(clang_type.GetBitSize(nullptr), uval64, is_signed); + llvm::Optional<uint64_t> size = clang_type.GetBitSize(nullptr); + if (!size) + return false; + llvm::APInt apint(*size, uval64, is_signed); template_param_infos.args.push_back( clang::TemplateArgument(*ast, llvm::APSInt(apint, !is_signed), ClangUtil::GetQualType(clang_type))); @@ -2108,95 +2102,6 @@ bool DWARFASTParserClang::ParseTemplateParameterInfos( return template_param_infos.args.size() == template_param_infos.names.size(); } -// Checks whether m1 is an overload of m2 (as opposed to an override). This is -// called by addOverridesForMethod to distinguish overrides (which share a -// vtable entry) from overloads (which require distinct entries). -static bool isOverload(clang::CXXMethodDecl *m1, clang::CXXMethodDecl *m2) { - // FIXME: This should detect covariant return types, but currently doesn't. - lldbassert(&m1->getASTContext() == &m2->getASTContext() && - "Methods should have the same AST context"); - clang::ASTContext &context = m1->getASTContext(); - - const auto *m1Type = - llvm::cast<clang::FunctionProtoType>( - context.getCanonicalType(m1->getType())); - - const auto *m2Type = - llvm::cast<clang::FunctionProtoType>( - context.getCanonicalType(m2->getType())); - - auto compareArgTypes = - [&context](const clang::QualType &m1p, const clang::QualType &m2p) { - return context.hasSameType(m1p.getUnqualifiedType(), - m2p.getUnqualifiedType()); - }; - - // FIXME: In C++14 and later, we can just pass m2Type->param_type_end() - // as a fourth parameter to std::equal(). - return (m1->getNumParams() != m2->getNumParams()) || - !std::equal(m1Type->param_type_begin(), m1Type->param_type_end(), - m2Type->param_type_begin(), compareArgTypes); -} - -// If decl is a virtual method, walk the base classes looking for methods that -// decl overrides. This table of overridden methods is used by IRGen to -// determine the vtable layout for decl's parent class. -static void addOverridesForMethod(clang::CXXMethodDecl *decl) { - if (!decl->isVirtual()) - return; - - clang::CXXBasePaths paths; - - auto find_overridden_methods = - [decl](const clang::CXXBaseSpecifier *specifier, clang::CXXBasePath &path) { - if (auto *base_record = - llvm::dyn_cast<clang::CXXRecordDecl>( - specifier->getType()->getAs<clang::RecordType>()->getDecl())) { - - clang::DeclarationName name = decl->getDeclName(); - - // If this is a destructor, check whether the base class destructor is - // virtual. - if (name.getNameKind() == clang::DeclarationName::CXXDestructorName) - if (auto *baseDtorDecl = base_record->getDestructor()) { - if (baseDtorDecl->isVirtual()) { - path.Decls = baseDtorDecl; - return true; - } else - return false; - } - - // Otherwise, search for name in the base class. - for (path.Decls = base_record->lookup(name); !path.Decls.empty(); - path.Decls = path.Decls.slice(1)) { - if (auto *method_decl = - llvm::dyn_cast<clang::CXXMethodDecl>(path.Decls.front())) - if (method_decl->isVirtual() && !isOverload(decl, method_decl)) { - path.Decls = method_decl; - return true; - } - } - } - - return false; - }; - - if (decl->getParent()->lookupInBases(find_overridden_methods, paths)) { - for (auto *overridden_decl : paths.found_decls()) - decl->addOverriddenMethod( - llvm::cast<clang::CXXMethodDecl>(overridden_decl)); - } -} - -// If clang_type is a CXXRecordDecl, builds the method override list for each -// of its virtual methods. -static void addMethodOverrides(ClangASTContext &ast, CompilerType &clang_type) { - if (auto *record = - ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType())) - for (auto *method : record->methods()) - addOverridesForMethod(method); -} - bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type, CompilerType &clang_type) { @@ -2287,14 +2192,14 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die, } SymbolContext sc(die.GetLLDBCompileUnit()); - std::vector<clang::CXXBaseSpecifier *> base_classes; + std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases; std::vector<int> member_accessibilities; bool is_a_class = false; // Parse members and base classes first DWARFDIECollection member_function_dies; DelayedPropertyList delayed_properties; - ParseChildMembers(sc, die, clang_type, class_language, base_classes, + ParseChildMembers(sc, die, clang_type, class_language, bases, member_accessibilities, member_function_dies, delayed_properties, default_accessibility, is_a_class, layout_info); @@ -2358,17 +2263,17 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die, &member_accessibilities.front(), member_accessibilities.size()); } - if (!base_classes.empty()) { + if (!bases.empty()) { // Make sure all base classes refer to complete types and not forward // declarations. If we don't do this, clang will crash with an - // assertion in the call to clang_type.SetBaseClassesForClassType() - for (auto &base_class : base_classes) { + // assertion in the call to clang_type.TransferBaseClasses() + for (const auto &base_class : bases) { clang::TypeSourceInfo *type_source_info = base_class->getTypeSourceInfo(); if (type_source_info) { CompilerType base_class_type( &m_ast, type_source_info->getType().getAsOpaquePtr()); - if (base_class_type.GetCompleteType() == false) { + if (!base_class_type.GetCompleteType()) { auto module = dwarf->GetObjectFile()->GetModule(); module->ReportError(":: Class '%s' has a base class '%s' which " "does not have a complete definition.", @@ -2381,7 +2286,7 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die, // We have no choice other than to pretend that the base class // is complete. If we don't do this, clang will crash when we // call setBases() inside of - // "clang_type.SetBaseClassesForClassType()" below. Since we + // "clang_type.TransferBaseClasses()" below. Since we // provide layout assistance, all ivars in this class and other // classes will be fine, this is the best we can do short of // crashing. @@ -2393,19 +2298,14 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die, } } } - m_ast.SetBaseClassesForClassType(clang_type.GetOpaqueQualType(), - &base_classes.front(), - base_classes.size()); - // Clang will copy each CXXBaseSpecifier in "base_classes" so we have - // to free them all. - ClangASTContext::DeleteBaseClassSpecifiers(&base_classes.front(), - base_classes.size()); + m_ast.TransferBaseClasses(clang_type.GetOpaqueQualType(), + std::move(bases)); } } } - addMethodOverrides(m_ast, clang_type); + m_ast.AddMethodOverridesForCXXRecordType(clang_type.GetOpaqueQualType()); ClangASTContext::BuildIndirectFields(clang_type); ClangASTContext::CompleteTagDeclarationDefinition(clang_type); @@ -2604,9 +2504,7 @@ size_t DWARFASTParserClang::ParseChildEnumerators( if (name && name[0] && got_value) { m_ast.AddEnumerationValueToEnumerationType( - clang_type.GetOpaqueQualType(), - m_ast.GetEnumerationIntegerType(clang_type.GetOpaqueQualType()), - decl, name, enum_value, enumerator_byte_size * 8); + clang_type, decl, name, enum_value, enumerator_byte_size * 8); ++enumerators_added; } } @@ -2663,7 +2561,7 @@ protected: }; #endif -Function *DWARFASTParserClang::ParseFunctionFromDWARF(const SymbolContext &sc, +Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit, const DWARFDIE &die) { DWARFRangeList func_ranges; const char *name = NULL; @@ -2724,9 +2622,9 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(const SymbolContext &sc, clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE(die, nullptr); - ParseChildParameters(sc, containing_decl_ctx, die, true, is_static, - is_variadic, has_template_params, param_types, - param_decls, type_quals); + ParseChildParameters(comp_unit, containing_decl_ctx, die, true, + is_static, is_variadic, has_template_params, + param_types, param_decls, type_quals); sstr << "("; for (size_t i = 0; i < param_types.size(); i++) { if (i > 0) @@ -2747,7 +2645,7 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(const SymbolContext &sc, std::unique_ptr<Declaration> decl_ap; if (decl_file != 0 || decl_line != 0 || decl_column != 0) decl_ap.reset(new Declaration( - sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), + comp_unit.GetSupportFiles().GetFileSpecAtIndex(decl_file), decl_line, decl_column)); SymbolFileDWARF *dwarf = die.GetDWARF(); @@ -2758,7 +2656,7 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(const SymbolContext &sc, if (dwarf->FixupAddress(func_range.GetBaseAddress())) { const user_id_t func_user_id = die.GetID(); - func_sp.reset(new Function(sc.comp_unit, + func_sp.reset(new Function(&comp_unit, func_user_id, // UserID is the DIE offset func_user_id, func_name, func_type, func_range)); // first address range @@ -2766,7 +2664,7 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(const SymbolContext &sc, if (func_sp.get() != NULL) { if (frame_base.IsValid()) func_sp->GetFrameBaseExpression() = frame_base; - sc.comp_unit->AddFunction(func_sp); + comp_unit.AddFunction(func_sp); return func_sp.get(); } } @@ -2778,7 +2676,7 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(const SymbolContext &sc, bool DWARFASTParserClang::ParseChildMembers( const SymbolContext &sc, const DWARFDIE &parent_die, CompilerType &class_clang_type, const LanguageType class_language, - std::vector<clang::CXXBaseSpecifier *> &base_classes, + std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes, std::vector<int> &member_accessibilities, DWARFDIECollection &member_function_dies, DelayedPropertyList &delayed_properties, AccessType &default_accessibility, @@ -2977,15 +2875,6 @@ bool DWARFASTParserClang::ParseChildMembers( class_language == eLanguageTypeObjC_plus_plus) accessibility = eAccessNone; - if (member_idx == 0 && !is_artificial && name && - (strstr(name, "_vptr$") == name)) { - // Not all compilers will mark the vtable pointer member as - // artificial (llvm-gcc). We can't have the virtual members in our - // classes otherwise it throws off all child offsets since we end up - // having and extra pointer sized member in our class layouts. - is_artificial = true; - } - // Handle static members if (is_external && member_byte_offset == UINT32_MAX) { Type *var_type = die.ResolveTypeUID(DIERef(encoding_form)); @@ -3000,7 +2889,7 @@ bool DWARFASTParserClang::ParseChildMembers( break; } - if (is_artificial == false) { + if (!is_artificial) { Type *member_type = die.ResolveTypeUID(DIERef(encoding_form)); clang::FieldDecl *field_decl = NULL; @@ -3141,7 +3030,7 @@ bool DWARFASTParserClang::ParseChildMembers( if (anon_field_info.IsValid()) { clang::FieldDecl *unnamed_bitfield_decl = ClangASTContext::AddFieldToRecordType( - class_clang_type, NULL, + class_clang_type, llvm::StringRef(), m_ast.GetBuiltinTypeForEncodingAndBitSize( eEncodingSint, word_width), accessibility, anon_field_info.bit_size); @@ -3198,7 +3087,7 @@ bool DWARFASTParserClang::ParseChildMembers( } if (ClangASTContext::IsCXXClassType(member_clang_type) && - member_clang_type.GetCompleteType() == false) { + !member_clang_type.GetCompleteType()) { if (die.GetCU()->GetProducer() == eProducerClang) module_sp->ReportError( "DWARF DIE at 0x%8.8x (class %s) has a member variable " @@ -3383,9 +3272,14 @@ bool DWARFASTParserClang::ParseChildMembers( if (class_language == eLanguageTypeObjC) { ast->SetObjCSuperClass(class_clang_type, base_class_clang_type); } else { - base_classes.push_back(ast->CreateBaseClassSpecifier( - base_class_clang_type.GetOpaqueQualType(), accessibility, - is_virtual, is_base_of_class)); + std::unique_ptr<clang::CXXBaseSpecifier> result = + ast->CreateBaseClassSpecifier( + base_class_clang_type.GetOpaqueQualType(), accessibility, + is_virtual, is_base_of_class); + if (!result) + break; + + base_classes.push_back(std::move(result)); if (is_virtual) { // Do not specify any offset for virtual inheritance. The DWARF @@ -3419,7 +3313,7 @@ bool DWARFASTParserClang::ParseChildMembers( } size_t DWARFASTParserClang::ParseChildParameters( - const SymbolContext &sc, clang::DeclContext *containing_decl_ctx, + CompileUnit &comp_unit, clang::DeclContext *containing_decl_ctx, const DWARFDIE &parent_die, bool skip_artificial, bool &is_static, bool &is_variadic, bool &has_template_params, std::vector<CompilerType> &function_param_types, @@ -3451,7 +3345,7 @@ size_t DWARFASTParserClang::ParseChildParameters( if (attributes.ExtractFormValueAtIndex(i, form_value)) { switch (attr) { case DW_AT_decl_file: - decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex( + decl.SetFile(comp_unit.GetSupportFiles().GetFileSpecAtIndex( form_value.Unsigned())); break; case DW_AT_decl_line: @@ -3517,8 +3411,9 @@ size_t DWARFASTParserClang::ParseChildParameters( function_param_types.push_back(type->GetForwardCompilerType()); clang::ParmVarDecl *param_var_decl = - m_ast.CreateParameterDeclaration( - name, type->GetForwardCompilerType(), storage); + m_ast.CreateParameterDeclaration(containing_decl_ctx, name, + type->GetForwardCompilerType(), + storage); assert(param_var_decl); function_param_decls.push_back(param_var_decl); @@ -3551,12 +3446,12 @@ size_t DWARFASTParserClang::ParseChildParameters( return arg_idx; } -void DWARFASTParserClang::ParseChildArrayInfo( - const SymbolContext &sc, const DWARFDIE &parent_die, int64_t &first_index, - std::vector<uint64_t> &element_orders, uint32_t &byte_stride, - uint32_t &bit_stride) { +llvm::Optional<SymbolFile::ArrayInfo> +DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die, + const ExecutionContext *exe_ctx) { + SymbolFile::ArrayInfo array_info; if (!parent_die) - return; + return llvm::None; for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling()) { @@ -3580,15 +3475,31 @@ void DWARFASTParserClang::ParseChildArrayInfo( break; case DW_AT_count: - num_elements = form_value.Unsigned(); + if (DWARFDIE var_die = die.GetReferencedDIE(DW_AT_count)) { + if (var_die.Tag() == DW_TAG_variable) + if (exe_ctx) { + if (auto frame = exe_ctx->GetFrameSP()) { + Status error; + lldb::VariableSP var_sp; + auto valobj_sp = frame->GetValueForVariableExpressionPath( + var_die.GetName(), eNoDynamicValues, 0, var_sp, + error); + if (valobj_sp) { + num_elements = valobj_sp->GetValueAsUnsigned(0); + break; + } + } + } + } else + num_elements = form_value.Unsigned(); break; case DW_AT_bit_stride: - bit_stride = form_value.Unsigned(); + array_info.bit_stride = form_value.Unsigned(); break; case DW_AT_byte_stride: - byte_stride = form_value.Unsigned(); + array_info.byte_stride = form_value.Unsigned(); break; case DW_AT_lower_bound: @@ -3622,11 +3533,12 @@ void DWARFASTParserClang::ParseChildArrayInfo( num_elements = upper_bound - lower_bound + 1; } - element_orders.push_back(num_elements); + array_info.element_orders.push_back(num_elements); } } break; } } + return array_info; } Type *DWARFASTParserClang::GetTypeForDIE(const DWARFDIE &die) { diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h index 57c1fc07b2b6..63e058d7bf21 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h +++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h @@ -10,15 +10,11 @@ #ifndef SymbolFileDWARF_DWARFASTParserClang_h_ #define SymbolFileDWARF_DWARFASTParserClang_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes #include "clang/AST/CharUnits.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" -// Project includes #include "DWARFASTParser.h" #include "DWARFDefines.h" #include "lldb/Core/ClangForward.h" @@ -26,8 +22,12 @@ #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/ClangASTImporter.h" +namespace lldb_private { +class CompileUnit; +} class DWARFDebugInfoEntry; class DWARFDIECollection; +class SymbolFileDWARF; class DWARFASTParserClang : public DWARFASTParser { public: @@ -41,7 +41,7 @@ public: bool *type_is_new_ptr) override; lldb_private::Function * - ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc, + ParseFunctionFromDWARF(lldb_private::CompileUnit &comp_unit, const DWARFDIE &die) override; bool @@ -80,19 +80,19 @@ protected: lldb_private::ClangASTContext::TemplateParameterInfos &template_param_infos); - bool - ParseChildMembers(const lldb_private::SymbolContext &sc, const DWARFDIE &die, - lldb_private::CompilerType &class_compiler_type, - const lldb::LanguageType class_language, - std::vector<clang::CXXBaseSpecifier *> &base_classes, - std::vector<int> &member_accessibilities, - DWARFDIECollection &member_function_dies, - DelayedPropertyList &delayed_properties, - lldb::AccessType &default_accessibility, bool &is_a_class, - lldb_private::ClangASTImporter::LayoutInfo &layout_info); + bool ParseChildMembers( + const lldb_private::SymbolContext &sc, const DWARFDIE &die, + lldb_private::CompilerType &class_compiler_type, + const lldb::LanguageType class_language, + std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes, + std::vector<int> &member_accessibilities, + DWARFDIECollection &member_function_dies, + DelayedPropertyList &delayed_properties, + lldb::AccessType &default_accessibility, bool &is_a_class, + lldb_private::ClangASTImporter::LayoutInfo &layout_info); size_t - ParseChildParameters(const lldb_private::SymbolContext &sc, + ParseChildParameters(lldb_private::CompileUnit &comp_unit, clang::DeclContext *containing_decl_ctx, const DWARFDIE &parent_die, bool skip_artificial, bool &is_static, bool &is_variadic, @@ -101,11 +101,6 @@ protected: std::vector<clang::ParmVarDecl *> &function_param_decls, unsigned &type_quals); - void ParseChildArrayInfo(const lldb_private::SymbolContext &sc, - const DWARFDIE &parent_die, int64_t &first_index, - std::vector<uint64_t> &element_orders, - uint32_t &byte_stride, uint32_t &bit_stride); - size_t ParseChildEnumerators(const lldb_private::SymbolContext &sc, lldb_private::CompilerType &compiler_type, bool is_signed, uint32_t enumerator_byte_size, diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp deleted file mode 100644 index 328212e4b684..000000000000 --- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp +++ /dev/null @@ -1,772 +0,0 @@ -//===-- DWARFASTParserGo.cpp ---------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "DWARFASTParserGo.h" - -#include "DWARFASTParserGo.h" -#include "DWARFDIE.h" -#include "DWARFDIECollection.h" -#include "DWARFDebugInfo.h" -#include "DWARFDeclContext.h" -#include "DWARFDefines.h" -#include "SymbolFileDWARF.h" -#include "SymbolFileDWARFDebugMap.h" -#include "UniqueDWARFASTType.h" - -#include "clang/Basic/Specifiers.h" - -#include "lldb/Core/Module.h" -#include "lldb/Core/Value.h" -#include "lldb/Symbol/CompileUnit.h" -#include "lldb/Symbol/Function.h" -#include "lldb/Symbol/ObjectFile.h" -#include "lldb/Symbol/TypeList.h" - -//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN - -#ifdef ENABLE_DEBUG_PRINTF -#include <stdio.h> -#define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__) -#else -#define DEBUG_PRINTF(fmt, ...) -#endif - -#define DW_AT_go_kind 0x2900 -#define DW_AT_go_key 0x2901 -#define DW_AT_go_elem 0x2902 - -using namespace lldb; -using namespace lldb_private; -DWARFASTParserGo::DWARFASTParserGo(GoASTContext &ast) : m_ast(ast) {} - -DWARFASTParserGo::~DWARFASTParserGo() {} - -TypeSP DWARFASTParserGo::ParseTypeFromDWARF( - const lldb_private::SymbolContext &sc, const DWARFDIE &die, - lldb_private::Log *log, bool *type_is_new_ptr) { - TypeSP type_sp; - - if (type_is_new_ptr) - *type_is_new_ptr = false; - - if (die) { - SymbolFileDWARF *dwarf = die.GetDWARF(); - if (log) { - dwarf->GetObjectFile()->GetModule()->LogMessage( - log, "DWARFASTParserGo::ParseTypeFromDWARF (die = 0x%8.8x) %s name = " - "'%s')", - die.GetOffset(), DW_TAG_value_to_name(die.Tag()), die.GetName()); - } - - Type *type_ptr = dwarf->m_die_to_type.lookup(die.GetDIE()); - TypeList *type_list = dwarf->GetTypeList(); - if (type_ptr == NULL) { - if (type_is_new_ptr) - *type_is_new_ptr = true; - - const dw_tag_t tag = die.Tag(); - - bool is_forward_declaration = false; - DWARFAttributes attributes; - const char *type_name_cstr = NULL; - ConstString type_name_const_str; - Type::ResolveState resolve_state = Type::eResolveStateUnresolved; - uint64_t byte_size = 0; - uint64_t go_kind = 0; - Declaration decl; - - Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID; - CompilerType compiler_type; - DWARFFormValue form_value; - - dw_attr_t attr; - - switch (tag) { - case DW_TAG_base_type: - case DW_TAG_pointer_type: - case DW_TAG_typedef: - case DW_TAG_unspecified_type: { - // Set a bit that lets us know that we are currently parsing this - dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED; - - const size_t num_attributes = die.GetAttributes(attributes); - lldb::user_id_t encoding_uid = LLDB_INVALID_UID; - - if (num_attributes > 0) { - uint32_t i; - for (i = 0; i < num_attributes; ++i) { - attr = attributes.AttributeAtIndex(i); - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attr) { - case DW_AT_name: - type_name_cstr = form_value.AsCString(); - if (type_name_cstr) - type_name_const_str.SetCString(type_name_cstr); - break; - case DW_AT_byte_size: - byte_size = form_value.Unsigned(); - break; - case DW_AT_encoding: - // = form_value.Unsigned(); - break; - case DW_AT_type: - encoding_uid = form_value.Reference(); - break; - case DW_AT_go_kind: - go_kind = form_value.Unsigned(); - break; - default: - // Do we care about DW_AT_go_key or DW_AT_go_elem? - break; - } - } - } - } - - DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8lx\n", - die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr, - encoding_uid); - - switch (tag) { - default: - break; - - case DW_TAG_unspecified_type: - resolve_state = Type::eResolveStateFull; - compiler_type = m_ast.CreateVoidType(type_name_const_str); - break; - - case DW_TAG_base_type: - resolve_state = Type::eResolveStateFull; - compiler_type = - m_ast.CreateBaseType(go_kind, type_name_const_str, byte_size); - break; - - case DW_TAG_pointer_type: - encoding_data_type = Type::eEncodingIsPointerUID; - break; - case DW_TAG_typedef: - encoding_data_type = Type::eEncodingIsTypedefUID; - CompilerType impl; - Type *type = dwarf->ResolveTypeUID(encoding_uid); - if (type) { - if (go_kind == 0 && type->GetName() == type_name_const_str) { - // Go emits extra typedefs as a forward declaration. Ignore - // these. - dwarf->m_die_to_type[die.GetDIE()] = type; - return type->shared_from_this(); - } - impl = type->GetForwardCompilerType(); - compiler_type = - m_ast.CreateTypedefType(go_kind, type_name_const_str, impl); - } - break; - } - - type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, - byte_size, NULL, encoding_uid, - encoding_data_type, &decl, compiler_type, - resolve_state)); - - dwarf->m_die_to_type[die.GetDIE()] = type_sp.get(); - } break; - - case DW_TAG_structure_type: { - // Set a bit that lets us know that we are currently parsing this - dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED; - bool byte_size_valid = false; - - const size_t num_attributes = die.GetAttributes(attributes); - if (num_attributes > 0) { - uint32_t i; - for (i = 0; i < num_attributes; ++i) { - attr = attributes.AttributeAtIndex(i); - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attr) { - case DW_AT_name: - type_name_cstr = form_value.AsCString(); - type_name_const_str.SetCString(type_name_cstr); - break; - - case DW_AT_byte_size: - byte_size = form_value.Unsigned(); - byte_size_valid = true; - break; - - case DW_AT_go_kind: - go_kind = form_value.Unsigned(); - break; - - // TODO: Should we use SLICETYPE's DW_AT_go_elem? - default: - break; - } - } - } - } - - // TODO(ribrdb): Do we need this? - - // UniqueDWARFASTType is large, so don't create a local variables on - // the stack, put it on the heap. This function is often called - // recursively and clang isn't good and sharing the stack space for - // variables in different blocks. - std::unique_ptr<UniqueDWARFASTType> unique_ast_entry_ap( - new UniqueDWARFASTType()); - - // Only try and unique the type if it has a name. - if (type_name_const_str && - dwarf->GetUniqueDWARFASTTypeMap().Find( - type_name_const_str, die, decl, - byte_size_valid ? byte_size : -1, *unique_ast_entry_ap)) { - // We have already parsed this type or from another compile unit. GCC - // loves to use the "one definition rule" which can result in - // multiple definitions of the same class over and over in each - // compile unit. - type_sp = unique_ast_entry_ap->m_type_sp; - if (type_sp) { - dwarf->m_die_to_type[die.GetDIE()] = type_sp.get(); - return type_sp; - } - } - - DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), - DW_TAG_value_to_name(tag), type_name_cstr); - - bool compiler_type_was_created = false; - compiler_type.SetCompilerType( - &m_ast, - dwarf->m_forward_decl_die_to_clang_type.lookup(die.GetDIE())); - if (!compiler_type) { - compiler_type_was_created = true; - compiler_type = - m_ast.CreateStructType(go_kind, type_name_const_str, byte_size); - } - - type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, - byte_size, NULL, LLDB_INVALID_UID, - Type::eEncodingIsUID, &decl, compiler_type, - Type::eResolveStateForward)); - - // Add our type to the unique type map so we don't end up creating many - // copies of the same type over and over in the ASTContext for our - // module - unique_ast_entry_ap->m_type_sp = type_sp; - unique_ast_entry_ap->m_die = die; - unique_ast_entry_ap->m_declaration = decl; - unique_ast_entry_ap->m_byte_size = byte_size; - dwarf->GetUniqueDWARFASTTypeMap().Insert(type_name_const_str, - *unique_ast_entry_ap); - - if (!is_forward_declaration) { - // Always start the definition for a class type so that if the class - // has child classes or types that require the class to be created - // for use as their decl contexts the class will be ready to accept - // these child definitions. - if (die.HasChildren() == false) { - // No children for this struct/union/class, lets finish it - m_ast.CompleteStructType(compiler_type); - } else if (compiler_type_was_created) { - // Leave this as a forward declaration until we need to know the - // details of the type. lldb_private::Type will automatically call - // the SymbolFile virtual function - // "SymbolFileDWARF::CompleteType(Type *)" When the definition - // needs to be defined. - dwarf->m_forward_decl_die_to_clang_type[die.GetDIE()] = - compiler_type.GetOpaqueQualType(); - dwarf->m_forward_decl_clang_type_to_die[compiler_type - .GetOpaqueQualType()] = - die.GetDIERef(); - // SetHasExternalStorage (compiler_type.GetOpaqueQualType(), true); - } - } - } break; - - case DW_TAG_subprogram: - case DW_TAG_subroutine_type: { - // Set a bit that lets us know that we are currently parsing this - dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED; - - bool is_variadic = false; - clang::StorageClass storage = - clang::SC_None; //, Extern, Static, PrivateExtern - - const size_t num_attributes = die.GetAttributes(attributes); - if (num_attributes > 0) { - uint32_t i; - for (i = 0; i < num_attributes; ++i) { - attr = attributes.AttributeAtIndex(i); - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attr) { - case DW_AT_name: - type_name_cstr = form_value.AsCString(); - type_name_const_str.SetCString(type_name_cstr); - break; - - case DW_AT_external: - if (form_value.Unsigned()) { - if (storage == clang::SC_None) - storage = clang::SC_Extern; - else - storage = clang::SC_PrivateExtern; - } - break; - - case DW_AT_high_pc: - case DW_AT_low_pc: - break; - } - } - } - } - - DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), - DW_TAG_value_to_name(tag), type_name_cstr); - - std::vector<CompilerType> function_param_types; - - // Parse the function children for the parameters - - if (die.HasChildren()) { - ParseChildParameters(sc, die, is_variadic, function_param_types); - } - - // compiler_type will get the function prototype clang type after this - // call - compiler_type = m_ast.CreateFunctionType( - type_name_const_str, function_param_types.data(), - function_param_types.size(), is_variadic); - - type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, 0, NULL, - LLDB_INVALID_UID, Type::eEncodingIsUID, &decl, - compiler_type, Type::eResolveStateFull)); - assert(type_sp.get()); - } break; - - case DW_TAG_array_type: { - // Set a bit that lets us know that we are currently parsing this - dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED; - - lldb::user_id_t type_die_offset = DW_INVALID_OFFSET; - int64_t first_index = 0; - uint32_t byte_stride = 0; - uint32_t bit_stride = 0; - const size_t num_attributes = die.GetAttributes(attributes); - - if (num_attributes > 0) { - uint32_t i; - for (i = 0; i < num_attributes; ++i) { - attr = attributes.AttributeAtIndex(i); - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attr) { - case DW_AT_name: - type_name_cstr = form_value.AsCString(); - type_name_const_str.SetCString(type_name_cstr); - break; - - case DW_AT_type: - type_die_offset = form_value.Reference(); - break; - case DW_AT_byte_size: - break; // byte_size = form_value.Unsigned(); break; - case DW_AT_go_kind: - go_kind = form_value.Unsigned(); - break; - default: - break; - } - } - } - - DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), - DW_TAG_value_to_name(tag), type_name_cstr); - - Type *element_type = dwarf->ResolveTypeUID(type_die_offset); - - if (element_type) { - std::vector<uint64_t> element_orders; - ParseChildArrayInfo(sc, die, first_index, element_orders, - byte_stride, bit_stride); - if (byte_stride == 0) - byte_stride = element_type->GetByteSize(); - CompilerType array_element_type = - element_type->GetForwardCompilerType(); - if (element_orders.size() > 0) { - if (element_orders.size() > 1) - printf("golang: unsupported multi-dimensional array %s\n", - type_name_cstr); - compiler_type = m_ast.CreateArrayType( - type_name_const_str, array_element_type, element_orders[0]); - } else { - compiler_type = m_ast.CreateArrayType(type_name_const_str, - array_element_type, 0); - } - type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, - byte_stride, NULL, type_die_offset, - Type::eEncodingIsUID, &decl, compiler_type, - Type::eResolveStateFull)); - type_sp->SetEncodingType(element_type); - } - } - } break; - - default: - dwarf->GetObjectFile()->GetModule()->ReportError( - "{0x%8.8x}: unhandled type tag 0x%4.4x (%s), " - "please file a bug and attach the file at the " - "start of this error message", - die.GetOffset(), tag, DW_TAG_value_to_name(tag)); - break; - } - - if (type_sp.get()) { - DWARFDIE sc_parent_die = - SymbolFileDWARF::GetParentSymbolContextDIE(die); - dw_tag_t sc_parent_tag = sc_parent_die.Tag(); - - SymbolContextScope *symbol_context_scope = NULL; - if (sc_parent_tag == DW_TAG_compile_unit || - sc_parent_tag == DW_TAG_partial_unit) { - symbol_context_scope = sc.comp_unit; - } else if (sc.function != NULL && sc_parent_die) { - symbol_context_scope = - sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID()); - if (symbol_context_scope == NULL) - symbol_context_scope = sc.function; - } - - if (symbol_context_scope != NULL) { - type_sp->SetSymbolContextScope(symbol_context_scope); - } - - // We are ready to put this type into the uniqued list up at the module - // level - type_list->Insert(type_sp); - - dwarf->m_die_to_type[die.GetDIE()] = type_sp.get(); - } - } else if (type_ptr != DIE_IS_BEING_PARSED) { - type_sp = type_ptr->shared_from_this(); - } - } - return type_sp; -} - -size_t DWARFASTParserGo::ParseChildParameters( - const SymbolContext &sc, - - const DWARFDIE &parent_die, bool &is_variadic, - std::vector<CompilerType> &function_param_types) { - if (!parent_die) - return 0; - - size_t arg_idx = 0; - for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); - die = die.GetSibling()) { - - dw_tag_t tag = die.Tag(); - switch (tag) { - case DW_TAG_formal_parameter: { - DWARFAttributes attributes; - const size_t num_attributes = die.GetAttributes(attributes); - if (num_attributes > 0) { - Declaration decl; - DWARFFormValue param_type_die_offset; - - uint32_t i; - for (i = 0; i < num_attributes; ++i) { - const dw_attr_t attr = attributes.AttributeAtIndex(i); - DWARFFormValue form_value; - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attr) { - case DW_AT_name: - // = form_value.AsCString(); - break; - case DW_AT_type: - param_type_die_offset = form_value; - break; - case DW_AT_location: - // if (form_value.BlockData()) - // { - // const DWARFDataExtractor& - // debug_info_data = - // debug_info(); - // uint32_t block_length = - // form_value.Unsigned(); - // DWARFDataExtractor - // location(debug_info_data, - // form_value.BlockData() - - // debug_info_data.GetDataStart(), - // block_length); - // } - // else - // { - // } - // break; - default: - break; - } - } - } - - Type *type = parent_die.ResolveTypeUID(DIERef(param_type_die_offset)); - if (type) { - function_param_types.push_back(type->GetForwardCompilerType()); - } - } - arg_idx++; - } break; - - case DW_TAG_unspecified_parameters: - is_variadic = true; - break; - - default: - break; - } - } - return arg_idx; -} - -void DWARFASTParserGo::ParseChildArrayInfo( - const SymbolContext &sc, const DWARFDIE &parent_die, int64_t &first_index, - std::vector<uint64_t> &element_orders, uint32_t &byte_stride, - uint32_t &bit_stride) { - if (!parent_die) - return; - - for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); - die = die.GetSibling()) { - const dw_tag_t tag = die.Tag(); - switch (tag) { - case DW_TAG_subrange_type: { - DWARFAttributes attributes; - const size_t num_child_attributes = die.GetAttributes(attributes); - if (num_child_attributes > 0) { - uint64_t num_elements = 0; - uint32_t i; - for (i = 0; i < num_child_attributes; ++i) { - const dw_attr_t attr = attributes.AttributeAtIndex(i); - DWARFFormValue form_value; - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attr) { - case DW_AT_count: - num_elements = form_value.Unsigned(); - break; - - default: - case DW_AT_type: - break; - } - } - } - - element_orders.push_back(num_elements); - } - } break; - } - } -} - -bool DWARFASTParserGo::CompleteTypeFromDWARF(const DWARFDIE &die, - lldb_private::Type *type, - CompilerType &compiler_type) { - if (!die) - return false; - - const dw_tag_t tag = die.Tag(); - - SymbolFileDWARF *dwarf = die.GetDWARF(); - Log *log = - nullptr; // (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION)); - if (log) - dwarf->GetObjectFile()->GetModule()->LogMessageVerboseBacktrace( - log, "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...", - die.GetID(), DW_TAG_value_to_name(tag), type->GetName().AsCString()); - assert(compiler_type); - DWARFAttributes attributes; - - switch (tag) { - case DW_TAG_structure_type: { - { - if (die.HasChildren()) { - SymbolContext sc(die.GetLLDBCompileUnit()); - - ParseChildMembers(sc, die, compiler_type); - } - } - m_ast.CompleteStructType(compiler_type); - return (bool)compiler_type; - } - - default: - assert(false && "not a forward go type decl!"); - break; - } - - return false; -} - -size_t DWARFASTParserGo::ParseChildMembers(const SymbolContext &sc, - const DWARFDIE &parent_die, - CompilerType &class_compiler_type) { - size_t count = 0; - uint32_t member_idx = 0; - - ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule(); - GoASTContext *ast = - llvm::dyn_cast_or_null<GoASTContext>(class_compiler_type.GetTypeSystem()); - if (ast == nullptr) - return 0; - - for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); - die = die.GetSibling()) { - dw_tag_t tag = die.Tag(); - - switch (tag) { - case DW_TAG_member: { - DWARFAttributes attributes; - const size_t num_attributes = die.GetAttributes(attributes); - if (num_attributes > 0) { - Declaration decl; - const char *name = NULL; - - DWARFFormValue encoding_uid; - uint32_t member_byte_offset = UINT32_MAX; - uint32_t i; - for (i = 0; i < num_attributes; ++i) { - const dw_attr_t attr = attributes.AttributeAtIndex(i); - DWARFFormValue form_value; - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attr) { - case DW_AT_name: - name = form_value.AsCString(); - break; - case DW_AT_type: - encoding_uid = form_value; - break; - case DW_AT_data_member_location: - if (form_value.BlockData()) { - Value initialValue(0); - Value memberOffset(0); - const DWARFDataExtractor &debug_info_data = die.GetData(); - uint32_t block_length = form_value.Unsigned(); - uint32_t block_offset = - form_value.BlockData() - debug_info_data.GetDataStart(); - if (DWARFExpression::Evaluate( - NULL, // ExecutionContext * - NULL, // RegisterContext * - module_sp, debug_info_data, die.GetCU(), block_offset, - block_length, eRegisterKindDWARF, &initialValue, NULL, - memberOffset, NULL)) { - member_byte_offset = memberOffset.ResolveValue(NULL).UInt(); - } - } else { - // With DWARF 3 and later, if the value is an integer constant, - // this form value is the offset in bytes from the beginning of - // the containing entity. - member_byte_offset = form_value.Unsigned(); - } - break; - - default: - break; - } - } - } - - Type *member_type = die.ResolveTypeUID(DIERef(encoding_uid)); - if (member_type) { - CompilerType member_go_type = member_type->GetFullCompilerType(); - ConstString name_const_str(name); - m_ast.AddFieldToStruct(class_compiler_type, name_const_str, - member_go_type, member_byte_offset); - } - } - ++member_idx; - } break; - - default: - break; - } - } - - return count; -} - -Function *DWARFASTParserGo::ParseFunctionFromDWARF(const SymbolContext &sc, - const DWARFDIE &die) { - DWARFRangeList func_ranges; - const char *name = NULL; - const char *mangled = NULL; - int decl_file = 0; - int decl_line = 0; - int decl_column = 0; - int call_file = 0; - int call_line = 0; - int call_column = 0; - DWARFExpression frame_base(die.GetCU()); - - assert(die.Tag() == DW_TAG_subprogram); - - if (die.Tag() != DW_TAG_subprogram) - return NULL; - - if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line, - decl_column, call_file, call_line, call_column, - &frame_base)) { - // Union of all ranges in the function DIE (if the function is - // discontiguous) - AddressRange func_range; - lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0); - lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0); - if (lowest_func_addr != LLDB_INVALID_ADDRESS && - lowest_func_addr <= highest_func_addr) { - ModuleSP module_sp(die.GetModule()); - func_range.GetBaseAddress().ResolveAddressUsingFileSections( - lowest_func_addr, module_sp->GetSectionList()); - if (func_range.GetBaseAddress().IsValid()) - func_range.SetByteSize(highest_func_addr - lowest_func_addr); - } - - if (func_range.GetBaseAddress().IsValid()) { - Mangled func_name; - func_name.SetValue(ConstString(name), false); - - FunctionSP func_sp; - std::unique_ptr<Declaration> decl_ap; - if (decl_file != 0 || decl_line != 0 || decl_column != 0) - decl_ap.reset(new Declaration( - sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), - decl_line, decl_column)); - - SymbolFileDWARF *dwarf = die.GetDWARF(); - // Supply the type _only_ if it has already been parsed - Type *func_type = dwarf->m_die_to_type.lookup(die.GetDIE()); - - assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED); - - if (dwarf->FixupAddress(func_range.GetBaseAddress())) { - const user_id_t func_user_id = die.GetID(); - func_sp.reset(new Function(sc.comp_unit, - func_user_id, // UserID is the DIE offset - func_user_id, func_name, func_type, - func_range)); // first address range - - if (func_sp.get() != NULL) { - if (frame_base.IsValid()) - func_sp->GetFrameBaseExpression() = frame_base; - sc.comp_unit->AddFunction(func_sp); - return func_sp.get(); - } - } - } - } - return NULL; -} diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h b/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h deleted file mode 100644 index 2a7c3871a309..000000000000 --- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h +++ /dev/null @@ -1,84 +0,0 @@ -//===-- DWARFASTParserGo.h --------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef SymbolFileDWARF_DWARFASTParserGo_h_ -#define SymbolFileDWARF_DWARFASTParserGo_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/SmallVector.h" - -// Project includes -#include "DWARFASTParser.h" -#include "DWARFDIE.h" -#include "DWARFDefines.h" -#include "lldb/Core/PluginInterface.h" -#include "lldb/Symbol/GoASTContext.h" - -class DWARFDebugInfoEntry; -class DWARFDIECollection; - -class DWARFASTParserGo : public DWARFASTParser { -public: - DWARFASTParserGo(lldb_private::GoASTContext &ast); - - ~DWARFASTParserGo() override; - - lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, - const DWARFDIE &die, lldb_private::Log *log, - bool *type_is_new_ptr) override; - - lldb_private::Function * - ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc, - const DWARFDIE &die) override; - - bool CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type, - lldb_private::CompilerType &go_type) override; - - lldb_private::CompilerDeclContext - GetDeclContextForUIDFromDWARF(const DWARFDIE &die) override { - return lldb_private::CompilerDeclContext(); - } - - lldb_private::CompilerDeclContext - GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) override { - return lldb_private::CompilerDeclContext(); - } - - lldb_private::CompilerDecl - GetDeclForUIDFromDWARF(const DWARFDIE &die) override { - return lldb_private::CompilerDecl(); - } - - std::vector<DWARFDIE> GetDIEForDeclContext( - lldb_private::CompilerDeclContext decl_context) override { - return std::vector<DWARFDIE>(); - } - -private: - size_t ParseChildParameters( - const lldb_private::SymbolContext &sc, const DWARFDIE &parent_die, - bool &is_variadic, - std::vector<lldb_private::CompilerType> &function_param_types); - void ParseChildArrayInfo(const lldb_private::SymbolContext &sc, - const DWARFDIE &parent_die, int64_t &first_index, - std::vector<uint64_t> &element_orders, - uint32_t &byte_stride, uint32_t &bit_stride); - - size_t ParseChildMembers(const lldb_private::SymbolContext &sc, - const DWARFDIE &die, - lldb_private::CompilerType &class_compiler_type); - - lldb_private::GoASTContext &m_ast; -}; - -#endif // SymbolFileDWARF_DWARFASTParserGo_h_ diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp deleted file mode 100644 index 476394487985..000000000000 --- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp +++ /dev/null @@ -1,510 +0,0 @@ -//===-- DWARFASTParserJava.cpp ----------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "DWARFASTParserJava.h" -#include "DWARFAttribute.h" -#include "DWARFUnit.h" -#include "DWARFDebugInfoEntry.h" -#include "DWARFDebugInfoEntry.h" -#include "DWARFDeclContext.h" -#include "SymbolFileDWARF.h" - -#include "lldb/Core/Module.h" -#include "lldb/Symbol/CompileUnit.h" -#include "lldb/Symbol/SymbolContextScope.h" -#include "lldb/Symbol/TypeList.h" - -using namespace lldb; -using namespace lldb_private; - -DWARFASTParserJava::DWARFASTParserJava(JavaASTContext &ast) : m_ast(ast) {} - -DWARFASTParserJava::~DWARFASTParserJava() {} - -TypeSP DWARFASTParserJava::ParseBaseTypeFromDIE(const DWARFDIE &die) { - SymbolFileDWARF *dwarf = die.GetDWARF(); - dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED; - - ConstString type_name; - uint64_t byte_size = 0; - - DWARFAttributes attributes; - const size_t num_attributes = die.GetAttributes(attributes); - for (uint32_t i = 0; i < num_attributes; ++i) { - DWARFFormValue form_value; - dw_attr_t attr = attributes.AttributeAtIndex(i); - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attr) { - case DW_AT_name: - type_name.SetCString(form_value.AsCString()); - break; - case DW_AT_byte_size: - byte_size = form_value.Unsigned(); - break; - case DW_AT_encoding: - break; - default: - assert(false && "Unsupported attribute for DW_TAG_base_type"); - } - } - } - - Declaration decl; - CompilerType compiler_type = m_ast.CreateBaseType(type_name); - return std::make_shared<Type>(die.GetID(), dwarf, type_name, byte_size, - nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, - decl, compiler_type, Type::eResolveStateFull); -} - -TypeSP DWARFASTParserJava::ParseArrayTypeFromDIE(const DWARFDIE &die) { - SymbolFileDWARF *dwarf = die.GetDWARF(); - dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED; - - ConstString linkage_name; - DWARFFormValue type_attr_value; - lldb::addr_t data_offset = LLDB_INVALID_ADDRESS; - DWARFExpression length_expression(die.GetCU()); - - DWARFAttributes attributes; - const size_t num_attributes = die.GetAttributes(attributes); - for (uint32_t i = 0; i < num_attributes; ++i) { - DWARFFormValue form_value; - dw_attr_t attr = attributes.AttributeAtIndex(i); - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attr) { - case DW_AT_linkage_name: - linkage_name.SetCString(form_value.AsCString()); - break; - case DW_AT_type: - type_attr_value = form_value; - break; - case DW_AT_data_member_location: - data_offset = form_value.Unsigned(); - break; - case DW_AT_declaration: - break; - default: - assert(false && "Unsupported attribute for DW_TAG_array_type"); - } - } - } - - for (DWARFDIE child_die = die.GetFirstChild(); child_die.IsValid(); - child_die = child_die.GetSibling()) { - if (child_die.Tag() == DW_TAG_subrange_type) { - DWARFAttributes attributes; - const size_t num_attributes = child_die.GetAttributes(attributes); - for (uint32_t i = 0; i < num_attributes; ++i) { - DWARFFormValue form_value; - dw_attr_t attr = attributes.AttributeAtIndex(i); - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attr) { - case DW_AT_count: - if (form_value.BlockData()) - length_expression.CopyOpcodeData( - form_value.BlockData(), form_value.Unsigned(), - child_die.GetCU()->GetByteOrder(), - child_die.GetCU()->GetAddressByteSize()); - break; - default: - assert(false && "Unsupported attribute for DW_TAG_subrange_type"); - } - } - } - } else { - assert(false && "Unsupported child for DW_TAG_array_type"); - } - } - - DIERef type_die_ref(type_attr_value); - Type *element_type = dwarf->ResolveTypeUID(type_die_ref); - if (!element_type) - return nullptr; - - CompilerType element_compiler_type = element_type->GetForwardCompilerType(); - CompilerType array_compiler_type = m_ast.CreateArrayType( - linkage_name, element_compiler_type, length_expression, data_offset); - - Declaration decl; - TypeSP type_sp(new Type(die.GetID(), dwarf, array_compiler_type.GetTypeName(), - -1, nullptr, type_die_ref.GetUID(dwarf), - Type::eEncodingIsUID, &decl, array_compiler_type, - Type::eResolveStateFull)); - type_sp->SetEncodingType(element_type); - return type_sp; -} - -TypeSP DWARFASTParserJava::ParseReferenceTypeFromDIE(const DWARFDIE &die) { - SymbolFileDWARF *dwarf = die.GetDWARF(); - dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED; - - Declaration decl; - DWARFFormValue type_attr_value; - - DWARFAttributes attributes; - const size_t num_attributes = die.GetAttributes(attributes); - for (uint32_t i = 0; i < num_attributes; ++i) { - DWARFFormValue form_value; - dw_attr_t attr = attributes.AttributeAtIndex(i); - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attr) { - case DW_AT_type: - type_attr_value = form_value; - break; - default: - assert(false && "Unsupported attribute for DW_TAG_array_type"); - } - } - } - - DIERef type_die_ref(type_attr_value); - Type *pointee_type = dwarf->ResolveTypeUID(type_die_ref); - if (!pointee_type) - return nullptr; - - CompilerType pointee_compiler_type = pointee_type->GetForwardCompilerType(); - CompilerType reference_compiler_type = - m_ast.CreateReferenceType(pointee_compiler_type); - TypeSP type_sp( - new Type(die.GetID(), dwarf, reference_compiler_type.GetTypeName(), -1, - nullptr, type_die_ref.GetUID(dwarf), Type::eEncodingIsUID, &decl, - reference_compiler_type, Type::eResolveStateFull)); - type_sp->SetEncodingType(pointee_type); - return type_sp; -} - -lldb::TypeSP DWARFASTParserJava::ParseClassTypeFromDIE(const DWARFDIE &die, - bool &is_new_type) { - SymbolFileDWARF *dwarf = die.GetDWARF(); - dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED; - - Declaration decl; - ConstString name; - ConstString linkage_name; - bool is_forward_declaration = false; - uint32_t byte_size = 0; - - DWARFAttributes attributes; - const size_t num_attributes = die.GetAttributes(attributes); - for (uint32_t i = 0; i < num_attributes; ++i) { - DWARFFormValue form_value; - dw_attr_t attr = attributes.AttributeAtIndex(i); - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attr) { - case DW_AT_name: - name.SetCString(form_value.AsCString()); - break; - case DW_AT_declaration: - is_forward_declaration = form_value.Boolean(); - break; - case DW_AT_byte_size: - byte_size = form_value.Unsigned(); - break; - case DW_AT_linkage_name: - linkage_name.SetCString(form_value.AsCString()); - break; - default: - assert(false && "Unsupported attribute for DW_TAG_class_type"); - } - } - } - - UniqueDWARFASTType unique_ast_entry; - if (name) { - std::string qualified_name; - if (die.GetQualifiedName(qualified_name)) { - name.SetCString(qualified_name.c_str()); - if (dwarf->GetUniqueDWARFASTTypeMap().Find(name, die, Declaration(), -1, - unique_ast_entry)) { - if (unique_ast_entry.m_type_sp) { - dwarf->GetDIEToType()[die.GetDIE()] = - unique_ast_entry.m_type_sp.get(); - is_new_type = false; - return unique_ast_entry.m_type_sp; - } - } - } - } - - if (is_forward_declaration) { - DWARFDeclContext die_decl_ctx; - die.GetDWARFDeclContext(die_decl_ctx); - - TypeSP type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx); - if (type_sp) { - // We found a real definition for this type elsewhere so lets use it - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); - is_new_type = false; - return type_sp; - } - } - - CompilerType compiler_type( - &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE())); - if (!compiler_type) - compiler_type = m_ast.CreateObjectType(name, linkage_name, byte_size); - - is_new_type = true; - TypeSP type_sp(new Type(die.GetID(), dwarf, name, - -1, // byte size isn't specified - nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, - &decl, compiler_type, Type::eResolveStateForward)); - - // Add our type to the unique type map - unique_ast_entry.m_type_sp = type_sp; - unique_ast_entry.m_die = die; - unique_ast_entry.m_declaration = decl; - unique_ast_entry.m_byte_size = -1; - dwarf->GetUniqueDWARFASTTypeMap().Insert(name, unique_ast_entry); - - if (!is_forward_declaration) { - // Leave this as a forward declaration until we need to know the details of - // the type - dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] = - compiler_type.GetOpaqueQualType(); - dwarf->GetForwardDeclClangTypeToDie()[compiler_type.GetOpaqueQualType()] = - die.GetDIERef(); - } - return type_sp; -} - -lldb::TypeSP DWARFASTParserJava::ParseTypeFromDWARF( - const lldb_private::SymbolContext &sc, const DWARFDIE &die, - lldb_private::Log *log, bool *type_is_new_ptr) { - if (type_is_new_ptr) - *type_is_new_ptr = false; - - if (!die) - return nullptr; - - SymbolFileDWARF *dwarf = die.GetDWARF(); - - Type *type_ptr = dwarf->m_die_to_type.lookup(die.GetDIE()); - if (type_ptr == DIE_IS_BEING_PARSED) - return nullptr; - if (type_ptr != nullptr) - return type_ptr->shared_from_this(); - - TypeSP type_sp; - if (type_is_new_ptr) - *type_is_new_ptr = true; - - switch (die.Tag()) { - case DW_TAG_base_type: { - type_sp = ParseBaseTypeFromDIE(die); - break; - } - case DW_TAG_array_type: { - type_sp = ParseArrayTypeFromDIE(die); - break; - } - case DW_TAG_class_type: { - bool is_new_type = false; - type_sp = ParseClassTypeFromDIE(die, is_new_type); - if (!is_new_type) - return type_sp; - break; - } - case DW_TAG_reference_type: { - type_sp = ParseReferenceTypeFromDIE(die); - break; - } - } - - if (!type_sp) - return nullptr; - - DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die); - dw_tag_t sc_parent_tag = sc_parent_die.Tag(); - - SymbolContextScope *symbol_context_scope = nullptr; - if (sc_parent_tag == DW_TAG_compile_unit || - sc_parent_tag == DW_TAG_partial_unit) { - symbol_context_scope = sc.comp_unit; - } else if (sc.function != nullptr && sc_parent_die) { - symbol_context_scope = - sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID()); - if (symbol_context_scope == nullptr) - symbol_context_scope = sc.function; - } - - if (symbol_context_scope != nullptr) - type_sp->SetSymbolContextScope(symbol_context_scope); - - dwarf->GetTypeList()->Insert(type_sp); - dwarf->m_die_to_type[die.GetDIE()] = type_sp.get(); - - return type_sp; -} - -lldb_private::Function *DWARFASTParserJava::ParseFunctionFromDWARF( - const lldb_private::SymbolContext &sc, const DWARFDIE &die) { - assert(die.Tag() == DW_TAG_subprogram); - - const char *name = nullptr; - const char *mangled = nullptr; - int decl_file = 0; - int decl_line = 0; - int decl_column = 0; - int call_file = 0; - int call_line = 0; - int call_column = 0; - DWARFRangeList func_ranges; - DWARFExpression frame_base(die.GetCU()); - - if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line, - decl_column, call_file, call_line, call_column, - &frame_base)) { - // Union of all ranges in the function DIE (if the function is - // discontiguous) - AddressRange func_range; - lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0); - lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0); - if (lowest_func_addr != LLDB_INVALID_ADDRESS && - lowest_func_addr <= highest_func_addr) { - ModuleSP module_sp(die.GetModule()); - func_range.GetBaseAddress().ResolveAddressUsingFileSections( - lowest_func_addr, module_sp->GetSectionList()); - if (func_range.GetBaseAddress().IsValid()) - func_range.SetByteSize(highest_func_addr - lowest_func_addr); - } - - if (func_range.GetBaseAddress().IsValid()) { - std::unique_ptr<Declaration> decl_ap; - if (decl_file != 0 || decl_line != 0 || decl_column != 0) - decl_ap.reset(new Declaration( - sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), - decl_line, decl_column)); - - if (die.GetDWARF()->FixupAddress(func_range.GetBaseAddress())) { - FunctionSP func_sp(new Function(sc.comp_unit, die.GetID(), die.GetID(), - Mangled(ConstString(name), false), - nullptr, // No function types in java - func_range)); - if (frame_base.IsValid()) - func_sp->GetFrameBaseExpression() = frame_base; - sc.comp_unit->AddFunction(func_sp); - - return func_sp.get(); - } - } - } - return nullptr; -} - -bool DWARFASTParserJava::CompleteTypeFromDWARF( - const DWARFDIE &die, lldb_private::Type *type, - lldb_private::CompilerType &java_type) { - switch (die.Tag()) { - case DW_TAG_class_type: { - if (die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 0) { - if (die.HasChildren()) - ParseChildMembers(die, java_type); - m_ast.CompleteObjectType(java_type); - return java_type.IsValid(); - } - } break; - default: - assert(false && "Not a forward java type declaration!"); - break; - } - return false; -} - -void DWARFASTParserJava::ParseChildMembers(const DWARFDIE &parent_die, - CompilerType &compiler_type) { - DWARFUnit *dwarf_cu = parent_die.GetCU(); - for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); - die = die.GetSibling()) { - switch (die.Tag()) { - case DW_TAG_member: { - const char *name = nullptr; - DWARFFormValue encoding_uid; - uint32_t member_byte_offset = UINT32_MAX; - DWARFExpression member_location_expression(dwarf_cu); - - DWARFAttributes attributes; - size_t num_attributes = die.GetAttributes(attributes); - for (size_t i = 0; i < num_attributes; ++i) { - DWARFFormValue form_value; - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attributes.AttributeAtIndex(i)) { - case DW_AT_name: - name = form_value.AsCString(); - break; - case DW_AT_type: - encoding_uid = form_value; - break; - case DW_AT_data_member_location: - if (form_value.BlockData()) - member_location_expression.CopyOpcodeData( - form_value.BlockData(), form_value.Unsigned(), - dwarf_cu->GetByteOrder(), dwarf_cu->GetAddressByteSize()); - else - member_byte_offset = form_value.Unsigned(); - break; - case DW_AT_artificial: - static_cast<void>(form_value.Boolean()); - break; - case DW_AT_accessibility: - // TODO: Handle when needed - break; - default: - assert(false && "Unhandled attribute for DW_TAG_member"); - break; - } - } - } - - if (strcmp(name, ".dynamic_type") == 0) - m_ast.SetDynamicTypeId(compiler_type, member_location_expression); - else { - if (Type *member_type = die.ResolveTypeUID(DIERef(encoding_uid))) - m_ast.AddMemberToObject(compiler_type, ConstString(name), - member_type->GetFullCompilerType(), - member_byte_offset); - } - break; - } - case DW_TAG_inheritance: { - DWARFFormValue encoding_uid; - uint32_t member_byte_offset = UINT32_MAX; - - DWARFAttributes attributes; - size_t num_attributes = die.GetAttributes(attributes); - for (size_t i = 0; i < num_attributes; ++i) { - DWARFFormValue form_value; - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attributes.AttributeAtIndex(i)) { - case DW_AT_type: - encoding_uid = form_value; - break; - case DW_AT_data_member_location: - member_byte_offset = form_value.Unsigned(); - break; - case DW_AT_accessibility: - // In java all base class is public so we can ignore this attribute - break; - default: - assert(false && "Unhandled attribute for DW_TAG_member"); - break; - } - } - } - if (Type *base_type = die.ResolveTypeUID(DIERef(encoding_uid))) - m_ast.AddBaseClassToObject(compiler_type, - base_type->GetFullCompilerType(), - member_byte_offset); - break; - } - default: - break; - } - } -} diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h b/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h deleted file mode 100644 index 01d81833d517..000000000000 --- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h +++ /dev/null @@ -1,81 +0,0 @@ -//===-- DWARFASTParserJava.h ------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef SymbolFileDWARF_DWARFASTParserJava_h_ -#define SymbolFileDWARF_DWARFASTParserJava_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/SmallVector.h" - -// Project includes -#include "DWARFASTParser.h" -#include "DWARFDIE.h" -#include "DWARFDefines.h" -#include "lldb/Core/PluginInterface.h" -#include "lldb/Symbol/JavaASTContext.h" - -class DWARFDebugInfoEntry; -class DWARFDIECollection; - -class DWARFASTParserJava : public DWARFASTParser { -public: - DWARFASTParserJava(lldb_private::JavaASTContext &ast); - ~DWARFASTParserJava() override; - - lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, - const DWARFDIE &die, lldb_private::Log *log, - bool *type_is_new_ptr) override; - - lldb_private::Function * - ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc, - const DWARFDIE &die) override; - - bool CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type, - lldb_private::CompilerType &java_type) override; - - lldb_private::CompilerDeclContext - GetDeclContextForUIDFromDWARF(const DWARFDIE &die) override { - return lldb_private::CompilerDeclContext(); - } - - lldb_private::CompilerDeclContext - GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) override { - return lldb_private::CompilerDeclContext(); - } - - lldb_private::CompilerDecl - GetDeclForUIDFromDWARF(const DWARFDIE &die) override { - return lldb_private::CompilerDecl(); - } - - std::vector<DWARFDIE> GetDIEForDeclContext( - lldb_private::CompilerDeclContext decl_context) override { - return std::vector<DWARFDIE>(); - } - - void ParseChildMembers(const DWARFDIE &parent_die, - lldb_private::CompilerType &class_compiler_type); - -private: - lldb_private::JavaASTContext &m_ast; - - lldb::TypeSP ParseBaseTypeFromDIE(const DWARFDIE &die); - - lldb::TypeSP ParseArrayTypeFromDIE(const DWARFDIE &die); - - lldb::TypeSP ParseReferenceTypeFromDIE(const DWARFDIE &die); - - lldb::TypeSP ParseClassTypeFromDIE(const DWARFDIE &die, bool &is_new_type); -}; - -#endif // SymbolFileDWARF_DWARFASTParserJava_h_ diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp deleted file mode 100644 index 3ef5c2eb8626..000000000000 --- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp +++ /dev/null @@ -1,210 +0,0 @@ -//===-- DWARFASTParserOCaml.cpp ---------------------------------*- C++ -*-===// - -#include "DWARFASTParserOCaml.h" - -#include "lldb/Core/Module.h" -#include "lldb/Symbol/CompileUnit.h" -#include "lldb/Symbol/Function.h" -#include "lldb/Symbol/ObjectFile.h" -#include "lldb/Symbol/Type.h" -#include "lldb/Symbol/TypeList.h" -#include "lldb/Utility/Log.h" -#include "lldb/Utility/Status.h" - -using namespace lldb; -using namespace lldb_private; - -DWARFASTParserOCaml::DWARFASTParserOCaml(OCamlASTContext &ast) : m_ast(ast) {} - -DWARFASTParserOCaml::~DWARFASTParserOCaml() {} - -TypeSP DWARFASTParserOCaml::ParseBaseTypeFromDIE(const DWARFDIE &die) { - SymbolFileDWARF *dwarf = die.GetDWARF(); - dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED; - - ConstString type_name; - uint64_t byte_size = 0; - - DWARFAttributes attributes; - const size_t num_attributes = die.GetAttributes(attributes); - for (uint32_t i = 0; i < num_attributes; ++i) { - DWARFFormValue form_value; - dw_attr_t attr = attributes.AttributeAtIndex(i); - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attr) { - case DW_AT_name: - type_name.SetCString(form_value.AsCString()); - break; - case DW_AT_byte_size: - byte_size = form_value.Unsigned(); - break; - case DW_AT_encoding: - break; - default: - assert(false && "Unsupported attribute for DW_TAG_base_type"); - } - } - } - - Declaration decl; - CompilerType compiler_type = m_ast.CreateBaseType(type_name, byte_size); - return std::make_shared<Type>(die.GetID(), dwarf, type_name, byte_size, - nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, - decl, compiler_type, Type::eResolveStateFull); -} - -lldb::TypeSP DWARFASTParserOCaml::ParseTypeFromDWARF(const SymbolContext &sc, - const DWARFDIE &die, - Log *log, - bool *type_is_new_ptr) { - if (type_is_new_ptr) - *type_is_new_ptr = false; - - if (!die) - return nullptr; - - SymbolFileDWARF *dwarf = die.GetDWARF(); - - Type *type_ptr = dwarf->m_die_to_type.lookup(die.GetDIE()); - if (type_ptr == DIE_IS_BEING_PARSED) - return nullptr; - if (type_ptr != nullptr) - return type_ptr->shared_from_this(); - - TypeSP type_sp; - if (type_is_new_ptr) - *type_is_new_ptr = true; - - switch (die.Tag()) { - case DW_TAG_base_type: { - type_sp = ParseBaseTypeFromDIE(die); - break; - } - case DW_TAG_array_type: { - break; - } - case DW_TAG_class_type: { - break; - } - case DW_TAG_reference_type: { - break; - } - } - - if (!type_sp) - return nullptr; - - DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die); - dw_tag_t sc_parent_tag = sc_parent_die.Tag(); - - SymbolContextScope *symbol_context_scope = nullptr; - if (sc_parent_tag == DW_TAG_compile_unit || - sc_parent_tag == DW_TAG_partial_unit) { - symbol_context_scope = sc.comp_unit; - } else if (sc.function != nullptr && sc_parent_die) { - symbol_context_scope = - sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID()); - if (symbol_context_scope == nullptr) - symbol_context_scope = sc.function; - } - - if (symbol_context_scope != nullptr) - type_sp->SetSymbolContextScope(symbol_context_scope); - - dwarf->GetTypeList()->Insert(type_sp); - dwarf->m_die_to_type[die.GetDIE()] = type_sp.get(); - - return type_sp; -} - -Function *DWARFASTParserOCaml::ParseFunctionFromDWARF(const SymbolContext &sc, - const DWARFDIE &die) { - DWARFRangeList func_ranges; - const char *name = NULL; - const char *mangled = NULL; - int decl_file = 0; - int decl_line = 0; - int decl_column = 0; - int call_file = 0; - int call_line = 0; - int call_column = 0; - DWARFExpression frame_base(die.GetCU()); - - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE)); - - if (die) { - SymbolFileDWARF *dwarf = die.GetDWARF(); - if (log) { - dwarf->GetObjectFile()->GetModule()->LogMessage( - log, "DWARFASTParserOCaml::ParseFunctionFromDWARF (die = 0x%8.8x) %s " - "name = '%s')", - die.GetOffset(), DW_TAG_value_to_name(die.Tag()), die.GetName()); - } - } - - assert(die.Tag() == DW_TAG_subprogram); - - if (die.Tag() != DW_TAG_subprogram) - return NULL; - - if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line, - decl_column, call_file, call_line, call_column, - &frame_base)) { - AddressRange func_range; - lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0); - lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0); - if (lowest_func_addr != LLDB_INVALID_ADDRESS && - lowest_func_addr <= highest_func_addr) { - ModuleSP module_sp(die.GetModule()); - func_range.GetBaseAddress().ResolveAddressUsingFileSections( - lowest_func_addr, module_sp->GetSectionList()); - if (func_range.GetBaseAddress().IsValid()) - func_range.SetByteSize(highest_func_addr - lowest_func_addr); - } - - if (func_range.GetBaseAddress().IsValid()) { - Mangled func_name; - - func_name.SetValue(ConstString(name), true); - - FunctionSP func_sp; - std::unique_ptr<Declaration> decl_ap; - if (decl_file != 0 || decl_line != 0 || decl_column != 0) - decl_ap.reset(new Declaration( - sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), - decl_line, decl_column)); - - SymbolFileDWARF *dwarf = die.GetDWARF(); - Type *func_type = dwarf->m_die_to_type.lookup(die.GetDIE()); - - assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED); - - if (dwarf->FixupAddress(func_range.GetBaseAddress())) { - const user_id_t func_user_id = die.GetID(); - func_sp.reset(new Function(sc.comp_unit, - func_user_id, // UserID is the DIE offset - func_user_id, func_name, func_type, - func_range)); // first address range - - if (func_sp.get() != NULL) { - if (frame_base.IsValid()) - func_sp->GetFrameBaseExpression() = frame_base; - sc.comp_unit->AddFunction(func_sp); - return func_sp.get(); - } - } - } - } - - return NULL; -} - -lldb_private::CompilerDeclContext -DWARFASTParserOCaml::GetDeclContextForUIDFromDWARF(const DWARFDIE &die) { - return CompilerDeclContext(); -} - -lldb_private::CompilerDeclContext -DWARFASTParserOCaml::GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) { - return CompilerDeclContext(); -} diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h b/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h deleted file mode 100644 index 09cb5e14934f..000000000000 --- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h +++ /dev/null @@ -1,59 +0,0 @@ -//===-- DWARFASTParserOCaml.h -----------------------------------*- C++ -*-===// - -#ifndef SymbolFileDWARF_DWARFASTParserOCaml_h_ -#define SymbolFileDWARF_DWARFASTParserOCaml_h_ - -#include "DWARFASTParser.h" -#include "DWARFDIE.h" -#include "DWARFDebugInfo.h" -#include "DWARFDefines.h" -#include "SymbolFileDWARF.h" - -#include "lldb/Symbol/OCamlASTContext.h" - -class DWARFDebugInfoEntry; -class DWARFDIECollection; - -class DWARFASTParserOCaml : public DWARFASTParser { -public: - DWARFASTParserOCaml(lldb_private::OCamlASTContext &ast); - - virtual ~DWARFASTParserOCaml(); - - lldb::TypeSP ParseBaseTypeFromDIE(const DWARFDIE &die); - - lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, - const DWARFDIE &die, lldb_private::Log *log, - bool *type_is_new_ptr) override; - - lldb_private::Function * - ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc, - const DWARFDIE &die) override; - - bool - CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type, - lldb_private::CompilerType &compiler_type) override { - return false; - } - - lldb_private::CompilerDecl - GetDeclForUIDFromDWARF(const DWARFDIE &die) override { - return lldb_private::CompilerDecl(); - } - - lldb_private::CompilerDeclContext - GetDeclContextForUIDFromDWARF(const DWARFDIE &die) override; - - lldb_private::CompilerDeclContext - GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) override; - - std::vector<DWARFDIE> GetDIEForDeclContext( - lldb_private::CompilerDeclContext decl_context) override { - return {}; - } - -protected: - lldb_private::OCamlASTContext &m_ast; -}; - -#endif // SymbolFileDWARF_DWARFASTParserOCaml_h_ diff --git a/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp b/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp index a765be0b46d0..d78b9ab10f5a 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp @@ -41,9 +41,13 @@ bool DWARFAbbreviationDeclaration::Extract(const DWARFDataExtractor &data, while (data.ValidOffset(*offset_ptr)) { dw_attr_t attr = data.GetULEB128(offset_ptr); dw_form_t form = data.GetULEB128(offset_ptr); + DWARFFormValue::ValueType val; + + if (form == DW_FORM_implicit_const) + val.value.sval = data.GetULEB128(offset_ptr); if (attr && form) - m_attributes.push_back(DWARFAttribute(attr, form)); + m_attributes.push_back(DWARFAttribute(attr, form, val)); else break; } diff --git a/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h b/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h index b2296c455d6a..afce52558f45 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h +++ b/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h @@ -35,20 +35,11 @@ public: dw_form_t GetFormByIndex(uint32_t idx) const { return m_attributes.size() > idx ? m_attributes[idx].get_form() : 0; } - bool GetAttrAndFormByIndex(uint32_t idx, dw_attr_t &attr, - dw_form_t &form) const { - if (m_attributes.size() > idx) { - m_attributes[idx].get(attr, form); - return true; - } - attr = form = 0; - return false; - } - // idx is assumed to be valid when calling GetAttrAndFormByIndexUnchecked() - void GetAttrAndFormByIndexUnchecked(uint32_t idx, dw_attr_t &attr, - dw_form_t &form) const { - m_attributes[idx].get(attr, form); + // idx is assumed to be valid when calling GetAttrAndFormByIndex() + void GetAttrAndFormValueByIndex(uint32_t idx, dw_attr_t &attr, + DWARFFormValue &form_value) const { + m_attributes[idx].get(attr, form_value.FormRef(), form_value.ValueRef()); } dw_form_t GetFormByIndexUnchecked(uint32_t idx) const { return m_attributes[idx].get_form(); diff --git a/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp b/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp index 2586d1f18530..dd830eb7b9dd 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp @@ -26,10 +26,10 @@ uint32_t DWARFAttributes::FindAttributeIndex(dw_attr_t attr) const { return UINT32_MAX; } -void DWARFAttributes::Append(const DWARFUnit *cu, - dw_offset_t attr_die_offset, dw_attr_t attr, - dw_form_t form) { - AttributeValue attr_value = {cu, attr_die_offset, {attr, form}}; +void DWARFAttributes::Append(const DWARFUnit *cu, dw_offset_t attr_die_offset, + dw_attr_t attr, dw_form_t form) { + AttributeValue attr_value = { + cu, attr_die_offset, {attr, form, DWARFFormValue::ValueType()}}; m_infos.push_back(attr_value); } diff --git a/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h b/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h index db4324cf7725..2399861d7fc3 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h +++ b/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h @@ -11,15 +11,17 @@ #define SymbolFileDWARF_DWARFAttribute_h_ #include "DWARFDefines.h" +#include "DWARFFormValue.h" #include "llvm/ADT/SmallVector.h" #include <vector> class DWARFUnit; -class DWARFFormValue; class DWARFAttribute { public: - DWARFAttribute(dw_attr_t attr, dw_form_t form) : m_attr(attr), m_form(form) {} + DWARFAttribute(dw_attr_t attr, dw_form_t form, + DWARFFormValue::ValueType value) + : m_attr(attr), m_form(form), m_value(value) {} void set(dw_attr_t attr, dw_form_t form) { m_attr = attr; @@ -29,9 +31,11 @@ public: void set_form(dw_form_t form) { m_form = form; } dw_attr_t get_attr() const { return m_attr; } dw_form_t get_form() const { return m_form; } - void get(dw_attr_t &attr, dw_form_t &form) const { + void get(dw_attr_t &attr, dw_form_t &form, + DWARFFormValue::ValueType &val) const { attr = m_attr; form = m_form; + val = m_value; } bool operator==(const DWARFAttribute &rhs) const { return m_attr == rhs.m_attr && m_form == rhs.m_form; @@ -43,6 +47,7 @@ public: protected: dw_attr_t m_attr; dw_form_t m_form; + DWARFFormValue::ValueType m_value; }; class DWARFAttributes { diff --git a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp index 8541f1cfe1f6..b9a7231286e3 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -34,8 +34,18 @@ DWARFUnitSP DWARFCompileUnit::Extract(SymbolFileDWARF *dwarf2Data, cu_sp->m_length = debug_info.GetDWARFInitialLength(offset_ptr); cu_sp->m_is_dwarf64 = debug_info.IsDWARF64(); cu_sp->m_version = debug_info.GetU16(offset_ptr); - abbr_offset = debug_info.GetDWARFOffset(offset_ptr); - cu_sp->m_addr_size = debug_info.GetU8(offset_ptr); + + if (cu_sp->m_version == 5) { + cu_sp->m_unit_type = debug_info.GetU8(offset_ptr); + cu_sp->m_addr_size = debug_info.GetU8(offset_ptr); + abbr_offset = debug_info.GetDWARFOffset(offset_ptr); + + if (cu_sp->m_unit_type == llvm::dwarf::DW_UT_skeleton) + cu_sp->m_dwo_id = debug_info.GetU64(offset_ptr); + } else { + abbr_offset = debug_info.GetDWARFOffset(offset_ptr); + cu_sp->m_addr_size = debug_info.GetU8(offset_ptr); + } bool length_OK = debug_info.ValidOffset(cu_sp->GetNextCompileUnitOffset() - 1); @@ -65,6 +75,23 @@ void DWARFCompileUnit::Dump(Stream *s) const { GetNextCompileUnitOffset()); } +uint32_t DWARFCompileUnit::GetHeaderByteSize() const { + if (m_version < 5) + return m_is_dwarf64 ? 23 : 11; + + switch (m_unit_type) { + case llvm::dwarf::DW_UT_compile: + case llvm::dwarf::DW_UT_partial: + return 12; + case llvm::dwarf::DW_UT_skeleton: + case llvm::dwarf::DW_UT_split_compile: + return 20; + case llvm::dwarf::DW_UT_type: + case llvm::dwarf::DW_UT_split_type: + return 24; + } + llvm_unreachable("invalid UnitType."); +} const lldb_private::DWARFDataExtractor &DWARFCompileUnit::GetData() const { return m_dwarf->get_debug_info_data(); diff --git a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h index d20f31505ed4..b92a155e0335 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h +++ b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h @@ -35,9 +35,7 @@ public: /// @return /// Byte size of the compile unit header //------------------------------------------------------------------ - uint32_t GetHeaderByteSize() const override { - return m_is_dwarf64 ? 23 : 11; - } + uint32_t GetHeaderByteSize() const override; private: DWARFCompileUnit(SymbolFileDWARF *dwarf2Data); diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp index d9754e911017..22b70b2d6852 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp @@ -166,13 +166,13 @@ void DWARFDIE::GetDWARFDeclContext(DWARFDeclContext &dwarf_decl_ctx) const { } } -void DWARFDIE::GetDWOContext(std::vector<CompilerContext> &context) const { +void DWARFDIE::GetDeclContext(std::vector<CompilerContext> &context) const { const dw_tag_t tag = Tag(); if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit) return; DWARFDIE parent = GetParent(); if (parent) - parent.GetDWOContext(context); + parent.GetDeclContext(context); switch (tag) { case DW_TAG_module: context.push_back( diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/source/Plugins/SymbolFile/DWARF/DWARFDIE.h index ecbf4912634e..b0d06a886ac1 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFDIE.h +++ b/source/Plugins/SymbolFile/DWARF/DWARFDIE.h @@ -90,7 +90,10 @@ public: void GetDWARFDeclContext(DWARFDeclContext &dwarf_decl_ctx) const; - void GetDWOContext(std::vector<lldb_private::CompilerContext> &context) const; + /// Return this DIE's decl context as it is needed to look up types + /// in Clang's -gmodules debug info format. + void + GetDeclContext(std::vector<lldb_private::CompilerContext> &context) const; //---------------------------------------------------------------------- // Getting attribute values from the DIE. diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h b/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h index ce0bfb3931d5..1f342035f135 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h +++ b/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h @@ -10,7 +10,6 @@ #ifndef liblldb_DWARFDataExtractor_h_ #define liblldb_DWARFDataExtractor_h_ -// Other libraries and framework includes. #include "lldb/Core/dwarf.h" #include "lldb/Utility/DataExtractor.h" diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h index 6524cb3ce483..e7a8635f0532 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h +++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h @@ -19,7 +19,7 @@ class SymbolFileDWARF; class DWARFDebugAranges { protected: - typedef lldb_private::RangeDataArray<dw_addr_t, uint32_t, dw_offset_t, 1> + typedef lldb_private::RangeDataVector<dw_addr_t, uint32_t, dw_offset_t> RangeToDIE; public: diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp index d32aef6e162c..7531aeac709a 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -40,9 +40,8 @@ bool DWARFDebugInfoEntry::FastExtract( m_offset = *offset_ptr; m_parent_idx = 0; m_sibling_idx = 0; - m_empty_children = false; const uint64_t abbr_idx = debug_info_data.GetULEB128(offset_ptr); - assert(abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE)); + lldbassert(abbr_idx <= UINT16_MAX); m_abbr_idx = abbr_idx; // assert (fixed_form_sizes); // For best performance this should be @@ -119,21 +118,33 @@ bool DWARFDebugInfoEntry::FastExtract( break; // 1 byte values + case DW_FORM_addrx1: case DW_FORM_data1: case DW_FORM_flag: case DW_FORM_ref1: + case DW_FORM_strx1: form_size = 1; break; // 2 byte values + case DW_FORM_addrx2: case DW_FORM_data2: case DW_FORM_ref2: + case DW_FORM_strx2: form_size = 2; break; + // 3 byte values + case DW_FORM_addrx3: + case DW_FORM_strx3: + form_size = 3; + break; + // 4 byte values + case DW_FORM_addrx4: case DW_FORM_data4: case DW_FORM_ref4: + case DW_FORM_strx4: form_size = 4; break; @@ -145,11 +156,14 @@ bool DWARFDebugInfoEntry::FastExtract( break; // signed or unsigned LEB 128 values + case DW_FORM_addrx: + case DW_FORM_rnglistx: case DW_FORM_sdata: case DW_FORM_udata: case DW_FORM_ref_udata: case DW_FORM_GNU_addr_index: case DW_FORM_GNU_str_index: + case DW_FORM_strx: debug_info_data.Skip_LEB128(&offset); break; @@ -166,6 +180,10 @@ bool DWARFDebugInfoEntry::FastExtract( debug_info_data.GetU32(&offset); break; + case DW_FORM_implicit_const: + form_size = 0; + break; + default: *offset_ptr = m_offset; return false; @@ -208,7 +226,7 @@ bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data, m_offset = offset; const uint64_t abbr_idx = debug_info_data.GetULEB128(&offset); - assert(abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE)); + lldbassert(abbr_idx <= UINT16_MAX); m_abbr_idx = abbr_idx; if (abbr_idx) { const DWARFAbbreviationDeclaration *abbrevDecl = @@ -225,15 +243,14 @@ bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data, // Skip all data in the .debug_info for the attributes const uint32_t numAttributes = abbrevDecl->NumAttributes(); - uint32_t i; - dw_attr_t attr; - dw_form_t form; - for (i = 0; i < numAttributes; ++i) { - abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form); + for (uint32_t i = 0; i < numAttributes; ++i) { + DWARFFormValue form_value(cu); + dw_attr_t attr; + abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value); + dw_form_t form = form_value.Form(); if (isCompileUnitTag && ((attr == DW_AT_entry_pc) || (attr == DW_AT_low_pc))) { - DWARFFormValue form_value(cu, form); if (form_value.ExtractValue(debug_info_data, &offset)) { if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc) const_cast<DWARFUnit *>(cu)->SetBaseAddress( @@ -279,6 +296,7 @@ bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data, // 0 sized form case DW_FORM_flag_present: + case DW_FORM_implicit_const: form_size = 0; break; @@ -370,6 +388,13 @@ void DWARFDebugInfoEntry::DumpAncestry(SymbolFileDWARF *dwarf2Data, Dump(dwarf2Data, cu, s, recurse_depth); } +static dw_offset_t GetRangesOffset(const DWARFDebugRangesBase *debug_ranges, + DWARFFormValue &form_value) { + if (form_value.Form() == DW_FORM_rnglistx) + return debug_ranges->GetOffset(form_value.Unsigned()); + return form_value.Unsigned(); +} + //---------------------------------------------------------------------- // GetDIENamesAndRanges // @@ -409,14 +434,13 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges( return false; const uint32_t numAttributes = abbrevDecl->NumAttributes(); - uint32_t i; - dw_attr_t attr; - dw_form_t form; bool do_offset = false; - for (i = 0; i < numAttributes; ++i) { - abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form); - DWARFFormValue form_value(cu, form); + for (uint32_t i = 0; i < numAttributes; ++i) { + DWARFFormValue form_value(cu); + dw_attr_t attr; + abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value); + if (form_value.ExtractValue(debug_info_data, &offset)) { switch (attr) { case DW_AT_low_pc: @@ -446,20 +470,15 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges( break; case DW_AT_ranges: { - const DWARFDebugRanges *debug_ranges = dwarf2Data->DebugRanges(); - if (debug_ranges) { - debug_ranges->FindRanges(cu->GetRangesBase(), form_value.Unsigned(), ranges); - // All DW_AT_ranges are relative to the base address of the compile - // unit. We add the compile unit base address to make sure all the - // addresses are properly fixed up. - ranges.Slide(cu->GetBaseAddress()); - } else { + const DWARFDebugRangesBase *debug_ranges = dwarf2Data->DebugRanges(); + if (debug_ranges) + debug_ranges->FindRanges(cu, GetRangesOffset(debug_ranges, form_value), ranges); + else cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError( "{0x%8.8x}: DIE has DW_AT_ranges(0x%" PRIx64 ") attribute yet DWARF has no .debug_ranges, please file a bug " "and attach the file at the start of this error message", m_offset, form_value.Unsigned()); - } } break; case DW_AT_name: @@ -521,7 +540,7 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges( block_length); } else { const DWARFDataExtractor &debug_loc_data = - dwarf2Data->get_debug_loc_data(); + dwarf2Data->DebugLocData(); const dw_offset_t debug_loc_offset = form_value.Unsigned(); size_t loc_list_length = DWARFExpression::LocationListSize( @@ -606,14 +625,13 @@ void DWARFDebugInfoEntry::Dump(SymbolFileDWARF *dwarf2Data, // Dump all data in the .debug_info for the attributes const uint32_t numAttributes = abbrevDecl->NumAttributes(); - uint32_t i; - dw_attr_t attr; - dw_form_t form; - for (i = 0; i < numAttributes; ++i) { - abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form); + for (uint32_t i = 0; i < numAttributes; ++i) { + DWARFFormValue form_value(cu); + dw_attr_t attr; + abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value); DumpAttribute(dwarf2Data, cu, debug_info_data, &offset, s, attr, - form); + form_value); } const DWARFDebugInfoEntry *child = GetFirstChild(); @@ -663,23 +681,21 @@ void DWARFDebugInfoEntry::DumpLocation(SymbolFileDWARF *dwarf2Data, void DWARFDebugInfoEntry::DumpAttribute( SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, const DWARFDataExtractor &debug_info_data, lldb::offset_t *offset_ptr, - Stream &s, dw_attr_t attr, dw_form_t form) { + Stream &s, dw_attr_t attr, DWARFFormValue &form_value) { bool show_form = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm); s.Printf(" "); s.Indent(DW_AT_value_to_name(attr)); if (show_form) { - s.Printf("[%s", DW_FORM_value_to_name(form)); + s.Printf("[%s", DW_FORM_value_to_name(form_value.Form())); } - DWARFFormValue form_value(cu, form); - if (!form_value.ExtractValue(debug_info_data, offset_ptr)) return; if (show_form) { - if (form == DW_FORM_indirect) { + if (form_value.Form() == DW_FORM_indirect) { s.Printf(" [%s]", DW_FORM_value_to_name(form_value.Form())); } @@ -719,7 +735,7 @@ void DWARFDebugInfoEntry::DumpAttribute( uint64_t debug_loc_offset = form_value.Unsigned(); if (dwarf2Data) { DWARFExpression::PrintDWARFLocationList( - s, cu, dwarf2Data->get_debug_loc_data(), debug_loc_offset); + s, cu, dwarf2Data->DebugLocData(), debug_loc_offset); } } } break; @@ -740,11 +756,13 @@ void DWARFDebugInfoEntry::DumpAttribute( } break; case DW_AT_ranges: { - lldb::offset_t ranges_offset = form_value.Unsigned(); + if (!dwarf2Data) + break; + lldb::offset_t ranges_offset = + GetRangesOffset(dwarf2Data->DebugRanges(), form_value); dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0; - if (dwarf2Data) - DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(), - &ranges_offset, base_addr); + DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(), + &ranges_offset, base_addr); } break; default: @@ -786,11 +804,11 @@ size_t DWARFDebugInfoEntry::GetAttributes( cu->GetAddressByteSize(), cu->IsDWARF64()); const uint32_t num_attributes = abbrevDecl->NumAttributes(); - uint32_t i; - dw_attr_t attr; - dw_form_t form; - for (i = 0; i < num_attributes; ++i) { - abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form); + for (uint32_t i = 0; i < num_attributes; ++i) { + DWARFFormValue form_value(cu); + dw_attr_t attr; + abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value); + const dw_form_t form = form_value.Form(); // If we are tracking down DW_AT_specification or DW_AT_abstract_origin // attributes, the depth will be non-zero. We need to omit certain @@ -811,7 +829,6 @@ size_t DWARFDebugInfoEntry::GetAttributes( } if ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin)) { - DWARFFormValue form_value(cu, form); if (form_value.ExtractValue(debug_info_data, &offset)) { dw_offset_t die_offset = form_value.Reference(); DWARFDIE spec_die = @@ -1055,14 +1072,11 @@ size_t DWARFDebugInfoEntry::GetAttributeAddressRanges( bool check_specification_or_abstract_origin) const { ranges.Clear(); - dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned( - dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET, - check_specification_or_abstract_origin); - if (debug_ranges_offset != DW_INVALID_OFFSET) { - DWARFDebugRanges *debug_ranges = dwarf2Data->DebugRanges(); - - debug_ranges->FindRanges(cu->GetRangesBase(), debug_ranges_offset, ranges); - ranges.Slide(cu->GetBaseAddress()); + DWARFFormValue form_value; + if (GetAttributeValue(dwarf2Data, cu, DW_AT_ranges, form_value)) { + if (DWARFDebugRangesBase *debug_ranges = dwarf2Data->DebugRanges()) + debug_ranges->FindRanges(cu, GetRangesOffset(debug_ranges, form_value), + ranges); } else if (check_hi_lo_pc) { dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; @@ -1713,16 +1727,13 @@ bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address, ((function_die != NULL) || (block_die != NULL)); } } else { - dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned( - dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET); - if (debug_ranges_offset != DW_INVALID_OFFSET) { + DWARFFormValue form_value; + if (GetAttributeValue(dwarf2Data, cu, DW_AT_ranges, form_value)) { DWARFRangeList ranges; - DWARFDebugRanges *debug_ranges = dwarf2Data->DebugRanges(); - debug_ranges->FindRanges(cu->GetRangesBase(), debug_ranges_offset, ranges); - // All DW_AT_ranges are relative to the base address of the compile - // unit. We add the compile unit base address to make sure all the - // addresses are properly fixed up. - ranges.Slide(cu->GetBaseAddress()); + DWARFDebugRangesBase *debug_ranges = dwarf2Data->DebugRanges(); + debug_ranges->FindRanges( + cu, GetRangesOffset(debug_ranges, form_value), ranges); + if (ranges.FindEntryThatContains(address)) { found_address = true; // puts("***MATCH***"); @@ -1829,7 +1840,6 @@ void DWARFDebugInfoEntry::DumpDIECollection( bool DWARFDebugInfoEntry::operator==(const DWARFDebugInfoEntry &rhs) const { return m_offset == rhs.m_offset && m_parent_idx == rhs.m_parent_idx && m_sibling_idx == rhs.m_sibling_idx && - m_empty_children == rhs.m_empty_children && m_abbr_idx == rhs.m_abbr_idx && m_has_children == rhs.m_has_children && m_tag == rhs.m_tag; } diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h index 97cb3046eb3e..ec19fc814fba 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h +++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h @@ -43,7 +43,6 @@ typedef UInt32ToDIEMMap::const_iterator UInt32ToDIEMMapConstIter; class DWARFDeclContext; #define DIE_SIBLING_IDX_BITSIZE 31 -#define DIE_ABBR_IDX_BITSIZE 15 class DWARFDebugInfoEntry { public: @@ -57,8 +56,7 @@ public: DWARFDebugInfoEntry() : m_offset(DW_INVALID_OFFSET), m_parent_idx(0), m_sibling_idx(0), - m_empty_children(false), m_abbr_idx(0), m_has_children(false), - m_tag(0) {} + m_has_children(false), m_abbr_idx(0), m_tag(0) {} explicit operator bool() const { return m_offset != DW_INVALID_OFFSET; } bool operator==(const DWARFDebugInfoEntry &rhs) const; @@ -178,7 +176,7 @@ public: DumpAttribute(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, const lldb_private::DWARFDataExtractor &debug_info_data, lldb::offset_t *offset_ptr, lldb_private::Stream &s, - dw_attr_t attr, dw_form_t form); + dw_attr_t attr, DWARFFormValue &form_value); // This one dumps the comp unit name, objfile name and die offset for this die // so the stream S. void DumpLocation(SymbolFileDWARF *dwarf2Data, DWARFUnit *cu, @@ -227,10 +225,10 @@ public: // we don't need to store our child pointer, if we have a child it will // be the next entry in the list... DWARFDebugInfoEntry *GetFirstChild() { - return (HasChildren() && !m_empty_children) ? this + 1 : NULL; + return HasChildren() ? this + 1 : NULL; } const DWARFDebugInfoEntry *GetFirstChild() const { - return (HasChildren() && !m_empty_children) ? this + 1 : NULL; + return HasChildren() ? this + 1 : NULL; } void GetDeclContextDIEs(DWARFUnit *cu, @@ -271,10 +269,6 @@ public: void SetParentIndex(uint32_t idx) { m_parent_idx = idx; } - bool GetEmptyChildren() const { return m_empty_children; } - - void SetEmptyChildren(bool b) { m_empty_children = b; } - static void DumpDIECollection(lldb_private::Stream &strm, DWARFDebugInfoEntry::collection &die_collection); @@ -285,13 +279,13 @@ protected: uint32_t m_parent_idx; // How many to subtract from "this" to get the parent. // If zero this die has no parent uint32_t m_sibling_idx : 31, // How many to add to "this" to get the sibling. - m_empty_children : 1; // If a DIE says it had children, yet it just - // contained a NULL tag, this will be set. - uint32_t m_abbr_idx : DIE_ABBR_IDX_BITSIZE, - m_has_children : 1, // Set to 1 if this DIE has children - m_tag : 16; // A copy of the DW_TAG value so we don't - // have to go through the compile unit - // abbrev table + // If it is zero, then the DIE doesn't have children, or the + // DWARF claimed it had children but the DIE only contained + // a single NULL terminating child. + m_has_children : 1; + uint16_t m_abbr_idx; + uint16_t m_tag; // A copy of the DW_TAG value so we don't have to go through + // the compile unit abbrev table }; #endif // SymbolFileDWARF_DWARFDebugInfoEntry_h_ diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp index 317ea4c22c66..d9f50122bd6f 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp @@ -41,7 +41,7 @@ void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data) { if (line_table_sp.get() == NULL) break; - if (ParseStatementTable(debug_line_data, &offset, line_table_sp.get())) { + if (ParseStatementTable(debug_line_data, &offset, line_table_sp.get(), nullptr)) { // Make sure we don't don't loop infinitely if (offset <= debug_line_offset) break; @@ -127,7 +127,7 @@ DWARFDebugLine::DumpStatementTable(Log *log, "--------\n", debug_line_offset); - if (ParseStatementTable(debug_line_data, &offset, DumpStateToFile, log)) + if (ParseStatementTable(debug_line_data, &offset, DumpStateToFile, log, nullptr)) return offset; else return debug_line_offset + 1; // Skip to next byte in .debug_line section @@ -366,17 +366,38 @@ void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data, void *userData) { lldb::offset_t offset = 0; if (debug_line_data.ValidOffset(offset)) { - if (!ParseStatementTable(debug_line_data, &offset, callback, userData)) + if (!ParseStatementTable(debug_line_data, &offset, callback, userData, nullptr)) ++offset; // Skip to next byte in .debug_line section } } +namespace { +struct EntryDescriptor { + dw_sleb128_t code; + dw_sleb128_t form; +}; + +static std::vector<EntryDescriptor> +ReadDescriptors(const DWARFDataExtractor &debug_line_data, + lldb::offset_t *offset_ptr) { + std::vector<EntryDescriptor> ret; + uint8_t n = debug_line_data.GetU8(offset_ptr); + for (uint8_t i = 0; i < n; ++i) { + EntryDescriptor ent; + ent.code = debug_line_data.GetULEB128(offset_ptr); + ent.form = debug_line_data.GetULEB128(offset_ptr); + ret.push_back(ent); + } + return ret; +} +} // namespace + //---------------------------------------------------------------------- // DWARFDebugLine::ParsePrologue //---------------------------------------------------------------------- bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr, - Prologue *prologue) { + Prologue *prologue, DWARFUnit *dwarf_cu) { const lldb::offset_t prologue_offset = *offset_ptr; // DEBUG_PRINTF("0x%8.8x: ParsePrologue()\n", *offset_ptr); @@ -386,9 +407,14 @@ bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data, const char *s; prologue->total_length = debug_line_data.GetDWARFInitialLength(offset_ptr); prologue->version = debug_line_data.GetU16(offset_ptr); - if (prologue->version < 2 || prologue->version > 4) + if (prologue->version < 2 || prologue->version > 5) return false; + if (prologue->version >= 5) { + prologue->address_size = debug_line_data.GetU8(offset_ptr); + prologue->segment_selector_size = debug_line_data.GetU8(offset_ptr); + } + prologue->prologue_length = debug_line_data.GetDWARFOffset(offset_ptr); const lldb::offset_t end_prologue_offset = prologue->prologue_length + *offset_ptr; @@ -410,25 +436,83 @@ bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data, prologue->standard_opcode_lengths.push_back(op_len); } - while (*offset_ptr < end_prologue_offset) { - s = debug_line_data.GetCStr(offset_ptr); - if (s && s[0]) - prologue->include_directories.push_back(s); - else - break; - } + if (prologue->version >= 5) { + std::vector<EntryDescriptor> dirEntryFormatV = + ReadDescriptors(debug_line_data, offset_ptr); + uint8_t dirCount = debug_line_data.GetULEB128(offset_ptr); + for (int i = 0; i < dirCount; ++i) { + for (EntryDescriptor &ent : dirEntryFormatV) { + DWARFFormValue value(dwarf_cu, ent.form); + if (ent.code != DW_LNCT_path) { + if (!value.SkipValue(debug_line_data, offset_ptr)) + return false; + continue; + } - while (*offset_ptr < end_prologue_offset) { - const char *name = debug_line_data.GetCStr(offset_ptr); - if (name && name[0]) { - FileNameEntry fileEntry; - fileEntry.name = name; - fileEntry.dir_idx = debug_line_data.GetULEB128(offset_ptr); - fileEntry.mod_time = debug_line_data.GetULEB128(offset_ptr); - fileEntry.length = debug_line_data.GetULEB128(offset_ptr); - prologue->file_names.push_back(fileEntry); - } else - break; + if (!value.ExtractValue(debug_line_data, offset_ptr)) + return false; + prologue->include_directories.push_back(value.AsCString()); + } + } + + std::vector<EntryDescriptor> filesEntryFormatV = + ReadDescriptors(debug_line_data, offset_ptr); + llvm::DenseSet<std::pair<uint64_t, uint64_t>> seen; + uint8_t n = debug_line_data.GetULEB128(offset_ptr); + for (int i = 0; i < n; ++i) { + FileNameEntry entry; + for (EntryDescriptor &ent : filesEntryFormatV) { + DWARFFormValue value(dwarf_cu, ent.form); + if (!value.ExtractValue(debug_line_data, offset_ptr)) + return false; + + switch (ent.code) { + case DW_LNCT_path: + entry.name = value.AsCString(); + break; + case DW_LNCT_directory_index: + entry.dir_idx = value.Unsigned(); + break; + case DW_LNCT_timestamp: + entry.mod_time = value.Unsigned(); + break; + case DW_LNCT_size: + entry.length = value.Unsigned(); + break; + case DW_LNCT_MD5: + assert(value.Unsigned() == 16); + std::uninitialized_copy_n(value.BlockData(), 16, + entry.checksum.Bytes.begin()); + break; + default: + break; + } + } + + if (seen.insert(entry.checksum.words()).second) + prologue->file_names.push_back(entry); + } + } else { + while (*offset_ptr < end_prologue_offset) { + s = debug_line_data.GetCStr(offset_ptr); + if (s && s[0]) + prologue->include_directories.push_back(s); + else + break; + } + + while (*offset_ptr < end_prologue_offset) { + const char *name = debug_line_data.GetCStr(offset_ptr); + if (name && name[0]) { + FileNameEntry fileEntry; + fileEntry.name = name; + fileEntry.dir_idx = debug_line_data.GetULEB128(offset_ptr); + fileEntry.mod_time = debug_line_data.GetULEB128(offset_ptr); + fileEntry.length = debug_line_data.GetULEB128(offset_ptr); + prologue->file_names.push_back(fileEntry); + } else + break; + } } // XXX GNU as is broken for 64-Bit DWARF @@ -445,11 +529,11 @@ bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data, bool DWARFDebugLine::ParseSupportFiles( const lldb::ModuleSP &module_sp, const DWARFDataExtractor &debug_line_data, const lldb_private::FileSpec &cu_comp_dir, dw_offset_t stmt_list, - FileSpecList &support_files) { + FileSpecList &support_files, DWARFUnit *dwarf_cu) { lldb::offset_t offset = stmt_list; Prologue prologue; - if (!ParsePrologue(debug_line_data, &offset, &prologue)) { + if (!ParsePrologue(debug_line_data, &offset, &prologue, dwarf_cu)) { Host::SystemLog(Host::eSystemLogError, "error: parsing line table prologue " "at 0x%8.8x (parsing ended around " "0x%8.8" PRIx64 "\n", @@ -463,7 +547,7 @@ bool DWARFDebugLine::ParseSupportFiles( for (uint32_t file_idx = 1; prologue.GetFile(file_idx, cu_comp_dir, file_spec); ++file_idx) { if (module_sp->RemapSourceFile(file_spec.GetPath(), remapped_file)) - file_spec.SetFile(remapped_file, false, FileSpec::Style::native); + file_spec.SetFile(remapped_file, FileSpec::Style::native); support_files.Append(file_spec); } return true; @@ -478,7 +562,7 @@ bool DWARFDebugLine::ParseSupportFiles( //---------------------------------------------------------------------- bool DWARFDebugLine::ParseStatementTable( const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr, - DWARFDebugLine::State::Callback callback, void *userData) { + DWARFDebugLine::State::Callback callback, void *userData, DWARFUnit *dwarf_cu) { Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_LINE)); Prologue::shared_ptr prologue(new Prologue()); @@ -489,7 +573,7 @@ bool DWARFDebugLine::ParseStatementTable( func_cat, "DWARFDebugLine::ParseStatementTable (.debug_line[0x%8.8x])", debug_line_offset); - if (!ParsePrologue(debug_line_data, offset_ptr, prologue.get())) { + if (!ParsePrologue(debug_line_data, offset_ptr, prologue.get(), dwarf_cu)) { if (log) log->Error("failed to parse DWARF line table prologue"); // Restore our offset and return false to indicate failure! @@ -775,9 +859,9 @@ static void ParseStatementTableCallback(dw_offset_t offset, //---------------------------------------------------------------------- bool DWARFDebugLine::ParseStatementTable( const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr, - LineTable *line_table) { + LineTable *line_table, DWARFUnit *dwarf_cu) { return ParseStatementTable(debug_line_data, offset_ptr, - ParseStatementTableCallback, line_table); + ParseStatementTableCallback, line_table, dwarf_cu); } inline bool DWARFDebugLine::Prologue::IsValid() const { @@ -866,7 +950,7 @@ bool DWARFDebugLine::Prologue::GetFile(uint32_t file_idx, const lldb_private::FileSpec &comp_dir, FileSpec &file) const { uint32_t idx = file_idx - 1; // File indexes are 1 based... if (idx < file_names.size()) { - file.SetFile(file_names[idx].name, false, FileSpec::Style::native); + file.SetFile(file_names[idx].name, FileSpec::Style::native); if (file.IsRelative()) { if (file_names[idx].dir_idx > 0) { const uint32_t dir_idx = file_names[idx].dir_idx - 1; diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h index 3ab15ac59028..04f72e03a2db 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h +++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h @@ -19,6 +19,9 @@ #include "DWARFDataExtractor.h" #include "DWARFDefines.h" +#include "llvm/Support/MD5.h" + +class DWARFUnit; class SymbolFileDWARF; //---------------------------------------------------------------------- @@ -36,6 +39,7 @@ public: dw_sleb128_t dir_idx; dw_sleb128_t mod_time; dw_sleb128_t length; + llvm::MD5::MD5Result checksum; }; //------------------------------------------------------------------ @@ -55,6 +59,10 @@ public: // total_length field itself). uint16_t version; // Version identifier for the statement information format. + + uint8_t address_size; + uint8_t segment_selector_size; + uint32_t prologue_length; // The number of bytes following the // prologue_length field to the beginning of the // first byte of the statement program itself. @@ -201,14 +209,15 @@ public: const lldb_private::DWARFDataExtractor &debug_line_data, const lldb_private::FileSpec &cu_comp_dir, dw_offset_t stmt_list, - lldb_private::FileSpecList &support_files); + lldb_private::FileSpecList &support_files, DWARFUnit *dwarf_cu); static bool ParsePrologue(const lldb_private::DWARFDataExtractor &debug_line_data, - lldb::offset_t *offset_ptr, Prologue *prologue); + lldb::offset_t *offset_ptr, Prologue *prologue, + DWARFUnit *dwarf_cu = nullptr); static bool ParseStatementTable(const lldb_private::DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr, State::Callback callback, - void *userData); + void *userData, DWARFUnit *dwarf_cu); static dw_offset_t DumpStatementTable(lldb_private::Log *log, const lldb_private::DWARFDataExtractor &debug_line_data, @@ -219,7 +228,8 @@ public: const dw_offset_t line_offset, uint32_t flags); static bool ParseStatementTable(const lldb_private::DWARFDataExtractor &debug_line_data, - lldb::offset_t *offset_ptr, LineTable *line_table); + lldb::offset_t *offset_ptr, LineTable *line_table, + DWARFUnit *dwarf_cu); static void Parse(const lldb_private::DWARFDataExtractor &debug_line_data, DWARFDebugLine::State::Callback callback, void *userData); // static void AppendLineTableData(const DWARFDebugLine::Prologue* prologue, diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp index 1c31d1c42598..d79acdc5cfc4 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp @@ -25,7 +25,7 @@ DWARFDebugMacroHeader::ParseHeader(const DWARFDataExtractor &debug_macro_data, header.m_version = debug_macro_data.GetU16(offset); uint8_t flags = debug_macro_data.GetU8(offset); - header.m_offset_is_64_bit = flags & OFFSET_SIZE_MASK ? true : false; + header.m_offset_is_64_bit = (flags & OFFSET_SIZE_MASK) != 0; if (flags & DEBUG_LINE_OFFSET_MASK) { if (header.m_offset_is_64_bit) diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp index 89e27efb3cc2..a0436dd7ffad 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "DWARFDebugRanges.h" +#include "DWARFUnit.h" #include "SymbolFileDWARF.h" #include "lldb/Utility/Stream.h" #include <assert.h> @@ -29,8 +30,6 @@ static dw_addr_t GetBaseAddressMarker(uint32_t addr_size) { DWARFDebugRanges::DWARFDebugRanges() : m_range_map() {} -DWARFDebugRanges::~DWARFDebugRanges() {} - void DWARFDebugRanges::Extract(SymbolFileDWARF *dwarf2Data) { DWARFRangeList range_list; lldb::offset_t offset = 0; @@ -112,14 +111,185 @@ void DWARFDebugRanges::Dump(Stream &s, } } -bool DWARFDebugRanges::FindRanges(dw_addr_t debug_ranges_base, +bool DWARFDebugRanges::FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset, DWARFRangeList &range_list) const { - dw_addr_t debug_ranges_address = debug_ranges_base + debug_ranges_offset; + dw_addr_t debug_ranges_address = cu->GetRangesBase() + debug_ranges_offset; range_map_const_iterator pos = m_range_map.find(debug_ranges_address); if (pos != m_range_map.end()) { range_list = pos->second; + + // All DW_AT_ranges are relative to the base address of the compile + // unit. We add the compile unit base address to make sure all the + // addresses are properly fixed up. + range_list.Slide(cu->GetBaseAddress()); + return true; + } + return false; +} + +uint64_t DWARFDebugRanges::GetOffset(size_t Index) const { + lldbassert(false && "DW_FORM_rnglistx is not present before DWARF5"); + return 0; +} + +bool DWARFDebugRngLists::ExtractRangeList( + const DWARFDataExtractor &data, uint8_t addrSize, + lldb::offset_t *offset_ptr, std::vector<RngListEntry> &rangeList) { + rangeList.clear(); + + bool error = false; + while (!error) { + switch (data.GetU8(offset_ptr)) { + case DW_RLE_end_of_list: + return true; + + case DW_RLE_start_length: { + dw_addr_t begin = data.GetMaxU64(offset_ptr, addrSize); + dw_addr_t len = data.GetULEB128(offset_ptr); + rangeList.push_back({DW_RLE_start_length, begin, len}); + break; + } + + case DW_RLE_start_end: { + dw_addr_t begin = data.GetMaxU64(offset_ptr, addrSize); + dw_addr_t end = data.GetMaxU64(offset_ptr, addrSize); + rangeList.push_back({DW_RLE_start_end, begin, end}); + break; + } + + case DW_RLE_base_address: { + dw_addr_t base = data.GetMaxU64(offset_ptr, addrSize); + rangeList.push_back({DW_RLE_base_address, base, 0}); + break; + } + + case DW_RLE_offset_pair: { + dw_addr_t begin = data.GetULEB128(offset_ptr); + dw_addr_t end = data.GetULEB128(offset_ptr); + rangeList.push_back({DW_RLE_offset_pair, begin, end}); + break; + } + + case DW_RLE_base_addressx: { + dw_addr_t base = data.GetULEB128(offset_ptr); + rangeList.push_back({DW_RLE_base_addressx, base, 0}); + break; + } + + case DW_RLE_startx_endx: { + dw_addr_t start = data.GetULEB128(offset_ptr); + dw_addr_t end = data.GetULEB128(offset_ptr); + rangeList.push_back({DW_RLE_startx_endx, start, end}); + break; + } + + case DW_RLE_startx_length: { + dw_addr_t start = data.GetULEB128(offset_ptr); + dw_addr_t length = data.GetULEB128(offset_ptr); + rangeList.push_back({DW_RLE_startx_length, start, length}); + break; + } + + default: + lldbassert(0 && "unknown range list entry encoding"); + error = true; + } + } + + return false; +} + +static uint64_t ReadAddressFromDebugAddrSection(const DWARFUnit *cu, + uint32_t index) { + uint32_t index_size = cu->GetAddressByteSize(); + dw_offset_t addr_base = cu->GetAddrBase(); + lldb::offset_t offset = addr_base + index * index_size; + return cu->GetSymbolFileDWARF()->get_debug_addr_data().GetMaxU64(&offset, + index_size); +} + +bool DWARFDebugRngLists::FindRanges(const DWARFUnit *cu, + dw_offset_t debug_ranges_offset, + DWARFRangeList &range_list) const { + range_list.Clear(); + dw_addr_t debug_ranges_address = cu->GetRangesBase() + debug_ranges_offset; + auto pos = m_range_map.find(debug_ranges_address); + if (pos != m_range_map.end()) { + dw_addr_t BaseAddr = cu->GetBaseAddress(); + for (const RngListEntry &E : pos->second) { + switch (E.encoding) { + case DW_RLE_start_length: + range_list.Append(DWARFRangeList::Entry(E.value0, E.value1)); + break; + case DW_RLE_base_address: + BaseAddr = E.value0; + break; + case DW_RLE_start_end: + range_list.Append(DWARFRangeList::Entry(E.value0, E.value1 - E.value0)); + break; + case DW_RLE_offset_pair: + range_list.Append( + DWARFRangeList::Entry(BaseAddr + E.value0, E.value1 - E.value0)); + break; + case DW_RLE_base_addressx: { + BaseAddr = ReadAddressFromDebugAddrSection(cu, E.value0); + break; + } + case DW_RLE_startx_endx: { + dw_addr_t start = ReadAddressFromDebugAddrSection(cu, E.value0); + dw_addr_t end = ReadAddressFromDebugAddrSection(cu, E.value1); + range_list.Append(DWARFRangeList::Entry(start, end - start)); + break; + } + case DW_RLE_startx_length: { + dw_addr_t start = ReadAddressFromDebugAddrSection(cu, E.value0); + range_list.Append(DWARFRangeList::Entry(start, E.value1)); + break; + } + default: + llvm_unreachable("unexpected encoding"); + } + } return true; } return false; } + +void DWARFDebugRngLists::Extract(SymbolFileDWARF *dwarf2Data) { + const DWARFDataExtractor &data = dwarf2Data->get_debug_rnglists_data(); + lldb::offset_t offset = 0; + + uint64_t length = data.GetU32(&offset); + bool isDwarf64 = (length == 0xffffffff); + if (isDwarf64) + length = data.GetU64(&offset); + lldb::offset_t end = offset + length; + + // Check version. + if (data.GetU16(&offset) < 5) + return; + + uint8_t addrSize = data.GetU8(&offset); + + // We do not support non-zero segment selector size. + if (data.GetU8(&offset) != 0) { + lldbassert(0 && "not implemented"); + return; + } + + uint32_t offsetsAmount = data.GetU32(&offset); + for (uint32_t i = 0; i < offsetsAmount; ++i) + Offsets.push_back(data.GetMaxU64(&offset, isDwarf64 ? 8 : 4)); + + lldb::offset_t listOffset = offset; + std::vector<RngListEntry> rangeList; + while (offset < end && ExtractRangeList(data, addrSize, &offset, rangeList)) { + m_range_map[listOffset] = rangeList; + listOffset = offset; + } +} + +uint64_t DWARFDebugRngLists::GetOffset(size_t Index) const { + return Offsets[Index]; +} diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h index f514359e00a4..5790f448ba85 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h +++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h @@ -15,17 +15,28 @@ #include <map> -class DWARFDebugRanges { +class DWARFDebugRangesBase { +public: + virtual ~DWARFDebugRangesBase(){}; + + virtual void Extract(SymbolFileDWARF *dwarf2Data) = 0; + virtual bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset, + DWARFRangeList &range_list) const = 0; + virtual uint64_t GetOffset(size_t Index) const = 0; +}; + +class DWARFDebugRanges final : public DWARFDebugRangesBase { public: DWARFDebugRanges(); - ~DWARFDebugRanges(); - void Extract(SymbolFileDWARF *dwarf2Data); + + void Extract(SymbolFileDWARF *dwarf2Data) override; + bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset, + DWARFRangeList &range_list) const override; + uint64_t GetOffset(size_t Index) const override; + static void Dump(lldb_private::Stream &s, const lldb_private::DWARFDataExtractor &debug_ranges_data, lldb::offset_t *offset_ptr, dw_addr_t cu_base_addr); - bool FindRanges(dw_addr_t debug_ranges_base, - dw_offset_t debug_ranges_offset, - DWARFRangeList &range_list) const; protected: bool Extract(SymbolFileDWARF *dwarf2Data, lldb::offset_t *offset_ptr, @@ -37,4 +48,27 @@ protected: range_map m_range_map; }; +// DWARF v5 .debug_rnglists section. +class DWARFDebugRngLists final : public DWARFDebugRangesBase { + struct RngListEntry { + uint8_t encoding; + uint64_t value0; + uint64_t value1; + }; + +public: + void Extract(SymbolFileDWARF *dwarf2Data) override; + bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset, + DWARFRangeList &range_list) const override; + uint64_t GetOffset(size_t Index) const override; + +protected: + bool ExtractRangeList(const lldb_private::DWARFDataExtractor &data, + uint8_t addrSize, lldb::offset_t *offset_ptr, + std::vector<RngListEntry> &list); + + std::vector<uint64_t> Offsets; + std::map<dw_offset_t, std::vector<RngListEntry>> m_range_map; +}; + #endif // SymbolFileDWARF_DWARFDebugRanges_h_ diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h b/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h index 1f3c59768fdf..aff5ea64e9ce 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h +++ b/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h @@ -10,13 +10,9 @@ #ifndef SymbolFileDWARF_DWARFDeclContext_h_ #define SymbolFileDWARF_DWARFDeclContext_h_ -// C Includes -// C++ Includes #include <string> #include <vector> -// Other libraries and framework includes #include "lldb/Utility/ConstString.h" -// Project includes #include "DWARFDefines.h" //---------------------------------------------------------------------- diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp index 1d927ba3bca3..99becdbb2bc1 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp @@ -504,9 +504,9 @@ const char *DW_MACINFO_value_to_name(uint32_t val) { return llvmstr.data(); } -const char *DW_CFA_value_to_name(uint32_t val) { +const char *DW_CFA_value_to_name(uint32_t val, llvm::Triple::ArchType Arch) { static char invalid[100]; - llvm::StringRef llvmstr = llvm::dwarf::CallFrameString(val); + llvm::StringRef llvmstr = llvm::dwarf::CallFrameString(val, Arch); if (llvmstr.empty()) { snprintf(invalid, sizeof(invalid), "Unknown DW_CFA constant: 0x%x", val); return invalid; diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDefines.h b/source/Plugins/SymbolFile/DWARF/DWARFDefines.h index 926f83b3564a..0f5a885efb86 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFDefines.h +++ b/source/Plugins/SymbolFile/DWARF/DWARFDefines.h @@ -64,7 +64,7 @@ const char *DW_LNE_value_to_name(uint32_t val); const char *DW_MACINFO_value_to_name(uint32_t val); -const char *DW_CFA_value_to_name(uint32_t val); +const char *DW_CFA_value_to_name(uint32_t val, llvm::Triple::ArchType Arch); const char *DW_GNU_EH_PE_value_to_name(uint32_t val); diff --git a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp index 4fde5748d3f3..5d2a8ffdb85b 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp @@ -154,6 +154,9 @@ DWARFFormValue::GetFixedFormSizesForAddressSize(uint8_t addr_size, DWARFFormValue::DWARFFormValue() : m_cu(NULL), m_form(0), m_value() {} +DWARFFormValue::DWARFFormValue(const DWARFUnit *cu) + : m_cu(cu), m_form(0), m_value() {} + DWARFFormValue::DWARFFormValue(const DWARFUnit *cu, dw_form_t form) : m_cu(cu), m_form(form), m_value() {} @@ -165,6 +168,9 @@ void DWARFFormValue::Clear() { bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data, lldb::offset_t *offset_ptr) { + if (m_form == DW_FORM_implicit_const) + return true; + bool indirect = false; bool is_block = false; m_value.data = NULL; @@ -176,8 +182,12 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data, switch (m_form) { case DW_FORM_addr: assert(m_cu); - m_value.value.uval = data.GetMaxU64( - offset_ptr, DWARFUnit::GetAddressByteSize(m_cu)); + m_value.value.uval = + data.GetMaxU64(offset_ptr, DWARFUnit::GetAddressByteSize(m_cu)); + break; + case DW_FORM_block1: + m_value.value.uval = data.GetU8(offset_ptr); + is_block = true; break; case DW_FORM_block2: m_value.value.uval = data.GetU16(offset_ptr); @@ -187,94 +197,82 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data, m_value.value.uval = data.GetU32(offset_ptr); is_block = true; break; - case DW_FORM_data2: - m_value.value.uval = data.GetU16(offset_ptr); - break; - case DW_FORM_data4: - m_value.value.uval = data.GetU32(offset_ptr); - break; - case DW_FORM_data8: - m_value.value.uval = data.GetU64(offset_ptr); - break; - case DW_FORM_string: - m_value.value.cstr = data.GetCStr(offset_ptr); + case DW_FORM_data16: + m_value.value.uval = 16; + is_block = true; break; case DW_FORM_exprloc: case DW_FORM_block: m_value.value.uval = data.GetULEB128(offset_ptr); is_block = true; break; - case DW_FORM_block1: - m_value.value.uval = data.GetU8(offset_ptr); - is_block = true; - break; - case DW_FORM_data1: - m_value.value.uval = data.GetU8(offset_ptr); - break; - case DW_FORM_flag: - m_value.value.uval = data.GetU8(offset_ptr); + case DW_FORM_string: + m_value.value.cstr = data.GetCStr(offset_ptr); break; case DW_FORM_sdata: m_value.value.sval = data.GetSLEB128(offset_ptr); break; case DW_FORM_strp: + case DW_FORM_line_strp: + case DW_FORM_sec_offset: assert(m_cu); m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFUnit::IsDWARF64(m_cu) ? 8 : 4); break; - // case DW_FORM_APPLE_db_str: - case DW_FORM_udata: - m_value.value.uval = data.GetULEB128(offset_ptr); - break; - case DW_FORM_ref_addr: - assert(m_cu); - ref_addr_size = 4; - if (m_cu->GetVersion() <= 2) - ref_addr_size = m_cu->GetAddressByteSize(); - else - ref_addr_size = m_cu->IsDWARF64() ? 8 : 4; - m_value.value.uval = data.GetMaxU64(offset_ptr, ref_addr_size); - break; + case DW_FORM_addrx1: + case DW_FORM_strx1: case DW_FORM_ref1: + case DW_FORM_data1: + case DW_FORM_flag: m_value.value.uval = data.GetU8(offset_ptr); break; + case DW_FORM_addrx2: + case DW_FORM_strx2: case DW_FORM_ref2: + case DW_FORM_data2: m_value.value.uval = data.GetU16(offset_ptr); break; + case DW_FORM_addrx3: + case DW_FORM_strx3: + m_value.value.uval = data.GetMaxU64(offset_ptr, 3); + break; + case DW_FORM_addrx4: + case DW_FORM_strx4: case DW_FORM_ref4: + case DW_FORM_data4: m_value.value.uval = data.GetU32(offset_ptr); break; + case DW_FORM_data8: case DW_FORM_ref8: + case DW_FORM_ref_sig8: m_value.value.uval = data.GetU64(offset_ptr); break; + case DW_FORM_addrx: + case DW_FORM_rnglistx: + case DW_FORM_strx: + case DW_FORM_udata: case DW_FORM_ref_udata: + case DW_FORM_GNU_str_index: + case DW_FORM_GNU_addr_index: m_value.value.uval = data.GetULEB128(offset_ptr); break; + case DW_FORM_ref_addr: + assert(m_cu); + if (m_cu->GetVersion() <= 2) + ref_addr_size = m_cu->GetAddressByteSize(); + else + ref_addr_size = m_cu->IsDWARF64() ? 8 : 4; + m_value.value.uval = data.GetMaxU64(offset_ptr, ref_addr_size); + break; case DW_FORM_indirect: m_form = data.GetULEB128(offset_ptr); indirect = true; break; - - case DW_FORM_sec_offset: - assert(m_cu); - m_value.value.uval = - data.GetMaxU64(offset_ptr, DWARFUnit::IsDWARF64(m_cu) ? 8 : 4); - break; case DW_FORM_flag_present: m_value.value.uval = 1; break; - case DW_FORM_ref_sig8: - m_value.value.uval = data.GetU64(offset_ptr); - break; - case DW_FORM_GNU_str_index: - m_value.value.uval = data.GetULEB128(offset_ptr); - break; - case DW_FORM_GNU_addr_index: - m_value.value.uval = data.GetULEB128(offset_ptr); - break; default: return false; - break; } } while (indirect); @@ -346,49 +344,65 @@ bool DWARFFormValue::SkipValue(dw_form_t form, // 0 bytes values (implied from DW_FORM) case DW_FORM_flag_present: + case DW_FORM_implicit_const: return true; - // 1 byte values - case DW_FORM_data1: - case DW_FORM_flag: - case DW_FORM_ref1: - *offset_ptr += 1; - return true; + // 1 byte values + case DW_FORM_addrx1: + case DW_FORM_data1: + case DW_FORM_flag: + case DW_FORM_ref1: + case DW_FORM_strx1: + *offset_ptr += 1; + return true; - // 2 byte values - case DW_FORM_data2: - case DW_FORM_ref2: - *offset_ptr += 2; - return true; + // 2 byte values + case DW_FORM_addrx2: + case DW_FORM_data2: + case DW_FORM_ref2: + case DW_FORM_strx2: + *offset_ptr += 2; + return true; - // 32 bit for DWARF 32, 64 for DWARF 64 - case DW_FORM_sec_offset: - case DW_FORM_strp: - assert(cu); - *offset_ptr += (cu->IsDWARF64() ? 8 : 4); - return true; + // 3 byte values + case DW_FORM_addrx3: + case DW_FORM_strx3: + *offset_ptr += 3; + return true; - // 4 byte values - case DW_FORM_data4: - case DW_FORM_ref4: - *offset_ptr += 4; - return true; + // 32 bit for DWARF 32, 64 for DWARF 64 + case DW_FORM_sec_offset: + case DW_FORM_strp: + assert(cu); + *offset_ptr += (cu->IsDWARF64() ? 8 : 4); + return true; - // 8 byte values - case DW_FORM_data8: - case DW_FORM_ref8: - case DW_FORM_ref_sig8: - *offset_ptr += 8; - return true; + // 4 byte values + case DW_FORM_addrx4: + case DW_FORM_data4: + case DW_FORM_ref4: + case DW_FORM_strx4: + *offset_ptr += 4; + return true; - // signed or unsigned LEB 128 values - case DW_FORM_sdata: - case DW_FORM_udata: - case DW_FORM_ref_udata: - case DW_FORM_GNU_addr_index: - case DW_FORM_GNU_str_index: - debug_info_data.Skip_LEB128(offset_ptr); - return true; + // 8 byte values + case DW_FORM_data8: + case DW_FORM_ref8: + case DW_FORM_ref_sig8: + *offset_ptr += 8; + return true; + + // signed or unsigned LEB 128 values + case DW_FORM_addrx: + case DW_FORM_rnglistx: + case DW_FORM_sdata: + case DW_FORM_udata: + case DW_FORM_ref_udata: + case DW_FORM_GNU_addr_index: + case DW_FORM_GNU_str_index: + case DW_FORM_strx: + debug_info_data.Skip_LEB128(offset_ptr); + return true; case DW_FORM_indirect: { dw_form_t indirect_form = debug_info_data.GetULEB128(offset_ptr); @@ -546,6 +560,26 @@ const char *DWARFFormValue::AsCString() const { index_size); return symbol_file->get_debug_str_data().PeekCStr(str_offset); } + + if (m_form == DW_FORM_strx || m_form == DW_FORM_strx1 || + m_form == DW_FORM_strx2 || m_form == DW_FORM_strx3 || + m_form == DW_FORM_strx4) { + + // The same code as above. + if (!symbol_file) + return nullptr; + + uint32_t indexSize = m_cu->IsDWARF64() ? 8 : 4; + lldb::offset_t offset = + m_cu->GetStrOffsetsBase() + m_value.value.uval * indexSize; + dw_offset_t strOffset = + symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset, indexSize); + return symbol_file->get_debug_str_data().PeekCStr(strOffset); + } + + if (m_form == DW_FORM_line_strp) + return symbol_file->get_debug_line_str_data().PeekCStr(m_value.value.uval); + return nullptr; } @@ -556,7 +590,9 @@ dw_addr_t DWARFFormValue::Address() const { return Unsigned(); assert(m_cu); - assert(m_form == DW_FORM_GNU_addr_index); + assert(m_form == DW_FORM_GNU_addr_index || m_form == DW_FORM_addrx || + m_form == DW_FORM_addrx1 || m_form == DW_FORM_addrx2 || + m_form == DW_FORM_addrx3 || m_form == DW_FORM_addrx4); if (!symbol_file) return 0; @@ -568,7 +604,7 @@ dw_addr_t DWARFFormValue::Address() const { } uint64_t DWARFFormValue::Reference() const { - uint64_t die_offset = m_value.value.uval; + uint64_t value = m_value.value.uval; switch (m_form) { case DW_FORM_ref1: case DW_FORM_ref2: @@ -577,32 +613,36 @@ uint64_t DWARFFormValue::Reference() const { case DW_FORM_ref_udata: assert(m_cu); // CU must be valid for DW_FORM_ref forms that are compile // unit relative or we will get this wrong - die_offset += m_cu->GetOffset(); - break; + return value + m_cu->GetOffset(); + + case DW_FORM_ref_addr: + case DW_FORM_ref_sig8: + case DW_FORM_GNU_ref_alt: + return value; default: - break; + return DW_INVALID_OFFSET; } - - return die_offset; } uint64_t DWARFFormValue::Reference(dw_offset_t base_offset) const { - uint64_t die_offset = m_value.value.uval; + uint64_t value = m_value.value.uval; switch (m_form) { case DW_FORM_ref1: case DW_FORM_ref2: case DW_FORM_ref4: case DW_FORM_ref8: case DW_FORM_ref_udata: - die_offset += base_offset; - break; + return value + base_offset; + + case DW_FORM_ref_addr: + case DW_FORM_ref_sig8: + case DW_FORM_GNU_ref_alt: + return value; default: - break; + return DW_INVALID_OFFSET; } - - return die_offset; } const uint8_t *DWARFFormValue::BlockData() const { return m_value.data; } @@ -729,6 +769,8 @@ int DWARFFormValue::Compare(const DWARFFormValue &a_value, bool DWARFFormValue::FormIsSupported(dw_form_t form) { switch (form) { case DW_FORM_addr: + case DW_FORM_addrx: + case DW_FORM_rnglistx: case DW_FORM_block2: case DW_FORM_block4: case DW_FORM_data2: @@ -741,6 +783,11 @@ bool DWARFFormValue::FormIsSupported(dw_form_t form) { case DW_FORM_flag: case DW_FORM_sdata: case DW_FORM_strp: + case DW_FORM_strx: + case DW_FORM_strx1: + case DW_FORM_strx2: + case DW_FORM_strx3: + case DW_FORM_strx4: case DW_FORM_udata: case DW_FORM_ref_addr: case DW_FORM_ref1: @@ -755,6 +802,7 @@ bool DWARFFormValue::FormIsSupported(dw_form_t form) { case DW_FORM_ref_sig8: case DW_FORM_GNU_str_index: case DW_FORM_GNU_addr_index: + case DW_FORM_implicit_const: return true; default: break; diff --git a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h index ef1a693b37c9..0890f0c1bfc5 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h +++ b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h @@ -11,9 +11,10 @@ #define SymbolFileDWARF_DWARFFormValue_h_ #include "DWARFDataExtractor.h" -#include <stddef.h> // for NULL +#include <stddef.h> class DWARFUnit; +class SymbolFileDWARF; class DWARFFormValue { public: @@ -55,12 +56,17 @@ public: }; DWARFFormValue(); + DWARFFormValue(const DWARFUnit *cu); DWARFFormValue(const DWARFUnit *cu, dw_form_t form); const DWARFUnit *GetCompileUnit() const { return m_cu; } void SetCompileUnit(const DWARFUnit *cu) { m_cu = cu; } dw_form_t Form() const { return m_form; } + dw_form_t& FormRef() { return m_form; } void SetForm(dw_form_t form) { m_form = form; } const ValueType &Value() const { return m_value; } + ValueType &ValueRef() { return m_value; } + void SetValue(const ValueType &val) { m_value = val; } + void Dump(lldb_private::Stream &s) const; bool ExtractValue(const lldb_private::DWARFDataExtractor &data, lldb::offset_t *offset_ptr); diff --git a/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp index f44b2bb97b2b..7afc71bc24f0 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -191,13 +191,6 @@ void DWARFUnit::ExtractDIEsRWLocked() { IsDWARF64()); while (offset < next_cu_offset && die.FastExtract(data, this, fixed_form_sizes, &offset)) { - // if (log) - // log->Printf("0x%8.8x: %*.*s%s%s", - // die.GetOffset(), - // depth * 2, depth * 2, "", - // DW_TAG_value_to_name (die.Tag()), - // die.HasChildren() ? " *" : ""); - const bool null_die = die.IsNULL(); if (depth == 0) { assert(m_die_array.empty() && "Compile unit DIE already added"); @@ -223,7 +216,7 @@ void DWARFUnit::ExtractDIEsRWLocked() { // the list (saves up to 25% in C++ code), we need a way to let the // DIE know that it actually doesn't have children. if (!m_die_array.empty()) - m_die_array.back().SetEmptyChildren(true); + m_die_array.back().SetHasChildren(false); } } else { die.SetParentIndex(m_die_array.size() - die_index_stack[depth - 1]); @@ -244,9 +237,6 @@ void DWARFUnit::ExtractDIEsRWLocked() { if (depth > 0) --depth; - if (depth == 0) - break; // We are done with this compile unit! - prev_die_had_children = false; } else { die_index_stack.back() = m_die_array.size() - 1; @@ -258,10 +248,17 @@ void DWARFUnit::ExtractDIEsRWLocked() { } prev_die_had_children = die_has_children; } + + if (depth == 0) + break; // We are done with this compile unit! } if (!m_die_array.empty()) { - lldbassert(!m_first_die || m_first_die == m_die_array.front()); + if (m_first_die) { + // Only needed for the assertion. + m_first_die.SetHasChildren(m_die_array.front().HasChildren()); + lldbassert(m_first_die == m_die_array.front()); + } m_first_die = m_die_array.front(); } @@ -301,8 +298,46 @@ void DWARFUnit::ExtractDIEsEndCheck(lldb::offset_t offset) const { } } +// This is used when a split dwarf is enabled. +// A skeleton compilation unit may contain the DW_AT_str_offsets_base attribute +// that points to the first string offset of the CU contribution to the +// .debug_str_offsets. At the same time, the corresponding split debug unit also +// may use DW_FORM_strx* forms pointing to its own .debug_str_offsets.dwo and +// for that case, we should find the offset (skip the section header). +static void SetDwoStrOffsetsBase(DWARFUnit *dwo_cu) { + lldb::offset_t baseOffset = 0; + + const DWARFDataExtractor &strOffsets = + dwo_cu->GetSymbolFileDWARF()->get_debug_str_offsets_data(); + uint64_t length = strOffsets.GetU32(&baseOffset); + if (length == 0xffffffff) + length = strOffsets.GetU64(&baseOffset); + + // Check version. + if (strOffsets.GetU16(&baseOffset) < 5) + return; + + // Skip padding. + baseOffset += 2; + + dwo_cu->SetStrOffsetsBase(baseOffset); +} + // m_die_array_mutex must be already held as read/write. void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) { + dw_addr_t addr_base = cu_die.GetAttributeValueAsUnsigned( + m_dwarf, this, DW_AT_addr_base, LLDB_INVALID_ADDRESS); + if (addr_base != LLDB_INVALID_ADDRESS) + SetAddrBase(addr_base); + + dw_addr_t ranges_base = cu_die.GetAttributeValueAsUnsigned( + m_dwarf, this, DW_AT_rnglists_base, LLDB_INVALID_ADDRESS); + if (ranges_base != LLDB_INVALID_ADDRESS) + SetRangesBase(ranges_base); + + SetStrOffsetsBase(cu_die.GetAttributeValueAsUnsigned( + m_dwarf, this, DW_AT_str_offsets_base, 0)); + uint64_t base_addr = cu_die.GetAttributeValueAsAddress( m_dwarf, this, DW_AT_low_pc, LLDB_INVALID_ADDRESS); if (base_addr == LLDB_INVALID_ADDRESS) @@ -333,11 +368,25 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) { m_dwo_symbol_file = std::move(dwo_symbol_file); - dw_addr_t addr_base = - cu_die.GetAttributeValueAsUnsigned(m_dwarf, this, DW_AT_GNU_addr_base, 0); - dw_addr_t ranges_base = cu_die.GetAttributeValueAsUnsigned( - m_dwarf, this, DW_AT_GNU_ranges_base, 0); - dwo_cu->SetAddrBase(addr_base, ranges_base, m_offset); + // Here for DWO CU we want to use the address base set in the skeleton unit + // (DW_AT_addr_base) if it is available and use the DW_AT_GNU_addr_base + // otherwise. We do that because pre-DWARF v5 could use the DW_AT_GNU_* + // attributes which were applicable to the DWO units. The corresponding + // DW_AT_* attributes standardized in DWARF v5 are also applicable to the main + // unit in contrast. + if (addr_base == LLDB_INVALID_ADDRESS) + addr_base = cu_die.GetAttributeValueAsUnsigned(m_dwarf, this, + DW_AT_GNU_addr_base, 0); + dwo_cu->SetAddrBase(addr_base); + + if (ranges_base == LLDB_INVALID_ADDRESS) + ranges_base = cu_die.GetAttributeValueAsUnsigned(m_dwarf, this, + DW_AT_GNU_ranges_base, 0); + dwo_cu->SetRangesBase(ranges_base); + + dwo_cu->SetBaseObjOffset(m_offset); + + SetDwoStrOffsetsBase(dwo_cu); } DWARFDIE DWARFUnit::LookupAddress(const dw_addr_t address) { @@ -395,14 +444,20 @@ dw_offset_t DWARFUnit::GetAbbrevOffset() const { return m_abbrevs ? m_abbrevs->GetOffset() : DW_INVALID_OFFSET; } -void DWARFUnit::SetAddrBase(dw_addr_t addr_base, - dw_addr_t ranges_base, - dw_offset_t base_obj_offset) { - m_addr_base = addr_base; +void DWARFUnit::SetAddrBase(dw_addr_t addr_base) { m_addr_base = addr_base; } + +void DWARFUnit::SetRangesBase(dw_addr_t ranges_base) { m_ranges_base = ranges_base; +} + +void DWARFUnit::SetBaseObjOffset(dw_offset_t base_obj_offset) { m_base_obj_offset = base_obj_offset; } +void DWARFUnit::SetStrOffsetsBase(dw_offset_t str_offsets_base) { + m_str_offsets_base = str_offsets_base; +} + // It may be called only with m_die_array_mutex held R/W. void DWARFUnit::ClearDIEsRWLocked() { m_die_array.clear(); @@ -586,9 +641,7 @@ void DWARFUnit::SetUserData(void *d) { } bool DWARFUnit::Supports_DW_AT_APPLE_objc_complete_type() { - if (GetProducer() == eProducerLLVMGCC) - return false; - return true; + return GetProducer() != eProducerLLVMGCC; } bool DWARFUnit::DW_AT_decl_file_attributes_are_invalid() { @@ -600,11 +653,8 @@ bool DWARFUnit::DW_AT_decl_file_attributes_are_invalid() { bool DWARFUnit::Supports_unnamed_objc_bitfields() { if (GetProducer() == eProducerClang) { const uint32_t major_version = GetProducerVersionMajor(); - if (major_version > 425 || - (major_version == 425 && GetProducerVersionUpdate() >= 13)) - return true; - else - return false; + return major_version > 425 || + (major_version == 425 && GetProducerVersionUpdate() >= 13); } return true; // Assume all other compilers didn't have incorrect ObjC bitfield // info diff --git a/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/source/Plugins/SymbolFile/DWARF/DWARFUnit.h index 3cc24d4202b8..178c894686ee 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ b/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -111,8 +111,11 @@ public: dw_addr_t GetBaseAddress() const { return m_base_addr; } dw_addr_t GetAddrBase() const { return m_addr_base; } dw_addr_t GetRangesBase() const { return m_ranges_base; } - void SetAddrBase(dw_addr_t addr_base, dw_addr_t ranges_base, - dw_offset_t base_obj_offset); + dw_addr_t GetStrOffsetsBase() const { return m_str_offsets_base; } + void SetAddrBase(dw_addr_t addr_base); + void SetRangesBase(dw_addr_t ranges_base); + void SetBaseObjOffset(dw_offset_t base_obj_offset); + void SetStrOffsetsBase(dw_offset_t str_offsets_base); void BuildAddressRangeTable(SymbolFileDWARF *dwarf, DWARFDebugAranges *debug_aranges); @@ -202,6 +205,8 @@ protected: dw_offset_t m_length = 0; uint16_t m_version = 0; uint8_t m_addr_size = 0; + uint8_t m_unit_type = 0; + uint64_t m_dwo_id = 0; DWARFProducer m_producer = eProducerInvalid; uint32_t m_producer_version_major = 0; uint32_t m_producer_version_minor = 0; @@ -214,7 +219,7 @@ protected: // If this is a dwo compile unit this is the offset of the base compile unit // in the main object file dw_offset_t m_base_obj_offset = DW_INVALID_OFFSET; - + dw_offset_t m_str_offsets_base = 0; // Value of DW_AT_str_offsets_base. // Offset of the initial length field. dw_offset_t m_offset; diff --git a/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp b/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp index 614ff470d161..c043272f8a3e 100644 --- a/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp +++ b/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp @@ -225,7 +225,8 @@ void DebugNamesDWARFIndex::GetFunctions( const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, std::vector<DWARFDIE> &dies) { - m_fallback.GetFunctions(name, info, parent_decl_ctx, name_type_mask, dies); + std::vector<DWARFDIE> v; + m_fallback.GetFunctions(name, info, parent_decl_ctx, name_type_mask, v); for (const DebugNames::Entry &entry : m_debug_names_up->equal_range(name.GetStringRef())) { @@ -235,8 +236,13 @@ void DebugNamesDWARFIndex::GetFunctions( if (DIERef ref = ToDIERef(entry)) ProcessFunctionDIE(name.GetStringRef(), ref, info, parent_decl_ctx, - name_type_mask, dies); + name_type_mask, v); } + + std::set<DWARFDebugInfoEntry *> seen; + for (DWARFDIE die : v) + if (seen.insert(die.GetDIE()).second) + dies.push_back(die); } void DebugNamesDWARFIndex::GetFunctions(const RegularExpression ®ex, diff --git a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp index 36211a08557e..f83ba6663dfc 100644 --- a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp +++ b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp @@ -279,7 +279,9 @@ bool DWARFMappedHash::Header::Read(const lldb_private::DWARFDataExtractor &data, switch (header_data.atoms[i].type) { case eAtomTypeDIEOffset: // DIE offset, check form for encoding hash_data.offset = - (dw_offset_t)form_value.Reference(header_data.die_base_offset); + DWARFFormValue::IsDataForm(form_value.Form()) + ? form_value.Unsigned() + : form_value.Reference(header_data.die_base_offset); break; case eAtomTypeTag: // DW_TAG value for the DIE diff --git a/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h b/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h index 0293fbd7c495..038e9b8c2b08 100644 --- a/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h +++ b/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h @@ -10,10 +10,6 @@ #ifndef SymbolFileDWARF_LogChannelDWARF_h_ #define SymbolFileDWARF_LogChannelDWARF_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Utility/Log.h" #define DWARF_LOG_DEBUG_INFO (1u << 1) diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index ac320ac52b08..2a0a89f0b25a 100644 --- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -9,7 +9,6 @@ #include "SymbolFileDWARF.h" -// Other libraries and framework includes #include "llvm/Support/Casting.h" #include "llvm/Support/Threading.h" @@ -17,12 +16,12 @@ #include "lldb/Core/ModuleList.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/Section.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/Value.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/RegularExpression.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/Timer.h" @@ -111,17 +110,14 @@ using namespace lldb_private; namespace { -PropertyDefinition g_properties[] = { +static constexpr PropertyDefinition g_properties[] = { {"comp-dir-symlink-paths", OptionValue::eTypeFileSpecList, true, 0, nullptr, - nullptr, + {}, "If the DW_AT_comp_dir matches any of these paths the symbolic " "links will be resolved at DWARF parse time."}, - {"ignore-file-indexes", OptionValue::eTypeBoolean, true, 0, nullptr, - nullptr, + {"ignore-file-indexes", OptionValue::eTypeBoolean, true, 0, nullptr, {}, "Ignore indexes present in the object files and always index DWARF " - "manually."}, - {nullptr, OptionValue::eTypeInvalid, false, 0, nullptr, nullptr, nullptr}, -}; + "manually."}}; enum { ePropertySymLinkPaths, @@ -200,7 +196,7 @@ static FileSpec resolveCompDir(const char *path_from_dwarf) { bool is_symlink = false; // Always normalize our compile unit directory to get rid of redundant // slashes and other path anomalies before we use it for path prepending - FileSpec local_spec(local_path, false); + FileSpec local_spec(local_path); const auto &file_specs = GetGlobalPluginProperties()->GetSymLinkPaths(); for (size_t i = 0; i < file_specs.GetSize() && !is_symlink; ++i) is_symlink = FileSpec::Equal(file_specs.GetFileSpecAtIndex(i), @@ -215,7 +211,7 @@ static FileSpec resolveCompDir(const char *path_from_dwarf) { return local_spec; FileSpec resolved_symlink; - const auto error = FileSystem::Readlink(local_spec, resolved_symlink); + const auto error = FileSystem::Instance().Readlink(local_spec, resolved_symlink); if (error.Success()) return resolved_symlink; @@ -263,6 +259,9 @@ SymbolFile *SymbolFileDWARF::CreateInstance(ObjectFile *obj_file) { } TypeList *SymbolFileDWARF::GetTypeList() { + // This method can be called without going through the symbol vendor so we + // need to lock the module. + std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile(); if (debug_map_symfile) return debug_map_symfile->GetTypeList(); @@ -341,9 +340,10 @@ void SymbolFileDWARF::GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset, } size_t SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope, - uint32_t type_mask, TypeList &type_list) + TypeClass type_mask, TypeList &type_list) { + ASSERT_MODULE_LOCK(this); TypeSet type_set; CompileUnit *comp_unit = NULL; @@ -413,9 +413,9 @@ SymbolFileDWARF::SymbolFileDWARF(ObjectFile *objfile) m_debug_map_module_wp(), m_debug_map_symfile(NULL), m_data_debug_abbrev(), m_data_debug_aranges(), m_data_debug_frame(), m_data_debug_info(), m_data_debug_line(), m_data_debug_macro(), m_data_debug_loc(), - m_data_debug_ranges(), m_data_debug_str(), m_data_apple_names(), - m_data_apple_types(), m_data_apple_namespaces(), m_abbr(), m_info(), - m_line(), m_fetched_external_modules(false), + m_data_debug_ranges(), m_data_debug_rnglists(), m_data_debug_str(), + m_data_apple_names(), m_data_apple_types(), m_data_apple_namespaces(), + m_abbr(), m_info(), m_line(), m_fetched_external_modules(false), m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate), m_ranges(), m_unique_ast_type_map() {} @@ -494,7 +494,7 @@ void SymbolFileDWARF::InitializeObject() { } bool SymbolFileDWARF::SupportedVersion(uint16_t version) { - return version == 2 || version == 3 || version == 4; + return version >= 2 && version <= 5; } uint32_t SymbolFileDWARF::CalculateAbilities() { @@ -645,19 +645,40 @@ const DWARFDataExtractor &SymbolFileDWARF::get_debug_line_data() { return GetCachedSectionData(eSectionTypeDWARFDebugLine, m_data_debug_line); } +const DWARFDataExtractor &SymbolFileDWARF::get_debug_line_str_data() { + return GetCachedSectionData(eSectionTypeDWARFDebugLineStr, m_data_debug_line_str); +} + const DWARFDataExtractor &SymbolFileDWARF::get_debug_macro_data() { return GetCachedSectionData(eSectionTypeDWARFDebugMacro, m_data_debug_macro); } +const DWARFDataExtractor &SymbolFileDWARF::DebugLocData() { + const DWARFDataExtractor &debugLocData = get_debug_loc_data(); + if (debugLocData.GetByteSize() > 0) + return debugLocData; + return get_debug_loclists_data(); +} + const DWARFDataExtractor &SymbolFileDWARF::get_debug_loc_data() { return GetCachedSectionData(eSectionTypeDWARFDebugLoc, m_data_debug_loc); } +const DWARFDataExtractor &SymbolFileDWARF::get_debug_loclists_data() { + return GetCachedSectionData(eSectionTypeDWARFDebugLocLists, + m_data_debug_loclists); +} + const DWARFDataExtractor &SymbolFileDWARF::get_debug_ranges_data() { return GetCachedSectionData(eSectionTypeDWARFDebugRanges, m_data_debug_ranges); } +const DWARFDataExtractor &SymbolFileDWARF::get_debug_rnglists_data() { + return GetCachedSectionData(eSectionTypeDWARFDebugRngLists, + m_data_debug_rnglists); +} + const DWARFDataExtractor &SymbolFileDWARF::get_debug_str_data() { return GetCachedSectionData(eSectionTypeDWARFDebugStr, m_data_debug_str); } @@ -747,21 +768,24 @@ SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) { return NULL; } -DWARFDebugRanges *SymbolFileDWARF::DebugRanges() { +DWARFDebugRangesBase *SymbolFileDWARF::DebugRanges() { if (m_ranges.get() == NULL) { static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION, static_cast<void *>(this)); - if (get_debug_ranges_data().GetByteSize() > 0) { + + if (get_debug_ranges_data().GetByteSize() > 0) m_ranges.reset(new DWARFDebugRanges()); - if (m_ranges.get()) - m_ranges->Extract(this); - } + else if (get_debug_rnglists_data().GetByteSize() > 0) + m_ranges.reset(new DWARFDebugRngLists()); + + if (m_ranges.get()) + m_ranges->Extract(this); } return m_ranges.get(); } -const DWARFDebugRanges *SymbolFileDWARF::DebugRanges() const { +const DWARFDebugRangesBase *SymbolFileDWARF::DebugRanges() const { return m_ranges.get(); } @@ -786,7 +810,7 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFUnit *dwarf_cu, if (module_sp) { const DWARFDIE cu_die = dwarf_cu->DIE(); if (cu_die) { - FileSpec cu_file_spec{cu_die.GetName(), false}; + FileSpec cu_file_spec(cu_die.GetName()); if (cu_file_spec) { // If we have a full path to the compile unit, we don't need to // resolve the file. This can be expensive e.g. when the source @@ -801,8 +825,7 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFUnit *dwarf_cu, std::string remapped_file; if (module_sp->RemapSourceFile(cu_file_spec.GetPath(), remapped_file)) - cu_file_spec.SetFile(remapped_file, false, - FileSpec::Style::native); + cu_file_spec.SetFile(remapped_file, FileSpec::Style::native); } LanguageType cu_language = DWARFUnit::LanguageTypeFromDWARF( @@ -851,6 +874,7 @@ uint32_t SymbolFileDWARF::GetNumCompileUnits() { } CompUnitSP SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) { + ASSERT_MODULE_LOCK(this); CompUnitSP cu_sp; DWARFDebugInfo *info = DebugInfo(); if (info) { @@ -861,8 +885,9 @@ CompUnitSP SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) { return cu_sp; } -Function *SymbolFileDWARF::ParseCompileUnitFunction(const SymbolContext &sc, - const DWARFDIE &die) { +Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit, + const DWARFDIE &die) { + ASSERT_MODULE_LOCK(this); if (die.IsValid()) { TypeSystem *type_system = GetTypeSystemForLanguage(die.GetCU()->GetLanguageType()); @@ -870,7 +895,7 @@ Function *SymbolFileDWARF::ParseCompileUnitFunction(const SymbolContext &sc, if (type_system) { DWARFASTParser *dwarf_ast = type_system->GetDWARFParser(); if (dwarf_ast) - return dwarf_ast->ParseFunctionFromDWARF(sc, die); + return dwarf_ast->ParseFunctionFromDWARF(comp_unit, die); } } return nullptr; @@ -884,20 +909,19 @@ bool SymbolFileDWARF::FixupAddress(Address &addr) { // This is a normal DWARF file, no address fixups need to happen return true; } -lldb::LanguageType -SymbolFileDWARF::ParseCompileUnitLanguage(const SymbolContext &sc) { - assert(sc.comp_unit); - DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); +lldb::LanguageType SymbolFileDWARF::ParseLanguage(CompileUnit &comp_unit) { + ASSERT_MODULE_LOCK(this); + DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); if (dwarf_cu) return dwarf_cu->GetLanguageType(); else return eLanguageTypeUnknown; } -size_t SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc) { - assert(sc.comp_unit); +size_t SymbolFileDWARF::ParseFunctions(CompileUnit &comp_unit) { + ASSERT_MODULE_LOCK(this); size_t functions_added = 0; - DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); + DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); if (dwarf_cu) { DWARFDIECollection function_dies; const size_t num_functions = @@ -905,8 +929,8 @@ size_t SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc) { size_t func_idx; for (func_idx = 0; func_idx < num_functions; ++func_idx) { DWARFDIE die = function_dies.GetDIEAtIndex(func_idx); - if (sc.comp_unit->FindFunctionByUID(die.GetID()).get() == NULL) { - if (ParseCompileUnitFunction(sc, die)) + if (comp_unit.FindFunctionByUID(die.GetID()).get() == NULL) { + if (ParseFunction(comp_unit, die)) ++functions_added; } } @@ -915,10 +939,10 @@ size_t SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc) { return functions_added; } -bool SymbolFileDWARF::ParseCompileUnitSupportFiles( - const SymbolContext &sc, FileSpecList &support_files) { - assert(sc.comp_unit); - DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); +bool SymbolFileDWARF::ParseSupportFiles(CompileUnit &comp_unit, + FileSpecList &support_files) { + ASSERT_MODULE_LOCK(this); + DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); if (dwarf_cu) { const DWARFBaseDIE cu_die = dwarf_cu->GetUnitDIEOnly(); @@ -930,19 +954,19 @@ bool SymbolFileDWARF::ParseCompileUnitSupportFiles( if (stmt_list != DW_INVALID_OFFSET) { // All file indexes in DWARF are one based and a file of index zero is // supposed to be the compile unit itself. - support_files.Append(*sc.comp_unit); + support_files.Append(comp_unit); return DWARFDebugLine::ParseSupportFiles( - sc.comp_unit->GetModule(), get_debug_line_data(), cu_comp_dir, - stmt_list, support_files); + comp_unit.GetModule(), get_debug_line_data(), cu_comp_dir, + stmt_list, support_files, dwarf_cu); } } } return false; } -bool SymbolFileDWARF::ParseCompileUnitIsOptimized( - const lldb_private::SymbolContext &sc) { - DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); +bool SymbolFileDWARF::ParseIsOptimized(CompileUnit &comp_unit) { + ASSERT_MODULE_LOCK(this); + DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); if (dwarf_cu) return dwarf_cu->GetIsOptimized(); return false; @@ -951,6 +975,7 @@ bool SymbolFileDWARF::ParseCompileUnitIsOptimized( bool SymbolFileDWARF::ParseImportedModules( const lldb_private::SymbolContext &sc, std::vector<lldb_private::ConstString> &imported_modules) { + ASSERT_MODULE_LOCK(this); assert(sc.comp_unit); DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); if (dwarf_cu) { @@ -1027,12 +1052,12 @@ static void ParseDWARFLineTableCallback(dw_offset_t offset, } } -bool SymbolFileDWARF::ParseCompileUnitLineTable(const SymbolContext &sc) { - assert(sc.comp_unit); - if (sc.comp_unit->GetLineTable() != NULL) +bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) { + ASSERT_MODULE_LOCK(this); + if (comp_unit.GetLineTable() != NULL) return true; - DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); + DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); if (dwarf_cu) { const DWARFBaseDIE dwarf_cu_die = dwarf_cu->GetUnitDIEOnly(); if (dwarf_cu_die) { @@ -1040,7 +1065,7 @@ bool SymbolFileDWARF::ParseCompileUnitLineTable(const SymbolContext &sc) { dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_stmt_list, DW_INVALID_OFFSET); if (cu_line_offset != DW_INVALID_OFFSET) { - std::unique_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit)); + std::unique_ptr<LineTable> line_table_ap(new LineTable(&comp_unit)); if (line_table_ap.get()) { ParseDWARFLineTableCallbackInfo info; info.line_table = line_table_ap.get(); @@ -1053,9 +1078,7 @@ bool SymbolFileDWARF::ParseCompileUnitLineTable(const SymbolContext &sc) { * #0 * for MIPS. Use ArchSpec to clear the bit #0. */ - ArchSpec arch; - GetObjectFile()->GetArchitecture(arch); - switch (arch.GetMachine()) { + switch (GetObjectFile()->GetArchitecture().GetMachine()) { case llvm::Triple::mips: case llvm::Triple::mipsel: case llvm::Triple::mips64: @@ -1070,17 +1093,17 @@ bool SymbolFileDWARF::ParseCompileUnitLineTable(const SymbolContext &sc) { lldb::offset_t offset = cu_line_offset; DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, - &info); + &info, dwarf_cu); SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile(); if (debug_map_symfile) { // We have an object file that has a line table with addresses that // are not linked. We need to link the line table and convert the // addresses that are relative to the .o file into addresses for // the main executable. - sc.comp_unit->SetLineTable( + comp_unit.SetLineTable( debug_map_symfile->LinkOSOLineTable(this, line_table_ap.get())); } else { - sc.comp_unit->SetLineTable(line_table_ap.release()); + comp_unit.SetLineTable(line_table_ap.release()); return true; } } @@ -1112,10 +1135,10 @@ SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset) { return debug_macros_sp; } -bool SymbolFileDWARF::ParseCompileUnitDebugMacros(const SymbolContext &sc) { - assert(sc.comp_unit); +bool SymbolFileDWARF::ParseDebugMacros(CompileUnit &comp_unit) { + ASSERT_MODULE_LOCK(this); - DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); + DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); if (dwarf_cu == nullptr) return false; @@ -1131,16 +1154,14 @@ bool SymbolFileDWARF::ParseCompileUnitDebugMacros(const SymbolContext &sc) { if (sect_offset == DW_INVALID_OFFSET) return false; - sc.comp_unit->SetDebugMacros(ParseDebugMacros(§_offset)); + comp_unit.SetDebugMacros(ParseDebugMacros(§_offset)); return true; } -size_t SymbolFileDWARF::ParseFunctionBlocks(const SymbolContext &sc, - Block *parent_block, - const DWARFDIE &orig_die, - addr_t subprogram_low_pc, - uint32_t depth) { +size_t SymbolFileDWARF::ParseBlocksRecursive( + lldb_private::CompileUnit &comp_unit, Block *parent_block, + const DWARFDIE &orig_die, addr_t subprogram_low_pc, uint32_t depth) { size_t blocks_added = 0; DWARFDIE die = orig_die; while (die) { @@ -1219,13 +1240,13 @@ size_t SymbolFileDWARF::ParseFunctionBlocks(const SymbolContext &sc, std::unique_ptr<Declaration> decl_ap; if (decl_file != 0 || decl_line != 0 || decl_column != 0) decl_ap.reset(new Declaration( - sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), + comp_unit.GetSupportFiles().GetFileSpecAtIndex(decl_file), decl_line, decl_column)); std::unique_ptr<Declaration> call_ap; if (call_file != 0 || call_line != 0 || call_column != 0) call_ap.reset(new Declaration( - sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file), + comp_unit.GetSupportFiles().GetFileSpecAtIndex(call_file), call_line, call_column)); block->SetInlinedFunctionInfo(name, mangled_name, decl_ap.get(), @@ -1235,8 +1256,9 @@ size_t SymbolFileDWARF::ParseFunctionBlocks(const SymbolContext &sc, ++blocks_added; if (die.HasChildren()) { - blocks_added += ParseFunctionBlocks(sc, block, die.GetFirstChild(), - subprogram_low_pc, depth + 1); + blocks_added += + ParseBlocksRecursive(comp_unit, block, die.GetFirstChild(), + subprogram_low_pc, depth + 1); } } } break; @@ -1292,6 +1314,9 @@ void SymbolFileDWARF::ParseDeclsForContext(CompilerDeclContext decl_ctx) { } SymbolFileDWARF *SymbolFileDWARF::GetDWARFForUID(lldb::user_id_t uid) { + // This method can be called without going through the symbol vendor so we + // need to lock the module. + std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API we // must make sure we use the correct DWARF file when resolving things. On // MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple @@ -1308,6 +1333,9 @@ SymbolFileDWARF *SymbolFileDWARF::GetDWARFForUID(lldb::user_id_t uid) { DWARFDIE SymbolFileDWARF::GetDIEFromUID(lldb::user_id_t uid) { + // This method can be called without going through the symbol vendor so we + // need to lock the module. + std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API we // must make sure we use the correct DWARF file when resolving things. On // MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple @@ -1322,6 +1350,9 @@ SymbolFileDWARF::GetDIEFromUID(lldb::user_id_t uid) { } CompilerDecl SymbolFileDWARF::GetDeclForUID(lldb::user_id_t type_uid) { + // This method can be called without going through the symbol vendor so we + // need to lock the module. + std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); // Anytime we have a lldb::user_id_t, we must get the DIE by calling // SymbolFileDWARF::GetDIEFromUID(). See comments inside the // SymbolFileDWARF::GetDIEFromUID() for details. @@ -1333,6 +1364,9 @@ CompilerDecl SymbolFileDWARF::GetDeclForUID(lldb::user_id_t type_uid) { CompilerDeclContext SymbolFileDWARF::GetDeclContextForUID(lldb::user_id_t type_uid) { + // This method can be called without going through the symbol vendor so we + // need to lock the module. + std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); // Anytime we have a lldb::user_id_t, we must get the DIE by calling // SymbolFileDWARF::GetDIEFromUID(). See comments inside the // SymbolFileDWARF::GetDIEFromUID() for details. @@ -1344,6 +1378,9 @@ SymbolFileDWARF::GetDeclContextForUID(lldb::user_id_t type_uid) { CompilerDeclContext SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid) { + // This method can be called without going through the symbol vendor so we + // need to lock the module. + std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); // Anytime we have a lldb::user_id_t, we must get the DIE by calling // SymbolFileDWARF::GetDIEFromUID(). See comments inside the // SymbolFileDWARF::GetDIEFromUID() for details. @@ -1354,6 +1391,9 @@ SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid) { } Type *SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid) { + // This method can be called without going through the symbol vendor so we + // need to lock the module. + std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); // Anytime we have a lldb::user_id_t, we must get the DIE by calling // SymbolFileDWARF::GetDIEFromUID(). See comments inside the // SymbolFileDWARF::GetDIEFromUID() for details. @@ -1364,6 +1404,17 @@ Type *SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid) { return nullptr; } +llvm::Optional<SymbolFile::ArrayInfo> +SymbolFileDWARF::GetDynamicArrayInfoForUID( + lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) { + std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); + DWARFDIE type_die = GetDIEFromUID(type_uid); + if (type_die) + return DWARFASTParser::ParseChildArrayInfo(type_die, exe_ctx); + else + return llvm::None; +} + Type *SymbolFileDWARF::ResolveTypeUID(const DIERef &die_ref) { return ResolveType(GetDIE(die_ref), true); } @@ -1429,8 +1480,7 @@ bool SymbolFileDWARF::HasForwardDeclForClangType( } bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) { - std::lock_guard<std::recursive_mutex> guard( - GetObjectFile()->GetModule()->GetMutex()); + std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); ClangASTContext *clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(compiler_type.GetTypeSystem()); @@ -1525,7 +1575,7 @@ bool SymbolFileDWARF::GetFunction(const DWARFDIE &die, SymbolContext &sc) { sc.function = sc.comp_unit->FindFunctionByUID(die.GetID()).get(); if (sc.function == NULL) - sc.function = ParseCompileUnitFunction(sc, die); + sc.function = ParseFunction(*sc.comp_unit, die); if (sc.function) { sc.module_sp = sc.function->CalculateSymbolContextModule(); @@ -1578,18 +1628,20 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit( return dwo_symfile; } - FileSpec dwo_file(dwo_name, true); + FileSpec dwo_file(dwo_name); + FileSystem::Instance().Resolve(dwo_file); if (dwo_file.IsRelative()) { const char *comp_dir = cu_die.GetAttributeValueAsString( this, &dwarf_cu, DW_AT_comp_dir, nullptr); if (!comp_dir) return nullptr; - dwo_file.SetFile(comp_dir, true, FileSpec::Style::native); + dwo_file.SetFile(comp_dir, FileSpec::Style::native); + FileSystem::Instance().Resolve(dwo_file); dwo_file.AppendPathComponent(dwo_name); } - if (!dwo_file.Exists()) + if (!FileSystem::Instance().Exists(dwo_file)) return nullptr; const lldb::offset_t file_offset = 0; @@ -1597,7 +1649,8 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit( lldb::offset_t dwo_file_data_offset = 0; ObjectFileSP dwo_obj_file = ObjectFile::FindPlugin( GetObjectFile()->GetModule(), &dwo_file, file_offset, - dwo_file.GetByteSize(), dwo_file_data_sp, dwo_file_data_offset); + FileSystem::Instance().GetByteSize(dwo_file), dwo_file_data_sp, + dwo_file_data_offset); if (dwo_obj_file == nullptr) return nullptr; @@ -1616,7 +1669,7 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() { DWARFUnit *dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx); const DWARFBaseDIE die = dwarf_cu->GetUnitDIEOnly(); - if (die && die.HasChildren() == false) { + if (die && !die.HasChildren()) { const char *name = die.GetAttributeValueAsString(DW_AT_name, nullptr); if (name) { @@ -1628,14 +1681,15 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() { die.GetAttributeValueAsString(DW_AT_GNU_dwo_name, nullptr); if (dwo_path) { ModuleSpec dwo_module_spec; - dwo_module_spec.GetFileSpec().SetFile(dwo_path, false, + dwo_module_spec.GetFileSpec().SetFile(dwo_path, FileSpec::Style::native); if (dwo_module_spec.GetFileSpec().IsRelative()) { const char *comp_dir = die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr); if (comp_dir) { - dwo_module_spec.GetFileSpec().SetFile(comp_dir, true, + dwo_module_spec.GetFileSpec().SetFile(comp_dir, FileSpec::Style::native); + FileSystem::Instance().Resolve(dwo_module_spec.GetFileSpec()); dwo_module_spec.GetFileSpec().AppendPathComponent(dwo_path); } } @@ -1726,7 +1780,7 @@ SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() { } uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr, - uint32_t resolve_scope, + SymbolContextItem resolve_scope, SymbolContext &sc) { static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, @@ -1784,7 +1838,7 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr, sc.function = sc.comp_unit->FindFunctionByUID(function_die.GetID()).get(); if (sc.function == NULL) - sc.function = ParseCompileUnitFunction(sc, function_die); + sc.function = ParseFunction(*sc.comp_unit, function_die); if (sc.function && (resolve_scope & eSymbolContextBlock)) block_die = function_die.LookupDeepestBlock(file_vm_addr); @@ -1860,7 +1914,7 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr, uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec, uint32_t line, bool check_inlines, - uint32_t resolve_scope, + SymbolContextItem resolve_scope, SymbolContextList &sc_list) { const uint32_t prev_size = sc_list.GetSize(); if (resolve_scope & eSymbolContextCompUnit) { @@ -1925,7 +1979,7 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec, .get(); if (sc.function == NULL) sc.function = - ParseCompileUnitFunction(sc, function_die); + ParseFunction(*sc.comp_unit, function_die); if (sc.function && (resolve_scope & eSymbolContextBlock)) @@ -1975,11 +2029,17 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec, } void SymbolFileDWARF::PreloadSymbols() { - std::lock_guard<std::recursive_mutex> guard( - GetObjectFile()->GetModule()->GetMutex()); + std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); m_index->Preload(); } +std::recursive_mutex &SymbolFileDWARF::GetModuleMutex() const { + lldb::ModuleSP module_sp(m_debug_map_module_wp.lock()); + if (module_sp) + return module_sp->GetMutex(); + return GetObjectFile()->GetModule()->GetMutex(); +} + bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile( const lldb_private::CompilerDeclContext *decl_ctx) { if (decl_ctx == nullptr || !decl_ctx->IsValid()) { @@ -2195,7 +2255,7 @@ bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die, sc.block = function_block.FindBlockByID(inlined_die.GetID()); if (sc.block == NULL) sc.block = function_block.FindBlockByID(inlined_die.GetOffset()); - if (sc.block == NULL || sc.block->GetStartAddress(addr) == false) + if (sc.block == NULL || !sc.block->GetStartAddress(addr)) addr.Clear(); } else { sc.block = NULL; @@ -2231,11 +2291,10 @@ bool SymbolFileDWARF::DIEInDeclContext(const CompilerDeclContext *decl_ctx, return false; } -uint32_t -SymbolFileDWARF::FindFunctions(const ConstString &name, - const CompilerDeclContext *parent_decl_ctx, - uint32_t name_type_mask, bool include_inlines, - bool append, SymbolContextList &sc_list) { +uint32_t SymbolFileDWARF::FindFunctions( + const ConstString &name, const CompilerDeclContext *parent_decl_ctx, + FunctionNameType name_type_mask, bool include_inlines, bool append, + SymbolContextList &sc_list) { static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, "SymbolFileDWARF::FindFunctions (name = '%s')", name.AsCString()); @@ -2378,9 +2437,8 @@ void SymbolFileDWARF::GetMangledNamesForFunction( } uint32_t SymbolFileDWARF::FindTypes( - const SymbolContext &sc, const ConstString &name, - const CompilerDeclContext *parent_decl_ctx, bool append, - uint32_t max_matches, + const ConstString &name, const CompilerDeclContext *parent_decl_ctx, + bool append, uint32_t max_matches, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, TypeMap &types) { // If we aren't appending the results to this list, then clear the list @@ -2469,8 +2527,8 @@ uint32_t SymbolFileDWARF::FindTypes( SymbolVendor *sym_vendor = external_module_sp->GetSymbolVendor(); if (sym_vendor) { const uint32_t num_external_matches = - sym_vendor->FindTypes(sc, name, parent_decl_ctx, append, - max_matches, searched_symbol_files, types); + sym_vendor->FindTypes(name, parent_decl_ctx, append, max_matches, + searched_symbol_files, types); if (num_external_matches) return num_external_matches; } @@ -2506,7 +2564,7 @@ size_t SymbolFileDWARF::FindTypes(const std::vector<CompilerContext> &context, if (die) { std::vector<CompilerContext> die_context; - die.GetDWOContext(die_context); + die.GetDeclContext(die_context); if (die_context != context) continue; @@ -2528,7 +2586,7 @@ size_t SymbolFileDWARF::FindTypes(const std::vector<CompilerContext> &context, } CompilerDeclContext -SymbolFileDWARF::FindNamespace(const SymbolContext &sc, const ConstString &name, +SymbolFileDWARF::FindNamespace(const ConstString &name, const CompilerDeclContext *parent_decl_ctx) { Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); @@ -3065,39 +3123,36 @@ size_t SymbolFileDWARF::ParseTypes(const SymbolContext &sc, return types_added; } -size_t SymbolFileDWARF::ParseFunctionBlocks(const SymbolContext &sc) { - assert(sc.comp_unit && sc.function); +size_t SymbolFileDWARF::ParseBlocksRecursive(Function &func) { + ASSERT_MODULE_LOCK(this); + CompileUnit *comp_unit = func.GetCompileUnit(); + lldbassert(comp_unit); + + DWARFUnit *dwarf_cu = GetDWARFCompileUnit(comp_unit); + if (!dwarf_cu) + return 0; + size_t functions_added = 0; - DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); - if (dwarf_cu) { - const dw_offset_t function_die_offset = sc.function->GetID(); - DWARFDIE function_die = dwarf_cu->GetDIE(function_die_offset); - if (function_die) { - ParseFunctionBlocks(sc, &sc.function->GetBlock(false), function_die, - LLDB_INVALID_ADDRESS, 0); - } + const dw_offset_t function_die_offset = func.GetID(); + DWARFDIE function_die = dwarf_cu->GetDIE(function_die_offset); + if (function_die) { + ParseBlocksRecursive(*comp_unit, &func.GetBlock(false), function_die, + LLDB_INVALID_ADDRESS, 0); } return functions_added; } -size_t SymbolFileDWARF::ParseTypes(const SymbolContext &sc) { - // At least a compile unit must be valid - assert(sc.comp_unit); +size_t SymbolFileDWARF::ParseTypes(CompileUnit &comp_unit) { + ASSERT_MODULE_LOCK(this); size_t types_added = 0; - DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); + DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); if (dwarf_cu) { - if (sc.function) { - dw_offset_t function_die_offset = sc.function->GetID(); - DWARFDIE func_die = dwarf_cu->GetDIE(function_die_offset); - if (func_die && func_die.HasChildren()) { - types_added = ParseTypes(sc, func_die.GetFirstChild(), true, true); - } - } else { - DWARFDIE dwarf_cu_die = dwarf_cu->DIE(); - if (dwarf_cu_die && dwarf_cu_die.HasChildren()) { - types_added = ParseTypes(sc, dwarf_cu_die.GetFirstChild(), true, true); - } + DWARFDIE dwarf_cu_die = dwarf_cu->DIE(); + if (dwarf_cu_die && dwarf_cu_die.HasChildren()) { + SymbolContext sc; + sc.comp_unit = &comp_unit; + types_added = ParseTypes(sc, dwarf_cu_die.GetFirstChild(), true, true); } } @@ -3105,6 +3160,7 @@ size_t SymbolFileDWARF::ParseTypes(const SymbolContext &sc) { } size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) { + ASSERT_MODULE_LOCK(this); if (sc.comp_unit != NULL) { DWARFDebugInfo *info = DebugInfo(); if (info == NULL) @@ -3298,7 +3354,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, uint32_t block_length = form_value.Unsigned(); location.CopyOpcodeData(module, data, block_offset, block_length); } else { - const DWARFDataExtractor &debug_loc_data = get_debug_loc_data(); + const DWARFDataExtractor &debug_loc_data = DebugLocData(); const dw_offset_t debug_loc_offset = form_value.Unsigned(); size_t loc_list_length = DWARFExpression::LocationListSize( @@ -3319,22 +3375,10 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, case DW_AT_start_scope: { if (form_value.Form() == DW_FORM_sec_offset) { DWARFRangeList dwarf_scope_ranges; - const DWARFDebugRanges *debug_ranges = DebugRanges(); - debug_ranges->FindRanges(die.GetCU()->GetRangesBase(), + const DWARFDebugRangesBase *debug_ranges = DebugRanges(); + debug_ranges->FindRanges(die.GetCU(), form_value.Unsigned(), dwarf_scope_ranges); - - // All DW_AT_start_scope are relative to the base address of the - // compile unit. We add the compile unit base address to make - // sure all the addresses are properly fixed up. - for (size_t i = 0, count = dwarf_scope_ranges.GetSize(); - i < count; ++i) { - const DWARFRangeList::Entry &range = - dwarf_scope_ranges.GetEntryRef(i); - scope_ranges.Append(range.GetRangeBase() + - die.GetCU()->GetBaseAddress(), - range.GetByteSize()); - } } else { // TODO: Handle the case when DW_AT_start_scope have form // constant. The @@ -3436,6 +3480,11 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, is_static_lifetime = true; } SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile(); + if (debug_map_symfile) + // Set the module of the expression to the linked module + // instead of the oject file so the relocated address can be + // found there. + location.SetModule(debug_map_symfile->GetObjectFile()->GetModule()); if (is_static_lifetime) { if (is_external) @@ -3736,6 +3785,60 @@ size_t SymbolFileDWARF::ParseVariables(const SymbolContext &sc, return vars_added; } +/// Collect call graph edges present in a function DIE. +static std::vector<lldb_private::CallEdge> +CollectCallEdges(DWARFDIE function_die) { + // Check if the function has a supported call site-related attribute. + // TODO: In the future it may be worthwhile to support call_all_source_calls. + uint64_t has_call_edges = + function_die.GetAttributeValueAsUnsigned(DW_AT_call_all_calls, 0); + if (!has_call_edges) + return {}; + + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + LLDB_LOG(log, "CollectCallEdges: Found call site info in {0}", + function_die.GetPubname()); + + // Scan the DIE for TAG_call_site entries. + // TODO: A recursive scan of all blocks in the subprogram is needed in order + // to be DWARF5-compliant. This may need to be done lazily to be performant. + // For now, assume that all entries are nested directly under the subprogram + // (this is the kind of DWARF LLVM produces) and parse them eagerly. + std::vector<CallEdge> call_edges; + for (DWARFDIE child = function_die.GetFirstChild(); child.IsValid(); + child = child.GetSibling()) { + if (child.Tag() != DW_TAG_call_site) + continue; + + // Extract DW_AT_call_origin (the call target's DIE). + DWARFDIE call_origin = child.GetReferencedDIE(DW_AT_call_origin); + if (!call_origin.IsValid()) { + LLDB_LOG(log, "CollectCallEdges: Invalid call origin in {0}", + function_die.GetPubname()); + continue; + } + + // Extract DW_AT_call_return_pc (the PC the call returns to) if it's + // available. It should only ever be unavailable for tail call edges, in + // which case use LLDB_INVALID_ADDRESS. + addr_t return_pc = child.GetAttributeValueAsAddress(DW_AT_call_return_pc, + LLDB_INVALID_ADDRESS); + + LLDB_LOG(log, "CollectCallEdges: Found call origin: {0} (retn-PC: {1:x})", + call_origin.GetPubname(), return_pc); + call_edges.emplace_back(call_origin.GetMangledName(), return_pc); + } + return call_edges; +} + +std::vector<lldb_private::CallEdge> +SymbolFileDWARF::ParseCallEdgesInFunction(UserID func_id) { + DWARFDIE func_die = GetDIEFromUID(func_id.GetID()); + if (func_die.IsValid()) + return CollectCallEdges(func_die); + return {}; +} + //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ @@ -3745,6 +3848,14 @@ uint32_t SymbolFileDWARF::GetPluginVersion() { return 1; } void SymbolFileDWARF::Dump(lldb_private::Stream &s) { m_index->Dump(s); } +void SymbolFileDWARF::DumpClangAST(Stream &s) { + TypeSystem *ts = GetTypeSystemForLanguage(eLanguageTypeC_plus_plus); + ClangASTContext *clang = llvm::dyn_cast_or_null<ClangASTContext>(ts); + if (!clang) + return; + clang->Dump(s); +} + SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() { if (m_debug_map_symfile == NULL && !m_debug_map_module_wp.expired()) { lldb::ModuleSP module_sp(m_debug_map_module_wp.lock()); @@ -3760,6 +3871,8 @@ SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() { DWARFExpression::LocationListFormat SymbolFileDWARF::GetLocationListFormat() const { + if (m_data_debug_loclists.m_data.GetByteSize() > 0) + return DWARFExpression::LocLists; return DWARFExpression::RegularLocationList; } @@ -3768,9 +3881,9 @@ SymbolFileDWARFDwp *SymbolFileDWARF::GetDwpSymbolFile() { ModuleSpec module_spec; module_spec.GetFileSpec() = m_obj_file->GetFileSpec(); module_spec.GetSymbolFileSpec() = - FileSpec(m_obj_file->GetFileSpec().GetPath() + ".dwp", false); + FileSpec(m_obj_file->GetFileSpec().GetPath() + ".dwp"); FileSpec dwp_filespec = Symbols::LocateExecutableSymbolFile(module_spec); - if (dwp_filespec.Exists()) { + if (FileSystem::Instance().Exists(dwp_filespec)) { m_dwp_symfile = SymbolFileDWARFDwp::Create(GetObjectFile()->GetModule(), dwp_filespec); } diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index a5f2ac8f3e7d..d351289f8b51 100644 --- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -10,8 +10,6 @@ #ifndef SymbolFileDWARF_SymbolFileDWARF_h_ #define SymbolFileDWARF_SymbolFileDWARF_h_ -// C Includes -// C++ Includes #include <list> #include <map> #include <mutex> @@ -19,7 +17,6 @@ #include <unordered_map> #include <vector> -// Other libraries and framework includes #include "llvm/ADT/DenseMap.h" #include "llvm/Support/Threading.h" @@ -35,7 +32,6 @@ #include "lldb/Utility/ConstString.h" #include "lldb/lldb-private.h" -// Project includes #include "DWARFDataExtractor.h" #include "DWARFDefines.h" #include "DWARFIndex.h" @@ -53,7 +49,7 @@ class DWARFDebugAranges; class DWARFDebugInfo; class DWARFDebugInfoEntry; class DWARFDebugLine; -class DWARFDebugRanges; +class DWARFDebugRangesBase; class DWARFDeclContext; class DWARFDIECollection; class DWARFFormValue; @@ -73,9 +69,6 @@ public: friend class DWARFUnit; friend class DWARFDIE; friend class DWARFASTParserClang; - friend class DWARFASTParserGo; - friend class DWARFASTParserJava; - friend class DWARFASTParserOCaml; //------------------------------------------------------------------ // Static Functions @@ -114,36 +107,34 @@ public: lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override; lldb::LanguageType - ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) override; + ParseLanguage(lldb_private::CompileUnit &comp_unit) override; - size_t - ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc) override; + size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override; - bool - ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc) override; + bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override; - bool - ParseCompileUnitDebugMacros(const lldb_private::SymbolContext &sc) override; + bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override; - bool ParseCompileUnitSupportFiles( - const lldb_private::SymbolContext &sc, - lldb_private::FileSpecList &support_files) override; + bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit, + lldb_private::FileSpecList &support_files) override; - bool - ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc) override; + bool ParseIsOptimized(lldb_private::CompileUnit &comp_unit) override; + + size_t ParseTypes(lldb_private::CompileUnit &comp_unit) override; bool ParseImportedModules( const lldb_private::SymbolContext &sc, std::vector<lldb_private::ConstString> &imported_modules) override; - size_t ParseFunctionBlocks(const lldb_private::SymbolContext &sc) override; - - size_t ParseTypes(const lldb_private::SymbolContext &sc) override; + size_t ParseBlocksRecursive(lldb_private::Function &func) override; size_t ParseVariablesForContext(const lldb_private::SymbolContext &sc) override; lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override; + llvm::Optional<ArrayInfo> GetDynamicArrayInfoForUID( + lldb::user_id_t type_uid, + const lldb_private::ExecutionContext *exe_ctx) override; bool CompleteType(lldb_private::CompilerType &compiler_type) override; @@ -168,12 +159,13 @@ public: ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override; uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr, - uint32_t resolve_scope, + lldb::SymbolContextItem resolve_scope, lldb_private::SymbolContext &sc) override; uint32_t ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line, - bool check_inlines, uint32_t resolve_scope, + bool check_inlines, + lldb::SymbolContextItem resolve_scope, lldb_private::SymbolContextList &sc_list) override; uint32_t @@ -189,8 +181,8 @@ public: uint32_t FindFunctions(const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, - uint32_t name_type_mask, bool include_inlines, bool append, - lldb_private::SymbolContextList &sc_list) override; + lldb::FunctionNameType name_type_mask, bool include_inlines, + bool append, lldb_private::SymbolContextList &sc_list) override; uint32_t FindFunctions(const lldb_private::RegularExpression ®ex, bool include_inlines, bool append, @@ -201,8 +193,7 @@ public: std::vector<lldb_private::ConstString> &mangled_names) override; uint32_t - FindTypes(const lldb_private::SymbolContext &sc, - const lldb_private::ConstString &name, + FindTypes(const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, @@ -214,19 +205,20 @@ public: lldb_private::TypeList *GetTypeList() override; size_t GetTypes(lldb_private::SymbolContextScope *sc_scope, - uint32_t type_mask, + lldb::TypeClass type_mask, lldb_private::TypeList &type_list) override; lldb_private::TypeSystem * GetTypeSystemForLanguage(lldb::LanguageType language) override; lldb_private::CompilerDeclContext FindNamespace( - const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx) override; void PreloadSymbols() override; + std::recursive_mutex &GetModuleMutex() const override; + //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ @@ -234,17 +226,20 @@ public: uint32_t GetPluginVersion() override; - const lldb_private::DWARFDataExtractor &get_debug_abbrev_data(); - const lldb_private::DWARFDataExtractor &get_debug_addr_data(); + virtual const lldb_private::DWARFDataExtractor &get_debug_abbrev_data(); + virtual const lldb_private::DWARFDataExtractor &get_debug_addr_data(); const lldb_private::DWARFDataExtractor &get_debug_aranges_data(); const lldb_private::DWARFDataExtractor &get_debug_frame_data(); - const lldb_private::DWARFDataExtractor &get_debug_info_data(); + virtual const lldb_private::DWARFDataExtractor &get_debug_info_data(); const lldb_private::DWARFDataExtractor &get_debug_line_data(); + const lldb_private::DWARFDataExtractor &get_debug_line_str_data(); const lldb_private::DWARFDataExtractor &get_debug_macro_data(); const lldb_private::DWARFDataExtractor &get_debug_loc_data(); + const lldb_private::DWARFDataExtractor &get_debug_loclists_data(); const lldb_private::DWARFDataExtractor &get_debug_ranges_data(); - const lldb_private::DWARFDataExtractor &get_debug_str_data(); - const lldb_private::DWARFDataExtractor &get_debug_str_offsets_data(); + const lldb_private::DWARFDataExtractor &get_debug_rnglists_data(); + virtual const lldb_private::DWARFDataExtractor &get_debug_str_data(); + virtual const lldb_private::DWARFDataExtractor &get_debug_str_offsets_data(); const lldb_private::DWARFDataExtractor &get_debug_types_data(); const lldb_private::DWARFDataExtractor &get_apple_names_data(); const lldb_private::DWARFDataExtractor &get_apple_types_data(); @@ -260,9 +255,11 @@ public: const DWARFDebugInfo *DebugInfo() const; - DWARFDebugRanges *DebugRanges(); + DWARFDebugRangesBase *DebugRanges(); - const DWARFDebugRanges *DebugRanges() const; + const DWARFDebugRangesBase *DebugRanges() const; + + const lldb_private::DWARFDataExtractor &DebugLocData(); static bool SupportedVersion(uint16_t version); @@ -316,8 +313,13 @@ public: DIEInDeclContext(const lldb_private::CompilerDeclContext *parent_decl_ctx, const DWARFDIE &die); + std::vector<lldb_private::CallEdge> + ParseCallEdgesInFunction(UserID func_id) override; + void Dump(lldb_private::Stream &s) override; + void DumpClangAST(lldb_private::Stream &s) override; + protected: typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *> DIEToTypePtr; @@ -352,14 +354,13 @@ protected: bool GetFunction(const DWARFDIE &die, lldb_private::SymbolContext &sc); - lldb_private::Function * - ParseCompileUnitFunction(const lldb_private::SymbolContext &sc, - const DWARFDIE &die); + lldb_private::Function *ParseFunction(lldb_private::CompileUnit &comp_unit, + const DWARFDIE &die); - size_t ParseFunctionBlocks(const lldb_private::SymbolContext &sc, - lldb_private::Block *parent_block, - const DWARFDIE &die, - lldb::addr_t subprogram_low_pc, uint32_t depth); + size_t ParseBlocksRecursive(lldb_private::CompileUnit &comp_unit, + lldb_private::Block *parent_block, + const DWARFDIE &die, + lldb::addr_t subprogram_low_pc, uint32_t depth); size_t ParseTypes(const lldb_private::SymbolContext &sc, const DWARFDIE &die, bool parse_siblings, bool parse_children); @@ -466,9 +467,12 @@ protected: DWARFDataSegment m_data_debug_frame; DWARFDataSegment m_data_debug_info; DWARFDataSegment m_data_debug_line; + DWARFDataSegment m_data_debug_line_str; DWARFDataSegment m_data_debug_macro; DWARFDataSegment m_data_debug_loc; + DWARFDataSegment m_data_debug_loclists; DWARFDataSegment m_data_debug_ranges; + DWARFDataSegment m_data_debug_rnglists; DWARFDataSegment m_data_debug_str; DWARFDataSegment m_data_debug_str_offsets; DWARFDataSegment m_data_debug_types; @@ -498,7 +502,7 @@ protected: typedef std::shared_ptr<std::set<DIERef>> DIERefSetSP; typedef std::unordered_map<std::string, DIERefSetSP> NameToOffsetMap; NameToOffsetMap m_function_scope_qualified_name_map; - std::unique_ptr<DWARFDebugRanges> m_ranges; + std::unique_ptr<DWARFDebugRangesBase> m_ranges; UniqueDWARFASTTypeMap m_unique_ast_type_map; DIEToTypePtr m_die_to_type; DIEToVariableSP m_die_to_variable_sp; diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp index 39c70d146524..2c1e6416a935 100644 --- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "SymbolFileDWARFDebugMap.h" #include "DWARFDebugAranges.h" @@ -90,11 +86,10 @@ SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap( const uint32_t oso_end_idx = comp_unit_info->last_symbol_index + 1; for (uint32_t idx = comp_unit_info->first_symbol_index + 2; // Skip the N_SO and N_OSO - idx < oso_end_idx; - ++idx) { + idx < oso_end_idx; ++idx) { Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx); if (exe_symbol) { - if (exe_symbol->IsDebug() == false) + if (!exe_symbol->IsDebug()) continue; switch (exe_symbol->GetType()) { @@ -184,7 +179,7 @@ public: GetSymbolVendor(bool can_create = true, lldb_private::Stream *feedback_strm = NULL) override { // Scope for locker - if (m_symfile_ap.get() || can_create == false) + if (m_symfile_ap.get() || !can_create) return m_symfile_ap.get(); ModuleSP exe_module_sp(m_exe_module_wp.lock()); @@ -351,7 +346,7 @@ void SymbolFileDWARFDebugMap::InitOSO() { so_symbol->GetType() == eSymbolTypeSourceFile && oso_symbol->GetType() == eSymbolTypeObjectFile) { m_compile_unit_infos[i].so_file.SetFile( - so_symbol->GetName().AsCString(), false, FileSpec::Style::native); + so_symbol->GetName().AsCString(), FileSpec::Style::native); m_compile_unit_infos[i].oso_path = oso_symbol->GetName(); m_compile_unit_infos[i].oso_mod_time = llvm::sys::toTimePoint(oso_symbol->GetIntegerValue(0)); @@ -421,10 +416,13 @@ Module *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo( m_oso_map[{comp_unit_info->oso_path, comp_unit_info->oso_mod_time}] = comp_unit_info->oso_sp; const char *oso_path = comp_unit_info->oso_path.GetCString(); - FileSpec oso_file(oso_path, false); + FileSpec oso_file(oso_path); ConstString oso_object; - if (oso_file.Exists()) { - auto oso_mod_time = FileSystem::GetModificationTime(oso_file); + if (FileSystem::Instance().Exists(oso_file)) { + // The modification time returned by the FS can have a higher precision + // than the one from the CU. + auto oso_mod_time = std::chrono::time_point_cast<std::chrono::seconds>( + FileSystem::Instance().GetModificationTime(oso_file)); if (oso_mod_time != comp_unit_info->oso_mod_time) { obj_file->GetModule()->ReportError( "debug map object file '%s' has changed (actual time is " @@ -490,7 +488,12 @@ ObjectFile *SymbolFileDWARFDebugMap::GetObjectFileByOSOIndex(uint32_t oso_idx) { SymbolFileDWARF * SymbolFileDWARFDebugMap::GetSymbolFile(const SymbolContext &sc) { - CompileUnitInfo *comp_unit_info = GetCompUnitInfo(sc); + return GetSymbolFile(*sc.comp_unit); +} + +SymbolFileDWARF * +SymbolFileDWARFDebugMap::GetSymbolFile(const CompileUnit &comp_unit) { + CompileUnitInfo *comp_unit_info = GetCompUnitInfo(comp_unit); if (comp_unit_info) return GetSymbolFileByCompUnitInfo(comp_unit_info); return NULL; @@ -518,7 +521,8 @@ uint32_t SymbolFileDWARFDebugMap::GetCompUnitInfoIndex( SymbolFileDWARF * SymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex(uint32_t oso_idx) { - if (oso_idx < m_compile_unit_infos.size()) + unsigned size = m_compile_unit_infos.size(); + if (oso_idx < size) return GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[oso_idx]); return NULL; } @@ -597,9 +601,14 @@ CompUnitSP SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx) { SymbolFileDWARFDebugMap::CompileUnitInfo * SymbolFileDWARFDebugMap::GetCompUnitInfo(const SymbolContext &sc) { + return GetCompUnitInfo(*sc.comp_unit); +} + +SymbolFileDWARFDebugMap::CompileUnitInfo * +SymbolFileDWARFDebugMap::GetCompUnitInfo(const CompileUnit &comp_unit) { const uint32_t cu_count = GetNumCompileUnits(); for (uint32_t i = 0; i < cu_count; ++i) { - if (sc.comp_unit == m_compile_unit_infos[i].compile_unit_sp.get()) + if (comp_unit == m_compile_unit_infos[i].compile_unit_sp.get()) return &m_compile_unit_infos[i]; } return NULL; @@ -617,50 +626,46 @@ size_t SymbolFileDWARFDebugMap::GetCompUnitInfosForModule( } lldb::LanguageType -SymbolFileDWARFDebugMap::ParseCompileUnitLanguage(const SymbolContext &sc) { - SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); +SymbolFileDWARFDebugMap::ParseLanguage(CompileUnit &comp_unit) { + SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit); if (oso_dwarf) - return oso_dwarf->ParseCompileUnitLanguage(sc); + return oso_dwarf->ParseLanguage(comp_unit); return eLanguageTypeUnknown; } -size_t -SymbolFileDWARFDebugMap::ParseCompileUnitFunctions(const SymbolContext &sc) { - SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); +size_t SymbolFileDWARFDebugMap::ParseFunctions(CompileUnit &comp_unit) { + SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit); if (oso_dwarf) - return oso_dwarf->ParseCompileUnitFunctions(sc); + return oso_dwarf->ParseFunctions(comp_unit); return 0; } -bool SymbolFileDWARFDebugMap::ParseCompileUnitLineTable( - const SymbolContext &sc) { - SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); +bool SymbolFileDWARFDebugMap::ParseLineTable(CompileUnit &comp_unit) { + SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit); if (oso_dwarf) - return oso_dwarf->ParseCompileUnitLineTable(sc); + return oso_dwarf->ParseLineTable(comp_unit); return false; } -bool SymbolFileDWARFDebugMap::ParseCompileUnitDebugMacros( - const SymbolContext &sc) { - SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); +bool SymbolFileDWARFDebugMap::ParseDebugMacros(CompileUnit &comp_unit) { + SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit); if (oso_dwarf) - return oso_dwarf->ParseCompileUnitDebugMacros(sc); + return oso_dwarf->ParseDebugMacros(comp_unit); return false; } -bool SymbolFileDWARFDebugMap::ParseCompileUnitSupportFiles( - const SymbolContext &sc, FileSpecList &support_files) { - SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); +bool SymbolFileDWARFDebugMap::ParseSupportFiles(CompileUnit &comp_unit, + FileSpecList &support_files) { + SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit); if (oso_dwarf) - return oso_dwarf->ParseCompileUnitSupportFiles(sc, support_files); + return oso_dwarf->ParseSupportFiles(comp_unit, support_files); return false; } -bool SymbolFileDWARFDebugMap::ParseCompileUnitIsOptimized( - const lldb_private::SymbolContext &sc) { - SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); +bool SymbolFileDWARFDebugMap::ParseIsOptimized(CompileUnit &comp_unit) { + SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit); if (oso_dwarf) - return oso_dwarf->ParseCompileUnitIsOptimized(sc); + return oso_dwarf->ParseIsOptimized(comp_unit); return false; } @@ -672,17 +677,21 @@ bool SymbolFileDWARFDebugMap::ParseImportedModules( return false; } -size_t SymbolFileDWARFDebugMap::ParseFunctionBlocks(const SymbolContext &sc) { - SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); +size_t SymbolFileDWARFDebugMap::ParseBlocksRecursive(Function &func) { + CompileUnit *comp_unit = func.GetCompileUnit(); + if (!comp_unit) + return 0; + + SymbolFileDWARF *oso_dwarf = GetSymbolFile(*comp_unit); if (oso_dwarf) - return oso_dwarf->ParseFunctionBlocks(sc); + return oso_dwarf->ParseBlocksRecursive(func); return 0; } -size_t SymbolFileDWARFDebugMap::ParseTypes(const SymbolContext &sc) { - SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); +size_t SymbolFileDWARFDebugMap::ParseTypes(CompileUnit &comp_unit) { + SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit); if (oso_dwarf) - return oso_dwarf->ParseTypes(sc); + return oso_dwarf->ParseTypes(comp_unit); return 0; } @@ -702,6 +711,16 @@ Type *SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid) { return NULL; } +llvm::Optional<SymbolFile::ArrayInfo> +SymbolFileDWARFDebugMap::GetDynamicArrayInfoForUID( + lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) { + const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid); + SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx); + if (oso_dwarf) + return oso_dwarf->GetDynamicArrayInfoForUID(type_uid, exe_ctx); + return llvm::None; +} + bool SymbolFileDWARFDebugMap::CompleteType(CompilerType &compiler_type) { bool success = false; if (compiler_type) { @@ -717,8 +736,10 @@ bool SymbolFileDWARFDebugMap::CompleteType(CompilerType &compiler_type) { return success; } -uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext( - const Address &exe_so_addr, uint32_t resolve_scope, SymbolContext &sc) { +uint32_t +SymbolFileDWARFDebugMap::ResolveSymbolContext(const Address &exe_so_addr, + SymbolContextItem resolve_scope, + SymbolContext &sc) { uint32_t resolved_flags = 0; Symtab *symtab = m_obj_file->GetSymtab(); if (symtab) { @@ -760,7 +781,7 @@ uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext( uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext( const FileSpec &file_spec, uint32_t line, bool check_inlines, - uint32_t resolve_scope, SymbolContextList &sc_list) { + SymbolContextItem resolve_scope, SymbolContextList &sc_list) { const uint32_t initial = sc_list.GetSize(); const uint32_t cu_count = GetNumCompileUnits(); @@ -792,8 +813,7 @@ uint32_t SymbolFileDWARFDebugMap::PrivateFindGlobalVariables( const ConstString &name, const CompilerDeclContext *parent_decl_ctx, const std::vector<uint32_t> &indexes, // Indexes into the symbol table that match "name" - uint32_t max_matches, - VariableList &variables) { + uint32_t max_matches, VariableList &variables) { const uint32_t original_size = variables.GetSize(); const size_t match_count = indexes.size(); for (size_t i = 0; i < match_count; ++i) { @@ -977,7 +997,7 @@ static void RemoveFunctionsWithModuleNotEqualTo(const ModuleSP &module_sp, uint32_t SymbolFileDWARFDebugMap::FindFunctions( const ConstString &name, const CompilerDeclContext *parent_decl_ctx, - uint32_t name_type_mask, bool include_inlines, bool append, + FunctionNameType name_type_mask, bool include_inlines, bool append, SymbolContextList &sc_list) { static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, @@ -1032,7 +1052,7 @@ uint32_t SymbolFileDWARFDebugMap::FindFunctions(const RegularExpression ®ex, } size_t SymbolFileDWARFDebugMap::GetTypes(SymbolContextScope *sc_scope, - uint32_t type_mask, + lldb::TypeClass type_mask, TypeList &type_list) { static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, @@ -1060,6 +1080,15 @@ size_t SymbolFileDWARFDebugMap::GetTypes(SymbolContextScope *sc_scope, return type_list.GetSize() - initial_size; } +std::vector<lldb_private::CallEdge> +SymbolFileDWARFDebugMap::ParseCallEdgesInFunction(UserID func_id) { + uint32_t oso_idx = GetOSOIndexFromUserID(func_id.GetID()); + SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx); + if (oso_dwarf) + return oso_dwarf->ParseCallEdgesInFunction(func_id); + return {}; +} + TypeSP SymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext( const DWARFDeclContext &die_decl_ctx) { TypeSP type_sp; @@ -1136,7 +1165,7 @@ TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE( // Only search all .o files for the definition if we don't need the // implementation because otherwise, with a valid debug map we should have // the ObjC class symbol and the code above should have found it. - if (must_be_implementation == false) { + if (!must_be_implementation) { TypeSP type_sp; ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { @@ -1151,32 +1180,20 @@ TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE( } uint32_t SymbolFileDWARFDebugMap::FindTypes( - const SymbolContext &sc, const ConstString &name, - const CompilerDeclContext *parent_decl_ctx, bool append, - uint32_t max_matches, + const ConstString &name, const CompilerDeclContext *parent_decl_ctx, + bool append, uint32_t max_matches, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, TypeMap &types) { if (!append) types.Clear(); const uint32_t initial_types_size = types.GetSize(); - SymbolFileDWARF *oso_dwarf; - if (sc.comp_unit) { - oso_dwarf = GetSymbolFile(sc); - if (oso_dwarf) - return oso_dwarf->FindTypes(sc, name, parent_decl_ctx, append, - max_matches, searched_symbol_files, types); - } else { - ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { - oso_dwarf->FindTypes(sc, name, parent_decl_ctx, append, max_matches, - searched_symbol_files, types); - if (types.GetSize() >= max_matches) - return true; - else - return false; - }); - } + ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { + oso_dwarf->FindTypes(name, parent_decl_ctx, append, max_matches, + searched_symbol_files, types); + return types.GetSize() >= max_matches; + }); return types.GetSize() - initial_types_size; } @@ -1195,27 +1212,26 @@ uint32_t SymbolFileDWARFDebugMap::FindTypes( //} CompilerDeclContext SymbolFileDWARFDebugMap::FindNamespace( - const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name, const CompilerDeclContext *parent_decl_ctx) { CompilerDeclContext matching_namespace; - SymbolFileDWARF *oso_dwarf; - if (sc.comp_unit) { - oso_dwarf = GetSymbolFile(sc); - if (oso_dwarf) - matching_namespace = oso_dwarf->FindNamespace(sc, name, parent_decl_ctx); - } else { - ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { - matching_namespace = oso_dwarf->FindNamespace(sc, name, parent_decl_ctx); + ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { + matching_namespace = oso_dwarf->FindNamespace(name, parent_decl_ctx); - return (bool)matching_namespace; - }); - } + return (bool)matching_namespace; + }); return matching_namespace; } +void SymbolFileDWARFDebugMap::DumpClangAST(Stream &s) { + ForEachSymbolFile([&s](SymbolFileDWARF *oso_dwarf) -> bool { + oso_dwarf->DumpClangAST(s); + return true; + }); +} + //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h index 550f74a203ea..176eadeeca71 100644 --- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h +++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h @@ -56,27 +56,33 @@ public: lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override; lldb::LanguageType - ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) override; - size_t - ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc) override; - bool - ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc) override; - bool - ParseCompileUnitDebugMacros(const lldb_private::SymbolContext &sc) override; - bool ParseCompileUnitSupportFiles( - const lldb_private::SymbolContext &sc, - lldb_private::FileSpecList &support_files) override; - bool - ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc) override; + ParseLanguage(lldb_private::CompileUnit &comp_unit) override; + + size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override; + + bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override; + + bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override; + + bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit, + lldb_private::FileSpecList &support_files) override; + + bool ParseIsOptimized(lldb_private::CompileUnit &comp_unit) override; + + size_t ParseTypes(lldb_private::CompileUnit &comp_unit) override; + bool ParseImportedModules( const lldb_private::SymbolContext &sc, std::vector<lldb_private::ConstString> &imported_modules) override; - size_t ParseFunctionBlocks(const lldb_private::SymbolContext &sc) override; - size_t ParseTypes(const lldb_private::SymbolContext &sc) override; + size_t ParseBlocksRecursive(lldb_private::Function &func) override; size_t ParseVariablesForContext(const lldb_private::SymbolContext &sc) override; lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override; + llvm::Optional<ArrayInfo> GetDynamicArrayInfoForUID( + lldb::user_id_t type_uid, + const lldb_private::ExecutionContext *exe_ctx) override; + lldb_private::CompilerDeclContext GetDeclContextForUID(lldb::user_id_t uid) override; lldb_private::CompilerDeclContext @@ -86,11 +92,12 @@ public: bool CompleteType(lldb_private::CompilerType &compiler_type) override; uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr, - uint32_t resolve_scope, + lldb::SymbolContextItem resolve_scope, lldb_private::SymbolContext &sc) override; uint32_t ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line, - bool check_inlines, uint32_t resolve_scope, + bool check_inlines, + lldb::SymbolContextItem resolve_scope, lldb_private::SymbolContextList &sc_list) override; uint32_t FindGlobalVariables(const lldb_private::ConstString &name, @@ -103,25 +110,27 @@ public: uint32_t FindFunctions(const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, - uint32_t name_type_mask, bool include_inlines, bool append, - lldb_private::SymbolContextList &sc_list) override; + lldb::FunctionNameType name_type_mask, bool include_inlines, + bool append, lldb_private::SymbolContextList &sc_list) override; uint32_t FindFunctions(const lldb_private::RegularExpression ®ex, bool include_inlines, bool append, lldb_private::SymbolContextList &sc_list) override; uint32_t - FindTypes(const lldb_private::SymbolContext &sc, - const lldb_private::ConstString &name, + FindTypes(const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, lldb_private::TypeMap &types) override; lldb_private::CompilerDeclContext FindNamespace( - const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx) override; size_t GetTypes(lldb_private::SymbolContextScope *sc_scope, - uint32_t type_mask, + lldb::TypeClass type_mask, lldb_private::TypeList &type_list) override; + std::vector<lldb_private::CallEdge> + ParseCallEdgesInFunction(lldb_private::UserID func_id) override; + + void DumpClangAST(lldb_private::Stream &s) override; //------------------------------------------------------------------ // PluginInterface protocol @@ -189,6 +198,7 @@ protected: bool GetFileSpecForSO(uint32_t oso_idx, lldb_private::FileSpec &file_spec); CompileUnitInfo *GetCompUnitInfo(const lldb_private::SymbolContext &sc); + CompileUnitInfo *GetCompUnitInfo(const lldb_private::CompileUnit &comp_unit); size_t GetCompUnitInfosForModule(const lldb_private::Module *oso_module, std::vector<CompileUnitInfo *> &cu_infos); @@ -206,6 +216,7 @@ protected: uint32_t GetCompUnitInfoIndex(const CompileUnitInfo *comp_unit_info); SymbolFileDWARF *GetSymbolFile(const lldb_private::SymbolContext &sc); + SymbolFileDWARF *GetSymbolFile(const lldb_private::CompileUnit &comp_unit); SymbolFileDWARF *GetSymbolFileByCompUnitInfo(CompileUnitInfo *comp_unit_info); diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp index 15fe362fa117..7881448535b8 100644 --- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp +++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp @@ -61,14 +61,6 @@ SymbolFileDWARFDwo::ParseCompileUnit(DWARFUnit *dwarf_cu, } DWARFUnit *SymbolFileDWARFDwo::GetCompileUnit() { - // A clang module is found via a skeleton CU, but is not a proper DWO. - // Clang modules have a .debug_info section instead of the *_dwo variant. - if (auto *section_list = m_obj_file->GetSectionList(false)) - if (auto section_sp = - section_list->FindSectionByType(eSectionTypeDWARFDebugInfo, true)) - if (!section_sp->GetName().GetStringRef().endswith("dwo")) - return nullptr; - // Only dwo files with 1 compile unit is supported if (GetNumCompileUnits() == 1) return DebugInfo()->GetCompileUnitAtIndex(0); @@ -126,6 +118,37 @@ DWARFUnit *SymbolFileDWARFDwo::GetBaseCompileUnit() { return m_base_dwarf_cu; } +const DWARFDataExtractor &SymbolFileDWARFDwo::get_debug_abbrev_data() { + return GetCachedSectionData(eSectionTypeDWARFDebugAbbrevDwo, + m_data_debug_abbrev); +} + +const DWARFDataExtractor &SymbolFileDWARFDwo::get_debug_addr_data() { + // For single file split dwarf case (when we have .dwo sections in a .o), + // we do not want to use the .debug_addr section from .o file, + // but want to get one from the final executable. + // For regular split debug case, .dwo file does not contain the + // .debug_addr, so we would always fall back to such lookup anyways. + llvm::call_once(m_data_debug_addr.m_flag, [this] { + SymbolFileDWARF::LoadSectionData(eSectionTypeDWARFDebugAddr, + std::ref(m_data_debug_addr.m_data)); + }); + return m_data_debug_addr.m_data; +} + +const DWARFDataExtractor &SymbolFileDWARFDwo::get_debug_info_data() { + return GetCachedSectionData(eSectionTypeDWARFDebugInfoDwo, m_data_debug_info); +} + +const DWARFDataExtractor &SymbolFileDWARFDwo::get_debug_str_data() { + return GetCachedSectionData(eSectionTypeDWARFDebugStrDwo, m_data_debug_str); +} + +const DWARFDataExtractor &SymbolFileDWARFDwo::get_debug_str_offsets_data() { + return GetCachedSectionData(eSectionTypeDWARFDebugStrOffsetsDwo, + m_data_debug_str_offsets); +} + SymbolFileDWARF *SymbolFileDWARFDwo::GetBaseSymbolFile() { return m_base_dwarf_cu->GetSymbolFileDWARF(); } diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h index 483a19512a36..b9ed37547aca 100644 --- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h +++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h @@ -10,10 +10,6 @@ #ifndef SymbolFileDWARFDwo_SymbolFileDWARFDwo_h_ #define SymbolFileDWARFDwo_SymbolFileDWARFDwo_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "SymbolFileDWARF.h" class SymbolFileDWARFDwo : public SymbolFileDWARF { @@ -50,6 +46,12 @@ public: DWARFUnit *GetBaseCompileUnit() override; + const lldb_private::DWARFDataExtractor &get_debug_abbrev_data() override; + const lldb_private::DWARFDataExtractor &get_debug_addr_data() override; + const lldb_private::DWARFDataExtractor &get_debug_info_data() override; + const lldb_private::DWARFDataExtractor &get_debug_str_data() override; + const lldb_private::DWARFDataExtractor &get_debug_str_offsets_data() override; + protected: void LoadSectionData(lldb::SectionType sect_type, lldb_private::DWARFDataExtractor &data) override; diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h index b1b505b5899f..905ba0a5c7b8 100644 --- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h +++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h @@ -10,10 +10,6 @@ #ifndef SymbolFileDWARFDwoDwp_SymbolFileDWARFDwoDwp_h_ #define SymbolFileDWARFDwoDwp_SymbolFileDWARFDwoDwp_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "SymbolFileDWARFDwo.h" #include "SymbolFileDWARFDwp.h" diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp index ae10e7179e33..73226dfc130f 100644 --- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp +++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp @@ -9,10 +9,6 @@ #include "SymbolFileDWARFDwp.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/Section.h" #include "lldb/Symbol/ObjectFile.h" @@ -30,7 +26,7 @@ lldbSectTypeToLlvmSectionKind(lldb::SectionType type) { case lldb::eSectionTypeDWARFDebugLine: return llvm::DW_SECT_LINE; case lldb::eSectionTypeDWARFDebugLoc: - return llvm::DW_SECT_LOC; + return llvm::DW_SECT_LOC; case lldb::eSectionTypeDWARFDebugStrOffsets: return llvm::DW_SECT_STR_OFFSETS; // case lldb::eSectionTypeDWARFDebugMacinfo: @@ -50,7 +46,8 @@ SymbolFileDWARFDwp::Create(lldb::ModuleSP module_sp, lldb::DataBufferSP file_data_sp; lldb::offset_t file_data_offset = 0; lldb::ObjectFileSP obj_file = lldb_private::ObjectFile::FindPlugin( - module_sp, &file_spec, file_offset, file_spec.GetByteSize(), file_data_sp, + module_sp, &file_spec, file_offset, + lldb_private::FileSystem::Instance().GetByteSize(file_spec), file_data_sp, file_data_offset); if (obj_file == nullptr) return nullptr; diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h index 470d1c5b1c48..87f4d9402335 100644 --- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h +++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h @@ -10,14 +10,10 @@ #ifndef SymbolFileDWARFDwp_SymbolFileDWARFDwp_h_ #define SymbolFileDWARFDwp_SymbolFileDWARFDwp_h_ -// C Includes -// C++ Includes #include <memory> -// Other libraries and framework includes #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" -// Project includes #include "lldb/Core/Module.h" #include "DWARFDataExtractor.h" diff --git a/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp b/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp index 8273d975e57d..dd912aecf0d8 100644 --- a/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp +++ b/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp @@ -9,10 +9,6 @@ #include "UniqueDWARFASTType.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Symbol/Declaration.h" bool UniqueDWARFASTTypeList::Find(const DWARFDIE &die, diff --git a/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h b/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h index 5d51044cbe1a..1e6b164e9457 100644 --- a/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h +++ b/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h @@ -10,14 +10,10 @@ #ifndef lldb_UniqueDWARFASTType_h_ #define lldb_UniqueDWARFASTType_h_ -// C Includes -// C++ Includes #include <vector> -// Other libraries and framework includes #include "llvm/ADT/DenseMap.h" -// Project includes #include "DWARFDIE.h" #include "lldb/Symbol/Declaration.h" |
