diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 21:59:52 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 21:59:52 +0000 |
commit | 435933dd67752b0d68c320107a5e69435a6f20ec (patch) | |
tree | d6d182de35e23e0da238fad40b066bab6a712352 /contrib/llvm/tools/lldb/source/Plugins/SymbolFile | |
parent | 1189dbaa8c30085bd4f9cc7759a459160bcf2375 (diff) | |
parent | 14f1b3e8826ce43b978db93a62d1166055db5394 (diff) | |
download | src-435933dd67752b0d68c320107a5e69435a6f20ec.tar.gz src-435933dd67752b0d68c320107a5e69435a6f20ec.zip |
Update lldb to trunk r290819 and resolve conflicts.
Notes
Notes:
svn path=/projects/clang400-import/; revision=311145
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Plugins/SymbolFile')
73 files changed, 21274 insertions, 23503 deletions
diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp index 5fe0cc4d416e..5ed9c6ab7282 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp @@ -9,83 +9,64 @@ #include "DIERef.h" #include "DWARFCompileUnit.h" -#include "DWARFFormValue.h" #include "DWARFDebugInfo.h" +#include "DWARFFormValue.h" #include "SymbolFileDWARF.h" #include "SymbolFileDWARFDebugMap.h" -DIERef::DIERef() : - cu_offset(DW_INVALID_OFFSET), - die_offset(DW_INVALID_OFFSET) -{} +DIERef::DIERef() + : cu_offset(DW_INVALID_OFFSET), die_offset(DW_INVALID_OFFSET) {} -DIERef::DIERef(dw_offset_t c, dw_offset_t d) : - cu_offset(c), - die_offset(d) -{} +DIERef::DIERef(dw_offset_t c, dw_offset_t d) : cu_offset(c), die_offset(d) {} -DIERef::DIERef(lldb::user_id_t uid, SymbolFileDWARF *dwarf) : - cu_offset(DW_INVALID_OFFSET), - die_offset(uid&0xffffffff) -{ - SymbolFileDWARFDebugMap *debug_map = dwarf->GetDebugMapSymfile(); - if (debug_map) - { - const uint32_t oso_idx = debug_map->GetOSOIndexFromUserID(uid); - SymbolFileDWARF *actual_dwarf = debug_map->GetSymbolFileByOSOIndex(oso_idx); - if (actual_dwarf) - { - DWARFDebugInfo *debug_info = actual_dwarf->DebugInfo(); - if (debug_info) - { - DWARFCompileUnit *dwarf_cu = debug_info->GetCompileUnitContainingDIEOffset(die_offset); - if (dwarf_cu) - { - cu_offset = dwarf_cu->GetOffset(); - return; - } - } +DIERef::DIERef(lldb::user_id_t uid, SymbolFileDWARF *dwarf) + : cu_offset(DW_INVALID_OFFSET), die_offset(uid & 0xffffffff) { + SymbolFileDWARFDebugMap *debug_map = dwarf->GetDebugMapSymfile(); + if (debug_map) { + const uint32_t oso_idx = debug_map->GetOSOIndexFromUserID(uid); + SymbolFileDWARF *actual_dwarf = debug_map->GetSymbolFileByOSOIndex(oso_idx); + if (actual_dwarf) { + DWARFDebugInfo *debug_info = actual_dwarf->DebugInfo(); + if (debug_info) { + DWARFCompileUnit *dwarf_cu = + debug_info->GetCompileUnitContainingDIEOffset(die_offset); + if (dwarf_cu) { + cu_offset = dwarf_cu->GetOffset(); + return; } - die_offset = DW_INVALID_OFFSET; - } - else - { - cu_offset = uid>>32; + } } + die_offset = DW_INVALID_OFFSET; + } else { + cu_offset = uid >> 32; + } } -DIERef::DIERef(const DWARFFormValue& form_value) : - cu_offset(DW_INVALID_OFFSET), - die_offset(DW_INVALID_OFFSET) -{ - if (form_value.IsValid()) - { - const DWARFCompileUnit* dwarf_cu = form_value.GetCompileUnit(); - if (dwarf_cu) - { - if (dwarf_cu->GetBaseObjOffset() != DW_INVALID_OFFSET) - cu_offset = dwarf_cu->GetBaseObjOffset(); - else - cu_offset = dwarf_cu->GetOffset(); - } - die_offset = form_value.Reference(); +DIERef::DIERef(const DWARFFormValue &form_value) + : cu_offset(DW_INVALID_OFFSET), die_offset(DW_INVALID_OFFSET) { + if (form_value.IsValid()) { + const DWARFCompileUnit *dwarf_cu = form_value.GetCompileUnit(); + if (dwarf_cu) { + if (dwarf_cu->GetBaseObjOffset() != DW_INVALID_OFFSET) + cu_offset = dwarf_cu->GetBaseObjOffset(); + else + cu_offset = dwarf_cu->GetOffset(); } + die_offset = form_value.Reference(); + } } -lldb::user_id_t -DIERef::GetUID(SymbolFileDWARF *dwarf) const -{ - //---------------------------------------------------------------------- - // Each SymbolFileDWARF will set its ID to what is expected. - // - // SymbolFileDWARF, when used for DWARF with .o files on MacOSX, has the - // ID set to the compile unit index. - // - // SymbolFileDWARFDwo sets the ID to the compile unit offset. - //---------------------------------------------------------------------- - if (dwarf) - return dwarf->GetID() | die_offset; - else - return LLDB_INVALID_UID; +lldb::user_id_t DIERef::GetUID(SymbolFileDWARF *dwarf) const { + //---------------------------------------------------------------------- + // Each SymbolFileDWARF will set its ID to what is expected. + // + // SymbolFileDWARF, when used for DWARF with .o files on MacOSX, has the + // ID set to the compile unit index. + // + // SymbolFileDWARFDwo sets the ID to the compile unit offset. + //---------------------------------------------------------------------- + if (dwarf) + return dwarf->GetID() | die_offset; + else + return LLDB_INVALID_UID; } - diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h index ad4ad45623a3..d0048d0f6d6b 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h @@ -16,49 +16,39 @@ class DWARFFormValue; class SymbolFileDWARF; -struct DIERef -{ - DIERef(); +struct DIERef { + DIERef(); - DIERef(dw_offset_t c, dw_offset_t d); + DIERef(dw_offset_t c, dw_offset_t d); - //---------------------------------------------------------------------- - // In order to properly decode a lldb::user_id_t back into a DIERef we - // need the DWARF file since it knows if DWARF in .o files is being used - // (MacOSX) or if DWO files are being used. The encoding of the user ID - // differs between the two types of DWARF. - //---------------------------------------------------------------------- - explicit - DIERef(lldb::user_id_t uid, SymbolFileDWARF *dwarf); + //---------------------------------------------------------------------- + // In order to properly decode a lldb::user_id_t back into a DIERef we + // need the DWARF file since it knows if DWARF in .o files is being used + // (MacOSX) or if DWO files are being used. The encoding of the user ID + // differs between the two types of DWARF. + //---------------------------------------------------------------------- + explicit DIERef(lldb::user_id_t uid, SymbolFileDWARF *dwarf); - explicit - DIERef(const DWARFFormValue& form_value); + explicit DIERef(const DWARFFormValue &form_value); - //---------------------------------------------------------------------- - // In order to properly encode a DIERef unto a lldb::user_id_t we need - // the DWARF file since it knows if DWARF in .o files is being used - // (MacOSX) or if DWO files are being used. The encoding of the user ID - // differs between the two types of DWARF. - //---------------------------------------------------------------------- - lldb::user_id_t - GetUID(SymbolFileDWARF *dwarf) const; + //---------------------------------------------------------------------- + // In order to properly encode a DIERef unto a lldb::user_id_t we need + // the DWARF file since it knows if DWARF in .o files is being used + // (MacOSX) or if DWO files are being used. The encoding of the user ID + // differs between the two types of DWARF. + //---------------------------------------------------------------------- + lldb::user_id_t GetUID(SymbolFileDWARF *dwarf) const; - bool - operator< (const DIERef &ref) const - { - return die_offset < ref.die_offset; - } + bool operator<(const DIERef &ref) const { + return die_offset < ref.die_offset; + } - bool - operator< (const DIERef &ref) - { - return die_offset < ref.die_offset; - } + bool operator<(const DIERef &ref) { return die_offset < ref.die_offset; } - dw_offset_t cu_offset; - dw_offset_t die_offset; + dw_offset_t cu_offset; + dw_offset_t die_offset; }; typedef std::vector<DIERef> DIEArray; -#endif // SymbolFileDWARF_DIERef_h_ +#endif // SymbolFileDWARF_DIERef_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h index 2fb360440f63..ae7c770d6ef7 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h @@ -17,37 +17,34 @@ class DWARFDIE; -class DWARFASTParser -{ +class DWARFASTParser { public: - virtual ~DWARFASTParser() {} + virtual ~DWARFASTParser() {} - virtual lldb::TypeSP - ParseTypeFromDWARF (const lldb_private::SymbolContext& sc, - const DWARFDIE &die, - lldb_private::Log *log, - bool *type_is_new_ptr) = 0; + virtual lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, + const DWARFDIE &die, + lldb_private::Log *log, + bool *type_is_new_ptr) = 0; - virtual lldb_private::Function * - ParseFunctionFromDWARF (const lldb_private::SymbolContext& sc, - const DWARFDIE &die) = 0; + virtual lldb_private::Function * + ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc, + const DWARFDIE &die) = 0; - virtual bool - CompleteTypeFromDWARF (const DWARFDIE &die, - lldb_private::Type *type, - lldb_private::CompilerType &compiler_type) = 0; + virtual bool + CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type, + lldb_private::CompilerType &compiler_type) = 0; - virtual lldb_private::CompilerDecl - GetDeclForUIDFromDWARF (const DWARFDIE &die) = 0; + virtual lldb_private::CompilerDecl + GetDeclForUIDFromDWARF(const DWARFDIE &die) = 0; - virtual lldb_private::CompilerDeclContext - GetDeclContextForUIDFromDWARF (const DWARFDIE &die) = 0; + virtual lldb_private::CompilerDeclContext + GetDeclContextForUIDFromDWARF(const DWARFDIE &die) = 0; - virtual lldb_private::CompilerDeclContext - GetDeclContextContainingUIDFromDWARF (const DWARFDIE &die) = 0; + virtual lldb_private::CompilerDeclContext + GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) = 0; - virtual std::vector<DWARFDIE> - GetDIEForDeclContext (lldb_private::CompilerDeclContext decl_context) = 0; + virtual std::vector<DWARFDIE> + GetDIEForDeclContext(lldb_private::CompilerDeclContext decl_context) = 0; }; -#endif // SymbolFileDWARF_DWARFASTParser_h_ +#endif // SymbolFileDWARF_DWARFASTParser_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 23381df3297a..554b71a36c4f 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -11,11 +11,11 @@ #include "DWARFASTParserClang.h" #include "DWARFCompileUnit.h" +#include "DWARFDIE.h" +#include "DWARFDIECollection.h" #include "DWARFDebugInfo.h" #include "DWARFDeclContext.h" #include "DWARFDefines.h" -#include "DWARFDIE.h" -#include "DWARFDIECollection.h" #include "SymbolFileDWARF.h" #include "SymbolFileDWARFDebugMap.h" #include "UniqueDWARFASTType.h" @@ -54,4206 +54,4035 @@ #define DEBUG_PRINTF(fmt, ...) #endif - using namespace lldb; using namespace lldb_private; -DWARFASTParserClang::DWARFASTParserClang (ClangASTContext &ast) : - m_ast (ast), - m_die_to_decl_ctx (), - m_decl_ctx_to_die () -{ +DWARFASTParserClang::DWARFASTParserClang(ClangASTContext &ast) + : m_ast(ast), m_die_to_decl_ctx(), m_decl_ctx_to_die() {} + +DWARFASTParserClang::~DWARFASTParserClang() {} + +static AccessType DW_ACCESS_to_AccessType(uint32_t dwarf_accessibility) { + switch (dwarf_accessibility) { + case DW_ACCESS_public: + return eAccessPublic; + case DW_ACCESS_private: + return eAccessPrivate; + case DW_ACCESS_protected: + return eAccessProtected; + default: + break; + } + return eAccessNone; } -DWARFASTParserClang::~DWARFASTParserClang () -{ +static bool DeclKindIsCXXClass(clang::Decl::Kind decl_kind) { + switch (decl_kind) { + case clang::Decl::CXXRecord: + case clang::Decl::ClassTemplateSpecialization: + return true; + default: + break; + } + return false; } - -static AccessType -DW_ACCESS_to_AccessType (uint32_t dwarf_accessibility) -{ - switch (dwarf_accessibility) - { - case DW_ACCESS_public: return eAccessPublic; - case DW_ACCESS_private: return eAccessPrivate; - case DW_ACCESS_protected: return eAccessProtected; - default: break; +struct BitfieldInfo { + uint64_t bit_size; + uint64_t bit_offset; + + BitfieldInfo() + : bit_size(LLDB_INVALID_ADDRESS), bit_offset(LLDB_INVALID_ADDRESS) {} + + void Clear() { + bit_size = LLDB_INVALID_ADDRESS; + bit_offset = LLDB_INVALID_ADDRESS; + } + + bool IsValid() const { + return (bit_size != LLDB_INVALID_ADDRESS) && + (bit_offset != LLDB_INVALID_ADDRESS); + } + + bool NextBitfieldOffsetIsValid(const uint64_t next_bit_offset) const { + if (IsValid()) { + // This bitfield info is valid, so any subsequent bitfields + // must not overlap and must be at a higher bit offset than + // any previous bitfield + size. + return (bit_size + bit_offset) <= next_bit_offset; + } else { + // If the this BitfieldInfo is not valid, then any offset isOK + return true; } - return eAccessNone; + } +}; + +ClangASTImporter &DWARFASTParserClang::GetClangASTImporter() { + if (!m_clang_ast_importer_ap) { + m_clang_ast_importer_ap.reset(new ClangASTImporter); + } + return *m_clang_ast_importer_ap; } -static bool -DeclKindIsCXXClass (clang::Decl::Kind decl_kind) -{ - switch (decl_kind) - { - case clang::Decl::CXXRecord: - case clang::Decl::ClassTemplateSpecialization: - return true; - default: - break; +TypeSP DWARFASTParserClang::ParseTypeFromDWO(const DWARFDIE &die, Log *log) { + ModuleSP dwo_module_sp = die.GetContainingDWOModule(); + if (dwo_module_sp) { + // This type comes from an external DWO module + std::vector<CompilerContext> dwo_context; + die.GetDWOContext(dwo_context); + TypeMap dwo_types; + if (dwo_module_sp->GetSymbolVendor()->FindTypes(dwo_context, true, + dwo_types)) { + const size_t num_dwo_types = dwo_types.GetSize(); + if (num_dwo_types == 1) { + // We found a real definition for this type elsewhere + // so lets use it and cache the fact that we found + // a complete type for this die + TypeSP dwo_type_sp = dwo_types.GetTypeAtIndex(0); + if (dwo_type_sp) { + lldb_private::CompilerType dwo_type = + dwo_type_sp->GetForwardCompilerType(); + + lldb_private::CompilerType type = + GetClangASTImporter().CopyType(m_ast, dwo_type); + + // printf ("copied_qual_type: ast = %p, clang_type = %p, name = + // '%s'\n", m_ast, copied_qual_type.getAsOpaquePtr(), + // external_type->GetName().GetCString()); + if (type) { + SymbolFileDWARF *dwarf = die.GetDWARF(); + TypeSP type_sp(new Type(die.GetID(), dwarf, dwo_type_sp->GetName(), + dwo_type_sp->GetByteSize(), NULL, + LLDB_INVALID_UID, Type::eEncodingInvalid, + &dwo_type_sp->GetDeclaration(), type, + Type::eResolveStateForward)); + + dwarf->GetTypeList()->Insert(type_sp); + dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); + clang::TagDecl *tag_decl = ClangASTContext::GetAsTagDecl(type); + if (tag_decl) + LinkDeclContextToDIE(tag_decl, die); + else { + clang::DeclContext *defn_decl_ctx = + GetCachedClangDeclContextForDIE(die); + if (defn_decl_ctx) + LinkDeclContextToDIE(defn_decl_ctx, die); + } + return type_sp; + } + } + } } - return false; + } + return TypeSP(); } -struct BitfieldInfo -{ - uint64_t bit_size; - uint64_t bit_offset; - - BitfieldInfo() : - bit_size(LLDB_INVALID_ADDRESS), - bit_offset(LLDB_INVALID_ADDRESS) - { - } +TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, + const DWARFDIE &die, Log *log, + bool *type_is_new_ptr) { + TypeSP type_sp; - void - Clear() - { - bit_size = LLDB_INVALID_ADDRESS; - bit_offset = LLDB_INVALID_ADDRESS; - } + if (type_is_new_ptr) + *type_is_new_ptr = false; - bool - IsValid() const - { - return (bit_size != LLDB_INVALID_ADDRESS) && - (bit_offset != LLDB_INVALID_ADDRESS); + AccessType accessibility = eAccessNone; + if (die) { + SymbolFileDWARF *dwarf = die.GetDWARF(); + if (log) { + DWARFDIE context_die; + clang::DeclContext *context = + GetClangDeclContextContainingDIE(die, &context_die); + + dwarf->GetObjectFile()->GetModule()->LogMessage( + log, "SymbolFileDWARF::ParseType (die = 0x%8.8x, decl_ctx = %p (die " + "0x%8.8x)) %s name = '%s')", + die.GetOffset(), static_cast<void *>(context), + context_die.GetOffset(), die.GetTagAsCString(), die.GetName()); } + // + // Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO)); + // if (log && dwarf_cu) + // { + // StreamString s; + // die->DumpLocation (this, dwarf_cu, s); + // dwarf->GetObjectFile()->GetModule()->LogMessage (log, + // "SymbolFileDwarf::%s %s", __FUNCTION__, s.GetData()); + // + // } + + Type *type_ptr = dwarf->GetDIEToType().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; + Declaration decl; + + Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID; + CompilerType clang_type; + DWARFFormValue form_value; + + dw_attr_t attr; + + switch (tag) { + case DW_TAG_typedef: + case DW_TAG_base_type: + case DW_TAG_pointer_type: + case DW_TAG_reference_type: + case DW_TAG_rvalue_reference_type: + case DW_TAG_const_type: + case DW_TAG_restrict_type: + case DW_TAG_volatile_type: + case DW_TAG_unspecified_type: { + // Set a bit that lets us know that we are currently parsing this + dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED; - bool - NextBitfieldOffsetIsValid(const uint64_t next_bit_offset) const - { - if (IsValid()) - { - // This bitfield info is valid, so any subsequent bitfields - // must not overlap and must be at a higher bit offset than - // any previous bitfield + size. - return (bit_size + bit_offset) <= next_bit_offset; + const size_t num_attributes = die.GetAttributes(attributes); + uint32_t encoding = 0; + DWARFFormValue encoding_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_decl_file: + decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex( + form_value.Unsigned())); + break; + case DW_AT_decl_line: + decl.SetLine(form_value.Unsigned()); + break; + case DW_AT_decl_column: + 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; + case DW_AT_byte_size: + byte_size = form_value.Unsigned(); + break; + case DW_AT_encoding: + encoding = form_value.Unsigned(); + break; + case DW_AT_type: + encoding_uid = form_value; + break; + default: + case DW_AT_sibling: + break; + } + } + } } - else - { - // If the this BitfieldInfo is not valid, then any offset isOK - return true; + + if (tag == DW_TAG_typedef && encoding_uid.IsValid()) { + // Try to parse a typedef from the DWO file first as modules + // can contain typedef'ed structures that have no names like: + // + // typedef struct { int a; } Foo; + // + // In this case we will have a structure with no name and a + // typedef named "Foo" that points to this unnamed structure. + // The name in the typedef is the only identifier for the struct, + // so always try to get typedefs from DWO files if possible. + // + // The type_sp returned will be empty if the typedef doesn't exist + // in a DWO file, so it is cheap to call this function just to check. + // + // If we don't do this we end up creating a TypeSP that says this + // is a typedef to type 0x123 (the DW_AT_type value would be 0x123 + // in the DW_TAG_typedef), and this is the unnamed structure type. + // We will have a hard time tracking down an unnammed structure + // type in the module DWO file, so we make sure we don't get into + // this situation by always resolving typedefs from the DWO file. + const DWARFDIE encoding_die = dwarf->GetDIE(DIERef(encoding_uid)); + + // First make sure that the die that this is typedef'ed to _is_ + // just a declaration (DW_AT_declaration == 1), not a full definition + // since template types can't be represented in modules since only + // concrete instances of templates are ever emitted and modules + // won't contain those + if (encoding_die && + encoding_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == + 1) { + type_sp = ParseTypeFromDWO(die, log); + if (type_sp) + return type_sp; + } } - } -}; + 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.Reference()); -ClangASTImporter & -DWARFASTParserClang::GetClangASTImporter() -{ - if (!m_clang_ast_importer_ap) - { - m_clang_ast_importer_ap.reset (new ClangASTImporter); - } - return *m_clang_ast_importer_ap; -} + switch (tag) { + default: + break; + case DW_TAG_unspecified_type: + if (strcmp(type_name_cstr, "nullptr_t") == 0 || + strcmp(type_name_cstr, "decltype(nullptr)") == 0) { + resolve_state = Type::eResolveStateFull; + clang_type = m_ast.GetBasicType(eBasicTypeNullPtr); + break; + } + // Fall through to base type below in case we can handle the type + // there... + LLVM_FALLTHROUGH; + + case DW_TAG_base_type: + resolve_state = Type::eResolveStateFull; + clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize( + type_name_cstr, encoding, byte_size * 8); + break; + + case DW_TAG_pointer_type: + encoding_data_type = Type::eEncodingIsPointerUID; + break; + case DW_TAG_reference_type: + encoding_data_type = Type::eEncodingIsLValueReferenceUID; + break; + case DW_TAG_rvalue_reference_type: + encoding_data_type = Type::eEncodingIsRValueReferenceUID; + break; + case DW_TAG_typedef: + encoding_data_type = Type::eEncodingIsTypedefUID; + break; + case DW_TAG_const_type: + encoding_data_type = Type::eEncodingIsConstUID; + break; + case DW_TAG_restrict_type: + encoding_data_type = Type::eEncodingIsRestrictUID; + break; + case DW_TAG_volatile_type: + encoding_data_type = Type::eEncodingIsVolatileUID; + break; + } -TypeSP -DWARFASTParserClang::ParseTypeFromDWO (const DWARFDIE &die, Log *log) -{ - ModuleSP dwo_module_sp = die.GetContainingDWOModule(); - if (dwo_module_sp) - { - // This type comes from an external DWO module - std::vector<CompilerContext> dwo_context; - die.GetDWOContext(dwo_context); - TypeMap dwo_types; - if (dwo_module_sp->GetSymbolVendor()->FindTypes(dwo_context, true, dwo_types)) - { - const size_t num_dwo_types = dwo_types.GetSize(); - if (num_dwo_types == 1) - { - // We found a real definition for this type elsewhere - // so lets use it and cache the fact that we found - // a complete type for this die - TypeSP dwo_type_sp = dwo_types.GetTypeAtIndex(0); - if (dwo_type_sp) - { - lldb_private::CompilerType dwo_type = dwo_type_sp->GetForwardCompilerType(); - - lldb_private::CompilerType type = GetClangASTImporter().CopyType (m_ast, dwo_type); - - //printf ("copied_qual_type: ast = %p, clang_type = %p, name = '%s'\n", m_ast, copied_qual_type.getAsOpaquePtr(), external_type->GetName().GetCString()); - if (type) - { - SymbolFileDWARF *dwarf = die.GetDWARF(); - TypeSP type_sp (new Type (die.GetID(), - dwarf, - dwo_type_sp->GetName(), - dwo_type_sp->GetByteSize(), - NULL, - LLDB_INVALID_UID, - Type::eEncodingInvalid, - &dwo_type_sp->GetDeclaration(), - type, - Type::eResolveStateForward)); - - dwarf->GetTypeList()->Insert(type_sp); - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); - clang::TagDecl *tag_decl = ClangASTContext::GetAsTagDecl(type); - if (tag_decl) - LinkDeclContextToDIE(tag_decl, die); - else - { - clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(die); - if (defn_decl_ctx) - LinkDeclContextToDIE(defn_decl_ctx, die); - } - return type_sp; + if (!clang_type && + (encoding_data_type == Type::eEncodingIsPointerUID || + encoding_data_type == Type::eEncodingIsTypedefUID) && + sc.comp_unit != NULL) { + if (tag == DW_TAG_pointer_type) { + DWARFDIE target_die = die.GetReferencedDIE(DW_AT_type); + + if (target_die.GetAttributeValueAsUnsigned(DW_AT_APPLE_block, 0)) { + // Blocks have a __FuncPtr inside them which is a pointer to a + // function of the proper type. + + for (DWARFDIE child_die = target_die.GetFirstChild(); + child_die.IsValid(); child_die = child_die.GetSibling()) { + if (!strcmp(child_die.GetAttributeValueAsString(DW_AT_name, ""), + "__FuncPtr")) { + DWARFDIE function_pointer_type = + child_die.GetReferencedDIE(DW_AT_type); + + if (function_pointer_type) { + DWARFDIE function_type = + function_pointer_type.GetReferencedDIE(DW_AT_type); + + bool function_type_is_new_pointer; + TypeSP lldb_function_type_sp = ParseTypeFromDWARF( + sc, function_type, log, &function_type_is_new_pointer); + + if (lldb_function_type_sp) { + clang_type = m_ast.CreateBlockPointerType( + lldb_function_type_sp->GetForwardCompilerType()); + encoding_data_type = Type::eEncodingIsUID; + encoding_uid.Clear(); + resolve_state = Type::eResolveStateFull; } + } + + break; } + } } - } - } - return TypeSP(); -} - -TypeSP -DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc, - const DWARFDIE &die, - Log *log, - bool *type_is_new_ptr) -{ - TypeSP type_sp; - - if (type_is_new_ptr) - *type_is_new_ptr = false; + } - AccessType accessibility = eAccessNone; - if (die) - { - SymbolFileDWARF *dwarf = die.GetDWARF(); - if (log) - { - DWARFDIE context_die; - clang::DeclContext *context = GetClangDeclContextContainingDIE (die, &context_die); + bool translation_unit_is_objc = + (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || + sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus); - dwarf->GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDWARF::ParseType (die = 0x%8.8x, decl_ctx = %p (die 0x%8.8x)) %s name = '%s')", - die.GetOffset(), - static_cast<void*>(context), - context_die.GetOffset(), - die.GetTagAsCString(), - die.GetName()); + if (translation_unit_is_objc) { + if (type_name_cstr != NULL) { + static ConstString g_objc_type_name_id("id"); + static ConstString g_objc_type_name_Class("Class"); + static ConstString g_objc_type_name_selector("SEL"); + if (type_name_const_str == g_objc_type_name_id) { + if (log) + dwarf->GetObjectFile()->GetModule()->LogMessage( + log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' " + "is Objective C 'id' built-in type.", + die.GetOffset(), die.GetTagAsCString(), die.GetName()); + clang_type = m_ast.GetBasicType(eBasicTypeObjCID); + encoding_data_type = Type::eEncodingIsUID; + encoding_uid.Clear(); + resolve_state = Type::eResolveStateFull; + + } else if (type_name_const_str == g_objc_type_name_Class) { + if (log) + dwarf->GetObjectFile()->GetModule()->LogMessage( + log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' " + "is Objective C 'Class' built-in type.", + die.GetOffset(), die.GetTagAsCString(), die.GetName()); + clang_type = m_ast.GetBasicType(eBasicTypeObjCClass); + encoding_data_type = Type::eEncodingIsUID; + encoding_uid.Clear(); + resolve_state = Type::eResolveStateFull; + } else if (type_name_const_str == g_objc_type_name_selector) { + if (log) + dwarf->GetObjectFile()->GetModule()->LogMessage( + log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' " + "is Objective C 'selector' built-in type.", + die.GetOffset(), die.GetTagAsCString(), die.GetName()); + clang_type = m_ast.GetBasicType(eBasicTypeObjCSel); + encoding_data_type = Type::eEncodingIsUID; + encoding_uid.Clear(); + resolve_state = Type::eResolveStateFull; + } + } else if (encoding_data_type == Type::eEncodingIsPointerUID && + encoding_uid.IsValid()) { + // Clang sometimes erroneously emits id as objc_object*. In that + // case we fix up the type to "id". + + const DWARFDIE encoding_die = dwarf->GetDIE(DIERef(encoding_uid)); + + if (encoding_die && encoding_die.Tag() == DW_TAG_structure_type) { + if (const char *struct_name = encoding_die.GetName()) { + if (!strcmp(struct_name, "objc_object")) { + if (log) + dwarf->GetObjectFile()->GetModule()->LogMessage( + log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s " + "'%s' is 'objc_object*', which we overrode to " + "'id'.", + die.GetOffset(), die.GetTagAsCString(), + die.GetName()); + clang_type = m_ast.GetBasicType(eBasicTypeObjCID); + encoding_data_type = Type::eEncodingIsUID; + encoding_uid.Clear(); + resolve_state = Type::eResolveStateFull; + } + } + } + } + } } - // - // Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO)); - // if (log && dwarf_cu) - // { - // StreamString s; - // die->DumpLocation (this, dwarf_cu, s); - // dwarf->GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDwarf::%s %s", __FUNCTION__, s.GetData()); - // - // } - - Type *type_ptr = dwarf->GetDIEToType().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; - Declaration decl; + type_sp.reset( + new Type(die.GetID(), dwarf, type_name_const_str, byte_size, NULL, + DIERef(encoding_uid).GetUID(dwarf), encoding_data_type, + &decl, clang_type, resolve_state)); + + dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); + + // Type* encoding_type = + // GetUniquedTypeForDIEOffset(encoding_uid, type_sp, + // NULL, 0, 0, false); + // if (encoding_type != NULL) + // { + // if (encoding_type != DIE_IS_BEING_PARSED) + // type_sp->SetEncodingType(encoding_type); + // else + // m_indirect_fixups.push_back(type_sp.get()); + // } + } break; + + case DW_TAG_structure_type: + case DW_TAG_union_type: + case DW_TAG_class_type: { + // Set a bit that lets us know that we are currently parsing this + dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED; + bool byte_size_valid = false; + + LanguageType class_language = eLanguageTypeUnknown; + bool is_complete_objc_class = false; + // bool struct_is_class = 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_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())); + break; - Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID; - CompilerType clang_type; - DWARFFormValue form_value; + case DW_AT_decl_line: + decl.SetLine(form_value.Unsigned()); + break; - dw_attr_t attr; + case DW_AT_decl_column: + decl.SetColumn(form_value.Unsigned()); + break; - switch (tag) - { - case DW_TAG_typedef: - case DW_TAG_base_type: - case DW_TAG_pointer_type: - case DW_TAG_reference_type: - case DW_TAG_rvalue_reference_type: - case DW_TAG_const_type: - case DW_TAG_restrict_type: - case DW_TAG_volatile_type: - case DW_TAG_unspecified_type: - { - // Set a bit that lets us know that we are currently parsing this - dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED; - - const size_t num_attributes = die.GetAttributes (attributes); - uint32_t encoding = 0; - DWARFFormValue encoding_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_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; - case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; - case DW_AT_decl_column: 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; - case DW_AT_byte_size: byte_size = form_value.Unsigned(); break; - case DW_AT_encoding: encoding = form_value.Unsigned(); break; - case DW_AT_type: encoding_uid = form_value; break; - default: - case DW_AT_sibling: - break; - } - } - } - } + case DW_AT_name: + type_name_cstr = form_value.AsCString(); + type_name_const_str.SetCString(type_name_cstr); + break; - if (tag == DW_TAG_typedef && encoding_uid.IsValid()) - { - // Try to parse a typedef from the DWO file first as modules - // can contain typedef'ed structures that have no names like: - // - // typedef struct { int a; } Foo; - // - // In this case we will have a structure with no name and a - // typedef named "Foo" that points to this unnamed structure. - // The name in the typedef is the only identifier for the struct, - // so always try to get typedefs from DWO files if possible. - // - // The type_sp returned will be empty if the typedef doesn't exist - // in a DWO file, so it is cheap to call this function just to check. - // - // If we don't do this we end up creating a TypeSP that says this - // is a typedef to type 0x123 (the DW_AT_type value would be 0x123 - // in the DW_TAG_typedef), and this is the unnamed structure type. - // We will have a hard time tracking down an unnammed structure - // type in the module DWO file, so we make sure we don't get into - // this situation by always resolving typedefs from the DWO file. - const DWARFDIE encoding_die = dwarf->GetDIE(DIERef(encoding_uid)); - - // First make sure that the die that this is typedef'ed to _is_ - // just a declaration (DW_AT_declaration == 1), not a full definition - // since template types can't be represented in modules since only - // concrete instances of templates are ever emitted and modules - // won't contain those - if (encoding_die && encoding_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 1) - { - type_sp = ParseTypeFromDWO(die, log); - if (type_sp) - return type_sp; - } - } + case DW_AT_byte_size: + byte_size = form_value.Unsigned(); + byte_size_valid = true; + 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.Reference()); + case DW_AT_accessibility: + accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); + break; - switch (tag) - { - default: - break; + case DW_AT_declaration: + is_forward_declaration = form_value.Boolean(); + break; - case DW_TAG_unspecified_type: - if (strcmp(type_name_cstr, "nullptr_t") == 0 || - strcmp(type_name_cstr, "decltype(nullptr)") == 0 ) - { - resolve_state = Type::eResolveStateFull; - clang_type = m_ast.GetBasicType(eBasicTypeNullPtr); - break; - } - // Fall through to base type below in case we can handle the type there... - LLVM_FALLTHROUGH; - - case DW_TAG_base_type: - resolve_state = Type::eResolveStateFull; - clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr, - encoding, - byte_size * 8); - break; - - case DW_TAG_pointer_type: encoding_data_type = Type::eEncodingIsPointerUID; break; - case DW_TAG_reference_type: encoding_data_type = Type::eEncodingIsLValueReferenceUID; break; - case DW_TAG_rvalue_reference_type: encoding_data_type = Type::eEncodingIsRValueReferenceUID; break; - case DW_TAG_typedef: encoding_data_type = Type::eEncodingIsTypedefUID; break; - case DW_TAG_const_type: encoding_data_type = Type::eEncodingIsConstUID; break; - case DW_TAG_restrict_type: encoding_data_type = Type::eEncodingIsRestrictUID; break; - case DW_TAG_volatile_type: encoding_data_type = Type::eEncodingIsVolatileUID; break; - } + case DW_AT_APPLE_runtime_class: + class_language = (LanguageType)form_value.Signed(); + break; - if (!clang_type && (encoding_data_type == Type::eEncodingIsPointerUID || encoding_data_type == Type::eEncodingIsTypedefUID) && sc.comp_unit != NULL) - { - if (tag == DW_TAG_pointer_type) - { - DWARFDIE target_die = die.GetReferencedDIE(DW_AT_type); - - if (target_die.GetAttributeValueAsUnsigned(DW_AT_APPLE_block, 0)) - { - // Blocks have a __FuncPtr inside them which is a pointer to a function of the proper type. - - for (DWARFDIE child_die = target_die.GetFirstChild(); - child_die.IsValid(); - child_die = child_die.GetSibling()) - { - if (!strcmp(child_die.GetAttributeValueAsString(DW_AT_name, ""), "__FuncPtr")) - { - DWARFDIE function_pointer_type = child_die.GetReferencedDIE(DW_AT_type); - - if (function_pointer_type) - { - DWARFDIE function_type = function_pointer_type.GetReferencedDIE(DW_AT_type); - - bool function_type_is_new_pointer; - TypeSP lldb_function_type_sp = ParseTypeFromDWARF(sc, function_type, log, &function_type_is_new_pointer); - - if (lldb_function_type_sp) - { - clang_type = m_ast.CreateBlockPointerType(lldb_function_type_sp->GetForwardCompilerType()); - encoding_data_type = Type::eEncodingIsUID; - encoding_uid.Clear(); - resolve_state = Type::eResolveStateFull; - } - } - - break; - } - } - } - } - - bool translation_unit_is_objc = (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus); - - if (translation_unit_is_objc) - { - if (type_name_cstr != NULL) - { - static ConstString g_objc_type_name_id("id"); - static ConstString g_objc_type_name_Class("Class"); - static ConstString g_objc_type_name_selector("SEL"); - - if (type_name_const_str == g_objc_type_name_id) - { - if (log) - dwarf->GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'id' built-in type.", - die.GetOffset(), - die.GetTagAsCString(), - die.GetName()); - clang_type = m_ast.GetBasicType(eBasicTypeObjCID); - encoding_data_type = Type::eEncodingIsUID; - encoding_uid.Clear(); - resolve_state = Type::eResolveStateFull; + case DW_AT_APPLE_objc_complete_type: + is_complete_objc_class = form_value.Signed(); + break; - } - else if (type_name_const_str == g_objc_type_name_Class) - { - if (log) - dwarf->GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'Class' built-in type.", - die.GetOffset(), - die.GetTagAsCString(), - die.GetName()); - clang_type = m_ast.GetBasicType(eBasicTypeObjCClass); - encoding_data_type = Type::eEncodingIsUID; - encoding_uid.Clear(); - resolve_state = Type::eResolveStateFull; - } - else if (type_name_const_str == g_objc_type_name_selector) - { - if (log) - dwarf->GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'selector' built-in type.", - die.GetOffset(), - die.GetTagAsCString(), - die.GetName()); - clang_type = m_ast.GetBasicType(eBasicTypeObjCSel); - encoding_data_type = Type::eEncodingIsUID; - encoding_uid.Clear(); - resolve_state = Type::eResolveStateFull; - } - } - else if (encoding_data_type == Type::eEncodingIsPointerUID && encoding_uid.IsValid()) - { - // Clang sometimes erroneously emits id as objc_object*. In that case we fix up the type to "id". - - const DWARFDIE encoding_die = dwarf->GetDIE(DIERef(encoding_uid)); - - if (encoding_die && encoding_die.Tag() == DW_TAG_structure_type) - { - if (const char *struct_name = encoding_die.GetName()) - { - if (!strcmp(struct_name, "objc_object")) - { - if (log) - dwarf->GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is 'objc_object*', which we overrode to 'id'.", - die.GetOffset(), - die.GetTagAsCString(), - die.GetName()); - clang_type = m_ast.GetBasicType(eBasicTypeObjCID); - encoding_data_type = Type::eEncodingIsUID; - encoding_uid.Clear(); - resolve_state = Type::eResolveStateFull; - } - } - } - } - } - } + case DW_AT_allocated: + case DW_AT_associated: + case DW_AT_data_location: + case DW_AT_description: + case DW_AT_start_scope: + case DW_AT_visibility: + default: + case DW_AT_sibling: + break; + } + } + } + } - type_sp.reset( new Type (die.GetID(), - dwarf, - type_name_const_str, - byte_size, - NULL, - DIERef(encoding_uid).GetUID(dwarf), - encoding_data_type, - &decl, - clang_type, - resolve_state)); - - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); - - // Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false); - // if (encoding_type != NULL) - // { - // if (encoding_type != DIE_IS_BEING_PARSED) - // type_sp->SetEncodingType(encoding_type); - // else - // m_indirect_fixups.push_back(type_sp.get()); - // } - } - break; - - case DW_TAG_structure_type: - case DW_TAG_union_type: - case DW_TAG_class_type: - { - // Set a bit that lets us know that we are currently parsing this - dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED; - bool byte_size_valid = false; - - LanguageType class_language = eLanguageTypeUnknown; - bool is_complete_objc_class = false; - //bool struct_is_class = 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_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())); - break; - - case DW_AT_decl_line: - decl.SetLine(form_value.Unsigned()); - break; - - case DW_AT_decl_column: - decl.SetColumn(form_value.Unsigned()); - break; - - 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_accessibility: - accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); - break; - - case DW_AT_declaration: - is_forward_declaration = form_value.Boolean(); - break; - - case DW_AT_APPLE_runtime_class: - class_language = (LanguageType)form_value.Signed(); - break; - - case DW_AT_APPLE_objc_complete_type: - is_complete_objc_class = form_value.Signed(); - break; - - case DW_AT_allocated: - case DW_AT_associated: - case DW_AT_data_location: - case DW_AT_description: - case DW_AT_start_scope: - case DW_AT_visibility: - default: - case DW_AT_sibling: - break; - } - } - } - } + // 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()); + + ConstString unique_typename(type_name_const_str); + Declaration unique_decl(decl); + + if (type_name_const_str) { + LanguageType die_language = die.GetLanguage(); + if (Language::LanguageIsCPlusPlus(die_language)) { + // For C++, we rely solely upon the one definition rule that says + // only + // one thing can exist at a given decl context. We ignore the file + // and + // line that things are declared on. + std::string qualified_name; + if (die.GetQualifiedName(qualified_name)) + unique_typename = ConstString(qualified_name); + unique_decl.Clear(); + } + + if (dwarf->GetUniqueDWARFASTTypeMap().Find( + unique_typename, die, unique_decl, + byte_size_valid ? byte_size : -1, *unique_ast_entry_ap)) { + type_sp = unique_ast_entry_ap->m_type_sp; + if (type_sp) { + dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); + return type_sp; + } + } + } - // 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()); - - ConstString unique_typename(type_name_const_str); - Declaration unique_decl(decl); - - if (type_name_const_str) - { - LanguageType die_language = die.GetLanguage(); - if (Language::LanguageIsCPlusPlus(die_language)) - { - // For C++, we rely solely upon the one definition rule that says only - // one thing can exist at a given decl context. We ignore the file and - // line that things are declared on. - std::string qualified_name; - if (die.GetQualifiedName(qualified_name)) - unique_typename = ConstString(qualified_name); - unique_decl.Clear(); - } + DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), + DW_TAG_value_to_name(tag), type_name_cstr); + + int tag_decl_kind = -1; + AccessType default_accessibility = eAccessNone; + if (tag == DW_TAG_structure_type) { + tag_decl_kind = clang::TTK_Struct; + default_accessibility = eAccessPublic; + } else if (tag == DW_TAG_union_type) { + tag_decl_kind = clang::TTK_Union; + default_accessibility = eAccessPublic; + } else if (tag == DW_TAG_class_type) { + tag_decl_kind = clang::TTK_Class; + default_accessibility = eAccessPrivate; + } - if (dwarf->GetUniqueDWARFASTTypeMap().Find(unique_typename, die, unique_decl, - byte_size_valid ? byte_size : -1, - *unique_ast_entry_ap)) - { - type_sp = unique_ast_entry_ap->m_type_sp; - if (type_sp) - { - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); - return type_sp; - } - } - } + if (byte_size_valid && byte_size == 0 && type_name_cstr && + die.HasChildren() == false && + sc.comp_unit->GetLanguage() == eLanguageTypeObjC) { + // Work around an issue with clang at the moment where + // forward declarations for objective C classes are emitted + // as: + // DW_TAG_structure_type [2] + // DW_AT_name( "ForwardObjcClass" ) + // DW_AT_byte_size( 0x00 ) + // DW_AT_decl_file( "..." ) + // DW_AT_decl_line( 1 ) + // + // Note that there is no DW_AT_declaration and there are + // no children, and the byte size is zero. + is_forward_declaration = true; + } - DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr); + if (class_language == eLanguageTypeObjC || + class_language == eLanguageTypeObjC_plus_plus) { + if (!is_complete_objc_class && + die.Supports_DW_AT_APPLE_objc_complete_type()) { + // We have a valid eSymbolTypeObjCClass class symbol whose + // name matches the current objective C class that we + // are trying to find and this DIE isn't the complete + // definition (we checked is_complete_objc_class above and + // know it is false), so the real definition is in here somewhere + type_sp = dwarf->FindCompleteObjCDefinitionTypeForDIE( + die, type_name_const_str, true); + + if (!type_sp) { + SymbolFileDWARFDebugMap *debug_map_symfile = + dwarf->GetDebugMapSymfile(); + if (debug_map_symfile) { + // We weren't able to find a full declaration in + // this DWARF, see if we have a declaration anywhere + // else... + type_sp = + debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE( + die, type_name_const_str, true); + } + } - int tag_decl_kind = -1; - AccessType default_accessibility = eAccessNone; - if (tag == DW_TAG_structure_type) - { - tag_decl_kind = clang::TTK_Struct; - default_accessibility = eAccessPublic; - } - else if (tag == DW_TAG_union_type) - { - tag_decl_kind = clang::TTK_Union; - default_accessibility = eAccessPublic; - } - else if (tag == DW_TAG_class_type) - { - tag_decl_kind = clang::TTK_Class; - default_accessibility = eAccessPrivate; - } + if (type_sp) { + if (log) { + dwarf->GetObjectFile()->GetModule()->LogMessage( + log, "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is an " + "incomplete objc type, complete type is 0x%8.8" PRIx64, + static_cast<void *>(this), die.GetOffset(), + DW_TAG_value_to_name(tag), type_name_cstr, + type_sp->GetID()); + } + + // We found a real definition for this type elsewhere + // so lets use it and cache the fact that we found + // a complete type for this die + dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); + return type_sp; + } + } + } - if (byte_size_valid && byte_size == 0 && type_name_cstr && - die.HasChildren() == false && - sc.comp_unit->GetLanguage() == eLanguageTypeObjC) - { - // Work around an issue with clang at the moment where - // forward declarations for objective C classes are emitted - // as: - // DW_TAG_structure_type [2] - // DW_AT_name( "ForwardObjcClass" ) - // DW_AT_byte_size( 0x00 ) - // DW_AT_decl_file( "..." ) - // DW_AT_decl_line( 1 ) - // - // Note that there is no DW_AT_declaration and there are - // no children, and the byte size is zero. - is_forward_declaration = true; - } + if (is_forward_declaration) { + // We have a forward declaration to a type and we need + // to try and find a full declaration. We look in the + // current type index just in case we have a forward + // declaration followed by an actual declarations in the + // DWARF. If this fails, we need to look elsewhere... + if (log) { + dwarf->GetObjectFile()->GetModule()->LogMessage( + log, "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a " + "forward declaration, trying to find complete type", + static_cast<void *>(this), die.GetOffset(), + DW_TAG_value_to_name(tag), type_name_cstr); + } + + // See if the type comes from a DWO module and if so, track down that + // type. + type_sp = ParseTypeFromDWO(die, log); + if (type_sp) + return type_sp; + + DWARFDeclContext die_decl_ctx; + die.GetDWARFDeclContext(die_decl_ctx); + + // type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, + // type_name_const_str); + type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx); + + if (!type_sp) { + SymbolFileDWARFDebugMap *debug_map_symfile = + dwarf->GetDebugMapSymfile(); + if (debug_map_symfile) { + // We weren't able to find a full declaration in + // this DWARF, see if we have a declaration anywhere + // else... + type_sp = + debug_map_symfile->FindDefinitionTypeForDWARFDeclContext( + die_decl_ctx); + } + } + + if (type_sp) { + if (log) { + dwarf->GetObjectFile()->GetModule()->LogMessage( + log, "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a " + "forward declaration, complete type is 0x%8.8" PRIx64, + static_cast<void *>(this), die.GetOffset(), + DW_TAG_value_to_name(tag), type_name_cstr, type_sp->GetID()); + } - if (class_language == eLanguageTypeObjC || - class_language == eLanguageTypeObjC_plus_plus) - { - if (!is_complete_objc_class && die.Supports_DW_AT_APPLE_objc_complete_type()) - { - // We have a valid eSymbolTypeObjCClass class symbol whose - // name matches the current objective C class that we - // are trying to find and this DIE isn't the complete - // definition (we checked is_complete_objc_class above and - // know it is false), so the real definition is in here somewhere - type_sp = dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name_const_str, true); - - if (!type_sp) - { - SymbolFileDWARFDebugMap *debug_map_symfile = dwarf->GetDebugMapSymfile(); - if (debug_map_symfile) - { - // We weren't able to find a full declaration in - // this DWARF, see if we have a declaration anywhere - // else... - type_sp = debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE (die, type_name_const_str, true); - } - } + // We found a real definition for this type elsewhere + // so lets use it and cache the fact that we found + // a complete type for this die + dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); + clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE( + dwarf->DebugInfo()->GetDIE(DIERef(type_sp->GetID(), dwarf))); + if (defn_decl_ctx) + LinkDeclContextToDIE(defn_decl_ctx, die); + return type_sp; + } + } + assert(tag_decl_kind != -1); + bool clang_type_was_created = false; + clang_type.SetCompilerType( + &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE())); + if (!clang_type) { + clang::DeclContext *decl_ctx = + GetClangDeclContextContainingDIE(die, nullptr); + if (accessibility == eAccessNone && decl_ctx) { + // Check the decl context that contains this class/struct/union. + // If it is a class we must give it an accessibility. + const clang::Decl::Kind containing_decl_kind = + decl_ctx->getDeclKind(); + if (DeclKindIsCXXClass(containing_decl_kind)) + accessibility = default_accessibility; + } + + ClangASTMetadata metadata; + metadata.SetUserID(die.GetID()); + metadata.SetIsDynamicCXXType(dwarf->ClassOrStructIsVirtual(die)); + + if (type_name_cstr && strchr(type_name_cstr, '<')) { + ClangASTContext::TemplateParameterInfos template_param_infos; + if (ParseTemplateParameterInfos(die, template_param_infos)) { + clang::ClassTemplateDecl *class_template_decl = + m_ast.ParseClassTemplateDecl(decl_ctx, accessibility, + type_name_cstr, tag_decl_kind, + template_param_infos); + + clang::ClassTemplateSpecializationDecl + *class_specialization_decl = + m_ast.CreateClassTemplateSpecializationDecl( + decl_ctx, class_template_decl, tag_decl_kind, + template_param_infos); + clang_type = m_ast.CreateClassTemplateSpecializationType( + class_specialization_decl); + clang_type_was_created = true; + + m_ast.SetMetadata(class_template_decl, metadata); + m_ast.SetMetadata(class_specialization_decl, metadata); + } + } + + if (!clang_type_was_created) { + clang_type_was_created = true; + clang_type = m_ast.CreateRecordType(decl_ctx, accessibility, + type_name_cstr, tag_decl_kind, + class_language, &metadata); + } + } - if (type_sp) - { - if (log) - { - dwarf->GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is an incomplete objc type, complete type is 0x%8.8" PRIx64, - static_cast<void*>(this), - die.GetOffset(), - DW_TAG_value_to_name(tag), - type_name_cstr, - type_sp->GetID()); - } + // Store a forward declaration to this class type in case any + // parameters in any class methods need it for the clang + // types for function prototypes. + LinkDeclContextToDIE(m_ast.GetDeclContextForType(clang_type), die); + type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, + byte_size, NULL, LLDB_INVALID_UID, + Type::eEncodingIsUID, &decl, clang_type, + Type::eResolveStateForward)); + + type_sp->SetIsCompleteObjCClass(is_complete_objc_class); + + // 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 = unique_decl; + unique_ast_entry_ap->m_byte_size = byte_size; + dwarf->GetUniqueDWARFASTTypeMap().Insert(unique_typename, + *unique_ast_entry_ap); + + if (is_forward_declaration && die.HasChildren()) { + // Check to see if the DIE actually has a definition, some version of + // GCC will + // emit DIEs with DW_AT_declaration set to true, but yet still have + // subprogram, + // members, or inheritance, so we can't trust it + DWARFDIE child_die = die.GetFirstChild(); + while (child_die) { + switch (child_die.Tag()) { + case DW_TAG_inheritance: + case DW_TAG_subprogram: + case DW_TAG_member: + case DW_TAG_APPLE_property: + case DW_TAG_class_type: + case DW_TAG_structure_type: + case DW_TAG_enumeration_type: + case DW_TAG_typedef: + case DW_TAG_union_type: + child_die.Clear(); + is_forward_declaration = false; + break; + default: + child_die = child_die.GetSibling(); + break; + } + } + } - // We found a real definition for this type elsewhere - // so lets use it and cache the fact that we found - // a complete type for this die - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); - return type_sp; - } - } - } + 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 + if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) { + ClangASTContext::CompleteTagDeclarationDefinition(clang_type); + } else { + dwarf->GetObjectFile()->GetModule()->ReportError( + "DWARF DIE at 0x%8.8x named \"%s\" was not able to start its " + "definition.\nPlease file a bug and attach the file at the " + "start of this error message", + die.GetOffset(), type_name_cstr); + } + if (tag == DW_TAG_structure_type) // this only applies in C + { + clang::RecordDecl *record_decl = + ClangASTContext::GetAsRecordDecl(clang_type); - if (is_forward_declaration) - { - // We have a forward declaration to a type and we need - // to try and find a full declaration. We look in the - // current type index just in case we have a forward - // declaration followed by an actual declarations in the - // DWARF. If this fails, we need to look elsewhere... - if (log) - { - dwarf->GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, trying to find complete type", - static_cast<void*>(this), - die.GetOffset(), - DW_TAG_value_to_name(tag), - type_name_cstr); - } + if (record_decl) { + GetClangASTImporter().InsertRecordDecl( + record_decl, ClangASTImporter::LayoutInfo()); + } + } + } else if (clang_type_was_created) { + // Start the definition if the class is not objective C since + // the underlying decls respond to isCompleteDefinition(). Objective + // C decls don't respond to isCompleteDefinition() so we can't + // start the declaration definition right away. For C++ + // class/union/structs + // we want to start the definition in case the class is needed as + // the + // declaration context for a contained class or type without the + // need + // to complete that type.. + + if (class_language != eLanguageTypeObjC && + class_language != eLanguageTypeObjC_plus_plus) + ClangASTContext::StartTagDeclarationDefinition(clang_type); + + // 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. + assert(!dwarf->GetForwardDeclClangTypeToDie().count( + ClangUtil::RemoveFastQualifiers(clang_type) + .GetOpaqueQualType()) && + "Type already in the forward declaration map!"); + // Can't assume m_ast.GetSymbolFile() is actually a SymbolFileDWARF, + // it can be a + // SymbolFileDWARFDebugMap for Apple binaries. + dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] = + clang_type.GetOpaqueQualType(); + dwarf->GetForwardDeclClangTypeToDie() + [ClangUtil::RemoveFastQualifiers(clang_type) + .GetOpaqueQualType()] = die.GetDIERef(); + m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true); + } + } + } break; - // See if the type comes from a DWO module and if so, track down that type. - type_sp = ParseTypeFromDWO(die, log); - if (type_sp) - return type_sp; - - DWARFDeclContext die_decl_ctx; - die.GetDWARFDeclContext(die_decl_ctx); - - //type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str); - type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx); - - if (!type_sp) - { - SymbolFileDWARFDebugMap *debug_map_symfile = dwarf->GetDebugMapSymfile(); - if (debug_map_symfile) - { - // We weren't able to find a full declaration in - // this DWARF, see if we have a declaration anywhere - // else... - type_sp = debug_map_symfile->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx); - } - } + case DW_TAG_enumeration_type: { + // Set a bit that lets us know that we are currently parsing this + dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED; - if (type_sp) - { - if (log) - { - dwarf->GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, complete type is 0x%8.8" PRIx64, - static_cast<void*>(this), - die.GetOffset(), - DW_TAG_value_to_name(tag), - type_name_cstr, - type_sp->GetID()); - } + DWARFFormValue encoding_form; - // We found a real definition for this type elsewhere - // so lets use it and cache the fact that we found - // a complete type for this die - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); - clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE( - dwarf->DebugInfo()->GetDIE(DIERef(type_sp->GetID(), dwarf))); - if (defn_decl_ctx) - LinkDeclContextToDIE(defn_decl_ctx, die); - return type_sp; - } - } - assert (tag_decl_kind != -1); - bool clang_type_was_created = false; - clang_type.SetCompilerType(&m_ast, dwarf->GetForwardDeclDieToClangType().lookup (die.GetDIE())); - if (!clang_type) - { - clang::DeclContext *decl_ctx = GetClangDeclContextContainingDIE (die, nullptr); - if (accessibility == eAccessNone && decl_ctx) - { - // Check the decl context that contains this class/struct/union. - // If it is a class we must give it an accessibility. - const clang::Decl::Kind containing_decl_kind = decl_ctx->getDeclKind(); - if (DeclKindIsCXXClass (containing_decl_kind)) - accessibility = default_accessibility; - } + 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_decl_file: + decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex( + form_value.Unsigned())); + break; + case DW_AT_decl_line: + decl.SetLine(form_value.Unsigned()); + break; + case DW_AT_decl_column: + decl.SetColumn(form_value.Unsigned()); + break; + case DW_AT_name: + type_name_cstr = form_value.AsCString(); + type_name_const_str.SetCString(type_name_cstr); + break; + case DW_AT_type: + encoding_form = form_value; + break; + case DW_AT_byte_size: + byte_size = form_value.Unsigned(); + break; + case DW_AT_accessibility: + break; // accessibility = + // DW_ACCESS_to_AccessType(form_value.Unsigned()); break; + case DW_AT_declaration: + is_forward_declaration = form_value.Boolean(); + break; + case DW_AT_allocated: + case DW_AT_associated: + case DW_AT_bit_stride: + case DW_AT_byte_stride: + case DW_AT_data_location: + case DW_AT_description: + case DW_AT_start_scope: + case DW_AT_visibility: + case DW_AT_specification: + case DW_AT_abstract_origin: + case DW_AT_sibling: + break; + } + } + } + + if (is_forward_declaration) { + type_sp = ParseTypeFromDWO(die, log); + if (type_sp) + return type_sp; + + DWARFDeclContext die_decl_ctx; + die.GetDWARFDeclContext(die_decl_ctx); + + type_sp = + dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx); + + if (!type_sp) { + SymbolFileDWARFDebugMap *debug_map_symfile = + dwarf->GetDebugMapSymfile(); + if (debug_map_symfile) { + // We weren't able to find a full declaration in + // this DWARF, see if we have a declaration anywhere + // else... + type_sp = + debug_map_symfile->FindDefinitionTypeForDWARFDeclContext( + die_decl_ctx); + } + } - ClangASTMetadata metadata; - metadata.SetUserID(die.GetID()); - metadata.SetIsDynamicCXXType(dwarf->ClassOrStructIsVirtual (die)); - - if (type_name_cstr && strchr (type_name_cstr, '<')) - { - ClangASTContext::TemplateParameterInfos template_param_infos; - if (ParseTemplateParameterInfos (die, template_param_infos)) - { - clang::ClassTemplateDecl *class_template_decl = m_ast.ParseClassTemplateDecl (decl_ctx, - accessibility, - type_name_cstr, - tag_decl_kind, - template_param_infos); - - clang::ClassTemplateSpecializationDecl *class_specialization_decl = m_ast.CreateClassTemplateSpecializationDecl (decl_ctx, - class_template_decl, - tag_decl_kind, - template_param_infos); - clang_type = m_ast.CreateClassTemplateSpecializationType (class_specialization_decl); - clang_type_was_created = true; - - m_ast.SetMetadata (class_template_decl, metadata); - m_ast.SetMetadata (class_specialization_decl, metadata); - } - } + if (type_sp) { + if (log) { + dwarf->GetObjectFile()->GetModule()->LogMessage( + log, "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a " + "forward declaration, complete type is 0x%8.8" PRIx64, + static_cast<void *>(this), die.GetOffset(), + DW_TAG_value_to_name(tag), type_name_cstr, + type_sp->GetID()); + } + + // We found a real definition for this type elsewhere + // so lets use it and cache the fact that we found + // a complete type for this die + dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); + clang::DeclContext *defn_decl_ctx = + GetCachedClangDeclContextForDIE(dwarf->DebugInfo()->GetDIE( + DIERef(type_sp->GetID(), dwarf))); + if (defn_decl_ctx) + LinkDeclContextToDIE(defn_decl_ctx, die); + return type_sp; + } + } + DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), + DW_TAG_value_to_name(tag), type_name_cstr); + + CompilerType enumerator_clang_type; + clang_type.SetCompilerType( + &m_ast, + dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE())); + if (!clang_type) { + if (encoding_form.IsValid()) { + Type *enumerator_type = + dwarf->ResolveTypeUID(DIERef(encoding_form)); + if (enumerator_type) + enumerator_clang_type = enumerator_type->GetFullCompilerType(); + } - if (!clang_type_was_created) - { - clang_type_was_created = true; - clang_type = m_ast.CreateRecordType (decl_ctx, - accessibility, - type_name_cstr, - tag_decl_kind, - class_language, - &metadata); - } - } + if (!enumerator_clang_type) { + if (byte_size > 0) { + enumerator_clang_type = + m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize( + NULL, DW_ATE_signed, byte_size * 8); + } else { + enumerator_clang_type = m_ast.GetBasicType(eBasicTypeInt); + } + } - // Store a forward declaration to this class type in case any - // parameters in any class methods need it for the clang - // types for function prototypes. - LinkDeclContextToDIE(m_ast.GetDeclContextForType(clang_type), die); - type_sp.reset (new Type (die.GetID(), - dwarf, - type_name_const_str, - byte_size, - NULL, - LLDB_INVALID_UID, - Type::eEncodingIsUID, - &decl, - clang_type, - Type::eResolveStateForward)); - - type_sp->SetIsCompleteObjCClass(is_complete_objc_class); - - - // 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 = unique_decl; - unique_ast_entry_ap->m_byte_size = byte_size; - dwarf->GetUniqueDWARFASTTypeMap().Insert (unique_typename, - *unique_ast_entry_ap); - - if (is_forward_declaration && die.HasChildren()) - { - // Check to see if the DIE actually has a definition, some version of GCC will - // emit DIEs with DW_AT_declaration set to true, but yet still have subprogram, - // members, or inheritance, so we can't trust it - DWARFDIE child_die = die.GetFirstChild(); - while (child_die) - { - switch (child_die.Tag()) - { - case DW_TAG_inheritance: - case DW_TAG_subprogram: - case DW_TAG_member: - case DW_TAG_APPLE_property: - case DW_TAG_class_type: - case DW_TAG_structure_type: - case DW_TAG_enumeration_type: - case DW_TAG_typedef: - case DW_TAG_union_type: - child_die.Clear(); - is_forward_declaration = false; - break; - default: - child_die = child_die.GetSibling(); - break; - } - } - } + clang_type = m_ast.CreateEnumerationType( + type_name_cstr, GetClangDeclContextContainingDIE(die, nullptr), + decl, enumerator_clang_type); + } else { + enumerator_clang_type = + m_ast.GetEnumerationIntegerType(clang_type.GetOpaqueQualType()); + } + + LinkDeclContextToDIE( + ClangASTContext::GetDeclContextForType(clang_type), die); + + type_sp.reset(new Type( + die.GetID(), dwarf, type_name_const_str, byte_size, NULL, + DIERef(encoding_form).GetUID(dwarf), Type::eEncodingIsUID, &decl, + clang_type, Type::eResolveStateForward)); + + if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) { + if (die.HasChildren()) { + SymbolContext cu_sc(die.GetLLDBCompileUnit()); + bool is_signed = false; + enumerator_clang_type.IsIntegerType(is_signed); + ParseChildEnumerators(cu_sc, clang_type, is_signed, + type_sp->GetByteSize(), die); + } + ClangASTContext::CompleteTagDeclarationDefinition(clang_type); + } else { + dwarf->GetObjectFile()->GetModule()->ReportError( + "DWARF DIE at 0x%8.8x named \"%s\" was not able to start its " + "definition.\nPlease file a bug and attach the file at the " + "start of this error message", + die.GetOffset(), type_name_cstr); + } + } + } break; + + case DW_TAG_inlined_subroutine: + case DW_TAG_subprogram: + case DW_TAG_subroutine_type: { + // Set a bit that lets us know that we are currently parsing this + dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED; + + DWARFFormValue type_die_form; + bool is_variadic = false; + bool is_inline = false; + bool is_static = false; + bool is_virtual = false; + bool is_explicit = false; + bool is_artificial = false; + bool has_template_params = false; + DWARFFormValue specification_die_form; + DWARFFormValue abstract_origin_die_form; + dw_offset_t object_pointer_die_offset = DW_INVALID_OFFSET; + + unsigned type_quals = 0; + clang::StorageClass storage = + clang::SC_None; //, Extern, Static, PrivateExtern - 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 - if (ClangASTContext::StartTagDeclarationDefinition (clang_type)) - { - ClangASTContext::CompleteTagDeclarationDefinition (clang_type); - } - else - { - dwarf->GetObjectFile()->GetModule()->ReportError("DWARF DIE at 0x%8.8x named \"%s\" was not able to start its definition.\nPlease file a bug and attach the file at the start of this error message", - die.GetOffset(), - type_name_cstr); - } + 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_decl_file: + decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex( + form_value.Unsigned())); + break; + case DW_AT_decl_line: + decl.SetLine(form_value.Unsigned()); + break; + case DW_AT_decl_column: + decl.SetColumn(form_value.Unsigned()); + break; + case DW_AT_name: + type_name_cstr = form_value.AsCString(); + type_name_const_str.SetCString(type_name_cstr); + break; - if (tag == DW_TAG_structure_type) // this only applies in C - { - clang::RecordDecl *record_decl = ClangASTContext::GetAsRecordDecl(clang_type); + case DW_AT_linkage_name: + case DW_AT_MIPS_linkage_name: + break; // mangled = + // form_value.AsCString(&dwarf->get_debug_str_data()); + // break; + case DW_AT_type: + type_die_form = form_value; + break; + case DW_AT_accessibility: + accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); + break; + case DW_AT_declaration: + break; // is_forward_declaration = form_value.Boolean(); break; + case DW_AT_inline: + is_inline = form_value.Boolean(); + break; + case DW_AT_virtuality: + is_virtual = form_value.Boolean(); + break; + case DW_AT_explicit: + is_explicit = form_value.Boolean(); + break; + case DW_AT_artificial: + is_artificial = form_value.Boolean(); + break; - if (record_decl) - { - GetClangASTImporter().InsertRecordDecl(record_decl, ClangASTImporter::LayoutInfo()); - } - } - } - else if (clang_type_was_created) - { - // Start the definition if the class is not objective C since - // the underlying decls respond to isCompleteDefinition(). Objective - // C decls don't respond to isCompleteDefinition() so we can't - // start the declaration definition right away. For C++ class/union/structs - // we want to start the definition in case the class is needed as the - // declaration context for a contained class or type without the need - // to complete that type.. - - if (class_language != eLanguageTypeObjC && - class_language != eLanguageTypeObjC_plus_plus) - ClangASTContext::StartTagDeclarationDefinition (clang_type); - - // 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. - assert(!dwarf->GetForwardDeclClangTypeToDie().count( - ClangUtil::RemoveFastQualifiers(clang_type).GetOpaqueQualType()) && - "Type already in the forward declaration map!"); - // Can't assume m_ast.GetSymbolFile() is actually a SymbolFileDWARF, it can be a - // SymbolFileDWARFDebugMap for Apple binaries. - dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] = clang_type.GetOpaqueQualType(); - dwarf->GetForwardDeclClangTypeToDie()[ClangUtil::RemoveFastQualifiers(clang_type) - .GetOpaqueQualType()] = die.GetDIERef(); - m_ast.SetHasExternalStorage (clang_type.GetOpaqueQualType(), true); - } - } + 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_TAG_enumeration_type: - { - // Set a bit that lets us know that we are currently parsing this - dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED; - - DWARFFormValue encoding_form; - - 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_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; - case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; - case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; - case DW_AT_name: - type_name_cstr = form_value.AsCString(); - type_name_const_str.SetCString(type_name_cstr); - break; - case DW_AT_type: encoding_form = form_value; break; - case DW_AT_byte_size: byte_size = form_value.Unsigned(); break; - case DW_AT_accessibility: break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; - case DW_AT_declaration: is_forward_declaration = form_value.Boolean(); break; - case DW_AT_allocated: - case DW_AT_associated: - case DW_AT_bit_stride: - case DW_AT_byte_stride: - case DW_AT_data_location: - case DW_AT_description: - case DW_AT_start_scope: - case DW_AT_visibility: - case DW_AT_specification: - case DW_AT_abstract_origin: - case DW_AT_sibling: - break; - } - } - } - - if (is_forward_declaration) - { - type_sp = ParseTypeFromDWO(die, log); - if (type_sp) - return type_sp; - - DWARFDeclContext die_decl_ctx; - die.GetDWARFDeclContext(die_decl_ctx); - - type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx); - - if (!type_sp) - { - SymbolFileDWARFDebugMap *debug_map_symfile = dwarf->GetDebugMapSymfile(); - if (debug_map_symfile) - { - // We weren't able to find a full declaration in - // this DWARF, see if we have a declaration anywhere - // else... - type_sp = debug_map_symfile->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx); - } - } - - if (type_sp) - { - if (log) - { - dwarf->GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, complete type is 0x%8.8" PRIx64, - static_cast<void*>(this), - die.GetOffset(), - DW_TAG_value_to_name(tag), - type_name_cstr, - type_sp->GetID()); - } - - // We found a real definition for this type elsewhere - // so lets use it and cache the fact that we found - // a complete type for this die - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); - clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(dwarf->DebugInfo()->GetDIE(DIERef(type_sp->GetID(), dwarf))); - if (defn_decl_ctx) - LinkDeclContextToDIE(defn_decl_ctx, die); - return type_sp; - } + break; - } - DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr); - - CompilerType enumerator_clang_type; - clang_type.SetCompilerType (&m_ast, dwarf->GetForwardDeclDieToClangType().lookup (die.GetDIE())); - if (!clang_type) - { - if (encoding_form.IsValid()) - { - Type *enumerator_type = dwarf->ResolveTypeUID(DIERef(encoding_form)); - if (enumerator_type) - enumerator_clang_type = enumerator_type->GetFullCompilerType (); - } + case DW_AT_specification: + specification_die_form = form_value; + break; - if (!enumerator_clang_type) - { - if (byte_size > 0) - { - enumerator_clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize(NULL, - DW_ATE_signed, - byte_size * 8); - } - else - { - enumerator_clang_type = m_ast.GetBasicType(eBasicTypeInt); - } - } + case DW_AT_abstract_origin: + abstract_origin_die_form = form_value; + break; - clang_type = m_ast.CreateEnumerationType (type_name_cstr, - GetClangDeclContextContainingDIE (die, nullptr), - decl, - enumerator_clang_type); - } - else - { - enumerator_clang_type = m_ast.GetEnumerationIntegerType (clang_type.GetOpaqueQualType()); - } + case DW_AT_object_pointer: + object_pointer_die_offset = form_value.Reference(); + break; - LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die); - - type_sp.reset( new Type (die.GetID(), - dwarf, - type_name_const_str, - byte_size, - NULL, - DIERef(encoding_form).GetUID(dwarf), - Type::eEncodingIsUID, - &decl, - clang_type, - Type::eResolveStateForward)); - - if (ClangASTContext::StartTagDeclarationDefinition (clang_type)) - { - if (die.HasChildren()) - { - SymbolContext cu_sc(die.GetLLDBCompileUnit()); - bool is_signed = false; - enumerator_clang_type.IsIntegerType(is_signed); - ParseChildEnumerators(cu_sc, clang_type, is_signed, type_sp->GetByteSize(), die); - } - ClangASTContext::CompleteTagDeclarationDefinition (clang_type); - } - else - { - dwarf->GetObjectFile()->GetModule()->ReportError("DWARF DIE at 0x%8.8x named \"%s\" was not able to start its definition.\nPlease file a bug and attach the file at the start of this error message", - die.GetOffset(), - type_name_cstr); - } - } - } - break; - - case DW_TAG_inlined_subroutine: - case DW_TAG_subprogram: - case DW_TAG_subroutine_type: - { - // Set a bit that lets us know that we are currently parsing this - dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED; - - DWARFFormValue type_die_form; - bool is_variadic = false; - bool is_inline = false; - bool is_static = false; - bool is_virtual = false; - bool is_explicit = false; - bool is_artificial = false; - bool has_template_params = false; - DWARFFormValue specification_die_form; - DWARFFormValue abstract_origin_die_form; - dw_offset_t object_pointer_die_offset = DW_INVALID_OFFSET; - - unsigned type_quals = 0; - 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_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; - case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; - case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; - case DW_AT_name: - type_name_cstr = form_value.AsCString(); - type_name_const_str.SetCString(type_name_cstr); - break; - - case DW_AT_linkage_name: - case DW_AT_MIPS_linkage_name: break; // mangled = form_value.AsCString(&dwarf->get_debug_str_data()); break; - case DW_AT_type: type_die_form = form_value; break; - case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; - case DW_AT_declaration: break; // is_forward_declaration = form_value.Boolean(); break; - case DW_AT_inline: is_inline = form_value.Boolean(); break; - case DW_AT_virtuality: is_virtual = form_value.Boolean(); break; - case DW_AT_explicit: is_explicit = form_value.Boolean(); break; - case DW_AT_artificial: is_artificial = form_value.Boolean(); 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_specification: - specification_die_form = form_value; - break; - - case DW_AT_abstract_origin: - abstract_origin_die_form = form_value; - break; - - case DW_AT_object_pointer: - object_pointer_die_offset = form_value.Reference(); - break; - - case DW_AT_allocated: - case DW_AT_associated: - case DW_AT_address_class: - case DW_AT_calling_convention: - case DW_AT_data_location: - case DW_AT_elemental: - case DW_AT_entry_pc: - case DW_AT_frame_base: - case DW_AT_high_pc: - case DW_AT_low_pc: - case DW_AT_prototyped: - case DW_AT_pure: - case DW_AT_ranges: - case DW_AT_recursive: - case DW_AT_return_addr: - case DW_AT_segment: - case DW_AT_start_scope: - case DW_AT_static_link: - case DW_AT_trampoline: - case DW_AT_visibility: - case DW_AT_vtable_elem_location: - case DW_AT_description: - case DW_AT_sibling: - break; - } - } - } - } + case DW_AT_allocated: + case DW_AT_associated: + case DW_AT_address_class: + case DW_AT_calling_convention: + case DW_AT_data_location: + case DW_AT_elemental: + case DW_AT_entry_pc: + case DW_AT_frame_base: + case DW_AT_high_pc: + case DW_AT_low_pc: + case DW_AT_prototyped: + case DW_AT_pure: + case DW_AT_ranges: + case DW_AT_recursive: + case DW_AT_return_addr: + case DW_AT_segment: + case DW_AT_start_scope: + case DW_AT_static_link: + case DW_AT_trampoline: + case DW_AT_visibility: + case DW_AT_vtable_elem_location: + case DW_AT_description: + case DW_AT_sibling: + break; + } + } + } + } - std::string object_pointer_name; - if (object_pointer_die_offset != DW_INVALID_OFFSET) - { - DWARFDIE object_pointer_die = die.GetDIE (object_pointer_die_offset); - if (object_pointer_die) - { - const char *object_pointer_name_cstr = object_pointer_die.GetName(); - if (object_pointer_name_cstr) - object_pointer_name = object_pointer_name_cstr; - } - } + std::string object_pointer_name; + if (object_pointer_die_offset != DW_INVALID_OFFSET) { + DWARFDIE object_pointer_die = die.GetDIE(object_pointer_die_offset); + if (object_pointer_die) { + const char *object_pointer_name_cstr = object_pointer_die.GetName(); + if (object_pointer_name_cstr) + object_pointer_name = object_pointer_name_cstr; + } + } - DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr); + DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), + DW_TAG_value_to_name(tag), type_name_cstr); - CompilerType return_clang_type; - Type *func_type = NULL; + CompilerType return_clang_type; + Type *func_type = NULL; - if (type_die_form.IsValid()) - func_type = dwarf->ResolveTypeUID(DIERef(type_die_form)); + if (type_die_form.IsValid()) + func_type = dwarf->ResolveTypeUID(DIERef(type_die_form)); - if (func_type) - return_clang_type = func_type->GetForwardCompilerType (); - else - return_clang_type = m_ast.GetBasicType(eBasicTypeVoid); + if (func_type) + return_clang_type = func_type->GetForwardCompilerType(); + else + return_clang_type = m_ast.GetBasicType(eBasicTypeVoid); + std::vector<CompilerType> function_param_types; + std::vector<clang::ParmVarDecl *> function_param_decls; - std::vector<CompilerType> function_param_types; - std::vector<clang::ParmVarDecl*> function_param_decls; + // Parse the function children for the parameters - // Parse the function children for the parameters + DWARFDIE decl_ctx_die; + clang::DeclContext *containing_decl_ctx = + GetClangDeclContextContainingDIE(die, &decl_ctx_die); + const clang::Decl::Kind containing_decl_kind = + containing_decl_ctx->getDeclKind(); - DWARFDIE decl_ctx_die; - clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (die, &decl_ctx_die); - const clang::Decl::Kind containing_decl_kind = containing_decl_ctx->getDeclKind(); + bool is_cxx_method = DeclKindIsCXXClass(containing_decl_kind); + // Start off static. This will be set to false in + // ParseChildParameters(...) + // if we find a "this" parameters as the first parameter + if (is_cxx_method) { + is_static = true; + } - bool is_cxx_method = DeclKindIsCXXClass (containing_decl_kind); - // Start off static. This will be set to false in ParseChildParameters(...) - // if we find a "this" parameters as the first parameter - if (is_cxx_method) - { - is_static = true; - } + 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); + } - 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); - } + bool ignore_containing_context = false; + // Check for templatized class member functions. If we had any + // DW_TAG_template_type_parameter + // or DW_TAG_template_value_parameter the DW_TAG_subprogram DIE, then we + // can't let this become + // a method in a class. Why? Because templatized functions are only + // emitted if one of the + // templatized methods is used in the current compile unit and we will + // end up with classes + // that may or may not include these member functions and this means one + // class won't match another + // class definition and it affects our ability to use a class in the + // clang expression parser. So + // for the greater good, we currently must not allow any template member + // functions in a class definition. + if (is_cxx_method && has_template_params) { + ignore_containing_context = true; + is_cxx_method = false; + } - bool ignore_containing_context = false; - // Check for templatized class member functions. If we had any DW_TAG_template_type_parameter - // or DW_TAG_template_value_parameter the DW_TAG_subprogram DIE, then we can't let this become - // a method in a class. Why? Because templatized functions are only emitted if one of the - // templatized methods is used in the current compile unit and we will end up with classes - // that may or may not include these member functions and this means one class won't match another - // class definition and it affects our ability to use a class in the clang expression parser. So - // for the greater good, we currently must not allow any template member functions in a class definition. - if (is_cxx_method && has_template_params) - { - ignore_containing_context = true; - is_cxx_method = false; + // clang_type will get the function prototype clang type after this call + clang_type = m_ast.CreateFunctionType( + return_clang_type, function_param_types.data(), + function_param_types.size(), is_variadic, type_quals); + + if (type_name_cstr) { + bool type_handled = false; + if (tag == DW_TAG_subprogram || tag == DW_TAG_inlined_subroutine) { + ObjCLanguage::MethodName objc_method(type_name_cstr, true); + if (objc_method.IsValid(true)) { + CompilerType class_opaque_type; + ConstString class_name(objc_method.GetClassName()); + if (class_name) { + TypeSP complete_objc_class_type_sp( + dwarf->FindCompleteObjCDefinitionTypeForDIE( + DWARFDIE(), class_name, false)); + + if (complete_objc_class_type_sp) { + CompilerType type_clang_forward_type = + complete_objc_class_type_sp->GetForwardCompilerType(); + if (ClangASTContext::IsObjCObjectOrInterfaceType( + type_clang_forward_type)) + class_opaque_type = type_clang_forward_type; + } + } + + if (class_opaque_type) { + // If accessibility isn't set to anything valid, assume public + // for + // now... + if (accessibility == eAccessNone) + accessibility = eAccessPublic; + + clang::ObjCMethodDecl *objc_method_decl = + m_ast.AddMethodToObjCObjectType( + class_opaque_type, type_name_cstr, clang_type, + accessibility, is_artificial, is_variadic); + type_handled = objc_method_decl != NULL; + if (type_handled) { + LinkDeclContextToDIE( + ClangASTContext::GetAsDeclContext(objc_method_decl), die); + m_ast.SetMetadataAsUserID(objc_method_decl, die.GetID()); + } else { + dwarf->GetObjectFile()->GetModule()->ReportError( + "{0x%8.8x}: invalid Objective-C method 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)); + } + } + } else if (is_cxx_method) { + // Look at the parent of this DIE and see if is is + // a class or struct and see if this is actually a + // C++ method + Type *class_type = dwarf->ResolveType(decl_ctx_die); + if (class_type) { + bool alternate_defn = false; + if (class_type->GetID() != decl_ctx_die.GetID() || + decl_ctx_die.GetContainingDWOModuleDIE()) { + alternate_defn = true; + + // We uniqued the parent class of this function to another + // class + // so we now need to associate all dies under "decl_ctx_die" + // to + // DIEs in the DIE for "class_type"... + SymbolFileDWARF *class_symfile = NULL; + DWARFDIE class_type_die; + + SymbolFileDWARFDebugMap *debug_map_symfile = + dwarf->GetDebugMapSymfile(); + if (debug_map_symfile) { + class_symfile = debug_map_symfile->GetSymbolFileByOSOIndex( + SymbolFileDWARFDebugMap::GetOSOIndexFromUserID( + class_type->GetID())); + class_type_die = class_symfile->DebugInfo()->GetDIE( + DIERef(class_type->GetID(), dwarf)); + } else { + class_symfile = dwarf; + class_type_die = dwarf->DebugInfo()->GetDIE( + DIERef(class_type->GetID(), dwarf)); + } + if (class_type_die) { + DWARFDIECollection failures; + + CopyUniqueClassMethodTypes(decl_ctx_die, class_type_die, + class_type, failures); + + // FIXME do something with these failures that's smarter + // than + // just dropping them on the ground. Unfortunately classes + // don't + // like having stuff added to them after their definitions + // are + // complete... + + type_ptr = dwarf->GetDIEToType()[die.GetDIE()]; + if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) { + type_sp = type_ptr->shared_from_this(); + break; } + } + } - // clang_type will get the function prototype clang type after this call - clang_type = m_ast.CreateFunctionType (return_clang_type, - function_param_types.data(), - function_param_types.size(), - is_variadic, - type_quals); - - - if (type_name_cstr) - { - bool type_handled = false; - if (tag == DW_TAG_subprogram || - tag == DW_TAG_inlined_subroutine) - { - ObjCLanguage::MethodName objc_method (type_name_cstr, true); - if (objc_method.IsValid(true)) - { - CompilerType class_opaque_type; - ConstString class_name(objc_method.GetClassName()); - if (class_name) - { - TypeSP complete_objc_class_type_sp (dwarf->FindCompleteObjCDefinitionTypeForDIE (DWARFDIE(), class_name, false)); - - if (complete_objc_class_type_sp) - { - CompilerType type_clang_forward_type = complete_objc_class_type_sp->GetForwardCompilerType (); - if (ClangASTContext::IsObjCObjectOrInterfaceType(type_clang_forward_type)) - class_opaque_type = type_clang_forward_type; - } - } - - if (class_opaque_type) - { - // If accessibility isn't set to anything valid, assume public for - // now... - if (accessibility == eAccessNone) - accessibility = eAccessPublic; - - clang::ObjCMethodDecl *objc_method_decl = m_ast.AddMethodToObjCObjectType (class_opaque_type, - type_name_cstr, - clang_type, - accessibility, - is_artificial, - is_variadic); - type_handled = objc_method_decl != NULL; - if (type_handled) - { - LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(objc_method_decl), die); - m_ast.SetMetadataAsUserID (objc_method_decl, die.GetID()); - } - else - { - dwarf->GetObjectFile()->GetModule()->ReportError ("{0x%8.8x}: invalid Objective-C method 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)); - } - } - } - else if (is_cxx_method) - { - // Look at the parent of this DIE and see if is is - // a class or struct and see if this is actually a - // C++ method - Type *class_type = dwarf->ResolveType (decl_ctx_die); - if (class_type) - { - bool alternate_defn = false; - if (class_type->GetID() != decl_ctx_die.GetID() || decl_ctx_die.GetContainingDWOModuleDIE()) - { - alternate_defn = true; - - // We uniqued the parent class of this function to another class - // so we now need to associate all dies under "decl_ctx_die" to - // DIEs in the DIE for "class_type"... - SymbolFileDWARF *class_symfile = NULL; - DWARFDIE class_type_die; - - SymbolFileDWARFDebugMap *debug_map_symfile = dwarf->GetDebugMapSymfile(); - if (debug_map_symfile) - { - class_symfile = debug_map_symfile->GetSymbolFileByOSOIndex(SymbolFileDWARFDebugMap::GetOSOIndexFromUserID(class_type->GetID())); - class_type_die = class_symfile->DebugInfo()->GetDIE (DIERef(class_type->GetID(), dwarf)); - } - else - { - class_symfile = dwarf; - class_type_die = dwarf->DebugInfo()->GetDIE (DIERef(class_type->GetID(), dwarf)); - } - if (class_type_die) - { - DWARFDIECollection failures; - - CopyUniqueClassMethodTypes (decl_ctx_die, - class_type_die, - class_type, - failures); - - // FIXME do something with these failures that's smarter than - // just dropping them on the ground. Unfortunately classes don't - // like having stuff added to them after their definitions are - // complete... - - type_ptr = dwarf->GetDIEToType()[die.GetDIE()]; - if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) - { - type_sp = type_ptr->shared_from_this(); - break; - } - } - } - - if (specification_die_form.IsValid()) - { - // We have a specification which we are going to base our function - // prototype off of, so we need this type to be completed so that the - // m_die_to_decl_ctx for the method in the specification has a valid - // clang decl context. - class_type->GetForwardCompilerType (); - // If we have a specification, then the function type should have been - // made with the specification and not with this die. - DWARFDIE spec_die = dwarf->DebugInfo()->GetDIE(DIERef(specification_die_form)); - clang::DeclContext *spec_clang_decl_ctx = GetClangDeclContextForDIE (spec_die); - if (spec_clang_decl_ctx) - { - LinkDeclContextToDIE(spec_clang_decl_ctx, die); - } - else - { - dwarf->GetObjectFile()->GetModule()->ReportWarning ("0x%8.8" PRIx64 ": DW_AT_specification(0x%8.8" PRIx64 ") has no decl\n", - die.GetID(), - specification_die_form.Reference()); - } - type_handled = true; - } - else if (abstract_origin_die_form.IsValid()) - { - // We have a specification which we are going to base our function - // prototype off of, so we need this type to be completed so that the - // m_die_to_decl_ctx for the method in the abstract origin has a valid - // clang decl context. - class_type->GetForwardCompilerType (); - - DWARFDIE abs_die = dwarf->DebugInfo()->GetDIE (DIERef(abstract_origin_die_form)); - clang::DeclContext *abs_clang_decl_ctx = GetClangDeclContextForDIE (abs_die); - if (abs_clang_decl_ctx) - { - LinkDeclContextToDIE (abs_clang_decl_ctx, die); - } - else - { - dwarf->GetObjectFile()->GetModule()->ReportWarning ("0x%8.8" PRIx64 ": DW_AT_abstract_origin(0x%8.8" PRIx64 ") has no decl\n", - die.GetID(), - abstract_origin_die_form.Reference()); - } - type_handled = true; - } - else - { - CompilerType class_opaque_type = class_type->GetForwardCompilerType (); - if (ClangASTContext::IsCXXClassType(class_opaque_type)) - { - if (class_opaque_type.IsBeingDefined () || alternate_defn) - { - if (!is_static && !die.HasChildren()) - { - // We have a C++ member function with no children (this pointer!) - // and clang will get mad if we try and make a function that isn't - // well formed in the DWARF, so we will just skip it... - type_handled = true; - } - else - { - bool add_method = true; - if (alternate_defn) - { - // If an alternate definition for the class exists, then add the method only if an - // equivalent is not already present. - clang::CXXRecordDecl *record_decl = m_ast.GetAsCXXRecordDecl(class_opaque_type.GetOpaqueQualType()); - if (record_decl) - { - for (auto method_iter = record_decl->method_begin(); - method_iter != record_decl->method_end(); - method_iter++) - { - clang::CXXMethodDecl *method_decl = *method_iter; - if (method_decl->getNameInfo().getAsString() == std::string(type_name_cstr)) - { - if (method_decl->getType() == - ClangUtil::GetQualType(clang_type)) - { - add_method = false; - LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(method_decl), die); - type_handled = true; - - break; - } - } - } - } - } - - if (add_method) - { - // REMOVE THE CRASH DESCRIPTION BELOW - Host::SetCrashDescriptionWithFormat ("SymbolFileDWARF::ParseType() is adding a method %s to class %s in DIE 0x%8.8" PRIx64 " from %s", - type_name_cstr, - class_type->GetName().GetCString(), - die.GetID(), - dwarf->GetObjectFile()->GetFileSpec().GetPath().c_str()); - - const bool is_attr_used = false; - // Neither GCC 4.2 nor clang++ currently set a valid accessibility - // in the DWARF for C++ methods... Default to public for now... - if (accessibility == eAccessNone) - accessibility = eAccessPublic; - - clang::CXXMethodDecl *cxx_method_decl; - cxx_method_decl = m_ast.AddMethodToCXXRecordType (class_opaque_type.GetOpaqueQualType(), - type_name_cstr, - clang_type, - accessibility, - is_virtual, - is_static, - is_inline, - is_explicit, - is_attr_used, - is_artificial); - - type_handled = cxx_method_decl != NULL; - - if (type_handled) - { - LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(cxx_method_decl), die); - - Host::SetCrashDescription (NULL); - - ClangASTMetadata metadata; - metadata.SetUserID(die.GetID()); - - if (!object_pointer_name.empty()) - { - metadata.SetObjectPtrName(object_pointer_name.c_str()); - if (log) - log->Printf ("Setting object pointer name: %s on method object %p.\n", - object_pointer_name.c_str(), - static_cast<void*>(cxx_method_decl)); - } - m_ast.SetMetadata (cxx_method_decl, metadata); - } - else - { - ignore_containing_context = true; - } - } - } - } - else - { - // We were asked to parse the type for a method in a class, yet the - // class hasn't been asked to complete itself through the - // clang::ExternalASTSource protocol, so we need to just have the - // class complete itself and do things the right way, then our - // DIE should then have an entry in the dwarf->GetDIEToType() map. First - // we need to modify the dwarf->GetDIEToType() so it doesn't think we are - // trying to parse this DIE anymore... - dwarf->GetDIEToType()[die.GetDIE()] = NULL; - - // Now we get the full type to force our class type to complete itself - // using the clang::ExternalASTSource protocol which will parse all - // base classes and all methods (including the method for this DIE). - class_type->GetFullCompilerType (); - - // The type for this DIE should have been filled in the function call above - type_ptr = dwarf->GetDIEToType()[die.GetDIE()]; - if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) - { - type_sp = type_ptr->shared_from_this(); - break; - } - - // FIXME This is fixing some even uglier behavior but we really need to - // uniq the methods of each class as well as the class itself. - // <rdar://problem/11240464> - type_handled = true; - } - } - } + if (specification_die_form.IsValid()) { + // We have a specification which we are going to base our + // function + // prototype off of, so we need this type to be completed so + // that the + // m_die_to_decl_ctx for the method in the specification has a + // valid + // clang decl context. + class_type->GetForwardCompilerType(); + // If we have a specification, then the function type should + // have been + // made with the specification and not with this die. + DWARFDIE spec_die = dwarf->DebugInfo()->GetDIE( + DIERef(specification_die_form)); + clang::DeclContext *spec_clang_decl_ctx = + GetClangDeclContextForDIE(spec_die); + if (spec_clang_decl_ctx) { + LinkDeclContextToDIE(spec_clang_decl_ctx, die); + } else { + dwarf->GetObjectFile()->GetModule()->ReportWarning( + "0x%8.8" PRIx64 ": DW_AT_specification(0x%8.8" PRIx64 + ") has no decl\n", + die.GetID(), specification_die_form.Reference()); + } + type_handled = true; + } else if (abstract_origin_die_form.IsValid()) { + // We have a specification which we are going to base our + // function + // prototype off of, so we need this type to be completed so + // that the + // m_die_to_decl_ctx for the method in the abstract origin has + // a valid + // clang decl context. + class_type->GetForwardCompilerType(); + + DWARFDIE abs_die = dwarf->DebugInfo()->GetDIE( + DIERef(abstract_origin_die_form)); + clang::DeclContext *abs_clang_decl_ctx = + GetClangDeclContextForDIE(abs_die); + if (abs_clang_decl_ctx) { + LinkDeclContextToDIE(abs_clang_decl_ctx, die); + } else { + dwarf->GetObjectFile()->GetModule()->ReportWarning( + "0x%8.8" PRIx64 ": DW_AT_abstract_origin(0x%8.8" PRIx64 + ") has no decl\n", + die.GetID(), abstract_origin_die_form.Reference()); + } + type_handled = true; + } else { + CompilerType class_opaque_type = + class_type->GetForwardCompilerType(); + if (ClangASTContext::IsCXXClassType(class_opaque_type)) { + if (class_opaque_type.IsBeingDefined() || alternate_defn) { + if (!is_static && !die.HasChildren()) { + // We have a C++ member function with no children (this + // pointer!) + // and clang will get mad if we try and make a function + // that isn't + // well formed in the DWARF, so we will just skip it... + type_handled = true; + } else { + bool add_method = true; + if (alternate_defn) { + // If an alternate definition for the class exists, + // then add the method only if an + // equivalent is not already present. + clang::CXXRecordDecl *record_decl = + m_ast.GetAsCXXRecordDecl( + class_opaque_type.GetOpaqueQualType()); + if (record_decl) { + for (auto method_iter = record_decl->method_begin(); + method_iter != record_decl->method_end(); + method_iter++) { + clang::CXXMethodDecl *method_decl = *method_iter; + if (method_decl->getNameInfo().getAsString() == + std::string(type_name_cstr)) { + if (method_decl->getType() == + ClangUtil::GetQualType(clang_type)) { + add_method = false; + LinkDeclContextToDIE( + ClangASTContext::GetAsDeclContext( + method_decl), + die); + type_handled = true; + + break; } + } } + } } - if (!type_handled) - { - clang::FunctionDecl *function_decl = nullptr; - - if (abstract_origin_die_form.IsValid()) - { - DWARFDIE abs_die = dwarf->DebugInfo()->GetDIE (DIERef(abstract_origin_die_form)); - - SymbolContext sc; - - if (dwarf->ResolveType (abs_die)) - { - function_decl = llvm::dyn_cast_or_null<clang::FunctionDecl>(GetCachedClangDeclContextForDIE(abs_die)); - - if (function_decl) - { - LinkDeclContextToDIE(function_decl, die); - } - } - } + if (add_method) { + llvm::PrettyStackTraceFormat stack_trace( + "SymbolFileDWARF::ParseType() is adding a method " + "%s to class %s in DIE 0x%8.8" PRIx64 " from %s", + type_name_cstr, + class_type->GetName().GetCString(), die.GetID(), + dwarf->GetObjectFile() + ->GetFileSpec() + .GetPath() + .c_str()); + + const bool is_attr_used = false; + // Neither GCC 4.2 nor clang++ currently set a valid + // accessibility + // in the DWARF for C++ methods... Default to public + // for now... + if (accessibility == eAccessNone) + accessibility = eAccessPublic; + + clang::CXXMethodDecl *cxx_method_decl = + m_ast.AddMethodToCXXRecordType( + class_opaque_type.GetOpaqueQualType(), + type_name_cstr, clang_type, accessibility, + is_virtual, is_static, is_inline, is_explicit, + is_attr_used, is_artificial); + + type_handled = cxx_method_decl != NULL; + + if (type_handled) { + LinkDeclContextToDIE( + ClangASTContext::GetAsDeclContext( + cxx_method_decl), + die); - if (!function_decl) - { - // We just have a function that isn't part of a class - function_decl = m_ast.CreateFunctionDeclaration (ignore_containing_context ? m_ast.GetTranslationUnitDecl() : containing_decl_ctx, - type_name_cstr, - clang_type, - storage, - is_inline); - - // if (template_param_infos.GetSize() > 0) - // { - // clang::FunctionTemplateDecl *func_template_decl = CreateFunctionTemplateDecl (containing_decl_ctx, - // function_decl, - // type_name_cstr, - // template_param_infos); - // - // CreateFunctionTemplateSpecializationInfo (function_decl, - // func_template_decl, - // template_param_infos); - // } - // Add the decl to our DIE to decl context map - - lldbassert (function_decl); - - if (function_decl) - { - LinkDeclContextToDIE(function_decl, die); - - if (!function_param_decls.empty()) - m_ast.SetFunctionParameters (function_decl, - &function_param_decls.front(), - function_param_decls.size()); - - ClangASTMetadata metadata; - metadata.SetUserID(die.GetID()); - - if (!object_pointer_name.empty()) - { - metadata.SetObjectPtrName(object_pointer_name.c_str()); - if (log) - log->Printf ("Setting object pointer name: %s on function object %p.", - object_pointer_name.c_str(), - static_cast<void*>(function_decl)); - } - m_ast.SetMetadata (function_decl, metadata); - } + ClangASTMetadata metadata; + metadata.SetUserID(die.GetID()); + + if (!object_pointer_name.empty()) { + metadata.SetObjectPtrName( + object_pointer_name.c_str()); + if (log) + log->Printf( + "Setting object pointer name: %s on method " + "object %p.\n", + object_pointer_name.c_str(), + static_cast<void *>(cxx_method_decl)); } + m_ast.SetMetadata(cxx_method_decl, metadata); + } else { + ignore_containing_context = true; + } } + } + } else { + // We were asked to parse the type for a method in a + // class, yet the + // class hasn't been asked to complete itself through the + // clang::ExternalASTSource protocol, so we need to just + // have the + // class complete itself and do things the right way, then + // our + // DIE should then have an entry in the + // dwarf->GetDIEToType() map. First + // we need to modify the dwarf->GetDIEToType() so it + // doesn't think we are + // trying to parse this DIE anymore... + dwarf->GetDIEToType()[die.GetDIE()] = NULL; + + // Now we get the full type to force our class type to + // complete itself + // using the clang::ExternalASTSource protocol which will + // parse all + // base classes and all methods (including the method for + // this DIE). + class_type->GetFullCompilerType(); + + // The type for this DIE should have been filled in the + // function call above + type_ptr = dwarf->GetDIEToType()[die.GetDIE()]; + if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) { + type_sp = type_ptr->shared_from_this(); + break; + } + + // FIXME This is fixing some even uglier behavior but we + // really need to + // uniq the methods of each class as well as the class + // itself. + // <rdar://problem/11240464> + type_handled = true; } - type_sp.reset( new Type (die.GetID(), - dwarf, - type_name_const_str, - 0, - NULL, - LLDB_INVALID_UID, - Type::eEncodingIsUID, - &decl, - clang_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->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED; - - DWARFFormValue type_die_form; - int64_t first_index = 0; - uint32_t byte_stride = 0; - uint32_t bit_stride = 0; - bool is_vector = 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_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; - case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; - case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; - 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_form = form_value; break; - case DW_AT_byte_size: break; // byte_size = form_value.Unsigned(); break; - case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break; - case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break; - case DW_AT_GNU_vector: is_vector = form_value.Boolean(); break; - case DW_AT_accessibility: break; // accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; - case DW_AT_declaration: break; // is_forward_declaration = form_value.Boolean(); break; - case DW_AT_allocated: - case DW_AT_associated: - case DW_AT_data_location: - case DW_AT_description: - case DW_AT_ordering: - case DW_AT_start_scope: - case DW_AT_visibility: - case DW_AT_specification: - case DW_AT_abstract_origin: - case DW_AT_sibling: - break; - } - } - } + } + } + } - DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr); - - DIERef type_die_ref(type_die_form); - 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); - 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) - { - ModuleSP module_sp = die.GetModule(); - if (module_sp) - { - if (die.GetCU()->GetProducer() == DWARFCompileUnit::eProducerClang) - module_sp->ReportError ("DWARF DW_TAG_array_type DIE at 0x%8.8x has a class/union/struct element type DIE 0x%8.8x that is a forward declaration, not a complete definition.\nTry compiling the source file with -fno-limit-debug-info or disable -gmodule", - die.GetOffset(), - type_die_ref.die_offset); - else - module_sp->ReportError ("DWARF DW_TAG_array_type DIE at 0x%8.8x has a class/union/struct element type DIE 0x%8.8x that is a forward declaration, not a complete definition.\nPlease file a bug against the compiler and include the preprocessed output for %s", - die.GetOffset(), - type_die_ref.die_offset, - die.GetLLDBCompileUnit() ? die.GetLLDBCompileUnit()->GetPath().c_str() : "the source file"); - } + if (!type_handled) { + clang::FunctionDecl *function_decl = nullptr; - // We have no choice other than to pretend that the element class type - // is complete. If we don't do this, clang will crash when trying - // to layout the class. 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. - if (ClangASTContext::StartTagDeclarationDefinition(array_element_type)) - { - ClangASTContext::CompleteTagDeclarationDefinition(array_element_type); - } - else - { - module_sp->ReportError ("DWARF DIE at 0x%8.8x was not able to start its definition.\nPlease file a bug and attach the file at the start of this error message", - type_die_ref.die_offset); - } - } + if (abstract_origin_die_form.IsValid()) { + DWARFDIE abs_die = + dwarf->DebugInfo()->GetDIE(DIERef(abstract_origin_die_form)); - uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride; - if (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) - { - num_elements = *pos; - clang_type = m_ast.CreateArrayType (array_element_type, - num_elements, - is_vector); - array_element_type = clang_type; - array_element_bit_stride = num_elements ? - array_element_bit_stride * num_elements : - array_element_bit_stride; - } - } - else - { - clang_type = m_ast.CreateArrayType (array_element_type, 0, is_vector); - } - ConstString empty_name; - type_sp.reset( new Type (die.GetID(), - dwarf, - empty_name, - array_element_bit_stride / 8, - NULL, - DIERef(type_die_form).GetUID(dwarf), - Type::eEncodingIsUID, - &decl, - clang_type, - Type::eResolveStateFull)); - type_sp->SetEncodingType (element_type); - } - } + SymbolContext sc; + + if (dwarf->ResolveType(abs_die)) { + function_decl = llvm::dyn_cast_or_null<clang::FunctionDecl>( + GetCachedClangDeclContextForDIE(abs_die)); + + if (function_decl) { + LinkDeclContextToDIE(function_decl, die); } - break; - - case DW_TAG_ptr_to_member_type: - { - DWARFFormValue type_die_form; - DWARFFormValue containing_type_die_form; - - 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_type: - type_die_form = form_value; break; - case DW_AT_containing_type: - containing_type_die_form = form_value; break; - } - } - } + } + } - Type *pointee_type = dwarf->ResolveTypeUID(DIERef(type_die_form)); - Type *class_type = dwarf->ResolveTypeUID(DIERef(containing_type_die_form)); + if (!function_decl) { + // We just have a function that isn't part of a class + function_decl = m_ast.CreateFunctionDeclaration( + ignore_containing_context ? m_ast.GetTranslationUnitDecl() + : containing_decl_ctx, + type_name_cstr, clang_type, storage, is_inline); + + // if (template_param_infos.GetSize() > + // 0) + // { + // clang::FunctionTemplateDecl + // *func_template_decl = + // CreateFunctionTemplateDecl + // (containing_decl_ctx, + // function_decl, + // type_name_cstr, + // template_param_infos); + // + // CreateFunctionTemplateSpecializationInfo + // (function_decl, + // func_template_decl, + // template_param_infos); + // } + // Add the decl to our DIE to decl context map + + lldbassert(function_decl); + + if (function_decl) { + LinkDeclContextToDIE(function_decl, die); + + if (!function_param_decls.empty()) + m_ast.SetFunctionParameters(function_decl, + &function_param_decls.front(), + function_param_decls.size()); + + ClangASTMetadata metadata; + metadata.SetUserID(die.GetID()); + + if (!object_pointer_name.empty()) { + metadata.SetObjectPtrName(object_pointer_name.c_str()); + if (log) + log->Printf("Setting object pointer name: %s on function " + "object %p.", + object_pointer_name.c_str(), + static_cast<void *>(function_decl)); + } + m_ast.SetMetadata(function_decl, metadata); + } + } + } + } + type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, 0, NULL, + LLDB_INVALID_UID, Type::eEncodingIsUID, &decl, + clang_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->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED; + + DWARFFormValue type_die_form; + int64_t first_index = 0; + uint32_t byte_stride = 0; + uint32_t bit_stride = 0; + bool is_vector = false; + const size_t num_attributes = die.GetAttributes(attributes); - CompilerType pointee_clang_type = pointee_type->GetForwardCompilerType (); - CompilerType class_clang_type = class_type->GetLayoutCompilerType (); - - clang_type = ClangASTContext::CreateMemberPointerType(class_clang_type, pointee_clang_type); + 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_decl_file: + decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex( + form_value.Unsigned())); + break; + case DW_AT_decl_line: + decl.SetLine(form_value.Unsigned()); + break; + case DW_AT_decl_column: + decl.SetColumn(form_value.Unsigned()); + break; + case DW_AT_name: + type_name_cstr = form_value.AsCString(); + type_name_const_str.SetCString(type_name_cstr); + break; - byte_size = clang_type.GetByteSize(nullptr); + case DW_AT_type: + type_die_form = form_value; + break; + case DW_AT_byte_size: + break; // byte_size = form_value.Unsigned(); break; + case DW_AT_byte_stride: + byte_stride = form_value.Unsigned(); + break; + case DW_AT_bit_stride: + bit_stride = form_value.Unsigned(); + break; + case DW_AT_GNU_vector: + is_vector = form_value.Boolean(); + break; + case DW_AT_accessibility: + break; // accessibility = + // DW_ACCESS_to_AccessType(form_value.Unsigned()); break; + case DW_AT_declaration: + break; // is_forward_declaration = form_value.Boolean(); break; + case DW_AT_allocated: + case DW_AT_associated: + case DW_AT_data_location: + case DW_AT_description: + case DW_AT_ordering: + case DW_AT_start_scope: + case DW_AT_visibility: + case DW_AT_specification: + case DW_AT_abstract_origin: + case DW_AT_sibling: + break; + } + } + } + + DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), + DW_TAG_value_to_name(tag), type_name_cstr); + + DIERef type_die_ref(type_die_form); + 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); + 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) { + ModuleSP module_sp = die.GetModule(); + if (module_sp) { + if (die.GetCU()->GetProducer() == + DWARFCompileUnit::eProducerClang) + module_sp->ReportError( + "DWARF DW_TAG_array_type DIE at 0x%8.8x has a " + "class/union/struct element type DIE 0x%8.8x that is a " + "forward declaration, not a complete definition.\nTry " + "compiling the source file with -fno-limit-debug-info or " + "disable -gmodule", + die.GetOffset(), type_die_ref.die_offset); + else + module_sp->ReportError( + "DWARF DW_TAG_array_type DIE at 0x%8.8x has a " + "class/union/struct element type DIE 0x%8.8x that is a " + "forward declaration, not a complete definition.\nPlease " + "file a bug against the compiler and include the " + "preprocessed output for %s", + die.GetOffset(), type_die_ref.die_offset, + die.GetLLDBCompileUnit() + ? die.GetLLDBCompileUnit()->GetPath().c_str() + : "the source file"); + } + + // We have no choice other than to pretend that the element class + // type + // is complete. If we don't do this, clang will crash when trying + // to layout the class. 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. + if (ClangASTContext::StartTagDeclarationDefinition( + array_element_type)) { + ClangASTContext::CompleteTagDeclarationDefinition( + array_element_type); + } else { + module_sp->ReportError("DWARF DIE at 0x%8.8x was not able to " + "start its definition.\nPlease file a " + "bug and attach the file at the start " + "of this error message", + type_die_ref.die_offset); + } + } - 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)); - } + uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride; + if (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) { + num_elements = *pos; + clang_type = m_ast.CreateArrayType(array_element_type, + num_elements, is_vector); + array_element_type = clang_type; + array_element_bit_stride = + num_elements ? array_element_bit_stride * num_elements + : array_element_bit_stride; + } + } else { + clang_type = + m_ast.CreateArrayType(array_element_type, 0, is_vector); + } + ConstString empty_name; + type_sp.reset(new Type( + die.GetID(), dwarf, empty_name, array_element_bit_stride / 8, + NULL, DIERef(type_die_form).GetUID(dwarf), Type::eEncodingIsUID, + &decl, clang_type, Type::eResolveStateFull)); + type_sp->SetEncodingType(element_type); + } + } + } break; - 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; + case DW_TAG_ptr_to_member_type: { + DWARFFormValue type_die_form; + DWARFFormValue containing_type_die_form; + + 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_type: + type_die_form = form_value; + break; + case DW_AT_containing_type: + containing_type_die_form = form_value; + break; + } } + } - if (type_sp.get()) - { - DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die); - dw_tag_t sc_parent_tag = sc_parent_die.Tag(); + Type *pointee_type = dwarf->ResolveTypeUID(DIERef(type_die_form)); + Type *class_type = + dwarf->ResolveTypeUID(DIERef(containing_type_die_form)); - SymbolContextScope * symbol_context_scope = NULL; - if (sc_parent_tag == DW_TAG_compile_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; - } + CompilerType pointee_clang_type = + pointee_type->GetForwardCompilerType(); + CompilerType class_clang_type = class_type->GetLayoutCompilerType(); - if (symbol_context_scope != NULL) - { - type_sp->SetSymbolContextScope(symbol_context_scope); - } + clang_type = ClangASTContext::CreateMemberPointerType( + class_clang_type, pointee_clang_type); - // We are ready to put this type into the uniqued list up at the module level - type_list->Insert (type_sp); + byte_size = clang_type.GetByteSize(nullptr); - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); - } + 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)); } - else if (type_ptr != DIE_IS_BEING_PARSED) - { - type_sp = type_ptr->shared_from_this(); + + 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) { + 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->GetDIEToType()[die.GetDIE()] = type_sp.get(); + } + } else if (type_ptr != DIE_IS_BEING_PARSED) { + type_sp = type_ptr->shared_from_this(); } - return type_sp; + } + return type_sp; } // DWARF parsing functions -class DWARFASTParserClang::DelayedAddObjCClassProperty -{ +class DWARFASTParserClang::DelayedAddObjCClassProperty { public: - DelayedAddObjCClassProperty(const CompilerType &class_opaque_type, - const char *property_name, - const CompilerType &property_opaque_type, // The property type is only required if you don't have an ivar decl - clang::ObjCIvarDecl *ivar_decl, - const char *property_setter_name, - const char *property_getter_name, - uint32_t property_attributes, - const ClangASTMetadata *metadata) : - m_class_opaque_type (class_opaque_type), - m_property_name (property_name), - m_property_opaque_type (property_opaque_type), - m_ivar_decl (ivar_decl), - m_property_setter_name (property_setter_name), - m_property_getter_name (property_getter_name), - m_property_attributes (property_attributes) - { - if (metadata != NULL) - { - m_metadata_ap.reset(new ClangASTMetadata()); - *m_metadata_ap = *metadata; - } + DelayedAddObjCClassProperty( + const CompilerType &class_opaque_type, const char *property_name, + const CompilerType &property_opaque_type, // The property type is only + // required if you don't have an + // ivar decl + clang::ObjCIvarDecl *ivar_decl, const char *property_setter_name, + const char *property_getter_name, uint32_t property_attributes, + const ClangASTMetadata *metadata) + : m_class_opaque_type(class_opaque_type), m_property_name(property_name), + m_property_opaque_type(property_opaque_type), m_ivar_decl(ivar_decl), + m_property_setter_name(property_setter_name), + m_property_getter_name(property_getter_name), + m_property_attributes(property_attributes) { + if (metadata != NULL) { + m_metadata_ap.reset(new ClangASTMetadata()); + *m_metadata_ap = *metadata; } - - DelayedAddObjCClassProperty (const DelayedAddObjCClassProperty &rhs) - { - *this = rhs; + } + + DelayedAddObjCClassProperty(const DelayedAddObjCClassProperty &rhs) { + *this = rhs; + } + + DelayedAddObjCClassProperty & + operator=(const DelayedAddObjCClassProperty &rhs) { + m_class_opaque_type = rhs.m_class_opaque_type; + m_property_name = rhs.m_property_name; + m_property_opaque_type = rhs.m_property_opaque_type; + m_ivar_decl = rhs.m_ivar_decl; + m_property_setter_name = rhs.m_property_setter_name; + m_property_getter_name = rhs.m_property_getter_name; + m_property_attributes = rhs.m_property_attributes; + + if (rhs.m_metadata_ap.get()) { + m_metadata_ap.reset(new ClangASTMetadata()); + *m_metadata_ap = *rhs.m_metadata_ap; } + return *this; + } - DelayedAddObjCClassProperty& operator= (const DelayedAddObjCClassProperty &rhs) - { - m_class_opaque_type = rhs.m_class_opaque_type; - m_property_name = rhs.m_property_name; - m_property_opaque_type = rhs.m_property_opaque_type; - m_ivar_decl = rhs.m_ivar_decl; - m_property_setter_name = rhs.m_property_setter_name; - m_property_getter_name = rhs.m_property_getter_name; - m_property_attributes = rhs.m_property_attributes; - - if (rhs.m_metadata_ap.get()) - { - m_metadata_ap.reset (new ClangASTMetadata()); - *m_metadata_ap = *rhs.m_metadata_ap; - } - return *this; - } - - bool - Finalize() - { - return ClangASTContext::AddObjCClassProperty (m_class_opaque_type, - m_property_name, - m_property_opaque_type, - m_ivar_decl, - m_property_setter_name, - m_property_getter_name, - m_property_attributes, - m_metadata_ap.get()); - } + bool Finalize() { + return ClangASTContext::AddObjCClassProperty( + m_class_opaque_type, m_property_name, m_property_opaque_type, + m_ivar_decl, m_property_setter_name, m_property_getter_name, + m_property_attributes, m_metadata_ap.get()); + } private: - CompilerType m_class_opaque_type; - const char *m_property_name; - CompilerType m_property_opaque_type; - clang::ObjCIvarDecl *m_ivar_decl; - const char *m_property_setter_name; - const char *m_property_getter_name; - uint32_t m_property_attributes; - std::unique_ptr<ClangASTMetadata> m_metadata_ap; + CompilerType m_class_opaque_type; + const char *m_property_name; + CompilerType m_property_opaque_type; + clang::ObjCIvarDecl *m_ivar_decl; + const char *m_property_setter_name; + const char *m_property_getter_name; + uint32_t m_property_attributes; + std::unique_ptr<ClangASTMetadata> m_metadata_ap; }; -bool -DWARFASTParserClang::ParseTemplateDIE (const DWARFDIE &die, - ClangASTContext::TemplateParameterInfos &template_param_infos) -{ - const dw_tag_t tag = die.Tag(); - - switch (tag) - { - case DW_TAG_template_type_parameter: - case DW_TAG_template_value_parameter: - { - DWARFAttributes attributes; - const size_t num_attributes = die.GetAttributes (attributes); - const char *name = nullptr; - CompilerType clang_type; - uint64_t uval64 = 0; - bool uval64_valid = false; - if (num_attributes > 0) - { - DWARFFormValue form_value; - for (size_t i=0; i<num_attributes; ++i) - { - const dw_attr_t attr = attributes.AttributeAtIndex(i); - - switch (attr) - { - case DW_AT_name: - if (attributes.ExtractFormValueAtIndex(i, form_value)) - name = form_value.AsCString(); - break; - - case DW_AT_type: - if (attributes.ExtractFormValueAtIndex(i, form_value)) - { - Type *lldb_type = die.ResolveTypeUID(DIERef(form_value)); - if (lldb_type) - clang_type = lldb_type->GetForwardCompilerType (); - } - break; +bool DWARFASTParserClang::ParseTemplateDIE( + const DWARFDIE &die, + ClangASTContext::TemplateParameterInfos &template_param_infos) { + const dw_tag_t tag = die.Tag(); - case DW_AT_const_value: - if (attributes.ExtractFormValueAtIndex(i, form_value)) - { - uval64_valid = true; - uval64 = form_value.Unsigned(); - } - break; - default: - break; - } - } + switch (tag) { + case DW_TAG_template_type_parameter: + case DW_TAG_template_value_parameter: { + DWARFAttributes attributes; + const size_t num_attributes = die.GetAttributes(attributes); + const char *name = nullptr; + CompilerType clang_type; + uint64_t uval64 = 0; + bool uval64_valid = false; + if (num_attributes > 0) { + DWARFFormValue form_value; + for (size_t i = 0; i < num_attributes; ++i) { + const dw_attr_t attr = attributes.AttributeAtIndex(i); + + switch (attr) { + case DW_AT_name: + if (attributes.ExtractFormValueAtIndex(i, form_value)) + name = form_value.AsCString(); + break; + + case DW_AT_type: + if (attributes.ExtractFormValueAtIndex(i, form_value)) { + Type *lldb_type = die.ResolveTypeUID(DIERef(form_value)); + if (lldb_type) + clang_type = lldb_type->GetForwardCompilerType(); + } + break; + + case DW_AT_const_value: + if (attributes.ExtractFormValueAtIndex(i, form_value)) { + uval64_valid = true; + uval64 = form_value.Unsigned(); + } + break; + default: + break; + } + } - clang::ASTContext *ast = m_ast.getASTContext(); - if (!clang_type) - clang_type = m_ast.GetBasicType(eBasicTypeVoid); - - if (clang_type) - { - bool is_signed = false; - if (name && name[0]) - template_param_infos.names.push_back(name); - else - template_param_infos.names.push_back(NULL); - - // Get the signed value for any integer or enumeration if available - clang_type.IsIntegerOrEnumerationType (is_signed); - - if (tag == DW_TAG_template_value_parameter && uval64_valid) - { - llvm::APInt apint (clang_type.GetBitSize(nullptr), uval64, is_signed); - template_param_infos.args.push_back( - clang::TemplateArgument(*ast, llvm::APSInt(apint, !is_signed), ClangUtil::GetQualType(clang_type))); - } - else - { - template_param_infos.args.push_back( - clang::TemplateArgument(ClangUtil::GetQualType(clang_type))); - } - } - else - { - return false; - } + clang::ASTContext *ast = m_ast.getASTContext(); + if (!clang_type) + clang_type = m_ast.GetBasicType(eBasicTypeVoid); - } + if (clang_type) { + bool is_signed = false; + if (name && name[0]) + template_param_infos.names.push_back(name); + else + template_param_infos.names.push_back(NULL); + + // Get the signed value for any integer or enumeration if available + clang_type.IsIntegerOrEnumerationType(is_signed); + + if (tag == DW_TAG_template_value_parameter && uval64_valid) { + llvm::APInt apint(clang_type.GetBitSize(nullptr), uval64, is_signed); + template_param_infos.args.push_back( + clang::TemplateArgument(*ast, llvm::APSInt(apint, !is_signed), + ClangUtil::GetQualType(clang_type))); + } else { + template_param_infos.args.push_back( + clang::TemplateArgument(ClangUtil::GetQualType(clang_type))); } - return true; - - default: - break; + } else { + return false; + } } - return false; + } + return true; + + default: + break; + } + return false; } -bool -DWARFASTParserClang::ParseTemplateParameterInfos (const DWARFDIE &parent_die, - ClangASTContext::TemplateParameterInfos &template_param_infos) -{ +bool DWARFASTParserClang::ParseTemplateParameterInfos( + const DWARFDIE &parent_die, + ClangASTContext::TemplateParameterInfos &template_param_infos) { - if (!parent_die) - return false; + if (!parent_die) + return false; - Args template_parameter_names; - for (DWARFDIE die = parent_die.GetFirstChild(); - die.IsValid(); - die = die.GetSibling()) - { - const dw_tag_t tag = die.Tag(); + Args template_parameter_names; + for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); + die = die.GetSibling()) { + const dw_tag_t tag = die.Tag(); - switch (tag) - { - case DW_TAG_template_type_parameter: - case DW_TAG_template_value_parameter: - ParseTemplateDIE (die, template_param_infos); - break; + switch (tag) { + case DW_TAG_template_type_parameter: + case DW_TAG_template_value_parameter: + ParseTemplateDIE(die, template_param_infos); + break; - default: - break; - } + default: + break; } - if (template_param_infos.args.empty()) - return false; - return template_param_infos.args.size() == template_param_infos.names.size(); + } + if (template_param_infos.args.empty()) + return false; + return template_param_infos.args.size() == template_param_infos.names.size(); } -bool -DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type, CompilerType &clang_type) -{ - SymbolFileDWARF *dwarf = die.GetDWARF(); +bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die, + lldb_private::Type *type, + CompilerType &clang_type) { + SymbolFileDWARF *dwarf = die.GetDWARF(); - std::lock_guard<std::recursive_mutex> guard(dwarf->GetObjectFile()->GetModule()->GetMutex()); + std::lock_guard<std::recursive_mutex> guard( + dwarf->GetObjectFile()->GetModule()->GetMutex()); - // Disable external storage for this type so we don't get anymore - // clang::ExternalASTSource queries for this type. - m_ast.SetHasExternalStorage (clang_type.GetOpaqueQualType(), false); + // Disable external storage for this type so we don't get anymore + // clang::ExternalASTSource queries for this type. + m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), false); - if (!die) - return false; + if (!die) + return false; #if defined LLDB_CONFIGURATION_DEBUG - //---------------------------------------------------------------------- - // For debugging purposes, the LLDB_DWARF_DONT_COMPLETE_TYPENAMES - // environment variable can be set with one or more typenames separated - // by ';' characters. This will cause this function to not complete any - // types whose names match. - // - // Examples of setting this environment variable: - // - // LLDB_DWARF_DONT_COMPLETE_TYPENAMES=Foo - // LLDB_DWARF_DONT_COMPLETE_TYPENAMES=Foo;Bar;Baz - //---------------------------------------------------------------------- - const char *dont_complete_typenames_cstr = getenv("LLDB_DWARF_DONT_COMPLETE_TYPENAMES"); - if (dont_complete_typenames_cstr && dont_complete_typenames_cstr[0]) - { - const char *die_name = die.GetName(); - if (die_name && die_name[0]) - { - const char *match = strstr(dont_complete_typenames_cstr, die_name); - if (match) - { - size_t die_name_length = strlen(die_name); - while (match) - { - const char separator_char = ';'; - const char next_char = match[die_name_length]; - if (next_char == '\0' || next_char == separator_char) - { - if (match == dont_complete_typenames_cstr || match[-1] == separator_char) - return false; - } - match = strstr(match+1, die_name); - } - } + //---------------------------------------------------------------------- + // For debugging purposes, the LLDB_DWARF_DONT_COMPLETE_TYPENAMES + // environment variable can be set with one or more typenames separated + // by ';' characters. This will cause this function to not complete any + // types whose names match. + // + // Examples of setting this environment variable: + // + // LLDB_DWARF_DONT_COMPLETE_TYPENAMES=Foo + // LLDB_DWARF_DONT_COMPLETE_TYPENAMES=Foo;Bar;Baz + //---------------------------------------------------------------------- + const char *dont_complete_typenames_cstr = + getenv("LLDB_DWARF_DONT_COMPLETE_TYPENAMES"); + if (dont_complete_typenames_cstr && dont_complete_typenames_cstr[0]) { + const char *die_name = die.GetName(); + if (die_name && die_name[0]) { + const char *match = strstr(dont_complete_typenames_cstr, die_name); + if (match) { + size_t die_name_length = strlen(die_name); + while (match) { + const char separator_char = ';'; + const char next_char = match[die_name_length]; + if (next_char == '\0' || next_char == separator_char) { + if (match == dont_complete_typenames_cstr || + match[-1] == separator_char) + return false; + } + match = strstr(match + 1, die_name); } + } } + } #endif - const dw_tag_t tag = die.Tag(); + const dw_tag_t tag = die.Tag(); + + 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(), die.GetTagAsCString(), type->GetName().AsCString()); + assert(clang_type); + DWARFAttributes attributes; + switch (tag) { + case DW_TAG_structure_type: + case DW_TAG_union_type: + case DW_TAG_class_type: { + ClangASTImporter::LayoutInfo layout_info; - 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(), - die.GetTagAsCString(), - type->GetName().AsCString()); - assert (clang_type); - DWARFAttributes attributes; - switch (tag) { - case DW_TAG_structure_type: - case DW_TAG_union_type: - case DW_TAG_class_type: - { - ClangASTImporter::LayoutInfo layout_info; - - { - if (die.HasChildren()) - { - LanguageType class_language = eLanguageTypeUnknown; - if (ClangASTContext::IsObjCObjectOrInterfaceType(clang_type)) - { - class_language = eLanguageTypeObjC; - // For objective C we don't start the definition when - // the class is created. - ClangASTContext::StartTagDeclarationDefinition (clang_type); - } - - int tag_decl_kind = -1; - AccessType default_accessibility = eAccessNone; - if (tag == DW_TAG_structure_type) - { - tag_decl_kind = clang::TTK_Struct; - default_accessibility = eAccessPublic; - } - else if (tag == DW_TAG_union_type) - { - tag_decl_kind = clang::TTK_Union; - default_accessibility = eAccessPublic; - } - else if (tag == DW_TAG_class_type) - { - tag_decl_kind = clang::TTK_Class; - default_accessibility = eAccessPrivate; - } + if (die.HasChildren()) { + LanguageType class_language = eLanguageTypeUnknown; + if (ClangASTContext::IsObjCObjectOrInterfaceType(clang_type)) { + class_language = eLanguageTypeObjC; + // For objective C we don't start the definition when + // the class is created. + ClangASTContext::StartTagDeclarationDefinition(clang_type); + } - SymbolContext sc(die.GetLLDBCompileUnit()); - std::vector<clang::CXXBaseSpecifier *> base_classes; - 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, - member_accessibilities, - member_function_dies, - delayed_properties, - default_accessibility, - is_a_class, - layout_info); - - // Now parse any methods if there were any... - size_t num_functions = member_function_dies.Size(); - if (num_functions > 0) - { - for (size_t i=0; i<num_functions; ++i) - { - dwarf->ResolveType(member_function_dies.GetDIEAtIndex(i)); - } - } + int tag_decl_kind = -1; + AccessType default_accessibility = eAccessNone; + if (tag == DW_TAG_structure_type) { + tag_decl_kind = clang::TTK_Struct; + default_accessibility = eAccessPublic; + } else if (tag == DW_TAG_union_type) { + tag_decl_kind = clang::TTK_Union; + default_accessibility = eAccessPublic; + } else if (tag == DW_TAG_class_type) { + tag_decl_kind = clang::TTK_Class; + default_accessibility = eAccessPrivate; + } - if (class_language == eLanguageTypeObjC) - { - ConstString class_name (clang_type.GetTypeName()); - if (class_name) - { - DIEArray method_die_offsets; - dwarf->GetObjCMethodDIEOffsets(class_name, method_die_offsets); - - if (!method_die_offsets.empty()) - { - DWARFDebugInfo* debug_info = dwarf->DebugInfo(); - - const size_t num_matches = method_die_offsets.size(); - for (size_t i=0; i<num_matches; ++i) - { - const DIERef& die_ref = method_die_offsets[i]; - DWARFDIE method_die = debug_info->GetDIE (die_ref); - - if (method_die) - method_die.ResolveType (); - } - } + SymbolContext sc(die.GetLLDBCompileUnit()); + std::vector<clang::CXXBaseSpecifier *> base_classes; + 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, + member_accessibilities, member_function_dies, + delayed_properties, default_accessibility, is_a_class, + layout_info); + + // Now parse any methods if there were any... + size_t num_functions = member_function_dies.Size(); + if (num_functions > 0) { + for (size_t i = 0; i < num_functions; ++i) { + dwarf->ResolveType(member_function_dies.GetDIEAtIndex(i)); + } + } - for (DelayedPropertyList::iterator pi = delayed_properties.begin(), pe = delayed_properties.end(); - pi != pe; - ++pi) - pi->Finalize(); - } - } + if (class_language == eLanguageTypeObjC) { + ConstString class_name(clang_type.GetTypeName()); + if (class_name) { + DIEArray method_die_offsets; + dwarf->GetObjCMethodDIEOffsets(class_name, method_die_offsets); - // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we - // need to tell the clang type it is actually a class. - if (class_language != eLanguageTypeObjC) - { - if (is_a_class && tag_decl_kind != clang::TTK_Class) - m_ast.SetTagTypeKind(ClangUtil::GetQualType(clang_type), clang::TTK_Class); - } + if (!method_die_offsets.empty()) { + DWARFDebugInfo *debug_info = dwarf->DebugInfo(); - // Since DW_TAG_structure_type gets used for both classes - // and structures, we may need to set any DW_TAG_member - // fields to have a "private" access if none was specified. - // When we parsed the child members we tracked that actual - // accessibility value for each DW_TAG_member in the - // "member_accessibilities" array. If the value for the - // member is zero, then it was set to the "default_accessibility" - // which for structs was "public". Below we correct this - // by setting any fields to "private" that weren't correctly - // set. - if (is_a_class && !member_accessibilities.empty()) - { - // This is a class and all members that didn't have - // their access specified are private. - m_ast.SetDefaultAccessForRecordFields (m_ast.GetAsRecordDecl(clang_type), - eAccessPrivate, - &member_accessibilities.front(), - member_accessibilities.size()); - } + const size_t num_matches = method_die_offsets.size(); + for (size_t i = 0; i < num_matches; ++i) { + const DIERef &die_ref = method_die_offsets[i]; + DWARFDIE method_die = debug_info->GetDIE(die_ref); - if (!base_classes.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) - { - 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) - { - auto module = dwarf->GetObjectFile()->GetModule(); - module->ReportError ( - ":: Class '%s' has a base class '%s' which does not have a complete definition.", - die.GetName(), - base_class_type.GetTypeName().GetCString()); - if (die.GetCU()->GetProducer() == DWARFCompileUnit::eProducerClang) - module->ReportError (":: Try compiling the source file with -fno-limit-debug-info."); - - // 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 provide layout assistance, all ivars in this - // class and other classes will be fine, this is the best we can do - // short of crashing. - if (ClangASTContext::StartTagDeclarationDefinition (base_class_type)) - { - ClangASTContext::CompleteTagDeclarationDefinition (base_class_type); - } - } - } - } - 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()); - } - } + if (method_die) + method_die.ResolveType(); + } } - ClangASTContext::BuildIndirectFields (clang_type); - ClangASTContext::CompleteTagDeclarationDefinition (clang_type); + for (DelayedPropertyList::iterator pi = delayed_properties.begin(), + pe = delayed_properties.end(); + pi != pe; ++pi) + pi->Finalize(); + } + } - if (!layout_info.field_offsets.empty() || - !layout_info.base_offsets.empty() || - !layout_info.vbase_offsets.empty() ) - { - if (type) - layout_info.bit_size = type->GetByteSize() * 8; - if (layout_info.bit_size == 0) - layout_info.bit_size = die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8; - - clang::CXXRecordDecl *record_decl = m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType()); - if (record_decl) - { - if (log) - { - ModuleSP module_sp = dwarf->GetObjectFile()->GetModule(); - - if (module_sp) - { - module_sp->LogMessage (log, - "ClangASTContext::CompleteTypeFromDWARF (clang_type = %p) caching layout info for record_decl = %p, bit_size = %" PRIu64 ", alignment = %" PRIu64 ", field_offsets[%u], base_offsets[%u], vbase_offsets[%u])", - static_cast<void*>(clang_type.GetOpaqueQualType()), - static_cast<void*>(record_decl), - layout_info.bit_size, - layout_info.alignment, - static_cast<uint32_t>(layout_info.field_offsets.size()), - static_cast<uint32_t>(layout_info.base_offsets.size()), - static_cast<uint32_t>(layout_info.vbase_offsets.size())); - - uint32_t idx; - { - llvm::DenseMap<const clang::FieldDecl *, uint64_t>::const_iterator pos, - end = layout_info.field_offsets.end(); - for (idx = 0, pos = layout_info.field_offsets.begin(); pos != end; ++pos, ++idx) - { - module_sp->LogMessage(log, - "ClangASTContext::CompleteTypeFromDWARF (clang_type = %p) field[%u] = { bit_offset=%u, name='%s' }", - static_cast<void *>(clang_type.GetOpaqueQualType()), - idx, - static_cast<uint32_t>(pos->second), - pos->first->getNameAsString().c_str()); - } - } + // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we + // need to tell the clang type it is actually a class. + if (class_language != eLanguageTypeObjC) { + if (is_a_class && tag_decl_kind != clang::TTK_Class) + m_ast.SetTagTypeKind(ClangUtil::GetQualType(clang_type), + clang::TTK_Class); + } - { - llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>::const_iterator base_pos, - base_end = layout_info.base_offsets.end(); - for (idx = 0, base_pos = layout_info.base_offsets.begin(); base_pos != base_end; ++base_pos, ++idx) - { - module_sp->LogMessage(log, - "ClangASTContext::CompleteTypeFromDWARF (clang_type = %p) base[%u] = { byte_offset=%u, name='%s' }", - clang_type.GetOpaqueQualType(), idx, (uint32_t)base_pos->second.getQuantity(), - base_pos->first->getNameAsString().c_str()); - } - } - { - llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>::const_iterator vbase_pos, - vbase_end = layout_info.vbase_offsets.end(); - for (idx = 0, vbase_pos = layout_info.vbase_offsets.begin(); vbase_pos != vbase_end; ++vbase_pos, ++idx) - { - module_sp->LogMessage(log, - "ClangASTContext::CompleteTypeFromDWARF (clang_type = %p) vbase[%u] = { byte_offset=%u, name='%s' }", - static_cast<void *>(clang_type.GetOpaqueQualType()), idx, - static_cast<uint32_t>(vbase_pos->second.getQuantity()), - vbase_pos->first->getNameAsString().c_str()); - } - } + // Since DW_TAG_structure_type gets used for both classes + // and structures, we may need to set any DW_TAG_member + // fields to have a "private" access if none was specified. + // When we parsed the child members we tracked that actual + // accessibility value for each DW_TAG_member in the + // "member_accessibilities" array. If the value for the + // member is zero, then it was set to the "default_accessibility" + // which for structs was "public". Below we correct this + // by setting any fields to "private" that weren't correctly + // set. + if (is_a_class && !member_accessibilities.empty()) { + // This is a class and all members that didn't have + // their access specified are private. + m_ast.SetDefaultAccessForRecordFields( + m_ast.GetAsRecordDecl(clang_type), eAccessPrivate, + &member_accessibilities.front(), member_accessibilities.size()); + } - } - } - GetClangASTImporter().InsertRecordDecl(record_decl, layout_info); + if (!base_classes.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) { + 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) { + auto module = dwarf->GetObjectFile()->GetModule(); + module->ReportError(":: Class '%s' has a base class '%s' which " + "does not have a complete definition.", + die.GetName(), + base_class_type.GetTypeName().GetCString()); + if (die.GetCU()->GetProducer() == + DWARFCompileUnit::eProducerClang) + module->ReportError(":: Try compiling the source file with " + "-fno-limit-debug-info."); + + // 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 provide layout assistance, all ivars in this + // class and other classes will be fine, this is the best we can + // do + // short of crashing. + if (ClangASTContext::StartTagDeclarationDefinition( + base_class_type)) { + ClangASTContext::CompleteTagDeclarationDefinition( + base_class_type); } + } } + } + 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()); } + } + } - return (bool)clang_type; - - case DW_TAG_enumeration_type: - if (ClangASTContext::StartTagDeclarationDefinition (clang_type)) + ClangASTContext::BuildIndirectFields(clang_type); + ClangASTContext::CompleteTagDeclarationDefinition(clang_type); + + if (!layout_info.field_offsets.empty() || + !layout_info.base_offsets.empty() || + !layout_info.vbase_offsets.empty()) { + if (type) + layout_info.bit_size = type->GetByteSize() * 8; + if (layout_info.bit_size == 0) + layout_info.bit_size = + die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8; + + clang::CXXRecordDecl *record_decl = + m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType()); + if (record_decl) { + if (log) { + ModuleSP module_sp = dwarf->GetObjectFile()->GetModule(); + + if (module_sp) { + module_sp->LogMessage( + log, + "ClangASTContext::CompleteTypeFromDWARF (clang_type = %p) " + "caching layout info for record_decl = %p, bit_size = %" PRIu64 + ", alignment = %" PRIu64 + ", field_offsets[%u], base_offsets[%u], vbase_offsets[%u])", + static_cast<void *>(clang_type.GetOpaqueQualType()), + static_cast<void *>(record_decl), layout_info.bit_size, + layout_info.alignment, + static_cast<uint32_t>(layout_info.field_offsets.size()), + static_cast<uint32_t>(layout_info.base_offsets.size()), + static_cast<uint32_t>(layout_info.vbase_offsets.size())); + + uint32_t idx; { - if (die.HasChildren()) - { - SymbolContext sc(die.GetLLDBCompileUnit()); - bool is_signed = false; - clang_type.IsIntegerType(is_signed); - ParseChildEnumerators(sc, clang_type, is_signed, type->GetByteSize(), die); - } - ClangASTContext::CompleteTagDeclarationDefinition (clang_type); + llvm::DenseMap<const clang::FieldDecl *, uint64_t>::const_iterator + pos, + end = layout_info.field_offsets.end(); + for (idx = 0, pos = layout_info.field_offsets.begin(); pos != end; + ++pos, ++idx) { + module_sp->LogMessage( + log, "ClangASTContext::CompleteTypeFromDWARF (clang_type = " + "%p) field[%u] = { bit_offset=%u, name='%s' }", + static_cast<void *>(clang_type.GetOpaqueQualType()), idx, + static_cast<uint32_t>(pos->second), + pos->first->getNameAsString().c_str()); + } } - return (bool)clang_type; - default: - assert(false && "not a forward clang type decl!"); - break; + { + llvm::DenseMap<const clang::CXXRecordDecl *, + clang::CharUnits>::const_iterator base_pos, + base_end = layout_info.base_offsets.end(); + for (idx = 0, base_pos = layout_info.base_offsets.begin(); + base_pos != base_end; ++base_pos, ++idx) { + module_sp->LogMessage( + log, "ClangASTContext::CompleteTypeFromDWARF (clang_type = " + "%p) base[%u] = { byte_offset=%u, name='%s' }", + clang_type.GetOpaqueQualType(), idx, + (uint32_t)base_pos->second.getQuantity(), + base_pos->first->getNameAsString().c_str()); + } + } + { + llvm::DenseMap<const clang::CXXRecordDecl *, + clang::CharUnits>::const_iterator vbase_pos, + vbase_end = layout_info.vbase_offsets.end(); + for (idx = 0, vbase_pos = layout_info.vbase_offsets.begin(); + vbase_pos != vbase_end; ++vbase_pos, ++idx) { + module_sp->LogMessage( + log, "ClangASTContext::CompleteTypeFromDWARF (clang_type = " + "%p) vbase[%u] = { byte_offset=%u, name='%s' }", + static_cast<void *>(clang_type.GetOpaqueQualType()), idx, + static_cast<uint32_t>(vbase_pos->second.getQuantity()), + vbase_pos->first->getNameAsString().c_str()); + } + } + } + } + GetClangASTImporter().InsertRecordDecl(record_decl, layout_info); + } + } + } + + return (bool)clang_type; + + case DW_TAG_enumeration_type: + if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) { + if (die.HasChildren()) { + SymbolContext sc(die.GetLLDBCompileUnit()); + bool is_signed = false; + clang_type.IsIntegerType(is_signed); + ParseChildEnumerators(sc, clang_type, is_signed, type->GetByteSize(), + die); + } + ClangASTContext::CompleteTagDeclarationDefinition(clang_type); } + return (bool)clang_type; - return false; + default: + assert(false && "not a forward clang type decl!"); + break; + } + + return false; } -std::vector<DWARFDIE> -DWARFASTParserClang::GetDIEForDeclContext(lldb_private::CompilerDeclContext decl_context) -{ - std::vector<DWARFDIE> result; - for (auto it = m_decl_ctx_to_die.find((clang::DeclContext *)decl_context.GetOpaqueDeclContext()); it != m_decl_ctx_to_die.end(); it++) - result.push_back(it->second); - return result; +std::vector<DWARFDIE> DWARFASTParserClang::GetDIEForDeclContext( + lldb_private::CompilerDeclContext decl_context) { + std::vector<DWARFDIE> result; + for (auto it = m_decl_ctx_to_die.find( + (clang::DeclContext *)decl_context.GetOpaqueDeclContext()); + it != m_decl_ctx_to_die.end(); it++) + result.push_back(it->second); + return result; } -CompilerDecl -DWARFASTParserClang::GetDeclForUIDFromDWARF (const DWARFDIE &die) -{ - clang::Decl *clang_decl = GetClangDeclForDIE(die); - if (clang_decl != nullptr) - return CompilerDecl(&m_ast, clang_decl); - return CompilerDecl(); +CompilerDecl DWARFASTParserClang::GetDeclForUIDFromDWARF(const DWARFDIE &die) { + clang::Decl *clang_decl = GetClangDeclForDIE(die); + if (clang_decl != nullptr) + return CompilerDecl(&m_ast, clang_decl); + return CompilerDecl(); } CompilerDeclContext -DWARFASTParserClang::GetDeclContextForUIDFromDWARF (const DWARFDIE &die) -{ - clang::DeclContext *clang_decl_ctx = GetClangDeclContextForDIE (die); - if (clang_decl_ctx) - return CompilerDeclContext(&m_ast, clang_decl_ctx); - return CompilerDeclContext(); +DWARFASTParserClang::GetDeclContextForUIDFromDWARF(const DWARFDIE &die) { + clang::DeclContext *clang_decl_ctx = GetClangDeclContextForDIE(die); + if (clang_decl_ctx) + return CompilerDeclContext(&m_ast, clang_decl_ctx); + return CompilerDeclContext(); } CompilerDeclContext -DWARFASTParserClang::GetDeclContextContainingUIDFromDWARF (const DWARFDIE &die) -{ - clang::DeclContext *clang_decl_ctx = GetClangDeclContextContainingDIE (die, nullptr); - if (clang_decl_ctx) - return CompilerDeclContext(&m_ast, clang_decl_ctx); - return CompilerDeclContext(); +DWARFASTParserClang::GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) { + clang::DeclContext *clang_decl_ctx = + GetClangDeclContextContainingDIE(die, nullptr); + if (clang_decl_ctx) + return CompilerDeclContext(&m_ast, clang_decl_ctx); + return CompilerDeclContext(); } -size_t -DWARFASTParserClang::ParseChildEnumerators (const SymbolContext& sc, - lldb_private::CompilerType &clang_type, - bool is_signed, - uint32_t enumerator_byte_size, - const DWARFDIE &parent_die) -{ - if (!parent_die) - return 0; - - size_t enumerators_added = 0; +size_t DWARFASTParserClang::ParseChildEnumerators( + const SymbolContext &sc, lldb_private::CompilerType &clang_type, + bool is_signed, uint32_t enumerator_byte_size, const DWARFDIE &parent_die) { + if (!parent_die) + return 0; - for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling()) - { - const dw_tag_t tag = die.Tag(); - if (tag == DW_TAG_enumerator) - { - DWARFAttributes attributes; - const size_t num_child_attributes = die.GetAttributes(attributes); - if (num_child_attributes > 0) - { - const char *name = NULL; - bool got_value = false; - int64_t enum_value = 0; - Declaration decl; - - 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_const_value: - got_value = true; - if (is_signed) - enum_value = form_value.Signed(); - else - enum_value = form_value.Unsigned(); - break; - - case DW_AT_name: - name = form_value.AsCString(); - break; - - case DW_AT_description: - default: - case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; - case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; - case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; - case DW_AT_sibling: - break; - } - } - } + size_t enumerators_added = 0; - 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); - ++enumerators_added; - } + for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); + die = die.GetSibling()) { + const dw_tag_t tag = die.Tag(); + if (tag == DW_TAG_enumerator) { + DWARFAttributes attributes; + const size_t num_child_attributes = die.GetAttributes(attributes); + if (num_child_attributes > 0) { + const char *name = NULL; + bool got_value = false; + int64_t enum_value = 0; + Declaration decl; + + 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_const_value: + got_value = true; + if (is_signed) + enum_value = form_value.Signed(); + else + enum_value = form_value.Unsigned(); + break; + + case DW_AT_name: + name = form_value.AsCString(); + break; + + case DW_AT_description: + default: + case DW_AT_decl_file: + decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex( + form_value.Unsigned())); + break; + case DW_AT_decl_line: + decl.SetLine(form_value.Unsigned()); + break; + case DW_AT_decl_column: + decl.SetColumn(form_value.Unsigned()); + break; + case DW_AT_sibling: + break; } + } + } + + 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); + ++enumerators_added; } + } } - return enumerators_added; + } + return enumerators_added; } #if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE) -class DIEStack -{ +class DIEStack { public: - - void Push (const DWARFDIE &die) - { - m_dies.push_back (die); + void Push(const DWARFDIE &die) { m_dies.push_back(die); } + + void LogDIEs(Log *log) { + StreamString log_strm; + const size_t n = m_dies.size(); + log_strm.Printf("DIEStack[%" PRIu64 "]:\n", (uint64_t)n); + for (size_t i = 0; i < n; i++) { + std::string qualified_name; + const DWARFDIE &die = m_dies[i]; + die.GetQualifiedName(qualified_name); + log_strm.Printf("[%" PRIu64 "] 0x%8.8x: %s name='%s'\n", (uint64_t)i, + die.GetOffset(), die.GetTagAsCString(), + qualified_name.c_str()); } - - - void LogDIEs (Log *log) - { - StreamString log_strm; - const size_t n = m_dies.size(); - log_strm.Printf("DIEStack[%" PRIu64 "]:\n", (uint64_t)n); - for (size_t i=0; i<n; i++) - { - std::string qualified_name; - const DWARFDIE &die = m_dies[i]; - die.GetQualifiedName(qualified_name); - log_strm.Printf ("[%" PRIu64 "] 0x%8.8x: %s name='%s'\n", - (uint64_t)i, - die.GetOffset(), - die.GetTagAsCString(), - qualified_name.c_str()); - } - log->PutCString(log_strm.GetData()); - } - void Pop () - { - m_dies.pop_back(); + log->PutCString(log_strm.GetData()); + } + void Pop() { m_dies.pop_back(); } + + class ScopedPopper { + public: + ScopedPopper(DIEStack &die_stack) + : m_die_stack(die_stack), m_valid(false) {} + + void Push(const DWARFDIE &die) { + m_valid = true; + m_die_stack.Push(die); } - class ScopedPopper - { - public: - ScopedPopper (DIEStack &die_stack) : - m_die_stack (die_stack), - m_valid (false) - { - } - - void - Push (const DWARFDIE &die) - { - m_valid = true; - m_die_stack.Push (die); - } - - ~ScopedPopper () - { - if (m_valid) - m_die_stack.Pop(); - } - - + ~ScopedPopper() { + if (m_valid) + m_die_stack.Pop(); + } - protected: - DIEStack &m_die_stack; - bool m_valid; - }; + protected: + DIEStack &m_die_stack; + bool m_valid; + }; protected: - typedef std::vector<DWARFDIE> Stack; - Stack m_dies; + typedef std::vector<DWARFDIE> Stack; + Stack m_dies; }; #endif -Function * -DWARFASTParserClang::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()); - - const dw_tag_t tag = die.Tag(); +Function *DWARFASTParserClang::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()); + + const dw_tag_t tag = die.Tag(); + + if (tag != DW_TAG_subprogram) + return NULL; - if (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)) - { + 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); + } - // 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; + if (mangled) + func_name.SetValue(ConstString(mangled), true); + else if (die.GetParent().Tag() == DW_TAG_compile_unit && + Language::LanguageIsCPlusPlus(die.GetLanguage()) && name && + strcmp(name, "main") != 0) { + // If the mangled name is not present in the DWARF, generate the + // demangled name + // using the decl context. We skip if the function is "main" as its name + // is + // never mangled. + bool is_static = false; + bool is_variadic = false; + bool has_template_params = false; + unsigned type_quals = 0; + std::vector<CompilerType> param_types; + std::vector<clang::ParmVarDecl *> param_decls; + DWARFDeclContext decl_ctx; + StreamString sstr; + + die.GetDWARFDeclContext(decl_ctx); + sstr << decl_ctx.GetQualifiedName(); + + 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); + sstr << "("; + for (size_t i = 0; i < param_types.size(); i++) { + if (i > 0) + sstr << ", "; + sstr << param_types[i].GetTypeName(); + } + if (is_variadic) + sstr << ", ..."; + sstr << ")"; + if (type_quals & clang::Qualifiers::Const) + sstr << " const"; + + func_name.SetValue(ConstString(sstr.GetString()), false); + } else + 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->GetDIEToType().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; +} - if (func_range.GetBaseAddress().IsValid()) - { - Mangled func_name; - if (mangled) - func_name.SetValue(ConstString(mangled), true); - else if (die.GetParent().Tag() == DW_TAG_compile_unit && - Language::LanguageIsCPlusPlus(die.GetLanguage()) && - name && strcmp(name, "main") != 0) - { - // If the mangled name is not present in the DWARF, generate the demangled name - // using the decl context. We skip if the function is "main" as its name is - // never mangled. - bool is_static = false; - bool is_variadic = false; - bool has_template_params = false; - unsigned type_quals = 0; - std::vector<CompilerType> param_types; - std::vector<clang::ParmVarDecl*> param_decls; - DWARFDeclContext decl_ctx; - StreamString sstr; - - die.GetDWARFDeclContext(decl_ctx); - sstr << decl_ctx.GetQualifiedName(); - - 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); - sstr << "("; - for (size_t i = 0; i < param_types.size(); i++) - { - if (i > 0) - sstr << ", "; - sstr << param_types[i].GetTypeName(); +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<int> &member_accessibilities, + DWARFDIECollection &member_function_dies, + DelayedPropertyList &delayed_properties, AccessType &default_accessibility, + bool &is_a_class, ClangASTImporter::LayoutInfo &layout_info) { + if (!parent_die) + return 0; + + // Get the parent byte size so we can verify any members will fit + const uint64_t parent_byte_size = + parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size, UINT64_MAX) * 8; + const uint64_t parent_bit_size = + parent_byte_size == UINT64_MAX ? UINT64_MAX : parent_byte_size * 8; + + uint32_t member_idx = 0; + BitfieldInfo last_field_info; + + ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule(); + ClangASTContext *ast = + llvm::dyn_cast_or_null<ClangASTContext>(class_clang_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: + case DW_TAG_APPLE_property: { + DWARFAttributes attributes; + const size_t num_attributes = die.GetAttributes(attributes); + if (num_attributes > 0) { + Declaration decl; + // DWARFExpression location; + const char *name = NULL; + const char *prop_name = NULL; + const char *prop_getter_name = NULL; + const char *prop_setter_name = NULL; + uint32_t prop_attributes = 0; + + bool is_artificial = false; + DWARFFormValue encoding_form; + AccessType accessibility = eAccessNone; + uint32_t member_byte_offset = + (parent_die.Tag() == DW_TAG_union_type) ? 0 : UINT32_MAX; + size_t byte_size = 0; + int64_t bit_offset = 0; + uint64_t data_bit_offset = UINT64_MAX; + size_t bit_size = 0; + bool is_external = + false; // On DW_TAG_members, this means the member is static + uint32_t i; + for (i = 0; i < num_attributes && !is_artificial; ++i) { + const dw_attr_t attr = attributes.AttributeAtIndex(i); + DWARFFormValue form_value; + if (attributes.ExtractFormValueAtIndex(i, form_value)) { + switch (attr) { + case DW_AT_decl_file: + decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex( + form_value.Unsigned())); + break; + case DW_AT_decl_line: + decl.SetLine(form_value.Unsigned()); + break; + case DW_AT_decl_column: + decl.SetColumn(form_value.Unsigned()); + break; + case DW_AT_name: + name = form_value.AsCString(); + break; + case DW_AT_type: + encoding_form = form_value; + break; + case DW_AT_bit_offset: + bit_offset = form_value.Signed(); + break; + case DW_AT_bit_size: + bit_size = form_value.Unsigned(); + break; + case DW_AT_byte_size: + byte_size = form_value.Unsigned(); + break; + case DW_AT_data_bit_offset: + data_bit_offset = form_value.Unsigned(); + break; + case DW_AT_data_member_location: + if (form_value.BlockData()) { + Value initialValue(0); + Value memberOffset(0); + const DWARFDataExtractor &debug_info_data = + die.GetDWARF()->get_debug_info_data(); + uint32_t block_length = form_value.Unsigned(); + uint32_t block_offset = + form_value.BlockData() - debug_info_data.GetDataStart(); + if (DWARFExpression::Evaluate( + nullptr, // ExecutionContext * + nullptr, // ClangExpressionVariableList * + nullptr, // ClangExpressionDeclMap * + nullptr, // RegisterContext * + module_sp, debug_info_data, die.GetCU(), block_offset, + block_length, eRegisterKindDWARF, &initialValue, + nullptr, memberOffset, nullptr)) { + member_byte_offset = memberOffset.ResolveValue(NULL).UInt(); } - if (is_variadic) - sstr << ", ..."; - sstr << ")"; - if (type_quals & clang::Qualifiers::Const) - sstr << " const"; + } 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; + + case DW_AT_accessibility: + accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); + break; + case DW_AT_artificial: + is_artificial = form_value.Boolean(); + break; + case DW_AT_APPLE_property_name: + prop_name = form_value.AsCString(); + break; + case DW_AT_APPLE_property_getter: + prop_getter_name = form_value.AsCString(); + break; + case DW_AT_APPLE_property_setter: + prop_setter_name = form_value.AsCString(); + break; + case DW_AT_APPLE_property_attribute: + prop_attributes = form_value.Unsigned(); + break; + case DW_AT_external: + is_external = form_value.Boolean(); + break; - func_name.SetValue(ConstString(sstr.GetData()), false); + default: + case DW_AT_declaration: + case DW_AT_description: + case DW_AT_mutable: + case DW_AT_visibility: + case DW_AT_sibling: + break; } - else - 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->GetDIEToType().lookup (die.GetDIE()); + } + } - assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED); + if (prop_name) { + ConstString fixed_getter; + ConstString fixed_setter; - 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; -} + // Check if the property getter/setter were provided as full + // names. We want basenames, so we extract them. -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<int> &member_accessibilities, - DWARFDIECollection &member_function_dies, - DelayedPropertyList &delayed_properties, AccessType &default_accessibility, - bool &is_a_class, ClangASTImporter::LayoutInfo &layout_info) -{ - if (!parent_die) - return 0; - - // Get the parent byte size so we can verify any members will fit - const uint64_t parent_byte_size = parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size, UINT64_MAX) * 8; - const uint64_t parent_bit_size = parent_byte_size == UINT64_MAX ? UINT64_MAX : parent_byte_size * 8; - - uint32_t member_idx = 0; - BitfieldInfo last_field_info; - - ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule(); - ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(class_clang_type.GetTypeSystem()); - if (ast == nullptr) - return 0; - - for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling()) - { - dw_tag_t tag = die.Tag(); + if (prop_getter_name && prop_getter_name[0] == '-') { + ObjCLanguage::MethodName prop_getter_method(prop_getter_name, true); + prop_getter_name = prop_getter_method.GetSelector().GetCString(); + } - switch (tag) - { - case DW_TAG_member: - case DW_TAG_APPLE_property: - { - DWARFAttributes attributes; - const size_t num_attributes = die.GetAttributes (attributes); - if (num_attributes > 0) - { - Declaration decl; - //DWARFExpression location; - const char *name = NULL; - const char *prop_name = NULL; - const char *prop_getter_name = NULL; - const char *prop_setter_name = NULL; - uint32_t prop_attributes = 0; - - - bool is_artificial = false; - DWARFFormValue encoding_form; - AccessType accessibility = eAccessNone; - uint32_t member_byte_offset = (parent_die.Tag() == DW_TAG_union_type) ? 0 : UINT32_MAX; - size_t byte_size = 0; - int64_t bit_offset = 0; - uint64_t data_bit_offset = UINT64_MAX; - size_t bit_size = 0; - bool is_external = false; // On DW_TAG_members, this means the member is static - uint32_t i; - for (i=0; i<num_attributes && !is_artificial; ++i) - { - const dw_attr_t attr = attributes.AttributeAtIndex(i); - DWARFFormValue form_value; - if (attributes.ExtractFormValueAtIndex(i, form_value)) - { - switch (attr) - { - case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; - case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; - case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; - case DW_AT_name: name = form_value.AsCString(); break; - case DW_AT_type: encoding_form = form_value; break; - case DW_AT_bit_offset: bit_offset = form_value.Signed(); break; - case DW_AT_bit_size: bit_size = form_value.Unsigned(); break; - case DW_AT_byte_size: byte_size = form_value.Unsigned(); break; - case DW_AT_data_bit_offset: data_bit_offset = form_value.Unsigned(); break; - case DW_AT_data_member_location: - if (form_value.BlockData()) - { - Value initialValue(0); - Value memberOffset(0); - const DWARFDataExtractor& debug_info_data = die.GetDWARF()->get_debug_info_data(); - uint32_t block_length = form_value.Unsigned(); - uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); - if (DWARFExpression::Evaluate(nullptr, // ExecutionContext * - nullptr, // ClangExpressionVariableList * - nullptr, // ClangExpressionDeclMap * - nullptr, // RegisterContext * - module_sp, - debug_info_data, - die.GetCU(), - block_offset, - block_length, - eRegisterKindDWARF, - &initialValue, - nullptr, - memberOffset, - nullptr)) - { - 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; - - case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break; - case DW_AT_artificial: is_artificial = form_value.Boolean(); break; - case DW_AT_APPLE_property_name: prop_name = form_value.AsCString(); - break; - case DW_AT_APPLE_property_getter: prop_getter_name = form_value.AsCString(); - break; - case DW_AT_APPLE_property_setter: prop_setter_name = form_value.AsCString(); - break; - case DW_AT_APPLE_property_attribute: prop_attributes = form_value.Unsigned(); break; - case DW_AT_external: is_external = form_value.Boolean(); break; - - default: - case DW_AT_declaration: - case DW_AT_description: - case DW_AT_mutable: - case DW_AT_visibility: - case DW_AT_sibling: - break; - } - } - } + if (prop_setter_name && prop_setter_name[0] == '-') { + ObjCLanguage::MethodName prop_setter_method(prop_setter_name, true); + prop_setter_name = prop_setter_method.GetSelector().GetCString(); + } - if (prop_name) - { - ConstString fixed_getter; - ConstString fixed_setter; + // If the names haven't been provided, they need to be + // filled in. - // Check if the property getter/setter were provided as full - // names. We want basenames, so we extract them. + if (!prop_getter_name) { + prop_getter_name = prop_name; + } + if (!prop_setter_name && prop_name[0] && + !(prop_attributes & DW_APPLE_PROPERTY_readonly)) { + StreamString ss; - if (prop_getter_name && prop_getter_name[0] == '-') - { - ObjCLanguage::MethodName prop_getter_method(prop_getter_name, true); - prop_getter_name = prop_getter_method.GetSelector().GetCString(); - } + ss.Printf("set%c%s:", toupper(prop_name[0]), &prop_name[1]); - if (prop_setter_name && prop_setter_name[0] == '-') - { - ObjCLanguage::MethodName prop_setter_method(prop_setter_name, true); - prop_setter_name = prop_setter_method.GetSelector().GetCString(); - } + fixed_setter.SetString(ss.GetString()); + prop_setter_name = fixed_setter.GetCString(); + } + } - // If the names haven't been provided, they need to be - // filled in. + // Clang has a DWARF generation bug where sometimes it + // represents fields that are references with bad byte size + // and bit size/offset information such as: + // + // DW_AT_byte_size( 0x00 ) + // DW_AT_bit_size( 0x40 ) + // DW_AT_bit_offset( 0xffffffffffffffc0 ) + // + // So check the bit offset to make sure it is sane, and if + // the values are not sane, remove them. If we don't do this + // then we will end up with a crash if we try to use this + // type in an expression when clang becomes unhappy with its + // recycled debug info. + + if (byte_size == 0 && bit_offset < 0) { + bit_size = 0; + bit_offset = 0; + } - if (!prop_getter_name) - { - prop_getter_name = prop_name; - } - if (!prop_setter_name && prop_name[0] && !(prop_attributes & DW_APPLE_PROPERTY_readonly)) - { - StreamString ss; + // FIXME: Make Clang ignore Objective-C accessibility for expressions + if (class_language == eLanguageTypeObjC || + 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; + } - ss.Printf("set%c%s:", - toupper(prop_name[0]), - &prop_name[1]); + // Handle static members + if (is_external && member_byte_offset == UINT32_MAX) { + Type *var_type = die.ResolveTypeUID(DIERef(encoding_form)); + + if (var_type) { + if (accessibility == eAccessNone) + accessibility = eAccessPublic; + ClangASTContext::AddVariableToRecordType( + class_clang_type, name, var_type->GetLayoutCompilerType(), + accessibility); + } + break; + } - fixed_setter.SetCString(ss.GetData()); - prop_setter_name = fixed_setter.GetCString(); - } - } + if (is_artificial == false) { + Type *member_type = die.ResolveTypeUID(DIERef(encoding_form)); + + clang::FieldDecl *field_decl = NULL; + if (tag == DW_TAG_member) { + if (member_type) { + if (accessibility == eAccessNone) + accessibility = default_accessibility; + member_accessibilities.push_back(accessibility); + + uint64_t field_bit_offset = + (member_byte_offset == UINT32_MAX ? 0 + : (member_byte_offset * 8)); + if (bit_size > 0) { + + BitfieldInfo this_field_info; + this_field_info.bit_offset = field_bit_offset; + this_field_info.bit_size = bit_size; + + ///////////////////////////////////////////////////////////// + // How to locate a field given the DWARF debug information + // + // AT_byte_size indicates the size of the word in which the + // bit offset must be interpreted. + // + // AT_data_member_location indicates the byte offset of the + // word from the base address of the structure. + // + // AT_bit_offset indicates how many bits into the word + // (according to the host endianness) the low-order bit of + // the field starts. AT_bit_offset can be negative. + // + // AT_bit_size indicates the size of the field in bits. + ///////////////////////////////////////////////////////////// + + if (data_bit_offset != UINT64_MAX) { + this_field_info.bit_offset = data_bit_offset; + } else { + if (byte_size == 0) + byte_size = member_type->GetByteSize(); + + ObjectFile *objfile = die.GetDWARF()->GetObjectFile(); + if (objfile->GetByteOrder() == eByteOrderLittle) { + this_field_info.bit_offset += byte_size * 8; + this_field_info.bit_offset -= (bit_offset + bit_size); + } else { + this_field_info.bit_offset += bit_offset; + } + } - // Clang has a DWARF generation bug where sometimes it - // represents fields that are references with bad byte size - // and bit size/offset information such as: - // - // DW_AT_byte_size( 0x00 ) - // DW_AT_bit_size( 0x40 ) - // DW_AT_bit_offset( 0xffffffffffffffc0 ) - // - // So check the bit offset to make sure it is sane, and if - // the values are not sane, remove them. If we don't do this - // then we will end up with a crash if we try to use this - // type in an expression when clang becomes unhappy with its - // recycled debug info. - - if (byte_size == 0 && bit_offset < 0) - { - bit_size = 0; - bit_offset = 0; - } + if ((this_field_info.bit_offset >= parent_bit_size) || + !last_field_info.NextBitfieldOffsetIsValid( + this_field_info.bit_offset)) { + ObjectFile *objfile = die.GetDWARF()->GetObjectFile(); + objfile->GetModule()->ReportWarning( + "0x%8.8" PRIx64 ": %s bitfield named \"%s\" has invalid " + "bit offset (0x%8.8" PRIx64 + ") member will be ignored. Please file a bug against the " + "compiler and include the preprocessed output for %s\n", + die.GetID(), DW_TAG_value_to_name(tag), name, + this_field_info.bit_offset, + sc.comp_unit ? sc.comp_unit->GetPath().c_str() + : "the source file"); + this_field_info.Clear(); + continue; + } - // FIXME: Make Clang ignore Objective-C accessibility for expressions - if (class_language == eLanguageTypeObjC || - 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; + // Update the field bit offset we will report for layout + field_bit_offset = this_field_info.bit_offset; + + // If the member to be emitted did not start on a character + // boundary and there is + // empty space between the last field and this one, then we need + // to emit an + // anonymous member filling up the space up to its start. There + // are three cases + // here: + // + // 1 If the previous member ended on a character boundary, then + // we can emit an + // anonymous member starting at the most recent character + // boundary. + // + // 2 If the previous member did not end on a character boundary + // and the distance + // from the end of the previous member to the current member + // is less than a + // word width, then we can emit an anonymous member starting + // right after the + // previous member and right before this member. + // + // 3 If the previous member did not end on a character boundary + // and the distance + // from the end of the previous member to the current member + // is greater than + // or equal a word width, then we act as in Case 1. + + const uint64_t character_width = 8; + const uint64_t word_width = 32; + + // Objective-C has invalid DW_AT_bit_offset values in older + // versions + // of clang, so we have to be careful and only insert unnamed + // bitfields + // if we have a new enough clang. + bool detect_unnamed_bitfields = true; + + if (class_language == eLanguageTypeObjC || + class_language == eLanguageTypeObjC_plus_plus) + detect_unnamed_bitfields = + die.GetCU()->Supports_unnamed_objc_bitfields(); + + if (detect_unnamed_bitfields) { + BitfieldInfo anon_field_info; + + if ((this_field_info.bit_offset % character_width) != + 0) // not char aligned + { + uint64_t last_field_end = 0; + + if (last_field_info.IsValid()) + last_field_end = + last_field_info.bit_offset + last_field_info.bit_size; + + if (this_field_info.bit_offset != last_field_end) { + if (((last_field_end % character_width) == 0) || // case 1 + (this_field_info.bit_offset - last_field_end >= + word_width)) // case 3 + { + anon_field_info.bit_size = + this_field_info.bit_offset % character_width; + anon_field_info.bit_offset = + this_field_info.bit_offset - + anon_field_info.bit_size; + } else // case 2 + { + anon_field_info.bit_size = + this_field_info.bit_offset - last_field_end; + anon_field_info.bit_offset = last_field_end; + } } - - // Handle static members - if (is_external && member_byte_offset == UINT32_MAX) - { - Type *var_type = die.ResolveTypeUID(DIERef(encoding_form)); - - if (var_type) - { - if (accessibility == eAccessNone) - accessibility = eAccessPublic; - ClangASTContext::AddVariableToRecordType (class_clang_type, - name, - var_type->GetLayoutCompilerType (), - accessibility); - } - break; + } + + if (anon_field_info.IsValid()) { + clang::FieldDecl *unnamed_bitfield_decl = + ClangASTContext::AddFieldToRecordType( + class_clang_type, NULL, + m_ast.GetBuiltinTypeForEncodingAndBitSize( + eEncodingSint, word_width), + accessibility, anon_field_info.bit_size); + + layout_info.field_offsets.insert(std::make_pair( + unnamed_bitfield_decl, anon_field_info.bit_offset)); + } + } + last_field_info = this_field_info; + } else { + last_field_info.Clear(); + } + + CompilerType member_clang_type = + member_type->GetLayoutCompilerType(); + if (!member_clang_type.IsCompleteType()) + member_clang_type.GetCompleteType(); + + { + // Older versions of clang emit array[0] and array[1] in the + // same way (<rdar://problem/12566646>). + // If the current field is at the end of the structure, then + // there is definitely no room for extra + // elements and we override the type to array[0]. + + CompilerType member_array_element_type; + uint64_t member_array_size; + bool member_array_is_incomplete; + + if (member_clang_type.IsArrayType( + &member_array_element_type, &member_array_size, + &member_array_is_incomplete) && + !member_array_is_incomplete) { + uint64_t parent_byte_size = + parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size, + UINT64_MAX); + + if (member_byte_offset >= parent_byte_size) { + if (member_array_size != 1 && + (member_array_size != 0 || + member_byte_offset > parent_byte_size)) { + module_sp->ReportError( + "0x%8.8" PRIx64 + ": DW_TAG_member '%s' refers to type 0x%8.8" PRIx64 + " which extends beyond the bounds of 0x%8.8" PRIx64, + die.GetID(), name, encoding_form.Reference(), + parent_die.GetID()); } - if (is_artificial == false) - { - Type *member_type = die.ResolveTypeUID(DIERef(encoding_form)); - - clang::FieldDecl *field_decl = NULL; - if (tag == DW_TAG_member) - { - if (member_type) - { - if (accessibility == eAccessNone) - accessibility = default_accessibility; - member_accessibilities.push_back(accessibility); - - uint64_t field_bit_offset = (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8)); - if (bit_size > 0) - { - - BitfieldInfo this_field_info; - this_field_info.bit_offset = field_bit_offset; - this_field_info.bit_size = bit_size; - - ///////////////////////////////////////////////////////////// - // How to locate a field given the DWARF debug information - // - // AT_byte_size indicates the size of the word in which the - // bit offset must be interpreted. - // - // AT_data_member_location indicates the byte offset of the - // word from the base address of the structure. - // - // AT_bit_offset indicates how many bits into the word - // (according to the host endianness) the low-order bit of - // the field starts. AT_bit_offset can be negative. - // - // AT_bit_size indicates the size of the field in bits. - ///////////////////////////////////////////////////////////// - - if (data_bit_offset != UINT64_MAX) - { - this_field_info.bit_offset = data_bit_offset; - } - else - { - if (byte_size == 0) - byte_size = member_type->GetByteSize(); - - ObjectFile *objfile = die.GetDWARF()->GetObjectFile(); - if (objfile->GetByteOrder() == eByteOrderLittle) - { - this_field_info.bit_offset += byte_size * 8; - this_field_info.bit_offset -= (bit_offset + bit_size); - } - else - { - this_field_info.bit_offset += bit_offset; - } - } - - if ((this_field_info.bit_offset >= parent_bit_size) || !last_field_info.NextBitfieldOffsetIsValid(this_field_info.bit_offset)) - { - ObjectFile *objfile = die.GetDWARF()->GetObjectFile(); - objfile->GetModule()->ReportWarning("0x%8.8" PRIx64 ": %s bitfield named \"%s\" has invalid bit offset (0x%8.8" PRIx64 ") member will be ignored. Please file a bug against the compiler and include the preprocessed output for %s\n", - die.GetID(), - DW_TAG_value_to_name(tag), - name, - this_field_info.bit_offset, - sc.comp_unit ? sc.comp_unit->GetPath().c_str() : "the source file"); - this_field_info.Clear(); - continue; - } - - // Update the field bit offset we will report for layout - field_bit_offset = this_field_info.bit_offset; - - // If the member to be emitted did not start on a character boundary and there is - // empty space between the last field and this one, then we need to emit an - // anonymous member filling up the space up to its start. There are three cases - // here: - // - // 1 If the previous member ended on a character boundary, then we can emit an - // anonymous member starting at the most recent character boundary. - // - // 2 If the previous member did not end on a character boundary and the distance - // from the end of the previous member to the current member is less than a - // word width, then we can emit an anonymous member starting right after the - // previous member and right before this member. - // - // 3 If the previous member did not end on a character boundary and the distance - // from the end of the previous member to the current member is greater than - // or equal a word width, then we act as in Case 1. - - const uint64_t character_width = 8; - const uint64_t word_width = 32; - - // Objective-C has invalid DW_AT_bit_offset values in older versions - // of clang, so we have to be careful and only insert unnamed bitfields - // if we have a new enough clang. - bool detect_unnamed_bitfields = true; - - if (class_language == eLanguageTypeObjC || class_language == eLanguageTypeObjC_plus_plus) - detect_unnamed_bitfields = die.GetCU()->Supports_unnamed_objc_bitfields (); - - if (detect_unnamed_bitfields) - { - BitfieldInfo anon_field_info; - - if ((this_field_info.bit_offset % character_width) != 0) // not char aligned - { - uint64_t last_field_end = 0; - - if (last_field_info.IsValid()) - last_field_end = last_field_info.bit_offset + last_field_info.bit_size; - - if (this_field_info.bit_offset != last_field_end) - { - if (((last_field_end % character_width) == 0) || // case 1 - (this_field_info.bit_offset - last_field_end >= word_width)) // case 3 - { - anon_field_info.bit_size = this_field_info.bit_offset % character_width; - anon_field_info.bit_offset = this_field_info.bit_offset - anon_field_info.bit_size; - } - else // case 2 - { - anon_field_info.bit_size = this_field_info.bit_offset - last_field_end; - anon_field_info.bit_offset = last_field_end; - } - } - } - - if (anon_field_info.IsValid()) - { - clang::FieldDecl *unnamed_bitfield_decl = - ClangASTContext::AddFieldToRecordType (class_clang_type, - NULL, - m_ast.GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, word_width), - accessibility, - anon_field_info.bit_size); - - layout_info.field_offsets.insert( - std::make_pair(unnamed_bitfield_decl, anon_field_info.bit_offset)); - } - } - last_field_info = this_field_info; - } - else - { - last_field_info.Clear(); - } - - CompilerType member_clang_type = member_type->GetLayoutCompilerType (); - if (!member_clang_type.IsCompleteType()) - member_clang_type.GetCompleteType(); - - { - // Older versions of clang emit array[0] and array[1] in the same way (<rdar://problem/12566646>). - // If the current field is at the end of the structure, then there is definitely no room for extra - // elements and we override the type to array[0]. - - CompilerType member_array_element_type; - uint64_t member_array_size; - bool member_array_is_incomplete; - - if (member_clang_type.IsArrayType(&member_array_element_type, - &member_array_size, - &member_array_is_incomplete) && - !member_array_is_incomplete) - { - uint64_t parent_byte_size = parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size, UINT64_MAX); - - if (member_byte_offset >= parent_byte_size) - { - if (member_array_size != 1 && (member_array_size != 0 || member_byte_offset > parent_byte_size)) - { - module_sp->ReportError ("0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8" PRIx64 " which extends beyond the bounds of 0x%8.8" PRIx64, - die.GetID(), - name, - encoding_form.Reference(), - parent_die.GetID()); - } - - member_clang_type = m_ast.CreateArrayType(member_array_element_type, 0, false); - } - } - } - - if (ClangASTContext::IsCXXClassType(member_clang_type) && member_clang_type.GetCompleteType() == false) - { - if (die.GetCU()->GetProducer() == DWARFCompileUnit::eProducerClang) - module_sp->ReportError ("DWARF DIE at 0x%8.8x (class %s) has a member variable 0x%8.8x (%s) whose type is a forward declaration, not a complete definition.\nTry compiling the source file with -fno-limit-debug-info", - parent_die.GetOffset(), - parent_die.GetName(), - die.GetOffset(), - name); - else - module_sp->ReportError ("DWARF DIE at 0x%8.8x (class %s) has a member variable 0x%8.8x (%s) whose type is a forward declaration, not a complete definition.\nPlease file a bug against the compiler and include the preprocessed output for %s", - parent_die.GetOffset(), - parent_die.GetName(), - die.GetOffset(), - name, - sc.comp_unit ? sc.comp_unit->GetPath().c_str() : "the source file"); - // We have no choice other than to pretend that the member class - // is complete. If we don't do this, clang will crash when trying - // to layout the class. 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. - if (ClangASTContext::StartTagDeclarationDefinition(member_clang_type)) - { - ClangASTContext::CompleteTagDeclarationDefinition(member_clang_type); - } - else - { - module_sp->ReportError ("DWARF DIE at 0x%8.8x (class %s) has a member variable 0x%8.8x (%s) whose type claims to be a C++ class but we were not able to start its definition.\nPlease file a bug and attach the file at the start of this error message", - parent_die.GetOffset(), - parent_die.GetName(), - die.GetOffset(), - name); - } - } - - field_decl = ClangASTContext::AddFieldToRecordType (class_clang_type, - name, - member_clang_type, - accessibility, - bit_size); - - m_ast.SetMetadataAsUserID (field_decl, die.GetID()); - - layout_info.field_offsets.insert(std::make_pair(field_decl, field_bit_offset)); - } - else - { - if (name) - module_sp->ReportError ("0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8" PRIx64 " which was unable to be parsed", - die.GetID(), - name, - encoding_form.Reference()); - else - module_sp->ReportError ("0x%8.8" PRIx64 ": DW_TAG_member refers to type 0x%8.8" PRIx64 " which was unable to be parsed", - die.GetID(), - encoding_form.Reference()); - } - } - - if (prop_name != NULL && member_type) - { - clang::ObjCIvarDecl *ivar_decl = NULL; + member_clang_type = m_ast.CreateArrayType( + member_array_element_type, 0, false); + } + } + } + + if (ClangASTContext::IsCXXClassType(member_clang_type) && + member_clang_type.GetCompleteType() == false) { + if (die.GetCU()->GetProducer() == + DWARFCompileUnit::eProducerClang) + module_sp->ReportError( + "DWARF DIE at 0x%8.8x (class %s) has a member variable " + "0x%8.8x (%s) whose type is a forward declaration, not a " + "complete definition.\nTry compiling the source file " + "with -fno-limit-debug-info", + parent_die.GetOffset(), parent_die.GetName(), + die.GetOffset(), name); + else + module_sp->ReportError( + "DWARF DIE at 0x%8.8x (class %s) has a member variable " + "0x%8.8x (%s) whose type is a forward declaration, not a " + "complete definition.\nPlease file a bug against the " + "compiler and include the preprocessed output for %s", + parent_die.GetOffset(), parent_die.GetName(), + die.GetOffset(), name, + sc.comp_unit ? sc.comp_unit->GetPath().c_str() + : "the source file"); + // We have no choice other than to pretend that the member class + // is complete. If we don't do this, clang will crash when + // trying + // to layout the class. 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. + if (ClangASTContext::StartTagDeclarationDefinition( + member_clang_type)) { + ClangASTContext::CompleteTagDeclarationDefinition( + member_clang_type); + } else { + module_sp->ReportError( + "DWARF DIE at 0x%8.8x (class %s) has a member variable " + "0x%8.8x (%s) whose type claims to be a C++ class but we " + "were not able to start its definition.\nPlease file a " + "bug and attach the file at the start of this error " + "message", + parent_die.GetOffset(), parent_die.GetName(), + die.GetOffset(), name); + } + } + + field_decl = ClangASTContext::AddFieldToRecordType( + class_clang_type, name, member_clang_type, accessibility, + bit_size); + + m_ast.SetMetadataAsUserID(field_decl, die.GetID()); + + layout_info.field_offsets.insert( + std::make_pair(field_decl, field_bit_offset)); + } else { + if (name) + module_sp->ReportError( + "0x%8.8" PRIx64 + ": DW_TAG_member '%s' refers to type 0x%8.8" PRIx64 + " which was unable to be parsed", + die.GetID(), name, encoding_form.Reference()); + else + module_sp->ReportError( + "0x%8.8" PRIx64 + ": DW_TAG_member refers to type 0x%8.8" PRIx64 + " which was unable to be parsed", + die.GetID(), encoding_form.Reference()); + } + } - if (field_decl) - { - ivar_decl = clang::dyn_cast<clang::ObjCIvarDecl>(field_decl); - assert (ivar_decl != NULL); - } + if (prop_name != NULL && member_type) { + clang::ObjCIvarDecl *ivar_decl = NULL; - ClangASTMetadata metadata; - metadata.SetUserID (die.GetID()); - delayed_properties.push_back(DelayedAddObjCClassProperty(class_clang_type, - prop_name, - member_type->GetLayoutCompilerType (), - ivar_decl, - prop_setter_name, - prop_getter_name, - prop_attributes, - &metadata)); - - if (ivar_decl) - m_ast.SetMetadataAsUserID (ivar_decl, die.GetID()); - } - } - } - ++member_idx; + if (field_decl) { + ivar_decl = clang::dyn_cast<clang::ObjCIvarDecl>(field_decl); + assert(ivar_decl != NULL); } - break; - case DW_TAG_subprogram: - // Let the type parsing code handle this one for us. - member_function_dies.Append (die); - break; + ClangASTMetadata metadata; + metadata.SetUserID(die.GetID()); + delayed_properties.push_back(DelayedAddObjCClassProperty( + class_clang_type, prop_name, + member_type->GetLayoutCompilerType(), ivar_decl, + prop_setter_name, prop_getter_name, prop_attributes, + &metadata)); + + if (ivar_decl) + m_ast.SetMetadataAsUserID(ivar_decl, die.GetID()); + } + } + } + ++member_idx; + } break; + + case DW_TAG_subprogram: + // Let the type parsing code handle this one for us. + member_function_dies.Append(die); + break; + + case DW_TAG_inheritance: { + is_a_class = true; + if (default_accessibility == eAccessNone) + default_accessibility = eAccessPrivate; + // TODO: implement DW_TAG_inheritance type parsing + DWARFAttributes attributes; + const size_t num_attributes = die.GetAttributes(attributes); + if (num_attributes > 0) { + Declaration decl; + DWARFExpression location(die.GetCU()); + DWARFFormValue encoding_form; + AccessType accessibility = default_accessibility; + bool is_virtual = false; + bool is_base_of_class = true; + off_t member_byte_offset = 0; + 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_decl_file: + decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex( + form_value.Unsigned())); + break; + case DW_AT_decl_line: + decl.SetLine(form_value.Unsigned()); + break; + case DW_AT_decl_column: + decl.SetColumn(form_value.Unsigned()); + break; + case DW_AT_type: + encoding_form = 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.GetDWARF()->get_debug_info_data(); + uint32_t block_length = form_value.Unsigned(); + uint32_t block_offset = + form_value.BlockData() - debug_info_data.GetDataStart(); + if (DWARFExpression::Evaluate( + nullptr, nullptr, nullptr, nullptr, module_sp, + debug_info_data, die.GetCU(), block_offset, + block_length, eRegisterKindDWARF, &initialValue, + nullptr, memberOffset, nullptr)) { + 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; - case DW_TAG_inheritance: - { - is_a_class = true; - if (default_accessibility == eAccessNone) - default_accessibility = eAccessPrivate; - // TODO: implement DW_TAG_inheritance type parsing - DWARFAttributes attributes; - const size_t num_attributes = die.GetAttributes (attributes); - if (num_attributes > 0) - { - Declaration decl; - DWARFExpression location(die.GetCU()); - DWARFFormValue encoding_form; - AccessType accessibility = default_accessibility; - bool is_virtual = false; - bool is_base_of_class = true; - off_t member_byte_offset = 0; - 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_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; - case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; - case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; - case DW_AT_type: encoding_form = 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.GetDWARF()->get_debug_info_data(); - uint32_t block_length = form_value.Unsigned(); - uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); - if (DWARFExpression::Evaluate (nullptr, - nullptr, - nullptr, - nullptr, - module_sp, - debug_info_data, - die.GetCU(), - block_offset, - block_length, - eRegisterKindDWARF, - &initialValue, - nullptr, - memberOffset, - nullptr)) - { - 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; - - case DW_AT_accessibility: - accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); - break; - - case DW_AT_virtuality: - is_virtual = form_value.Boolean(); - break; - - case DW_AT_sibling: - break; - - default: - break; - } - } - } + case DW_AT_accessibility: + accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); + break; - Type *base_class_type = die.ResolveTypeUID(DIERef(encoding_form)); - if (base_class_type == NULL) - { - module_sp->ReportError("0x%8.8x: DW_TAG_inheritance failed to resolve the base class at 0x%8.8" PRIx64 " from enclosing type 0x%8.8x. \nPlease file a bug and attach the file at the start of this error message", - die.GetOffset(), - encoding_form.Reference(), - parent_die.GetOffset()); - break; - } + case DW_AT_virtuality: + is_virtual = form_value.Boolean(); + break; - CompilerType base_class_clang_type = base_class_type->GetFullCompilerType (); - assert (base_class_clang_type); - 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)); - - if (is_virtual) - { - // Do not specify any offset for virtual inheritance. The DWARF produced by clang doesn't - // give us a constant offset, but gives us a DWARF expressions that requires an actual object - // in memory. the DW_AT_data_member_location for a virtual base class looks like: - // DW_AT_data_member_location( DW_OP_dup, DW_OP_deref, DW_OP_constu(0x00000018), DW_OP_minus, DW_OP_deref, DW_OP_plus ) - // Given this, there is really no valid response we can give to clang for virtual base - // class offsets, and this should eventually be removed from LayoutRecordType() in the external - // AST source in clang. - } - else - { - layout_info.base_offsets.insert( - std::make_pair(ast->GetAsCXXRecordDecl(base_class_clang_type.GetOpaqueQualType()), - clang::CharUnits::fromQuantity(member_byte_offset))); - } - } - } - } - break; + case DW_AT_sibling: + break; default: - break; + break; + } + } } - } - - return true; -} + Type *base_class_type = die.ResolveTypeUID(DIERef(encoding_form)); + if (base_class_type == NULL) { + module_sp->ReportError("0x%8.8x: DW_TAG_inheritance failed to " + "resolve the base class at 0x%8.8" PRIx64 + " from enclosing type 0x%8.8x. \nPlease file " + "a bug and attach the file at the start of " + "this error message", + die.GetOffset(), encoding_form.Reference(), + parent_die.GetOffset()); + break; + } -size_t -DWARFASTParserClang::ParseChildParameters (const SymbolContext& sc, - 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, - std::vector<clang::ParmVarDecl*>& function_param_decls, - unsigned &type_quals) -{ - if (!parent_die) - return 0; - - size_t arg_idx = 0; - for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling()) - { - const 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) - { - const char *name = NULL; - Declaration decl; - DWARFFormValue param_type_die_form; - bool is_artificial = false; - // one of None, Auto, Register, Extern, Static, PrivateExtern - - clang::StorageClass storage = clang::SC_None; - 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_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; - case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; - case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; - case DW_AT_name: name = form_value.AsCString(); - break; - case DW_AT_type: param_type_die_form = form_value; break; - case DW_AT_artificial: is_artificial = form_value.Boolean(); 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; - case DW_AT_const_value: - case DW_AT_default_value: - case DW_AT_description: - case DW_AT_endianity: - case DW_AT_is_optional: - case DW_AT_segment: - case DW_AT_variable_parameter: - default: - case DW_AT_abstract_origin: - case DW_AT_sibling: - break; - } - } - } + CompilerType base_class_clang_type = + base_class_type->GetFullCompilerType(); + assert(base_class_clang_type); + 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)); + + if (is_virtual) { + // Do not specify any offset for virtual inheritance. The DWARF + // produced by clang doesn't + // give us a constant offset, but gives us a DWARF expressions that + // requires an actual object + // in memory. the DW_AT_data_member_location for a virtual base + // class looks like: + // DW_AT_data_member_location( DW_OP_dup, DW_OP_deref, + // DW_OP_constu(0x00000018), DW_OP_minus, DW_OP_deref, + // DW_OP_plus ) + // Given this, there is really no valid response we can give to + // clang for virtual base + // class offsets, and this should eventually be removed from + // LayoutRecordType() in the external + // AST source in clang. + } else { + layout_info.base_offsets.insert(std::make_pair( + ast->GetAsCXXRecordDecl( + base_class_clang_type.GetOpaqueQualType()), + clang::CharUnits::fromQuantity(member_byte_offset))); + } + } + } + } break; - bool skip = false; - if (skip_artificial) - { - if (is_artificial) - { - // In order to determine if a C++ member function is - // "const" we have to look at the const-ness of "this"... - // Ugly, but that - if (arg_idx == 0) - { - if (DeclKindIsCXXClass(containing_decl_ctx->getDeclKind())) - { - // Often times compilers omit the "this" name for the - // specification DIEs, so we can't rely upon the name - // being in the formal parameter DIE... - if (name == NULL || ::strcmp(name, "this")==0) - { - Type *this_type = die.ResolveTypeUID (DIERef(param_type_die_form)); - if (this_type) - { - uint32_t encoding_mask = this_type->GetEncodingMask(); - if (encoding_mask & Type::eEncodingIsPointerUID) - { - is_static = false; - - if (encoding_mask & (1u << Type::eEncodingIsConstUID)) - type_quals |= clang::Qualifiers::Const; - if (encoding_mask & (1u << Type::eEncodingIsVolatileUID)) - type_quals |= clang::Qualifiers::Volatile; - } - } - } - } - } - skip = true; - } - else - { - - // HACK: Objective C formal parameters "self" and "_cmd" - // are not marked as artificial in the DWARF... - CompileUnit *comp_unit = die.GetLLDBCompileUnit(); - if (comp_unit) - { - switch (comp_unit->GetLanguage()) - { - case eLanguageTypeObjC: - case eLanguageTypeObjC_plus_plus: - if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0)) - skip = true; - break; - default: - break; - } - } - } - } + default: + break; + } + } - if (!skip) - { - Type *type = die.ResolveTypeUID(DIERef(param_type_die_form)); - if (type) - { - function_param_types.push_back (type->GetForwardCompilerType ()); + return true; +} - clang::ParmVarDecl *param_var_decl = m_ast.CreateParameterDeclaration (name, - type->GetForwardCompilerType (), - storage); - assert(param_var_decl); - function_param_decls.push_back(param_var_decl); +size_t DWARFASTParserClang::ParseChildParameters( + const SymbolContext &sc, 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, + std::vector<clang::ParmVarDecl *> &function_param_decls, + unsigned &type_quals) { + if (!parent_die) + return 0; + + size_t arg_idx = 0; + for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); + die = die.GetSibling()) { + const 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) { + const char *name = NULL; + Declaration decl; + DWARFFormValue param_type_die_form; + bool is_artificial = false; + // one of None, Auto, Register, Extern, Static, PrivateExtern + + clang::StorageClass storage = clang::SC_None; + 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_decl_file: + decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex( + form_value.Unsigned())); + break; + case DW_AT_decl_line: + decl.SetLine(form_value.Unsigned()); + break; + case DW_AT_decl_column: + decl.SetColumn(form_value.Unsigned()); + break; + case DW_AT_name: + name = form_value.AsCString(); + break; + case DW_AT_type: + param_type_die_form = form_value; + break; + case DW_AT_artificial: + is_artificial = form_value.Boolean(); + 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; + case DW_AT_const_value: + case DW_AT_default_value: + case DW_AT_description: + case DW_AT_endianity: + case DW_AT_is_optional: + case DW_AT_segment: + case DW_AT_variable_parameter: + default: + case DW_AT_abstract_origin: + case DW_AT_sibling: + break; + } + } + } - m_ast.SetMetadataAsUserID (param_var_decl, die.GetID()); - } + bool skip = false; + if (skip_artificial) { + if (is_artificial) { + // In order to determine if a C++ member function is + // "const" we have to look at the const-ness of "this"... + // Ugly, but that + if (arg_idx == 0) { + if (DeclKindIsCXXClass(containing_decl_ctx->getDeclKind())) { + // Often times compilers omit the "this" name for the + // specification DIEs, so we can't rely upon the name + // being in the formal parameter DIE... + if (name == NULL || ::strcmp(name, "this") == 0) { + Type *this_type = + die.ResolveTypeUID(DIERef(param_type_die_form)); + if (this_type) { + uint32_t encoding_mask = this_type->GetEncodingMask(); + if (encoding_mask & Type::eEncodingIsPointerUID) { + is_static = false; + + if (encoding_mask & (1u << Type::eEncodingIsConstUID)) + type_quals |= clang::Qualifiers::Const; + if (encoding_mask & (1u << Type::eEncodingIsVolatileUID)) + type_quals |= clang::Qualifiers::Volatile; } + } } - arg_idx++; + } } + skip = true; + } else { + + // HACK: Objective C formal parameters "self" and "_cmd" + // are not marked as artificial in the DWARF... + CompileUnit *comp_unit = die.GetLLDBCompileUnit(); + if (comp_unit) { + switch (comp_unit->GetLanguage()) { + case eLanguageTypeObjC: + case eLanguageTypeObjC_plus_plus: + if (name && name[0] && + (strcmp(name, "self") == 0 || strcmp(name, "_cmd") == 0)) + skip = true; break; - - case DW_TAG_unspecified_parameters: - is_variadic = true; + default: break; + } + } + } + } - case DW_TAG_template_type_parameter: - case DW_TAG_template_value_parameter: - // The one caller of this was never using the template_param_infos, - // and the local variable was taking up a large amount of stack space - // in SymbolFileDWARF::ParseType() so this was removed. If we ever need - // the template params back, we can add them back. - // ParseTemplateDIE (dwarf_cu, die, template_param_infos); - has_template_params = true; - break; + if (!skip) { + Type *type = die.ResolveTypeUID(DIERef(param_type_die_form)); + if (type) { + function_param_types.push_back(type->GetForwardCompilerType()); - default: - break; + clang::ParmVarDecl *param_var_decl = + m_ast.CreateParameterDeclaration( + name, type->GetForwardCompilerType(), storage); + assert(param_var_decl); + function_param_decls.push_back(param_var_decl); + + m_ast.SetMetadataAsUserID(param_var_decl, die.GetID()); + } } + } + arg_idx++; + } break; + + case DW_TAG_unspecified_parameters: + is_variadic = true; + break; + + case DW_TAG_template_type_parameter: + case DW_TAG_template_value_parameter: + // The one caller of this was never using the template_param_infos, + // and the local variable was taking up a large amount of stack space + // in SymbolFileDWARF::ParseType() so this was removed. If we ever need + // the template params back, we can add them back. + // ParseTemplateDIE (dwarf_cu, die, template_param_infos); + has_template_params = true; + break; + + default: + break; } - return arg_idx; + } + 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) -{ - 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; - uint64_t lower_bound = 0; - uint64_t upper_bound = 0; - bool upper_bound_valid = false; - 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_name: - break; - - case DW_AT_count: - num_elements = form_value.Unsigned(); - break; - - case DW_AT_bit_stride: - bit_stride = form_value.Unsigned(); - break; - - case DW_AT_byte_stride: - byte_stride = form_value.Unsigned(); - break; - - case DW_AT_lower_bound: - lower_bound = form_value.Unsigned(); - break; - - case DW_AT_upper_bound: - upper_bound_valid = true; - upper_bound = form_value.Unsigned(); - break; - - default: - case DW_AT_abstract_origin: - case DW_AT_accessibility: - case DW_AT_allocated: - case DW_AT_associated: - case DW_AT_data_location: - case DW_AT_declaration: - case DW_AT_description: - case DW_AT_sibling: - case DW_AT_threads_scaled: - case DW_AT_type: - case DW_AT_visibility: - break; - } - } - } +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) { + if (!parent_die) + return; - if (num_elements == 0) - { - if (upper_bound_valid && upper_bound >= lower_bound) - num_elements = upper_bound - lower_bound + 1; - } + 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; + uint64_t lower_bound = 0; + uint64_t upper_bound = 0; + bool upper_bound_valid = false; + 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_name: + break; + + case DW_AT_count: + num_elements = form_value.Unsigned(); + break; + + case DW_AT_bit_stride: + bit_stride = form_value.Unsigned(); + break; + + case DW_AT_byte_stride: + byte_stride = form_value.Unsigned(); + break; + + case DW_AT_lower_bound: + lower_bound = form_value.Unsigned(); + break; + + case DW_AT_upper_bound: + upper_bound_valid = true; + upper_bound = form_value.Unsigned(); + break; - element_orders.push_back (num_elements); - } + default: + case DW_AT_abstract_origin: + case DW_AT_accessibility: + case DW_AT_allocated: + case DW_AT_associated: + case DW_AT_data_location: + case DW_AT_declaration: + case DW_AT_description: + case DW_AT_sibling: + case DW_AT_threads_scaled: + case DW_AT_type: + case DW_AT_visibility: + break; } - break; + } } - } -} - -Type * -DWARFASTParserClang::GetTypeForDIE (const DWARFDIE &die) -{ - if (die) - { - SymbolFileDWARF *dwarf = die.GetDWARF(); - DWARFAttributes attributes; - const size_t num_attributes = die.GetAttributes(attributes); - if (num_attributes > 0) - { - DWARFFormValue type_die_form; - for (size_t i = 0; i < num_attributes; ++i) - { - dw_attr_t attr = attributes.AttributeAtIndex(i); - DWARFFormValue form_value; - if (attr == DW_AT_type && attributes.ExtractFormValueAtIndex(i, form_value)) - return dwarf->ResolveTypeUID(dwarf->GetDIE (DIERef(form_value)), true); - } + if (num_elements == 0) { + if (upper_bound_valid && upper_bound >= lower_bound) + num_elements = upper_bound - lower_bound + 1; } - } - return nullptr; + element_orders.push_back(num_elements); + } + } break; + } + } } -clang::Decl * -DWARFASTParserClang::GetClangDeclForDIE (const DWARFDIE &die) -{ - if (!die) - return nullptr; - - switch (die.Tag()) - { - case DW_TAG_variable: - case DW_TAG_constant: - case DW_TAG_formal_parameter: - case DW_TAG_imported_declaration: - case DW_TAG_imported_module: - break; - default: - return nullptr; +Type *DWARFASTParserClang::GetTypeForDIE(const DWARFDIE &die) { + if (die) { + SymbolFileDWARF *dwarf = die.GetDWARF(); + DWARFAttributes attributes; + const size_t num_attributes = die.GetAttributes(attributes); + if (num_attributes > 0) { + DWARFFormValue type_die_form; + for (size_t i = 0; i < num_attributes; ++i) { + dw_attr_t attr = attributes.AttributeAtIndex(i); + DWARFFormValue form_value; + + if (attr == DW_AT_type && + attributes.ExtractFormValueAtIndex(i, form_value)) + return dwarf->ResolveTypeUID(dwarf->GetDIE(DIERef(form_value)), true); + } } + } - DIEToDeclMap::iterator cache_pos = m_die_to_decl.find(die.GetDIE()); - if (cache_pos != m_die_to_decl.end()) - return cache_pos->second; + return nullptr; +} - if (DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification)) - { - clang::Decl *decl = GetClangDeclForDIE(spec_die); - m_die_to_decl[die.GetDIE()] = decl; - m_decl_to_die[decl].insert(die.GetDIE()); - return decl; - } - - if (DWARFDIE abstract_origin_die = die.GetReferencedDIE(DW_AT_abstract_origin)) - { - clang::Decl *decl = GetClangDeclForDIE(abstract_origin_die); - m_die_to_decl[die.GetDIE()] = decl; - m_decl_to_die[decl].insert(die.GetDIE()); - return decl; - } +clang::Decl *DWARFASTParserClang::GetClangDeclForDIE(const DWARFDIE &die) { + if (!die) + return nullptr; - clang::Decl *decl = nullptr; - switch (die.Tag()) - { - case DW_TAG_variable: - case DW_TAG_constant: - case DW_TAG_formal_parameter: - { - SymbolFileDWARF *dwarf = die.GetDWARF(); - Type *type = GetTypeForDIE(die); - if (dwarf && type) - { - const char *name = die.GetName(); - clang::DeclContext *decl_context = - ClangASTContext::DeclContextGetAsDeclContext(dwarf->GetDeclContextContainingUID(die.GetID())); - decl = m_ast.CreateVariableDeclaration(decl_context, name, - ClangUtil::GetQualType(type->GetForwardCompilerType())); - } - break; - } - case DW_TAG_imported_declaration: - { - SymbolFileDWARF *dwarf = die.GetDWARF(); - DWARFDIE imported_uid = die.GetAttributeValueAsReferenceDIE(DW_AT_import); - if (imported_uid) - { - CompilerDecl imported_decl = imported_uid.GetDecl(); - if (imported_decl) - { - clang::DeclContext *decl_context = ClangASTContext::DeclContextGetAsDeclContext(dwarf->GetDeclContextContainingUID(die.GetID())); - if (clang::NamedDecl *clang_imported_decl = llvm::dyn_cast<clang::NamedDecl>((clang::Decl *)imported_decl.GetOpaqueDecl())) - decl = m_ast.CreateUsingDeclaration(decl_context, clang_imported_decl); - } - } - break; - } - case DW_TAG_imported_module: - { - SymbolFileDWARF *dwarf = die.GetDWARF(); - DWARFDIE imported_uid = die.GetAttributeValueAsReferenceDIE(DW_AT_import); + switch (die.Tag()) { + case DW_TAG_variable: + case DW_TAG_constant: + case DW_TAG_formal_parameter: + case DW_TAG_imported_declaration: + case DW_TAG_imported_module: + break; + default: + return nullptr; + } - if (imported_uid) - { - CompilerDeclContext imported_decl_ctx = imported_uid.GetDeclContext(); - if (imported_decl_ctx) - { - clang::DeclContext *decl_context = ClangASTContext::DeclContextGetAsDeclContext(dwarf->GetDeclContextContainingUID(die.GetID())); - if (clang::NamespaceDecl *ns_decl = ClangASTContext::DeclContextGetAsNamespaceDecl(imported_decl_ctx)) - decl = m_ast.CreateUsingDirectiveDeclaration(decl_context, ns_decl); - } - } - break; - } - default: - break; - } + DIEToDeclMap::iterator cache_pos = m_die_to_decl.find(die.GetDIE()); + if (cache_pos != m_die_to_decl.end()) + return cache_pos->second; + if (DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification)) { + clang::Decl *decl = GetClangDeclForDIE(spec_die); m_die_to_decl[die.GetDIE()] = decl; m_decl_to_die[decl].insert(die.GetDIE()); + return decl; + } + if (DWARFDIE abstract_origin_die = + die.GetReferencedDIE(DW_AT_abstract_origin)) { + clang::Decl *decl = GetClangDeclForDIE(abstract_origin_die); + m_die_to_decl[die.GetDIE()] = decl; + m_decl_to_die[decl].insert(die.GetDIE()); return decl; -} + } -clang::DeclContext * -DWARFASTParserClang::GetClangDeclContextForDIE (const DWARFDIE &die) -{ - if (die) - { - clang::DeclContext *decl_ctx = GetCachedClangDeclContextForDIE (die); - if (decl_ctx) - return decl_ctx; - - bool try_parsing_type = true; - switch (die.Tag()) - { - case DW_TAG_compile_unit: - decl_ctx = m_ast.GetTranslationUnitDecl(); - try_parsing_type = false; - break; + clang::Decl *decl = nullptr; + switch (die.Tag()) { + case DW_TAG_variable: + case DW_TAG_constant: + case DW_TAG_formal_parameter: { + SymbolFileDWARF *dwarf = die.GetDWARF(); + Type *type = GetTypeForDIE(die); + if (dwarf && type) { + const char *name = die.GetName(); + clang::DeclContext *decl_context = + ClangASTContext::DeclContextGetAsDeclContext( + dwarf->GetDeclContextContainingUID(die.GetID())); + decl = m_ast.CreateVariableDeclaration( + decl_context, name, + ClangUtil::GetQualType(type->GetForwardCompilerType())); + } + break; + } + case DW_TAG_imported_declaration: { + SymbolFileDWARF *dwarf = die.GetDWARF(); + DWARFDIE imported_uid = die.GetAttributeValueAsReferenceDIE(DW_AT_import); + if (imported_uid) { + CompilerDecl imported_decl = imported_uid.GetDecl(); + if (imported_decl) { + clang::DeclContext *decl_context = + ClangASTContext::DeclContextGetAsDeclContext( + dwarf->GetDeclContextContainingUID(die.GetID())); + if (clang::NamedDecl *clang_imported_decl = + llvm::dyn_cast<clang::NamedDecl>( + (clang::Decl *)imported_decl.GetOpaqueDecl())) + decl = + m_ast.CreateUsingDeclaration(decl_context, clang_imported_decl); + } + } + break; + } + case DW_TAG_imported_module: { + SymbolFileDWARF *dwarf = die.GetDWARF(); + DWARFDIE imported_uid = die.GetAttributeValueAsReferenceDIE(DW_AT_import); + + if (imported_uid) { + CompilerDeclContext imported_decl_ctx = imported_uid.GetDeclContext(); + if (imported_decl_ctx) { + clang::DeclContext *decl_context = + ClangASTContext::DeclContextGetAsDeclContext( + dwarf->GetDeclContextContainingUID(die.GetID())); + if (clang::NamespaceDecl *ns_decl = + ClangASTContext::DeclContextGetAsNamespaceDecl( + imported_decl_ctx)) + decl = m_ast.CreateUsingDirectiveDeclaration(decl_context, ns_decl); + } + } + break; + } + default: + break; + } - case DW_TAG_namespace: - decl_ctx = ResolveNamespaceDIE (die); - try_parsing_type = false; - break; + m_die_to_decl[die.GetDIE()] = decl; + m_decl_to_die[decl].insert(die.GetDIE()); - case DW_TAG_lexical_block: - decl_ctx = (clang::DeclContext *)ResolveBlockDIE(die); - try_parsing_type = false; - break; + return decl; +} - default: - break; - } +clang::DeclContext * +DWARFASTParserClang::GetClangDeclContextForDIE(const DWARFDIE &die) { + if (die) { + clang::DeclContext *decl_ctx = GetCachedClangDeclContextForDIE(die); + if (decl_ctx) + return decl_ctx; + + bool try_parsing_type = true; + switch (die.Tag()) { + case DW_TAG_compile_unit: + decl_ctx = m_ast.GetTranslationUnitDecl(); + try_parsing_type = false; + break; + + case DW_TAG_namespace: + decl_ctx = ResolveNamespaceDIE(die); + try_parsing_type = false; + break; + + case DW_TAG_lexical_block: + decl_ctx = (clang::DeclContext *)ResolveBlockDIE(die); + try_parsing_type = false; + break; + + default: + break; + } - if (decl_ctx == nullptr && try_parsing_type) - { - Type* type = die.GetDWARF()->ResolveType (die); - if (type) - decl_ctx = GetCachedClangDeclContextForDIE (die); - } + if (decl_ctx == nullptr && try_parsing_type) { + Type *type = die.GetDWARF()->ResolveType(die); + if (type) + decl_ctx = GetCachedClangDeclContextForDIE(die); + } - if (decl_ctx) - { - LinkDeclContextToDIE (decl_ctx, die); - return decl_ctx; - } + if (decl_ctx) { + LinkDeclContextToDIE(decl_ctx, die); + return decl_ctx; } - return nullptr; + } + return nullptr; } -clang::BlockDecl * -DWARFASTParserClang::ResolveBlockDIE (const DWARFDIE &die) -{ - if (die && die.Tag() == DW_TAG_lexical_block) - { - clang::BlockDecl *decl = llvm::cast_or_null<clang::BlockDecl>(m_die_to_decl_ctx[die.GetDIE()]); - - if (!decl) - { - DWARFDIE decl_context_die; - clang::DeclContext *decl_context = GetClangDeclContextContainingDIE(die, &decl_context_die); - decl = m_ast.CreateBlockDeclaration(decl_context); +clang::BlockDecl *DWARFASTParserClang::ResolveBlockDIE(const DWARFDIE &die) { + if (die && die.Tag() == DW_TAG_lexical_block) { + clang::BlockDecl *decl = + llvm::cast_or_null<clang::BlockDecl>(m_die_to_decl_ctx[die.GetDIE()]); - if (decl) - LinkDeclContextToDIE((clang::DeclContext *)decl, die); - } + if (!decl) { + DWARFDIE decl_context_die; + clang::DeclContext *decl_context = + GetClangDeclContextContainingDIE(die, &decl_context_die); + decl = m_ast.CreateBlockDeclaration(decl_context); - return decl; + if (decl) + LinkDeclContextToDIE((clang::DeclContext *)decl, die); } - return nullptr; + + return decl; + } + return nullptr; } clang::NamespaceDecl * -DWARFASTParserClang::ResolveNamespaceDIE (const DWARFDIE &die) -{ - if (die && die.Tag() == DW_TAG_namespace) - { - // See if we already parsed this namespace DIE and associated it with a - // uniqued namespace declaration - clang::NamespaceDecl *namespace_decl = static_cast<clang::NamespaceDecl *>(m_die_to_decl_ctx[die.GetDIE()]); - if (namespace_decl) - return namespace_decl; - else - { - const char *namespace_name = die.GetName(); - clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (die, nullptr); - namespace_decl = m_ast.GetUniqueNamespaceDeclaration (namespace_name, containing_decl_ctx); - Log *log = nullptr;// (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO)); - if (log) - { - SymbolFileDWARF *dwarf = die.GetDWARF(); - if (namespace_name) - { - dwarf->GetObjectFile()->GetModule()->LogMessage (log, - "ASTContext => %p: 0x%8.8" PRIx64 ": DW_TAG_namespace with DW_AT_name(\"%s\") => clang::NamespaceDecl *%p (original = %p)", - static_cast<void*>(m_ast.getASTContext()), - die.GetID(), - namespace_name, - static_cast<void*>(namespace_decl), - static_cast<void*>(namespace_decl->getOriginalNamespace())); - } - else - { - dwarf->GetObjectFile()->GetModule()->LogMessage (log, - "ASTContext => %p: 0x%8.8" PRIx64 ": DW_TAG_namespace (anonymous) => clang::NamespaceDecl *%p (original = %p)", - static_cast<void*>(m_ast.getASTContext()), - die.GetID(), - static_cast<void*>(namespace_decl), - static_cast<void*>(namespace_decl->getOriginalNamespace())); - } - } - - if (namespace_decl) - LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die); - return namespace_decl; +DWARFASTParserClang::ResolveNamespaceDIE(const DWARFDIE &die) { + if (die && die.Tag() == DW_TAG_namespace) { + // See if we already parsed this namespace DIE and associated it with a + // uniqued namespace declaration + clang::NamespaceDecl *namespace_decl = + static_cast<clang::NamespaceDecl *>(m_die_to_decl_ctx[die.GetDIE()]); + if (namespace_decl) + return namespace_decl; + else { + const char *namespace_name = die.GetName(); + clang::DeclContext *containing_decl_ctx = + GetClangDeclContextContainingDIE(die, nullptr); + namespace_decl = m_ast.GetUniqueNamespaceDeclaration(namespace_name, + containing_decl_ctx); + Log *log = + nullptr; // (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO)); + if (log) { + SymbolFileDWARF *dwarf = die.GetDWARF(); + if (namespace_name) { + dwarf->GetObjectFile()->GetModule()->LogMessage( + log, "ASTContext => %p: 0x%8.8" PRIx64 + ": DW_TAG_namespace with DW_AT_name(\"%s\") => " + "clang::NamespaceDecl *%p (original = %p)", + static_cast<void *>(m_ast.getASTContext()), die.GetID(), + namespace_name, static_cast<void *>(namespace_decl), + static_cast<void *>(namespace_decl->getOriginalNamespace())); + } else { + dwarf->GetObjectFile()->GetModule()->LogMessage( + log, "ASTContext => %p: 0x%8.8" PRIx64 + ": DW_TAG_namespace (anonymous) => clang::NamespaceDecl *%p " + "(original = %p)", + static_cast<void *>(m_ast.getASTContext()), die.GetID(), + static_cast<void *>(namespace_decl), + static_cast<void *>(namespace_decl->getOriginalNamespace())); } + } + + if (namespace_decl) + LinkDeclContextToDIE((clang::DeclContext *)namespace_decl, die); + return namespace_decl; } - return nullptr; + } + return nullptr; } -clang::DeclContext * -DWARFASTParserClang::GetClangDeclContextContainingDIE (const DWARFDIE &die, - DWARFDIE *decl_ctx_die_copy) -{ - SymbolFileDWARF *dwarf = die.GetDWARF(); +clang::DeclContext *DWARFASTParserClang::GetClangDeclContextContainingDIE( + const DWARFDIE &die, DWARFDIE *decl_ctx_die_copy) { + SymbolFileDWARF *dwarf = die.GetDWARF(); - DWARFDIE decl_ctx_die = dwarf->GetDeclContextDIEContainingDIE (die); + DWARFDIE decl_ctx_die = dwarf->GetDeclContextDIEContainingDIE(die); - if (decl_ctx_die_copy) - *decl_ctx_die_copy = decl_ctx_die; + if (decl_ctx_die_copy) + *decl_ctx_die_copy = decl_ctx_die; - if (decl_ctx_die) - { - clang::DeclContext *clang_decl_ctx = GetClangDeclContextForDIE (decl_ctx_die); - if (clang_decl_ctx) - return clang_decl_ctx; - } - return m_ast.GetTranslationUnitDecl(); + if (decl_ctx_die) { + clang::DeclContext *clang_decl_ctx = + GetClangDeclContextForDIE(decl_ctx_die); + if (clang_decl_ctx) + return clang_decl_ctx; + } + return m_ast.GetTranslationUnitDecl(); } clang::DeclContext * -DWARFASTParserClang::GetCachedClangDeclContextForDIE (const DWARFDIE &die) -{ - if (die) - { - DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die.GetDIE()); - if (pos != m_die_to_decl_ctx.end()) - return pos->second; - } - return nullptr; +DWARFASTParserClang::GetCachedClangDeclContextForDIE(const DWARFDIE &die) { + if (die) { + DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die.GetDIE()); + if (pos != m_die_to_decl_ctx.end()) + return pos->second; + } + return nullptr; } -void -DWARFASTParserClang::LinkDeclContextToDIE (clang::DeclContext *decl_ctx, const DWARFDIE &die) -{ - m_die_to_decl_ctx[die.GetDIE()] = decl_ctx; - // There can be many DIEs for a single decl context - //m_decl_ctx_to_die[decl_ctx].insert(die.GetDIE()); - m_decl_ctx_to_die.insert(std::make_pair(decl_ctx, die)); +void DWARFASTParserClang::LinkDeclContextToDIE(clang::DeclContext *decl_ctx, + const DWARFDIE &die) { + m_die_to_decl_ctx[die.GetDIE()] = decl_ctx; + // There can be many DIEs for a single decl context + // m_decl_ctx_to_die[decl_ctx].insert(die.GetDIE()); + m_decl_ctx_to_die.insert(std::make_pair(decl_ctx, die)); } -bool -DWARFASTParserClang::CopyUniqueClassMethodTypes (const DWARFDIE &src_class_die, - const DWARFDIE &dst_class_die, - lldb_private::Type *class_type, - DWARFDIECollection &failures) -{ - if (!class_type || !src_class_die || !dst_class_die) - return false; - if (src_class_die.Tag() != dst_class_die.Tag()) - return false; +bool DWARFASTParserClang::CopyUniqueClassMethodTypes( + const DWARFDIE &src_class_die, const DWARFDIE &dst_class_die, + lldb_private::Type *class_type, DWARFDIECollection &failures) { + if (!class_type || !src_class_die || !dst_class_die) + return false; + if (src_class_die.Tag() != dst_class_die.Tag()) + return false; - // We need to complete the class type so we can get all of the method types - // parsed so we can then unique those types to their equivalent counterparts - // in "dst_cu" and "dst_class_die" - class_type->GetFullCompilerType (); - - DWARFDIE src_die; - DWARFDIE dst_die; - UniqueCStringMap<DWARFDIE> src_name_to_die; - UniqueCStringMap<DWARFDIE> dst_name_to_die; - UniqueCStringMap<DWARFDIE> src_name_to_die_artificial; - UniqueCStringMap<DWARFDIE> dst_name_to_die_artificial; - for (src_die = src_class_die.GetFirstChild(); src_die.IsValid(); src_die = src_die.GetSibling()) - { - if (src_die.Tag() == DW_TAG_subprogram) - { - // Make sure this is a declaration and not a concrete instance by looking - // for DW_AT_declaration set to 1. Sometimes concrete function instances - // are placed inside the class definitions and shouldn't be included in - // the list of things are are tracking here. - if (src_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 1) - { - const char *src_name = src_die.GetMangledName (); - if (src_name) - { - ConstString src_const_name(src_name); - if (src_die.GetAttributeValueAsUnsigned(DW_AT_artificial, 0)) - src_name_to_die_artificial.Append(src_const_name.GetCString(), src_die); - else - src_name_to_die.Append(src_const_name.GetCString(), src_die); - } - } + // We need to complete the class type so we can get all of the method types + // parsed so we can then unique those types to their equivalent counterparts + // in "dst_cu" and "dst_class_die" + class_type->GetFullCompilerType(); + + DWARFDIE src_die; + DWARFDIE dst_die; + UniqueCStringMap<DWARFDIE> src_name_to_die; + UniqueCStringMap<DWARFDIE> dst_name_to_die; + UniqueCStringMap<DWARFDIE> src_name_to_die_artificial; + UniqueCStringMap<DWARFDIE> dst_name_to_die_artificial; + for (src_die = src_class_die.GetFirstChild(); src_die.IsValid(); + src_die = src_die.GetSibling()) { + if (src_die.Tag() == DW_TAG_subprogram) { + // Make sure this is a declaration and not a concrete instance by looking + // for DW_AT_declaration set to 1. Sometimes concrete function instances + // are placed inside the class definitions and shouldn't be included in + // the list of things are are tracking here. + if (src_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 1) { + const char *src_name = src_die.GetMangledName(); + if (src_name) { + ConstString src_const_name(src_name); + if (src_die.GetAttributeValueAsUnsigned(DW_AT_artificial, 0)) + src_name_to_die_artificial.Append(src_const_name.GetStringRef(), + src_die); + else + src_name_to_die.Append(src_const_name.GetStringRef(), src_die); } + } } - for (dst_die = dst_class_die.GetFirstChild(); dst_die.IsValid(); dst_die = dst_die.GetSibling()) - { - if (dst_die.Tag() == DW_TAG_subprogram) - { - // Make sure this is a declaration and not a concrete instance by looking - // for DW_AT_declaration set to 1. Sometimes concrete function instances - // are placed inside the class definitions and shouldn't be included in - // the list of things are are tracking here. - if (dst_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 1) - { - const char *dst_name = dst_die.GetMangledName (); - if (dst_name) - { - ConstString dst_const_name(dst_name); - if ( dst_die.GetAttributeValueAsUnsigned(DW_AT_artificial, 0)) - dst_name_to_die_artificial.Append(dst_const_name.GetCString(), dst_die); - else - dst_name_to_die.Append(dst_const_name.GetCString(), dst_die); - } - } + } + for (dst_die = dst_class_die.GetFirstChild(); dst_die.IsValid(); + dst_die = dst_die.GetSibling()) { + if (dst_die.Tag() == DW_TAG_subprogram) { + // Make sure this is a declaration and not a concrete instance by looking + // for DW_AT_declaration set to 1. Sometimes concrete function instances + // are placed inside the class definitions and shouldn't be included in + // the list of things are are tracking here. + if (dst_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 1) { + const char *dst_name = dst_die.GetMangledName(); + if (dst_name) { + ConstString dst_const_name(dst_name); + if (dst_die.GetAttributeValueAsUnsigned(DW_AT_artificial, 0)) + dst_name_to_die_artificial.Append(dst_const_name.GetStringRef(), + dst_die); + else + dst_name_to_die.Append(dst_const_name.GetStringRef(), dst_die); } + } } - const uint32_t src_size = src_name_to_die.GetSize (); - const uint32_t dst_size = dst_name_to_die.GetSize (); - Log *log = nullptr; // (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO | DWARF_LOG_TYPE_COMPLETION)); - - // Is everything kosher so we can go through the members at top speed? - bool fast_path = true; - - if (src_size != dst_size) - { - if (src_size != 0 && dst_size != 0) - { - if (log) - log->Printf("warning: trying to unique class DIE 0x%8.8x to 0x%8.8x, but they didn't have the same size (src=%d, dst=%d)", - src_class_die.GetOffset(), - dst_class_die.GetOffset(), - src_size, - dst_size); - } - - fast_path = false; + } + const uint32_t src_size = src_name_to_die.GetSize(); + const uint32_t dst_size = dst_name_to_die.GetSize(); + Log *log = nullptr; // (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO | + // DWARF_LOG_TYPE_COMPLETION)); + + // Is everything kosher so we can go through the members at top speed? + bool fast_path = true; + + if (src_size != dst_size) { + if (src_size != 0 && dst_size != 0) { + if (log) + log->Printf("warning: trying to unique class DIE 0x%8.8x to 0x%8.8x, " + "but they didn't have the same size (src=%d, dst=%d)", + src_class_die.GetOffset(), dst_class_die.GetOffset(), + src_size, dst_size); } - uint32_t idx; + fast_path = false; + } - if (fast_path) - { - for (idx = 0; idx < src_size; ++idx) - { - src_die = src_name_to_die.GetValueAtIndexUnchecked (idx); - dst_die = dst_name_to_die.GetValueAtIndexUnchecked (idx); + uint32_t idx; - if (src_die.Tag() != dst_die.Tag()) - { - if (log) - log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, but 0x%8.8x (%s) tags didn't match 0x%8.8x (%s)", - src_class_die.GetOffset(), - dst_class_die.GetOffset(), - src_die.GetOffset(), - src_die.GetTagAsCString(), - dst_die.GetOffset(), - dst_die.GetTagAsCString()); - fast_path = false; - } + if (fast_path) { + for (idx = 0; idx < src_size; ++idx) { + src_die = src_name_to_die.GetValueAtIndexUnchecked(idx); + dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx); - const char *src_name = src_die.GetMangledName (); - const char *dst_name = dst_die.GetMangledName (); + if (src_die.Tag() != dst_die.Tag()) { + if (log) + log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, " + "but 0x%8.8x (%s) tags didn't match 0x%8.8x (%s)", + src_class_die.GetOffset(), dst_class_die.GetOffset(), + src_die.GetOffset(), src_die.GetTagAsCString(), + dst_die.GetOffset(), dst_die.GetTagAsCString()); + fast_path = false; + } - // Make sure the names match - if (src_name == dst_name || (strcmp (src_name, dst_name) == 0)) - continue; + const char *src_name = src_die.GetMangledName(); + const char *dst_name = dst_die.GetMangledName(); - if (log) - log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, but 0x%8.8x (%s) names didn't match 0x%8.8x (%s)", - src_class_die.GetOffset(), - dst_class_die.GetOffset(), - src_die.GetOffset(), - src_name, - dst_die.GetOffset(), - dst_name); - - fast_path = false; - } - } + // Make sure the names match + if (src_name == dst_name || (strcmp(src_name, dst_name) == 0)) + continue; - DWARFASTParserClang *src_dwarf_ast_parser = (DWARFASTParserClang *)src_die.GetDWARFParser(); - DWARFASTParserClang *dst_dwarf_ast_parser = (DWARFASTParserClang *)dst_die.GetDWARFParser(); + if (log) + log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, " + "but 0x%8.8x (%s) names didn't match 0x%8.8x (%s)", + src_class_die.GetOffset(), dst_class_die.GetOffset(), + src_die.GetOffset(), src_name, dst_die.GetOffset(), + dst_name); - // Now do the work of linking the DeclContexts and Types. - if (fast_path) - { - // We can do this quickly. Just run across the tables index-for-index since - // we know each node has matching names and tags. - for (idx = 0; idx < src_size; ++idx) - { - src_die = src_name_to_die.GetValueAtIndexUnchecked (idx); - dst_die = dst_name_to_die.GetValueAtIndexUnchecked (idx); - - clang::DeclContext *src_decl_ctx = src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()]; - if (src_decl_ctx) - { - if (log) - log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x", - static_cast<void*>(src_decl_ctx), - src_die.GetOffset(), dst_die.GetOffset()); - dst_dwarf_ast_parser->LinkDeclContextToDIE (src_decl_ctx, dst_die); - } - else - { - if (log) - log->Printf ("warning: tried to unique decl context from 0x%8.8x for 0x%8.8x, but none was found", - src_die.GetOffset(), dst_die.GetOffset()); - } - - Type *src_child_type = dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()]; - if (src_child_type) - { - if (log) - log->Printf ("uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x", - static_cast<void*>(src_child_type), - src_child_type->GetID(), - src_die.GetOffset(), dst_die.GetOffset()); - dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type; - } - else - { - if (log) - log->Printf ("warning: tried to unique lldb_private::Type from 0x%8.8x for 0x%8.8x, but none was found", src_die.GetOffset(), dst_die.GetOffset()); - } - } + fast_path = false; } - else - { - // We must do this slowly. For each member of the destination, look - // up a member in the source with the same name, check its tag, and - // unique them if everything matches up. Report failures. - - if (!src_name_to_die.IsEmpty() && !dst_name_to_die.IsEmpty()) - { - src_name_to_die.Sort(); - - for (idx = 0; idx < dst_size; ++idx) - { - const char *dst_name = dst_name_to_die.GetCStringAtIndex(idx); - dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx); - src_die = src_name_to_die.Find(dst_name, DWARFDIE()); - - if (src_die && (src_die.Tag() == dst_die.Tag())) - { - clang::DeclContext *src_decl_ctx = src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()]; - if (src_decl_ctx) - { - if (log) - log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x", - static_cast<void*>(src_decl_ctx), - src_die.GetOffset(), - dst_die.GetOffset()); - dst_dwarf_ast_parser->LinkDeclContextToDIE (src_decl_ctx, dst_die); - } - else - { - if (log) - log->Printf ("warning: tried to unique decl context from 0x%8.8x for 0x%8.8x, but none was found", src_die.GetOffset(), dst_die.GetOffset()); - } - - Type *src_child_type = dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()]; - if (src_child_type) - { - if (log) - log->Printf ("uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x", - static_cast<void*>(src_child_type), - src_child_type->GetID(), - src_die.GetOffset(), - dst_die.GetOffset()); - dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type; - } - else - { - if (log) - log->Printf ("warning: tried to unique lldb_private::Type from 0x%8.8x for 0x%8.8x, but none was found", src_die.GetOffset(), dst_die.GetOffset()); - } - } - else - { - if (log) - log->Printf ("warning: couldn't find a match for 0x%8.8x", dst_die.GetOffset()); - - failures.Append(dst_die); - } - } - } + } + + DWARFASTParserClang *src_dwarf_ast_parser = + (DWARFASTParserClang *)src_die.GetDWARFParser(); + DWARFASTParserClang *dst_dwarf_ast_parser = + (DWARFASTParserClang *)dst_die.GetDWARFParser(); + + // Now do the work of linking the DeclContexts and Types. + if (fast_path) { + // We can do this quickly. Just run across the tables index-for-index since + // we know each node has matching names and tags. + for (idx = 0; idx < src_size; ++idx) { + src_die = src_name_to_die.GetValueAtIndexUnchecked(idx); + dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx); + + clang::DeclContext *src_decl_ctx = + src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()]; + if (src_decl_ctx) { + if (log) + log->Printf("uniquing decl context %p from 0x%8.8x for 0x%8.8x", + static_cast<void *>(src_decl_ctx), src_die.GetOffset(), + dst_die.GetOffset()); + dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, dst_die); + } else { + if (log) + log->Printf("warning: tried to unique decl context from 0x%8.8x for " + "0x%8.8x, but none was found", + src_die.GetOffset(), dst_die.GetOffset()); + } + + Type *src_child_type = + dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()]; + if (src_child_type) { + if (log) + log->Printf( + "uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x", + static_cast<void *>(src_child_type), src_child_type->GetID(), + src_die.GetOffset(), dst_die.GetOffset()); + dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type; + } else { + if (log) + log->Printf("warning: tried to unique lldb_private::Type from " + "0x%8.8x for 0x%8.8x, but none was found", + src_die.GetOffset(), dst_die.GetOffset()); + } } - - const uint32_t src_size_artificial = src_name_to_die_artificial.GetSize (); - const uint32_t dst_size_artificial = dst_name_to_die_artificial.GetSize (); - - if (src_size_artificial && dst_size_artificial) - { - dst_name_to_die_artificial.Sort(); - - for (idx = 0; idx < src_size_artificial; ++idx) - { - const char *src_name_artificial = src_name_to_die_artificial.GetCStringAtIndex(idx); - src_die = src_name_to_die_artificial.GetValueAtIndexUnchecked (idx); - dst_die = dst_name_to_die_artificial.Find(src_name_artificial, DWARFDIE()); - - if (dst_die) - { - // Both classes have the artificial types, link them - clang::DeclContext *src_decl_ctx = src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()]; - if (src_decl_ctx) - { - if (log) - log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x", - static_cast<void*>(src_decl_ctx), - src_die.GetOffset(), dst_die.GetOffset()); - dst_dwarf_ast_parser->LinkDeclContextToDIE (src_decl_ctx, dst_die); - } - else - { - if (log) - log->Printf ("warning: tried to unique decl context from 0x%8.8x for 0x%8.8x, but none was found", src_die.GetOffset(), dst_die.GetOffset()); - } - - Type *src_child_type = dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()]; - if (src_child_type) - { - if (log) - log->Printf ("uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x", - static_cast<void*>(src_child_type), - src_child_type->GetID(), - src_die.GetOffset(), dst_die.GetOffset()); - dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type; - } - else - { - if (log) - log->Printf ("warning: tried to unique lldb_private::Type from 0x%8.8x for 0x%8.8x, but none was found", src_die.GetOffset(), dst_die.GetOffset()); - } - } + } else { + // We must do this slowly. For each member of the destination, look + // up a member in the source with the same name, check its tag, and + // unique them if everything matches up. Report failures. + + if (!src_name_to_die.IsEmpty() && !dst_name_to_die.IsEmpty()) { + src_name_to_die.Sort(); + + for (idx = 0; idx < dst_size; ++idx) { + llvm::StringRef dst_name = dst_name_to_die.GetCStringAtIndex(idx); + dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx); + src_die = src_name_to_die.Find(dst_name, DWARFDIE()); + + if (src_die && (src_die.Tag() == dst_die.Tag())) { + clang::DeclContext *src_decl_ctx = + src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()]; + if (src_decl_ctx) { + if (log) + log->Printf("uniquing decl context %p from 0x%8.8x for 0x%8.8x", + static_cast<void *>(src_decl_ctx), + src_die.GetOffset(), dst_die.GetOffset()); + dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, dst_die); + } else { + if (log) + log->Printf("warning: tried to unique decl context from 0x%8.8x " + "for 0x%8.8x, but none was found", + src_die.GetOffset(), dst_die.GetOffset()); + } + + Type *src_child_type = + dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()]; + if (src_child_type) { + if (log) + log->Printf("uniquing type %p (uid=0x%" PRIx64 + ") from 0x%8.8x for 0x%8.8x", + static_cast<void *>(src_child_type), + src_child_type->GetID(), src_die.GetOffset(), + dst_die.GetOffset()); + dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = + src_child_type; + } else { + if (log) + log->Printf("warning: tried to unique lldb_private::Type from " + "0x%8.8x for 0x%8.8x, but none was found", + src_die.GetOffset(), dst_die.GetOffset()); + } + } else { + if (log) + log->Printf("warning: couldn't find a match for 0x%8.8x", + dst_die.GetOffset()); + + failures.Append(dst_die); } + } } + } + + const uint32_t src_size_artificial = src_name_to_die_artificial.GetSize(); + const uint32_t dst_size_artificial = dst_name_to_die_artificial.GetSize(); + + if (src_size_artificial && dst_size_artificial) { + dst_name_to_die_artificial.Sort(); + + for (idx = 0; idx < src_size_artificial; ++idx) { + llvm::StringRef src_name_artificial = + src_name_to_die_artificial.GetCStringAtIndex(idx); + src_die = src_name_to_die_artificial.GetValueAtIndexUnchecked(idx); + dst_die = + dst_name_to_die_artificial.Find(src_name_artificial, DWARFDIE()); + + if (dst_die) { + // Both classes have the artificial types, link them + clang::DeclContext *src_decl_ctx = + src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()]; + if (src_decl_ctx) { + if (log) + log->Printf("uniquing decl context %p from 0x%8.8x for 0x%8.8x", + static_cast<void *>(src_decl_ctx), src_die.GetOffset(), + dst_die.GetOffset()); + dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, dst_die); + } else { + if (log) + log->Printf("warning: tried to unique decl context from 0x%8.8x " + "for 0x%8.8x, but none was found", + src_die.GetOffset(), dst_die.GetOffset()); + } - if (dst_size_artificial) - { - for (idx = 0; idx < dst_size_artificial; ++idx) - { - const char *dst_name_artificial = dst_name_to_die_artificial.GetCStringAtIndex(idx); - dst_die = dst_name_to_die_artificial.GetValueAtIndexUnchecked (idx); - if (log) - log->Printf ("warning: need to create artificial method for 0x%8.8x for method '%s'", dst_die.GetOffset(), dst_name_artificial); - - failures.Append(dst_die); + Type *src_child_type = + dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()]; + if (src_child_type) { + if (log) + log->Printf( + "uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x", + static_cast<void *>(src_child_type), src_child_type->GetID(), + src_die.GetOffset(), dst_die.GetOffset()); + dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type; + } else { + if (log) + log->Printf("warning: tried to unique lldb_private::Type from " + "0x%8.8x for 0x%8.8x, but none was found", + src_die.GetOffset(), dst_die.GetOffset()); } + } } + } + + if (dst_size_artificial) { + for (idx = 0; idx < dst_size_artificial; ++idx) { + llvm::StringRef dst_name_artificial = + dst_name_to_die_artificial.GetCStringAtIndex(idx); + dst_die = dst_name_to_die_artificial.GetValueAtIndexUnchecked(idx); + if (log) + log->Printf("warning: need to create artificial method for 0x%8.8x for " + "method '%s'", + dst_die.GetOffset(), dst_name_artificial.str().c_str()); + + failures.Append(dst_die); + } + } - return (failures.Size() != 0); + return (failures.Size() != 0); } - diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h index 0826423b0359..3d6d08eef9ed 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h @@ -13,10 +13,10 @@ // 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" -#include "clang/AST/CharUnits.h" // Project includes #include "DWARFASTParser.h" @@ -29,149 +29,131 @@ class DWARFDebugInfoEntry; class DWARFDIECollection; -class DWARFASTParserClang : public DWARFASTParser -{ +class DWARFASTParserClang : public DWARFASTParser { public: - DWARFASTParserClang (lldb_private::ClangASTContext &ast); - - ~DWARFASTParserClang() override; + DWARFASTParserClang(lldb_private::ClangASTContext &ast); - // DWARFASTParser interface. - lldb::TypeSP - ParseTypeFromDWARF (const lldb_private::SymbolContext& sc, - const DWARFDIE &die, - lldb_private::Log *log, - bool *type_is_new_ptr) override; + ~DWARFASTParserClang() override; + // DWARFASTParser interface. + 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; + 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; + bool + CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type, + lldb_private::CompilerType &compiler_type) override; - lldb_private::CompilerDecl - GetDeclForUIDFromDWARF (const DWARFDIE &die) override; + lldb_private::CompilerDecl + GetDeclForUIDFromDWARF(const DWARFDIE &die) override; - std::vector<DWARFDIE> - GetDIEForDeclContext (lldb_private::CompilerDeclContext decl_context) override; + std::vector<DWARFDIE> + GetDIEForDeclContext(lldb_private::CompilerDeclContext decl_context) override; - lldb_private::CompilerDeclContext - GetDeclContextForUIDFromDWARF (const DWARFDIE &die) override; + lldb_private::CompilerDeclContext + GetDeclContextForUIDFromDWARF(const DWARFDIE &die) override; - lldb_private::CompilerDeclContext - GetDeclContextContainingUIDFromDWARF (const DWARFDIE &die) override; + lldb_private::CompilerDeclContext + GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) override; - lldb_private::ClangASTImporter & - GetClangASTImporter(); + lldb_private::ClangASTImporter &GetClangASTImporter(); protected: - class DelayedAddObjCClassProperty; - typedef std::vector <DelayedAddObjCClassProperty> DelayedPropertyList; - - clang::BlockDecl * - ResolveBlockDIE (const DWARFDIE &die); - - clang::NamespaceDecl * - ResolveNamespaceDIE (const DWARFDIE &die); - - bool - ParseTemplateDIE (const DWARFDIE &die, - lldb_private::ClangASTContext::TemplateParameterInfos &template_param_infos); - bool - ParseTemplateParameterInfos (const DWARFDIE &parent_die, - 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); - - size_t - ParseChildParameters (const lldb_private::SymbolContext& sc, - clang::DeclContext *containing_decl_ctx, - const DWARFDIE &parent_die, - bool skip_artificial, - bool &is_static, - bool &is_variadic, - bool &has_template_params, - std::vector<lldb_private::CompilerType>& function_args, - 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, - const DWARFDIE &parent_die); - - lldb_private::Type * - GetTypeForDIE (const DWARFDIE &die); - - clang::Decl * - GetClangDeclForDIE (const DWARFDIE &die); - - clang::DeclContext * - GetClangDeclContextForDIE (const DWARFDIE &die); - - clang::DeclContext * - GetClangDeclContextContainingDIE (const DWARFDIE &die, - DWARFDIE *decl_ctx_die); - - bool - CopyUniqueClassMethodTypes (const DWARFDIE &src_class_die, - const DWARFDIE &dst_class_die, - lldb_private::Type *class_type, - DWARFDIECollection &failures); - - clang::DeclContext * - GetCachedClangDeclContextForDIE (const DWARFDIE &die); - - void - LinkDeclContextToDIE (clang::DeclContext *decl_ctx, - const DWARFDIE &die); - - void - LinkDeclToDIE (clang::Decl *decl, const DWARFDIE &die); - - lldb::TypeSP - ParseTypeFromDWO (const DWARFDIE &die, lldb_private::Log *log); - - //---------------------------------------------------------------------- - // Return true if this type is a declaration to a type in an external - // module. - //---------------------------------------------------------------------- - lldb::ModuleSP - GetModuleForType (const DWARFDIE &die); - - typedef llvm::SmallPtrSet<const DWARFDebugInfoEntry *, 4> DIEPointerSet; - typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::DeclContext *> DIEToDeclContextMap; - //typedef llvm::DenseMap<const clang::DeclContext *, DIEPointerSet> DeclContextToDIEMap; - typedef std::multimap<const clang::DeclContext *, const DWARFDIE> DeclContextToDIEMap; - typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::Decl *> DIEToDeclMap; - typedef llvm::DenseMap<const clang::Decl *, DIEPointerSet> DeclToDIEMap; - - lldb_private::ClangASTContext &m_ast; - DIEToDeclMap m_die_to_decl; - DeclToDIEMap m_decl_to_die; - DIEToDeclContextMap m_die_to_decl_ctx; - DeclContextToDIEMap m_decl_ctx_to_die; - std::unique_ptr<lldb_private::ClangASTImporter> m_clang_ast_importer_ap; + class DelayedAddObjCClassProperty; + typedef std::vector<DelayedAddObjCClassProperty> DelayedPropertyList; + + clang::BlockDecl *ResolveBlockDIE(const DWARFDIE &die); + + clang::NamespaceDecl *ResolveNamespaceDIE(const DWARFDIE &die); + + bool ParseTemplateDIE(const DWARFDIE &die, + lldb_private::ClangASTContext::TemplateParameterInfos + &template_param_infos); + bool ParseTemplateParameterInfos( + const DWARFDIE &parent_die, + 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); + + size_t + ParseChildParameters(const lldb_private::SymbolContext &sc, + clang::DeclContext *containing_decl_ctx, + const DWARFDIE &parent_die, bool skip_artificial, + bool &is_static, bool &is_variadic, + bool &has_template_params, + std::vector<lldb_private::CompilerType> &function_args, + 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, + const DWARFDIE &parent_die); + + lldb_private::Type *GetTypeForDIE(const DWARFDIE &die); + + clang::Decl *GetClangDeclForDIE(const DWARFDIE &die); + + clang::DeclContext *GetClangDeclContextForDIE(const DWARFDIE &die); + + clang::DeclContext *GetClangDeclContextContainingDIE(const DWARFDIE &die, + DWARFDIE *decl_ctx_die); + + bool CopyUniqueClassMethodTypes(const DWARFDIE &src_class_die, + const DWARFDIE &dst_class_die, + lldb_private::Type *class_type, + DWARFDIECollection &failures); + + clang::DeclContext *GetCachedClangDeclContextForDIE(const DWARFDIE &die); + + void LinkDeclContextToDIE(clang::DeclContext *decl_ctx, const DWARFDIE &die); + + void LinkDeclToDIE(clang::Decl *decl, const DWARFDIE &die); + + lldb::TypeSP ParseTypeFromDWO(const DWARFDIE &die, lldb_private::Log *log); + + //---------------------------------------------------------------------- + // Return true if this type is a declaration to a type in an external + // module. + //---------------------------------------------------------------------- + lldb::ModuleSP GetModuleForType(const DWARFDIE &die); + + typedef llvm::SmallPtrSet<const DWARFDebugInfoEntry *, 4> DIEPointerSet; + typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::DeclContext *> + DIEToDeclContextMap; + // typedef llvm::DenseMap<const clang::DeclContext *, DIEPointerSet> + // DeclContextToDIEMap; + typedef std::multimap<const clang::DeclContext *, const DWARFDIE> + DeclContextToDIEMap; + typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::Decl *> + DIEToDeclMap; + typedef llvm::DenseMap<const clang::Decl *, DIEPointerSet> DeclToDIEMap; + + lldb_private::ClangASTContext &m_ast; + DIEToDeclMap m_die_to_decl; + DeclToDIEMap m_decl_to_die; + DIEToDeclContextMap m_die_to_decl_ctx; + DeclContextToDIEMap m_decl_ctx_to_die; + std::unique_ptr<lldb_private::ClangASTImporter> m_clang_ast_importer_ap; }; #endif // SymbolFileDWARF_DWARFASTParserClang_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp index 346e2d63b908..2507465750c7 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp @@ -11,11 +11,11 @@ #include "DWARFASTParserGo.h" #include "DWARFCompileUnit.h" +#include "DWARFDIE.h" +#include "DWARFDIECollection.h" #include "DWARFDebugInfo.h" #include "DWARFDeclContext.h" #include "DWARFDefines.h" -#include "DWARFDIE.h" -#include "DWARFDIECollection.h" #include "SymbolFileDWARF.h" #include "SymbolFileDWARFDebugMap.h" #include "UniqueDWARFASTType.h" @@ -44,787 +44,732 @@ using namespace lldb; using namespace lldb_private; -DWARFASTParserGo::DWARFASTParserGo(GoASTContext &ast) - : m_ast(ast) -{ -} +DWARFASTParserGo::DWARFASTParserGo(GoASTContext &ast) : m_ast(ast) {} -DWARFASTParserGo::~DWARFASTParserGo() -{ -} +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; +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 (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()); - } + 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(); - } + 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; + } + } + } + } - 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); - } - } - } + 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_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()); - } + case DW_AT_byte_size: + byte_size = form_value.Unsigned(); + byte_size_valid = true; 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); - } - } - } + case DW_AT_go_kind: + go_kind = form_value.Unsigned(); 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; + // TODO: Should we use SLICETYPE's DW_AT_go_elem? + default: + break; + } } + } + } - if (type_sp.get()) - { - DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die); - dw_tag_t sc_parent_tag = sc_parent_die.Tag(); + // 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; + } + } - SymbolContextScope *symbol_context_scope = NULL; - if (sc_parent_tag == DW_TAG_compile_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; - } + 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); + } - if (symbol_context_scope != NULL) - { - type_sp->SetSymbolContextScope(symbol_context_scope); - } + 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; - // We are ready to put this type into the uniqued list up at the module level - type_list->Insert(type_sp); + case DW_AT_external: + if (form_value.Unsigned()) { + if (storage == clang::SC_None) + storage = clang::SC_Extern; + else + storage = clang::SC_PrivateExtern; + } + break; - dwarf->m_die_to_type[die.GetDIE()] = type_sp.get(); + case DW_AT_high_pc: + case DW_AT_low_pc: + break; + } } + } } - 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, + DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), + DW_TAG_value_to_name(tag), type_name_cstr); - const DWARFDIE &parent_die, bool &is_variadic, - std::vector<CompilerType> &function_param_types) -{ - if (!parent_die) - return 0; + std::vector<CompilerType> function_param_types; - size_t arg_idx = 0; - for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling()) - { + // Parse the function children for the parameters - 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; + if (die.HasChildren()) { + ParseChildParameters(sc, die, is_variadic, function_param_types); + } - case DW_TAG_unspecified_parameters: - is_variadic = true; + // 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; - default: + 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) { + 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 arg_idx; + } + return type_sp; } -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); - } +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; } - 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; } -bool -DWARFASTParserGo::CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type, CompilerType &compiler_type) -{ - if (!die) - return false; +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; - 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); - } + default: + case DW_AT_type: + break; } - m_ast.CompleteStructType(compiler_type); - return (bool)compiler_type; + } } - default: - assert(false && "not a forward go type decl!"); - 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; -} -size_t -DWARFASTParserGo::ParseChildMembers(const SymbolContext &sc, const DWARFDIE &parent_die, CompilerType &class_compiler_type) -{ - size_t count = 0; - uint32_t member_idx = 0; + const dw_tag_t tag = die.Tag(); - 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; + 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; - for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling()) + switch (tag) { + case DW_TAG_structure_type: { { - 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.GetDWARF()->get_debug_info_data(); - uint32_t block_length = form_value.Unsigned(); - uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); - if (DWARFExpression::Evaluate(NULL, // ExecutionContext * - NULL, // ClangExpressionVariableList * - NULL, // ClangExpressionDeclMap * - 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); - } + 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.GetDWARF()->get_debug_info_data(); + uint32_t block_length = form_value.Unsigned(); + uint32_t block_offset = + form_value.BlockData() - debug_info_data.GetDataStart(); + if (DWARFExpression::Evaluate( + NULL, // ExecutionContext * + NULL, // ClangExpressionVariableList * + NULL, // ClangExpressionDeclMap * + 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(); } - ++member_idx; - } - break; + } 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; + 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; + 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); - } +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 (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(); - } - } + 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; + } + return NULL; } diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h index 5039fc7f7672..2a7c3871a309 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h @@ -18,67 +18,67 @@ #include "llvm/ADT/SmallVector.h" // Project includes -#include "lldb/Core/PluginInterface.h" -#include "lldb/Symbol/GoASTContext.h" -#include "DWARFDefines.h" #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 -{ +class DWARFASTParserGo : public DWARFASTParser { public: - DWARFASTParserGo(lldb_private::GoASTContext &ast); + DWARFASTParserGo(lldb_private::GoASTContext &ast); - ~DWARFASTParserGo() override; + ~DWARFASTParserGo() override; - lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, const DWARFDIE &die, lldb_private::Log *log, - bool *type_is_new_ptr) 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; + 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; + 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 + GetDeclContextForUIDFromDWARF(const DWARFDIE &die) override { + return lldb_private::CompilerDeclContext(); + } - lldb_private::CompilerDeclContext - GetDeclContextContainingUIDFromDWARF(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(); - } + 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>(); - } + 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; + 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/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp index b21bf2ded489..8b5202ba265f 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp @@ -23,533 +23,487 @@ 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"); - } - } +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); + 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) - { +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_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"); - } + 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"); } + } - 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; - 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; + 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"); - } - } +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; -} + DIERef type_die_ref(type_attr_value); + Type *pointee_type = dwarf->ResolveTypeUID(type_die_ref); + if (!pointee_type) + return nullptr; -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"); - } - } - } + 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; +} - 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; - } - } - } +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"); + } } - - 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; + } + + 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; } + } } - - 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(); + } + + 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; } - 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; - } - } +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 (!type_sp) - return nullptr; + if (!die) + return nullptr; - DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die); - dw_tag_t sc_parent_tag = sc_parent_die.Tag(); + SymbolFileDWARF *dwarf = die.GetDWARF(); - SymbolContextScope *symbol_context_scope = nullptr; - if (sc_parent_tag == DW_TAG_compile_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; - } + 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) { + 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); + 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(); + dwarf->GetTypeList()->Insert(type_sp); + dwarf->m_die_to_type[die.GetDIE()] = type_sp.get(); - return type_sp; + 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); - } +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(); - } - } + 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; + } + 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(); - } - } +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) { + DWARFCompileUnit *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 && "Not a forward java type declaration!"); + 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; } - return false; -} + case DW_TAG_inheritance: { + DWARFFormValue encoding_uid; + uint32_t member_byte_offset = UINT32_MAX; -void -DWARFASTParserJava::ParseChildMembers(const DWARFDIE &parent_die, CompilerType &compiler_type) -{ - DWARFCompileUnit *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; + 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/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h index 6a7eee75e6f7..01d81833d517 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h @@ -27,64 +27,55 @@ class DWARFDebugInfoEntry; class DWARFDIECollection; -class DWARFASTParserJava : public DWARFASTParser -{ +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); + 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_private::JavaASTContext &m_ast; - lldb::TypeSP - ParseBaseTypeFromDIE(const DWARFDIE &die); + lldb::TypeSP ParseBaseTypeFromDIE(const DWARFDIE &die); - lldb::TypeSP - ParseArrayTypeFromDIE(const DWARFDIE &die); + lldb::TypeSP ParseArrayTypeFromDIE(const DWARFDIE &die); - lldb::TypeSP - ParseReferenceTypeFromDIE(const DWARFDIE &die); + lldb::TypeSP ParseReferenceTypeFromDIE(const DWARFDIE &die); - lldb::TypeSP - ParseClassTypeFromDIE(const DWARFDIE &die, bool &is_new_type); + lldb::TypeSP ParseClassTypeFromDIE(const DWARFDIE &die, bool &is_new_type); }; #endif // SymbolFileDWARF_DWARFASTParserJava_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp new file mode 100644 index 000000000000..0cf7ff2b938f --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp @@ -0,0 +1,209 @@ +//===-- DWARFASTParserOCaml.cpp ---------------------------------*- C++ -*-===// + +#include "DWARFASTParserOCaml.h" + +#include "lldb/Core/Error.h" +#include "lldb/Core/Log.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" + +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) { + 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/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h new file mode 100644 index 000000000000..e3b2279ca8fc --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h @@ -0,0 +1,60 @@ +//===-- DWARFASTParserOCaml.h -----------------------------------*- C++ -*-===// + +#ifndef SymbolFileDWARF_DWARFASTParserOCaml_h_ +#define SymbolFileDWARF_DWARFASTParserOCaml_h_ + +#include "DWARFASTParser.h" +#include "DWARFCompileUnit.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/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp index 14fc2cea2329..bc49fc5de2cd 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp @@ -15,103 +15,80 @@ using namespace lldb_private; -DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() : - m_code (InvalidCode), - m_tag (0), - m_has_children (0), - m_attributes() -{ -} +DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() + : m_code(InvalidCode), m_tag(0), m_has_children(0), m_attributes() {} -DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration(dw_tag_t tag, uint8_t has_children) : - m_code (InvalidCode), - m_tag (tag), - m_has_children (has_children), - m_attributes() -{ -} +DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration(dw_tag_t tag, + uint8_t has_children) + : m_code(InvalidCode), m_tag(tag), m_has_children(has_children), + m_attributes() {} -bool -DWARFAbbreviationDeclaration::Extract(const DWARFDataExtractor& data, lldb::offset_t* offset_ptr) -{ - return Extract(data, offset_ptr, data.GetULEB128(offset_ptr)); +bool DWARFAbbreviationDeclaration::Extract(const DWARFDataExtractor &data, + lldb::offset_t *offset_ptr) { + return Extract(data, offset_ptr, data.GetULEB128(offset_ptr)); } -bool -DWARFAbbreviationDeclaration::Extract(const DWARFDataExtractor& data, lldb::offset_t *offset_ptr, dw_uleb128_t code) -{ - m_code = code; - m_attributes.clear(); - if (m_code) - { - m_tag = data.GetULEB128(offset_ptr); - m_has_children = data.GetU8(offset_ptr); - - while (data.ValidOffset(*offset_ptr)) - { - dw_attr_t attr = data.GetULEB128(offset_ptr); - dw_form_t form = data.GetULEB128(offset_ptr); - - if (attr && form) - m_attributes.push_back(DWARFAttribute(attr, form)); - else - break; - } - - return m_tag != 0; - } - else - { - m_tag = 0; - m_has_children = 0; +bool DWARFAbbreviationDeclaration::Extract(const DWARFDataExtractor &data, + lldb::offset_t *offset_ptr, + dw_uleb128_t code) { + m_code = code; + m_attributes.clear(); + if (m_code) { + m_tag = data.GetULEB128(offset_ptr); + m_has_children = data.GetU8(offset_ptr); + + while (data.ValidOffset(*offset_ptr)) { + dw_attr_t attr = data.GetULEB128(offset_ptr); + dw_form_t form = data.GetULEB128(offset_ptr); + + if (attr && form) + m_attributes.push_back(DWARFAttribute(attr, form)); + else + break; } - return false; -} + return m_tag != 0; + } else { + m_tag = 0; + m_has_children = 0; + } + return false; +} -void -DWARFAbbreviationDeclaration::Dump(Stream *s) const -{ - s->Printf("Debug Abbreviation Declaration: code = 0x%4.4x, tag = %s, has_children = %s\n", m_code, DW_TAG_value_to_name(m_tag), DW_CHILDREN_value_to_name(m_has_children)); +void DWARFAbbreviationDeclaration::Dump(Stream *s) const { + s->Printf("Debug Abbreviation Declaration: code = 0x%4.4x, tag = %s, " + "has_children = %s\n", + m_code, DW_TAG_value_to_name(m_tag), + DW_CHILDREN_value_to_name(m_has_children)); - DWARFAttribute::const_iterator pos; + DWARFAttribute::const_iterator pos; - for (pos = m_attributes.begin(); pos != m_attributes.end(); ++pos) - s->Printf(" attr = %s, form = %s\n", DW_AT_value_to_name(pos->get_attr()), DW_FORM_value_to_name(pos->get_form())); + for (pos = m_attributes.begin(); pos != m_attributes.end(); ++pos) + s->Printf(" attr = %s, form = %s\n", + DW_AT_value_to_name(pos->get_attr()), + DW_FORM_value_to_name(pos->get_form())); - s->Printf("\n"); + s->Printf("\n"); } - - -bool -DWARFAbbreviationDeclaration::IsValid() -{ - return m_code != 0 && m_tag != 0; +bool DWARFAbbreviationDeclaration::IsValid() { + return m_code != 0 && m_tag != 0; } - - uint32_t -DWARFAbbreviationDeclaration::FindAttributeIndex(dw_attr_t attr) const -{ - uint32_t i; - const uint32_t kNumAttributes = m_attributes.size(); - for (i = 0; i < kNumAttributes; ++i) - { - if (m_attributes[i].get_attr() == attr) - return i; - } - return DW_INVALID_INDEX; +DWARFAbbreviationDeclaration::FindAttributeIndex(dw_attr_t attr) const { + uint32_t i; + const uint32_t kNumAttributes = m_attributes.size(); + for (i = 0; i < kNumAttributes; ++i) { + if (m_attributes[i].get_attr() == attr) + return i; + } + return DW_INVALID_INDEX; } - -bool -DWARFAbbreviationDeclaration::operator == (const DWARFAbbreviationDeclaration& rhs) const -{ - return Tag() == rhs.Tag() - && HasChildren() == rhs.HasChildren() - && Attributes() == rhs.Attributes(); +bool DWARFAbbreviationDeclaration:: +operator==(const DWARFAbbreviationDeclaration &rhs) const { + return Tag() == rhs.Tag() && HasChildren() == rhs.HasChildren() && + Attributes() == rhs.Attributes(); } - diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h index 0ef153a704cd..28e713f9beb1 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h @@ -10,63 +10,66 @@ #ifndef liblldb_DWARFAbbreviationDeclaration_h_ #define liblldb_DWARFAbbreviationDeclaration_h_ -#include "SymbolFileDWARF.h" #include "DWARFAttribute.h" +#include "SymbolFileDWARF.h" class DWARFCompileUnit; -class DWARFAbbreviationDeclaration -{ +class DWARFAbbreviationDeclaration { public: - enum { InvalidCode = 0 }; - DWARFAbbreviationDeclaration(); + enum { InvalidCode = 0 }; + DWARFAbbreviationDeclaration(); + + // For hand crafting an abbreviation declaration + DWARFAbbreviationDeclaration(dw_tag_t tag, uint8_t has_children); + void AddAttribute(const DWARFAttribute &attr) { + m_attributes.push_back(attr); + } - // For hand crafting an abbreviation declaration - DWARFAbbreviationDeclaration(dw_tag_t tag, uint8_t has_children); - void AddAttribute(const DWARFAttribute& attr) - { - m_attributes.push_back(attr); - } + dw_uleb128_t Code() const { return m_code; } + void SetCode(dw_uleb128_t code) { m_code = code; } + dw_tag_t Tag() const { return m_tag; } + bool HasChildren() const { return m_has_children; } + size_t NumAttributes() const { return m_attributes.size(); } + dw_attr_t GetAttrByIndex(uint32_t idx) const { + return m_attributes.size() > idx ? m_attributes[idx].get_attr() : 0; + } + 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; + } - dw_uleb128_t Code() const { return m_code; } - void SetCode(dw_uleb128_t code) { m_code = code; } - dw_tag_t Tag() const { return m_tag; } - bool HasChildren() const { return m_has_children; } - size_t NumAttributes() const { return m_attributes.size(); } - dw_attr_t GetAttrByIndex(uint32_t idx) const { return m_attributes.size() > idx ? m_attributes[idx].get_attr() : 0; } - 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); + } + dw_form_t GetFormByIndexUnchecked(uint32_t idx) const { + return m_attributes[idx].get_form(); + } + uint32_t FindAttributeIndex(dw_attr_t attr) const; + bool Extract(const lldb_private::DWARFDataExtractor &data, + lldb::offset_t *offset_ptr); + bool Extract(const lldb_private::DWARFDataExtractor &data, + lldb::offset_t *offset_ptr, dw_uleb128_t code); + bool IsValid(); + void Dump(lldb_private::Stream *s) const; + bool operator==(const DWARFAbbreviationDeclaration &rhs) const; + const DWARFAttribute::collection &Attributes() const { return m_attributes; } - // 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); - } - dw_form_t GetFormByIndexUnchecked (uint32_t idx) const - { - return m_attributes[idx].get_form(); - } - uint32_t FindAttributeIndex(dw_attr_t attr) const; - bool Extract(const lldb_private::DWARFDataExtractor& data, lldb::offset_t *offset_ptr); - bool Extract(const lldb_private::DWARFDataExtractor& data, lldb::offset_t *offset_ptr, dw_uleb128_t code); - bool IsValid(); - void Dump(lldb_private::Stream *s) const; - bool operator == (const DWARFAbbreviationDeclaration& rhs) const; - const DWARFAttribute::collection& Attributes() const { return m_attributes; } protected: - dw_uleb128_t m_code; - dw_tag_t m_tag; - uint8_t m_has_children; - DWARFAttribute::collection m_attributes; + dw_uleb128_t m_code; + dw_tag_t m_tag; + uint8_t m_has_children; + DWARFAttribute::collection m_attributes; }; -#endif // liblldb_DWARFAbbreviationDeclaration_h_ +#endif // liblldb_DWARFAbbreviationDeclaration_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp index a522bcb35288..d2573f3742ba 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp @@ -8,83 +8,67 @@ //===----------------------------------------------------------------------===// #include "DWARFAttribute.h" -#include "DWARFDebugInfo.h" #include "DWARFCompileUnit.h" +#include "DWARFDebugInfo.h" -DWARFAttributes::DWARFAttributes() : - m_infos() -{ -} +DWARFAttributes::DWARFAttributes() : m_infos() {} -DWARFAttributes::~DWARFAttributes() -{ -} +DWARFAttributes::~DWARFAttributes() {} - -uint32_t -DWARFAttributes::FindAttributeIndex(dw_attr_t attr) const -{ - collection::const_iterator end = m_infos.end(); - collection::const_iterator beg = m_infos.begin(); - collection::const_iterator pos; - for (pos = beg; pos != end; ++pos) - { - if (pos->attr.get_attr() == attr) - return std::distance(beg, pos); - } - return UINT32_MAX; +uint32_t DWARFAttributes::FindAttributeIndex(dw_attr_t attr) const { + collection::const_iterator end = m_infos.end(); + collection::const_iterator beg = m_infos.begin(); + collection::const_iterator pos; + for (pos = beg; pos != end; ++pos) { + if (pos->attr.get_attr() == attr) + return std::distance(beg, pos); + } + return UINT32_MAX; } -void -DWARFAttributes::Append(const DWARFCompileUnit *cu, dw_offset_t attr_die_offset, dw_attr_t attr, dw_form_t form) -{ - AttributeValue attr_value = { cu, attr_die_offset, { attr, form } }; - m_infos.push_back(attr_value); +void DWARFAttributes::Append(const DWARFCompileUnit *cu, + dw_offset_t attr_die_offset, dw_attr_t attr, + dw_form_t form) { + AttributeValue attr_value = {cu, attr_die_offset, {attr, form}}; + m_infos.push_back(attr_value); } -bool -DWARFAttributes::ContainsAttribute(dw_attr_t attr) const -{ - return FindAttributeIndex(attr) != UINT32_MAX; +bool DWARFAttributes::ContainsAttribute(dw_attr_t attr) const { + return FindAttributeIndex(attr) != UINT32_MAX; } -bool -DWARFAttributes::RemoveAttribute(dw_attr_t attr) -{ - uint32_t attr_index = FindAttributeIndex(attr); - if (attr_index != UINT32_MAX) - { - m_infos.erase(m_infos.begin() + attr_index); - return true; - } - return false; +bool DWARFAttributes::RemoveAttribute(dw_attr_t attr) { + uint32_t attr_index = FindAttributeIndex(attr); + if (attr_index != UINT32_MAX) { + m_infos.erase(m_infos.begin() + attr_index); + return true; + } + return false; } -bool -DWARFAttributes::ExtractFormValueAtIndex (uint32_t i, DWARFFormValue &form_value) const -{ - const DWARFCompileUnit *cu = CompileUnitAtIndex(i); - form_value.SetCompileUnit(cu); - form_value.SetForm(FormAtIndex(i)); - lldb::offset_t offset = DIEOffsetAtIndex(i); - return form_value.ExtractValue(cu->GetSymbolFileDWARF()->get_debug_info_data(), &offset); +bool DWARFAttributes::ExtractFormValueAtIndex( + uint32_t i, DWARFFormValue &form_value) const { + const DWARFCompileUnit *cu = CompileUnitAtIndex(i); + form_value.SetCompileUnit(cu); + form_value.SetForm(FormAtIndex(i)); + lldb::offset_t offset = DIEOffsetAtIndex(i); + return form_value.ExtractValue( + cu->GetSymbolFileDWARF()->get_debug_info_data(), &offset); } -uint64_t -DWARFAttributes::FormValueAsUnsigned (dw_attr_t attr, uint64_t fail_value) const -{ - const uint32_t attr_idx = FindAttributeIndex (attr); - if (attr_idx != UINT32_MAX) - return FormValueAsUnsignedAtIndex (attr_idx, fail_value); - return fail_value; +uint64_t DWARFAttributes::FormValueAsUnsigned(dw_attr_t attr, + uint64_t fail_value) const { + const uint32_t attr_idx = FindAttributeIndex(attr); + if (attr_idx != UINT32_MAX) + return FormValueAsUnsignedAtIndex(attr_idx, fail_value); + return fail_value; } uint64_t -DWARFAttributes::FormValueAsUnsignedAtIndex(uint32_t i, uint64_t fail_value) const -{ - DWARFFormValue form_value; - if (ExtractFormValueAtIndex(i, form_value)) - return form_value.Reference(); - return fail_value; +DWARFAttributes::FormValueAsUnsignedAtIndex(uint32_t i, + uint64_t fail_value) const { + DWARFFormValue form_value; + if (ExtractFormValueAtIndex(i, form_value)) + return form_value.Reference(); + return fail_value; } - diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h index f5ca9cce525e..317e710e6d94 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h @@ -10,72 +10,76 @@ #ifndef SymbolFileDWARF_DWARFAttribute_h_ #define SymbolFileDWARF_DWARFAttribute_h_ -#include "llvm/ADT/SmallVector.h" #include "DWARFDefines.h" +#include "llvm/ADT/SmallVector.h" #include <vector> class DWARFCompileUnit; class DWARFFormValue; -class DWARFAttribute -{ +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) : m_attr(attr), m_form(form) {} - void set (dw_attr_t attr, dw_form_t form) { m_attr = attr; m_form = form; } - void set_attr (dw_attr_t attr) { m_attr = attr; } - 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 - { - attr = m_attr; - form = m_form; - } - bool operator == (const DWARFAttribute& rhs) const { return m_attr == rhs.m_attr && m_form == rhs.m_form; } - typedef std::vector<DWARFAttribute> collection; - typedef collection::iterator iterator; - typedef collection::const_iterator const_iterator; + void set(dw_attr_t attr, dw_form_t form) { + m_attr = attr; + m_form = form; + } + void set_attr(dw_attr_t attr) { m_attr = attr; } + 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 { + attr = m_attr; + form = m_form; + } + bool operator==(const DWARFAttribute &rhs) const { + return m_attr == rhs.m_attr && m_form == rhs.m_form; + } + typedef std::vector<DWARFAttribute> collection; + typedef collection::iterator iterator; + typedef collection::const_iterator const_iterator; protected: - dw_attr_t m_attr; - dw_form_t m_form; + dw_attr_t m_attr; + dw_form_t m_form; }; - -class DWARFAttributes -{ +class DWARFAttributes { public: - DWARFAttributes(); - ~DWARFAttributes(); + DWARFAttributes(); + ~DWARFAttributes(); - void Append(const DWARFCompileUnit *cu, dw_offset_t attr_die_offset, dw_attr_t attr, dw_form_t form); - const DWARFCompileUnit * CompileUnitAtIndex(uint32_t i) const { return m_infos[i].cu; } - dw_offset_t DIEOffsetAtIndex(uint32_t i) const { return m_infos[i].die_offset; } - dw_attr_t AttributeAtIndex(uint32_t i) const { return m_infos[i].attr.get_attr(); } - dw_attr_t FormAtIndex(uint32_t i) const { return m_infos[i].attr.get_form(); } - bool ExtractFormValueAtIndex (uint32_t i, DWARFFormValue &form_value) const; - uint64_t FormValueAsUnsignedAtIndex (uint32_t i, uint64_t fail_value) const; - uint64_t FormValueAsUnsigned (dw_attr_t attr, uint64_t fail_value) const; - uint32_t FindAttributeIndex(dw_attr_t attr) const; - bool ContainsAttribute(dw_attr_t attr) const; - bool RemoveAttribute(dw_attr_t attr); - void Clear() { m_infos.clear(); } - size_t Size() const { return m_infos.size(); } + void Append(const DWARFCompileUnit *cu, dw_offset_t attr_die_offset, + dw_attr_t attr, dw_form_t form); + const DWARFCompileUnit *CompileUnitAtIndex(uint32_t i) const { + return m_infos[i].cu; + } + dw_offset_t DIEOffsetAtIndex(uint32_t i) const { + return m_infos[i].die_offset; + } + dw_attr_t AttributeAtIndex(uint32_t i) const { + return m_infos[i].attr.get_attr(); + } + dw_attr_t FormAtIndex(uint32_t i) const { return m_infos[i].attr.get_form(); } + bool ExtractFormValueAtIndex(uint32_t i, DWARFFormValue &form_value) const; + uint64_t FormValueAsUnsignedAtIndex(uint32_t i, uint64_t fail_value) const; + uint64_t FormValueAsUnsigned(dw_attr_t attr, uint64_t fail_value) const; + uint32_t FindAttributeIndex(dw_attr_t attr) const; + bool ContainsAttribute(dw_attr_t attr) const; + bool RemoveAttribute(dw_attr_t attr); + void Clear() { m_infos.clear(); } + size_t Size() const { return m_infos.size(); } protected: - struct AttributeValue - { - const DWARFCompileUnit *cu; // Keep the compile unit with each attribute in case we have DW_FORM_ref_addr values - dw_offset_t die_offset; - DWARFAttribute attr; - }; - typedef llvm::SmallVector<AttributeValue, 8> collection; - collection m_infos; + struct AttributeValue { + const DWARFCompileUnit *cu; // Keep the compile unit with each attribute in + // case we have DW_FORM_ref_addr values + dw_offset_t die_offset; + DWARFAttribute attr; + }; + typedef llvm::SmallVector<AttributeValue, 8> collection; + collection m_infos; }; -#endif // SymbolFileDWARF_DWARFAttribute_h_ +#endif // SymbolFileDWARF_DWARFAttribute_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp index c5d7568b5272..6d3ff8e35910 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -9,6 +9,7 @@ #include "DWARFCompileUnit.h" +#include "Plugins/Language/ObjC/ObjCLanguage.h" #include "lldb/Core/Mangled.h" #include "lldb/Core/Module.h" #include "lldb/Core/Stream.h" @@ -18,130 +19,108 @@ #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/LineTable.h" #include "lldb/Symbol/ObjectFile.h" -#include "Plugins/Language/ObjC/ObjCLanguage.h" +#include "DWARFDIECollection.h" #include "DWARFDebugAbbrev.h" #include "DWARFDebugAranges.h" #include "DWARFDebugInfo.h" -#include "DWARFDIECollection.h" #include "DWARFFormValue.h" #include "LogChannelDWARF.h" #include "NameToDIE.h" #include "SymbolFileDWARF.h" -#include "SymbolFileDWARFDwo.h" #include "SymbolFileDWARFDebugMap.h" +#include "SymbolFileDWARFDwo.h" using namespace lldb; using namespace lldb_private; using namespace std; - extern int g_verbose; -DWARFCompileUnit::DWARFCompileUnit(SymbolFileDWARF* dwarf2Data) : - m_dwarf2Data (dwarf2Data), - m_abbrevs (NULL), - m_user_data (NULL), - m_die_array (), - m_func_aranges_ap (), - m_base_addr (0), - m_offset (DW_INVALID_OFFSET), - m_length (0), - m_version (0), - m_addr_size (DWARFCompileUnit::GetDefaultAddressSize()), - m_producer (eProducerInvalid), - m_producer_version_major (0), - m_producer_version_minor (0), - m_producer_version_update (0), - m_language_type (eLanguageTypeUnknown), - m_is_dwarf64 (false), - m_is_optimized (eLazyBoolCalculate), - m_addr_base (0), - m_base_obj_offset (DW_INVALID_OFFSET) -{ +DWARFCompileUnit::DWARFCompileUnit(SymbolFileDWARF *dwarf2Data) + : m_dwarf2Data(dwarf2Data), m_abbrevs(NULL), m_user_data(NULL), + m_die_array(), m_func_aranges_ap(), m_base_addr(0), + m_offset(DW_INVALID_OFFSET), m_length(0), m_version(0), + m_addr_size(DWARFCompileUnit::GetDefaultAddressSize()), + m_producer(eProducerInvalid), m_producer_version_major(0), + m_producer_version_minor(0), m_producer_version_update(0), + m_language_type(eLanguageTypeUnknown), m_is_dwarf64(false), + m_is_optimized(eLazyBoolCalculate), m_addr_base(0), + m_ranges_base(0), m_base_obj_offset(DW_INVALID_OFFSET) {} + +DWARFCompileUnit::~DWARFCompileUnit() {} + +void DWARFCompileUnit::Clear() { + m_offset = DW_INVALID_OFFSET; + m_length = 0; + m_version = 0; + m_abbrevs = NULL; + m_addr_size = DWARFCompileUnit::GetDefaultAddressSize(); + m_base_addr = 0; + m_die_array.clear(); + m_func_aranges_ap.reset(); + m_user_data = NULL; + m_producer = eProducerInvalid; + m_language_type = eLanguageTypeUnknown; + m_is_dwarf64 = false; + m_is_optimized = eLazyBoolCalculate; + m_addr_base = 0; + m_base_obj_offset = DW_INVALID_OFFSET; } -DWARFCompileUnit::~DWARFCompileUnit() -{} - -void -DWARFCompileUnit::Clear() -{ - m_offset = DW_INVALID_OFFSET; - m_length = 0; - m_version = 0; - m_abbrevs = NULL; - m_addr_size = DWARFCompileUnit::GetDefaultAddressSize(); - m_base_addr = 0; - m_die_array.clear(); - m_func_aranges_ap.reset(); - m_user_data = NULL; - m_producer = eProducerInvalid; - m_language_type = eLanguageTypeUnknown; - m_is_dwarf64 = false; - m_is_optimized = eLazyBoolCalculate; - m_addr_base = 0; - m_base_obj_offset = DW_INVALID_OFFSET; -} +bool DWARFCompileUnit::Extract(const DWARFDataExtractor &debug_info, + lldb::offset_t *offset_ptr) { + Clear(); -bool -DWARFCompileUnit::Extract(const DWARFDataExtractor &debug_info, lldb::offset_t *offset_ptr) -{ - Clear(); - - m_offset = *offset_ptr; - - if (debug_info.ValidOffset(*offset_ptr)) - { - dw_offset_t abbr_offset; - const DWARFDebugAbbrev *abbr = m_dwarf2Data->DebugAbbrev(); - m_length = debug_info.GetDWARFInitialLength(offset_ptr); - m_is_dwarf64 = debug_info.IsDWARF64(); - m_version = debug_info.GetU16(offset_ptr); - abbr_offset = debug_info.GetDWARFOffset(offset_ptr); - m_addr_size = debug_info.GetU8 (offset_ptr); - - bool length_OK = debug_info.ValidOffset(GetNextCompileUnitOffset()-1); - bool version_OK = SymbolFileDWARF::SupportedVersion(m_version); - bool abbr_offset_OK = m_dwarf2Data->get_debug_abbrev_data().ValidOffset(abbr_offset); - bool addr_size_OK = ((m_addr_size == 4) || (m_addr_size == 8)); - - if (length_OK && version_OK && addr_size_OK && abbr_offset_OK && abbr != NULL) - { - m_abbrevs = abbr->GetAbbreviationDeclarationSet(abbr_offset); - return true; - } + m_offset = *offset_ptr; - // reset the offset to where we tried to parse from if anything went wrong - *offset_ptr = m_offset; - } - - return false; -} + if (debug_info.ValidOffset(*offset_ptr)) { + dw_offset_t abbr_offset; + const DWARFDebugAbbrev *abbr = m_dwarf2Data->DebugAbbrev(); + m_length = debug_info.GetDWARFInitialLength(offset_ptr); + m_is_dwarf64 = debug_info.IsDWARF64(); + m_version = debug_info.GetU16(offset_ptr); + abbr_offset = debug_info.GetDWARFOffset(offset_ptr); + m_addr_size = debug_info.GetU8(offset_ptr); + bool length_OK = debug_info.ValidOffset(GetNextCompileUnitOffset() - 1); + bool version_OK = SymbolFileDWARF::SupportedVersion(m_version); + bool abbr_offset_OK = + m_dwarf2Data->get_debug_abbrev_data().ValidOffset(abbr_offset); + bool addr_size_OK = ((m_addr_size == 4) || (m_addr_size == 8)); -void -DWARFCompileUnit::ClearDIEs(bool keep_compile_unit_die) -{ - if (m_die_array.size() > 1) - { - // std::vectors never get any smaller when resized to a smaller size, - // or when clear() or erase() are called, the size will report that it - // is smaller, but the memory allocated remains intact (call capacity() - // to see this). So we need to create a temporary vector and swap the - // contents which will cause just the internal pointers to be swapped - // so that when "tmp_array" goes out of scope, it will destroy the - // contents. - - // Save at least the compile unit DIE - DWARFDebugInfoEntry::collection tmp_array; - m_die_array.swap(tmp_array); - if (keep_compile_unit_die) - m_die_array.push_back(tmp_array.front()); + if (length_OK && version_OK && addr_size_OK && abbr_offset_OK && + abbr != NULL) { + m_abbrevs = abbr->GetAbbreviationDeclarationSet(abbr_offset); + return true; } - if (m_dwo_symbol_file) - m_dwo_symbol_file->GetCompileUnit()->ClearDIEs(keep_compile_unit_die); + // reset the offset to where we tried to parse from if anything went wrong + *offset_ptr = m_offset; + } + + return false; +} + +void DWARFCompileUnit::ClearDIEs(bool keep_compile_unit_die) { + if (m_die_array.size() > 1) { + // std::vectors never get any smaller when resized to a smaller size, + // or when clear() or erase() are called, the size will report that it + // is smaller, but the memory allocated remains intact (call capacity() + // to see this). So we need to create a temporary vector and swap the + // contents which will cause just the internal pointers to be swapped + // so that when "tmp_array" goes out of scope, it will destroy the + // contents. + + // Save at least the compile unit DIE + DWARFDebugInfoEntry::collection tmp_array; + m_die_array.swap(tmp_array); + if (keep_compile_unit_die) + m_die_array.push_back(tmp_array.front()); + } + + if (m_dwo_symbol_file) + m_dwo_symbol_file->GetCompileUnit()->ClearDIEs(keep_compile_unit_die); } //---------------------------------------------------------------------- @@ -150,454 +129,422 @@ DWARFCompileUnit::ClearDIEs(bool keep_compile_unit_die) // Parses a compile unit and indexes its DIEs if it hasn't already been // done. //---------------------------------------------------------------------- -size_t -DWARFCompileUnit::ExtractDIEsIfNeeded (bool cu_die_only) -{ - const size_t initial_die_array_size = m_die_array.size(); - if ((cu_die_only && initial_die_array_size > 0) || initial_die_array_size > 1) - return 0; // Already parsed - - Timer scoped_timer (__PRETTY_FUNCTION__, - "%8.8x: DWARFCompileUnit::ExtractDIEsIfNeeded( cu_die_only = %i )", - m_offset, - cu_die_only); - - // Set the offset to that of the first DIE and calculate the start of the - // next compilation unit header. - lldb::offset_t offset = GetFirstDIEOffset(); - lldb::offset_t next_cu_offset = GetNextCompileUnitOffset(); - - DWARFDebugInfoEntry die; - // Keep a flat array of the DIE for binary lookup by DIE offset - if (!cu_die_only) - { - Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO | DWARF_LOG_LOOKUPS)); - if (log) - { - m_dwarf2Data->GetObjectFile()->GetModule()->LogMessageVerboseBacktrace (log, - "DWARFCompileUnit::ExtractDIEsIfNeeded () for compile unit at .debug_info[0x%8.8x]", - GetOffset()); - } +size_t DWARFCompileUnit::ExtractDIEsIfNeeded(bool cu_die_only) { + const size_t initial_die_array_size = m_die_array.size(); + if ((cu_die_only && initial_die_array_size > 0) || initial_die_array_size > 1) + return 0; // Already parsed + + Timer scoped_timer( + LLVM_PRETTY_FUNCTION, + "%8.8x: DWARFCompileUnit::ExtractDIEsIfNeeded( cu_die_only = %i )", + m_offset, cu_die_only); + + // Set the offset to that of the first DIE and calculate the start of the + // next compilation unit header. + lldb::offset_t offset = GetFirstDIEOffset(); + lldb::offset_t next_cu_offset = GetNextCompileUnitOffset(); + + DWARFDebugInfoEntry die; + // Keep a flat array of the DIE for binary lookup by DIE offset + if (!cu_die_only) { + Log *log( + LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO | DWARF_LOG_LOOKUPS)); + if (log) { + m_dwarf2Data->GetObjectFile()->GetModule()->LogMessageVerboseBacktrace( + log, "DWARFCompileUnit::ExtractDIEsIfNeeded () for compile unit at " + ".debug_info[0x%8.8x]", + GetOffset()); } - - uint32_t depth = 0; - // We are in our compile unit, parse starting at the offset - // we were told to parse - const DWARFDataExtractor& debug_info_data = m_dwarf2Data->get_debug_info_data(); - std::vector<uint32_t> die_index_stack; - die_index_stack.reserve(32); - die_index_stack.push_back(0); - bool prev_die_had_children = false; - DWARFFormValue::FixedFormSizes fixed_form_sizes = - DWARFFormValue::GetFixedFormSizesForAddressSize (GetAddressByteSize(), m_is_dwarf64); - while (offset < next_cu_offset && - die.FastExtract (debug_info_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) - { - if (initial_die_array_size == 0) - AddCompileUnitDIE(die); - uint64_t base_addr = die.GetAttributeValueAsAddress(m_dwarf2Data, this, DW_AT_low_pc, LLDB_INVALID_ADDRESS); - if (base_addr == LLDB_INVALID_ADDRESS) - base_addr = die.GetAttributeValueAsAddress(m_dwarf2Data, this, DW_AT_entry_pc, 0); - SetBaseAddress (base_addr); - if (cu_die_only) - return 1; - } - else - { - if (null_die) - { - if (prev_die_had_children) - { - // This will only happen if a DIE says is has children - // but all it contains is a NULL tag. Since we are removing - // the NULL DIEs from 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); - } - } - else - { - die.SetParentIndex(m_die_array.size() - die_index_stack[depth-1]); - - if (die_index_stack.back()) - m_die_array[die_index_stack.back()].SetSiblingIndex(m_die_array.size()-die_index_stack.back()); - - // Only push the DIE if it isn't a NULL DIE - m_die_array.push_back(die); - } + } + + uint32_t depth = 0; + // We are in our compile unit, parse starting at the offset + // we were told to parse + const DWARFDataExtractor &debug_info_data = + m_dwarf2Data->get_debug_info_data(); + std::vector<uint32_t> die_index_stack; + die_index_stack.reserve(32); + die_index_stack.push_back(0); + bool prev_die_had_children = false; + DWARFFormValue::FixedFormSizes fixed_form_sizes = + DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize(), + m_is_dwarf64); + while (offset < next_cu_offset && + die.FastExtract(debug_info_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) { + if (initial_die_array_size == 0) + AddCompileUnitDIE(die); + uint64_t base_addr = die.GetAttributeValueAsAddress( + m_dwarf2Data, this, DW_AT_low_pc, LLDB_INVALID_ADDRESS); + if (base_addr == LLDB_INVALID_ADDRESS) + base_addr = die.GetAttributeValueAsAddress(m_dwarf2Data, this, + DW_AT_entry_pc, 0); + SetBaseAddress(base_addr); + if (cu_die_only) + return 1; + } else { + if (null_die) { + if (prev_die_had_children) { + // This will only happen if a DIE says is has children + // but all it contains is a NULL tag. Since we are removing + // the NULL DIEs from 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); } + } else { + die.SetParentIndex(m_die_array.size() - die_index_stack[depth - 1]); - if (null_die) - { - // NULL DIE. - if (!die_index_stack.empty()) - die_index_stack.pop_back(); - - 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; - // Normal DIE - const bool die_has_children = die.HasChildren(); - if (die_has_children) - { - die_index_stack.push_back(0); - ++depth; - } - prev_die_had_children = die_has_children; - } - } + if (die_index_stack.back()) + m_die_array[die_index_stack.back()].SetSiblingIndex( + m_die_array.size() - die_index_stack.back()); - // Give a little bit of info if we encounter corrupt DWARF (our offset - // should always terminate at or before the start of the next compilation - // unit header). - if (offset > next_cu_offset) - { - m_dwarf2Data->GetObjectFile()->GetModule()->ReportWarning ("DWARF compile unit extends beyond its bounds cu 0x%8.8x at 0x%8.8" PRIx64 "\n", - GetOffset(), - offset); + // Only push the DIE if it isn't a NULL DIE + m_die_array.push_back(die); + } } - // Since std::vector objects will double their size, we really need to - // make a new array with the perfect size so we don't end up wasting - // space. So here we copy and swap to make sure we don't have any extra - // memory taken up. - - if (m_die_array.size () < m_die_array.capacity()) - { - DWARFDebugInfoEntry::collection exact_size_die_array (m_die_array.begin(), m_die_array.end()); - exact_size_die_array.swap (m_die_array); - } - Log *verbose_log (LogChannelDWARF::GetLogIfAll (DWARF_LOG_DEBUG_INFO | DWARF_LOG_VERBOSE)); - if (verbose_log) - { - StreamString strm; - Dump(&strm); - if (m_die_array.empty()) - strm.Printf("error: no DIE for compile unit"); - else - m_die_array[0].Dump(m_dwarf2Data, this, strm, UINT32_MAX); - verbose_log->PutCString (strm.GetString().c_str()); + if (null_die) { + // NULL DIE. + if (!die_index_stack.empty()) + die_index_stack.pop_back(); + + 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; + // Normal DIE + const bool die_has_children = die.HasChildren(); + if (die_has_children) { + die_index_stack.push_back(0); + ++depth; + } + prev_die_had_children = die_has_children; } + } + + // Give a little bit of info if we encounter corrupt DWARF (our offset + // should always terminate at or before the start of the next compilation + // unit header). + if (offset > next_cu_offset) { + m_dwarf2Data->GetObjectFile()->GetModule()->ReportWarning( + "DWARF compile unit extends beyond its bounds cu 0x%8.8x at " + "0x%8.8" PRIx64 "\n", + GetOffset(), offset); + } + + // Since std::vector objects will double their size, we really need to + // make a new array with the perfect size so we don't end up wasting + // space. So here we copy and swap to make sure we don't have any extra + // memory taken up. + + if (m_die_array.size() < m_die_array.capacity()) { + DWARFDebugInfoEntry::collection exact_size_die_array(m_die_array.begin(), + m_die_array.end()); + exact_size_die_array.swap(m_die_array); + } + Log *verbose_log( + LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO | DWARF_LOG_VERBOSE)); + if (verbose_log) { + StreamString strm; + Dump(&strm); + if (m_die_array.empty()) + strm.Printf("error: no DIE for compile unit"); + else + m_die_array[0].Dump(m_dwarf2Data, this, strm, UINT32_MAX); + verbose_log->PutString(strm.GetString()); + } - if (!m_dwo_symbol_file) - return m_die_array.size(); + if (!m_dwo_symbol_file) + return m_die_array.size(); - DWARFCompileUnit* dwo_cu = m_dwo_symbol_file->GetCompileUnit(); - size_t dwo_die_count = dwo_cu->ExtractDIEsIfNeeded(cu_die_only); - return m_die_array.size() + dwo_die_count - 1; // We have 2 CU die, but we waht to count it only as one + DWARFCompileUnit *dwo_cu = m_dwo_symbol_file->GetCompileUnit(); + size_t dwo_die_count = dwo_cu->ExtractDIEsIfNeeded(cu_die_only); + return m_die_array.size() + dwo_die_count - + 1; // We have 2 CU die, but we want to count it only as one } -void -DWARFCompileUnit::AddCompileUnitDIE(DWARFDebugInfoEntry& die) -{ - assert (m_die_array.empty() && "Compile unit DIE already added"); - AddDIE(die); - - const DWARFDebugInfoEntry &cu_die = m_die_array.front(); - std::unique_ptr<SymbolFileDWARFDwo> dwo_symbol_file = m_dwarf2Data->GetDwoSymbolFileForCompileUnit(*this, cu_die); - if (!dwo_symbol_file) - return; - - DWARFCompileUnit* dwo_cu = dwo_symbol_file->GetCompileUnit(); - if (!dwo_cu) - return; // Can't fetch the compile unit from the dwo file. - - DWARFDIE dwo_cu_die = dwo_cu->GetCompileUnitDIEOnly(); - if (!dwo_cu_die.IsValid()) - return; // Can't fetch the compile unit DIE from the dwo file. - - uint64_t main_dwo_id = cu_die.GetAttributeValueAsUnsigned(m_dwarf2Data, - this, - DW_AT_GNU_dwo_id, - 0); - uint64_t sub_dwo_id = dwo_cu_die.GetAttributeValueAsUnsigned(DW_AT_GNU_dwo_id, 0); - if (main_dwo_id != sub_dwo_id) - return; // The 2 dwo ID isn't match. Don't use the dwo file as it belongs to a differectn compilation. - - m_dwo_symbol_file = std::move(dwo_symbol_file); - - dw_addr_t addr_base = cu_die.GetAttributeValueAsUnsigned(m_dwarf2Data, - this, - DW_AT_GNU_addr_base, - 0); - dwo_cu->SetAddrBase(addr_base, m_offset); +void DWARFCompileUnit::AddCompileUnitDIE(DWARFDebugInfoEntry &die) { + assert(m_die_array.empty() && "Compile unit DIE already added"); + AddDIE(die); + + const DWARFDebugInfoEntry &cu_die = m_die_array.front(); + std::unique_ptr<SymbolFileDWARFDwo> dwo_symbol_file = + m_dwarf2Data->GetDwoSymbolFileForCompileUnit(*this, cu_die); + if (!dwo_symbol_file) + return; + + DWARFCompileUnit *dwo_cu = dwo_symbol_file->GetCompileUnit(); + if (!dwo_cu) + return; // Can't fetch the compile unit from the dwo file. + + DWARFDIE dwo_cu_die = dwo_cu->GetCompileUnitDIEOnly(); + if (!dwo_cu_die.IsValid()) + return; // Can't fetch the compile unit DIE from the dwo file. + + uint64_t main_dwo_id = cu_die.GetAttributeValueAsUnsigned( + m_dwarf2Data, this, DW_AT_GNU_dwo_id, 0); + uint64_t sub_dwo_id = + dwo_cu_die.GetAttributeValueAsUnsigned(DW_AT_GNU_dwo_id, 0); + if (main_dwo_id != sub_dwo_id) + return; // The 2 dwo ID isn't match. Don't use the dwo file as it belongs to + // a differectn compilation. + + m_dwo_symbol_file = std::move(dwo_symbol_file); + + dw_addr_t addr_base = cu_die.GetAttributeValueAsUnsigned( + m_dwarf2Data, this, DW_AT_GNU_addr_base, 0); + dw_addr_t ranges_base = cu_die.GetAttributeValueAsUnsigned( + m_dwarf2Data, this, DW_AT_GNU_ranges_base, 0); + dwo_cu->SetAddrBase(addr_base, ranges_base, m_offset); } -dw_offset_t -DWARFCompileUnit::GetAbbrevOffset() const -{ - return m_abbrevs ? m_abbrevs->GetOffset() : DW_INVALID_OFFSET; +dw_offset_t DWARFCompileUnit::GetAbbrevOffset() const { + return m_abbrevs ? m_abbrevs->GetOffset() : DW_INVALID_OFFSET; } - - -bool -DWARFCompileUnit::Verify(Stream *s) const -{ - const DWARFDataExtractor& debug_info = m_dwarf2Data->get_debug_info_data(); - bool valid_offset = debug_info.ValidOffset(m_offset); - bool length_OK = debug_info.ValidOffset(GetNextCompileUnitOffset()-1); - bool version_OK = SymbolFileDWARF::SupportedVersion(m_version); - bool abbr_offset_OK = m_dwarf2Data->get_debug_abbrev_data().ValidOffset(GetAbbrevOffset()); - bool addr_size_OK = ((m_addr_size == 4) || (m_addr_size == 8)); - bool verbose = s->GetVerbose(); - if (valid_offset && length_OK && version_OK && addr_size_OK && abbr_offset_OK) - { - if (verbose) - s->Printf(" 0x%8.8x: OK\n", m_offset); - return true; - } - else - { - s->Printf(" 0x%8.8x: ", m_offset); - - m_dwarf2Data->get_debug_info_data().Dump (s, m_offset, lldb::eFormatHex, 1, Size(), 32, LLDB_INVALID_ADDRESS, 0, 0); - s->EOL(); - if (valid_offset) - { - if (!length_OK) - s->Printf(" The length (0x%8.8x) for this compile unit is too large for the .debug_info provided.\n", m_length); - if (!version_OK) - s->Printf(" The 16 bit compile unit header version is not supported.\n"); - if (!abbr_offset_OK) - s->Printf(" The offset into the .debug_abbrev section (0x%8.8x) is not valid.\n", GetAbbrevOffset()); - if (!addr_size_OK) - s->Printf(" The address size is unsupported: 0x%2.2x\n", m_addr_size); - } - else - s->Printf(" The start offset of the compile unit header in the .debug_info is invalid.\n"); - } - return false; +bool DWARFCompileUnit::Verify(Stream *s) const { + const DWARFDataExtractor &debug_info = m_dwarf2Data->get_debug_info_data(); + bool valid_offset = debug_info.ValidOffset(m_offset); + bool length_OK = debug_info.ValidOffset(GetNextCompileUnitOffset() - 1); + bool version_OK = SymbolFileDWARF::SupportedVersion(m_version); + bool abbr_offset_OK = + m_dwarf2Data->get_debug_abbrev_data().ValidOffset(GetAbbrevOffset()); + bool addr_size_OK = ((m_addr_size == 4) || (m_addr_size == 8)); + bool verbose = s->GetVerbose(); + if (valid_offset && length_OK && version_OK && addr_size_OK && + abbr_offset_OK) { + if (verbose) + s->Printf(" 0x%8.8x: OK\n", m_offset); + return true; + } else { + s->Printf(" 0x%8.8x: ", m_offset); + + m_dwarf2Data->get_debug_info_data().Dump(s, m_offset, lldb::eFormatHex, 1, + Size(), 32, LLDB_INVALID_ADDRESS, + 0, 0); + s->EOL(); + if (valid_offset) { + if (!length_OK) + s->Printf(" The length (0x%8.8x) for this compile unit is too " + "large for the .debug_info provided.\n", + m_length); + if (!version_OK) + s->Printf(" The 16 bit compile unit header version is not " + "supported.\n"); + if (!abbr_offset_OK) + s->Printf(" The offset into the .debug_abbrev section (0x%8.8x) " + "is not valid.\n", + GetAbbrevOffset()); + if (!addr_size_OK) + s->Printf(" The address size is unsupported: 0x%2.2x\n", + m_addr_size); + } else + s->Printf(" The start offset of the compile unit header in the " + ".debug_info is invalid.\n"); + } + return false; } - -void -DWARFCompileUnit::Dump(Stream *s) const -{ - s->Printf("0x%8.8x: Compile Unit: length = 0x%8.8x, version = 0x%4.4x, abbr_offset = 0x%8.8x, addr_size = 0x%2.2x (next CU at {0x%8.8x})\n", - m_offset, m_length, m_version, GetAbbrevOffset(), m_addr_size, GetNextCompileUnitOffset()); +void DWARFCompileUnit::Dump(Stream *s) const { + s->Printf("0x%8.8x: Compile Unit: length = 0x%8.8x, version = 0x%4.4x, " + "abbr_offset = 0x%8.8x, addr_size = 0x%2.2x (next CU at " + "{0x%8.8x})\n", + m_offset, m_length, m_version, GetAbbrevOffset(), m_addr_size, + GetNextCompileUnitOffset()); } - static uint8_t g_default_addr_size = 4; -uint8_t -DWARFCompileUnit::GetAddressByteSize(const DWARFCompileUnit* cu) -{ - if (cu) - return cu->GetAddressByteSize(); - return DWARFCompileUnit::GetDefaultAddressSize(); +uint8_t DWARFCompileUnit::GetAddressByteSize(const DWARFCompileUnit *cu) { + if (cu) + return cu->GetAddressByteSize(); + return DWARFCompileUnit::GetDefaultAddressSize(); } -bool -DWARFCompileUnit::IsDWARF64(const DWARFCompileUnit* cu) -{ - if (cu) - return cu->IsDWARF64(); - return false; +bool DWARFCompileUnit::IsDWARF64(const DWARFCompileUnit *cu) { + if (cu) + return cu->IsDWARF64(); + return false; } -uint8_t -DWARFCompileUnit::GetDefaultAddressSize() -{ - return g_default_addr_size; +uint8_t DWARFCompileUnit::GetDefaultAddressSize() { + return g_default_addr_size; } -void -DWARFCompileUnit::SetDefaultAddressSize(uint8_t addr_size) -{ - g_default_addr_size = addr_size; +void DWARFCompileUnit::SetDefaultAddressSize(uint8_t addr_size) { + g_default_addr_size = addr_size; } -lldb::user_id_t -DWARFCompileUnit::GetID () const -{ - dw_offset_t local_id = m_base_obj_offset != DW_INVALID_OFFSET ? m_base_obj_offset : m_offset; - if (m_dwarf2Data) - return DIERef(local_id, local_id).GetUID(m_dwarf2Data); - else - return local_id; +lldb::user_id_t DWARFCompileUnit::GetID() const { + dw_offset_t local_id = + m_base_obj_offset != DW_INVALID_OFFSET ? m_base_obj_offset : m_offset; + if (m_dwarf2Data) + return DIERef(local_id, local_id).GetUID(m_dwarf2Data); + else + return local_id; } -void -DWARFCompileUnit::BuildAddressRangeTable (SymbolFileDWARF* dwarf2Data, - DWARFDebugAranges* debug_aranges) -{ - // This function is usually called if there in no .debug_aranges section - // in order to produce a compile unit level set of address ranges that - // is accurate. - - size_t num_debug_aranges = debug_aranges->GetNumRanges(); - - // First get the compile unit DIE only and check if it has a DW_AT_ranges - const DWARFDebugInfoEntry* die = GetCompileUnitDIEPtrOnly(); - - const dw_offset_t cu_offset = GetOffset(); - if (die) - { - DWARFRangeList ranges; - const size_t num_ranges = die->GetAttributeAddressRanges(dwarf2Data, this, ranges, false); - if (num_ranges > 0) - { - // This compile unit has DW_AT_ranges, assume this is correct if it - // is present since clang no longer makes .debug_aranges by default - // and it emits DW_AT_ranges for DW_TAG_compile_units. GCC also does - // this with recent GCC builds. - for (size_t i=0; i<num_ranges; ++i) - { - const DWARFRangeList::Entry &range = ranges.GetEntryRef(i); - debug_aranges->AppendRange(cu_offset, range.GetRangeBase(), range.GetRangeEnd()); - } - - return; // We got all of our ranges from the DW_AT_ranges attribute - } +void DWARFCompileUnit::BuildAddressRangeTable( + SymbolFileDWARF *dwarf2Data, DWARFDebugAranges *debug_aranges) { + // This function is usually called if there in no .debug_aranges section + // in order to produce a compile unit level set of address ranges that + // is accurate. + + size_t num_debug_aranges = debug_aranges->GetNumRanges(); + + // First get the compile unit DIE only and check if it has a DW_AT_ranges + const DWARFDebugInfoEntry *die = GetCompileUnitDIEPtrOnly(); + + const dw_offset_t cu_offset = GetOffset(); + if (die) { + DWARFRangeList ranges; + const size_t num_ranges = + die->GetAttributeAddressRanges(dwarf2Data, this, ranges, false); + if (num_ranges > 0) { + // This compile unit has DW_AT_ranges, assume this is correct if it + // is present since clang no longer makes .debug_aranges by default + // and it emits DW_AT_ranges for DW_TAG_compile_units. GCC also does + // this with recent GCC builds. + for (size_t i = 0; i < num_ranges; ++i) { + const DWARFRangeList::Entry &range = ranges.GetEntryRef(i); + debug_aranges->AppendRange(cu_offset, range.GetRangeBase(), + range.GetRangeEnd()); + } + + return; // We got all of our ranges from the DW_AT_ranges attribute } - // We don't have a DW_AT_ranges attribute, so we need to parse the DWARF - - // If the DIEs weren't parsed, then we don't want all dies for all compile units - // to stay loaded when they weren't needed. So we can end up parsing the DWARF - // and then throwing them all away to keep memory usage down. - const bool clear_dies = ExtractDIEsIfNeeded (false) > 1; - - die = DIEPtr(); - if (die) - die->BuildAddressRangeTable(dwarf2Data, this, debug_aranges); - - if (debug_aranges->GetNumRanges() == num_debug_aranges) - { - // We got nothing from the functions, maybe we have a line tables only - // situation. Check the line tables and build the arange table from this. - SymbolContext sc; - sc.comp_unit = dwarf2Data->GetCompUnitForDWARFCompUnit(this); - if (sc.comp_unit) - { - SymbolFileDWARFDebugMap *debug_map_sym_file = m_dwarf2Data->GetDebugMapSymfile(); - if (debug_map_sym_file == NULL) - { - LineTable *line_table = sc.comp_unit->GetLineTable(); - - if (line_table) - { - LineTable::FileAddressRanges file_ranges; - const bool append = true; - const size_t num_ranges = line_table->GetContiguousFileAddressRanges (file_ranges, append); - for (uint32_t idx=0; idx<num_ranges; ++idx) - { - const LineTable::FileAddressRanges::Entry &range = file_ranges.GetEntryRef(idx); - debug_aranges->AppendRange(cu_offset, range.GetRangeBase(), range.GetRangeEnd()); - } - } - } - else - debug_map_sym_file->AddOSOARanges(dwarf2Data,debug_aranges); + } + // We don't have a DW_AT_ranges attribute, so we need to parse the DWARF + + // If the DIEs weren't parsed, then we don't want all dies for all compile + // units + // to stay loaded when they weren't needed. So we can end up parsing the DWARF + // and then throwing them all away to keep memory usage down. + const bool clear_dies = ExtractDIEsIfNeeded(false) > 1; + + die = DIEPtr(); + if (die) + die->BuildAddressRangeTable(dwarf2Data, this, debug_aranges); + + if (debug_aranges->GetNumRanges() == num_debug_aranges) { + // We got nothing from the functions, maybe we have a line tables only + // situation. Check the line tables and build the arange table from this. + SymbolContext sc; + sc.comp_unit = dwarf2Data->GetCompUnitForDWARFCompUnit(this); + if (sc.comp_unit) { + SymbolFileDWARFDebugMap *debug_map_sym_file = + m_dwarf2Data->GetDebugMapSymfile(); + if (debug_map_sym_file == NULL) { + LineTable *line_table = sc.comp_unit->GetLineTable(); + + if (line_table) { + LineTable::FileAddressRanges file_ranges; + const bool append = true; + const size_t num_ranges = + line_table->GetContiguousFileAddressRanges(file_ranges, append); + for (uint32_t idx = 0; idx < num_ranges; ++idx) { + const LineTable::FileAddressRanges::Entry &range = + file_ranges.GetEntryRef(idx); + debug_aranges->AppendRange(cu_offset, range.GetRangeBase(), + range.GetRangeEnd()); + } } + } else + debug_map_sym_file->AddOSOARanges(dwarf2Data, debug_aranges); } - - if (debug_aranges->GetNumRanges() == num_debug_aranges) - { - // We got nothing from the functions, maybe we have a line tables only - // situation. Check the line tables and build the arange table from this. - SymbolContext sc; - sc.comp_unit = dwarf2Data->GetCompUnitForDWARFCompUnit(this); - if (sc.comp_unit) - { - LineTable *line_table = sc.comp_unit->GetLineTable(); - - if (line_table) - { - LineTable::FileAddressRanges file_ranges; - const bool append = true; - const size_t num_ranges = line_table->GetContiguousFileAddressRanges (file_ranges, append); - for (uint32_t idx=0; idx<num_ranges; ++idx) - { - const LineTable::FileAddressRanges::Entry &range = file_ranges.GetEntryRef(idx); - debug_aranges->AppendRange(GetOffset(), range.GetRangeBase(), range.GetRangeEnd()); - } - } + } + + if (debug_aranges->GetNumRanges() == num_debug_aranges) { + // We got nothing from the functions, maybe we have a line tables only + // situation. Check the line tables and build the arange table from this. + SymbolContext sc; + sc.comp_unit = dwarf2Data->GetCompUnitForDWARFCompUnit(this); + if (sc.comp_unit) { + LineTable *line_table = sc.comp_unit->GetLineTable(); + + if (line_table) { + LineTable::FileAddressRanges file_ranges; + const bool append = true; + const size_t num_ranges = + line_table->GetContiguousFileAddressRanges(file_ranges, append); + for (uint32_t idx = 0; idx < num_ranges; ++idx) { + const LineTable::FileAddressRanges::Entry &range = + file_ranges.GetEntryRef(idx); + debug_aranges->AppendRange(GetOffset(), range.GetRangeBase(), + range.GetRangeEnd()); } + } } - - // Keep memory down by clearing DIEs if this generate function - // caused them to be parsed - if (clear_dies) - ClearDIEs (true); + } + // Keep memory down by clearing DIEs if this generate function + // caused them to be parsed + if (clear_dies) + ClearDIEs(true); } +const DWARFDebugAranges &DWARFCompileUnit::GetFunctionAranges() { + if (m_func_aranges_ap.get() == NULL) { + m_func_aranges_ap.reset(new DWARFDebugAranges()); + Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES)); -const DWARFDebugAranges & -DWARFCompileUnit::GetFunctionAranges () -{ - if (m_func_aranges_ap.get() == NULL) - { - m_func_aranges_ap.reset (new DWARFDebugAranges()); - Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES)); - - if (log) - { - m_dwarf2Data->GetObjectFile()->GetModule()->LogMessage (log, - "DWARFCompileUnit::GetFunctionAranges() for compile unit at .debug_info[0x%8.8x]", - GetOffset()); - } - const DWARFDebugInfoEntry* die = DIEPtr(); - if (die) - die->BuildFunctionAddressRangeTable (m_dwarf2Data, this, m_func_aranges_ap.get()); - - if (m_dwo_symbol_file) - { - DWARFCompileUnit* dwo_cu = m_dwo_symbol_file->GetCompileUnit(); - const DWARFDebugInfoEntry* dwo_die = dwo_cu->DIEPtr(); - if (dwo_die) - dwo_die->BuildFunctionAddressRangeTable (m_dwo_symbol_file.get(), - dwo_cu, - m_func_aranges_ap.get()); - } - - const bool minimize = false; - m_func_aranges_ap->Sort(minimize); + if (log) { + m_dwarf2Data->GetObjectFile()->GetModule()->LogMessage( + log, "DWARFCompileUnit::GetFunctionAranges() for compile unit at " + ".debug_info[0x%8.8x]", + GetOffset()); + } + const DWARFDebugInfoEntry *die = DIEPtr(); + if (die) + die->BuildFunctionAddressRangeTable(m_dwarf2Data, this, + m_func_aranges_ap.get()); + + if (m_dwo_symbol_file) { + DWARFCompileUnit *dwo_cu = m_dwo_symbol_file->GetCompileUnit(); + const DWARFDebugInfoEntry *dwo_die = dwo_cu->DIEPtr(); + if (dwo_die) + dwo_die->BuildFunctionAddressRangeTable(m_dwo_symbol_file.get(), dwo_cu, + m_func_aranges_ap.get()); } - return *m_func_aranges_ap.get(); + + const bool minimize = false; + m_func_aranges_ap->Sort(minimize); + } + return *m_func_aranges_ap.get(); } DWARFDIE -DWARFCompileUnit::LookupAddress (const dw_addr_t address) -{ - if (DIE()) - { - const DWARFDebugAranges &func_aranges = GetFunctionAranges (); - - // Re-check the aranges auto pointer contents in case it was created above - if (!func_aranges.IsEmpty()) - return GetDIE(func_aranges.FindAddress(address)); - } - return DWARFDIE(); +DWARFCompileUnit::LookupAddress(const dw_addr_t address) { + if (DIE()) { + const DWARFDebugAranges &func_aranges = GetFunctionAranges(); + + // Re-check the aranges auto pointer contents in case it was created above + if (!func_aranges.IsEmpty()) + return GetDIE(func_aranges.FindAddress(address)); + } + return DWARFDIE(); } //---------------------------------------------------------------------- // Compare function DWARFDebugAranges::Range structures //---------------------------------------------------------------------- -static bool CompareDIEOffset (const DWARFDebugInfoEntry& die, const dw_offset_t die_offset) -{ - return die.GetOffset() < die_offset; +static bool CompareDIEOffset(const DWARFDebugInfoEntry &die, + const dw_offset_t die_offset) { + return die.GetOffset() < die_offset; } //---------------------------------------------------------------------- @@ -609,627 +556,575 @@ static bool CompareDIEOffset (const DWARFDebugInfoEntry& die, const dw_offset_t // from the DWARF file. //---------------------------------------------------------------------- DWARFDIE -DWARFCompileUnit::GetDIE (dw_offset_t die_offset) -{ - if (die_offset != DW_INVALID_OFFSET) - { - if (m_dwo_symbol_file) - return m_dwo_symbol_file->GetCompileUnit()->GetDIE(die_offset); - - if (ContainsDIEOffset(die_offset)) - { - ExtractDIEsIfNeeded (false); - DWARFDebugInfoEntry::iterator end = m_die_array.end(); - DWARFDebugInfoEntry::iterator pos = lower_bound(m_die_array.begin(), end, die_offset, CompareDIEOffset); - if (pos != end) - { - if (die_offset == (*pos).GetOffset()) - return DWARFDIE(this, &(*pos)); - } - } - else - { - // Don't specify the compile unit offset as we don't know it because the DIE belongs to - // a different compile unit in the same symbol file. - return m_dwarf2Data->DebugInfo()->GetDIEForDIEOffset(die_offset); - } +DWARFCompileUnit::GetDIE(dw_offset_t die_offset) { + if (die_offset != DW_INVALID_OFFSET) { + if (m_dwo_symbol_file) + return m_dwo_symbol_file->GetCompileUnit()->GetDIE(die_offset); + + if (ContainsDIEOffset(die_offset)) { + ExtractDIEsIfNeeded(false); + DWARFDebugInfoEntry::iterator end = m_die_array.end(); + DWARFDebugInfoEntry::iterator pos = + lower_bound(m_die_array.begin(), end, die_offset, CompareDIEOffset); + if (pos != end) { + if (die_offset == (*pos).GetOffset()) + return DWARFDIE(this, &(*pos)); + } + } else { + // Don't specify the compile unit offset as we don't know it because the + // DIE belongs to + // a different compile unit in the same symbol file. + return m_dwarf2Data->DebugInfo()->GetDIEForDIEOffset(die_offset); } - return DWARFDIE(); // Not found + } + return DWARFDIE(); // Not found } -size_t -DWARFCompileUnit::AppendDIEsWithTag (const dw_tag_t tag, DWARFDIECollection& dies, uint32_t depth) const -{ - size_t old_size = dies.Size(); - DWARFDebugInfoEntry::const_iterator pos; - DWARFDebugInfoEntry::const_iterator end = m_die_array.end(); - for (pos = m_die_array.begin(); pos != end; ++pos) - { - if (pos->Tag() == tag) - dies.Append (DWARFDIE(this, &(*pos))); - } - - // Return the number of DIEs added to the collection - return dies.Size() - old_size; +size_t DWARFCompileUnit::AppendDIEsWithTag(const dw_tag_t tag, + DWARFDIECollection &dies, + uint32_t depth) const { + size_t old_size = dies.Size(); + DWARFDebugInfoEntry::const_iterator pos; + DWARFDebugInfoEntry::const_iterator end = m_die_array.end(); + for (pos = m_die_array.begin(); pos != end; ++pos) { + if (pos->Tag() == tag) + dies.Append(DWARFDIE(this, &(*pos))); + } + + // Return the number of DIEs added to the collection + return dies.Size() - old_size; } -//void -//DWARFCompileUnit::AddGlobalDIEByIndex (uint32_t die_idx) +// void +// DWARFCompileUnit::AddGlobalDIEByIndex (uint32_t die_idx) //{ // m_global_die_indexes.push_back (die_idx); //} // // -//void -//DWARFCompileUnit::AddGlobal (const DWARFDebugInfoEntry* die) +// void +// DWARFCompileUnit::AddGlobal (const DWARFDebugInfoEntry* die) //{ // // Indexes to all file level global and static variables // m_global_die_indexes; -// +// // if (m_die_array.empty()) // return; -// +// // const DWARFDebugInfoEntry* first_die = &m_die_array[0]; // const DWARFDebugInfoEntry* end = first_die + m_die_array.size(); // if (first_die <= die && die < end) // m_global_die_indexes.push_back (die - first_die); //} +void DWARFCompileUnit::Index(NameToDIE &func_basenames, + NameToDIE &func_fullnames, NameToDIE &func_methods, + NameToDIE &func_selectors, + NameToDIE &objc_class_selectors, + NameToDIE &globals, NameToDIE &types, + NameToDIE &namespaces) { + Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); + + if (log) { + m_dwarf2Data->GetObjectFile()->GetModule()->LogMessage( + log, + "DWARFCompileUnit::Index() for compile unit at .debug_info[0x%8.8x]", + GetOffset()); + } + + const LanguageType cu_language = GetLanguageType(); + DWARFFormValue::FixedFormSizes fixed_form_sizes = + DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize(), + m_is_dwarf64); + + IndexPrivate(this, cu_language, fixed_form_sizes, GetOffset(), func_basenames, + func_fullnames, func_methods, func_selectors, + objc_class_selectors, globals, types, namespaces); + + SymbolFileDWARFDwo *dwo_symbol_file = GetDwoSymbolFile(); + if (dwo_symbol_file) { + IndexPrivate(dwo_symbol_file->GetCompileUnit(), cu_language, + fixed_form_sizes, GetOffset(), func_basenames, func_fullnames, + func_methods, func_selectors, objc_class_selectors, globals, + types, namespaces); + } +} -void -DWARFCompileUnit::Index (NameToDIE& func_basenames, - NameToDIE& func_fullnames, - NameToDIE& func_methods, - NameToDIE& func_selectors, - NameToDIE& objc_class_selectors, - NameToDIE& globals, - NameToDIE& types, - NameToDIE& namespaces) -{ - Log *log (LogChannelDWARF::GetLogIfAll (DWARF_LOG_LOOKUPS)); - - if (log) - { - m_dwarf2Data->GetObjectFile()->GetModule()->LogMessage (log, - "DWARFCompileUnit::Index() for compile unit at .debug_info[0x%8.8x]", - GetOffset()); - } +void DWARFCompileUnit::IndexPrivate( + DWARFCompileUnit *dwarf_cu, const LanguageType cu_language, + const DWARFFormValue::FixedFormSizes &fixed_form_sizes, + const dw_offset_t cu_offset, NameToDIE &func_basenames, + NameToDIE &func_fullnames, NameToDIE &func_methods, + NameToDIE &func_selectors, NameToDIE &objc_class_selectors, + NameToDIE &globals, NameToDIE &types, NameToDIE &namespaces) { + DWARFDebugInfoEntry::const_iterator pos; + DWARFDebugInfoEntry::const_iterator begin = dwarf_cu->m_die_array.begin(); + DWARFDebugInfoEntry::const_iterator end = dwarf_cu->m_die_array.end(); + for (pos = begin; pos != end; ++pos) { + const DWARFDebugInfoEntry &die = *pos; + + const dw_tag_t tag = die.Tag(); + + switch (tag) { + case DW_TAG_array_type: + case DW_TAG_base_type: + case DW_TAG_class_type: + case DW_TAG_constant: + case DW_TAG_enumeration_type: + case DW_TAG_inlined_subroutine: + case DW_TAG_namespace: + case DW_TAG_string_type: + case DW_TAG_structure_type: + case DW_TAG_subprogram: + case DW_TAG_subroutine_type: + case DW_TAG_typedef: + case DW_TAG_union_type: + case DW_TAG_unspecified_type: + case DW_TAG_variable: + break; - const LanguageType cu_language = GetLanguageType(); - DWARFFormValue::FixedFormSizes fixed_form_sizes = - DWARFFormValue::GetFixedFormSizesForAddressSize (GetAddressByteSize(), m_is_dwarf64); - - IndexPrivate(this, - cu_language, - fixed_form_sizes, - GetOffset(), - func_basenames, - func_fullnames, - func_methods, - func_selectors, - objc_class_selectors, - globals, - types, - namespaces); - - SymbolFileDWARFDwo* dwo_symbol_file = GetDwoSymbolFile(); - if (dwo_symbol_file) - { - IndexPrivate(dwo_symbol_file->GetCompileUnit(), - cu_language, - fixed_form_sizes, - GetOffset(), - func_basenames, - func_fullnames, - func_methods, - func_selectors, - objc_class_selectors, - globals, - types, - namespaces); + default: + continue; } -} -void -DWARFCompileUnit::IndexPrivate (DWARFCompileUnit* dwarf_cu, - const LanguageType cu_language, - const DWARFFormValue::FixedFormSizes& fixed_form_sizes, - const dw_offset_t cu_offset, - NameToDIE& func_basenames, - NameToDIE& func_fullnames, - NameToDIE& func_methods, - NameToDIE& func_selectors, - NameToDIE& objc_class_selectors, - NameToDIE& globals, - NameToDIE& types, - NameToDIE& namespaces) -{ - DWARFDebugInfoEntry::const_iterator pos; - DWARFDebugInfoEntry::const_iterator begin = dwarf_cu->m_die_array.begin(); - DWARFDebugInfoEntry::const_iterator end = dwarf_cu->m_die_array.end(); - for (pos = begin; pos != end; ++pos) - { - const DWARFDebugInfoEntry &die = *pos; - - const dw_tag_t tag = die.Tag(); - - switch (tag) - { - case DW_TAG_array_type: - case DW_TAG_base_type: - case DW_TAG_class_type: - case DW_TAG_constant: - case DW_TAG_enumeration_type: - case DW_TAG_inlined_subroutine: - case DW_TAG_namespace: - case DW_TAG_string_type: - case DW_TAG_structure_type: - case DW_TAG_subprogram: - case DW_TAG_subroutine_type: - case DW_TAG_typedef: - case DW_TAG_union_type: - case DW_TAG_unspecified_type: - case DW_TAG_variable: - break; - - default: - continue; - } - - DWARFAttributes attributes; - const char *name = NULL; - const char *mangled_cstr = NULL; - bool is_declaration = false; - //bool is_artificial = false; - bool has_address = false; - bool has_location_or_const_value = false; - bool is_global_or_static_variable = false; - - DWARFFormValue specification_die_form; - const size_t num_attributes = die.GetAttributes(dwarf_cu, fixed_form_sizes, attributes); - if (num_attributes > 0) - { - for (uint32_t i=0; i<num_attributes; ++i) - { - dw_attr_t attr = attributes.AttributeAtIndex(i); - DWARFFormValue form_value; - switch (attr) - { - case DW_AT_name: - if (attributes.ExtractFormValueAtIndex(i, form_value)) - name = form_value.AsCString(); - break; - - case DW_AT_declaration: - if (attributes.ExtractFormValueAtIndex(i, form_value)) - is_declaration = form_value.Unsigned() != 0; - break; - -// case DW_AT_artificial: -// if (attributes.ExtractFormValueAtIndex(i, form_value)) -// is_artificial = form_value.Unsigned() != 0; -// break; - - case DW_AT_MIPS_linkage_name: - case DW_AT_linkage_name: - if (attributes.ExtractFormValueAtIndex(i, form_value)) - mangled_cstr = form_value.AsCString(); - break; - - case DW_AT_low_pc: - case DW_AT_high_pc: - case DW_AT_ranges: - has_address = true; - break; - - case DW_AT_entry_pc: - has_address = true; - break; - - case DW_AT_location: - case DW_AT_const_value: - has_location_or_const_value = true; - if (tag == DW_TAG_variable) - { - const DWARFDebugInfoEntry* parent_die = die.GetParent(); - while ( parent_die != NULL ) - { - switch (parent_die->Tag()) - { - case DW_TAG_subprogram: - case DW_TAG_lexical_block: - case DW_TAG_inlined_subroutine: - // Even if this is a function level static, we don't add it. We could theoretically - // add these if we wanted to by introspecting into the DW_AT_location and seeing - // if the location describes a hard coded address, but we dont want the performance - // penalty of that right now. - is_global_or_static_variable = false; -// if (attributes.ExtractFormValueAtIndex(dwarf2Data, i, form_value)) -// { -// // If we have valid block data, then we have location expression bytes -// // that are fixed (not a location list). -// const uint8_t *block_data = form_value.BlockData(); -// if (block_data) -// { -// uint32_t block_length = form_value.Unsigned(); -// if (block_length == 1 + attributes.CompileUnitAtIndex(i)->GetAddressByteSize()) -// { -// if (block_data[0] == DW_OP_addr) -// add_die = true; -// } -// } -// } - parent_die = NULL; // Terminate the while loop. - break; - - case DW_TAG_compile_unit: - is_global_or_static_variable = true; - parent_die = NULL; // Terminate the while loop. - break; - - default: - parent_die = parent_die->GetParent(); // Keep going in the while loop. - break; - } - } - } - break; - - case DW_AT_specification: - if (attributes.ExtractFormValueAtIndex(i, form_value)) - specification_die_form = form_value; - break; - } + DWARFAttributes attributes; + const char *name = NULL; + const char *mangled_cstr = NULL; + bool is_declaration = false; + // bool is_artificial = false; + bool has_address = false; + bool has_location_or_const_value = false; + bool is_global_or_static_variable = false; + + DWARFFormValue specification_die_form; + const size_t num_attributes = + die.GetAttributes(dwarf_cu, fixed_form_sizes, attributes); + if (num_attributes > 0) { + for (uint32_t i = 0; i < num_attributes; ++i) { + dw_attr_t attr = attributes.AttributeAtIndex(i); + DWARFFormValue form_value; + switch (attr) { + case DW_AT_name: + if (attributes.ExtractFormValueAtIndex(i, form_value)) + name = form_value.AsCString(); + break; + + case DW_AT_declaration: + if (attributes.ExtractFormValueAtIndex(i, form_value)) + is_declaration = form_value.Unsigned() != 0; + break; + + // case DW_AT_artificial: + // if (attributes.ExtractFormValueAtIndex(i, + // form_value)) + // is_artificial = form_value.Unsigned() != 0; + // break; + + case DW_AT_MIPS_linkage_name: + case DW_AT_linkage_name: + if (attributes.ExtractFormValueAtIndex(i, form_value)) + mangled_cstr = form_value.AsCString(); + break; + + case DW_AT_low_pc: + case DW_AT_high_pc: + case DW_AT_ranges: + has_address = true; + break; + + case DW_AT_entry_pc: + has_address = true; + break; + + case DW_AT_location: + case DW_AT_const_value: + has_location_or_const_value = true; + if (tag == DW_TAG_variable) { + const DWARFDebugInfoEntry *parent_die = die.GetParent(); + while (parent_die != NULL) { + switch (parent_die->Tag()) { + case DW_TAG_subprogram: + case DW_TAG_lexical_block: + case DW_TAG_inlined_subroutine: + // Even if this is a function level static, we don't add it. We + // could theoretically + // add these if we wanted to by introspecting into the + // DW_AT_location and seeing + // if the location describes a hard coded address, but we dont + // want the performance + // penalty of that right now. + is_global_or_static_variable = false; + // if + // (attributes.ExtractFormValueAtIndex(dwarf2Data, + // i, form_value)) + // { + // // If we have valid block + // data, then we have location + // expression bytes + // // that are fixed (not a + // location list). + // const uint8_t *block_data = + // form_value.BlockData(); + // if (block_data) + // { + // uint32_t block_length = + // form_value.Unsigned(); + // if (block_length == 1 + + // attributes.CompileUnitAtIndex(i)->GetAddressByteSize()) + // { + // if (block_data[0] == + // DW_OP_addr) + // add_die = true; + // } + // } + // } + parent_die = NULL; // Terminate the while loop. + break; + + case DW_TAG_compile_unit: + is_global_or_static_variable = true; + parent_die = NULL; // Terminate the while loop. + break; + + default: + parent_die = + parent_die->GetParent(); // Keep going in the while loop. + break; + } } + } + break; + + case DW_AT_specification: + if (attributes.ExtractFormValueAtIndex(i, form_value)) + specification_die_form = form_value; + break; } + } + } - switch (tag) - { - case DW_TAG_subprogram: - if (has_address) - { - if (name) - { - ObjCLanguage::MethodName objc_method(name, true); - if (objc_method.IsValid(true)) - { - ConstString objc_class_name_with_category (objc_method.GetClassNameWithCategory()); - ConstString objc_selector_name (objc_method.GetSelector()); - ConstString objc_fullname_no_category_name (objc_method.GetFullNameWithoutCategory(true)); - ConstString objc_class_name_no_category (objc_method.GetClassName()); - func_fullnames.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset())); - if (objc_class_name_with_category) - objc_class_selectors.Insert(objc_class_name_with_category, DIERef(cu_offset, die.GetOffset())); - if (objc_class_name_no_category && objc_class_name_no_category != objc_class_name_with_category) - objc_class_selectors.Insert(objc_class_name_no_category, DIERef(cu_offset, die.GetOffset())); - if (objc_selector_name) - func_selectors.Insert (objc_selector_name, DIERef(cu_offset, die.GetOffset())); - if (objc_fullname_no_category_name) - func_fullnames.Insert (objc_fullname_no_category_name, DIERef(cu_offset, die.GetOffset())); - } - // If we have a mangled name, then the DW_AT_name attribute - // is usually the method name without the class or any parameters - const DWARFDebugInfoEntry *parent = die.GetParent(); - bool is_method = false; - if (parent) - { - dw_tag_t parent_tag = parent->Tag(); - if (parent_tag == DW_TAG_class_type || parent_tag == DW_TAG_structure_type) - { - is_method = true; - } - else - { - if (specification_die_form.IsValid()) - { - DWARFDIE specification_die = dwarf_cu->GetSymbolFileDWARF()->DebugInfo()->GetDIE (DIERef(specification_die_form)); - if (specification_die.GetParent().IsStructOrClass()) - is_method = true; - } - } - } - - - if (is_method) - func_methods.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset())); - else - func_basenames.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset())); - - if (!is_method && !mangled_cstr && !objc_method.IsValid(true)) - func_fullnames.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset())); - } - if (mangled_cstr) - { - // Make sure our mangled name isn't the same string table entry - // as our name. If it starts with '_', then it is ok, else compare - // the string to make sure it isn't the same and we don't end up - // with duplicate entries - if (name && name != mangled_cstr && ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) - { - Mangled mangled (ConstString(mangled_cstr), true); - func_fullnames.Insert (mangled.GetMangledName(), DIERef(cu_offset, die.GetOffset())); - ConstString demangled = mangled.GetDemangledName(cu_language); - if (demangled) - func_fullnames.Insert (demangled, DIERef(cu_offset, die.GetOffset())); - } - } + switch (tag) { + case DW_TAG_subprogram: + if (has_address) { + if (name) { + ObjCLanguage::MethodName objc_method(name, true); + if (objc_method.IsValid(true)) { + ConstString objc_class_name_with_category( + objc_method.GetClassNameWithCategory()); + ConstString objc_selector_name(objc_method.GetSelector()); + ConstString objc_fullname_no_category_name( + objc_method.GetFullNameWithoutCategory(true)); + ConstString objc_class_name_no_category(objc_method.GetClassName()); + func_fullnames.Insert(ConstString(name), + DIERef(cu_offset, die.GetOffset())); + if (objc_class_name_with_category) + objc_class_selectors.Insert(objc_class_name_with_category, + DIERef(cu_offset, die.GetOffset())); + if (objc_class_name_no_category && + objc_class_name_no_category != objc_class_name_with_category) + objc_class_selectors.Insert(objc_class_name_no_category, + DIERef(cu_offset, die.GetOffset())); + if (objc_selector_name) + func_selectors.Insert(objc_selector_name, + DIERef(cu_offset, die.GetOffset())); + if (objc_fullname_no_category_name) + func_fullnames.Insert(objc_fullname_no_category_name, + DIERef(cu_offset, die.GetOffset())); + } + // If we have a mangled name, then the DW_AT_name attribute + // is usually the method name without the class or any parameters + const DWARFDebugInfoEntry *parent = die.GetParent(); + bool is_method = false; + if (parent) { + dw_tag_t parent_tag = parent->Tag(); + if (parent_tag == DW_TAG_class_type || + parent_tag == DW_TAG_structure_type) { + is_method = true; + } else { + if (specification_die_form.IsValid()) { + DWARFDIE specification_die = + dwarf_cu->GetSymbolFileDWARF()->DebugInfo()->GetDIE( + DIERef(specification_die_form)); + if (specification_die.GetParent().IsStructOrClass()) + is_method = true; + } } - break; - - case DW_TAG_inlined_subroutine: - if (has_address) - { - if (name) - func_basenames.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset())); - if (mangled_cstr) - { - // Make sure our mangled name isn't the same string table entry - // as our name. If it starts with '_', then it is ok, else compare - // the string to make sure it isn't the same and we don't end up - // with duplicate entries - if (name && name != mangled_cstr && ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) - { - Mangled mangled (ConstString(mangled_cstr), true); - func_fullnames.Insert (mangled.GetMangledName(), DIERef(cu_offset, die.GetOffset())); - ConstString demangled = mangled.GetDemangledName(cu_language); - if (demangled) - func_fullnames.Insert (demangled, DIERef(cu_offset, die.GetOffset())); - } - } - else - func_fullnames.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset())); - } - break; - - case DW_TAG_array_type: - case DW_TAG_base_type: - case DW_TAG_class_type: - case DW_TAG_constant: - case DW_TAG_enumeration_type: - case DW_TAG_string_type: - case DW_TAG_structure_type: - case DW_TAG_subroutine_type: - case DW_TAG_typedef: - case DW_TAG_union_type: - case DW_TAG_unspecified_type: - if (name && !is_declaration) - types.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset())); - if (mangled_cstr && !is_declaration) - types.Insert (ConstString(mangled_cstr), DIERef(cu_offset, die.GetOffset())); - break; - - case DW_TAG_namespace: - if (name) - namespaces.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset())); - break; - - case DW_TAG_variable: - if (name && has_location_or_const_value && is_global_or_static_variable) - { - globals.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset())); - // Be sure to include variables by their mangled and demangled - // names if they have any since a variable can have a basename - // "i", a mangled named "_ZN12_GLOBAL__N_11iE" and a demangled - // mangled name "(anonymous namespace)::i"... - - // Make sure our mangled name isn't the same string table entry - // as our name. If it starts with '_', then it is ok, else compare - // the string to make sure it isn't the same and we don't end up - // with duplicate entries - if (mangled_cstr && name != mangled_cstr && ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) - { - Mangled mangled (ConstString(mangled_cstr), true); - globals.Insert (mangled.GetMangledName(), DIERef(cu_offset, die.GetOffset())); - ConstString demangled = mangled.GetDemangledName(cu_language); - if (demangled) - globals.Insert (demangled, DIERef(cu_offset, die.GetOffset())); - } - } - break; - - default: - continue; + } + + if (is_method) + func_methods.Insert(ConstString(name), + DIERef(cu_offset, die.GetOffset())); + else + func_basenames.Insert(ConstString(name), + DIERef(cu_offset, die.GetOffset())); + + if (!is_method && !mangled_cstr && !objc_method.IsValid(true)) + func_fullnames.Insert(ConstString(name), + DIERef(cu_offset, die.GetOffset())); } - } -} + if (mangled_cstr) { + // Make sure our mangled name isn't the same string table entry + // as our name. If it starts with '_', then it is ok, else compare + // the string to make sure it isn't the same and we don't end up + // with duplicate entries + if (name && name != mangled_cstr && + ((mangled_cstr[0] == '_') || + (::strcmp(name, mangled_cstr) != 0))) { + Mangled mangled(ConstString(mangled_cstr), true); + func_fullnames.Insert(mangled.GetMangledName(), + DIERef(cu_offset, die.GetOffset())); + ConstString demangled = mangled.GetDemangledName(cu_language); + if (demangled) + func_fullnames.Insert(demangled, + DIERef(cu_offset, die.GetOffset())); + } + } + } + break; + + case DW_TAG_inlined_subroutine: + if (has_address) { + if (name) + func_basenames.Insert(ConstString(name), + DIERef(cu_offset, die.GetOffset())); + if (mangled_cstr) { + // Make sure our mangled name isn't the same string table entry + // as our name. If it starts with '_', then it is ok, else compare + // the string to make sure it isn't the same and we don't end up + // with duplicate entries + if (name && name != mangled_cstr && + ((mangled_cstr[0] == '_') || + (::strcmp(name, mangled_cstr) != 0))) { + Mangled mangled(ConstString(mangled_cstr), true); + func_fullnames.Insert(mangled.GetMangledName(), + DIERef(cu_offset, die.GetOffset())); + ConstString demangled = mangled.GetDemangledName(cu_language); + if (demangled) + func_fullnames.Insert(demangled, + DIERef(cu_offset, die.GetOffset())); + } + } else + func_fullnames.Insert(ConstString(name), + DIERef(cu_offset, die.GetOffset())); + } + break; + + case DW_TAG_array_type: + case DW_TAG_base_type: + case DW_TAG_class_type: + case DW_TAG_constant: + case DW_TAG_enumeration_type: + case DW_TAG_string_type: + case DW_TAG_structure_type: + case DW_TAG_subroutine_type: + case DW_TAG_typedef: + case DW_TAG_union_type: + case DW_TAG_unspecified_type: + if (name && !is_declaration) + types.Insert(ConstString(name), DIERef(cu_offset, die.GetOffset())); + if (mangled_cstr && !is_declaration) + types.Insert(ConstString(mangled_cstr), + DIERef(cu_offset, die.GetOffset())); + break; + + case DW_TAG_namespace: + if (name) + namespaces.Insert(ConstString(name), + DIERef(cu_offset, die.GetOffset())); + break; + + case DW_TAG_variable: + if (name && has_location_or_const_value && is_global_or_static_variable) { + globals.Insert(ConstString(name), DIERef(cu_offset, die.GetOffset())); + // Be sure to include variables by their mangled and demangled + // names if they have any since a variable can have a basename + // "i", a mangled named "_ZN12_GLOBAL__N_11iE" and a demangled + // mangled name "(anonymous namespace)::i"... + + // Make sure our mangled name isn't the same string table entry + // as our name. If it starts with '_', then it is ok, else compare + // the string to make sure it isn't the same and we don't end up + // with duplicate entries + if (mangled_cstr && name != mangled_cstr && + ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) { + Mangled mangled(ConstString(mangled_cstr), true); + globals.Insert(mangled.GetMangledName(), + DIERef(cu_offset, die.GetOffset())); + ConstString demangled = mangled.GetDemangledName(cu_language); + if (demangled) + globals.Insert(demangled, DIERef(cu_offset, die.GetOffset())); + } + } + break; -bool -DWARFCompileUnit::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; + default: + continue; } - return true; // Assume all other compilers didn't have incorrect ObjC bitfield info + } } -bool -DWARFCompileUnit::Supports_DW_AT_APPLE_objc_complete_type () -{ - if (GetProducer() == eProducerLLVMGCC) - return false; - return true; +bool DWARFCompileUnit::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 true; // Assume all other compilers didn't have incorrect ObjC bitfield + // info } -bool -DWARFCompileUnit::DW_AT_decl_file_attributes_are_invalid() -{ - // llvm-gcc makes completely invalid decl file attributes and won't ever - // be fixed, so we need to know to ignore these. - return GetProducer() == eProducerLLVMGCC; +bool DWARFCompileUnit::Supports_DW_AT_APPLE_objc_complete_type() { + if (GetProducer() == eProducerLLVMGCC) + return false; + return true; } -void -DWARFCompileUnit::ParseProducerInfo () -{ - m_producer_version_major = UINT32_MAX; - m_producer_version_minor = UINT32_MAX; - m_producer_version_update = UINT32_MAX; +bool DWARFCompileUnit::DW_AT_decl_file_attributes_are_invalid() { + // llvm-gcc makes completely invalid decl file attributes and won't ever + // be fixed, so we need to know to ignore these. + return GetProducer() == eProducerLLVMGCC; +} - const DWARFDebugInfoEntry *die = GetCompileUnitDIEPtrOnly(); - if (die) - { - - const char *producer_cstr = die->GetAttributeValueAsString(m_dwarf2Data, this, DW_AT_producer, NULL); - if (producer_cstr) - { - RegularExpression llvm_gcc_regex("^4\\.[012]\\.[01] \\(Based on Apple Inc\\. build [0-9]+\\) \\(LLVM build [\\.0-9]+\\)$"); - if (llvm_gcc_regex.Execute (producer_cstr)) - { - m_producer = eProducerLLVMGCC; - } - else if (strstr(producer_cstr, "clang")) - { - static RegularExpression g_clang_version_regex("clang-([0-9]+)\\.([0-9]+)\\.([0-9]+)"); - RegularExpression::Match regex_match(3); - if (g_clang_version_regex.Execute (producer_cstr, ®ex_match)) - { - std::string str; - if (regex_match.GetMatchAtIndex (producer_cstr, 1, str)) - m_producer_version_major = StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10); - if (regex_match.GetMatchAtIndex (producer_cstr, 2, str)) - m_producer_version_minor = StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10); - if (regex_match.GetMatchAtIndex (producer_cstr, 3, str)) - m_producer_version_update = StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10); - } - m_producer = eProducerClang; - } - else if (strstr(producer_cstr, "GNU")) - m_producer = eProducerGCC; +void DWARFCompileUnit::ParseProducerInfo() { + m_producer_version_major = UINT32_MAX; + m_producer_version_minor = UINT32_MAX; + m_producer_version_update = UINT32_MAX; + + const DWARFDebugInfoEntry *die = GetCompileUnitDIEPtrOnly(); + if (die) { + + const char *producer_cstr = die->GetAttributeValueAsString( + m_dwarf2Data, this, DW_AT_producer, NULL); + if (producer_cstr) { + RegularExpression llvm_gcc_regex( + llvm::StringRef("^4\\.[012]\\.[01] \\(Based on Apple " + "Inc\\. build [0-9]+\\) \\(LLVM build " + "[\\.0-9]+\\)$")); + if (llvm_gcc_regex.Execute(llvm::StringRef(producer_cstr))) { + m_producer = eProducerLLVMGCC; + } else if (strstr(producer_cstr, "clang")) { + static RegularExpression g_clang_version_regex( + llvm::StringRef("clang-([0-9]+)\\.([0-9]+)\\.([0-9]+)")); + RegularExpression::Match regex_match(3); + if (g_clang_version_regex.Execute(llvm::StringRef(producer_cstr), + ®ex_match)) { + std::string str; + if (regex_match.GetMatchAtIndex(producer_cstr, 1, str)) + m_producer_version_major = + StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10); + if (regex_match.GetMatchAtIndex(producer_cstr, 2, str)) + m_producer_version_minor = + StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10); + if (regex_match.GetMatchAtIndex(producer_cstr, 3, str)) + m_producer_version_update = + StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10); } + m_producer = eProducerClang; + } else if (strstr(producer_cstr, "GNU")) + m_producer = eProducerGCC; } - if (m_producer == eProducerInvalid) - m_producer = eProcucerOther; + } + if (m_producer == eProducerInvalid) + m_producer = eProcucerOther; } -DWARFCompileUnit::Producer -DWARFCompileUnit::GetProducer () -{ - if (m_producer == eProducerInvalid) - ParseProducerInfo (); - return m_producer; +DWARFCompileUnit::Producer DWARFCompileUnit::GetProducer() { + if (m_producer == eProducerInvalid) + ParseProducerInfo(); + return m_producer; } - -uint32_t -DWARFCompileUnit::GetProducerVersionMajor() -{ - if (m_producer_version_major == 0) - ParseProducerInfo (); - return m_producer_version_major; +uint32_t DWARFCompileUnit::GetProducerVersionMajor() { + if (m_producer_version_major == 0) + ParseProducerInfo(); + return m_producer_version_major; } -uint32_t -DWARFCompileUnit::GetProducerVersionMinor() -{ - if (m_producer_version_minor == 0) - ParseProducerInfo (); - return m_producer_version_minor; +uint32_t DWARFCompileUnit::GetProducerVersionMinor() { + if (m_producer_version_minor == 0) + ParseProducerInfo(); + return m_producer_version_minor; } -uint32_t -DWARFCompileUnit::GetProducerVersionUpdate() -{ - if (m_producer_version_update == 0) - ParseProducerInfo (); - return m_producer_version_update; +uint32_t DWARFCompileUnit::GetProducerVersionUpdate() { + if (m_producer_version_update == 0) + ParseProducerInfo(); + return m_producer_version_update; } -LanguageType -DWARFCompileUnit::LanguageTypeFromDWARF(uint64_t val) -{ - // Note: user languages between lo_user and hi_user - // must be handled explicitly here. - switch (val) - { - case DW_LANG_Mips_Assembler: - return eLanguageTypeMipsAssembler; - case DW_LANG_GOOGLE_RenderScript: - return eLanguageTypeExtRenderScript; - default: - return static_cast<LanguageType>(val); - } +LanguageType DWARFCompileUnit::LanguageTypeFromDWARF(uint64_t val) { + // Note: user languages between lo_user and hi_user + // must be handled explicitly here. + switch (val) { + case DW_LANG_Mips_Assembler: + return eLanguageTypeMipsAssembler; + case DW_LANG_GOOGLE_RenderScript: + return eLanguageTypeExtRenderScript; + default: + return static_cast<LanguageType>(val); + } } -LanguageType -DWARFCompileUnit::GetLanguageType() -{ - if (m_language_type != eLanguageTypeUnknown) - return m_language_type; - - const DWARFDebugInfoEntry *die = GetCompileUnitDIEPtrOnly(); - if (die) - m_language_type = LanguageTypeFromDWARF(die->GetAttributeValueAsUnsigned(m_dwarf2Data, this, DW_AT_language, 0)); +LanguageType DWARFCompileUnit::GetLanguageType() { + if (m_language_type != eLanguageTypeUnknown) return m_language_type; -} -bool -DWARFCompileUnit::IsDWARF64() const -{ - return m_is_dwarf64; + const DWARFDebugInfoEntry *die = GetCompileUnitDIEPtrOnly(); + if (die) + m_language_type = LanguageTypeFromDWARF(die->GetAttributeValueAsUnsigned( + m_dwarf2Data, this, DW_AT_language, 0)); + return m_language_type; } -bool -DWARFCompileUnit::GetIsOptimized () -{ - if (m_is_optimized == eLazyBoolCalculate) - { - const DWARFDebugInfoEntry *die = GetCompileUnitDIEPtrOnly(); - if (die) - { - m_is_optimized = eLazyBoolNo; - if (die->GetAttributeValueAsUnsigned (m_dwarf2Data, this, DW_AT_APPLE_optimized, 0) == 1) - { - m_is_optimized = eLazyBoolYes; - } - } - } - if (m_is_optimized == eLazyBoolYes) - { - return true; - } - else - { - return false; +bool DWARFCompileUnit::IsDWARF64() const { return m_is_dwarf64; } + +bool DWARFCompileUnit::GetIsOptimized() { + if (m_is_optimized == eLazyBoolCalculate) { + const DWARFDebugInfoEntry *die = GetCompileUnitDIEPtrOnly(); + if (die) { + m_is_optimized = eLazyBoolNo; + if (die->GetAttributeValueAsUnsigned(m_dwarf2Data, this, + DW_AT_APPLE_optimized, 0) == 1) { + m_is_optimized = eLazyBoolYes; + } } + } + if (m_is_optimized == eLazyBoolYes) { + return true; + } else { + return false; + } } -DWARFFormValue::FixedFormSizes -DWARFCompileUnit::GetFixedFormSizes () -{ - return DWARFFormValue::GetFixedFormSizesForAddressSize (GetAddressByteSize(), IsDWARF64()); +DWARFFormValue::FixedFormSizes DWARFCompileUnit::GetFixedFormSizes() { + return DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize(), + IsDWARF64()); } -TypeSystem * -DWARFCompileUnit::GetTypeSystem () -{ - if (m_dwarf2Data) - return m_dwarf2Data->GetTypeSystemForLanguage(GetLanguageType()); - else - return nullptr; +TypeSystem *DWARFCompileUnit::GetTypeSystem() { + if (m_dwarf2Data) + return m_dwarf2Data->GetTypeSystemForLanguage(GetLanguageType()); + else + return nullptr; } -void -DWARFCompileUnit::SetUserData(void *d) -{ - m_user_data = d; - if (m_dwo_symbol_file) - m_dwo_symbol_file->GetCompileUnit()->SetUserData(d); +void DWARFCompileUnit::SetUserData(void *d) { + m_user_data = d; + if (m_dwo_symbol_file) + m_dwo_symbol_file->GetCompileUnit()->SetUserData(d); } -void -DWARFCompileUnit::SetAddrBase(dw_addr_t addr_base, dw_offset_t base_obj_offset) -{ - m_addr_base = addr_base; - m_base_obj_offset = base_obj_offset; +void DWARFCompileUnit::SetAddrBase(dw_addr_t addr_base, + dw_addr_t ranges_base, + dw_offset_t base_obj_offset) { + m_addr_base = addr_base; + m_ranges_base = ranges_base; + m_base_obj_offset = base_obj_offset; } -lldb::ByteOrder -DWARFCompileUnit::GetByteOrder() const -{ - return m_dwarf2Data->GetObjectFile()->GetByteOrder(); +lldb::ByteOrder DWARFCompileUnit::GetByteOrder() const { + return m_dwarf2Data->GetObjectFile()->GetByteOrder(); } diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h index 8d96e3698ab2..430251337575 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h @@ -10,258 +10,214 @@ #ifndef SymbolFileDWARF_DWARFCompileUnit_h_ #define SymbolFileDWARF_DWARFCompileUnit_h_ -#include "lldb/lldb-enumerations.h" -#include "DWARFDebugInfoEntry.h" #include "DWARFDIE.h" +#include "DWARFDebugInfoEntry.h" +#include "lldb/lldb-enumerations.h" class NameToDIE; class SymbolFileDWARF; class SymbolFileDWARFDwo; -class DWARFCompileUnit -{ +class DWARFCompileUnit { public: - enum Producer - { - eProducerInvalid = 0, - eProducerClang, - eProducerGCC, - eProducerLLVMGCC, - eProcucerOther - }; - - DWARFCompileUnit(SymbolFileDWARF* dwarf2Data); - ~DWARFCompileUnit(); - - bool Extract(const lldb_private::DWARFDataExtractor &debug_info, lldb::offset_t *offset_ptr); - size_t ExtractDIEsIfNeeded (bool cu_die_only); - DWARFDIE LookupAddress(const dw_addr_t address); - size_t AppendDIEsWithTag (const dw_tag_t tag, DWARFDIECollection& matching_dies, uint32_t depth = UINT32_MAX) const; - void Clear(); - bool Verify(lldb_private::Stream *s) const; - void Dump(lldb_private::Stream *s) const; - dw_offset_t GetOffset() const { return m_offset; } - lldb::user_id_t GetID () const; - uint32_t Size() const { return m_is_dwarf64 ? 23 : 11; /* Size in bytes of the compile unit header */ } - bool ContainsDIEOffset(dw_offset_t die_offset) const { return die_offset >= GetFirstDIEOffset() && die_offset < GetNextCompileUnitOffset(); } - dw_offset_t GetFirstDIEOffset() const { return m_offset + Size(); } - dw_offset_t GetNextCompileUnitOffset() const { return m_offset + m_length + (m_is_dwarf64 ? 12 : 4); } - size_t GetDebugInfoSize() const { return m_length + (m_is_dwarf64 ? 12 : 4) - Size(); /* Size in bytes of the .debug_info data associated with this compile unit. */ } - uint32_t GetLength() const { return m_length; } - uint16_t GetVersion() const { return m_version; } - const DWARFAbbreviationDeclarationSet* GetAbbreviations() const { return m_abbrevs; } - dw_offset_t GetAbbrevOffset() const; - uint8_t GetAddressByteSize() const { return m_addr_size; } - dw_addr_t GetBaseAddress() const { return m_base_addr; } - dw_addr_t GetAddrBase() const { return m_addr_base; } - void SetAddrBase(dw_addr_t addr_base, dw_offset_t base_obj_offset); - void ClearDIEs(bool keep_compile_unit_die); - void BuildAddressRangeTable (SymbolFileDWARF* dwarf2Data, - DWARFDebugAranges* debug_aranges); - - lldb::ByteOrder - GetByteOrder() const; - - lldb_private::TypeSystem * - GetTypeSystem(); - - DWARFFormValue::FixedFormSizes - GetFixedFormSizes (); - - void - SetBaseAddress(dw_addr_t base_addr) - { - m_base_addr = base_addr; - } - - DWARFDIE - GetCompileUnitDIEOnly() - { - return DWARFDIE(this, GetCompileUnitDIEPtrOnly()); - } - - DWARFDIE - DIE () - { - return DWARFDIE(this, DIEPtr()); - } - - void - AddDIE (DWARFDebugInfoEntry& die) - { - // The average bytes per DIE entry has been seen to be - // around 14-20 so lets pre-reserve half of that since - // we are now stripping the NULL tags. - - // Only reserve the memory if we are adding children of - // the main compile unit DIE. The compile unit DIE is always - // the first entry, so if our size is 1, then we are adding - // the first compile unit child DIE and should reserve - // the memory. - if (m_die_array.empty()) - m_die_array.reserve(GetDebugInfoSize() / 24); - m_die_array.push_back(die); - } - - void - AddCompileUnitDIE (DWARFDebugInfoEntry& die); - - bool - HasDIEsParsed () const - { - return m_die_array.size() > 1; - } - - DWARFDIE - GetDIE (dw_offset_t die_offset); - - static uint8_t - GetAddressByteSize(const DWARFCompileUnit* cu); - - static bool - IsDWARF64(const DWARFCompileUnit* cu); - - static uint8_t - GetDefaultAddressSize(); - - static void - SetDefaultAddressSize(uint8_t addr_size); - - void * - GetUserData() const - { - return m_user_data; - } - - void - SetUserData(void *d); - - bool - Supports_DW_AT_APPLE_objc_complete_type (); - - bool - DW_AT_decl_file_attributes_are_invalid(); - - bool - Supports_unnamed_objc_bitfields (); - - void - Index (NameToDIE& func_basenames, - NameToDIE& func_fullnames, - NameToDIE& func_methods, - NameToDIE& func_selectors, - NameToDIE& objc_class_selectors, - NameToDIE& globals, - NameToDIE& types, - NameToDIE& namespaces); - - const DWARFDebugAranges & - GetFunctionAranges (); - - SymbolFileDWARF* - GetSymbolFileDWARF () const - { - return m_dwarf2Data; - } - - Producer - GetProducer (); - - uint32_t - GetProducerVersionMajor(); - - uint32_t - GetProducerVersionMinor(); - - uint32_t - GetProducerVersionUpdate(); - - static lldb::LanguageType - LanguageTypeFromDWARF(uint64_t val); - - lldb::LanguageType - GetLanguageType(); - - bool - IsDWARF64() const; - - bool - GetIsOptimized (); - - SymbolFileDWARFDwo* - GetDwoSymbolFile() const - { - return m_dwo_symbol_file.get(); - } - - dw_offset_t - GetBaseObjOffset() const - { - return m_base_obj_offset; - } + enum Producer { + eProducerInvalid = 0, + eProducerClang, + eProducerGCC, + eProducerLLVMGCC, + eProcucerOther + }; + + DWARFCompileUnit(SymbolFileDWARF *dwarf2Data); + ~DWARFCompileUnit(); + + bool Extract(const lldb_private::DWARFDataExtractor &debug_info, + lldb::offset_t *offset_ptr); + size_t ExtractDIEsIfNeeded(bool cu_die_only); + DWARFDIE LookupAddress(const dw_addr_t address); + size_t AppendDIEsWithTag(const dw_tag_t tag, + DWARFDIECollection &matching_dies, + uint32_t depth = UINT32_MAX) const; + void Clear(); + bool Verify(lldb_private::Stream *s) const; + void Dump(lldb_private::Stream *s) const; + dw_offset_t GetOffset() const { return m_offset; } + lldb::user_id_t GetID() const; + uint32_t Size() const { + return m_is_dwarf64 ? 23 + : 11; /* Size in bytes of the compile unit header */ + } + bool ContainsDIEOffset(dw_offset_t die_offset) const { + return die_offset >= GetFirstDIEOffset() && + die_offset < GetNextCompileUnitOffset(); + } + dw_offset_t GetFirstDIEOffset() const { return m_offset + Size(); } + dw_offset_t GetNextCompileUnitOffset() const { + return m_offset + m_length + (m_is_dwarf64 ? 12 : 4); + } + size_t GetDebugInfoSize() const { + return m_length + (m_is_dwarf64 ? 12 : 4) - Size(); /* Size in bytes of the + .debug_info data + associated with this + compile unit. */ + } + uint32_t GetLength() const { return m_length; } + uint16_t GetVersion() const { return m_version; } + const DWARFAbbreviationDeclarationSet *GetAbbreviations() const { + return m_abbrevs; + } + dw_offset_t GetAbbrevOffset() const; + uint8_t GetAddressByteSize() const { return m_addr_size; } + 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); + void ClearDIEs(bool keep_compile_unit_die); + void BuildAddressRangeTable(SymbolFileDWARF *dwarf2Data, + DWARFDebugAranges *debug_aranges); + + lldb::ByteOrder GetByteOrder() const; + + lldb_private::TypeSystem *GetTypeSystem(); + + DWARFFormValue::FixedFormSizes GetFixedFormSizes(); + + void SetBaseAddress(dw_addr_t base_addr) { m_base_addr = base_addr; } + + DWARFDIE + GetCompileUnitDIEOnly() { return DWARFDIE(this, GetCompileUnitDIEPtrOnly()); } + + DWARFDIE + DIE() { return DWARFDIE(this, DIEPtr()); } + + void AddDIE(DWARFDebugInfoEntry &die) { + // The average bytes per DIE entry has been seen to be + // around 14-20 so lets pre-reserve half of that since + // we are now stripping the NULL tags. + + // Only reserve the memory if we are adding children of + // the main compile unit DIE. The compile unit DIE is always + // the first entry, so if our size is 1, then we are adding + // the first compile unit child DIE and should reserve + // the memory. + if (m_die_array.empty()) + m_die_array.reserve(GetDebugInfoSize() / 24); + m_die_array.push_back(die); + } + + void AddCompileUnitDIE(DWARFDebugInfoEntry &die); + + bool HasDIEsParsed() const { return m_die_array.size() > 1; } + + DWARFDIE + GetDIE(dw_offset_t die_offset); + + static uint8_t GetAddressByteSize(const DWARFCompileUnit *cu); + + static bool IsDWARF64(const DWARFCompileUnit *cu); + + static uint8_t GetDefaultAddressSize(); + + static void SetDefaultAddressSize(uint8_t addr_size); + + void *GetUserData() const { return m_user_data; } + + void SetUserData(void *d); + + bool Supports_DW_AT_APPLE_objc_complete_type(); + + bool DW_AT_decl_file_attributes_are_invalid(); + + bool Supports_unnamed_objc_bitfields(); + + void Index(NameToDIE &func_basenames, NameToDIE &func_fullnames, + NameToDIE &func_methods, NameToDIE &func_selectors, + NameToDIE &objc_class_selectors, NameToDIE &globals, + NameToDIE &types, NameToDIE &namespaces); + + const DWARFDebugAranges &GetFunctionAranges(); + + SymbolFileDWARF *GetSymbolFileDWARF() const { return m_dwarf2Data; } + + Producer GetProducer(); + + uint32_t GetProducerVersionMajor(); + + uint32_t GetProducerVersionMinor(); + + uint32_t GetProducerVersionUpdate(); + + static lldb::LanguageType LanguageTypeFromDWARF(uint64_t val); + + lldb::LanguageType GetLanguageType(); + + bool IsDWARF64() const; + + bool GetIsOptimized(); + + SymbolFileDWARFDwo *GetDwoSymbolFile() const { + return m_dwo_symbol_file.get(); + } + + dw_offset_t GetBaseObjOffset() const { return m_base_obj_offset; } protected: - SymbolFileDWARF* m_dwarf2Data; - std::unique_ptr<SymbolFileDWARFDwo> m_dwo_symbol_file; - const DWARFAbbreviationDeclarationSet *m_abbrevs; - void * m_user_data; - DWARFDebugInfoEntry::collection m_die_array; // The compile unit debug information entry item - std::unique_ptr<DWARFDebugAranges> m_func_aranges_ap; // A table similar to the .debug_aranges table, but this one points to the exact DW_TAG_subprogram DIEs - dw_addr_t m_base_addr; - dw_offset_t m_offset; - dw_offset_t m_length; - uint16_t m_version; - uint8_t m_addr_size; - Producer m_producer; - uint32_t m_producer_version_major; - uint32_t m_producer_version_minor; - uint32_t m_producer_version_update; - lldb::LanguageType m_language_type; - bool m_is_dwarf64; - lldb_private::LazyBool m_is_optimized; - dw_addr_t m_addr_base; // Value of DW_AT_addr_base - dw_offset_t m_base_obj_offset; // If this is a dwo compile unit this is the offset of - // the base compile unit in the main object file - - void - ParseProducerInfo (); - - static void - IndexPrivate (DWARFCompileUnit* dwarf_cu, - const lldb::LanguageType cu_language, - const DWARFFormValue::FixedFormSizes& fixed_form_sizes, - const dw_offset_t cu_offset, - NameToDIE& func_basenames, - NameToDIE& func_fullnames, - NameToDIE& func_methods, - NameToDIE& func_selectors, - NameToDIE& objc_class_selectors, - NameToDIE& globals, - NameToDIE& types, - NameToDIE& namespaces); + SymbolFileDWARF *m_dwarf2Data; + std::unique_ptr<SymbolFileDWARFDwo> m_dwo_symbol_file; + const DWARFAbbreviationDeclarationSet *m_abbrevs; + void *m_user_data; + DWARFDebugInfoEntry::collection + m_die_array; // The compile unit debug information entry item + std::unique_ptr<DWARFDebugAranges> m_func_aranges_ap; // A table similar to + // the .debug_aranges + // table, but this one + // points to the exact + // DW_TAG_subprogram + // DIEs + dw_addr_t m_base_addr; + dw_offset_t m_offset; + dw_offset_t m_length; + uint16_t m_version; + uint8_t m_addr_size; + Producer m_producer; + uint32_t m_producer_version_major; + uint32_t m_producer_version_minor; + uint32_t m_producer_version_update; + lldb::LanguageType m_language_type; + bool m_is_dwarf64; + lldb_private::LazyBool m_is_optimized; + dw_addr_t m_addr_base; // Value of DW_AT_addr_base + dw_addr_t m_ranges_base; // Value of DW_AT_ranges_base + dw_offset_t m_base_obj_offset; // If this is a dwo compile unit this is the + // offset of the base compile unit in the main + // object file + + void ParseProducerInfo(); + + static void + IndexPrivate(DWARFCompileUnit *dwarf_cu, const lldb::LanguageType cu_language, + const DWARFFormValue::FixedFormSizes &fixed_form_sizes, + const dw_offset_t cu_offset, NameToDIE &func_basenames, + NameToDIE &func_fullnames, NameToDIE &func_methods, + NameToDIE &func_selectors, NameToDIE &objc_class_selectors, + NameToDIE &globals, NameToDIE &types, NameToDIE &namespaces); private: - - const DWARFDebugInfoEntry* - GetCompileUnitDIEPtrOnly() - { - ExtractDIEsIfNeeded (true); - if (m_die_array.empty()) - return NULL; - return &m_die_array[0]; - } - - const DWARFDebugInfoEntry* - DIEPtr() - { - ExtractDIEsIfNeeded (false); - if (m_die_array.empty()) - return NULL; - return &m_die_array[0]; - } - - - DISALLOW_COPY_AND_ASSIGN (DWARFCompileUnit); + const DWARFDebugInfoEntry *GetCompileUnitDIEPtrOnly() { + ExtractDIEsIfNeeded(true); + if (m_die_array.empty()) + return NULL; + return &m_die_array[0]; + } + + const DWARFDebugInfoEntry *DIEPtr() { + ExtractDIEsIfNeeded(false); + if (m_die_array.empty()) + return NULL; + return &m_die_array[0]; + } + + DISALLOW_COPY_AND_ASSIGN(DWARFCompileUnit); }; -#endif // SymbolFileDWARF_DWARFCompileUnit_h_ +#endif // SymbolFileDWARF_DWARFCompileUnit_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp index 0f02c74fd2eb..5222419d3233 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp @@ -11,13 +11,13 @@ #include "DWARFASTParser.h" #include "DWARFCompileUnit.h" +#include "DWARFDIECollection.h" #include "DWARFDebugAbbrev.h" #include "DWARFDebugAranges.h" #include "DWARFDebugInfo.h" #include "DWARFDebugInfoEntry.h" #include "DWARFDebugRanges.h" #include "DWARFDeclContext.h" -#include "DWARFDIECollection.h" #include "DWARFFormValue.h" #include "SymbolFileDWARF.h" @@ -28,543 +28,441 @@ using namespace lldb_private; -DIERef -DWARFDIE::GetDIERef() const -{ - if (!IsValid()) - return DIERef(); +DIERef DWARFDIE::GetDIERef() const { + if (!IsValid()) + return DIERef(); - dw_offset_t cu_offset = m_cu->GetOffset(); - if (m_cu->GetBaseObjOffset() != DW_INVALID_OFFSET) - cu_offset = m_cu->GetBaseObjOffset(); - return DIERef(cu_offset, m_die->GetOffset()); + dw_offset_t cu_offset = m_cu->GetOffset(); + if (m_cu->GetBaseObjOffset() != DW_INVALID_OFFSET) + cu_offset = m_cu->GetBaseObjOffset(); + return DIERef(cu_offset, m_die->GetOffset()); } -dw_tag_t -DWARFDIE::Tag() const -{ - if (m_die) - return m_die->Tag(); - else - return 0; +dw_tag_t DWARFDIE::Tag() const { + if (m_die) + return m_die->Tag(); + else + return 0; } -const char * -DWARFDIE::GetTagAsCString () const -{ - return lldb_private::DW_TAG_value_to_name (Tag()); +const char *DWARFDIE::GetTagAsCString() const { + return lldb_private::DW_TAG_value_to_name(Tag()); } DWARFDIE -DWARFDIE::GetParent () const -{ - if (IsValid()) - return DWARFDIE(m_cu, m_die->GetParent()); - else - return DWARFDIE(); +DWARFDIE::GetParent() const { + if (IsValid()) + return DWARFDIE(m_cu, m_die->GetParent()); + else + return DWARFDIE(); } DWARFDIE -DWARFDIE::GetFirstChild () const -{ - if (IsValid()) - return DWARFDIE(m_cu, m_die->GetFirstChild()); - else - return DWARFDIE(); +DWARFDIE::GetFirstChild() const { + if (IsValid()) + return DWARFDIE(m_cu, m_die->GetFirstChild()); + else + return DWARFDIE(); } DWARFDIE -DWARFDIE::GetSibling () const -{ - if (IsValid()) - return DWARFDIE(m_cu, m_die->GetSibling()); - else - return DWARFDIE(); +DWARFDIE::GetSibling() const { + if (IsValid()) + return DWARFDIE(m_cu, m_die->GetSibling()); + else + return DWARFDIE(); } DWARFDIE -DWARFDIE::GetReferencedDIE (const dw_attr_t attr) const -{ - const dw_offset_t die_offset = GetAttributeValueAsReference (attr, DW_INVALID_OFFSET); - if (die_offset != DW_INVALID_OFFSET) - return GetDIE(die_offset); - else - return DWARFDIE(); +DWARFDIE::GetReferencedDIE(const dw_attr_t attr) const { + const dw_offset_t die_offset = + GetAttributeValueAsReference(attr, DW_INVALID_OFFSET); + if (die_offset != DW_INVALID_OFFSET) + return GetDIE(die_offset); + else + return DWARFDIE(); } DWARFDIE -DWARFDIE::GetDIE (dw_offset_t die_offset) const -{ - if (IsValid()) - return m_cu->GetDIE(die_offset); - else - return DWARFDIE(); +DWARFDIE::GetDIE(dw_offset_t die_offset) const { + if (IsValid()) + return m_cu->GetDIE(die_offset); + else + return DWARFDIE(); } -const char * -DWARFDIE::GetAttributeValueAsString (const dw_attr_t attr, const char *fail_value) const -{ - if (IsValid()) - return m_die->GetAttributeValueAsString(GetDWARF(), GetCU(), attr, fail_value); - else - return fail_value; +const char *DWARFDIE::GetAttributeValueAsString(const dw_attr_t attr, + const char *fail_value) const { + if (IsValid()) + return m_die->GetAttributeValueAsString(GetDWARF(), GetCU(), attr, + fail_value); + else + return fail_value; } -uint64_t -DWARFDIE::GetAttributeValueAsUnsigned (const dw_attr_t attr, uint64_t fail_value) const -{ - if (IsValid()) - return m_die->GetAttributeValueAsUnsigned(GetDWARF(), GetCU(), attr, fail_value); - else - return fail_value; +uint64_t DWARFDIE::GetAttributeValueAsUnsigned(const dw_attr_t attr, + uint64_t fail_value) const { + if (IsValid()) + return m_die->GetAttributeValueAsUnsigned(GetDWARF(), GetCU(), attr, + fail_value); + else + return fail_value; } -int64_t -DWARFDIE::GetAttributeValueAsSigned (const dw_attr_t attr, int64_t fail_value) const -{ - if (IsValid()) - return m_die->GetAttributeValueAsSigned(GetDWARF(), GetCU(), attr, fail_value); - else - return fail_value; +int64_t DWARFDIE::GetAttributeValueAsSigned(const dw_attr_t attr, + int64_t fail_value) const { + if (IsValid()) + return m_die->GetAttributeValueAsSigned(GetDWARF(), GetCU(), attr, + fail_value); + else + return fail_value; } DWARFDIE -DWARFDIE::GetAttributeValueAsReferenceDIE (const dw_attr_t attr) const -{ - if (IsValid()) - { - DWARFCompileUnit *cu = GetCU(); - SymbolFileDWARF *dwarf = cu->GetSymbolFileDWARF(); - const bool check_specification_or_abstract_origin = true; - DWARFFormValue form_value; - if (m_die->GetAttributeValue(dwarf, cu, attr, form_value, nullptr, check_specification_or_abstract_origin)) - return dwarf->GetDIE(DIERef(form_value)); - } - return DWARFDIE(); +DWARFDIE::GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const { + if (IsValid()) { + DWARFCompileUnit *cu = GetCU(); + SymbolFileDWARF *dwarf = cu->GetSymbolFileDWARF(); + const bool check_specification_or_abstract_origin = true; + DWARFFormValue form_value; + if (m_die->GetAttributeValue(dwarf, cu, attr, form_value, nullptr, + check_specification_or_abstract_origin)) + return dwarf->GetDIE(DIERef(form_value)); + } + return DWARFDIE(); +} + +uint64_t DWARFDIE::GetAttributeValueAsReference(const dw_attr_t attr, + uint64_t fail_value) const { + if (IsValid()) + return m_die->GetAttributeValueAsReference(GetDWARF(), GetCU(), attr, + fail_value); + else + return fail_value; +} + +uint64_t DWARFDIE::GetAttributeValueAsAddress(const dw_attr_t attr, + uint64_t fail_value) const { + if (IsValid()) + return m_die->GetAttributeValueAsAddress(GetDWARF(), GetCU(), attr, + fail_value); + else + return fail_value; } -uint64_t -DWARFDIE::GetAttributeValueAsReference (const dw_attr_t attr, uint64_t fail_value) const -{ - if (IsValid()) - return m_die->GetAttributeValueAsReference(GetDWARF(), GetCU(), attr, fail_value); - else - return fail_value; -} - -uint64_t -DWARFDIE::GetAttributeValueAsAddress (const dw_attr_t attr, uint64_t fail_value) const -{ - if (IsValid()) - return m_die->GetAttributeValueAsAddress(GetDWARF(), GetCU(), attr, fail_value); - else - return fail_value; -} - - DWARFDIE -DWARFDIE::LookupDeepestBlock (lldb::addr_t file_addr) const -{ - if (IsValid()) - { - SymbolFileDWARF *dwarf= GetDWARF(); - DWARFCompileUnit *cu = GetCU(); - DWARFDebugInfoEntry* function_die = nullptr; - DWARFDebugInfoEntry* block_die = nullptr; - if (m_die->LookupAddress (file_addr, - dwarf, - cu, - &function_die, - &block_die)) - { - if (block_die && block_die != function_die) - { - if (cu->ContainsDIEOffset(block_die->GetOffset())) - return DWARFDIE(cu, block_die); - else - return DWARFDIE(dwarf->DebugInfo()->GetCompileUnit(DIERef(cu->GetOffset(), block_die->GetOffset())), block_die); - } - } +DWARFDIE::LookupDeepestBlock(lldb::addr_t file_addr) const { + if (IsValid()) { + SymbolFileDWARF *dwarf = GetDWARF(); + DWARFCompileUnit *cu = GetCU(); + DWARFDebugInfoEntry *function_die = nullptr; + DWARFDebugInfoEntry *block_die = nullptr; + if (m_die->LookupAddress(file_addr, dwarf, cu, &function_die, &block_die)) { + if (block_die && block_die != function_die) { + if (cu->ContainsDIEOffset(block_die->GetOffset())) + return DWARFDIE(cu, block_die); + else + return DWARFDIE(dwarf->DebugInfo()->GetCompileUnit( + DIERef(cu->GetOffset(), block_die->GetOffset())), + block_die); + } } - return DWARFDIE(); -} - -lldb::user_id_t -DWARFDIE::GetID () const -{ - return GetDIERef().GetUID(GetDWARF()); + } + return DWARFDIE(); } -const char * -DWARFDIE::GetName () const -{ - if (IsValid()) - return m_die->GetName (GetDWARF(), m_cu); - else - return nullptr; +lldb::user_id_t DWARFDIE::GetID() const { + return GetDIERef().GetUID(GetDWARF()); } -const char * -DWARFDIE::GetMangledName () const -{ - if (IsValid()) - return m_die->GetMangledName (GetDWARF(), m_cu); - else - return nullptr; +const char *DWARFDIE::GetName() const { + if (IsValid()) + return m_die->GetName(GetDWARF(), m_cu); + else + return nullptr; } -const char * -DWARFDIE::GetPubname () const -{ - if (IsValid()) - return m_die->GetPubname (GetDWARF(), m_cu); - else - return nullptr; +const char *DWARFDIE::GetMangledName() const { + if (IsValid()) + return m_die->GetMangledName(GetDWARF(), m_cu); + else + return nullptr; } -const char * -DWARFDIE::GetQualifiedName (std::string &storage) const -{ - if (IsValid()) - return m_die->GetQualifiedName (GetDWARF(), m_cu, storage); - else - return nullptr; +const char *DWARFDIE::GetPubname() const { + if (IsValid()) + return m_die->GetPubname(GetDWARF(), m_cu); + else + return nullptr; } -lldb::LanguageType -DWARFDIE::GetLanguage () const -{ - if (IsValid()) - return m_cu->GetLanguageType(); - else - return lldb::eLanguageTypeUnknown; +const char *DWARFDIE::GetQualifiedName(std::string &storage) const { + if (IsValid()) + return m_die->GetQualifiedName(GetDWARF(), m_cu, storage); + else + return nullptr; } - -lldb::ModuleSP -DWARFDIE::GetModule () const -{ - SymbolFileDWARF *dwarf = GetDWARF(); - if (dwarf) - return dwarf->GetObjectFile()->GetModule(); - else - return lldb::ModuleSP(); +lldb::LanguageType DWARFDIE::GetLanguage() const { + if (IsValid()) + return m_cu->GetLanguageType(); + else + return lldb::eLanguageTypeUnknown; } -lldb_private::CompileUnit * -DWARFDIE::GetLLDBCompileUnit () const -{ - if (IsValid()) - return GetDWARF()->GetCompUnitForDWARFCompUnit(GetCU()); - else - return nullptr; +lldb::ModuleSP DWARFDIE::GetModule() const { + SymbolFileDWARF *dwarf = GetDWARF(); + if (dwarf) + return dwarf->GetObjectFile()->GetModule(); + else + return lldb::ModuleSP(); } -lldb_private::Type * -DWARFDIE::ResolveType () const -{ - if (IsValid()) - return GetDWARF()->ResolveType(*this, true); - else - return nullptr; +lldb_private::CompileUnit *DWARFDIE::GetLLDBCompileUnit() const { + if (IsValid()) + return GetDWARF()->GetCompUnitForDWARFCompUnit(GetCU()); + else + return nullptr; } -lldb_private::Type * -DWARFDIE::ResolveTypeUID (const DIERef &die_ref) const -{ - SymbolFileDWARF *dwarf = GetDWARF(); - if (dwarf) - return dwarf->ResolveTypeUID(dwarf->GetDIE(die_ref), true); - else - return nullptr; -} - -void -DWARFDIE::GetDeclContextDIEs (DWARFDIECollection &decl_context_dies) const -{ - if (IsValid()) - { - DWARFDIE parent_decl_ctx_die = m_die->GetParentDeclContextDIE (GetDWARF(), GetCU()); - if (parent_decl_ctx_die && parent_decl_ctx_die.GetDIE() != GetDIE()) - { - decl_context_dies.Append(parent_decl_ctx_die); - parent_decl_ctx_die.GetDeclContextDIEs (decl_context_dies); - } - } +lldb_private::Type *DWARFDIE::ResolveType() const { + if (IsValid()) + return GetDWARF()->ResolveType(*this, true); + else + return nullptr; } -void -DWARFDIE::GetDWARFDeclContext (DWARFDeclContext &dwarf_decl_ctx) const -{ - if (IsValid()) - { - dwarf_decl_ctx.SetLanguage(GetLanguage()); - m_die->GetDWARFDeclContext (GetDWARF(), GetCU(), dwarf_decl_ctx); - } - else - { - dwarf_decl_ctx.Clear(); - } +lldb_private::Type *DWARFDIE::ResolveTypeUID(const DIERef &die_ref) const { + SymbolFileDWARF *dwarf = GetDWARF(); + if (dwarf) + return dwarf->ResolveTypeUID(dwarf->GetDIE(die_ref), true); + else + return nullptr; } -void -DWARFDIE::GetDWOContext (std::vector<CompilerContext> &context) const -{ - const dw_tag_t tag = Tag(); - if (tag == DW_TAG_compile_unit) - return; - DWARFDIE parent = GetParent(); - if (parent) - parent.GetDWOContext(context); - switch (tag) - { - case DW_TAG_module: - context.push_back(CompilerContext(CompilerContextKind::Module, ConstString(GetName()))); - break; - case DW_TAG_namespace: - context.push_back(CompilerContext(CompilerContextKind::Namespace, ConstString(GetName()))); - break; - case DW_TAG_structure_type: - context.push_back(CompilerContext(CompilerContextKind::Structure, ConstString(GetName()))); - break; - case DW_TAG_union_type: - context.push_back(CompilerContext(CompilerContextKind::Union, ConstString(GetName()))); - break; - case DW_TAG_class_type: - context.push_back(CompilerContext(CompilerContextKind::Class, ConstString(GetName()))); - break; - case DW_TAG_enumeration_type: - context.push_back(CompilerContext(CompilerContextKind::Enumeration, ConstString(GetName()))); - break; - case DW_TAG_subprogram: - context.push_back(CompilerContext(CompilerContextKind::Function, ConstString(GetPubname()))); - break; - case DW_TAG_variable: - context.push_back(CompilerContext(CompilerContextKind::Variable, ConstString(GetPubname()))); - break; - case DW_TAG_typedef: - context.push_back(CompilerContext(CompilerContextKind::Typedef, ConstString(GetName()))); - break; - default: - break; +void DWARFDIE::GetDeclContextDIEs(DWARFDIECollection &decl_context_dies) const { + if (IsValid()) { + DWARFDIE parent_decl_ctx_die = + m_die->GetParentDeclContextDIE(GetDWARF(), GetCU()); + if (parent_decl_ctx_die && parent_decl_ctx_die.GetDIE() != GetDIE()) { + decl_context_dies.Append(parent_decl_ctx_die); + parent_decl_ctx_die.GetDeclContextDIEs(decl_context_dies); } + } +} + +void DWARFDIE::GetDWARFDeclContext(DWARFDeclContext &dwarf_decl_ctx) const { + if (IsValid()) { + dwarf_decl_ctx.SetLanguage(GetLanguage()); + m_die->GetDWARFDeclContext(GetDWARF(), GetCU(), dwarf_decl_ctx); + } else { + dwarf_decl_ctx.Clear(); + } +} + +void DWARFDIE::GetDWOContext(std::vector<CompilerContext> &context) const { + const dw_tag_t tag = Tag(); + if (tag == DW_TAG_compile_unit) + return; + DWARFDIE parent = GetParent(); + if (parent) + parent.GetDWOContext(context); + switch (tag) { + case DW_TAG_module: + context.push_back( + CompilerContext(CompilerContextKind::Module, ConstString(GetName()))); + break; + case DW_TAG_namespace: + context.push_back(CompilerContext(CompilerContextKind::Namespace, + ConstString(GetName()))); + break; + case DW_TAG_structure_type: + context.push_back(CompilerContext(CompilerContextKind::Structure, + ConstString(GetName()))); + break; + case DW_TAG_union_type: + context.push_back( + CompilerContext(CompilerContextKind::Union, ConstString(GetName()))); + break; + case DW_TAG_class_type: + context.push_back( + CompilerContext(CompilerContextKind::Class, ConstString(GetName()))); + break; + case DW_TAG_enumeration_type: + context.push_back(CompilerContext(CompilerContextKind::Enumeration, + ConstString(GetName()))); + break; + case DW_TAG_subprogram: + context.push_back(CompilerContext(CompilerContextKind::Function, + ConstString(GetPubname()))); + break; + case DW_TAG_variable: + context.push_back(CompilerContext(CompilerContextKind::Variable, + ConstString(GetPubname()))); + break; + case DW_TAG_typedef: + context.push_back( + CompilerContext(CompilerContextKind::Typedef, ConstString(GetName()))); + break; + default: + break; + } } - - DWARFDIE -DWARFDIE::GetParentDeclContextDIE () const -{ - if (IsValid()) - return m_die->GetParentDeclContextDIE(GetDWARF(), m_cu); - else - return DWARFDIE(); +DWARFDIE::GetParentDeclContextDIE() const { + if (IsValid()) + return m_die->GetParentDeclContextDIE(GetDWARF(), m_cu); + else + return DWARFDIE(); } - -dw_offset_t -DWARFDIE::GetOffset () const -{ - if (IsValid()) - return m_die->GetOffset(); - else - return DW_INVALID_OFFSET; +dw_offset_t DWARFDIE::GetOffset() const { + if (IsValid()) + return m_die->GetOffset(); + else + return DW_INVALID_OFFSET; } -dw_offset_t -DWARFDIE::GetCompileUnitRelativeOffset () const -{ - if (IsValid()) - return m_die->GetOffset() - m_cu->GetOffset(); - else - return DW_INVALID_OFFSET; +dw_offset_t DWARFDIE::GetCompileUnitRelativeOffset() const { + if (IsValid()) + return m_die->GetOffset() - m_cu->GetOffset(); + else + return DW_INVALID_OFFSET; } -SymbolFileDWARF * -DWARFDIE::GetDWARF () const -{ - if (m_cu) - return m_cu->GetSymbolFileDWARF(); - else - return nullptr; +SymbolFileDWARF *DWARFDIE::GetDWARF() const { + if (m_cu) + return m_cu->GetSymbolFileDWARF(); + else + return nullptr; } -lldb_private::TypeSystem * -DWARFDIE::GetTypeSystem () const -{ - if (m_cu) - return m_cu->GetTypeSystem(); - else - return nullptr; +lldb_private::TypeSystem *DWARFDIE::GetTypeSystem() const { + if (m_cu) + return m_cu->GetTypeSystem(); + else + return nullptr; } -DWARFASTParser * -DWARFDIE::GetDWARFParser () const -{ - lldb_private::TypeSystem *type_system = GetTypeSystem (); - if (type_system) - return type_system->GetDWARFParser(); - else - return nullptr; +DWARFASTParser *DWARFDIE::GetDWARFParser() const { + lldb_private::TypeSystem *type_system = GetTypeSystem(); + if (type_system) + return type_system->GetDWARFParser(); + else + return nullptr; } -bool -DWARFDIE::IsStructOrClass () const -{ - const dw_tag_t tag = Tag(); - return tag == DW_TAG_class_type || tag == DW_TAG_structure_type; +bool DWARFDIE::IsStructOrClass() const { + const dw_tag_t tag = Tag(); + return tag == DW_TAG_class_type || tag == DW_TAG_structure_type; } - DWARFDIE -DWARFDIE::GetContainingDWOModuleDIE () const -{ - if (IsValid()) - { - DWARFDIE top_module_die; - // Now make sure this DIE is scoped in a DW_TAG_module tag and return true if so - for (DWARFDIE parent = GetParent(); parent.IsValid(); parent = parent.GetParent()) - { - const dw_tag_t tag = parent.Tag(); - if (tag == DW_TAG_module) - top_module_die = parent; - else if (tag == DW_TAG_compile_unit) - break; - } - - return top_module_die; +DWARFDIE::GetContainingDWOModuleDIE() const { + if (IsValid()) { + DWARFDIE top_module_die; + // Now make sure this DIE is scoped in a DW_TAG_module tag and return true + // if so + for (DWARFDIE parent = GetParent(); parent.IsValid(); + parent = parent.GetParent()) { + const dw_tag_t tag = parent.Tag(); + if (tag == DW_TAG_module) + top_module_die = parent; + else if (tag == DW_TAG_compile_unit) + break; } - return DWARFDIE(); + + return top_module_die; + } + return DWARFDIE(); } -lldb::ModuleSP -DWARFDIE::GetContainingDWOModule () const -{ - if (IsValid()) - { - DWARFDIE dwo_module_die = GetContainingDWOModuleDIE(); +lldb::ModuleSP DWARFDIE::GetContainingDWOModule() const { + if (IsValid()) { + DWARFDIE dwo_module_die = GetContainingDWOModuleDIE(); - if (dwo_module_die) - { - const char *module_name = dwo_module_die.GetName(); - if (module_name) - return GetDWARF()->GetDWOModule (lldb_private::ConstString(module_name)); - } + if (dwo_module_die) { + const char *module_name = dwo_module_die.GetName(); + if (module_name) + return GetDWARF()->GetDWOModule(lldb_private::ConstString(module_name)); } - return lldb::ModuleSP(); + } + return lldb::ModuleSP(); } -bool -DWARFDIE::HasChildren () const -{ - if (m_die) - return m_die->HasChildren(); - else - return false; -} - -bool -DWARFDIE::Supports_DW_AT_APPLE_objc_complete_type () const -{ - if (IsValid()) - return GetDWARF()->Supports_DW_AT_APPLE_objc_complete_type(m_cu); - else - return false; -} - -size_t -DWARFDIE::GetAttributes (DWARFAttributes &attributes, uint32_t depth) const -{ - if (IsValid()) - { - return m_die->GetAttributes (m_cu, - m_cu->GetFixedFormSizes(), - attributes, - depth); - } - if (depth == 0) - attributes.Clear(); - return 0; +bool DWARFDIE::HasChildren() const { + if (m_die) + return m_die->HasChildren(); + else + return false; } - -bool -DWARFDIE::GetDIENamesAndRanges (const char * &name, - const char * &mangled, - DWARFRangeList& ranges, - int& decl_file, - int& decl_line, - int& decl_column, - int& call_file, - int& call_line, - int& call_column, - lldb_private::DWARFExpression *frame_base) const -{ - if (IsValid()) - { - return m_die->GetDIENamesAndRanges (GetDWARF(), - GetCU(), - name, - mangled, - ranges, - decl_file, - decl_line, - decl_column, - call_file, - call_line, - call_column, - frame_base); - } - else - return false; +bool DWARFDIE::Supports_DW_AT_APPLE_objc_complete_type() const { + if (IsValid()) + return GetDWARF()->Supports_DW_AT_APPLE_objc_complete_type(m_cu); + else + return false; } -void -DWARFDIE::Dump (lldb_private::Stream *s, const uint32_t recurse_depth) const -{ - if (s && IsValid()) - m_die->Dump (GetDWARF(), GetCU(), *s, recurse_depth); +size_t DWARFDIE::GetAttributes(DWARFAttributes &attributes, + uint32_t depth) const { + if (IsValid()) { + return m_die->GetAttributes(m_cu, m_cu->GetFixedFormSizes(), attributes, + depth); + } + if (depth == 0) + attributes.Clear(); + return 0; } - -CompilerDecl -DWARFDIE::GetDecl () const -{ - DWARFASTParser *dwarf_ast = GetDWARFParser(); - if (dwarf_ast) - return dwarf_ast->GetDeclForUIDFromDWARF(*this); - else - return CompilerDecl(); +bool DWARFDIE::GetDIENamesAndRanges( + const char *&name, const char *&mangled, DWARFRangeList &ranges, + int &decl_file, int &decl_line, int &decl_column, int &call_file, + int &call_line, int &call_column, + lldb_private::DWARFExpression *frame_base) const { + if (IsValid()) { + return m_die->GetDIENamesAndRanges( + GetDWARF(), GetCU(), name, mangled, ranges, decl_file, decl_line, + decl_column, call_file, call_line, call_column, frame_base); + } else + return false; } -CompilerDeclContext -DWARFDIE::GetDeclContext () const -{ - DWARFASTParser *dwarf_ast = GetDWARFParser(); - if (dwarf_ast) - return dwarf_ast->GetDeclContextForUIDFromDWARF(*this); - else - return CompilerDeclContext(); +void DWARFDIE::Dump(lldb_private::Stream *s, + const uint32_t recurse_depth) const { + if (s && IsValid()) + m_die->Dump(GetDWARF(), GetCU(), *s, recurse_depth); } -CompilerDeclContext -DWARFDIE::GetContainingDeclContext () const -{ - DWARFASTParser *dwarf_ast = GetDWARFParser(); - if (dwarf_ast) - return dwarf_ast->GetDeclContextContainingUIDFromDWARF(*this); - else - return CompilerDeclContext(); +CompilerDecl DWARFDIE::GetDecl() const { + DWARFASTParser *dwarf_ast = GetDWARFParser(); + if (dwarf_ast) + return dwarf_ast->GetDeclForUIDFromDWARF(*this); + else + return CompilerDecl(); } -bool operator == (const DWARFDIE &lhs, const DWARFDIE &rhs) -{ - return lhs.GetDIE() == rhs.GetDIE() && lhs.GetCU() == rhs.GetCU(); +CompilerDeclContext DWARFDIE::GetDeclContext() const { + DWARFASTParser *dwarf_ast = GetDWARFParser(); + if (dwarf_ast) + return dwarf_ast->GetDeclContextForUIDFromDWARF(*this); + else + return CompilerDeclContext(); } -bool operator != (const DWARFDIE &lhs, const DWARFDIE &rhs) -{ - return lhs.GetDIE() != rhs.GetDIE() || lhs.GetCU() != rhs.GetCU(); +CompilerDeclContext DWARFDIE::GetContainingDeclContext() const { + DWARFASTParser *dwarf_ast = GetDWARFParser(); + if (dwarf_ast) + return dwarf_ast->GetDeclContextContainingUIDFromDWARF(*this); + else + return CompilerDeclContext(); } +bool operator==(const DWARFDIE &lhs, const DWARFDIE &rhs) { + return lhs.GetDIE() == rhs.GetDIE() && lhs.GetCU() == rhs.GetCU(); +} +bool operator!=(const DWARFDIE &lhs, const DWARFDIE &rhs) { + return lhs.GetDIE() != rhs.GetDIE() || lhs.GetCU() != rhs.GetCU(); +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h index 2dcd1d7dc43e..8af3015b9d76 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h @@ -10,8 +10,8 @@ #ifndef SymbolFileDWARF_DWARFDIE_h_ #define SymbolFileDWARF_DWARFDIE_h_ -#include "lldb/lldb-types.h" #include "lldb/Core/dwarf.h" +#include "lldb/lldb-types.h" struct DIERef; class DWARFASTParser; @@ -22,274 +22,200 @@ class DWARFDeclContext; class DWARFDIECollection; class SymbolFileDWARF; -class DWARFDIE -{ +class DWARFDIE { public: - DWARFDIE () : - m_cu (nullptr), - m_die (nullptr) - { - } + DWARFDIE() : m_cu(nullptr), m_die(nullptr) {} - DWARFDIE (DWARFCompileUnit *cu, DWARFDebugInfoEntry *die) : - m_cu (cu), - m_die (die) - { - } + DWARFDIE(DWARFCompileUnit *cu, DWARFDebugInfoEntry *die) + : m_cu(cu), m_die(die) {} - DWARFDIE (const DWARFCompileUnit *cu, DWARFDebugInfoEntry *die) : - m_cu (const_cast<DWARFCompileUnit *>(cu)), - m_die (die) - { - } + DWARFDIE(const DWARFCompileUnit *cu, DWARFDebugInfoEntry *die) + : m_cu(const_cast<DWARFCompileUnit *>(cu)), m_die(die) {} - DWARFDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die) : - m_cu (cu), - m_die (const_cast<DWARFDebugInfoEntry *>(die)) - { - } + DWARFDIE(DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die) + : m_cu(cu), m_die(const_cast<DWARFDebugInfoEntry *>(die)) {} - DWARFDIE (const DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die) : - m_cu (const_cast<DWARFCompileUnit *>(cu)), - m_die (const_cast<DWARFDebugInfoEntry *>(die)) - { - } + DWARFDIE(const DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die) + : m_cu(const_cast<DWARFCompileUnit *>(cu)), + m_die(const_cast<DWARFDebugInfoEntry *>(die)) {} - //---------------------------------------------------------------------- - // Tests - //---------------------------------------------------------------------- - explicit operator bool () const - { - return IsValid(); - } + //---------------------------------------------------------------------- + // Tests + //---------------------------------------------------------------------- + explicit operator bool() const { return IsValid(); } - bool - IsValid() const - { - return m_cu && m_die; - } + bool IsValid() const { return m_cu && m_die; } - bool - IsStructOrClass () const; + bool IsStructOrClass() const; - bool - HasChildren () const; + bool HasChildren() const; - bool - Supports_DW_AT_APPLE_objc_complete_type () const; + bool Supports_DW_AT_APPLE_objc_complete_type() const; - //---------------------------------------------------------------------- - // Accessors - //---------------------------------------------------------------------- - SymbolFileDWARF * - GetDWARF () const; + //---------------------------------------------------------------------- + // Accessors + //---------------------------------------------------------------------- + SymbolFileDWARF *GetDWARF() const; - DWARFCompileUnit * - GetCU() const - { - return m_cu; - } + DWARFCompileUnit *GetCU() const { return m_cu; } - DWARFDebugInfoEntry * - GetDIE() const - { - return m_die; - } + DWARFDebugInfoEntry *GetDIE() const { return m_die; } - DIERef - GetDIERef() const; - - lldb_private::TypeSystem * - GetTypeSystem () const; - - DWARFASTParser * - GetDWARFParser () const; - - void - Set (DWARFCompileUnit *cu, DWARFDebugInfoEntry *die) - { - if (cu && die) - { - m_cu = cu; - m_die = die; - } - else - { - Clear(); - } - } + DIERef GetDIERef() const; - void - Clear () - { - m_cu = nullptr; - m_die = nullptr; + lldb_private::TypeSystem *GetTypeSystem() const; + + DWARFASTParser *GetDWARFParser() const; + + void Set(DWARFCompileUnit *cu, DWARFDebugInfoEntry *die) { + if (cu && die) { + m_cu = cu; + m_die = die; + } else { + Clear(); } + } + + void Clear() { + m_cu = nullptr; + m_die = nullptr; + } + + lldb::ModuleSP GetContainingDWOModule() const; - lldb::ModuleSP - GetContainingDWOModule () const; + DWARFDIE + GetContainingDWOModuleDIE() const; - DWARFDIE - GetContainingDWOModuleDIE () const; + //---------------------------------------------------------------------- + // Accessing information about a DIE + //---------------------------------------------------------------------- + dw_tag_t Tag() const; - //---------------------------------------------------------------------- - // Accessing information about a DIE - //---------------------------------------------------------------------- - dw_tag_t - Tag() const; + const char *GetTagAsCString() const; - const char * - GetTagAsCString () const; + dw_offset_t GetOffset() const; - dw_offset_t - GetOffset () const; + dw_offset_t GetCompileUnitRelativeOffset() const; - dw_offset_t - GetCompileUnitRelativeOffset () const; + //---------------------------------------------------------------------- + // Get the LLDB user ID for this DIE. This is often just the DIE offset, + // but it might have a SymbolFileDWARF::GetID() in the high 32 bits if + // we are doing Darwin DWARF in .o file, or DWARF stand alone debug + // info. + //---------------------------------------------------------------------- + lldb::user_id_t GetID() const; - //---------------------------------------------------------------------- - // Get the LLDB user ID for this DIE. This is often just the DIE offset, - // but it might have a SymbolFileDWARF::GetID() in the high 32 bits if - // we are doing Darwin DWARF in .o file, or DWARF stand alone debug - // info. - //---------------------------------------------------------------------- - lldb::user_id_t - GetID() const; + const char *GetName() const; - const char * - GetName () const; + const char *GetMangledName() const; - const char * - GetMangledName () const; + const char *GetPubname() const; - const char * - GetPubname () const; + const char *GetQualifiedName(std::string &storage) const; - const char * - GetQualifiedName (std::string &storage) const; + lldb::LanguageType GetLanguage() const; - lldb::LanguageType - GetLanguage () const; + lldb::ModuleSP GetModule() const; - lldb::ModuleSP - GetModule () const; + lldb_private::CompileUnit *GetLLDBCompileUnit() const; - lldb_private::CompileUnit * - GetLLDBCompileUnit () const; + lldb_private::Type *ResolveType() const; - lldb_private::Type * - ResolveType () const; + //---------------------------------------------------------------------- + // Resolve a type by UID using this DIE's DWARF file + //---------------------------------------------------------------------- + lldb_private::Type *ResolveTypeUID(const DIERef &die_ref) const; - //---------------------------------------------------------------------- - // Resolve a type by UID using this DIE's DWARF file - //---------------------------------------------------------------------- - lldb_private::Type * - ResolveTypeUID (const DIERef &die_ref) const; + //---------------------------------------------------------------------- + // Functions for obtaining DIE relations and references + //---------------------------------------------------------------------- - //---------------------------------------------------------------------- - // Functions for obtaining DIE relations and references - //---------------------------------------------------------------------- + DWARFDIE + GetParent() const; - DWARFDIE - GetParent () const; + DWARFDIE + GetFirstChild() const; - DWARFDIE - GetFirstChild () const; + DWARFDIE + GetSibling() const; - DWARFDIE - GetSibling () const; + DWARFDIE + GetReferencedDIE(const dw_attr_t attr) const; - DWARFDIE - GetReferencedDIE (const dw_attr_t attr) const; + //---------------------------------------------------------------------- + // Get a another DIE from the same DWARF file as this DIE. This will + // check the current DIE's compile unit first to see if "die_offset" is + // in the same compile unit, and fall back to checking the DWARF file. + //---------------------------------------------------------------------- + DWARFDIE + GetDIE(dw_offset_t die_offset) const; - //---------------------------------------------------------------------- - // Get a another DIE from the same DWARF file as this DIE. This will - // check the current DIE's compile unit first to see if "die_offset" is - // in the same compile unit, and fall back to checking the DWARF file. - //---------------------------------------------------------------------- - DWARFDIE - GetDIE (dw_offset_t die_offset) const; + DWARFDIE + LookupDeepestBlock(lldb::addr_t file_addr) const; - DWARFDIE - LookupDeepestBlock (lldb::addr_t file_addr) const; + DWARFDIE + GetParentDeclContextDIE() const; - DWARFDIE - GetParentDeclContextDIE () const; + //---------------------------------------------------------------------- + // DeclContext related functions + //---------------------------------------------------------------------- + void GetDeclContextDIEs(DWARFDIECollection &decl_context_dies) const; - //---------------------------------------------------------------------- - // DeclContext related functions - //---------------------------------------------------------------------- - void - GetDeclContextDIEs (DWARFDIECollection &decl_context_dies) const; + void GetDWARFDeclContext(DWARFDeclContext &dwarf_decl_ctx) const; - void - GetDWARFDeclContext (DWARFDeclContext &dwarf_decl_ctx) const; + void GetDWOContext(std::vector<lldb_private::CompilerContext> &context) const; - void - GetDWOContext (std::vector<lldb_private::CompilerContext> &context) const; + //---------------------------------------------------------------------- + // Getting attribute values from the DIE. + // + // GetAttributeValueAsXXX() functions should only be used if you are + // looking for one or two attributes on a DIE. If you are trying to + // parse all attributes, use GetAttributes (...) instead + //---------------------------------------------------------------------- + const char *GetAttributeValueAsString(const dw_attr_t attr, + const char *fail_value) const; - //---------------------------------------------------------------------- - // Getting attribute values from the DIE. - // - // GetAttributeValueAsXXX() functions should only be used if you are - // looking for one or two attributes on a DIE. If you are trying to - // parse all attributes, use GetAttributes (...) instead - //---------------------------------------------------------------------- - const char * - GetAttributeValueAsString (const dw_attr_t attr, const char *fail_value) const; + uint64_t GetAttributeValueAsUnsigned(const dw_attr_t attr, + uint64_t fail_value) const; - uint64_t - GetAttributeValueAsUnsigned (const dw_attr_t attr, uint64_t fail_value) const; + int64_t GetAttributeValueAsSigned(const dw_attr_t attr, + int64_t fail_value) const; - int64_t - GetAttributeValueAsSigned (const dw_attr_t attr, int64_t fail_value) const; + uint64_t GetAttributeValueAsReference(const dw_attr_t attr, + uint64_t fail_value) const; - uint64_t - GetAttributeValueAsReference (const dw_attr_t attr, uint64_t fail_value) const; + DWARFDIE + GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const; - DWARFDIE - GetAttributeValueAsReferenceDIE (const dw_attr_t attr) const; + uint64_t GetAttributeValueAsAddress(const dw_attr_t attr, + uint64_t fail_value) const; - uint64_t - GetAttributeValueAsAddress (const dw_attr_t attr, uint64_t fail_value) const; + size_t GetAttributes(DWARFAttributes &attributes, uint32_t depth = 0) const; - size_t - GetAttributes (DWARFAttributes &attributes, uint32_t depth = 0) const; + bool GetDIENamesAndRanges(const char *&name, const char *&mangled, + DWARFRangeList &ranges, int &decl_file, + int &decl_line, int &decl_column, int &call_file, + int &call_line, int &call_column, + lldb_private::DWARFExpression *frame_base) const; - bool - GetDIENamesAndRanges (const char * &name, - const char * &mangled, - DWARFRangeList& ranges, - int& decl_file, - int& decl_line, - int& decl_column, - int& call_file, - int& call_line, - int& call_column, - lldb_private::DWARFExpression *frame_base) const; + //---------------------------------------------------------------------- + // Pretty printing + //---------------------------------------------------------------------- - //---------------------------------------------------------------------- - // Pretty printing - //---------------------------------------------------------------------- + void Dump(lldb_private::Stream *s, const uint32_t recurse_depth) const; - void - Dump (lldb_private::Stream *s, const uint32_t recurse_depth) const; + lldb_private::CompilerDecl GetDecl() const; - lldb_private::CompilerDecl - GetDecl () const; + lldb_private::CompilerDeclContext GetDeclContext() const; - lldb_private::CompilerDeclContext - GetDeclContext() const; - - lldb_private::CompilerDeclContext - GetContainingDeclContext() const; + lldb_private::CompilerDeclContext GetContainingDeclContext() const; protected: - DWARFCompileUnit *m_cu; - DWARFDebugInfoEntry *m_die; + DWARFCompileUnit *m_cu; + DWARFDebugInfoEntry *m_die; }; -bool operator == (const DWARFDIE &lhs, const DWARFDIE &rhs); -bool operator != (const DWARFDIE &lhs, const DWARFDIE &rhs); +bool operator==(const DWARFDIE &lhs, const DWARFDIE &rhs); +bool operator!=(const DWARFDIE &lhs, const DWARFDIE &rhs); -#endif // SymbolFileDWARF_DWARFDIE_h_ +#endif // SymbolFileDWARF_DWARFDIE_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.cpp index e9f09fd8776c..5fb63589591e 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.cpp @@ -16,32 +16,20 @@ using namespace lldb_private; using namespace std; -void -DWARFDIECollection::Append (const DWARFDIE &die) -{ - m_dies.push_back (die); -} +void DWARFDIECollection::Append(const DWARFDIE &die) { m_dies.push_back(die); } DWARFDIE -DWARFDIECollection::GetDIEAtIndex(uint32_t idx) const -{ - if (idx < m_dies.size()) - return m_dies[idx]; - return DWARFDIE(); +DWARFDIECollection::GetDIEAtIndex(uint32_t idx) const { + if (idx < m_dies.size()) + return m_dies[idx]; + return DWARFDIE(); } +size_t DWARFDIECollection::Size() const { return m_dies.size(); } -size_t -DWARFDIECollection::Size() const -{ - return m_dies.size(); -} - -void -DWARFDIECollection::Dump(Stream *s, const char* title) const -{ - if (title && title[0] != '\0') - s->Printf( "%s\n", title); - for (const auto &die : m_dies) - s->Printf( "0x%8.8x\n", die.GetOffset()); +void DWARFDIECollection::Dump(Stream *s, const char *title) const { + if (title && title[0] != '\0') + s->Printf("%s\n", title); + for (const auto &die : m_dies) + s->Printf("0x%8.8x\n", die.GetOffset()); } diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.h index 83d58ec49300..e1e73e71ae7f 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.h @@ -13,36 +13,26 @@ #include "DWARFDIE.h" #include <vector> -class DWARFDIECollection -{ +class DWARFDIECollection { public: - DWARFDIECollection() : - m_dies() - { - } - ~DWARFDIECollection() - { - } + DWARFDIECollection() : m_dies() {} + ~DWARFDIECollection() {} - void - Append (const DWARFDIE &die); + void Append(const DWARFDIE &die); - void - Dump(lldb_private::Stream *s, const char* title) const; + void Dump(lldb_private::Stream *s, const char *title) const; - DWARFDIE - GetDIEAtIndex (uint32_t idx) const; + DWARFDIE + GetDIEAtIndex(uint32_t idx) const; - size_t - Size() const; + size_t Size() const; protected: - typedef std::vector<DWARFDIE> collection; - typedef collection::iterator iterator; - typedef collection::const_iterator const_iterator; + typedef std::vector<DWARFDIE> collection; + typedef collection::iterator iterator; + typedef collection::const_iterator const_iterator; - collection m_dies; // Ordered list of die offsets + collection m_dies; // Ordered list of die offsets }; - -#endif // SymbolFileDWARF_DWARFDIECollection_h_ +#endif // SymbolFileDWARF_DWARFDIECollection_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp index 9bf47cd7a9ac..0c807d7d604b 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp @@ -12,19 +12,16 @@ namespace lldb_private { uint64_t -DWARFDataExtractor::GetDWARFInitialLength(lldb::offset_t *offset_ptr) const -{ - uint64_t length = GetU32(offset_ptr); - m_is_dwarf64 = (length == UINT32_MAX); - if (m_is_dwarf64) - length = GetU64(offset_ptr); - return length; +DWARFDataExtractor::GetDWARFInitialLength(lldb::offset_t *offset_ptr) const { + uint64_t length = GetU32(offset_ptr); + m_is_dwarf64 = (length == UINT32_MAX); + if (m_is_dwarf64) + length = GetU64(offset_ptr); + return length; } dw_offset_t -DWARFDataExtractor::GetDWARFOffset(lldb::offset_t *offset_ptr) const -{ - return GetMaxU64(offset_ptr, m_is_dwarf64 ? 8 : 4); +DWARFDataExtractor::GetDWARFOffset(lldb::offset_t *offset_ptr) const { + return GetMaxU64(offset_ptr, m_is_dwarf64 ? 8 : 4); } - } diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h index 0281b5ad5c89..62ddbe8ecd5a 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DWARFDataExtractor_h_ -#define liblldb_DWARFDataExtractor_h_ +#ifndef liblldb_DWARFDataExtractor_h_ +#define liblldb_DWARFDataExtractor_h_ // Other libraries and framework includes. #include "lldb/Core/DataExtractor.h" @@ -16,30 +16,25 @@ namespace lldb_private { -class DWARFDataExtractor : public lldb_private::DataExtractor -{ +class DWARFDataExtractor : public lldb_private::DataExtractor { public: - DWARFDataExtractor() : DataExtractor(), m_is_dwarf64(false) { } + DWARFDataExtractor() : DataExtractor(), m_is_dwarf64(false) {} - DWARFDataExtractor (const DWARFDataExtractor& data, lldb::offset_t offset, lldb::offset_t length) : - DataExtractor(data, offset, length), m_is_dwarf64(false) { } + DWARFDataExtractor(const DWARFDataExtractor &data, lldb::offset_t offset, + lldb::offset_t length) + : DataExtractor(data, offset, length), m_is_dwarf64(false) {} - uint64_t - GetDWARFInitialLength(lldb::offset_t *offset_ptr) const; + uint64_t GetDWARFInitialLength(lldb::offset_t *offset_ptr) const; - dw_offset_t - GetDWARFOffset(lldb::offset_t *offset_ptr) const; + dw_offset_t GetDWARFOffset(lldb::offset_t *offset_ptr) const; - size_t - GetDWARFSizeofInitialLength() const { return m_is_dwarf64 ? 12 : 4; } + size_t GetDWARFSizeofInitialLength() const { return m_is_dwarf64 ? 12 : 4; } - bool - IsDWARF64() const { return m_is_dwarf64; } + bool IsDWARF64() const { return m_is_dwarf64; } protected: - mutable bool m_is_dwarf64; + mutable bool m_is_dwarf64; }; - } -#endif // liblldb_DWARFDataExtractor_h_ +#endif // liblldb_DWARFDataExtractor_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp index 6773d0762a21..fe6df913b762 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp @@ -18,74 +18,63 @@ using namespace std; //---------------------------------------------------------------------- // DWARFAbbreviationDeclarationSet::Clear() //---------------------------------------------------------------------- -void -DWARFAbbreviationDeclarationSet::Clear() -{ - m_idx_offset = 0; - m_decls.clear(); +void DWARFAbbreviationDeclarationSet::Clear() { + m_idx_offset = 0; + m_decls.clear(); } - //---------------------------------------------------------------------- // DWARFAbbreviationDeclarationSet::Extract() //---------------------------------------------------------------------- -bool -DWARFAbbreviationDeclarationSet::Extract(const DWARFDataExtractor& data, lldb::offset_t *offset_ptr) -{ - const lldb::offset_t begin_offset = *offset_ptr; - m_offset = begin_offset; - Clear(); - DWARFAbbreviationDeclaration abbrevDeclaration; - dw_uleb128_t prev_abbr_code = 0; - while (abbrevDeclaration.Extract(data, offset_ptr)) - { - m_decls.push_back(abbrevDeclaration); - if (m_idx_offset == 0) - m_idx_offset = abbrevDeclaration.Code(); - else - { - if (prev_abbr_code + 1 != abbrevDeclaration.Code()) - m_idx_offset = UINT32_MAX; // Out of order indexes, we can't do O(1) lookups... - } - prev_abbr_code = abbrevDeclaration.Code(); +bool DWARFAbbreviationDeclarationSet::Extract(const DWARFDataExtractor &data, + lldb::offset_t *offset_ptr) { + const lldb::offset_t begin_offset = *offset_ptr; + m_offset = begin_offset; + Clear(); + DWARFAbbreviationDeclaration abbrevDeclaration; + dw_uleb128_t prev_abbr_code = 0; + while (abbrevDeclaration.Extract(data, offset_ptr)) { + m_decls.push_back(abbrevDeclaration); + if (m_idx_offset == 0) + m_idx_offset = abbrevDeclaration.Code(); + else { + if (prev_abbr_code + 1 != abbrevDeclaration.Code()) + m_idx_offset = + UINT32_MAX; // Out of order indexes, we can't do O(1) lookups... } - return begin_offset != *offset_ptr; + prev_abbr_code = abbrevDeclaration.Code(); + } + return begin_offset != *offset_ptr; } - //---------------------------------------------------------------------- // DWARFAbbreviationDeclarationSet::Dump() //---------------------------------------------------------------------- -void -DWARFAbbreviationDeclarationSet::Dump(Stream *s) const -{ - std::for_each (m_decls.begin(), m_decls.end(), bind2nd(std::mem_fun_ref(&DWARFAbbreviationDeclaration::Dump),s)); +void DWARFAbbreviationDeclarationSet::Dump(Stream *s) const { + std::for_each( + m_decls.begin(), m_decls.end(), + bind2nd(std::mem_fun_ref(&DWARFAbbreviationDeclaration::Dump), s)); } - //---------------------------------------------------------------------- // DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration() //---------------------------------------------------------------------- -const DWARFAbbreviationDeclaration* -DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration(dw_uleb128_t abbrCode) const -{ - if (m_idx_offset == UINT32_MAX) - { - DWARFAbbreviationDeclarationCollConstIter pos; - DWARFAbbreviationDeclarationCollConstIter end = m_decls.end(); - for (pos = m_decls.begin(); pos != end; ++pos) - { - if (pos->Code() == abbrCode) - return &(*pos); - } - } - else - { - uint32_t idx = abbrCode - m_idx_offset; - if (idx < m_decls.size()) - return &m_decls[idx]; +const DWARFAbbreviationDeclaration * +DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration( + dw_uleb128_t abbrCode) const { + if (m_idx_offset == UINT32_MAX) { + DWARFAbbreviationDeclarationCollConstIter pos; + DWARFAbbreviationDeclarationCollConstIter end = m_decls.end(); + for (pos = m_decls.begin(); pos != end; ++pos) { + if (pos->Code() == abbrCode) + return &(*pos); } - return NULL; + } else { + uint32_t idx = abbrCode - m_idx_offset; + if (idx < m_decls.size()) + return &m_decls[idx]; + } + return NULL; } //---------------------------------------------------------------------- @@ -94,22 +83,20 @@ DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration(dw_uleb128_t abbrCod // Append an abbreviation declaration with a sequential code for O(n) // lookups. Handy when creating an DWARFAbbreviationDeclarationSet. //---------------------------------------------------------------------- -dw_uleb128_t -DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential(const DWARFAbbreviationDeclaration& abbrevDecl) -{ - // Get the next abbreviation code based on our current array size - dw_uleb128_t code = m_decls.size()+1; +dw_uleb128_t DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential( + const DWARFAbbreviationDeclaration &abbrevDecl) { + // Get the next abbreviation code based on our current array size + dw_uleb128_t code = m_decls.size() + 1; - // Push the new declaration on the back - m_decls.push_back(abbrevDecl); + // Push the new declaration on the back + m_decls.push_back(abbrevDecl); - // Update the code for this new declaration - m_decls.back().SetCode(code); + // Update the code for this new declaration + m_decls.back().SetCode(code); - return code; // return the new abbreviation code! + return code; // return the new abbreviation code! } - //---------------------------------------------------------------------- // Encode // @@ -117,8 +104,9 @@ DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential(const DWARFAbbreviat // into a byte representation as would be found in a ".debug_abbrev" // debug information section. //---------------------------------------------------------------------- -//void -//DWARFAbbreviationDeclarationSet::Encode(BinaryStreamBuf& debug_abbrev_buf) const +// void +// DWARFAbbreviationDeclarationSet::Encode(BinaryStreamBuf& debug_abbrev_buf) +// const //{ // DWARFAbbreviationDeclarationCollConstIter pos; // DWARFAbbreviationDeclarationCollConstIter end = m_decls.end(); @@ -127,76 +115,63 @@ DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential(const DWARFAbbreviat // debug_abbrev_buf.Append8(0); //} - //---------------------------------------------------------------------- // DWARFDebugAbbrev constructor //---------------------------------------------------------------------- -DWARFDebugAbbrev::DWARFDebugAbbrev() : - m_abbrevCollMap(), - m_prev_abbr_offset_pos(m_abbrevCollMap.end()) -{ -} - +DWARFDebugAbbrev::DWARFDebugAbbrev() + : m_abbrevCollMap(), m_prev_abbr_offset_pos(m_abbrevCollMap.end()) {} //---------------------------------------------------------------------- // DWARFDebugAbbrev::Parse() //---------------------------------------------------------------------- -void -DWARFDebugAbbrev::Parse(const DWARFDataExtractor& data) -{ - lldb::offset_t offset = 0; +void DWARFDebugAbbrev::Parse(const DWARFDataExtractor &data) { + lldb::offset_t offset = 0; - while (data.ValidOffset(offset)) - { - uint32_t initial_cu_offset = offset; - DWARFAbbreviationDeclarationSet abbrevDeclSet; + while (data.ValidOffset(offset)) { + uint32_t initial_cu_offset = offset; + DWARFAbbreviationDeclarationSet abbrevDeclSet; - if (abbrevDeclSet.Extract(data, &offset)) - m_abbrevCollMap[initial_cu_offset] = abbrevDeclSet; - else - break; - } - m_prev_abbr_offset_pos = m_abbrevCollMap.end(); + if (abbrevDeclSet.Extract(data, &offset)) + m_abbrevCollMap[initial_cu_offset] = abbrevDeclSet; + else + break; + } + m_prev_abbr_offset_pos = m_abbrevCollMap.end(); } //---------------------------------------------------------------------- // DWARFDebugAbbrev::Dump() //---------------------------------------------------------------------- -void -DWARFDebugAbbrev::Dump(Stream *s) const -{ - if (m_abbrevCollMap.empty()) - { - s->PutCString("< EMPTY >\n"); - return; - } - - DWARFAbbreviationDeclarationCollMapConstIter pos; - for (pos = m_abbrevCollMap.begin(); pos != m_abbrevCollMap.end(); ++pos) - { - s->Printf("Abbrev table for offset: 0x%8.8x\n", pos->first); - pos->second.Dump(s); - } +void DWARFDebugAbbrev::Dump(Stream *s) const { + if (m_abbrevCollMap.empty()) { + s->PutCString("< EMPTY >\n"); + return; + } + + DWARFAbbreviationDeclarationCollMapConstIter pos; + for (pos = m_abbrevCollMap.begin(); pos != m_abbrevCollMap.end(); ++pos) { + s->Printf("Abbrev table for offset: 0x%8.8x\n", pos->first); + pos->second.Dump(s); + } } - //---------------------------------------------------------------------- // DWARFDebugAbbrev::GetAbbreviationDeclarationSet() //---------------------------------------------------------------------- -const DWARFAbbreviationDeclarationSet* -DWARFDebugAbbrev::GetAbbreviationDeclarationSet(dw_offset_t cu_abbr_offset) const -{ - DWARFAbbreviationDeclarationCollMapConstIter end = m_abbrevCollMap.end(); - DWARFAbbreviationDeclarationCollMapConstIter pos; - if (m_prev_abbr_offset_pos != end && m_prev_abbr_offset_pos->first == cu_abbr_offset) - return &(m_prev_abbr_offset_pos->second); - else - { - pos = m_abbrevCollMap.find(cu_abbr_offset); - m_prev_abbr_offset_pos = pos; - } - - if (pos != m_abbrevCollMap.end()) - return &(pos->second); - return NULL; +const DWARFAbbreviationDeclarationSet * +DWARFDebugAbbrev::GetAbbreviationDeclarationSet( + dw_offset_t cu_abbr_offset) const { + DWARFAbbreviationDeclarationCollMapConstIter end = m_abbrevCollMap.end(); + DWARFAbbreviationDeclarationCollMapConstIter pos; + if (m_prev_abbr_offset_pos != end && + m_prev_abbr_offset_pos->first == cu_abbr_offset) + return &(m_prev_abbr_offset_pos->second); + else { + pos = m_abbrevCollMap.find(cu_abbr_offset); + m_prev_abbr_offset_pos = pos; + } + + if (pos != m_abbrevCollMap.end()) + return &(pos->second); + return NULL; } diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h index 8ec2c4ba8e21..137c81780513 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h @@ -15,60 +15,60 @@ #include "lldb/lldb-private.h" -#include "DWARFDefines.h" #include "DWARFAbbreviationDeclaration.h" +#include "DWARFDefines.h" -typedef std::vector<DWARFAbbreviationDeclaration> DWARFAbbreviationDeclarationColl; -typedef DWARFAbbreviationDeclarationColl::iterator DWARFAbbreviationDeclarationCollIter; -typedef DWARFAbbreviationDeclarationColl::const_iterator DWARFAbbreviationDeclarationCollConstIter; - +typedef std::vector<DWARFAbbreviationDeclaration> + DWARFAbbreviationDeclarationColl; +typedef DWARFAbbreviationDeclarationColl::iterator + DWARFAbbreviationDeclarationCollIter; +typedef DWARFAbbreviationDeclarationColl::const_iterator + DWARFAbbreviationDeclarationCollConstIter; -class DWARFAbbreviationDeclarationSet -{ +class DWARFAbbreviationDeclarationSet { public: - DWARFAbbreviationDeclarationSet() : - m_offset(DW_INVALID_OFFSET), - m_idx_offset(0), - m_decls() - { - } + DWARFAbbreviationDeclarationSet() + : m_offset(DW_INVALID_OFFSET), m_idx_offset(0), m_decls() {} - DWARFAbbreviationDeclarationSet(dw_offset_t offset, uint32_t idx_offset) : - m_offset(offset), - m_idx_offset(idx_offset), - m_decls() - { - } + DWARFAbbreviationDeclarationSet(dw_offset_t offset, uint32_t idx_offset) + : m_offset(offset), m_idx_offset(idx_offset), m_decls() {} - void Clear(); - dw_offset_t GetOffset() const { return m_offset; } - void Dump(lldb_private::Stream *s) const; - bool Extract(const lldb_private::DWARFDataExtractor& data, lldb::offset_t *offset_ptr); - //void Encode(BinaryStreamBuf& debug_abbrev_buf) const; - dw_uleb128_t AppendAbbrevDeclSequential(const DWARFAbbreviationDeclaration& abbrevDecl); + void Clear(); + dw_offset_t GetOffset() const { return m_offset; } + void Dump(lldb_private::Stream *s) const; + bool Extract(const lldb_private::DWARFDataExtractor &data, + lldb::offset_t *offset_ptr); + // void Encode(BinaryStreamBuf& debug_abbrev_buf) const; + dw_uleb128_t + AppendAbbrevDeclSequential(const DWARFAbbreviationDeclaration &abbrevDecl); + + const DWARFAbbreviationDeclaration * + GetAbbreviationDeclaration(dw_uleb128_t abbrCode) const; - const DWARFAbbreviationDeclaration* GetAbbreviationDeclaration(dw_uleb128_t abbrCode) const; private: - dw_offset_t m_offset; - uint32_t m_idx_offset; - std::vector<DWARFAbbreviationDeclaration> m_decls; + dw_offset_t m_offset; + uint32_t m_idx_offset; + std::vector<DWARFAbbreviationDeclaration> m_decls; }; -typedef std::map<dw_offset_t, DWARFAbbreviationDeclarationSet> DWARFAbbreviationDeclarationCollMap; -typedef DWARFAbbreviationDeclarationCollMap::iterator DWARFAbbreviationDeclarationCollMapIter; -typedef DWARFAbbreviationDeclarationCollMap::const_iterator DWARFAbbreviationDeclarationCollMapConstIter; - +typedef std::map<dw_offset_t, DWARFAbbreviationDeclarationSet> + DWARFAbbreviationDeclarationCollMap; +typedef DWARFAbbreviationDeclarationCollMap::iterator + DWARFAbbreviationDeclarationCollMapIter; +typedef DWARFAbbreviationDeclarationCollMap::const_iterator + DWARFAbbreviationDeclarationCollMapConstIter; -class DWARFDebugAbbrev -{ +class DWARFDebugAbbrev { public: - DWARFDebugAbbrev(); - const DWARFAbbreviationDeclarationSet* GetAbbreviationDeclarationSet(dw_offset_t cu_abbr_offset) const; - void Dump(lldb_private::Stream *s) const; - void Parse(const lldb_private::DWARFDataExtractor& data); + DWARFDebugAbbrev(); + const DWARFAbbreviationDeclarationSet * + GetAbbreviationDeclarationSet(dw_offset_t cu_abbr_offset) const; + void Dump(lldb_private::Stream *s) const; + void Parse(const lldb_private::DWARFDataExtractor &data); + protected: - DWARFAbbreviationDeclarationCollMap m_abbrevCollMap; - mutable DWARFAbbreviationDeclarationCollMapConstIter m_prev_abbr_offset_pos; + DWARFAbbreviationDeclarationCollMap m_abbrevCollMap; + mutable DWARFAbbreviationDeclarationCollMapConstIter m_prev_abbr_offset_pos; }; -#endif // SymbolFileDWARF_DWARFDebugAbbrev_h_ +#endif // SymbolFileDWARF_DWARFDebugAbbrev_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp index b0b71368b800..06b46f0569eb 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp @@ -9,302 +9,262 @@ #include "DWARFDebugArangeSet.h" -#include <assert.h> -#include "lldb/Core/Stream.h" #include "SymbolFileDWARF.h" +#include "lldb/Core/Stream.h" +#include <assert.h> using namespace lldb_private; -DWARFDebugArangeSet::DWARFDebugArangeSet() : - m_offset(DW_INVALID_OFFSET), - m_header(), - m_arange_descriptors() -{ - m_header.length = 0; - m_header.version = 0; - m_header.cu_offset = 0; - m_header.addr_size = 0; - m_header.seg_size = 0; +DWARFDebugArangeSet::DWARFDebugArangeSet() + : m_offset(DW_INVALID_OFFSET), m_header(), m_arange_descriptors() { + m_header.length = 0; + m_header.version = 0; + m_header.cu_offset = 0; + m_header.addr_size = 0; + m_header.seg_size = 0; } -void -DWARFDebugArangeSet::Clear() -{ - m_offset = DW_INVALID_OFFSET; - m_header.length = 0; - m_header.version = 0; - m_header.cu_offset = 0; - m_header.addr_size = 0; - m_header.seg_size = 0; - m_arange_descriptors.clear(); +void DWARFDebugArangeSet::Clear() { + m_offset = DW_INVALID_OFFSET; + m_header.length = 0; + m_header.version = 0; + m_header.cu_offset = 0; + m_header.addr_size = 0; + m_header.seg_size = 0; + m_arange_descriptors.clear(); } -void -DWARFDebugArangeSet::SetHeader -( - uint16_t version, - uint32_t cu_offset, - uint8_t addr_size, - uint8_t seg_size -) -{ - m_header.version = version; - m_header.cu_offset = cu_offset; - m_header.addr_size = addr_size; - m_header.seg_size = seg_size; +void DWARFDebugArangeSet::SetHeader(uint16_t version, uint32_t cu_offset, + uint8_t addr_size, uint8_t seg_size) { + m_header.version = version; + m_header.cu_offset = cu_offset; + m_header.addr_size = addr_size; + m_header.seg_size = seg_size; } -void -DWARFDebugArangeSet::Compact() -{ - if (m_arange_descriptors.empty()) - return; +void DWARFDebugArangeSet::Compact() { + if (m_arange_descriptors.empty()) + return; - // Iterate through all arange descriptors and combine any ranges that - // overlap or have matching boundaries. The m_arange_descriptors are assumed - // to be in ascending order after being built by adding descriptors - // using the AddDescriptor method. - uint32_t i = 0; - while (i + 1 < m_arange_descriptors.size()) - { - if (m_arange_descriptors[i].end_address() >= m_arange_descriptors[i+1].address) - { - // The current range ends at or exceeds the start of the next address range. - // Compute the max end address between the two and use that to make the new - // length. - const dw_addr_t max_end_addr = std::max(m_arange_descriptors[i].end_address(), m_arange_descriptors[i+1].end_address()); - m_arange_descriptors[i].length = max_end_addr - m_arange_descriptors[i].address; - // Now remove the next entry as it was just combined with the previous one. - m_arange_descriptors.erase(m_arange_descriptors.begin()+i+1); - } - else - { - // Discontiguous address range, just proceed to the next one. - ++i; - } + // Iterate through all arange descriptors and combine any ranges that + // overlap or have matching boundaries. The m_arange_descriptors are assumed + // to be in ascending order after being built by adding descriptors + // using the AddDescriptor method. + uint32_t i = 0; + while (i + 1 < m_arange_descriptors.size()) { + if (m_arange_descriptors[i].end_address() >= + m_arange_descriptors[i + 1].address) { + // The current range ends at or exceeds the start of the next address + // range. + // Compute the max end address between the two and use that to make the + // new + // length. + const dw_addr_t max_end_addr = + std::max(m_arange_descriptors[i].end_address(), + m_arange_descriptors[i + 1].end_address()); + m_arange_descriptors[i].length = + max_end_addr - m_arange_descriptors[i].address; + // Now remove the next entry as it was just combined with the previous + // one. + m_arange_descriptors.erase(m_arange_descriptors.begin() + i + 1); + } else { + // Discontiguous address range, just proceed to the next one. + ++i; } + } } //---------------------------------------------------------------------- // Compare function DWARFDebugArangeSet::Descriptor structures //---------------------------------------------------------------------- -static bool DescriptorLessThan (const DWARFDebugArangeSet::Descriptor& range1, const DWARFDebugArangeSet::Descriptor& range2) -{ - return range1.address < range2.address; +static bool DescriptorLessThan(const DWARFDebugArangeSet::Descriptor &range1, + const DWARFDebugArangeSet::Descriptor &range2) { + return range1.address < range2.address; } //---------------------------------------------------------------------- // Add a range descriptor and keep things sorted so we can easily // compact the ranges before being saved or used. //---------------------------------------------------------------------- -void -DWARFDebugArangeSet::AddDescriptor(const DWARFDebugArangeSet::Descriptor& range) -{ - if (m_arange_descriptors.empty()) - { - m_arange_descriptors.push_back(range); - return; - } +void DWARFDebugArangeSet::AddDescriptor( + const DWARFDebugArangeSet::Descriptor &range) { + if (m_arange_descriptors.empty()) { + m_arange_descriptors.push_back(range); + return; + } - DescriptorIter end = m_arange_descriptors.end(); - DescriptorIter pos = lower_bound(m_arange_descriptors.begin(), end, range, DescriptorLessThan); - const dw_addr_t range_end_addr = range.end_address(); - if (pos != end) - { - const dw_addr_t found_end_addr = pos->end_address(); - if (range.address < pos->address) - { - if (range_end_addr < pos->address) - { - // Non-contiguous entries, add this one before the found entry - m_arange_descriptors.insert(pos, range); - } - else if (range_end_addr == pos->address) - { - // The top end of 'range' is the lower end of the entry - // pointed to by 'pos'. We can combine range with the - // entry we found by setting the starting address and - // increasing the length since they don't overlap. - pos->address = range.address; - pos->length += range.length; - } - else - { - // We can combine these two and make sure the largest end - // address is used to make end address. - pos->address = range.address; - pos->length = std::max(found_end_addr, range_end_addr) - pos->address; - } - } - else if (range.address == pos->address) - { - pos->length = std::max(pos->length, range.length); - } + DescriptorIter end = m_arange_descriptors.end(); + DescriptorIter pos = + lower_bound(m_arange_descriptors.begin(), end, range, DescriptorLessThan); + const dw_addr_t range_end_addr = range.end_address(); + if (pos != end) { + const dw_addr_t found_end_addr = pos->end_address(); + if (range.address < pos->address) { + if (range_end_addr < pos->address) { + // Non-contiguous entries, add this one before the found entry + m_arange_descriptors.insert(pos, range); + } else if (range_end_addr == pos->address) { + // The top end of 'range' is the lower end of the entry + // pointed to by 'pos'. We can combine range with the + // entry we found by setting the starting address and + // increasing the length since they don't overlap. + pos->address = range.address; + pos->length += range.length; + } else { + // We can combine these two and make sure the largest end + // address is used to make end address. + pos->address = range.address; + pos->length = std::max(found_end_addr, range_end_addr) - pos->address; + } + } else if (range.address == pos->address) { + pos->length = std::max(pos->length, range.length); } - else - { - // NOTE: 'pos' points to entry past the end which is ok for insert, - // don't use otherwise!!! - const dw_addr_t max_addr = m_arange_descriptors.back().end_address(); - if (max_addr < range.address) - { - // Non-contiguous entries, add this one before the found entry - m_arange_descriptors.insert(pos, range); - } - else if (max_addr == range.address) - { - m_arange_descriptors.back().length += range.length; - } - else - { - m_arange_descriptors.back().length = std::max(max_addr, range_end_addr) - m_arange_descriptors.back().address; - } + } else { + // NOTE: 'pos' points to entry past the end which is ok for insert, + // don't use otherwise!!! + const dw_addr_t max_addr = m_arange_descriptors.back().end_address(); + if (max_addr < range.address) { + // Non-contiguous entries, add this one before the found entry + m_arange_descriptors.insert(pos, range); + } else if (max_addr == range.address) { + m_arange_descriptors.back().length += range.length; + } else { + m_arange_descriptors.back().length = std::max(max_addr, range_end_addr) - + m_arange_descriptors.back().address; } + } } -bool -DWARFDebugArangeSet::Extract(const DWARFDataExtractor &data, lldb::offset_t *offset_ptr) -{ - if (data.ValidOffset(*offset_ptr)) - { - m_arange_descriptors.clear(); - m_offset = *offset_ptr; +bool DWARFDebugArangeSet::Extract(const DWARFDataExtractor &data, + lldb::offset_t *offset_ptr) { + if (data.ValidOffset(*offset_ptr)) { + m_arange_descriptors.clear(); + m_offset = *offset_ptr; - // 7.20 Address Range Table - // - // Each set of entries in the table of address ranges contained in - // the .debug_aranges section begins with a header consisting of: a - // 4-byte length containing the length of the set of entries for this - // compilation unit, not including the length field itself; a 2-byte - // version identifier containing the value 2 for DWARF Version 2; a - // 4-byte offset into the.debug_infosection; a 1-byte unsigned integer - // containing the size in bytes of an address (or the offset portion of - // an address for segmented addressing) on the target system; and a - // 1-byte unsigned integer containing the size in bytes of a segment - // descriptor on the target system. This header is followed by a series - // of tuples. Each tuple consists of an address and a length, each in - // the size appropriate for an address on the target architecture. - m_header.length = data.GetDWARFInitialLength(offset_ptr); - m_header.version = data.GetU16(offset_ptr); - m_header.cu_offset = data.GetDWARFOffset(offset_ptr); - m_header.addr_size = data.GetU8(offset_ptr); - m_header.seg_size = data.GetU8(offset_ptr); - - // Try to avoid reading invalid arange sets by making sure: - // 1 - the version looks good - // 2 - the address byte size looks plausible - // 3 - the length seems to make sense - // size looks plausible - if ((m_header.version >= 2 && m_header.version <= 5) && - (m_header.addr_size == 4 || m_header.addr_size == 8) && - (m_header.length > 0)) - { - if (data.ValidOffset(m_offset + sizeof(m_header.length) + m_header.length - 1)) - { - // The first tuple following the header in each set begins at an offset - // that is a multiple of the size of a single tuple (that is, twice the - // size of an address). The header is padded, if necessary, to the - // appropriate boundary. - const uint32_t header_size = *offset_ptr - m_offset; - const uint32_t tuple_size = m_header.addr_size << 1; - uint32_t first_tuple_offset = 0; - while (first_tuple_offset < header_size) - first_tuple_offset += tuple_size; - - *offset_ptr = m_offset + first_tuple_offset; - - Descriptor arangeDescriptor; - - static_assert(sizeof(arangeDescriptor.address) == sizeof(arangeDescriptor.length), - "DWARFDebugArangeSet::Descriptor.address and DWARFDebugArangeSet::Descriptor.length must have same size"); - - while (data.ValidOffset(*offset_ptr)) - { - arangeDescriptor.address = data.GetMaxU64(offset_ptr, m_header.addr_size); - arangeDescriptor.length = data.GetMaxU64(offset_ptr, m_header.addr_size); - - // Each set of tuples is terminated by a 0 for the address and 0 - // for the length. - if (arangeDescriptor.address || arangeDescriptor.length) - m_arange_descriptors.push_back(arangeDescriptor); - else - break; // We are done if we get a zero address and length - } - } -#if defined (LLDB_CONFIGURATION_DEBUG) - else - { - printf ("warning: .debug_arange set length is too large arange data at 0x%8.8x: length=0x%8.8x, version=0x%4.4x, cu_offset=0x%8.8x, addr_size=%u, seg_size=%u\n", - m_offset, - m_header.length, - m_header.version, - m_header.cu_offset, - m_header.addr_size, - m_header.seg_size); - } -#endif - } -#if defined (LLDB_CONFIGURATION_DEBUG) - else - { - printf ("warning: .debug_arange set has bad header at 0x%8.8x: length=0x%8.8x, version=0x%4.4x, cu_offset=0x%8.8x, addr_size=%u, seg_size=%u\n", - m_offset, - m_header.length, - m_header.version, - m_header.cu_offset, - m_header.addr_size, - m_header.seg_size); + // 7.20 Address Range Table + // + // Each set of entries in the table of address ranges contained in + // the .debug_aranges section begins with a header consisting of: a + // 4-byte length containing the length of the set of entries for this + // compilation unit, not including the length field itself; a 2-byte + // version identifier containing the value 2 for DWARF Version 2; a + // 4-byte offset into the.debug_infosection; a 1-byte unsigned integer + // containing the size in bytes of an address (or the offset portion of + // an address for segmented addressing) on the target system; and a + // 1-byte unsigned integer containing the size in bytes of a segment + // descriptor on the target system. This header is followed by a series + // of tuples. Each tuple consists of an address and a length, each in + // the size appropriate for an address on the target architecture. + m_header.length = data.GetDWARFInitialLength(offset_ptr); + m_header.version = data.GetU16(offset_ptr); + m_header.cu_offset = data.GetDWARFOffset(offset_ptr); + m_header.addr_size = data.GetU8(offset_ptr); + m_header.seg_size = data.GetU8(offset_ptr); + + // Try to avoid reading invalid arange sets by making sure: + // 1 - the version looks good + // 2 - the address byte size looks plausible + // 3 - the length seems to make sense + // size looks plausible + if ((m_header.version >= 2 && m_header.version <= 5) && + (m_header.addr_size == 4 || m_header.addr_size == 8) && + (m_header.length > 0)) { + if (data.ValidOffset(m_offset + sizeof(m_header.length) + + m_header.length - 1)) { + // The first tuple following the header in each set begins at an offset + // that is a multiple of the size of a single tuple (that is, twice the + // size of an address). The header is padded, if necessary, to the + // appropriate boundary. + const uint32_t header_size = *offset_ptr - m_offset; + const uint32_t tuple_size = m_header.addr_size << 1; + uint32_t first_tuple_offset = 0; + while (first_tuple_offset < header_size) + first_tuple_offset += tuple_size; + + *offset_ptr = m_offset + first_tuple_offset; + + Descriptor arangeDescriptor; + + static_assert( + sizeof(arangeDescriptor.address) == sizeof(arangeDescriptor.length), + "DWARFDebugArangeSet::Descriptor.address and " + "DWARFDebugArangeSet::Descriptor.length must have same size"); + + while (data.ValidOffset(*offset_ptr)) { + arangeDescriptor.address = + data.GetMaxU64(offset_ptr, m_header.addr_size); + arangeDescriptor.length = + data.GetMaxU64(offset_ptr, m_header.addr_size); + + // Each set of tuples is terminated by a 0 for the address and 0 + // for the length. + if (arangeDescriptor.address || arangeDescriptor.length) + m_arange_descriptors.push_back(arangeDescriptor); + else + break; // We are done if we get a zero address and length } + } +#if defined(LLDB_CONFIGURATION_DEBUG) + else { + printf("warning: .debug_arange set length is too large arange data at " + "0x%8.8x: length=0x%8.8x, version=0x%4.4x, cu_offset=0x%8.8x, " + "addr_size=%u, seg_size=%u\n", + m_offset, m_header.length, m_header.version, m_header.cu_offset, + m_header.addr_size, m_header.seg_size); + } #endif - - return !m_arange_descriptors.empty(); } - return false; -} - +#if defined(LLDB_CONFIGURATION_DEBUG) + else { + printf("warning: .debug_arange set has bad header at 0x%8.8x: " + "length=0x%8.8x, version=0x%4.4x, cu_offset=0x%8.8x, " + "addr_size=%u, seg_size=%u\n", + m_offset, m_header.length, m_header.version, m_header.cu_offset, + m_header.addr_size, m_header.seg_size); + } +#endif -dw_offset_t -DWARFDebugArangeSet::GetOffsetOfNextEntry() const -{ - return m_offset + m_header.length + 4; + return !m_arange_descriptors.empty(); + } + return false; } +dw_offset_t DWARFDebugArangeSet::GetOffsetOfNextEntry() const { + return m_offset + m_header.length + 4; +} -void -DWARFDebugArangeSet::Dump(Stream *s) const -{ - s->Printf("Address Range Header: length = 0x%8.8x, version = 0x%4.4x, cu_offset = 0x%8.8x, addr_size = 0x%2.2x, seg_size = 0x%2.2x\n", - m_header.length ,m_header.version, m_header.cu_offset, m_header.addr_size, m_header.seg_size); +void DWARFDebugArangeSet::Dump(Stream *s) const { + s->Printf("Address Range Header: length = 0x%8.8x, version = 0x%4.4x, " + "cu_offset = 0x%8.8x, addr_size = 0x%2.2x, seg_size = 0x%2.2x\n", + m_header.length, m_header.version, m_header.cu_offset, + m_header.addr_size, m_header.seg_size); - const uint32_t hex_width = m_header.addr_size * 2; - DescriptorConstIter pos; - DescriptorConstIter end = m_arange_descriptors.end(); - for (pos = m_arange_descriptors.begin(); pos != end; ++pos) - s->Printf("[0x%*.*" PRIx64 " - 0x%*.*" PRIx64 ")\n", - hex_width, hex_width, pos->address, - hex_width, hex_width, pos->end_address()); + const uint32_t hex_width = m_header.addr_size * 2; + DescriptorConstIter pos; + DescriptorConstIter end = m_arange_descriptors.end(); + for (pos = m_arange_descriptors.begin(); pos != end; ++pos) + s->Printf("[0x%*.*" PRIx64 " - 0x%*.*" PRIx64 ")\n", hex_width, hex_width, + pos->address, hex_width, hex_width, pos->end_address()); } - -class DescriptorContainsAddress -{ +class DescriptorContainsAddress { public: - DescriptorContainsAddress (dw_addr_t address) : m_address(address) {} - bool operator() (const DWARFDebugArangeSet::Descriptor& desc) const - { - return (m_address >= desc.address) && (m_address < (desc.address + desc.length)); - } - private: - const dw_addr_t m_address; + DescriptorContainsAddress(dw_addr_t address) : m_address(address) {} + bool operator()(const DWARFDebugArangeSet::Descriptor &desc) const { + return (m_address >= desc.address) && + (m_address < (desc.address + desc.length)); + } + +private: + const dw_addr_t m_address; }; -dw_offset_t -DWARFDebugArangeSet::FindAddress(dw_addr_t address) const -{ - DescriptorConstIter end = m_arange_descriptors.end(); - DescriptorConstIter pos = std::find_if( m_arange_descriptors.begin(), end, // Range - DescriptorContainsAddress(address));// Predicate - if (pos != end) - return m_header.cu_offset; +dw_offset_t DWARFDebugArangeSet::FindAddress(dw_addr_t address) const { + DescriptorConstIter end = m_arange_descriptors.end(); + DescriptorConstIter pos = + std::find_if(m_arange_descriptors.begin(), end, // Range + DescriptorContainsAddress(address)); // Predicate + if (pos != end) + return m_header.cu_offset; - return DW_INVALID_OFFSET; + return DW_INVALID_OFFSET; } diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h index fde36b7e0adc..ae6319a13d0e 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h @@ -15,62 +15,62 @@ class SymbolFileDWARF; -class DWARFDebugArangeSet -{ +class DWARFDebugArangeSet { public: - struct Header - { - uint32_t length; // The total length of the entries for that set, not including the length field itself. - uint16_t version; // The DWARF version number - uint32_t cu_offset; // The offset from the beginning of the .debug_info section of the compilation unit entry referenced by the table. - uint8_t addr_size; // The size in bytes of an address on the target architecture. For segmented addressing, this is the size of the offset portion of the address - uint8_t seg_size; // The size in bytes of a segment descriptor on the target architecture. If the target system uses a flat address space, this value is 0. - }; + struct Header { + uint32_t length; // The total length of the entries for that set, not + // including the length field itself. + uint16_t version; // The DWARF version number + uint32_t cu_offset; // The offset from the beginning of the .debug_info + // section of the compilation unit entry referenced by + // the table. + uint8_t addr_size; // The size in bytes of an address on the target + // architecture. For segmented addressing, this is the + // size of the offset portion of the address + uint8_t seg_size; // The size in bytes of a segment descriptor on the target + // architecture. If the target system uses a flat address + // space, this value is 0. + }; - struct Descriptor - { - dw_addr_t address; - dw_addr_t length; - dw_addr_t end_address() const { return address + length; } - }; + struct Descriptor { + dw_addr_t address; + dw_addr_t length; + dw_addr_t end_address() const { return address + length; } + }; + DWARFDebugArangeSet(); + void Clear(); + void SetOffset(uint32_t offset) { m_offset = offset; } + void SetHeader(uint16_t version, uint32_t cu_offset, uint8_t addr_size, + uint8_t seg_size); + void AddDescriptor(const DWARFDebugArangeSet::Descriptor &range); + void Compact(); + bool Extract(const lldb_private::DWARFDataExtractor &data, + lldb::offset_t *offset_ptr); + void Dump(lldb_private::Stream *s) const; + dw_offset_t GetCompileUnitDIEOffset() const { return m_header.cu_offset; } + dw_offset_t GetOffsetOfNextEntry() const; + dw_offset_t FindAddress(dw_addr_t address) const; + size_t NumDescriptors() const { return m_arange_descriptors.size(); } + const Header &GetHeader() const { return m_header; } + const Descriptor *GetDescriptor(uint32_t i) const { + if (i < m_arange_descriptors.size()) + return &m_arange_descriptors[i]; + return NULL; + } - DWARFDebugArangeSet(); - void Clear(); - void SetOffset(uint32_t offset) { m_offset = offset; } - void SetHeader(uint16_t version, uint32_t cu_offset, uint8_t addr_size, uint8_t seg_size); - void AddDescriptor(const DWARFDebugArangeSet::Descriptor& range); - void Compact(); - bool Extract(const lldb_private::DWARFDataExtractor &data, lldb::offset_t *offset_ptr); - void Dump(lldb_private::Stream *s) const; - dw_offset_t GetCompileUnitDIEOffset() const { return m_header.cu_offset; } - dw_offset_t GetOffsetOfNextEntry() const; - dw_offset_t FindAddress(dw_addr_t address) const; - size_t NumDescriptors() const { return m_arange_descriptors.size(); } - const Header& GetHeader() const { return m_header; } - const Descriptor* GetDescriptor(uint32_t i) const - { - if (i < m_arange_descriptors.size()) - return &m_arange_descriptors[i]; - return NULL; - } - - const Descriptor & - GetDescriptorRef (uint32_t i) const - { - return m_arange_descriptors[i]; - } - + const Descriptor &GetDescriptorRef(uint32_t i) const { + return m_arange_descriptors[i]; + } protected: - typedef std::vector<Descriptor> DescriptorColl; - typedef DescriptorColl::iterator DescriptorIter; - typedef DescriptorColl::const_iterator DescriptorConstIter; - + typedef std::vector<Descriptor> DescriptorColl; + typedef DescriptorColl::iterator DescriptorIter; + typedef DescriptorColl::const_iterator DescriptorConstIter; - uint32_t m_offset; - Header m_header; - DescriptorColl m_arange_descriptors; + uint32_t m_offset; + Header m_header; + DescriptorColl m_arange_descriptors; }; -#endif // SymbolFileDWARF_DWARFDebugArangeSet_h_ +#endif // SymbolFileDWARF_DWARFDebugArangeSet_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp index 60e5c6ed62fe..5e71e9dfcbb3 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp @@ -18,10 +18,10 @@ #include "lldb/Core/Stream.h" #include "lldb/Core/Timer.h" +#include "DWARFCompileUnit.h" +#include "DWARFDebugInfo.h" #include "LogChannelDWARF.h" #include "SymbolFileDWARF.h" -#include "DWARFDebugInfo.h" -#include "DWARFCompileUnit.h" using namespace lldb; using namespace lldb_private; @@ -29,148 +29,122 @@ using namespace lldb_private; //---------------------------------------------------------------------- // Constructor //---------------------------------------------------------------------- -DWARFDebugAranges::DWARFDebugAranges() : - m_aranges() -{ -} +DWARFDebugAranges::DWARFDebugAranges() : m_aranges() {} //---------------------------------------------------------------------- // CountArangeDescriptors //---------------------------------------------------------------------- -class CountArangeDescriptors -{ +class CountArangeDescriptors { public: - CountArangeDescriptors (uint32_t& count_ref) : count(count_ref) - { -// printf("constructor CountArangeDescriptors()\n"); - } - void operator() (const DWARFDebugArangeSet& set) - { - count += set.NumDescriptors(); - } - uint32_t& count; + CountArangeDescriptors(uint32_t &count_ref) : count(count_ref) { + // printf("constructor CountArangeDescriptors()\n"); + } + void operator()(const DWARFDebugArangeSet &set) { + count += set.NumDescriptors(); + } + uint32_t &count; }; - //---------------------------------------------------------------------- // Extract //---------------------------------------------------------------------- -bool -DWARFDebugAranges::Extract(const DWARFDataExtractor &debug_aranges_data) -{ - if (debug_aranges_data.ValidOffset(0)) - { - lldb::offset_t offset = 0; - - DWARFDebugArangeSet set; - Range range; - while (set.Extract(debug_aranges_data, &offset)) - { - const uint32_t num_descriptors = set.NumDescriptors(); - if (num_descriptors > 0) - { - const dw_offset_t cu_offset = set.GetCompileUnitDIEOffset(); - - for (uint32_t i=0; i<num_descriptors; ++i) - { - const DWARFDebugArangeSet::Descriptor &descriptor = set.GetDescriptorRef(i); - m_aranges.Append(RangeToDIE::Entry (descriptor.address, descriptor.length, cu_offset)); - } - } - set.Clear(); +bool DWARFDebugAranges::Extract(const DWARFDataExtractor &debug_aranges_data) { + if (debug_aranges_data.ValidOffset(0)) { + lldb::offset_t offset = 0; + + DWARFDebugArangeSet set; + Range range; + while (set.Extract(debug_aranges_data, &offset)) { + const uint32_t num_descriptors = set.NumDescriptors(); + if (num_descriptors > 0) { + const dw_offset_t cu_offset = set.GetCompileUnitDIEOffset(); + + for (uint32_t i = 0; i < num_descriptors; ++i) { + const DWARFDebugArangeSet::Descriptor &descriptor = + set.GetDescriptorRef(i); + m_aranges.Append(RangeToDIE::Entry(descriptor.address, + descriptor.length, cu_offset)); } + } + set.Clear(); } - return false; + } + return false; } //---------------------------------------------------------------------- // Generate //---------------------------------------------------------------------- -bool -DWARFDebugAranges::Generate(SymbolFileDWARF* dwarf2Data) -{ - Clear(); - DWARFDebugInfo* debug_info = dwarf2Data->DebugInfo(); - if (debug_info) - { - uint32_t cu_idx = 0; - const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits(); - for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) - { - DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx); - if (cu) - cu->BuildAddressRangeTable(dwarf2Data, this); - } +bool DWARFDebugAranges::Generate(SymbolFileDWARF *dwarf2Data) { + Clear(); + DWARFDebugInfo *debug_info = dwarf2Data->DebugInfo(); + if (debug_info) { + uint32_t cu_idx = 0; + const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits(); + for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) { + DWARFCompileUnit *cu = debug_info->GetCompileUnitAtIndex(cu_idx); + if (cu) + cu->BuildAddressRangeTable(dwarf2Data, this); } - return !IsEmpty(); + } + return !IsEmpty(); } +void DWARFDebugAranges::Dump(Log *log) const { + if (log == NULL) + return; -void -DWARFDebugAranges::Dump (Log *log) const -{ - if (log == NULL) - return; - - const size_t num_entries = m_aranges.GetSize(); - for (size_t i=0; i<num_entries; ++i) - { - const RangeToDIE::Entry *entry = m_aranges.GetEntryAtIndex(i); - if (entry) - log->Printf ("0x%8.8x: [0x%" PRIx64 " - 0x%" PRIx64 ")", - entry->data, - entry->GetRangeBase(), - entry->GetRangeEnd()); - } + const size_t num_entries = m_aranges.GetSize(); + for (size_t i = 0; i < num_entries; ++i) { + const RangeToDIE::Entry *entry = m_aranges.GetEntryAtIndex(i); + if (entry) + log->Printf("0x%8.8x: [0x%" PRIx64 " - 0x%" PRIx64 ")", entry->data, + entry->GetRangeBase(), entry->GetRangeEnd()); + } } -void -DWARFDebugAranges::AppendRange (dw_offset_t offset, dw_addr_t low_pc, dw_addr_t high_pc) -{ - if (high_pc > low_pc) - m_aranges.Append(RangeToDIE::Entry (low_pc, high_pc - low_pc, offset)); +void DWARFDebugAranges::AppendRange(dw_offset_t offset, dw_addr_t low_pc, + dw_addr_t high_pc) { + if (high_pc > low_pc) + m_aranges.Append(RangeToDIE::Entry(low_pc, high_pc - low_pc, offset)); } -void -DWARFDebugAranges::Sort (bool minimize) -{ - Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", - __PRETTY_FUNCTION__, static_cast<void*>(this)); - - Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES)); - size_t orig_arange_size = 0; - if (log) - { - orig_arange_size = m_aranges.GetSize(); - log->Printf ("DWARFDebugAranges::Sort(minimize = %u) with %" PRIu64 " entries", minimize, (uint64_t)orig_arange_size); - } - - m_aranges.Sort(); - m_aranges.CombineConsecutiveEntriesWithEqualData(); - - if (log) - { - if (minimize) - { - const size_t new_arange_size = m_aranges.GetSize(); - const size_t delta = orig_arange_size - new_arange_size; - log->Printf ("DWARFDebugAranges::Sort() %" PRIu64 " entries after minimizing (%" PRIu64 " entries combined for %" PRIu64 " bytes saved)", - (uint64_t)new_arange_size, - (uint64_t)delta, - (uint64_t)delta * sizeof(Range)); - } - Dump (log); +void DWARFDebugAranges::Sort(bool minimize) { + Timer scoped_timer(LLVM_PRETTY_FUNCTION, "%s this = %p", LLVM_PRETTY_FUNCTION, + static_cast<void *>(this)); + + Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES)); + size_t orig_arange_size = 0; + if (log) { + orig_arange_size = m_aranges.GetSize(); + log->Printf("DWARFDebugAranges::Sort(minimize = %u) with %" PRIu64 + " entries", + minimize, (uint64_t)orig_arange_size); + } + + m_aranges.Sort(); + m_aranges.CombineConsecutiveEntriesWithEqualData(); + + if (log) { + if (minimize) { + const size_t new_arange_size = m_aranges.GetSize(); + const size_t delta = orig_arange_size - new_arange_size; + log->Printf("DWARFDebugAranges::Sort() %" PRIu64 + " entries after minimizing (%" PRIu64 + " entries combined for %" PRIu64 " bytes saved)", + (uint64_t)new_arange_size, (uint64_t)delta, + (uint64_t)delta * sizeof(Range)); } + Dump(log); + } } //---------------------------------------------------------------------- // FindAddress //---------------------------------------------------------------------- -dw_offset_t -DWARFDebugAranges::FindAddress(dw_addr_t address) const -{ - const RangeToDIE::Entry *entry = m_aranges.FindEntryThatContains(address); - if (entry) - return entry->data; - return DW_INVALID_OFFSET; +dw_offset_t DWARFDebugAranges::FindAddress(dw_addr_t address) const { + const RangeToDIE::Entry *entry = m_aranges.FindEntryThatContains(address); + if (entry) + return entry->data; + return DW_INVALID_OFFSET; } diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h index 206aa3a60f49..6524cb3ce483 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h @@ -17,78 +17,50 @@ class SymbolFileDWARF; -class DWARFDebugAranges -{ +class DWARFDebugAranges { protected: - typedef lldb_private::RangeDataArray<dw_addr_t, uint32_t, dw_offset_t, 1> RangeToDIE; + typedef lldb_private::RangeDataArray<dw_addr_t, uint32_t, dw_offset_t, 1> + RangeToDIE; public: - typedef RangeToDIE::Entry Range; - typedef std::vector<RangeToDIE::Entry> RangeColl; - - DWARFDebugAranges(); - - void - Clear() - { - m_aranges.Clear(); - } - - bool - Extract(const lldb_private::DWARFDataExtractor &debug_aranges_data); - - bool - Generate(SymbolFileDWARF* dwarf2Data); - - // Use append range multiple times and then call sort - void - AppendRange (dw_offset_t cu_offset, - dw_addr_t low_pc, - dw_addr_t high_pc); - - void - Sort (bool minimize); - - const Range* - RangeAtIndex(uint32_t idx) const - { - return m_aranges.GetEntryAtIndex (idx); - } - - void - Dump (lldb_private::Log *log) const; - - dw_offset_t - FindAddress(dw_addr_t address) const; - - bool - IsEmpty() const - { - return m_aranges.IsEmpty(); - } - size_t - GetNumRanges() const - { - return m_aranges.GetSize(); - } - - dw_offset_t - OffsetAtIndex(uint32_t idx) const - { - const Range *range = m_aranges.GetEntryAtIndex (idx); - if (range) - return range->data; - return DW_INVALID_OFFSET; - } - - static void - Dump(SymbolFileDWARF* dwarf2Data, lldb_private::Stream *s); - -protected: + typedef RangeToDIE::Entry Range; + typedef std::vector<RangeToDIE::Entry> RangeColl; + DWARFDebugAranges(); - RangeToDIE m_aranges; -}; + void Clear() { m_aranges.Clear(); } + + bool Extract(const lldb_private::DWARFDataExtractor &debug_aranges_data); + + bool Generate(SymbolFileDWARF *dwarf2Data); + + // Use append range multiple times and then call sort + void AppendRange(dw_offset_t cu_offset, dw_addr_t low_pc, dw_addr_t high_pc); + + void Sort(bool minimize); + + const Range *RangeAtIndex(uint32_t idx) const { + return m_aranges.GetEntryAtIndex(idx); + } + void Dump(lldb_private::Log *log) const; + + dw_offset_t FindAddress(dw_addr_t address) const; + + bool IsEmpty() const { return m_aranges.IsEmpty(); } + size_t GetNumRanges() const { return m_aranges.GetSize(); } + + dw_offset_t OffsetAtIndex(uint32_t idx) const { + const Range *range = m_aranges.GetEntryAtIndex(idx); + if (range) + return range->data; + return DW_INVALID_OFFSET; + } + + static void Dump(SymbolFileDWARF *dwarf2Data, lldb_private::Stream *s); + +protected: + RangeToDIE m_aranges; +}; -#endif // SymbolFileDWARF_DWARFDebugAranges_h_ +#endif // SymbolFileDWARF_DWARFDebugAranges_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp index 417f2cd79bda..9dc656d79326 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp @@ -14,12 +14,13 @@ #include "lldb/Core/RegularExpression.h" #include "lldb/Core/Stream.h" +#include "lldb/Host/PosixApi.h" #include "lldb/Symbol/ObjectFile.h" -#include "DWARFDebugAranges.h" -#include "DWARFDebugInfo.h" #include "DWARFCompileUnit.h" #include "DWARFDebugAranges.h" +#include "DWARFDebugAranges.h" +#include "DWARFDebugInfo.h" #include "DWARFDebugInfoEntry.h" #include "DWARFFormValue.h" #include "LogChannelDWARF.h" @@ -31,229 +32,192 @@ using namespace std; //---------------------------------------------------------------------- // Constructor //---------------------------------------------------------------------- -DWARFDebugInfo::DWARFDebugInfo() : - m_dwarf2Data(NULL), - m_compile_units(), - m_cu_aranges_ap () -{ -} +DWARFDebugInfo::DWARFDebugInfo() + : m_dwarf2Data(NULL), m_compile_units(), m_cu_aranges_ap() {} //---------------------------------------------------------------------- // SetDwarfData //---------------------------------------------------------------------- -void -DWARFDebugInfo::SetDwarfData(SymbolFileDWARF* dwarf2Data) -{ - m_dwarf2Data = dwarf2Data; - m_compile_units.clear(); +void DWARFDebugInfo::SetDwarfData(SymbolFileDWARF *dwarf2Data) { + m_dwarf2Data = dwarf2Data; + m_compile_units.clear(); } +DWARFDebugAranges &DWARFDebugInfo::GetCompileUnitAranges() { + if (m_cu_aranges_ap.get() == NULL && m_dwarf2Data) { + Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES)); + + m_cu_aranges_ap.reset(new DWARFDebugAranges()); + const DWARFDataExtractor &debug_aranges_data = + m_dwarf2Data->get_debug_aranges_data(); + if (debug_aranges_data.GetByteSize() > 0) { + if (log) + log->Printf( + "DWARFDebugInfo::GetCompileUnitAranges() for \"%s\" from " + ".debug_aranges", + m_dwarf2Data->GetObjectFile()->GetFileSpec().GetPath().c_str()); + m_cu_aranges_ap->Extract(debug_aranges_data); + } -DWARFDebugAranges & -DWARFDebugInfo::GetCompileUnitAranges () -{ - if (m_cu_aranges_ap.get() == NULL && m_dwarf2Data) - { - Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES)); - - m_cu_aranges_ap.reset (new DWARFDebugAranges()); - const DWARFDataExtractor &debug_aranges_data = m_dwarf2Data->get_debug_aranges_data(); - if (debug_aranges_data.GetByteSize() > 0) - { - if (log) - log->Printf ("DWARFDebugInfo::GetCompileUnitAranges() for \"%s\" from .debug_aranges", - m_dwarf2Data->GetObjectFile()->GetFileSpec().GetPath().c_str()); - m_cu_aranges_ap->Extract (debug_aranges_data); - - } - - // Make a list of all CUs represented by the arange data in the file. - std::set<dw_offset_t> cus_with_data; - for (size_t n=0;n<m_cu_aranges_ap.get()->GetNumRanges();n++) - { - dw_offset_t offset = m_cu_aranges_ap.get()->OffsetAtIndex(n); - if (offset != DW_INVALID_OFFSET) - cus_with_data.insert (offset); - } + // Make a list of all CUs represented by the arange data in the file. + std::set<dw_offset_t> cus_with_data; + for (size_t n = 0; n < m_cu_aranges_ap.get()->GetNumRanges(); n++) { + dw_offset_t offset = m_cu_aranges_ap.get()->OffsetAtIndex(n); + if (offset != DW_INVALID_OFFSET) + cus_with_data.insert(offset); + } - // Manually build arange data for everything that wasn't in the .debug_aranges table. - bool printed = false; - const size_t num_compile_units = GetNumCompileUnits(); - for (size_t idx = 0; idx < num_compile_units; ++idx) - { - DWARFCompileUnit* cu = GetCompileUnitAtIndex(idx); - - dw_offset_t offset = cu->GetOffset(); - if (cus_with_data.find(offset) == cus_with_data.end()) - { - if (log) - { - if (!printed) - log->Printf ("DWARFDebugInfo::GetCompileUnitAranges() for \"%s\" by parsing", - m_dwarf2Data->GetObjectFile()->GetFileSpec().GetPath().c_str()); - printed = true; - } - cu->BuildAddressRangeTable (m_dwarf2Data, m_cu_aranges_ap.get()); - } + // Manually build arange data for everything that wasn't in the + // .debug_aranges table. + bool printed = false; + const size_t num_compile_units = GetNumCompileUnits(); + for (size_t idx = 0; idx < num_compile_units; ++idx) { + DWARFCompileUnit *cu = GetCompileUnitAtIndex(idx); + + dw_offset_t offset = cu->GetOffset(); + if (cus_with_data.find(offset) == cus_with_data.end()) { + if (log) { + if (!printed) + log->Printf( + "DWARFDebugInfo::GetCompileUnitAranges() for \"%s\" by parsing", + m_dwarf2Data->GetObjectFile()->GetFileSpec().GetPath().c_str()); + printed = true; } - - const bool minimize = true; - m_cu_aranges_ap->Sort (minimize); + cu->BuildAddressRangeTable(m_dwarf2Data, m_cu_aranges_ap.get()); + } } - return *m_cu_aranges_ap.get(); + + const bool minimize = true; + m_cu_aranges_ap->Sort(minimize); + } + return *m_cu_aranges_ap.get(); } -void -DWARFDebugInfo::ParseCompileUnitHeadersIfNeeded() -{ - if (m_compile_units.empty()) - { - if (m_dwarf2Data != NULL) - { - lldb::offset_t offset = 0; - const DWARFDataExtractor &debug_info_data = m_dwarf2Data->get_debug_info_data(); - while (debug_info_data.ValidOffset(offset)) - { - DWARFCompileUnitSP cu_sp(new DWARFCompileUnit(m_dwarf2Data)); - // Out of memory? - if (cu_sp.get() == NULL) - break; - - if (cu_sp->Extract(debug_info_data, &offset) == false) - break; - - m_compile_units.push_back(cu_sp); - - offset = cu_sp->GetNextCompileUnitOffset(); - } - } +void DWARFDebugInfo::ParseCompileUnitHeadersIfNeeded() { + if (m_compile_units.empty()) { + if (m_dwarf2Data != NULL) { + lldb::offset_t offset = 0; + const DWARFDataExtractor &debug_info_data = + m_dwarf2Data->get_debug_info_data(); + while (debug_info_data.ValidOffset(offset)) { + DWARFCompileUnitSP cu_sp(new DWARFCompileUnit(m_dwarf2Data)); + // Out of memory? + if (cu_sp.get() == NULL) + break; + + if (cu_sp->Extract(debug_info_data, &offset) == false) + break; + + m_compile_units.push_back(cu_sp); + + offset = cu_sp->GetNextCompileUnitOffset(); + } } + } } -size_t -DWARFDebugInfo::GetNumCompileUnits() -{ - ParseCompileUnitHeadersIfNeeded(); - return m_compile_units.size(); +size_t DWARFDebugInfo::GetNumCompileUnits() { + ParseCompileUnitHeadersIfNeeded(); + return m_compile_units.size(); } -DWARFCompileUnit* -DWARFDebugInfo::GetCompileUnitAtIndex(uint32_t idx) -{ - DWARFCompileUnit* cu = NULL; - if (idx < GetNumCompileUnits()) - cu = m_compile_units[idx].get(); - return cu; +DWARFCompileUnit *DWARFDebugInfo::GetCompileUnitAtIndex(uint32_t idx) { + DWARFCompileUnit *cu = NULL; + if (idx < GetNumCompileUnits()) + cu = m_compile_units[idx].get(); + return cu; } -bool -DWARFDebugInfo::ContainsCompileUnit (const DWARFCompileUnit *cu) const -{ - // Not a verify efficient function, but it is handy for use in assertions - // to make sure that a compile unit comes from a debug information file. - CompileUnitColl::const_iterator end_pos = m_compile_units.end(); - CompileUnitColl::const_iterator pos; - - for (pos = m_compile_units.begin(); pos != end_pos; ++pos) - { - if (pos->get() == cu) - return true; - } - return false; +bool DWARFDebugInfo::ContainsCompileUnit(const DWARFCompileUnit *cu) const { + // Not a verify efficient function, but it is handy for use in assertions + // to make sure that a compile unit comes from a debug information file. + CompileUnitColl::const_iterator end_pos = m_compile_units.end(); + CompileUnitColl::const_iterator pos; + + for (pos = m_compile_units.begin(); pos != end_pos; ++pos) { + if (pos->get() == cu) + return true; + } + return false; } -bool -DWARFDebugInfo::OffsetLessThanCompileUnitOffset (dw_offset_t offset, const DWARFCompileUnitSP& cu_sp) -{ - return offset < cu_sp->GetOffset(); +bool DWARFDebugInfo::OffsetLessThanCompileUnitOffset( + dw_offset_t offset, const DWARFCompileUnitSP &cu_sp) { + return offset < cu_sp->GetOffset(); } -DWARFCompileUnit * -DWARFDebugInfo::GetCompileUnit(dw_offset_t cu_offset, uint32_t* idx_ptr) -{ - DWARFCompileUnitSP cu_sp; - uint32_t cu_idx = DW_INVALID_INDEX; - if (cu_offset != DW_INVALID_OFFSET) - { - ParseCompileUnitHeadersIfNeeded(); - - // Watch out for single compile unit executable as they are pretty common - const size_t num_cus = m_compile_units.size(); - if (num_cus == 1) - { - if (m_compile_units[0]->GetOffset() == cu_offset) - { - cu_sp = m_compile_units[0]; - cu_idx = 0; - } - } - else if (num_cus) - { - CompileUnitColl::const_iterator end_pos = m_compile_units.end(); - CompileUnitColl::const_iterator begin_pos = m_compile_units.begin(); - CompileUnitColl::const_iterator pos = std::upper_bound(begin_pos, end_pos, cu_offset, OffsetLessThanCompileUnitOffset); - if (pos != begin_pos) - { - --pos; - if ((*pos)->GetOffset() == cu_offset) - { - cu_sp = *pos; - cu_idx = std::distance(begin_pos, pos); - } - } +DWARFCompileUnit *DWARFDebugInfo::GetCompileUnit(dw_offset_t cu_offset, + uint32_t *idx_ptr) { + DWARFCompileUnitSP cu_sp; + uint32_t cu_idx = DW_INVALID_INDEX; + if (cu_offset != DW_INVALID_OFFSET) { + ParseCompileUnitHeadersIfNeeded(); + + // Watch out for single compile unit executable as they are pretty common + const size_t num_cus = m_compile_units.size(); + if (num_cus == 1) { + if (m_compile_units[0]->GetOffset() == cu_offset) { + cu_sp = m_compile_units[0]; + cu_idx = 0; + } + } else if (num_cus) { + CompileUnitColl::const_iterator end_pos = m_compile_units.end(); + CompileUnitColl::const_iterator begin_pos = m_compile_units.begin(); + CompileUnitColl::const_iterator pos = std::upper_bound( + begin_pos, end_pos, cu_offset, OffsetLessThanCompileUnitOffset); + if (pos != begin_pos) { + --pos; + if ((*pos)->GetOffset() == cu_offset) { + cu_sp = *pos; + cu_idx = std::distance(begin_pos, pos); } + } } - if (idx_ptr) - *idx_ptr = cu_idx; - return cu_sp.get(); + } + if (idx_ptr) + *idx_ptr = cu_idx; + return cu_sp.get(); } -DWARFCompileUnit * -DWARFDebugInfo::GetCompileUnit (const DIERef& die_ref) -{ - if (die_ref.cu_offset == DW_INVALID_OFFSET) - return GetCompileUnitContainingDIEOffset(die_ref.die_offset); - else - return GetCompileUnit(die_ref.cu_offset); +DWARFCompileUnit *DWARFDebugInfo::GetCompileUnit(const DIERef &die_ref) { + if (die_ref.cu_offset == DW_INVALID_OFFSET) + return GetCompileUnitContainingDIEOffset(die_ref.die_offset); + else + return GetCompileUnit(die_ref.cu_offset); } -DWARFCompileUnit* -DWARFDebugInfo::GetCompileUnitContainingDIEOffset(dw_offset_t die_offset) -{ - ParseCompileUnitHeadersIfNeeded(); +DWARFCompileUnit * +DWARFDebugInfo::GetCompileUnitContainingDIEOffset(dw_offset_t die_offset) { + ParseCompileUnitHeadersIfNeeded(); - DWARFCompileUnitSP cu_sp; + DWARFCompileUnitSP cu_sp; - // Watch out for single compile unit executable as they are pretty common - const size_t num_cus = m_compile_units.size(); - if (num_cus == 1) - { - if (m_compile_units[0]->ContainsDIEOffset(die_offset)) - return m_compile_units[0].get(); - } - else if (num_cus) - { - CompileUnitColl::const_iterator end_pos = m_compile_units.end(); - CompileUnitColl::const_iterator begin_pos = m_compile_units.begin(); - CompileUnitColl::const_iterator pos = std::upper_bound(begin_pos, end_pos, die_offset, OffsetLessThanCompileUnitOffset); - if (pos != begin_pos) - { - --pos; - if ((*pos)->ContainsDIEOffset(die_offset)) - return (*pos).get(); - } + // Watch out for single compile unit executable as they are pretty common + const size_t num_cus = m_compile_units.size(); + if (num_cus == 1) { + if (m_compile_units[0]->ContainsDIEOffset(die_offset)) + return m_compile_units[0].get(); + } else if (num_cus) { + CompileUnitColl::const_iterator end_pos = m_compile_units.end(); + CompileUnitColl::const_iterator begin_pos = m_compile_units.begin(); + CompileUnitColl::const_iterator pos = std::upper_bound( + begin_pos, end_pos, die_offset, OffsetLessThanCompileUnitOffset); + if (pos != begin_pos) { + --pos; + if ((*pos)->ContainsDIEOffset(die_offset)) + return (*pos).get(); } + } - return nullptr; + return nullptr; } DWARFDIE -DWARFDebugInfo::GetDIEForDIEOffset(dw_offset_t die_offset) -{ - DWARFCompileUnit* cu = GetCompileUnitContainingDIEOffset(die_offset); - if (cu) - return cu->GetDIE(die_offset); - return DWARFDIE(); +DWARFDebugInfo::GetDIEForDIEOffset(dw_offset_t die_offset) { + DWARFCompileUnit *cu = GetCompileUnitContainingDIEOffset(die_offset); + if (cu) + return cu->GetDIE(die_offset); + return DWARFDIE(); } //---------------------------------------------------------------------- @@ -262,12 +226,11 @@ DWARFDebugInfo::GetDIEForDIEOffset(dw_offset_t die_offset) // Get the DIE (Debug Information Entry) with the specified offset. //---------------------------------------------------------------------- DWARFDIE -DWARFDebugInfo::GetDIE(const DIERef& die_ref) -{ - DWARFCompileUnit *cu = GetCompileUnit(die_ref); - if (cu) - return cu->GetDIE (die_ref.die_offset); - return DWARFDIE(); // Not found +DWARFDebugInfo::GetDIE(const DIERef &die_ref) { + DWARFCompileUnit *cu = GetCompileUnit(die_ref); + if (cu) + return cu->GetDIE(die_ref.die_offset); + return DWARFDIE(); // Not found } //---------------------------------------------------------------------- @@ -280,88 +243,75 @@ DWARFDebugInfo::GetDIE(const DIERef& die_ref) // for different tasks such as parsing the file contents into a // structured data, dumping, verifying and much more. //---------------------------------------------------------------------- -void -DWARFDebugInfo::Parse(SymbolFileDWARF* dwarf2Data, Callback callback, void* userData) -{ - if (dwarf2Data) - { - lldb::offset_t offset = 0; - uint32_t depth = 0; - DWARFCompileUnitSP cu(new DWARFCompileUnit(dwarf2Data)); - if (cu.get() == NULL) - return; - DWARFDebugInfoEntry die; - - while (cu->Extract(dwarf2Data->get_debug_info_data(), &offset)) - { - const dw_offset_t next_cu_offset = cu->GetNextCompileUnitOffset(); - - depth = 0; - // Call the callback function with no DIE pointer for the compile unit - // and get the offset that we are to continue to parse from - offset = callback(dwarf2Data, cu.get(), NULL, offset, depth, userData); - - // Make sure we are within our compile unit - if (offset < next_cu_offset) - { - // We are in our compile unit, parse starting at the offset - // we were told to parse - bool done = false; - while (!done && die.Extract(dwarf2Data, cu.get(), &offset)) - { - // Call the callback function with DIE pointer that falls within the compile unit - offset = callback(dwarf2Data, cu.get(), &die, offset, depth, userData); - - if (die.IsNULL()) - { - if (depth) - --depth; - else - done = true; // We are done with this compile unit! - } - else if (die.HasChildren()) - ++depth; - } - } - - // Make sure the offset returned is valid, and if not stop parsing. - // Returning DW_INVALID_OFFSET from this callback is a good way to end - // all parsing - if (!dwarf2Data->get_debug_info_data().ValidOffset(offset)) - break; - - // See if during the callback anyone retained a copy of the compile - // unit other than ourselves and if so, let whomever did own the object - // and create a new one for our own use! - if (!cu.unique()) - cu.reset(new DWARFCompileUnit(dwarf2Data)); - - - // Make sure we start on a proper - offset = next_cu_offset; +void DWARFDebugInfo::Parse(SymbolFileDWARF *dwarf2Data, Callback callback, + void *userData) { + if (dwarf2Data) { + lldb::offset_t offset = 0; + uint32_t depth = 0; + DWARFCompileUnitSP cu(new DWARFCompileUnit(dwarf2Data)); + if (cu.get() == NULL) + return; + DWARFDebugInfoEntry die; + + while (cu->Extract(dwarf2Data->get_debug_info_data(), &offset)) { + const dw_offset_t next_cu_offset = cu->GetNextCompileUnitOffset(); + + depth = 0; + // Call the callback function with no DIE pointer for the compile unit + // and get the offset that we are to continue to parse from + offset = callback(dwarf2Data, cu.get(), NULL, offset, depth, userData); + + // Make sure we are within our compile unit + if (offset < next_cu_offset) { + // We are in our compile unit, parse starting at the offset + // we were told to parse + bool done = false; + while (!done && die.Extract(dwarf2Data, cu.get(), &offset)) { + // Call the callback function with DIE pointer that falls within the + // compile unit + offset = + callback(dwarf2Data, cu.get(), &die, offset, depth, userData); + + if (die.IsNULL()) { + if (depth) + --depth; + else + done = true; // We are done with this compile unit! + } else if (die.HasChildren()) + ++depth; } + } + + // Make sure the offset returned is valid, and if not stop parsing. + // Returning DW_INVALID_OFFSET from this callback is a good way to end + // all parsing + if (!dwarf2Data->get_debug_info_data().ValidOffset(offset)) + break; + + // See if during the callback anyone retained a copy of the compile + // unit other than ourselves and if so, let whomever did own the object + // and create a new one for our own use! + if (!cu.unique()) + cu.reset(new DWARFCompileUnit(dwarf2Data)); + + // Make sure we start on a proper + offset = next_cu_offset; } + } } -typedef struct DumpInfo -{ - DumpInfo(Stream* init_strm, uint32_t off, uint32_t depth) : - strm(init_strm), - die_offset(off), - recurse_depth(depth), - found_depth(UINT32_MAX), - found_die(false), - ancestors() - { - } - Stream* strm; - const uint32_t die_offset; - const uint32_t recurse_depth; - uint32_t found_depth; - bool found_die; - std::vector<DWARFDebugInfoEntry> ancestors; - - DISALLOW_COPY_AND_ASSIGN(DumpInfo); +typedef struct DumpInfo { + DumpInfo(Stream *init_strm, uint32_t off, uint32_t depth) + : strm(init_strm), die_offset(off), recurse_depth(depth), + found_depth(UINT32_MAX), found_die(false), ancestors() {} + Stream *strm; + const uint32_t die_offset; + const uint32_t recurse_depth; + uint32_t found_depth; + bool found_die; + std::vector<DWARFDebugInfoEntry> ancestors; + + DISALLOW_COPY_AND_ASSIGN(DumpInfo); } DumpInfo; //---------------------------------------------------------------------- @@ -374,168 +324,134 @@ typedef struct DumpInfo // This function dump DWARF information and obey recurse depth and // whether a single DIE is to be dumped (or all of the data). //---------------------------------------------------------------------- -static dw_offset_t DumpCallback -( - SymbolFileDWARF* dwarf2Data, - DWARFCompileUnit* cu, - DWARFDebugInfoEntry* die, - const dw_offset_t next_offset, - const uint32_t curr_depth, - void* userData -) -{ - DumpInfo* dumpInfo = (DumpInfo*)userData; - Stream *s = dumpInfo->strm; - bool show_parents = s->GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowAncestors); - - if (die) - { - // Are we dumping everything? - if (dumpInfo->die_offset == DW_INVALID_OFFSET) - { - // Yes we are dumping everything. Obey our recurse level though - if (curr_depth < dumpInfo->recurse_depth) - die->Dump(dwarf2Data, cu, *s, 0); - } - else - { - // We are dumping a specific DIE entry by offset - if (dumpInfo->die_offset == die->GetOffset()) - { - // We found the DIE we were looking for, dump it! - if (show_parents) - { - s->SetIndentLevel(0); - const uint32_t num_ancestors = dumpInfo->ancestors.size(); - if (num_ancestors > 0) - { - for (uint32_t i=0; i<num_ancestors-1; ++i) - { - dumpInfo->ancestors[i].Dump(dwarf2Data, cu, *s, 0); - s->IndentMore(); - } - } - } - - dumpInfo->found_depth = curr_depth; - - die->Dump(dwarf2Data, cu, *s, 0); - - // Note that we found the DIE we were looking for - dumpInfo->found_die = true; - - // Since we are dumping a single DIE, if there are no children we are done! - if (!die->HasChildren() || dumpInfo->recurse_depth == 0) - return DW_INVALID_OFFSET; // Return an invalid address to end parsing - } - else if (dumpInfo->found_die) - { - // Are we done with all the children? - if (curr_depth <= dumpInfo->found_depth) - return DW_INVALID_OFFSET; - - // We have already found our DIE and are printing it's children. Obey - // our recurse depth and return an invalid offset if we get done - // dumping all of the children - if (dumpInfo->recurse_depth == UINT32_MAX || curr_depth <= dumpInfo->found_depth + dumpInfo->recurse_depth) - die->Dump(dwarf2Data, cu, *s, 0); - } - else if (dumpInfo->die_offset > die->GetOffset()) - { - if (show_parents) - dumpInfo->ancestors.back() = *die; +static dw_offset_t DumpCallback(SymbolFileDWARF *dwarf2Data, + DWARFCompileUnit *cu, DWARFDebugInfoEntry *die, + const dw_offset_t next_offset, + const uint32_t curr_depth, void *userData) { + DumpInfo *dumpInfo = (DumpInfo *)userData; + Stream *s = dumpInfo->strm; + bool show_parents = + s->GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowAncestors); + + if (die) { + // Are we dumping everything? + if (dumpInfo->die_offset == DW_INVALID_OFFSET) { + // Yes we are dumping everything. Obey our recurse level though + if (curr_depth < dumpInfo->recurse_depth) + die->Dump(dwarf2Data, cu, *s, 0); + } else { + // We are dumping a specific DIE entry by offset + if (dumpInfo->die_offset == die->GetOffset()) { + // We found the DIE we were looking for, dump it! + if (show_parents) { + s->SetIndentLevel(0); + const uint32_t num_ancestors = dumpInfo->ancestors.size(); + if (num_ancestors > 0) { + for (uint32_t i = 0; i < num_ancestors - 1; ++i) { + dumpInfo->ancestors[i].Dump(dwarf2Data, cu, *s, 0); + s->IndentMore(); } + } } - // Keep up with our indent level - if (die->IsNULL()) - { - if (show_parents) - dumpInfo->ancestors.pop_back(); - - if (curr_depth <= 1) - return cu->GetNextCompileUnitOffset(); - else - s->IndentLess(); - } - else if (die->HasChildren()) - { - if (show_parents) - { - DWARFDebugInfoEntry null_die; - dumpInfo->ancestors.push_back(null_die); - } - s->IndentMore(); - } + dumpInfo->found_depth = curr_depth; + + die->Dump(dwarf2Data, cu, *s, 0); + + // Note that we found the DIE we were looking for + dumpInfo->found_die = true; + + // Since we are dumping a single DIE, if there are no children we are + // done! + if (!die->HasChildren() || dumpInfo->recurse_depth == 0) + return DW_INVALID_OFFSET; // Return an invalid address to end parsing + } else if (dumpInfo->found_die) { + // Are we done with all the children? + if (curr_depth <= dumpInfo->found_depth) + return DW_INVALID_OFFSET; + + // We have already found our DIE and are printing it's children. Obey + // our recurse depth and return an invalid offset if we get done + // dumping all of the children + if (dumpInfo->recurse_depth == UINT32_MAX || + curr_depth <= dumpInfo->found_depth + dumpInfo->recurse_depth) + die->Dump(dwarf2Data, cu, *s, 0); + } else if (dumpInfo->die_offset > die->GetOffset()) { + if (show_parents) + dumpInfo->ancestors.back() = *die; + } } - else - { - if (cu == NULL) - s->PutCString("NULL - cu"); - // We have a compile unit, reset our indent level to zero just in case - s->SetIndentLevel(0); - - // See if we are dumping everything? - if (dumpInfo->die_offset == DW_INVALID_OFFSET) - { - // We are dumping everything - if (cu) - { - cu->Dump(s); - return cu->GetFirstDIEOffset(); // Return true to parse all DIEs in this Compile Unit - } - else - { - return DW_INVALID_OFFSET; - } - } - else - { - if (show_parents) - { - dumpInfo->ancestors.clear(); - dumpInfo->ancestors.resize(1); - } - // We are dumping only a single DIE possibly with it's children and - // we must find it's compile unit before we can dump it properly - if (cu && dumpInfo->die_offset < cu->GetFirstDIEOffset()) - { - // Not found, maybe the DIE offset provided wasn't correct? - // *ostrm_ptr << "DIE at offset " << HEX32 << dumpInfo->die_offset << " was not found." << endl; - return DW_INVALID_OFFSET; - } - else - { - // See if the DIE is in this compile unit? - if (cu && dumpInfo->die_offset < cu->GetNextCompileUnitOffset()) - { - // This DIE is in this compile unit! - if (s->GetVerbose()) - cu->Dump(s); // Dump the compile unit for the DIE in verbose mode - - return next_offset; - // // We found our compile unit that contains our DIE, just skip to dumping the requested DIE... - // return dumpInfo->die_offset; - } - else - { - // Skip to the next compile unit as the DIE isn't in the current one! - if (cu) - { - return cu->GetNextCompileUnitOffset(); - } - else - { - return DW_INVALID_OFFSET; - } - } - } + // Keep up with our indent level + if (die->IsNULL()) { + if (show_parents) + dumpInfo->ancestors.pop_back(); + + if (curr_depth <= 1) + return cu->GetNextCompileUnitOffset(); + else + s->IndentLess(); + } else if (die->HasChildren()) { + if (show_parents) { + DWARFDebugInfoEntry null_die; + dumpInfo->ancestors.push_back(null_die); + } + s->IndentMore(); + } + } else { + if (cu == NULL) + s->PutCString("NULL - cu"); + // We have a compile unit, reset our indent level to zero just in case + s->SetIndentLevel(0); + + // See if we are dumping everything? + if (dumpInfo->die_offset == DW_INVALID_OFFSET) { + // We are dumping everything + if (cu) { + cu->Dump(s); + return cu->GetFirstDIEOffset(); // Return true to parse all DIEs in this + // Compile Unit + } else { + return DW_INVALID_OFFSET; + } + } else { + if (show_parents) { + dumpInfo->ancestors.clear(); + dumpInfo->ancestors.resize(1); + } + + // We are dumping only a single DIE possibly with it's children and + // we must find it's compile unit before we can dump it properly + if (cu && dumpInfo->die_offset < cu->GetFirstDIEOffset()) { + // Not found, maybe the DIE offset provided wasn't correct? + // *ostrm_ptr << "DIE at offset " << HEX32 << dumpInfo->die_offset << " + // was not found." << endl; + return DW_INVALID_OFFSET; + } else { + // See if the DIE is in this compile unit? + if (cu && dumpInfo->die_offset < cu->GetNextCompileUnitOffset()) { + // This DIE is in this compile unit! + if (s->GetVerbose()) + cu->Dump(s); // Dump the compile unit for the DIE in verbose mode + + return next_offset; + // // We found our compile unit that contains our DIE, just skip to + // dumping the requested DIE... + // return dumpInfo->die_offset; + } else { + // Skip to the next compile unit as the DIE isn't in the current one! + if (cu) { + return cu->GetNextCompileUnitOffset(); + } else { + return DW_INVALID_OFFSET; + } } + } } + } - // Just return the current offset to parse the next CU or DIE entry - return next_offset; + // Just return the current offset to parse the next CU or DIE entry + return next_offset; } //---------------------------------------------------------------------- @@ -550,65 +466,51 @@ static dw_offset_t DumpCallback // headers and the DW_TAG_compile unit tags. A depth of 2 will also // dump all types and functions. //---------------------------------------------------------------------- -void -DWARFDebugInfo::Dump -( - Stream *s, - SymbolFileDWARF* dwarf2Data, - const uint32_t die_offset, - const uint32_t recurse_depth -) -{ - DumpInfo dumpInfo(s, die_offset, recurse_depth); - s->PutCString(".debug_info contents"); - if (dwarf2Data->get_debug_info_data().GetByteSize() > 0) - { - if (die_offset == DW_INVALID_OFFSET) - s->PutCString(":\n"); - else - { - s->Printf(" for DIE entry at .debug_info[0x%8.8x]", die_offset); - if (recurse_depth != UINT32_MAX) - s->Printf(" recursing %u levels deep.", recurse_depth); - s->EOL(); - } - } - else - { - s->PutCString(": < EMPTY >\n"); - return; +void DWARFDebugInfo::Dump(Stream *s, SymbolFileDWARF *dwarf2Data, + const uint32_t die_offset, + const uint32_t recurse_depth) { + DumpInfo dumpInfo(s, die_offset, recurse_depth); + s->PutCString(".debug_info contents"); + if (dwarf2Data->get_debug_info_data().GetByteSize() > 0) { + if (die_offset == DW_INVALID_OFFSET) + s->PutCString(":\n"); + else { + s->Printf(" for DIE entry at .debug_info[0x%8.8x]", die_offset); + if (recurse_depth != UINT32_MAX) + s->Printf(" recursing %u levels deep.", recurse_depth); + s->EOL(); } - DWARFDebugInfo::Parse(dwarf2Data, DumpCallback, &dumpInfo); + } else { + s->PutCString(": < EMPTY >\n"); + return; + } + DWARFDebugInfo::Parse(dwarf2Data, DumpCallback, &dumpInfo); } - //---------------------------------------------------------------------- // Dump // // Dump the contents of this DWARFDebugInfo object as has been parsed // and/or modified after it has been parsed. //---------------------------------------------------------------------- -void -DWARFDebugInfo::Dump (Stream *s, const uint32_t die_offset, const uint32_t recurse_depth) -{ - DumpInfo dumpInfo(s, die_offset, recurse_depth); +void DWARFDebugInfo::Dump(Stream *s, const uint32_t die_offset, + const uint32_t recurse_depth) { + DumpInfo dumpInfo(s, die_offset, recurse_depth); - s->PutCString("Dumping .debug_info section from internal representation\n"); + s->PutCString("Dumping .debug_info section from internal representation\n"); - CompileUnitColl::const_iterator pos; - uint32_t curr_depth = 0; - ParseCompileUnitHeadersIfNeeded(); - for (pos = m_compile_units.begin(); pos != m_compile_units.end(); ++pos) - { - DWARFCompileUnit *cu = pos->get(); - DumpCallback(m_dwarf2Data, cu, NULL, 0, curr_depth, &dumpInfo); - - const DWARFDIE die = cu->DIE(); - if (die) - die.Dump(s, recurse_depth); - } -} + CompileUnitColl::const_iterator pos; + uint32_t curr_depth = 0; + ParseCompileUnitHeadersIfNeeded(); + for (pos = m_compile_units.begin(); pos != m_compile_units.end(); ++pos) { + DWARFCompileUnit *cu = pos->get(); + DumpCallback(m_dwarf2Data, cu, NULL, 0, curr_depth, &dumpInfo); + const DWARFDIE die = cu->DIE(); + if (die) + die.Dump(s, recurse_depth); + } +} //---------------------------------------------------------------------- // FindCallbackString @@ -620,46 +522,37 @@ DWARFDebugInfo::Dump (Stream *s, const uint32_t die_offset, const uint32_t recur // This function will find the die_offset of any items whose DW_AT_name // matches the given string //---------------------------------------------------------------------- -typedef struct FindCallbackStringInfoTag -{ - const char* name; - bool ignore_case; - RegularExpression* regex; - vector<dw_offset_t>& die_offsets; +typedef struct FindCallbackStringInfoTag { + const char *name; + bool ignore_case; + RegularExpression *regex; + vector<dw_offset_t> &die_offsets; } FindCallbackStringInfo; -static dw_offset_t FindCallbackString -( - SymbolFileDWARF* dwarf2Data, - DWARFCompileUnit* cu, - DWARFDebugInfoEntry* die, - const dw_offset_t next_offset, - const uint32_t curr_depth, - void* userData -) -{ - FindCallbackStringInfo* info = (FindCallbackStringInfo*)userData; +static dw_offset_t +FindCallbackString(SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu, + DWARFDebugInfoEntry *die, const dw_offset_t next_offset, + const uint32_t curr_depth, void *userData) { + FindCallbackStringInfo *info = (FindCallbackStringInfo *)userData; - if (die) - { - const char* die_name = die->GetName(dwarf2Data, cu); - if (die_name) - { - if (info->regex) - { - if (info->regex->Execute(die_name)) - info->die_offsets.push_back(die->GetOffset()); - } - else - { - if ((info->ignore_case ? strcasecmp(die_name, info->name) : strcmp(die_name, info->name)) == 0) - info->die_offsets.push_back(die->GetOffset()); - } - } - } + if (!die) + return next_offset; - // Just return the current offset to parse the next CU or DIE entry + const char *die_name = die->GetName(dwarf2Data, cu); + if (!die_name) return next_offset; + + if (info->regex) { + if (info->regex->Execute(llvm::StringRef(die_name))) + info->die_offsets.push_back(die->GetOffset()); + } else { + if ((info->ignore_case ? strcasecmp(die_name, info->name) + : strcmp(die_name, info->name)) == 0) + info->die_offsets.push_back(die->GetOffset()); + } + + // Just return the current offset to parse the next CU or DIE entry + return next_offset; } //---------------------------------------------------------------------- @@ -670,16 +563,14 @@ static dw_offset_t FindCallbackString // .debug_pubnames section). The string must match the entire name // and case sensitive searches are an option. //---------------------------------------------------------------------- -bool -DWARFDebugInfo::Find(const char* name, bool ignore_case, vector<dw_offset_t>& die_offsets) const -{ - die_offsets.clear(); - if (name && name[0]) - { - FindCallbackStringInfo info = { name, ignore_case, NULL, die_offsets }; - DWARFDebugInfo::Parse(m_dwarf2Data, FindCallbackString, &info); - } - return !die_offsets.empty(); +bool DWARFDebugInfo::Find(const char *name, bool ignore_case, + vector<dw_offset_t> &die_offsets) const { + die_offsets.clear(); + if (name && name[0]) { + FindCallbackStringInfo info = {name, ignore_case, NULL, die_offsets}; + DWARFDebugInfo::Parse(m_dwarf2Data, FindCallbackString, &info); + } + return !die_offsets.empty(); } //---------------------------------------------------------------------- @@ -690,11 +581,10 @@ DWARFDebugInfo::Find(const char* name, bool ignore_case, vector<dw_offset_t>& di // .debug_pubnames section). The string must match the supplied regular // expression. //---------------------------------------------------------------------- -bool -DWARFDebugInfo::Find(RegularExpression& re, vector<dw_offset_t>& die_offsets) const -{ - die_offsets.clear(); - FindCallbackStringInfo info = { NULL, false, &re, die_offsets }; - DWARFDebugInfo::Parse(m_dwarf2Data, FindCallbackString, &info); - return !die_offsets.empty(); +bool DWARFDebugInfo::Find(RegularExpression &re, + vector<dw_offset_t> &die_offsets) const { + die_offsets.clear(); + FindCallbackStringInfo info = {NULL, false, &re, die_offsets}; + DWARFDebugInfo::Parse(m_dwarf2Data, FindCallbackString, &info); + return !die_offsets.empty(); } diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h index 7783135bdb95..a05a8886bb48 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h @@ -10,78 +10,82 @@ #ifndef SymbolFileDWARF_DWARFDebugInfo_h_ #define SymbolFileDWARF_DWARFDebugInfo_h_ -#include <vector> #include <map> +#include <vector> +#include "DWARFDIE.h" +#include "SymbolFileDWARF.h" #include "lldb/lldb-private.h" #include "lldb/lldb-private.h" -#include "SymbolFileDWARF.h" -#include "DWARFDIE.h" -typedef std::multimap<const char*, dw_offset_t, CStringCompareFunctionObject> CStringToDIEMap; +typedef std::multimap<const char *, dw_offset_t, CStringCompareFunctionObject> + CStringToDIEMap; typedef CStringToDIEMap::iterator CStringToDIEMapIter; typedef CStringToDIEMap::const_iterator CStringToDIEMapConstIter; -class DWARFDebugInfo -{ +class DWARFDebugInfo { public: - typedef dw_offset_t (*Callback)( - SymbolFileDWARF* dwarf2Data, - DWARFCompileUnit* cu, - DWARFDebugInfoEntry* die, - const dw_offset_t next_offset, - const uint32_t depth, - void* userData); - - DWARFDebugInfo(); - void SetDwarfData(SymbolFileDWARF* dwarf2Data); - - size_t GetNumCompileUnits(); - bool ContainsCompileUnit (const DWARFCompileUnit *cu) const; - DWARFCompileUnit* GetCompileUnitAtIndex (uint32_t idx); - DWARFCompileUnit* GetCompileUnit(dw_offset_t cu_offset, uint32_t* idx_ptr = NULL); - DWARFCompileUnit* GetCompileUnitContainingDIEOffset (dw_offset_t die_offset); - DWARFCompileUnit* GetCompileUnit(const DIERef& die_ref); - DWARFDIE GetDIEForDIEOffset(dw_offset_t die_offset); - DWARFDIE GetDIE (const DIERef& die_ref); - - void Dump(lldb_private::Stream *s, const uint32_t die_offset, const uint32_t recurse_depth); - static void Parse(SymbolFileDWARF* parser, Callback callback, void* userData); - static void Verify(lldb_private::Stream *s, SymbolFileDWARF* dwarf2Data); - static void Dump(lldb_private::Stream *s, SymbolFileDWARF* dwarf2Data, const uint32_t die_offset, const uint32_t recurse_depth); - bool Find(const char* name, bool ignore_case, std::vector<dw_offset_t>& die_offsets) const; - bool Find(lldb_private::RegularExpression& re, std::vector<dw_offset_t>& die_offsets) const; - - enum - { - eDumpFlag_Verbose = (1<<0), // Verbose dumping - eDumpFlag_ShowForm = (1<<1), // Show the DW_form type - eDumpFlag_ShowAncestors = (1<<2) // Show all parent DIEs when dumping single DIEs - }; - - DWARFDebugAranges & - GetCompileUnitAranges (); + typedef dw_offset_t (*Callback)(SymbolFileDWARF *dwarf2Data, + DWARFCompileUnit *cu, + DWARFDebugInfoEntry *die, + const dw_offset_t next_offset, + const uint32_t depth, void *userData); + + DWARFDebugInfo(); + void SetDwarfData(SymbolFileDWARF *dwarf2Data); + + size_t GetNumCompileUnits(); + bool ContainsCompileUnit(const DWARFCompileUnit *cu) const; + DWARFCompileUnit *GetCompileUnitAtIndex(uint32_t idx); + DWARFCompileUnit *GetCompileUnit(dw_offset_t cu_offset, + uint32_t *idx_ptr = NULL); + DWARFCompileUnit *GetCompileUnitContainingDIEOffset(dw_offset_t die_offset); + DWARFCompileUnit *GetCompileUnit(const DIERef &die_ref); + DWARFDIE GetDIEForDIEOffset(dw_offset_t die_offset); + DWARFDIE GetDIE(const DIERef &die_ref); + + void Dump(lldb_private::Stream *s, const uint32_t die_offset, + const uint32_t recurse_depth); + static void Parse(SymbolFileDWARF *parser, Callback callback, void *userData); + static void Verify(lldb_private::Stream *s, SymbolFileDWARF *dwarf2Data); + static void Dump(lldb_private::Stream *s, SymbolFileDWARF *dwarf2Data, + const uint32_t die_offset, const uint32_t recurse_depth); + bool Find(const char *name, bool ignore_case, + std::vector<dw_offset_t> &die_offsets) const; + bool Find(lldb_private::RegularExpression &re, + std::vector<dw_offset_t> &die_offsets) const; + + enum { + eDumpFlag_Verbose = (1 << 0), // Verbose dumping + eDumpFlag_ShowForm = (1 << 1), // Show the DW_form type + eDumpFlag_ShowAncestors = + (1 << 2) // Show all parent DIEs when dumping single DIEs + }; + + DWARFDebugAranges &GetCompileUnitAranges(); protected: - typedef std::shared_ptr<DWARFCompileUnit> DWARFCompileUnitSP; + typedef std::shared_ptr<DWARFCompileUnit> DWARFCompileUnitSP; - static bool - OffsetLessThanCompileUnitOffset (dw_offset_t offset, const DWARFCompileUnitSP& cu_sp); + static bool OffsetLessThanCompileUnitOffset(dw_offset_t offset, + const DWARFCompileUnitSP &cu_sp); - typedef std::vector<DWARFCompileUnitSP> CompileUnitColl; + typedef std::vector<DWARFCompileUnitSP> CompileUnitColl; - //---------------------------------------------------------------------- - // Member variables - //---------------------------------------------------------------------- - SymbolFileDWARF* m_dwarf2Data; - CompileUnitColl m_compile_units; - std::unique_ptr<DWARFDebugAranges> m_cu_aranges_ap; // A quick address to compile unit table + //---------------------------------------------------------------------- + // Member variables + //---------------------------------------------------------------------- + SymbolFileDWARF *m_dwarf2Data; + CompileUnitColl m_compile_units; + std::unique_ptr<DWARFDebugAranges> + m_cu_aranges_ap; // A quick address to compile unit table private: - // All parsing needs to be done partially any managed by this class as accessors are called. - void ParseCompileUnitHeadersIfNeeded(); + // All parsing needs to be done partially any managed by this class as + // accessors are called. + void ParseCompileUnitHeadersIfNeeded(); - DISALLOW_COPY_AND_ASSIGN (DWARFDebugInfo); + DISALLOW_COPY_AND_ASSIGN(DWARFDebugInfo); }; -#endif // SymbolFileDWARF_DWARFDebugInfo_h_ +#endif // SymbolFileDWARF_DWARFDebugInfo_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp index f48d8fc9eeb2..a824c4ac6afe 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -19,13 +19,13 @@ #include "lldb/Symbol/ObjectFile.h" #include "DWARFCompileUnit.h" +#include "DWARFDIECollection.h" #include "DWARFDebugAbbrev.h" #include "DWARFDebugAranges.h" #include "DWARFDebugInfo.h" +#include "DWARFDebugRanges.h" #include "DWARFDeclContext.h" -#include "DWARFDIECollection.h" #include "DWARFFormValue.h" -#include "DWARFDebugRanges.h" #include "SymbolFileDWARF.h" #include "SymbolFileDWARFDwo.h" @@ -33,159 +33,157 @@ using namespace lldb_private; using namespace std; extern int g_verbose; -bool -DWARFDebugInfoEntry::FastExtract -( - const DWARFDataExtractor& debug_info_data, - const DWARFCompileUnit* cu, - const DWARFFormValue::FixedFormSizes& fixed_form_sizes, - lldb::offset_t *offset_ptr -) -{ - 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)); - m_abbr_idx = abbr_idx; - - //assert (fixed_form_sizes); // For best performance this should be specified! - - if (m_abbr_idx) - { - lldb::offset_t offset = *offset_ptr; - - const DWARFAbbreviationDeclaration *abbrevDecl = cu->GetAbbreviations()->GetAbbreviationDeclaration(m_abbr_idx); - - if (abbrevDecl == NULL) - { - cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError ("{0x%8.8x}: invalid abbreviation code %u, please file a bug and attach the file at the start of this error message", - m_offset, - (unsigned)abbr_idx); - // WE can't parse anymore if the DWARF is borked... - *offset_ptr = UINT32_MAX; - return false; - } - m_tag = abbrevDecl->Tag(); - m_has_children = abbrevDecl->HasChildren(); - // Skip all data in the .debug_info for the attributes - const uint32_t numAttributes = abbrevDecl->NumAttributes(); - uint32_t i; - dw_form_t form; - for (i=0; i<numAttributes; ++i) - { - form = abbrevDecl->GetFormByIndexUnchecked(i); +bool DWARFDebugInfoEntry::FastExtract( + const DWARFDataExtractor &debug_info_data, const DWARFCompileUnit *cu, + const DWARFFormValue::FixedFormSizes &fixed_form_sizes, + lldb::offset_t *offset_ptr) { + 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)); + m_abbr_idx = abbr_idx; + + // assert (fixed_form_sizes); // For best performance this should be + // specified! + + if (m_abbr_idx) { + lldb::offset_t offset = *offset_ptr; - const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form); - if (fixed_skip_size) - offset += fixed_skip_size; - else - { - bool form_is_indirect = false; - do - { - form_is_indirect = false; - uint32_t form_size = 0; - switch (form) - { - // Blocks if inlined data that have a length field and the data bytes - // inlined in the .debug_info - case DW_FORM_exprloc : - case DW_FORM_block : form_size = debug_info_data.GetULEB128 (&offset); break; - case DW_FORM_block1 : form_size = debug_info_data.GetU8_unchecked (&offset); break; - case DW_FORM_block2 : form_size = debug_info_data.GetU16_unchecked (&offset);break; - case DW_FORM_block4 : form_size = debug_info_data.GetU32_unchecked (&offset);break; - - // Inlined NULL terminated C-strings - case DW_FORM_string : - debug_info_data.GetCStr (&offset); - break; - - // Compile unit address sized values - case DW_FORM_addr : - form_size = cu->GetAddressByteSize(); - break; - case DW_FORM_ref_addr : - if (cu->GetVersion() <= 2) - form_size = cu->GetAddressByteSize(); - else - form_size = cu->IsDWARF64() ? 8 : 4; - break; - - // 0 sized form - case DW_FORM_flag_present: - form_size = 0; - break; - - // 1 byte values - case DW_FORM_data1 : - case DW_FORM_flag : - case DW_FORM_ref1 : - form_size = 1; - break; - - // 2 byte values - case DW_FORM_data2 : - case DW_FORM_ref2 : - form_size = 2; - break; - - // 4 byte values - case DW_FORM_data4 : - case DW_FORM_ref4 : - form_size = 4; - break; - - // 8 byte values - case DW_FORM_data8 : - case DW_FORM_ref8 : - case DW_FORM_ref_sig8 : - form_size = 8; - break; - - // 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); - break; - - case DW_FORM_indirect : - form_is_indirect = true; - form = debug_info_data.GetULEB128 (&offset); - break; - - case DW_FORM_strp : - case DW_FORM_sec_offset : - if (cu->IsDWARF64 ()) - debug_info_data.GetU64 (offset_ptr); - else - debug_info_data.GetU32 (offset_ptr); - break; - - default: - *offset_ptr = m_offset; - return false; - } - offset += form_size; - - } while (form_is_indirect); - } - } - *offset_ptr = offset; - return true; - } - else - { - m_tag = 0; - m_has_children = false; - return true; // NULL debug tag entry + const DWARFAbbreviationDeclaration *abbrevDecl = + cu->GetAbbreviations()->GetAbbreviationDeclaration(m_abbr_idx); + + if (abbrevDecl == NULL) { + cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError( + "{0x%8.8x}: invalid abbreviation code %u, please file a bug and " + "attach the file at the start of this error message", + m_offset, (unsigned)abbr_idx); + // WE can't parse anymore if the DWARF is borked... + *offset_ptr = UINT32_MAX; + return false; } + m_tag = abbrevDecl->Tag(); + m_has_children = abbrevDecl->HasChildren(); + // Skip all data in the .debug_info for the attributes + const uint32_t numAttributes = abbrevDecl->NumAttributes(); + uint32_t i; + dw_form_t form; + for (i = 0; i < numAttributes; ++i) { + form = abbrevDecl->GetFormByIndexUnchecked(i); + + const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form); + if (fixed_skip_size) + offset += fixed_skip_size; + else { + bool form_is_indirect = false; + do { + form_is_indirect = false; + uint32_t form_size = 0; + switch (form) { + // Blocks if inlined data that have a length field and the data bytes + // inlined in the .debug_info + case DW_FORM_exprloc: + case DW_FORM_block: + form_size = debug_info_data.GetULEB128(&offset); + break; + case DW_FORM_block1: + form_size = debug_info_data.GetU8_unchecked(&offset); + break; + case DW_FORM_block2: + form_size = debug_info_data.GetU16_unchecked(&offset); + break; + case DW_FORM_block4: + form_size = debug_info_data.GetU32_unchecked(&offset); + break; + + // Inlined NULL terminated C-strings + case DW_FORM_string: + debug_info_data.GetCStr(&offset); + break; + + // Compile unit address sized values + case DW_FORM_addr: + form_size = cu->GetAddressByteSize(); + break; + case DW_FORM_ref_addr: + if (cu->GetVersion() <= 2) + form_size = cu->GetAddressByteSize(); + else + form_size = cu->IsDWARF64() ? 8 : 4; + break; + + // 0 sized form + case DW_FORM_flag_present: + form_size = 0; + break; + + // 1 byte values + case DW_FORM_data1: + case DW_FORM_flag: + case DW_FORM_ref1: + form_size = 1; + break; + + // 2 byte values + case DW_FORM_data2: + case DW_FORM_ref2: + form_size = 2; + break; + + // 4 byte values + case DW_FORM_data4: + case DW_FORM_ref4: + form_size = 4; + break; + + // 8 byte values + case DW_FORM_data8: + case DW_FORM_ref8: + case DW_FORM_ref_sig8: + form_size = 8; + break; + + // 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); + break; + + case DW_FORM_indirect: + form_is_indirect = true; + form = debug_info_data.GetULEB128(&offset); + break; + + case DW_FORM_strp: + case DW_FORM_sec_offset: + if (cu->IsDWARF64()) + debug_info_data.GetU64(offset_ptr); + else + debug_info_data.GetU32(offset_ptr); + break; - return false; + default: + *offset_ptr = m_offset; + return false; + } + offset += form_size; + + } while (form_is_indirect); + } + } + *offset_ptr = offset; + return true; + } else { + m_tag = 0; + m_has_children = false; + return true; // NULL debug tag entry + } + + return false; } //---------------------------------------------------------------------- @@ -195,165 +193,164 @@ DWARFDebugInfoEntry::FastExtract // .debug_info and .debug_abbrev data within the SymbolFileDWARF class // starting at the given offset //---------------------------------------------------------------------- -bool -DWARFDebugInfoEntry::Extract -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - lldb::offset_t *offset_ptr -) -{ - const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data(); -// const DWARFDataExtractor& debug_str_data = dwarf2Data->get_debug_str_data(); - const uint32_t cu_end_offset = cu->GetNextCompileUnitOffset(); - lldb::offset_t offset = *offset_ptr; -// if (offset >= cu_end_offset) -// Log::Error("DIE at offset 0x%8.8x is beyond the end of the current compile unit (0x%8.8x)", m_offset, cu_end_offset); - if ((offset < cu_end_offset) && debug_info_data.ValidOffset(offset)) - { - m_offset = offset; - - const uint64_t abbr_idx = debug_info_data.GetULEB128(&offset); - assert (abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE)); - m_abbr_idx = abbr_idx; - if (abbr_idx) - { - const DWARFAbbreviationDeclaration *abbrevDecl = cu->GetAbbreviations()->GetAbbreviationDeclaration(abbr_idx); - - if (abbrevDecl) - { - m_tag = abbrevDecl->Tag(); - m_has_children = abbrevDecl->HasChildren(); - - bool isCompileUnitTag = m_tag == DW_TAG_compile_unit; - if (cu && isCompileUnitTag) - const_cast<DWARFCompileUnit *>(cu)->SetBaseAddress(0); - - // 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); - - 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<DWARFCompileUnit*>(cu)->SetBaseAddress(form_value.Address()); - } - } - else - { - bool form_is_indirect = false; - do - { - form_is_indirect = false; - uint32_t form_size = 0; - switch (form) - { - // Blocks if inlined data that have a length field and the data bytes - // inlined in the .debug_info - case DW_FORM_exprloc : - case DW_FORM_block : form_size = debug_info_data.GetULEB128(&offset); break; - case DW_FORM_block1 : form_size = debug_info_data.GetU8(&offset); break; - case DW_FORM_block2 : form_size = debug_info_data.GetU16(&offset); break; - case DW_FORM_block4 : form_size = debug_info_data.GetU32(&offset); break; - - // Inlined NULL terminated C-strings - case DW_FORM_string : debug_info_data.GetCStr(&offset); break; - - // Compile unit address sized values - case DW_FORM_addr : - form_size = cu->GetAddressByteSize(); - break; - case DW_FORM_ref_addr : - if (cu->GetVersion() <= 2) - form_size = cu->GetAddressByteSize(); - else - form_size = cu->IsDWARF64() ? 8 : 4; - break; - - // 0 sized form - case DW_FORM_flag_present: - form_size = 0; - break; - - // 1 byte values - case DW_FORM_data1 : - case DW_FORM_flag : - case DW_FORM_ref1 : - form_size = 1; - break; - - // 2 byte values - case DW_FORM_data2 : - case DW_FORM_ref2 : - form_size = 2; - break; - - // 4 byte values - case DW_FORM_data4 : - case DW_FORM_ref4 : - form_size = 4; - break; - - // 8 byte values - case DW_FORM_data8 : - case DW_FORM_ref8 : - case DW_FORM_ref_sig8 : - form_size = 8; - break; - - // 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); - break; - - case DW_FORM_indirect : - form = debug_info_data.GetULEB128(&offset); - form_is_indirect = true; - break; - - case DW_FORM_strp : - case DW_FORM_sec_offset : - if (cu->IsDWARF64 ()) - debug_info_data.GetU64 (offset_ptr); - else - debug_info_data.GetU32 (offset_ptr); - break; - - default: - *offset_ptr = offset; - return false; - } - - offset += form_size; - } while (form_is_indirect); - } - } - *offset_ptr = offset; - return true; +bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data, + const DWARFCompileUnit *cu, + lldb::offset_t *offset_ptr) { + const DWARFDataExtractor &debug_info_data = dwarf2Data->get_debug_info_data(); + // const DWARFDataExtractor& debug_str_data = + // dwarf2Data->get_debug_str_data(); + const uint32_t cu_end_offset = cu->GetNextCompileUnitOffset(); + lldb::offset_t offset = *offset_ptr; + // if (offset >= cu_end_offset) + // Log::Error("DIE at offset 0x%8.8x is beyond the end of the current + // compile unit (0x%8.8x)", m_offset, cu_end_offset); + if ((offset < cu_end_offset) && debug_info_data.ValidOffset(offset)) { + m_offset = offset; + + const uint64_t abbr_idx = debug_info_data.GetULEB128(&offset); + assert(abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE)); + m_abbr_idx = abbr_idx; + if (abbr_idx) { + const DWARFAbbreviationDeclaration *abbrevDecl = + cu->GetAbbreviations()->GetAbbreviationDeclaration(abbr_idx); + + if (abbrevDecl) { + m_tag = abbrevDecl->Tag(); + m_has_children = abbrevDecl->HasChildren(); + + bool isCompileUnitTag = m_tag == DW_TAG_compile_unit; + if (cu && isCompileUnitTag) + const_cast<DWARFCompileUnit *>(cu)->SetBaseAddress(0); + + // 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); + + 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<DWARFCompileUnit *>(cu)->SetBaseAddress( + form_value.Address()); } + } else { + bool form_is_indirect = false; + do { + form_is_indirect = false; + uint32_t form_size = 0; + switch (form) { + // Blocks if inlined data that have a length field and the data + // bytes + // inlined in the .debug_info + case DW_FORM_exprloc: + case DW_FORM_block: + form_size = debug_info_data.GetULEB128(&offset); + break; + case DW_FORM_block1: + form_size = debug_info_data.GetU8(&offset); + break; + case DW_FORM_block2: + form_size = debug_info_data.GetU16(&offset); + break; + case DW_FORM_block4: + form_size = debug_info_data.GetU32(&offset); + break; + + // Inlined NULL terminated C-strings + case DW_FORM_string: + debug_info_data.GetCStr(&offset); + break; + + // Compile unit address sized values + case DW_FORM_addr: + form_size = cu->GetAddressByteSize(); + break; + case DW_FORM_ref_addr: + if (cu->GetVersion() <= 2) + form_size = cu->GetAddressByteSize(); + else + form_size = cu->IsDWARF64() ? 8 : 4; + break; + + // 0 sized form + case DW_FORM_flag_present: + form_size = 0; + break; + + // 1 byte values + case DW_FORM_data1: + case DW_FORM_flag: + case DW_FORM_ref1: + form_size = 1; + break; + + // 2 byte values + case DW_FORM_data2: + case DW_FORM_ref2: + form_size = 2; + break; + + // 4 byte values + case DW_FORM_data4: + case DW_FORM_ref4: + form_size = 4; + break; + + // 8 byte values + case DW_FORM_data8: + case DW_FORM_ref8: + case DW_FORM_ref_sig8: + form_size = 8; + break; + + // 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); + break; + + case DW_FORM_indirect: + form = debug_info_data.GetULEB128(&offset); + form_is_indirect = true; + break; + + case DW_FORM_strp: + case DW_FORM_sec_offset: + if (cu->IsDWARF64()) + debug_info_data.GetU64(offset_ptr); + else + debug_info_data.GetU32(offset_ptr); + break; + + default: + *offset_ptr = offset; + return false; + } + + offset += form_size; + } while (form_is_indirect); + } } - else - { - m_tag = 0; - m_has_children = false; - *offset_ptr = offset; - return true; // NULL debug tag entry - } + *offset_ptr = offset; + return true; + } + } else { + m_tag = 0; + m_has_children = false; + *offset_ptr = offset; + return true; // NULL debug tag entry } + } - return false; + return false; } //---------------------------------------------------------------------- @@ -362,20 +359,15 @@ DWARFDebugInfoEntry::Extract // Dumps all of a debug information entries parents up until oldest and // all of it's attributes to the specified stream. //---------------------------------------------------------------------- -void -DWARFDebugInfoEntry::DumpAncestry -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - const DWARFDebugInfoEntry* oldest, - Stream &s, - uint32_t recurse_depth -) const -{ - const DWARFDebugInfoEntry* parent = GetParent(); - if (parent && parent != oldest) - parent->DumpAncestry(dwarf2Data, cu, oldest, s, 0); - Dump(dwarf2Data, cu, s, recurse_depth); +void DWARFDebugInfoEntry::DumpAncestry(SymbolFileDWARF *dwarf2Data, + const DWARFCompileUnit *cu, + const DWARFDebugInfoEntry *oldest, + Stream &s, + uint32_t recurse_depth) const { + const DWARFDebugInfoEntry *parent = GetParent(); + if (parent && parent != oldest) + parent->DumpAncestry(dwarf2Data, cu, oldest, s, 0); + Dump(dwarf2Data, cu, s, recurse_depth); } //---------------------------------------------------------------------- @@ -385,238 +377,206 @@ DWARFDebugInfoEntry::DumpAncestry // DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges // attributes. //---------------------------------------------------------------------- -bool -DWARFDebugInfoEntry::GetDIENamesAndRanges -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - const char * &name, - const char * &mangled, - DWARFRangeList& ranges, - int& decl_file, - int& decl_line, - int& decl_column, - int& call_file, - int& call_line, - int& call_column, - DWARFExpression *frame_base -) const -{ - if (dwarf2Data == nullptr) - return false; - - SymbolFileDWARFDwo* dwo_symbol_file = cu->GetDwoSymbolFile(); - if (dwo_symbol_file) - return GetDIENamesAndRanges(dwo_symbol_file, - dwo_symbol_file->GetCompileUnit(), - name, - mangled, - ranges, - decl_file, - decl_line, - decl_column, - call_file, - call_line, - call_column, - frame_base); - - dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; - dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; - std::vector<DIERef> die_refs; - bool set_frame_base_loclist_addr = false; - - lldb::offset_t offset; - const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset); - - lldb::ModuleSP module = dwarf2Data->GetObjectFile()->GetModule(); - - if (abbrevDecl) - { - const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data(); - - if (!debug_info_data.ValidOffset(offset)) - return false; - - const uint32_t numAttributes = abbrevDecl->NumAttributes(); - uint32_t i; - dw_attr_t attr; - dw_form_t form; - bool do_offset = false; +bool DWARFDebugInfoEntry::GetDIENamesAndRanges( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, const char *&name, + const char *&mangled, DWARFRangeList &ranges, int &decl_file, + int &decl_line, int &decl_column, int &call_file, int &call_line, + int &call_column, DWARFExpression *frame_base) const { + if (dwarf2Data == nullptr) + return false; - for (i=0; i<numAttributes; ++i) - { - abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form); - DWARFFormValue form_value(cu, form); - if (form_value.ExtractValue(debug_info_data, &offset)) - { - switch (attr) - { - case DW_AT_low_pc: - lo_pc = form_value.Address(); - - if (do_offset) - hi_pc += lo_pc; - do_offset = false; - break; - - case DW_AT_entry_pc: - lo_pc = form_value.Address(); - break; - - case DW_AT_high_pc: - if (form_value.Form() == DW_FORM_addr || - form_value.Form() == DW_FORM_GNU_addr_index) - { - hi_pc = form_value.Address(); - } - else - { - hi_pc = form_value.Unsigned(); - if (lo_pc == LLDB_INVALID_ADDRESS) - do_offset = hi_pc != LLDB_INVALID_ADDRESS; - else - hi_pc += lo_pc; // DWARF 4 introduces <offset-from-lo-pc> to save on relocations - } - break; - - case DW_AT_ranges: - { - const DWARFDebugRanges* debug_ranges = dwarf2Data->DebugRanges(); - if (debug_ranges) - { - debug_ranges->FindRanges(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 - { - 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: - if (name == NULL) - name = form_value.AsCString(); - break; - - case DW_AT_MIPS_linkage_name: - case DW_AT_linkage_name: - if (mangled == NULL) - mangled = form_value.AsCString(); - break; - - case DW_AT_abstract_origin: - die_refs.emplace_back(form_value); - break; - - case DW_AT_specification: - die_refs.emplace_back(form_value); - break; - - case DW_AT_decl_file: - if (decl_file == 0) - decl_file = form_value.Unsigned(); - break; - - case DW_AT_decl_line: - if (decl_line == 0) - decl_line = form_value.Unsigned(); - break; - - case DW_AT_decl_column: - if (decl_column == 0) - decl_column = form_value.Unsigned(); - break; - - case DW_AT_call_file: - if (call_file == 0) - call_file = form_value.Unsigned(); - break; - - case DW_AT_call_line: - if (call_line == 0) - call_line = form_value.Unsigned(); - break; - - case DW_AT_call_column: - if (call_column == 0) - call_column = form_value.Unsigned(); - break; - - case DW_AT_frame_base: - if (frame_base) - { - if (form_value.BlockData()) - { - uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); - uint32_t block_length = form_value.Unsigned(); - frame_base->SetOpcodeData(module, debug_info_data, block_offset, block_length); - } - else - { - const DWARFDataExtractor &debug_loc_data = dwarf2Data->get_debug_loc_data(); - const dw_offset_t debug_loc_offset = form_value.Unsigned(); - - size_t loc_list_length = DWARFExpression::LocationListSize(cu, debug_loc_data, debug_loc_offset); - if (loc_list_length > 0) - { - frame_base->SetOpcodeData(module, debug_loc_data, debug_loc_offset, loc_list_length); - if (lo_pc != LLDB_INVALID_ADDRESS) - { - assert (lo_pc >= cu->GetBaseAddress()); - frame_base->SetLocationListSlide(lo_pc - cu->GetBaseAddress()); - } - else - { - set_frame_base_loclist_addr = true; - } - } - } - } - break; - - default: - break; + SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile(); + if (dwo_symbol_file) + return GetDIENamesAndRanges( + dwo_symbol_file, dwo_symbol_file->GetCompileUnit(), name, mangled, + ranges, decl_file, decl_line, decl_column, call_file, call_line, + call_column, frame_base); + + dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; + dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; + std::vector<DIERef> die_refs; + bool set_frame_base_loclist_addr = false; + + lldb::offset_t offset; + const DWARFAbbreviationDeclaration *abbrevDecl = + GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset); + + lldb::ModuleSP module = dwarf2Data->GetObjectFile()->GetModule(); + + if (abbrevDecl) { + const DWARFDataExtractor &debug_info_data = + dwarf2Data->get_debug_info_data(); + + if (!debug_info_data.ValidOffset(offset)) + 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); + if (form_value.ExtractValue(debug_info_data, &offset)) { + switch (attr) { + case DW_AT_low_pc: + lo_pc = form_value.Address(); + + if (do_offset) + hi_pc += lo_pc; + do_offset = false; + break; + + case DW_AT_entry_pc: + lo_pc = form_value.Address(); + break; + + case DW_AT_high_pc: + if (form_value.Form() == DW_FORM_addr || + form_value.Form() == DW_FORM_GNU_addr_index) { + hi_pc = form_value.Address(); + } else { + hi_pc = form_value.Unsigned(); + if (lo_pc == LLDB_INVALID_ADDRESS) + do_offset = hi_pc != LLDB_INVALID_ADDRESS; + else + hi_pc += lo_pc; // DWARF 4 introduces <offset-from-lo-pc> to save + // on relocations + } + 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 { + 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: + if (name == NULL) + name = form_value.AsCString(); + break; + + case DW_AT_MIPS_linkage_name: + case DW_AT_linkage_name: + if (mangled == NULL) + mangled = form_value.AsCString(); + break; + + case DW_AT_abstract_origin: + die_refs.emplace_back(form_value); + break; + + case DW_AT_specification: + die_refs.emplace_back(form_value); + break; + + case DW_AT_decl_file: + if (decl_file == 0) + decl_file = form_value.Unsigned(); + break; + + case DW_AT_decl_line: + if (decl_line == 0) + decl_line = form_value.Unsigned(); + break; + + case DW_AT_decl_column: + if (decl_column == 0) + decl_column = form_value.Unsigned(); + break; + + case DW_AT_call_file: + if (call_file == 0) + call_file = form_value.Unsigned(); + break; + + case DW_AT_call_line: + if (call_line == 0) + call_line = form_value.Unsigned(); + break; + + case DW_AT_call_column: + if (call_column == 0) + call_column = form_value.Unsigned(); + break; + + case DW_AT_frame_base: + if (frame_base) { + if (form_value.BlockData()) { + uint32_t block_offset = + form_value.BlockData() - debug_info_data.GetDataStart(); + uint32_t block_length = form_value.Unsigned(); + frame_base->SetOpcodeData(module, debug_info_data, block_offset, + block_length); + } else { + const DWARFDataExtractor &debug_loc_data = + dwarf2Data->get_debug_loc_data(); + const dw_offset_t debug_loc_offset = form_value.Unsigned(); + + size_t loc_list_length = DWARFExpression::LocationListSize( + cu, debug_loc_data, debug_loc_offset); + if (loc_list_length > 0) { + frame_base->SetOpcodeData(module, debug_loc_data, + debug_loc_offset, loc_list_length); + if (lo_pc != LLDB_INVALID_ADDRESS) { + assert(lo_pc >= cu->GetBaseAddress()); + frame_base->SetLocationListSlide(lo_pc - + cu->GetBaseAddress()); + } else { + set_frame_base_loclist_addr = true; } + } } - } - } + } + break; - if (ranges.IsEmpty()) - { - if (lo_pc != LLDB_INVALID_ADDRESS) - { - if (hi_pc != LLDB_INVALID_ADDRESS && hi_pc > lo_pc) - ranges.Append(DWARFRangeList::Entry (lo_pc, hi_pc - lo_pc)); - else - ranges.Append(DWARFRangeList::Entry (lo_pc, 0)); + default: + break; } + } } - - if (set_frame_base_loclist_addr) - { - dw_addr_t lowest_range_pc = ranges.GetMinRangeBase(0); - assert (lowest_range_pc >= cu->GetBaseAddress()); - frame_base->SetLocationListSlide (lowest_range_pc - cu->GetBaseAddress()); + } + + if (ranges.IsEmpty()) { + if (lo_pc != LLDB_INVALID_ADDRESS) { + if (hi_pc != LLDB_INVALID_ADDRESS && hi_pc > lo_pc) + ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc)); + else + ranges.Append(DWARFRangeList::Entry(lo_pc, 0)); } - - if (ranges.IsEmpty() || name == NULL || mangled == NULL) - { - for (const DIERef& die_ref : die_refs) - { - if (die_ref.die_offset != DW_INVALID_OFFSET) - { - DWARFDIE die = dwarf2Data->GetDIE(die_ref); - if (die) - die.GetDIE()->GetDIENamesAndRanges(die.GetDWARF(), die.GetCU(), name, mangled, ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column); - } - } + } + + if (set_frame_base_loclist_addr) { + dw_addr_t lowest_range_pc = ranges.GetMinRangeBase(0); + assert(lowest_range_pc >= cu->GetBaseAddress()); + frame_base->SetLocationListSlide(lowest_range_pc - cu->GetBaseAddress()); + } + + if (ranges.IsEmpty() || name == NULL || mangled == NULL) { + for (const DIERef &die_ref : die_refs) { + if (die_ref.die_offset != DW_INVALID_OFFSET) { + DWARFDIE die = dwarf2Data->GetDIE(die_ref); + if (die) + die.GetDIE()->GetDIENamesAndRanges( + die.GetDWARF(), die.GetCU(), name, mangled, ranges, decl_file, + decl_line, decl_column, call_file, call_line, call_column); + } } - return !ranges.IsEmpty(); + } + return !ranges.IsEmpty(); } //---------------------------------------------------------------------- @@ -625,95 +585,74 @@ DWARFDebugInfoEntry::GetDIENamesAndRanges // Dumps a debug information entry and all of it's attributes to the // specified stream. //---------------------------------------------------------------------- -void -DWARFDebugInfoEntry::Dump -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - Stream &s, - uint32_t recurse_depth -) const -{ - const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data(); - lldb::offset_t offset = m_offset; - - if (debug_info_data.ValidOffset(offset)) - { - dw_uleb128_t abbrCode = debug_info_data.GetULEB128(&offset); - - s.Printf("\n0x%8.8x: ", m_offset); - s.Indent(); - if (abbrCode != m_abbr_idx) - { - s.Printf( "error: DWARF has been modified\n"); - } - else if (abbrCode) - { - const DWARFAbbreviationDeclaration* abbrevDecl = cu->GetAbbreviations()->GetAbbreviationDeclaration (abbrCode); - - if (abbrevDecl) - { - s.PutCString(DW_TAG_value_to_name(abbrevDecl->Tag())); - s.Printf( " [%u] %c\n", abbrCode, abbrevDecl->HasChildren() ? '*':' '); - - // 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); - - DumpAttribute(dwarf2Data, cu, debug_info_data, &offset, s, attr, form); - } +void DWARFDebugInfoEntry::Dump(SymbolFileDWARF *dwarf2Data, + const DWARFCompileUnit *cu, Stream &s, + uint32_t recurse_depth) const { + const DWARFDataExtractor &debug_info_data = dwarf2Data->get_debug_info_data(); + lldb::offset_t offset = m_offset; + + if (debug_info_data.ValidOffset(offset)) { + dw_uleb128_t abbrCode = debug_info_data.GetULEB128(&offset); + + s.Printf("\n0x%8.8x: ", m_offset); + s.Indent(); + if (abbrCode != m_abbr_idx) { + s.Printf("error: DWARF has been modified\n"); + } else if (abbrCode) { + const DWARFAbbreviationDeclaration *abbrevDecl = + cu->GetAbbreviations()->GetAbbreviationDeclaration(abbrCode); + + if (abbrevDecl) { + s.PutCString(DW_TAG_value_to_name(abbrevDecl->Tag())); + s.Printf(" [%u] %c\n", abbrCode, abbrevDecl->HasChildren() ? '*' : ' '); + + // 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); - const DWARFDebugInfoEntry* child = GetFirstChild(); - if (recurse_depth > 0 && child) - { - s.IndentMore(); - - while (child) - { - child->Dump(dwarf2Data, cu, s, recurse_depth-1); - child = child->GetSibling(); - } - s.IndentLess(); - } - } - else - s.Printf( "Abbreviation code note found in 'debug_abbrev' class for code: %u\n", abbrCode); + DumpAttribute(dwarf2Data, cu, debug_info_data, &offset, s, attr, + form); } - else - { - s.Printf( "NULL\n"); + + const DWARFDebugInfoEntry *child = GetFirstChild(); + if (recurse_depth > 0 && child) { + s.IndentMore(); + + while (child) { + child->Dump(dwarf2Data, cu, s, recurse_depth - 1); + child = child->GetSibling(); + } + s.IndentLess(); } + } else + s.Printf("Abbreviation code note found in 'debug_abbrev' class for " + "code: %u\n", + abbrCode); + } else { + s.Printf("NULL\n"); } + } } -void -DWARFDebugInfoEntry::DumpLocation -( - SymbolFileDWARF* dwarf2Data, - DWARFCompileUnit* cu, - Stream &s -) const -{ - const DWARFDIE cu_die = cu->GetCompileUnitDIEOnly(); - const char *cu_name = NULL; - if (cu_die) - cu_name = cu_die.GetName (); - const char *obj_file_name = NULL; - ObjectFile *obj_file = dwarf2Data->GetObjectFile(); - if (obj_file) - obj_file_name = obj_file->GetFileSpec().GetFilename().AsCString("<Unknown>"); - const char *die_name = GetName (dwarf2Data, cu); - s.Printf ("0x%8.8x/0x%8.8x: %-30s (from %s in %s)", - cu->GetOffset(), - GetOffset(), - die_name ? die_name : "", - cu_name ? cu_name : "<NULL>", - obj_file_name ? obj_file_name : "<NULL>"); +void DWARFDebugInfoEntry::DumpLocation(SymbolFileDWARF *dwarf2Data, + DWARFCompileUnit *cu, Stream &s) const { + const DWARFDIE cu_die = cu->GetCompileUnitDIEOnly(); + const char *cu_name = NULL; + if (cu_die) + cu_name = cu_die.GetName(); + const char *obj_file_name = NULL; + ObjectFile *obj_file = dwarf2Data->GetObjectFile(); + if (obj_file) + obj_file_name = + obj_file->GetFileSpec().GetFilename().AsCString("<Unknown>"); + const char *die_name = GetName(dwarf2Data, cu); + s.Printf("0x%8.8x/0x%8.8x: %-30s (from %s in %s)", cu->GetOffset(), + GetOffset(), die_name ? die_name : "", cu_name ? cu_name : "<NULL>", + obj_file_name ? obj_file_name : "<NULL>"); } //---------------------------------------------------------------------- @@ -723,162 +662,142 @@ DWARFDebugInfoEntry::DumpLocation // special display of attributes is done (disassemble location lists, // show enumeration values for attributes, etc). //---------------------------------------------------------------------- -void -DWARFDebugInfoEntry::DumpAttribute -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - const DWARFDataExtractor& debug_info_data, - lldb::offset_t *offset_ptr, - Stream &s, - dw_attr_t attr, - dw_form_t form -) -{ - bool verbose = s.GetVerbose(); - bool show_form = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm); - - if (verbose) - s.Offset (*offset_ptr); - else - s.Printf (" "); - s.Indent(DW_AT_value_to_name(attr)); - - if (show_form) - { - s.Printf( "[%s", DW_FORM_value_to_name(form)); +void DWARFDebugInfoEntry::DumpAttribute( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, + const DWARFDataExtractor &debug_info_data, lldb::offset_t *offset_ptr, + Stream &s, dw_attr_t attr, dw_form_t form) { + bool verbose = s.GetVerbose(); + bool show_form = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm); + + if (verbose) + s.Offset(*offset_ptr); + else + s.Printf(" "); + s.Indent(DW_AT_value_to_name(attr)); + + if (show_form) { + s.Printf("[%s", DW_FORM_value_to_name(form)); + } + + DWARFFormValue form_value(cu, form); + + if (!form_value.ExtractValue(debug_info_data, offset_ptr)) + return; + + if (show_form) { + if (form == DW_FORM_indirect) { + s.Printf(" [%s]", DW_FORM_value_to_name(form_value.Form())); } - DWARFFormValue form_value(cu, form); + s.PutCString("] "); + } - if (!form_value.ExtractValue(debug_info_data, offset_ptr)) - return; + s.PutCString("( "); - if (show_form) - { - if (form == DW_FORM_indirect) - { - s.Printf( " [%s]", DW_FORM_value_to_name(form_value.Form())); - } + // Always dump form value if verbose is enabled + if (verbose) { + form_value.Dump(s); + } - s.PutCString("] "); - } + // Check to see if we have any special attribute formatters + switch (attr) { + case DW_AT_stmt_list: + if (verbose) + s.PutCString(" ( "); + s.Printf("0x%8.8" PRIx64, form_value.Unsigned()); + if (verbose) + s.PutCString(" )"); + break; - s.PutCString("( "); + case DW_AT_language: + if (verbose) + s.PutCString(" ( "); + s.PutCString(DW_LANG_value_to_name(form_value.Unsigned())); + if (verbose) + s.PutCString(" )"); + break; - // Always dump form value if verbose is enabled + case DW_AT_encoding: + if (verbose) + s.PutCString(" ( "); + s.PutCString(DW_ATE_value_to_name(form_value.Unsigned())); if (verbose) - { + s.PutCString(" )"); + break; + + case DW_AT_frame_base: + case DW_AT_location: + case DW_AT_data_member_location: { + const uint8_t *blockData = form_value.BlockData(); + if (blockData) { + if (!verbose) form_value.Dump(s); - } - - - // Check to see if we have any special attribute formatters - switch (attr) - { - case DW_AT_stmt_list: - if ( verbose ) s.PutCString(" ( "); - s.Printf( "0x%8.8" PRIx64, form_value.Unsigned()); - if ( verbose ) s.PutCString(" )"); - break; - - case DW_AT_language: - if ( verbose ) s.PutCString(" ( "); - s.PutCString(DW_LANG_value_to_name(form_value.Unsigned())); - if ( verbose ) s.PutCString(" )"); - break; - - case DW_AT_encoding: - if ( verbose ) s.PutCString(" ( "); - s.PutCString(DW_ATE_value_to_name(form_value.Unsigned())); - if ( verbose ) s.PutCString(" )"); - break; - - case DW_AT_frame_base: - case DW_AT_location: - case DW_AT_data_member_location: - { - const uint8_t* blockData = form_value.BlockData(); - if (blockData) - { - if (!verbose) - form_value.Dump(s); - - // Location description is inlined in data in the form value - DWARFDataExtractor locationData(debug_info_data, (*offset_ptr) - form_value.Unsigned(), form_value.Unsigned()); - if ( verbose ) s.PutCString(" ( "); - DWARFExpression::PrintDWARFExpression(s, - locationData, - DWARFCompileUnit::GetAddressByteSize(cu), - 4, - false); - if ( verbose ) s.PutCString(" )"); - } - else - { - // We have a location list offset as the value that is - // the offset into the .debug_loc section that describes - // the value over it's lifetime - uint64_t debug_loc_offset = form_value.Unsigned(); - if (dwarf2Data) - { - if ( !verbose ) - form_value.Dump(s); - DWARFExpression::PrintDWARFLocationList(s, - cu, - dwarf2Data->get_debug_loc_data(), - debug_loc_offset); - } - else - { - if ( !verbose ) - form_value.Dump(s); - } - } - } - break; - - case DW_AT_abstract_origin: - case DW_AT_specification: - { - uint64_t abstract_die_offset = form_value.Reference(); - form_value.Dump(s); - // *ostrm_ptr << HEX32 << abstract_die_offset << " ( "; - if ( verbose ) s.PutCString(" ( "); - GetName(dwarf2Data, cu, abstract_die_offset, s); - if ( verbose ) s.PutCString(" )"); - } - break; - case DW_AT_type: - { - uint64_t type_die_offset = form_value.Reference(); - if (!verbose) - form_value.Dump(s); - s.PutCString(" ( "); - AppendTypeName(dwarf2Data, cu, type_die_offset, s); - s.PutCString(" )"); - } - break; + // Location description is inlined in data in the form value + DWARFDataExtractor locationData(debug_info_data, + (*offset_ptr) - form_value.Unsigned(), + form_value.Unsigned()); + if (verbose) + s.PutCString(" ( "); + DWARFExpression::PrintDWARFExpression( + s, locationData, DWARFCompileUnit::GetAddressByteSize(cu), 4, false); + if (verbose) + s.PutCString(" )"); + } else { + // We have a location list offset as the value that is + // the offset into the .debug_loc section that describes + // the value over it's lifetime + uint64_t debug_loc_offset = form_value.Unsigned(); + if (dwarf2Data) { + if (!verbose) + form_value.Dump(s); + DWARFExpression::PrintDWARFLocationList( + s, cu, dwarf2Data->get_debug_loc_data(), debug_loc_offset); + } else { + if (!verbose) + form_value.Dump(s); + } + } + } break; - case DW_AT_ranges: - { - if ( !verbose ) - form_value.Dump(s); - lldb::offset_t ranges_offset = form_value.Unsigned(); - dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0; - if (dwarf2Data) - DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(), &ranges_offset, base_addr); - } - break; + case DW_AT_abstract_origin: + case DW_AT_specification: { + uint64_t abstract_die_offset = form_value.Reference(); + form_value.Dump(s); + // *ostrm_ptr << HEX32 << abstract_die_offset << " ( "; + if (verbose) + s.PutCString(" ( "); + GetName(dwarf2Data, cu, abstract_die_offset, s); + if (verbose) + s.PutCString(" )"); + } break; + + case DW_AT_type: { + uint64_t type_die_offset = form_value.Reference(); + if (!verbose) + form_value.Dump(s); + s.PutCString(" ( "); + AppendTypeName(dwarf2Data, cu, type_die_offset, s); + s.PutCString(" )"); + } break; + + case DW_AT_ranges: { + if (!verbose) + form_value.Dump(s); + lldb::offset_t ranges_offset = form_value.Unsigned(); + dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0; + if (dwarf2Data) + DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(), + &ranges_offset, base_addr); + } break; - default: - if ( !verbose ) - form_value.Dump(s); - break; - } + default: + if (!verbose) + form_value.Dump(s); + break; + } - s.PutCString(" )\n"); + s.PutCString(" )\n"); } //---------------------------------------------------------------------- @@ -887,94 +806,78 @@ DWARFDebugInfoEntry::DumpAttribute // the results. Any duplicate attributes will have the first instance // take precedence (this can happen for declaration attributes). //---------------------------------------------------------------------- -size_t -DWARFDebugInfoEntry::GetAttributes (const DWARFCompileUnit* cu, - DWARFFormValue::FixedFormSizes fixed_form_sizes, - DWARFAttributes& attributes, - uint32_t curr_depth) const -{ - SymbolFileDWARF* dwarf2Data = nullptr; - const DWARFAbbreviationDeclaration* abbrevDecl = nullptr; - lldb::offset_t offset = 0; - if (cu) - { - if (m_tag != DW_TAG_compile_unit) - { - SymbolFileDWARFDwo* dwo_symbol_file = cu->GetDwoSymbolFile(); - if (dwo_symbol_file) - return GetAttributes(dwo_symbol_file->GetCompileUnit(), - fixed_form_sizes, - attributes, - curr_depth); - } - - dwarf2Data = cu->GetSymbolFileDWARF(); - abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset); +size_t DWARFDebugInfoEntry::GetAttributes( + const DWARFCompileUnit *cu, DWARFFormValue::FixedFormSizes fixed_form_sizes, + DWARFAttributes &attributes, uint32_t curr_depth) const { + SymbolFileDWARF *dwarf2Data = nullptr; + const DWARFAbbreviationDeclaration *abbrevDecl = nullptr; + lldb::offset_t offset = 0; + if (cu) { + if (m_tag != DW_TAG_compile_unit) { + SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile(); + if (dwo_symbol_file) + return GetAttributes(dwo_symbol_file->GetCompileUnit(), + fixed_form_sizes, attributes, curr_depth); } - if (abbrevDecl) - { - const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data(); - - if (fixed_form_sizes.Empty()) - fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize( - 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); - - // 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 - // attributes that don't make sense. - switch (attr) - { - case DW_AT_sibling: - case DW_AT_declaration: - if (curr_depth > 0) - { - // This attribute doesn't make sense when combined with - // the DIE that references this DIE. We know a DIE is - // referencing this DIE because curr_depth is not zero - break; - } - LLVM_FALLTHROUGH; - default: - attributes.Append(cu, offset, attr, form); - break; - } - - 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 = const_cast<DWARFCompileUnit*>(cu)->GetDIE(die_offset); - if (spec_die) - spec_die.GetAttributes(attributes, curr_depth + 1); - } - } - else - { - const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form); - if (fixed_skip_size) - offset += fixed_skip_size; - else - DWARFFormValue::SkipValue(form, debug_info_data, &offset, cu); - } + dwarf2Data = cu->GetSymbolFileDWARF(); + abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset); + } + + if (abbrevDecl) { + const DWARFDataExtractor &debug_info_data = + dwarf2Data->get_debug_info_data(); + + if (fixed_form_sizes.Empty()) + fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize( + 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); + + // 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 + // attributes that don't make sense. + switch (attr) { + case DW_AT_sibling: + case DW_AT_declaration: + if (curr_depth > 0) { + // This attribute doesn't make sense when combined with + // the DIE that references this DIE. We know a DIE is + // referencing this DIE because curr_depth is not zero + break; } + LLVM_FALLTHROUGH; + default: + attributes.Append(cu, offset, attr, form); + break; + } + + 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 = + const_cast<DWARFCompileUnit *>(cu)->GetDIE(die_offset); + if (spec_die) + spec_die.GetAttributes(attributes, curr_depth + 1); + } + } else { + const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form); + if (fixed_skip_size) + offset += fixed_skip_size; + else + DWARFFormValue::SkipValue(form, debug_info_data, &offset, cu); + } } - else - { - attributes.Clear(); - } - return attributes.Size(); - + } else { + attributes.Clear(); + } + return attributes.Size(); } //---------------------------------------------------------------------- @@ -985,105 +888,84 @@ DWARFDebugInfoEntry::GetAttributes (const DWARFCompileUnit* cu, // if we fail since an offset of zero is invalid for an attribute (it // would be a compile unit header). //---------------------------------------------------------------------- -dw_offset_t -DWARFDebugInfoEntry::GetAttributeValue -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - const dw_attr_t attr, - DWARFFormValue& form_value, - dw_offset_t* end_attr_offset_ptr, - bool check_specification_or_abstract_origin -) const -{ - SymbolFileDWARFDwo* dwo_symbol_file = cu->GetDwoSymbolFile(); - if (dwo_symbol_file && m_tag != DW_TAG_compile_unit) - return GetAttributeValue(dwo_symbol_file, - dwo_symbol_file->GetCompileUnit(), - attr, - form_value, - end_attr_offset_ptr, - check_specification_or_abstract_origin); - - lldb::offset_t offset; - const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset); - - if (abbrevDecl) - { - uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr); - - if (attr_idx != DW_INVALID_INDEX) - { - const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data(); - - uint32_t idx=0; - while (idx<attr_idx) - DWARFFormValue::SkipValue(abbrevDecl->GetFormByIndex(idx++), debug_info_data, &offset, cu); - - const dw_offset_t attr_offset = offset; - form_value.SetCompileUnit(cu); - form_value.SetForm(abbrevDecl->GetFormByIndex(idx)); - if (form_value.ExtractValue(debug_info_data, &offset)) - { - if (end_attr_offset_ptr) - *end_attr_offset_ptr = offset; - return attr_offset; - } - } +dw_offset_t DWARFDebugInfoEntry::GetAttributeValue( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, + const dw_attr_t attr, DWARFFormValue &form_value, + dw_offset_t *end_attr_offset_ptr, + bool check_specification_or_abstract_origin) const { + SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile(); + if (dwo_symbol_file && m_tag != DW_TAG_compile_unit) + return GetAttributeValue(dwo_symbol_file, dwo_symbol_file->GetCompileUnit(), + attr, form_value, end_attr_offset_ptr, + check_specification_or_abstract_origin); + + lldb::offset_t offset; + const DWARFAbbreviationDeclaration *abbrevDecl = + GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset); + + if (abbrevDecl) { + uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr); + + if (attr_idx != DW_INVALID_INDEX) { + const DWARFDataExtractor &debug_info_data = + dwarf2Data->get_debug_info_data(); + + uint32_t idx = 0; + while (idx < attr_idx) + DWARFFormValue::SkipValue(abbrevDecl->GetFormByIndex(idx++), + debug_info_data, &offset, cu); + + const dw_offset_t attr_offset = offset; + form_value.SetCompileUnit(cu); + form_value.SetForm(abbrevDecl->GetFormByIndex(idx)); + if (form_value.ExtractValue(debug_info_data, &offset)) { + if (end_attr_offset_ptr) + *end_attr_offset_ptr = offset; + return attr_offset; + } + } + } + + if (check_specification_or_abstract_origin) { + if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value)) { + DWARFDIE die = + const_cast<DWARFCompileUnit *>(cu)->GetDIE(form_value.Reference()); + if (die) { + dw_offset_t die_offset = die.GetDIE()->GetAttributeValue( + die.GetDWARF(), die.GetCU(), attr, form_value, end_attr_offset_ptr, + false); + if (die_offset) + return die_offset; + } } - if (check_specification_or_abstract_origin) - { - if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value)) - { - DWARFDIE die = const_cast<DWARFCompileUnit*>(cu)->GetDIE(form_value.Reference()); - if (die) - { - dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(die.GetDWARF(), - die.GetCU(), - attr, - form_value, - end_attr_offset_ptr, - false); - if (die_offset) - return die_offset; - } - } - - if (GetAttributeValue(dwarf2Data, cu, DW_AT_abstract_origin, form_value)) - { - DWARFDIE die = const_cast<DWARFCompileUnit*>(cu)->GetDIE(form_value.Reference()); - if (die) - { - dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(die.GetDWARF(), - die.GetCU(), - attr, - form_value, - end_attr_offset_ptr, - false); - if (die_offset) - return die_offset; - } - } + if (GetAttributeValue(dwarf2Data, cu, DW_AT_abstract_origin, form_value)) { + DWARFDIE die = + const_cast<DWARFCompileUnit *>(cu)->GetDIE(form_value.Reference()); + if (die) { + dw_offset_t die_offset = die.GetDIE()->GetAttributeValue( + die.GetDWARF(), die.GetCU(), attr, form_value, end_attr_offset_ptr, + false); + if (die_offset) + return die_offset; + } } + } - if (!dwo_symbol_file) - return 0; + if (!dwo_symbol_file) + return 0; - DWARFCompileUnit* dwo_cu = dwo_symbol_file->GetCompileUnit(); - if (!dwo_cu) - return 0; + DWARFCompileUnit *dwo_cu = dwo_symbol_file->GetCompileUnit(); + if (!dwo_cu) + return 0; - DWARFDIE dwo_cu_die = dwo_cu->GetCompileUnitDIEOnly(); - if (!dwo_cu_die.IsValid()) - return 0; + DWARFDIE dwo_cu_die = dwo_cu->GetCompileUnitDIEOnly(); + if (!dwo_cu_die.IsValid()) + return 0; - return dwo_cu_die.GetDIE()->GetAttributeValue(dwo_symbol_file, - dwo_cu, - attr, - form_value, - end_attr_offset_ptr, - check_specification_or_abstract_origin); + return dwo_cu_die.GetDIE()->GetAttributeValue( + dwo_symbol_file, dwo_cu, attr, form_value, end_attr_offset_ptr, + check_specification_or_abstract_origin); } //---------------------------------------------------------------------- @@ -1094,19 +976,15 @@ DWARFDebugInfoEntry::GetAttributeValue // and will only be available as long as the SymbolFileDWARF is still around // and it's content doesn't change. //---------------------------------------------------------------------- -const char* -DWARFDebugInfoEntry::GetAttributeValueAsString -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - const dw_attr_t attr, - const char* fail_value, - bool check_specification_or_abstract_origin) const -{ - DWARFFormValue form_value; - if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr, check_specification_or_abstract_origin)) - return form_value.AsCString(); - return fail_value; +const char *DWARFDebugInfoEntry::GetAttributeValueAsString( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, + const dw_attr_t attr, const char *fail_value, + bool check_specification_or_abstract_origin) const { + DWARFFormValue form_value; + if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr, + check_specification_or_abstract_origin)) + return form_value.AsCString(); + return fail_value; } //---------------------------------------------------------------------- @@ -1114,20 +992,15 @@ DWARFDebugInfoEntry::GetAttributeValueAsString // // Get the value of an attribute as unsigned and return it. //---------------------------------------------------------------------- -uint64_t -DWARFDebugInfoEntry::GetAttributeValueAsUnsigned -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - const dw_attr_t attr, - uint64_t fail_value, - bool check_specification_or_abstract_origin -) const -{ - DWARFFormValue form_value; - if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr, check_specification_or_abstract_origin)) - return form_value.Unsigned(); - return fail_value; +uint64_t DWARFDebugInfoEntry::GetAttributeValueAsUnsigned( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, + const dw_attr_t attr, uint64_t fail_value, + bool check_specification_or_abstract_origin) const { + DWARFFormValue form_value; + if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr, + check_specification_or_abstract_origin)) + return form_value.Unsigned(); + return fail_value; } //---------------------------------------------------------------------- @@ -1135,20 +1008,15 @@ DWARFDebugInfoEntry::GetAttributeValueAsUnsigned // // Get the value of an attribute a signed value and return it. //---------------------------------------------------------------------- -int64_t -DWARFDebugInfoEntry::GetAttributeValueAsSigned -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - const dw_attr_t attr, - int64_t fail_value, - bool check_specification_or_abstract_origin -) const -{ - DWARFFormValue form_value; - if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr, check_specification_or_abstract_origin)) - return form_value.Signed(); - return fail_value; +int64_t DWARFDebugInfoEntry::GetAttributeValueAsSigned( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, + const dw_attr_t attr, int64_t fail_value, + bool check_specification_or_abstract_origin) const { + DWARFFormValue form_value; + if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr, + check_specification_or_abstract_origin)) + return form_value.Signed(); + return fail_value; } //---------------------------------------------------------------------- @@ -1157,36 +1025,26 @@ DWARFDebugInfoEntry::GetAttributeValueAsSigned // Get the value of an attribute as reference and fix up and compile // unit relative offsets as needed. //---------------------------------------------------------------------- -uint64_t -DWARFDebugInfoEntry::GetAttributeValueAsReference -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - const dw_attr_t attr, - uint64_t fail_value, - bool check_specification_or_abstract_origin -) const -{ - DWARFFormValue form_value; - if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr, check_specification_or_abstract_origin)) - return form_value.Reference(); - return fail_value; +uint64_t DWARFDebugInfoEntry::GetAttributeValueAsReference( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, + const dw_attr_t attr, uint64_t fail_value, + bool check_specification_or_abstract_origin) const { + DWARFFormValue form_value; + if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr, + check_specification_or_abstract_origin)) + return form_value.Reference(); + return fail_value; } -uint64_t -DWARFDebugInfoEntry::GetAttributeValueAsAddress -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - const dw_attr_t attr, - uint64_t fail_value, - bool check_specification_or_abstract_origin -) const -{ - DWARFFormValue form_value; - if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr, check_specification_or_abstract_origin)) - return form_value.Address(); - return fail_value; +uint64_t DWARFDebugInfoEntry::GetAttributeValueAsAddress( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, + const dw_attr_t attr, uint64_t fail_value, + bool check_specification_or_abstract_origin) const { + DWARFFormValue form_value; + if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr, + check_specification_or_abstract_origin)) + return form_value.Address(); + return fail_value; } //---------------------------------------------------------------------- @@ -1197,27 +1055,20 @@ DWARFDebugInfoEntry::GetAttributeValueAsAddress // // Returns the hi_pc or fail_value. //---------------------------------------------------------------------- -dw_addr_t -DWARFDebugInfoEntry::GetAttributeHighPC -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - dw_addr_t lo_pc, - uint64_t fail_value, - bool check_specification_or_abstract_origin -) const -{ - DWARFFormValue form_value; - if (GetAttributeValue(dwarf2Data, cu, DW_AT_high_pc, form_value, nullptr, check_specification_or_abstract_origin)) - { - dw_form_t form = form_value.Form(); - if (form == DW_FORM_addr || form == DW_FORM_GNU_addr_index) - return form_value.Address(); - - // DWARF4 can specify the hi_pc as an <offset-from-lowpc> - return lo_pc + form_value.Unsigned(); - } - return fail_value; +dw_addr_t DWARFDebugInfoEntry::GetAttributeHighPC( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, dw_addr_t lo_pc, + uint64_t fail_value, bool check_specification_or_abstract_origin) const { + DWARFFormValue form_value; + if (GetAttributeValue(dwarf2Data, cu, DW_AT_high_pc, form_value, nullptr, + check_specification_or_abstract_origin)) { + dw_form_t form = form_value.Form(); + if (form == DW_FORM_addr || form == DW_FORM_GNU_addr_index) + return form_value.Address(); + + // DWARF4 can specify the hi_pc as an <offset-from-lowpc> + return lo_pc + form_value.Unsigned(); + } + return fail_value; } //---------------------------------------------------------------------- @@ -1228,61 +1079,48 @@ DWARFDebugInfoEntry::GetAttributeHighPC // // Returns true or sets lo_pc and hi_pc to fail_value. //---------------------------------------------------------------------- -bool -DWARFDebugInfoEntry::GetAttributeAddressRange -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - dw_addr_t& lo_pc, - dw_addr_t& hi_pc, - uint64_t fail_value, - bool check_specification_or_abstract_origin -) const -{ - lo_pc = GetAttributeValueAsAddress(dwarf2Data, cu, DW_AT_low_pc, fail_value, check_specification_or_abstract_origin); - if (lo_pc != fail_value) - { - hi_pc = GetAttributeHighPC(dwarf2Data, cu, lo_pc, fail_value, check_specification_or_abstract_origin); - if (hi_pc != fail_value) - return true; - } - lo_pc = fail_value; - hi_pc = fail_value; - return false; +bool DWARFDebugInfoEntry::GetAttributeAddressRange( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, dw_addr_t &lo_pc, + dw_addr_t &hi_pc, uint64_t fail_value, + bool check_specification_or_abstract_origin) const { + lo_pc = GetAttributeValueAsAddress(dwarf2Data, cu, DW_AT_low_pc, fail_value, + check_specification_or_abstract_origin); + if (lo_pc != fail_value) { + hi_pc = GetAttributeHighPC(dwarf2Data, cu, lo_pc, fail_value, + check_specification_or_abstract_origin); + if (hi_pc != fail_value) + return true; + } + lo_pc = fail_value; + hi_pc = fail_value; + return false; } -size_t -DWARFDebugInfoEntry::GetAttributeAddressRanges (SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - DWARFRangeList &ranges, - bool check_hi_lo_pc, - 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(debug_ranges_offset, ranges); - ranges.Slide (cu->GetBaseAddress()); - } - else if (check_hi_lo_pc) - { - dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; - dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; - if (GetAttributeAddressRange (dwarf2Data, cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS, check_specification_or_abstract_origin)) - { - if (lo_pc < hi_pc) - ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc)); - } +size_t DWARFDebugInfoEntry::GetAttributeAddressRanges( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, + DWARFRangeList &ranges, bool check_hi_lo_pc, + 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()); + } else if (check_hi_lo_pc) { + dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; + dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; + if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc, + LLDB_INVALID_ADDRESS, + check_specification_or_abstract_origin)) { + if (lo_pc < hi_pc) + ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc)); } - return ranges.GetSize(); + } + return ranges.GetSize(); } //---------------------------------------------------------------------- @@ -1291,14 +1129,9 @@ DWARFDebugInfoEntry::GetAttributeAddressRanges (SymbolFileDWARF* dwarf2Data, // Get value of the DW_AT_name attribute and return it if one exists, // else return NULL. //---------------------------------------------------------------------- -const char* -DWARFDebugInfoEntry::GetName -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu -) const -{ - return GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true); +const char *DWARFDebugInfoEntry::GetName(SymbolFileDWARF *dwarf2Data, + const DWARFCompileUnit *cu) const { + return GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true); } //---------------------------------------------------------------------- @@ -1307,31 +1140,28 @@ DWARFDebugInfoEntry::GetName // Get value of the DW_AT_MIPS_linkage_name attribute and return it if // one exists, else return the value of the DW_AT_name attribute //---------------------------------------------------------------------- -const char* -DWARFDebugInfoEntry::GetMangledName -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - bool substitute_name_allowed -) const -{ - const char* name = nullptr; - - name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_MIPS_linkage_name, nullptr, true); - if (name) - return name; - - name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_linkage_name, nullptr, true); - if (name) - return name; - - if (!substitute_name_allowed) - return nullptr; - - name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true); +const char * +DWARFDebugInfoEntry::GetMangledName(SymbolFileDWARF *dwarf2Data, + const DWARFCompileUnit *cu, + bool substitute_name_allowed) const { + const char *name = nullptr; + + name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_MIPS_linkage_name, + nullptr, true); + if (name) return name; -} + name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_linkage_name, nullptr, + true); + if (name) + return name; + + if (!substitute_name_allowed) + return nullptr; + + name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true); + return name; +} //---------------------------------------------------------------------- // GetPubname @@ -1339,29 +1169,25 @@ DWARFDebugInfoEntry::GetMangledName // Get value the name for a DIE as it should appear for a // .debug_pubnames or .debug_pubtypes section. //---------------------------------------------------------------------- -const char* -DWARFDebugInfoEntry::GetPubname -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu -) const -{ - const char* name = nullptr; - if (!dwarf2Data) - return name; - - name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_MIPS_linkage_name, nullptr, true); - if (name) - return name; - - name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_linkage_name, nullptr, true); - if (name) - return name; - - name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true); +const char *DWARFDebugInfoEntry::GetPubname(SymbolFileDWARF *dwarf2Data, + const DWARFCompileUnit *cu) const { + const char *name = nullptr; + if (!dwarf2Data) return name; -} + name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_MIPS_linkage_name, + nullptr, true); + if (name) + return name; + + name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_linkage_name, nullptr, + true); + if (name) + return name; + + name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true); + return name; +} //---------------------------------------------------------------------- // GetName @@ -1372,41 +1198,30 @@ DWARFDebugInfoEntry::GetPubname // into the stream, and if no DW_AT_name attribute exists for the DIE // then nothing is printed. //---------------------------------------------------------------------- -bool -DWARFDebugInfoEntry::GetName -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - const dw_offset_t die_offset, - Stream &s -) -{ - if (dwarf2Data == NULL) - { - s.PutCString("NULL"); - return false; - } - - DWARFDebugInfoEntry die; - lldb::offset_t offset = die_offset; - if (die.Extract(dwarf2Data, cu, &offset)) - { - if (die.IsNULL()) - { - s.PutCString("NULL"); - return true; - } - else - { - const char* name = die.GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true); - if (name) - { - s.PutCString(name); - return true; - } - } - } +bool DWARFDebugInfoEntry::GetName(SymbolFileDWARF *dwarf2Data, + const DWARFCompileUnit *cu, + const dw_offset_t die_offset, Stream &s) { + if (dwarf2Data == NULL) { + s.PutCString("NULL"); return false; + } + + DWARFDebugInfoEntry die; + lldb::offset_t offset = die_offset; + if (die.Extract(dwarf2Data, cu, &offset)) { + if (die.IsNULL()) { + s.PutCString("NULL"); + return true; + } else { + const char *name = die.GetAttributeValueAsString( + dwarf2Data, cu, DW_AT_name, nullptr, true); + if (name) { + s.PutCString(name); + return true; + } + } + } + return false; } //---------------------------------------------------------------------- @@ -1417,144 +1232,168 @@ DWARFDebugInfoEntry::GetName // the supplied stream. This is used to show the name of types given // a type identifier. //---------------------------------------------------------------------- -bool -DWARFDebugInfoEntry::AppendTypeName -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - const dw_offset_t die_offset, - Stream &s -) -{ - if (dwarf2Data == NULL) - { - s.PutCString("NULL"); - return false; - } - - DWARFDebugInfoEntry die; - lldb::offset_t offset = die_offset; - if (die.Extract(dwarf2Data, cu, &offset)) - { - if (die.IsNULL()) - { - s.PutCString("NULL"); - return true; +bool DWARFDebugInfoEntry::AppendTypeName(SymbolFileDWARF *dwarf2Data, + const DWARFCompileUnit *cu, + const dw_offset_t die_offset, + Stream &s) { + if (dwarf2Data == NULL) { + s.PutCString("NULL"); + return false; + } + + DWARFDebugInfoEntry die; + lldb::offset_t offset = die_offset; + if (die.Extract(dwarf2Data, cu, &offset)) { + if (die.IsNULL()) { + s.PutCString("NULL"); + return true; + } else { + const char *name = die.GetPubname(dwarf2Data, cu); + if (name) + s.PutCString(name); + else { + bool result = true; + const DWARFAbbreviationDeclaration *abbrevDecl = + die.GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset); + + if (abbrevDecl == NULL) + return false; + + switch (abbrevDecl->Tag()) { + case DW_TAG_array_type: + break; // print out a "[]" after printing the full type of the element + // below + case DW_TAG_base_type: + s.PutCString("base "); + break; + case DW_TAG_class_type: + s.PutCString("class "); + break; + case DW_TAG_const_type: + s.PutCString("const "); + break; + case DW_TAG_enumeration_type: + s.PutCString("enum "); + break; + case DW_TAG_file_type: + s.PutCString("file "); + break; + case DW_TAG_interface_type: + s.PutCString("interface "); + break; + case DW_TAG_packed_type: + s.PutCString("packed "); + break; + case DW_TAG_pointer_type: + break; // print out a '*' after printing the full type below + case DW_TAG_ptr_to_member_type: + break; // print out a '*' after printing the full type below + case DW_TAG_reference_type: + break; // print out a '&' after printing the full type below + case DW_TAG_restrict_type: + s.PutCString("restrict "); + break; + case DW_TAG_set_type: + s.PutCString("set "); + break; + case DW_TAG_shared_type: + s.PutCString("shared "); + break; + case DW_TAG_string_type: + s.PutCString("string "); + break; + case DW_TAG_structure_type: + s.PutCString("struct "); + break; + case DW_TAG_subrange_type: + s.PutCString("subrange "); + break; + case DW_TAG_subroutine_type: + s.PutCString("function "); + break; + case DW_TAG_thrown_type: + s.PutCString("thrown "); + break; + case DW_TAG_union_type: + s.PutCString("union "); + break; + case DW_TAG_unspecified_type: + s.PutCString("unspecified "); + break; + case DW_TAG_volatile_type: + s.PutCString("volatile "); + break; + default: + return false; } - else - { - const char* name = die.GetPubname(dwarf2Data, cu); - if (name) - s.PutCString(name); - else - { - bool result = true; - const DWARFAbbreviationDeclaration* abbrevDecl = die.GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset); - - if (abbrevDecl == NULL) - return false; - - switch (abbrevDecl->Tag()) - { - case DW_TAG_array_type: break; // print out a "[]" after printing the full type of the element below - case DW_TAG_base_type: s.PutCString("base "); break; - case DW_TAG_class_type: s.PutCString("class "); break; - case DW_TAG_const_type: s.PutCString("const "); break; - case DW_TAG_enumeration_type: s.PutCString("enum "); break; - case DW_TAG_file_type: s.PutCString("file "); break; - case DW_TAG_interface_type: s.PutCString("interface "); break; - case DW_TAG_packed_type: s.PutCString("packed "); break; - case DW_TAG_pointer_type: break; // print out a '*' after printing the full type below - case DW_TAG_ptr_to_member_type: break; // print out a '*' after printing the full type below - case DW_TAG_reference_type: break; // print out a '&' after printing the full type below - case DW_TAG_restrict_type: s.PutCString("restrict "); break; - case DW_TAG_set_type: s.PutCString("set "); break; - case DW_TAG_shared_type: s.PutCString("shared "); break; - case DW_TAG_string_type: s.PutCString("string "); break; - case DW_TAG_structure_type: s.PutCString("struct "); break; - case DW_TAG_subrange_type: s.PutCString("subrange "); break; - case DW_TAG_subroutine_type: s.PutCString("function "); break; - case DW_TAG_thrown_type: s.PutCString("thrown "); break; - case DW_TAG_union_type: s.PutCString("union "); break; - case DW_TAG_unspecified_type: s.PutCString("unspecified "); break; - case DW_TAG_volatile_type: s.PutCString("volatile "); break; - default: - return false; - } - // Follow the DW_AT_type if possible - DWARFFormValue form_value; - if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_type, form_value)) - { - uint64_t next_die_offset = form_value.Reference(); - result = AppendTypeName(dwarf2Data, cu, next_die_offset, s); - } + // Follow the DW_AT_type if possible + DWARFFormValue form_value; + if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_type, form_value)) { + uint64_t next_die_offset = form_value.Reference(); + result = AppendTypeName(dwarf2Data, cu, next_die_offset, s); + } - switch (abbrevDecl->Tag()) - { - case DW_TAG_array_type: s.PutCString("[]"); break; - case DW_TAG_pointer_type: s.PutChar('*'); break; - case DW_TAG_ptr_to_member_type: s.PutChar('*'); break; - case DW_TAG_reference_type: s.PutChar('&'); break; - default: - break; - } - return result; - } + switch (abbrevDecl->Tag()) { + case DW_TAG_array_type: + s.PutCString("[]"); + break; + case DW_TAG_pointer_type: + s.PutChar('*'); + break; + case DW_TAG_ptr_to_member_type: + s.PutChar('*'); + break; + case DW_TAG_reference_type: + s.PutChar('&'); + break; + default: + break; } + return result; + } } - return false; + } + return false; } -bool -DWARFDebugInfoEntry::Contains (const DWARFDebugInfoEntry *die) const -{ - if (die) - { - const dw_offset_t die_offset = die->GetOffset(); - if (die_offset > GetOffset()) - { - const DWARFDebugInfoEntry *sibling = GetSibling(); - assert (sibling); // TODO: take this out - if (sibling) - return die_offset < sibling->GetOffset(); - } +bool DWARFDebugInfoEntry::Contains(const DWARFDebugInfoEntry *die) const { + if (die) { + const dw_offset_t die_offset = die->GetOffset(); + if (die_offset > GetOffset()) { + const DWARFDebugInfoEntry *sibling = GetSibling(); + assert(sibling); // TODO: take this out + if (sibling) + return die_offset < sibling->GetOffset(); } - return false; + } + return false; } //---------------------------------------------------------------------- // BuildAddressRangeTable //---------------------------------------------------------------------- -void -DWARFDebugInfoEntry::BuildAddressRangeTable -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - DWARFDebugAranges* debug_aranges -) const -{ - if (m_tag) - { - if (m_tag == DW_TAG_subprogram) - { - dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; - dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; - if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS)) - { - /// printf("BuildAddressRangeTable() 0x%8.8x: %30s: [0x%8.8x - 0x%8.8x)\n", m_offset, DW_TAG_value_to_name(tag), lo_pc, hi_pc); - debug_aranges->AppendRange (cu->GetOffset(), lo_pc, hi_pc); - } - } - +void DWARFDebugInfoEntry::BuildAddressRangeTable( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, + DWARFDebugAranges *debug_aranges) const { + if (m_tag) { + if (m_tag == DW_TAG_subprogram) { + dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; + dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; + if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc, + LLDB_INVALID_ADDRESS)) { + /// printf("BuildAddressRangeTable() 0x%8.8x: %30s: [0x%8.8x - + /// 0x%8.8x)\n", m_offset, DW_TAG_value_to_name(tag), lo_pc, hi_pc); + debug_aranges->AppendRange(cu->GetOffset(), lo_pc, hi_pc); + } + } - const DWARFDebugInfoEntry* child = GetFirstChild(); - while (child) - { - child->BuildAddressRangeTable(dwarf2Data, cu, debug_aranges); - child = child->GetSibling(); - } + const DWARFDebugInfoEntry *child = GetFirstChild(); + while (child) { + child->BuildAddressRangeTable(dwarf2Data, cu, debug_aranges); + child = child->GetSibling(); } + } } //---------------------------------------------------------------------- @@ -1565,477 +1404,478 @@ DWARFDebugInfoEntry::BuildAddressRangeTable // table instead of the compile unit offset (which is the way the // standard .debug_aranges section does it). //---------------------------------------------------------------------- -void -DWARFDebugInfoEntry::BuildFunctionAddressRangeTable -( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - DWARFDebugAranges* debug_aranges -) const -{ - if (m_tag) - { - if (m_tag == DW_TAG_subprogram) - { - dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; - dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; - if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS)) - { - // printf("BuildAddressRangeTable() 0x%8.8x: [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n", m_offset, lo_pc, hi_pc); // DEBUG ONLY - debug_aranges->AppendRange (GetOffset(), lo_pc, hi_pc); - } - } +void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, + DWARFDebugAranges *debug_aranges) const { + if (m_tag) { + if (m_tag == DW_TAG_subprogram) { + dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; + dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; + if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc, + LLDB_INVALID_ADDRESS)) { + // printf("BuildAddressRangeTable() 0x%8.8x: [0x%16.16" PRIx64 " - + // 0x%16.16" PRIx64 ")\n", m_offset, lo_pc, hi_pc); // DEBUG ONLY + debug_aranges->AppendRange(GetOffset(), lo_pc, hi_pc); + } + } - const DWARFDebugInfoEntry* child = GetFirstChild(); - while (child) - { - child->BuildFunctionAddressRangeTable(dwarf2Data, cu, debug_aranges); - child = child->GetSibling(); - } + const DWARFDebugInfoEntry *child = GetFirstChild(); + while (child) { + child->BuildFunctionAddressRangeTable(dwarf2Data, cu, debug_aranges); + child = child->GetSibling(); } + } } -void -DWARFDebugInfoEntry::GetDeclContextDIEs (DWARFCompileUnit* cu, - DWARFDIECollection &decl_context_dies) const -{ +void DWARFDebugInfoEntry::GetDeclContextDIEs( + DWARFCompileUnit *cu, DWARFDIECollection &decl_context_dies) const { - DWARFDIE die (cu, const_cast<DWARFDebugInfoEntry *>(this)); - die.GetDeclContextDIEs(decl_context_dies); + DWARFDIE die(cu, const_cast<DWARFDebugInfoEntry *>(this)); + die.GetDeclContextDIEs(decl_context_dies); } -void -DWARFDebugInfoEntry::GetDWARFDeclContext (SymbolFileDWARF* dwarf2Data, - DWARFCompileUnit* cu, - DWARFDeclContext &dwarf_decl_ctx) const -{ - const dw_tag_t tag = Tag(); - if (tag != DW_TAG_compile_unit) - { - dwarf_decl_ctx.AppendDeclContext(tag, GetName(dwarf2Data, cu)); - DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE (dwarf2Data, cu); - if (parent_decl_ctx_die && parent_decl_ctx_die.GetDIE() != this) - { - if (parent_decl_ctx_die.Tag() != DW_TAG_compile_unit) - parent_decl_ctx_die.GetDIE()->GetDWARFDeclContext (parent_decl_ctx_die.GetDWARF(), parent_decl_ctx_die.GetCU(), dwarf_decl_ctx); - } +void DWARFDebugInfoEntry::GetDWARFDeclContext( + SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu, + DWARFDeclContext &dwarf_decl_ctx) const { + const dw_tag_t tag = Tag(); + if (tag != DW_TAG_compile_unit) { + dwarf_decl_ctx.AppendDeclContext(tag, GetName(dwarf2Data, cu)); + DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(dwarf2Data, cu); + if (parent_decl_ctx_die && parent_decl_ctx_die.GetDIE() != this) { + if (parent_decl_ctx_die.Tag() != DW_TAG_compile_unit) + parent_decl_ctx_die.GetDIE()->GetDWARFDeclContext( + parent_decl_ctx_die.GetDWARF(), parent_decl_ctx_die.GetCU(), + dwarf_decl_ctx); } + } } +bool DWARFDebugInfoEntry::MatchesDWARFDeclContext( + SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu, + const DWARFDeclContext &dwarf_decl_ctx) const { -bool -DWARFDebugInfoEntry::MatchesDWARFDeclContext (SymbolFileDWARF* dwarf2Data, - DWARFCompileUnit* cu, - const DWARFDeclContext &dwarf_decl_ctx) const -{ - - DWARFDeclContext this_dwarf_decl_ctx; - GetDWARFDeclContext (dwarf2Data, cu, this_dwarf_decl_ctx); - return this_dwarf_decl_ctx == dwarf_decl_ctx; + DWARFDeclContext this_dwarf_decl_ctx; + GetDWARFDeclContext(dwarf2Data, cu, this_dwarf_decl_ctx); + return this_dwarf_decl_ctx == dwarf_decl_ctx; } DWARFDIE -DWARFDebugInfoEntry::GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data, - DWARFCompileUnit* cu) const -{ - DWARFAttributes attributes; - GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes); - return GetParentDeclContextDIE (dwarf2Data, cu, attributes); +DWARFDebugInfoEntry::GetParentDeclContextDIE(SymbolFileDWARF *dwarf2Data, + DWARFCompileUnit *cu) const { + DWARFAttributes attributes; + GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes); + return GetParentDeclContextDIE(dwarf2Data, cu, attributes); } DWARFDIE -DWARFDebugInfoEntry::GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data, - DWARFCompileUnit* cu, - const DWARFAttributes& attributes) const -{ - DWARFDIE die (cu, const_cast<DWARFDebugInfoEntry *>(this)); - - while (die) - { - // If this is the original DIE that we are searching for a declaration - // for, then don't look in the cache as we don't want our own decl - // context to be our decl context... - if (die.GetDIE() != this) - { - switch (die.Tag()) - { - case DW_TAG_compile_unit: - case DW_TAG_namespace: - case DW_TAG_structure_type: - case DW_TAG_union_type: - case DW_TAG_class_type: - return die; - - default: - break; - } - } - - dw_offset_t die_offset; - - die_offset = attributes.FormValueAsUnsigned(DW_AT_specification, DW_INVALID_OFFSET); - if (die_offset != DW_INVALID_OFFSET) - { - DWARFDIE spec_die = cu->GetDIE (die_offset); - if (spec_die) - { - DWARFDIE decl_ctx_die = spec_die.GetParentDeclContextDIE(); - if (decl_ctx_die) - return decl_ctx_die; - } - } - - die_offset = attributes.FormValueAsUnsigned(DW_AT_abstract_origin, DW_INVALID_OFFSET); - if (die_offset != DW_INVALID_OFFSET) - { - DWARFDIE abs_die = cu->GetDIE (die_offset); - if (abs_die) - { - DWARFDIE decl_ctx_die = abs_die.GetParentDeclContextDIE(); - if (decl_ctx_die) - return decl_ctx_die; - } - } - - die = die.GetParent(); - } - return DWARFDIE(); -} +DWARFDebugInfoEntry::GetParentDeclContextDIE( + SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu, + const DWARFAttributes &attributes) const { + DWARFDIE die(cu, const_cast<DWARFDebugInfoEntry *>(this)); + + while (die) { + // If this is the original DIE that we are searching for a declaration + // for, then don't look in the cache as we don't want our own decl + // context to be our decl context... + if (die.GetDIE() != this) { + switch (die.Tag()) { + case DW_TAG_compile_unit: + case DW_TAG_namespace: + case DW_TAG_structure_type: + case DW_TAG_union_type: + case DW_TAG_class_type: + return die; + + default: + break; + } + } + + dw_offset_t die_offset; + + die_offset = + attributes.FormValueAsUnsigned(DW_AT_specification, DW_INVALID_OFFSET); + if (die_offset != DW_INVALID_OFFSET) { + DWARFDIE spec_die = cu->GetDIE(die_offset); + if (spec_die) { + DWARFDIE decl_ctx_die = spec_die.GetParentDeclContextDIE(); + if (decl_ctx_die) + return decl_ctx_die; + } + } + die_offset = attributes.FormValueAsUnsigned(DW_AT_abstract_origin, + DW_INVALID_OFFSET); + if (die_offset != DW_INVALID_OFFSET) { + DWARFDIE abs_die = cu->GetDIE(die_offset); + if (abs_die) { + DWARFDIE decl_ctx_die = abs_die.GetParentDeclContextDIE(); + if (decl_ctx_die) + return decl_ctx_die; + } + } -const char * -DWARFDebugInfoEntry::GetQualifiedName (SymbolFileDWARF* dwarf2Data, - DWARFCompileUnit* cu, - std::string &storage) const -{ - DWARFAttributes attributes; - GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes); - return GetQualifiedName (dwarf2Data, cu, attributes, storage); + die = die.GetParent(); + } + return DWARFDIE(); } -const char* -DWARFDebugInfoEntry::GetQualifiedName (SymbolFileDWARF* dwarf2Data, - DWARFCompileUnit* cu, - const DWARFAttributes& attributes, - std::string &storage) const -{ - - const char *name = GetName (dwarf2Data, cu); - - if (name) - { - DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE (dwarf2Data, cu); - storage.clear(); - // TODO: change this to get the correct decl context parent.... - while (parent_decl_ctx_die) - { - const dw_tag_t parent_tag = parent_decl_ctx_die.Tag(); - switch (parent_tag) - { - case DW_TAG_namespace: - { - const char *namespace_name = parent_decl_ctx_die.GetName (); - if (namespace_name) - { - storage.insert (0, "::"); - storage.insert (0, namespace_name); - } - else - { - storage.insert (0, "(anonymous namespace)::"); - } - parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE(); - } - break; - - case DW_TAG_class_type: - case DW_TAG_structure_type: - case DW_TAG_union_type: - { - const char *class_union_struct_name = parent_decl_ctx_die.GetName (); - - if (class_union_struct_name) - { - storage.insert (0, "::"); - storage.insert (0, class_union_struct_name); - } - parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE(); - } - break; - - default: - parent_decl_ctx_die.Clear(); - break; - } - } - - if (storage.empty()) - storage.append ("::"); - - storage.append (name); - } - if (storage.empty()) - return NULL; - return storage.c_str(); +const char *DWARFDebugInfoEntry::GetQualifiedName(SymbolFileDWARF *dwarf2Data, + DWARFCompileUnit *cu, + std::string &storage) const { + DWARFAttributes attributes; + GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes); + return GetQualifiedName(dwarf2Data, cu, attributes, storage); } +const char *DWARFDebugInfoEntry::GetQualifiedName( + SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu, + const DWARFAttributes &attributes, std::string &storage) const { + + const char *name = GetName(dwarf2Data, cu); + + if (name) { + DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(dwarf2Data, cu); + storage.clear(); + // TODO: change this to get the correct decl context parent.... + while (parent_decl_ctx_die) { + const dw_tag_t parent_tag = parent_decl_ctx_die.Tag(); + switch (parent_tag) { + case DW_TAG_namespace: { + const char *namespace_name = parent_decl_ctx_die.GetName(); + if (namespace_name) { + storage.insert(0, "::"); + storage.insert(0, namespace_name); + } else { + storage.insert(0, "(anonymous namespace)::"); + } + parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE(); + } break; + + case DW_TAG_class_type: + case DW_TAG_structure_type: + case DW_TAG_union_type: { + const char *class_union_struct_name = parent_decl_ctx_die.GetName(); + + if (class_union_struct_name) { + storage.insert(0, "::"); + storage.insert(0, class_union_struct_name); + } + parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE(); + } break; + + default: + parent_decl_ctx_die.Clear(); + break; + } + } + + if (storage.empty()) + storage.append("::"); + + storage.append(name); + } + if (storage.empty()) + return NULL; + return storage.c_str(); +} //---------------------------------------------------------------------- // LookupAddress //---------------------------------------------------------------------- -bool -DWARFDebugInfoEntry::LookupAddress -( - const dw_addr_t address, - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - DWARFDebugInfoEntry** function_die, - DWARFDebugInfoEntry** block_die -) -{ - bool found_address = false; - if (m_tag) - { - bool check_children = false; - bool match_addr_range = false; - // printf("0x%8.8x: %30s: address = 0x%8.8x - ", m_offset, DW_TAG_value_to_name(tag), address); - switch (m_tag) - { - case DW_TAG_array_type : break; - case DW_TAG_class_type : check_children = true; break; - case DW_TAG_entry_point : break; - case DW_TAG_enumeration_type : break; - case DW_TAG_formal_parameter : break; - case DW_TAG_imported_declaration : break; - case DW_TAG_label : break; - case DW_TAG_lexical_block : check_children = true; match_addr_range = true; break; - case DW_TAG_member : break; - case DW_TAG_pointer_type : break; - case DW_TAG_reference_type : break; - case DW_TAG_compile_unit : match_addr_range = true; break; - case DW_TAG_string_type : break; - case DW_TAG_structure_type : check_children = true; break; - case DW_TAG_subroutine_type : break; - case DW_TAG_typedef : break; - case DW_TAG_union_type : break; - case DW_TAG_unspecified_parameters : break; - case DW_TAG_variant : break; - case DW_TAG_common_block : check_children = true; break; - case DW_TAG_common_inclusion : break; - case DW_TAG_inheritance : break; - case DW_TAG_inlined_subroutine : check_children = true; match_addr_range = true; break; - case DW_TAG_module : match_addr_range = true; break; - case DW_TAG_ptr_to_member_type : break; - case DW_TAG_set_type : break; - case DW_TAG_subrange_type : break; - case DW_TAG_with_stmt : break; - case DW_TAG_access_declaration : break; - case DW_TAG_base_type : break; - case DW_TAG_catch_block : match_addr_range = true; break; - case DW_TAG_const_type : break; - case DW_TAG_constant : break; - case DW_TAG_enumerator : break; - case DW_TAG_file_type : break; - case DW_TAG_friend : break; - case DW_TAG_namelist : break; - case DW_TAG_namelist_item : break; - case DW_TAG_packed_type : break; - case DW_TAG_subprogram : match_addr_range = true; break; - case DW_TAG_template_type_parameter : break; - case DW_TAG_template_value_parameter : break; - case DW_TAG_thrown_type : break; - case DW_TAG_try_block : match_addr_range = true; break; - case DW_TAG_variant_part : break; - case DW_TAG_variable : break; - case DW_TAG_volatile_type : break; - case DW_TAG_dwarf_procedure : break; - case DW_TAG_restrict_type : break; - case DW_TAG_interface_type : break; - case DW_TAG_namespace : check_children = true; break; - case DW_TAG_imported_module : break; - case DW_TAG_unspecified_type : break; - case DW_TAG_partial_unit : break; - case DW_TAG_imported_unit : break; - case DW_TAG_shared_type : break; - default: break; - } - - if (match_addr_range) - { - dw_addr_t lo_pc = GetAttributeValueAsAddress(dwarf2Data, cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS); - if (lo_pc != LLDB_INVALID_ADDRESS) - { - dw_addr_t hi_pc = GetAttributeHighPC(dwarf2Data, cu, lo_pc, LLDB_INVALID_ADDRESS); - if (hi_pc != LLDB_INVALID_ADDRESS) - { - // printf("\n0x%8.8x: %30s: address = 0x%8.8x [0x%8.8x - 0x%8.8x) ", m_offset, DW_TAG_value_to_name(tag), address, lo_pc, hi_pc); - if ((lo_pc <= address) && (address < hi_pc)) - { - found_address = true; - // puts("***MATCH***"); - switch (m_tag) - { - case DW_TAG_compile_unit: // File - check_children = ((function_die != NULL) || (block_die != NULL)); - break; - - case DW_TAG_subprogram: // Function - if (function_die) - *function_die = this; - check_children = (block_die != NULL); - break; - - case DW_TAG_inlined_subroutine: // Inlined Function - case DW_TAG_lexical_block: // Block { } in code - if (block_die) - { - *block_die = this; - check_children = true; - } - break; - - default: - check_children = true; - break; - } - } - } - else - { // compile units may not have a valid high/low pc when there - // are address gaps in subroutines so we must always search - // if there is no valid high and low PC - check_children = (m_tag == DW_TAG_compile_unit) && ((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) - { - DWARFRangeList ranges; - DWARFDebugRanges* debug_ranges = dwarf2Data->DebugRanges(); - debug_ranges->FindRanges(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()); - if (ranges.FindEntryThatContains(address)) - { - found_address = true; - // puts("***MATCH***"); - switch (m_tag) - { - case DW_TAG_compile_unit: // File - check_children = ((function_die != NULL) || (block_die != NULL)); - break; - - case DW_TAG_subprogram: // Function - if (function_die) - *function_die = this; - check_children = (block_die != NULL); - break; - - case DW_TAG_inlined_subroutine: // Inlined Function - case DW_TAG_lexical_block: // Block { } in code - if (block_die) - { - *block_die = this; - check_children = true; - } - break; - - default: - check_children = true; - break; - } - } - else - { - check_children = false; - } - } - } - } +bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address, + SymbolFileDWARF *dwarf2Data, + const DWARFCompileUnit *cu, + DWARFDebugInfoEntry **function_die, + DWARFDebugInfoEntry **block_die) { + bool found_address = false; + if (m_tag) { + bool check_children = false; + bool match_addr_range = false; + // printf("0x%8.8x: %30s: address = 0x%8.8x - ", m_offset, + // DW_TAG_value_to_name(tag), address); + switch (m_tag) { + case DW_TAG_array_type: + break; + case DW_TAG_class_type: + check_children = true; + break; + case DW_TAG_entry_point: + break; + case DW_TAG_enumeration_type: + break; + case DW_TAG_formal_parameter: + break; + case DW_TAG_imported_declaration: + break; + case DW_TAG_label: + break; + case DW_TAG_lexical_block: + check_children = true; + match_addr_range = true; + break; + case DW_TAG_member: + break; + case DW_TAG_pointer_type: + break; + case DW_TAG_reference_type: + break; + case DW_TAG_compile_unit: + match_addr_range = true; + break; + case DW_TAG_string_type: + break; + case DW_TAG_structure_type: + check_children = true; + break; + case DW_TAG_subroutine_type: + break; + case DW_TAG_typedef: + break; + case DW_TAG_union_type: + break; + case DW_TAG_unspecified_parameters: + break; + case DW_TAG_variant: + break; + case DW_TAG_common_block: + check_children = true; + break; + case DW_TAG_common_inclusion: + break; + case DW_TAG_inheritance: + break; + case DW_TAG_inlined_subroutine: + check_children = true; + match_addr_range = true; + break; + case DW_TAG_module: + match_addr_range = true; + break; + case DW_TAG_ptr_to_member_type: + break; + case DW_TAG_set_type: + break; + case DW_TAG_subrange_type: + break; + case DW_TAG_with_stmt: + break; + case DW_TAG_access_declaration: + break; + case DW_TAG_base_type: + break; + case DW_TAG_catch_block: + match_addr_range = true; + break; + case DW_TAG_const_type: + break; + case DW_TAG_constant: + break; + case DW_TAG_enumerator: + break; + case DW_TAG_file_type: + break; + case DW_TAG_friend: + break; + case DW_TAG_namelist: + break; + case DW_TAG_namelist_item: + break; + case DW_TAG_packed_type: + break; + case DW_TAG_subprogram: + match_addr_range = true; + break; + case DW_TAG_template_type_parameter: + break; + case DW_TAG_template_value_parameter: + break; + case DW_TAG_thrown_type: + break; + case DW_TAG_try_block: + match_addr_range = true; + break; + case DW_TAG_variant_part: + break; + case DW_TAG_variable: + break; + case DW_TAG_volatile_type: + break; + case DW_TAG_dwarf_procedure: + break; + case DW_TAG_restrict_type: + break; + case DW_TAG_interface_type: + break; + case DW_TAG_namespace: + check_children = true; + break; + case DW_TAG_imported_module: + break; + case DW_TAG_unspecified_type: + break; + case DW_TAG_partial_unit: + break; + case DW_TAG_imported_unit: + break; + case DW_TAG_shared_type: + break; + default: + break; + } + if (match_addr_range) { + dw_addr_t lo_pc = GetAttributeValueAsAddress(dwarf2Data, cu, DW_AT_low_pc, + LLDB_INVALID_ADDRESS); + if (lo_pc != LLDB_INVALID_ADDRESS) { + dw_addr_t hi_pc = + GetAttributeHighPC(dwarf2Data, cu, lo_pc, LLDB_INVALID_ADDRESS); + if (hi_pc != LLDB_INVALID_ADDRESS) { + // printf("\n0x%8.8x: %30s: address = 0x%8.8x [0x%8.8x - 0x%8.8x) ", + // m_offset, DW_TAG_value_to_name(tag), address, lo_pc, hi_pc); + if ((lo_pc <= address) && (address < hi_pc)) { + found_address = true; + // puts("***MATCH***"); + switch (m_tag) { + case DW_TAG_compile_unit: // File + check_children = ((function_die != NULL) || (block_die != NULL)); + break; + + case DW_TAG_subprogram: // Function + if (function_die) + *function_die = this; + check_children = (block_die != NULL); + break; + + case DW_TAG_inlined_subroutine: // Inlined Function + case DW_TAG_lexical_block: // Block { } in code + if (block_die) { + *block_die = this; + check_children = true; + } + break; - if (check_children) - { - // printf("checking children\n"); - DWARFDebugInfoEntry* child = GetFirstChild(); - while (child) - { - if (child->LookupAddress(address, dwarf2Data, cu, function_die, block_die)) - return true; - child = child->GetSibling(); + default: + check_children = true; + break; } + } + } else { // compile units may not have a valid high/low pc when there + // are address gaps in subroutines so we must always search + // if there is no valid high and low PC + check_children = (m_tag == DW_TAG_compile_unit) && + ((function_die != NULL) || (block_die != NULL)); } - } - return found_address; -} + } else { + dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned( + dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET); + if (debug_ranges_offset != DW_INVALID_OFFSET) { + 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()); + if (ranges.FindEntryThatContains(address)) { + found_address = true; + // puts("***MATCH***"); + switch (m_tag) { + case DW_TAG_compile_unit: // File + check_children = ((function_die != NULL) || (block_die != NULL)); + break; + + case DW_TAG_subprogram: // Function + if (function_die) + *function_die = this; + check_children = (block_die != NULL); + break; + + case DW_TAG_inlined_subroutine: // Inlined Function + case DW_TAG_lexical_block: // Block { } in code + if (block_die) { + *block_die = this; + check_children = true; + } + break; -const DWARFAbbreviationDeclaration* -DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr (SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit *cu, - lldb::offset_t &offset) const -{ - if (dwarf2Data) - { - offset = GetOffset(); - - const DWARFAbbreviationDeclarationSet *abbrev_set = cu->GetAbbreviations(); - if (abbrev_set) - { - const DWARFAbbreviationDeclaration* abbrev_decl = abbrev_set->GetAbbreviationDeclaration (m_abbr_idx); - if (abbrev_decl) - { - // Make sure the abbreviation code still matches. If it doesn't and - // the DWARF data was mmap'ed, the backing file might have been modified - // which is bad news. - const uint64_t abbrev_code = dwarf2Data->get_debug_info_data().GetULEB128 (&offset); - - if (abbrev_decl->Code() == abbrev_code) - return abbrev_decl; - - dwarf2Data->GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("0x%8.8x: the DWARF debug information has been modified (abbrev code was %u, and is now %u)", - GetOffset(), - (uint32_t)abbrev_decl->Code(), - (uint32_t)abbrev_code); + default: + check_children = true; + break; } + } else { + check_children = false; + } } + } } - offset = DW_INVALID_OFFSET; - return NULL; -} - -bool -DWARFDebugInfoEntry::OffsetLessThan (const DWARFDebugInfoEntry& a, const DWARFDebugInfoEntry& b) -{ - return a.GetOffset() < b.GetOffset(); + if (check_children) { + // printf("checking children\n"); + DWARFDebugInfoEntry *child = GetFirstChild(); + while (child) { + if (child->LookupAddress(address, dwarf2Data, cu, function_die, + block_die)) + return true; + child = child->GetSibling(); + } + } + } + return found_address; } -void -DWARFDebugInfoEntry::DumpDIECollection (Stream &strm, DWARFDebugInfoEntry::collection &die_collection) -{ - DWARFDebugInfoEntry::const_iterator pos; - DWARFDebugInfoEntry::const_iterator end = die_collection.end(); - strm.PutCString("\noffset parent sibling child\n"); - strm.PutCString("-------- -------- -------- --------\n"); - for (pos = die_collection.begin(); pos != end; ++pos) - { - const DWARFDebugInfoEntry& die_ref = *pos; - const DWARFDebugInfoEntry* p = die_ref.GetParent(); - const DWARFDebugInfoEntry* s = die_ref.GetSibling(); - const DWARFDebugInfoEntry* c = die_ref.GetFirstChild(); - strm.Printf("%.8x: %.8x %.8x %.8x 0x%4.4x %s%s\n", - die_ref.GetOffset(), - p ? p->GetOffset() : 0, - s ? s->GetOffset() : 0, - c ? c->GetOffset() : 0, - die_ref.Tag(), - DW_TAG_value_to_name(die_ref.Tag()), - die_ref.HasChildren() ? " *" : ""); +const DWARFAbbreviationDeclaration * +DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, + lldb::offset_t &offset) const { + if (dwarf2Data) { + offset = GetOffset(); + + const DWARFAbbreviationDeclarationSet *abbrev_set = cu->GetAbbreviations(); + if (abbrev_set) { + const DWARFAbbreviationDeclaration *abbrev_decl = + abbrev_set->GetAbbreviationDeclaration(m_abbr_idx); + if (abbrev_decl) { + // Make sure the abbreviation code still matches. If it doesn't and + // the DWARF data was mmap'ed, the backing file might have been modified + // which is bad news. + const uint64_t abbrev_code = + dwarf2Data->get_debug_info_data().GetULEB128(&offset); + + if (abbrev_decl->Code() == abbrev_code) + return abbrev_decl; + + dwarf2Data->GetObjectFile()->GetModule()->ReportErrorIfModifyDetected( + "0x%8.8x: the DWARF debug information has been modified (abbrev " + "code was %u, and is now %u)", + GetOffset(), (uint32_t)abbrev_decl->Code(), (uint32_t)abbrev_code); + } } + } + offset = DW_INVALID_OFFSET; + return NULL; } +bool DWARFDebugInfoEntry::OffsetLessThan(const DWARFDebugInfoEntry &a, + const DWARFDebugInfoEntry &b) { + return a.GetOffset() < b.GetOffset(); +} +void DWARFDebugInfoEntry::DumpDIECollection( + Stream &strm, DWARFDebugInfoEntry::collection &die_collection) { + DWARFDebugInfoEntry::const_iterator pos; + DWARFDebugInfoEntry::const_iterator end = die_collection.end(); + strm.PutCString("\noffset parent sibling child\n"); + strm.PutCString("-------- -------- -------- --------\n"); + for (pos = die_collection.begin(); pos != end; ++pos) { + const DWARFDebugInfoEntry &die_ref = *pos; + const DWARFDebugInfoEntry *p = die_ref.GetParent(); + const DWARFDebugInfoEntry *s = die_ref.GetSibling(); + const DWARFDebugInfoEntry *c = die_ref.GetFirstChild(); + strm.Printf("%.8x: %.8x %.8x %.8x 0x%4.4x %s%s\n", die_ref.GetOffset(), + p ? p->GetOffset() : 0, s ? s->GetOffset() : 0, + c ? c->GetOffset() : 0, die_ref.Tag(), + DW_TAG_value_to_name(die_ref.Tag()), + die_ref.HasChildren() ? " *" : ""); + } +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h index 27b4fe93bc33..15abac77a475 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h @@ -13,390 +13,295 @@ #include "SymbolFileDWARF.h" #include "llvm/ADT/SmallVector.h" -#include "DWARFDebugAbbrev.h" #include "DWARFAbbreviationDeclaration.h" +#include "DWARFDebugAbbrev.h" #include "DWARFDebugRanges.h" -#include <vector> #include <map> #include <set> +#include <vector> -typedef std::map<const DWARFDebugInfoEntry*, dw_addr_t> DIEToAddressMap; -typedef DIEToAddressMap::iterator DIEToAddressMapIter; -typedef DIEToAddressMap::const_iterator DIEToAddressMapConstIter; - -typedef std::map<dw_addr_t, const DWARFDebugInfoEntry*> AddressToDIEMap; -typedef AddressToDIEMap::iterator AddressToDIEMapIter; -typedef AddressToDIEMap::const_iterator AddressToDIEMapConstIter; +typedef std::map<const DWARFDebugInfoEntry *, dw_addr_t> DIEToAddressMap; +typedef DIEToAddressMap::iterator DIEToAddressMapIter; +typedef DIEToAddressMap::const_iterator DIEToAddressMapConstIter; +typedef std::map<dw_addr_t, const DWARFDebugInfoEntry *> AddressToDIEMap; +typedef AddressToDIEMap::iterator AddressToDIEMapIter; +typedef AddressToDIEMap::const_iterator AddressToDIEMapConstIter; -typedef std::map<dw_offset_t, dw_offset_t> DIEToDIEMap; -typedef DIEToDIEMap::iterator DIEToDIEMapIter; -typedef DIEToDIEMap::const_iterator DIEToDIEMapConstIter; +typedef std::map<dw_offset_t, dw_offset_t> DIEToDIEMap; +typedef DIEToDIEMap::iterator DIEToDIEMapIter; +typedef DIEToDIEMap::const_iterator DIEToDIEMapConstIter; -typedef std::map<uint32_t, const DWARFDebugInfoEntry*> UInt32ToDIEMap; -typedef UInt32ToDIEMap::iterator UInt32ToDIEMapIter; -typedef UInt32ToDIEMap::const_iterator UInt32ToDIEMapConstIter; +typedef std::map<uint32_t, const DWARFDebugInfoEntry *> UInt32ToDIEMap; +typedef UInt32ToDIEMap::iterator UInt32ToDIEMapIter; +typedef UInt32ToDIEMap::const_iterator UInt32ToDIEMapConstIter; -typedef std::multimap<uint32_t, const DWARFDebugInfoEntry*> UInt32ToDIEMMap; -typedef UInt32ToDIEMMap::iterator UInt32ToDIEMMapIter; -typedef UInt32ToDIEMMap::const_iterator UInt32ToDIEMMapConstIter; +typedef std::multimap<uint32_t, const DWARFDebugInfoEntry *> UInt32ToDIEMMap; +typedef UInt32ToDIEMMap::iterator UInt32ToDIEMMapIter; +typedef UInt32ToDIEMMap::const_iterator UInt32ToDIEMMapConstIter; class DWARFDeclContext; #define DIE_SIBLING_IDX_BITSIZE 31 #define DIE_ABBR_IDX_BITSIZE 15 -class DWARFDebugInfoEntry -{ +class DWARFDebugInfoEntry { public: - typedef std::vector<DWARFDebugInfoEntry> collection; - typedef collection::iterator iterator; - typedef collection::const_iterator const_iterator; - - typedef std::vector<dw_offset_t> offset_collection; - typedef offset_collection::iterator offset_collection_iterator; - typedef offset_collection::const_iterator offset_collection_const_iterator; - - 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) - { - } - - void Clear () - { - 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; - } - - bool Contains (const DWARFDebugInfoEntry *die) const; - - void BuildAddressRangeTable( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - DWARFDebugAranges* debug_aranges) const; - - void BuildFunctionAddressRangeTable( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - DWARFDebugAranges* debug_aranges) const; - - bool FastExtract( - const lldb_private::DWARFDataExtractor& debug_info_data, - const DWARFCompileUnit* cu, - const DWARFFormValue::FixedFormSizes& fixed_form_sizes, - lldb::offset_t* offset_ptr); - - bool Extract( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - lldb::offset_t* offset_ptr); - - bool LookupAddress( - const dw_addr_t address, - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - DWARFDebugInfoEntry** function_die, - DWARFDebugInfoEntry** block_die); - - size_t GetAttributes( - const DWARFCompileUnit* cu, - DWARFFormValue::FixedFormSizes fixed_form_sizes, - DWARFAttributes& attrs, - uint32_t curr_depth = 0) const; // "curr_depth" for internal use only, don't set this yourself!!! - - dw_offset_t GetAttributeValue(SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - const dw_attr_t attr, - DWARFFormValue& formValue, - dw_offset_t* end_attr_offset_ptr = nullptr, - bool check_specification_or_abstract_origin = false) const; - - const char* GetAttributeValueAsString( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - const dw_attr_t attr, - const char* fail_value, - bool check_specification_or_abstract_origin = false) const; - - uint64_t GetAttributeValueAsUnsigned( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - const dw_attr_t attr, - uint64_t fail_value, - bool check_specification_or_abstract_origin = false) const; - - uint64_t GetAttributeValueAsReference( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - const dw_attr_t attr, - uint64_t fail_value, - bool check_specification_or_abstract_origin = false) const; - - int64_t GetAttributeValueAsSigned( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - const dw_attr_t attr, - int64_t fail_value, + typedef std::vector<DWARFDebugInfoEntry> collection; + typedef collection::iterator iterator; + typedef collection::const_iterator const_iterator; + + typedef std::vector<dw_offset_t> offset_collection; + typedef offset_collection::iterator offset_collection_iterator; + typedef offset_collection::const_iterator offset_collection_const_iterator; + + 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) {} + + void Clear() { + 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; + } + + bool Contains(const DWARFDebugInfoEntry *die) const; + + void BuildAddressRangeTable(SymbolFileDWARF *dwarf2Data, + const DWARFCompileUnit *cu, + DWARFDebugAranges *debug_aranges) const; + + void BuildFunctionAddressRangeTable(SymbolFileDWARF *dwarf2Data, + const DWARFCompileUnit *cu, + DWARFDebugAranges *debug_aranges) const; + + bool FastExtract(const lldb_private::DWARFDataExtractor &debug_info_data, + const DWARFCompileUnit *cu, + const DWARFFormValue::FixedFormSizes &fixed_form_sizes, + lldb::offset_t *offset_ptr); + + bool Extract(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, + lldb::offset_t *offset_ptr); + + bool LookupAddress(const dw_addr_t address, SymbolFileDWARF *dwarf2Data, + const DWARFCompileUnit *cu, + DWARFDebugInfoEntry **function_die, + DWARFDebugInfoEntry **block_die); + + size_t GetAttributes(const DWARFCompileUnit *cu, + DWARFFormValue::FixedFormSizes fixed_form_sizes, + DWARFAttributes &attrs, + uint32_t curr_depth = 0) + const; // "curr_depth" for internal use only, don't set this yourself!!! + + dw_offset_t + GetAttributeValue(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, + const dw_attr_t attr, DWARFFormValue &formValue, + dw_offset_t *end_attr_offset_ptr = nullptr, bool check_specification_or_abstract_origin = false) const; - uint64_t GetAttributeValueAsAddress( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - const dw_attr_t attr, - uint64_t fail_value, - bool check_specification_or_abstract_origin = false) const; - - dw_addr_t GetAttributeHighPC( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - dw_addr_t lo_pc, - uint64_t fail_value, - bool check_specification_or_abstract_origin = false) const; - - bool GetAttributeAddressRange( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - dw_addr_t& lo_pc, - dw_addr_t& hi_pc, - uint64_t fail_value, - bool check_specification_or_abstract_origin = false) const; - - size_t GetAttributeAddressRanges ( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - DWARFRangeList &ranges, - bool check_hi_lo_pc, - bool check_specification_or_abstract_origin = false) const; - - const char* GetName( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu) const; - - const char* GetMangledName( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - bool substitute_name_allowed = true) const; - - const char* GetPubname( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu) const; - - static bool GetName( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - const dw_offset_t die_offset, - lldb_private::Stream &s); - - static bool AppendTypeName( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - const dw_offset_t die_offset, - lldb_private::Stream &s); - - const char * GetQualifiedName ( - SymbolFileDWARF* dwarf2Data, - DWARFCompileUnit* cu, - std::string &storage) const; - - const char * GetQualifiedName ( - SymbolFileDWARF* dwarf2Data, - DWARFCompileUnit* cu, - const DWARFAttributes& attributes, - std::string &storage) const; - - static bool OffsetLessThan ( - const DWARFDebugInfoEntry& a, - const DWARFDebugInfoEntry& b); - - void Dump( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - lldb_private::Stream &s, - uint32_t recurse_depth) const; - - void DumpAncestry( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - const DWARFDebugInfoEntry* oldest, - lldb_private::Stream &s, + const char *GetAttributeValueAsString( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, + const dw_attr_t attr, const char *fail_value, + bool check_specification_or_abstract_origin = false) const; + + uint64_t GetAttributeValueAsUnsigned( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, + const dw_attr_t attr, uint64_t fail_value, + bool check_specification_or_abstract_origin = false) const; + + uint64_t GetAttributeValueAsReference( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, + const dw_attr_t attr, uint64_t fail_value, + bool check_specification_or_abstract_origin = false) const; + + int64_t GetAttributeValueAsSigned( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, + const dw_attr_t attr, int64_t fail_value, + bool check_specification_or_abstract_origin = false) const; + + uint64_t GetAttributeValueAsAddress( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, + const dw_attr_t attr, uint64_t fail_value, + bool check_specification_or_abstract_origin = false) const; + + dw_addr_t + GetAttributeHighPC(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, + dw_addr_t lo_pc, uint64_t fail_value, + bool check_specification_or_abstract_origin = false) const; + + bool GetAttributeAddressRange( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, dw_addr_t &lo_pc, + dw_addr_t &hi_pc, uint64_t fail_value, + bool check_specification_or_abstract_origin = false) const; + + size_t GetAttributeAddressRanges( + SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, + DWARFRangeList &ranges, bool check_hi_lo_pc, + bool check_specification_or_abstract_origin = false) const; + + const char *GetName(SymbolFileDWARF *dwarf2Data, + const DWARFCompileUnit *cu) const; + + const char *GetMangledName(SymbolFileDWARF *dwarf2Data, + const DWARFCompileUnit *cu, + bool substitute_name_allowed = true) const; + + const char *GetPubname(SymbolFileDWARF *dwarf2Data, + const DWARFCompileUnit *cu) const; + + static bool GetName(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, + const dw_offset_t die_offset, lldb_private::Stream &s); + + static bool AppendTypeName(SymbolFileDWARF *dwarf2Data, + const DWARFCompileUnit *cu, + const dw_offset_t die_offset, + lldb_private::Stream &s); + + const char *GetQualifiedName(SymbolFileDWARF *dwarf2Data, + DWARFCompileUnit *cu, + std::string &storage) const; + + const char *GetQualifiedName(SymbolFileDWARF *dwarf2Data, + DWARFCompileUnit *cu, + const DWARFAttributes &attributes, + std::string &storage) const; + + static bool OffsetLessThan(const DWARFDebugInfoEntry &a, + const DWARFDebugInfoEntry &b); + + void Dump(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, + lldb_private::Stream &s, uint32_t recurse_depth) const; + + void DumpAncestry(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, + const DWARFDebugInfoEntry *oldest, lldb_private::Stream &s, uint32_t recurse_depth) const; - static void DumpAttribute( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* 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); - // This one dumps the comp unit name, objfile name and die offset for this die so the stream S. - void DumpLocation( - SymbolFileDWARF* dwarf2Data, - DWARFCompileUnit* cu, + static void + DumpAttribute(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *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); + // This one dumps the comp unit name, objfile name and die offset for this die + // so the stream S. + void DumpLocation(SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu, lldb_private::Stream &s) const; - - bool GetDIENamesAndRanges( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - const char * &name, - const char * &mangled, - DWARFRangeList& rangeList, - int& decl_file, - int& decl_line, - int& decl_column, - int& call_file, - int& call_line, - int& call_column, - lldb_private::DWARFExpression *frame_base = NULL) const; - - const DWARFAbbreviationDeclaration* - GetAbbreviationDeclarationPtr (SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit *cu, - lldb::offset_t &offset) const; - - dw_tag_t - Tag () const - { - return m_tag; - } - - bool - IsNULL() const - { - return m_abbr_idx == 0; - } - - dw_offset_t - GetOffset () const - { - return m_offset; - } - - void - SetOffset (dw_offset_t offset) - { - m_offset = offset; - } - - bool - HasChildren () const - { - return m_has_children; - } - - void - SetHasChildren (bool b) - { - m_has_children = b; - } - - // We know we are kept in a vector of contiguous entries, so we know - // our parent will be some index behind "this". - DWARFDebugInfoEntry* GetParent() { return m_parent_idx > 0 ? this - m_parent_idx : NULL; } - const DWARFDebugInfoEntry* GetParent() const { return m_parent_idx > 0 ? this - m_parent_idx : NULL; } - // We know we are kept in a vector of contiguous entries, so we know - // our sibling will be some index after "this". - DWARFDebugInfoEntry* GetSibling() { return m_sibling_idx > 0 ? this + m_sibling_idx : NULL; } - const DWARFDebugInfoEntry* GetSibling() const { return m_sibling_idx > 0 ? this + m_sibling_idx : NULL; } - // We know we are kept in a vector of contiguous entries, so we know - // 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; } - const DWARFDebugInfoEntry* GetFirstChild() const { return (HasChildren() && !m_empty_children) ? this + 1 : NULL; } - - - void GetDeclContextDIEs (DWARFCompileUnit* cu, - DWARFDIECollection &decl_context_dies) const; - - void GetDWARFDeclContext (SymbolFileDWARF* dwarf2Data, - DWARFCompileUnit* cu, - DWARFDeclContext &dwarf_decl_ctx) const; - - - bool MatchesDWARFDeclContext(SymbolFileDWARF* dwarf2Data, - DWARFCompileUnit* cu, - const DWARFDeclContext &dwarf_decl_ctx) const; - - DWARFDIE GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data, - DWARFCompileUnit* cu) const; - DWARFDIE GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data, - DWARFCompileUnit* cu, - const DWARFAttributes& attributes) const; - - void - SetParent (DWARFDebugInfoEntry* parent) - { - if (parent) - { - // We know we are kept in a vector of contiguous entries, so we know - // our parent will be some index behind "this". - m_parent_idx = this - parent; - } - else - m_parent_idx = 0; - } - void - SetSibling (DWARFDebugInfoEntry* sibling) - { - if (sibling) - { - // We know we are kept in a vector of contiguous entries, so we know - // our sibling will be some index after "this". - m_sibling_idx = sibling - this; - sibling->SetParent(GetParent()); - } - else - m_sibling_idx = 0; - } - - void - SetSiblingIndex (uint32_t idx) - { - m_sibling_idx = idx; - } - - 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); -protected: + bool + GetDIENamesAndRanges(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, + const char *&name, const char *&mangled, + DWARFRangeList &rangeList, int &decl_file, + int &decl_line, int &decl_column, int &call_file, + int &call_line, int &call_column, + lldb_private::DWARFExpression *frame_base = NULL) const; + + const DWARFAbbreviationDeclaration * + GetAbbreviationDeclarationPtr(SymbolFileDWARF *dwarf2Data, + const DWARFCompileUnit *cu, + lldb::offset_t &offset) const; + + dw_tag_t Tag() const { return m_tag; } + + bool IsNULL() const { return m_abbr_idx == 0; } + + dw_offset_t GetOffset() const { return m_offset; } + + void SetOffset(dw_offset_t offset) { m_offset = offset; } + + bool HasChildren() const { return m_has_children; } + + void SetHasChildren(bool b) { m_has_children = b; } + + // We know we are kept in a vector of contiguous entries, so we know + // our parent will be some index behind "this". + DWARFDebugInfoEntry *GetParent() { + return m_parent_idx > 0 ? this - m_parent_idx : NULL; + } + const DWARFDebugInfoEntry *GetParent() const { + return m_parent_idx > 0 ? this - m_parent_idx : NULL; + } + // We know we are kept in a vector of contiguous entries, so we know + // our sibling will be some index after "this". + DWARFDebugInfoEntry *GetSibling() { + return m_sibling_idx > 0 ? this + m_sibling_idx : NULL; + } + const DWARFDebugInfoEntry *GetSibling() const { + return m_sibling_idx > 0 ? this + m_sibling_idx : NULL; + } + // We know we are kept in a vector of contiguous entries, so we know + // 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; + } + const DWARFDebugInfoEntry *GetFirstChild() const { + return (HasChildren() && !m_empty_children) ? this + 1 : NULL; + } + + void GetDeclContextDIEs(DWARFCompileUnit *cu, + DWARFDIECollection &decl_context_dies) const; + + void GetDWARFDeclContext(SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu, + DWARFDeclContext &dwarf_decl_ctx) const; + + bool MatchesDWARFDeclContext(SymbolFileDWARF *dwarf2Data, + DWARFCompileUnit *cu, + const DWARFDeclContext &dwarf_decl_ctx) const; + + DWARFDIE GetParentDeclContextDIE(SymbolFileDWARF *dwarf2Data, + DWARFCompileUnit *cu) const; + DWARFDIE GetParentDeclContextDIE(SymbolFileDWARF *dwarf2Data, + DWARFCompileUnit *cu, + const DWARFAttributes &attributes) const; + + void SetParent(DWARFDebugInfoEntry *parent) { + if (parent) { + // We know we are kept in a vector of contiguous entries, so we know + // our parent will be some index behind "this". + m_parent_idx = this - parent; + } else + m_parent_idx = 0; + } + void SetSibling(DWARFDebugInfoEntry *sibling) { + if (sibling) { + // We know we are kept in a vector of contiguous entries, so we know + // our sibling will be some index after "this". + m_sibling_idx = sibling - this; + sibling->SetParent(GetParent()); + } else + m_sibling_idx = 0; + } + + void SetSiblingIndex(uint32_t idx) { m_sibling_idx = idx; } + + 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); - dw_offset_t m_offset; // Offset within the .debug_info of the start of this entry - 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 +protected: + dw_offset_t + m_offset; // Offset within the .debug_info of the start of this entry + 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 }; -#endif // SymbolFileDWARF_DWARFDebugInfoEntry_h_ +#endif // SymbolFileDWARF_DWARFDebugInfoEntry_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp index 84c2142e8419..bce21c44b73e 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp @@ -18,8 +18,8 @@ #include "lldb/Core/Timer.h" #include "lldb/Host/Host.h" -#include "SymbolFileDWARF.h" #include "LogChannelDWARF.h" +#include "SymbolFileDWARF.h" using namespace lldb; using namespace lldb_private; @@ -31,359 +31,329 @@ using namespace std; // Parse all information in the debug_line_data into an internal // representation. //---------------------------------------------------------------------- -void -DWARFDebugLine::Parse(const DWARFDataExtractor& debug_line_data) -{ - m_lineTableMap.clear(); - lldb::offset_t offset = 0; - LineTable::shared_ptr line_table_sp(new LineTable); - while (debug_line_data.ValidOffset(offset)) - { - const lldb::offset_t debug_line_offset = offset; - - if (line_table_sp.get() == NULL) - break; - - if (ParseStatementTable(debug_line_data, &offset, line_table_sp.get())) - { - // Make sure we don't don't loop infinitely - if (offset <= debug_line_offset) - break; - //DEBUG_PRINTF("m_lineTableMap[0x%8.8x] = line_table_sp\n", debug_line_offset); - m_lineTableMap[debug_line_offset] = line_table_sp; - line_table_sp.reset(new LineTable); - } - else - ++offset; // Try next byte in line table - } +void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data) { + m_lineTableMap.clear(); + lldb::offset_t offset = 0; + LineTable::shared_ptr line_table_sp(new LineTable); + while (debug_line_data.ValidOffset(offset)) { + const lldb::offset_t debug_line_offset = offset; + + if (line_table_sp.get() == NULL) + break; + + if (ParseStatementTable(debug_line_data, &offset, line_table_sp.get())) { + // Make sure we don't don't loop infinitely + if (offset <= debug_line_offset) + break; + // DEBUG_PRINTF("m_lineTableMap[0x%8.8x] = line_table_sp\n", + // debug_line_offset); + m_lineTableMap[debug_line_offset] = line_table_sp; + line_table_sp.reset(new LineTable); + } else + ++offset; // Try next byte in line table + } } -void -DWARFDebugLine::ParseIfNeeded(const DWARFDataExtractor& debug_line_data) -{ - if (m_lineTableMap.empty()) - Parse(debug_line_data); +void DWARFDebugLine::ParseIfNeeded(const DWARFDataExtractor &debug_line_data) { + if (m_lineTableMap.empty()) + Parse(debug_line_data); } - //---------------------------------------------------------------------- // DWARFDebugLine::GetLineTable //---------------------------------------------------------------------- DWARFDebugLine::LineTable::shared_ptr -DWARFDebugLine::GetLineTable(const dw_offset_t offset) const -{ - DWARFDebugLine::LineTable::shared_ptr line_table_shared_ptr; - LineTableConstIter pos = m_lineTableMap.find(offset); - if (pos != m_lineTableMap.end()) - line_table_shared_ptr = pos->second; - return line_table_shared_ptr; +DWARFDebugLine::GetLineTable(const dw_offset_t offset) const { + DWARFDebugLine::LineTable::shared_ptr line_table_shared_ptr; + LineTableConstIter pos = m_lineTableMap.find(offset); + if (pos != m_lineTableMap.end()) + line_table_shared_ptr = pos->second; + return line_table_shared_ptr; } - //---------------------------------------------------------------------- // DumpStateToFile //---------------------------------------------------------------------- -static void -DumpStateToFile (dw_offset_t offset, const DWARFDebugLine::State& state, void* userData) -{ - Log *log = (Log *)userData; - if (state.row == DWARFDebugLine::State::StartParsingLineTable) - { - // If the row is zero we are being called with the prologue only - state.prologue->Dump (log); - log->PutCString ("Address Line Column File"); - log->PutCString ("------------------ ------ ------ ------"); - } - else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) - { - // Done parsing line table - } - else - { - log->Printf( "0x%16.16" PRIx64 " %6u %6u %6u%s\n", state.address, state.line, state.column, state.file, state.end_sequence ? " END" : ""); - } +static void DumpStateToFile(dw_offset_t offset, + const DWARFDebugLine::State &state, + void *userData) { + Log *log = (Log *)userData; + if (state.row == DWARFDebugLine::State::StartParsingLineTable) { + // If the row is zero we are being called with the prologue only + state.prologue->Dump(log); + log->PutCString("Address Line Column File"); + log->PutCString("------------------ ------ ------ ------"); + } else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) { + // Done parsing line table + } else { + log->Printf("0x%16.16" PRIx64 " %6u %6u %6u%s\n", state.address, state.line, + state.column, state.file, state.end_sequence ? " END" : ""); + } } //---------------------------------------------------------------------- // DWARFDebugLine::DumpLineTableRows //---------------------------------------------------------------------- -bool -DWARFDebugLine::DumpLineTableRows(Log *log, SymbolFileDWARF* dwarf2Data, dw_offset_t debug_line_offset) -{ - const DWARFDataExtractor& debug_line_data = dwarf2Data->get_debug_line_data(); - - if (debug_line_offset == DW_INVALID_OFFSET) - { - // Dump line table to a single file only - debug_line_offset = 0; - while (debug_line_data.ValidOffset(debug_line_offset)) - debug_line_offset = DumpStatementTable (log, debug_line_data, debug_line_offset); - } - else - { - // Dump line table to a single file only - DumpStatementTable (log, debug_line_data, debug_line_offset); - } - return false; +bool DWARFDebugLine::DumpLineTableRows(Log *log, SymbolFileDWARF *dwarf2Data, + dw_offset_t debug_line_offset) { + const DWARFDataExtractor &debug_line_data = dwarf2Data->get_debug_line_data(); + + if (debug_line_offset == DW_INVALID_OFFSET) { + // Dump line table to a single file only + debug_line_offset = 0; + while (debug_line_data.ValidOffset(debug_line_offset)) + debug_line_offset = + DumpStatementTable(log, debug_line_data, debug_line_offset); + } else { + // Dump line table to a single file only + DumpStatementTable(log, debug_line_data, debug_line_offset); + } + return false; } //---------------------------------------------------------------------- // DWARFDebugLine::DumpStatementTable //---------------------------------------------------------------------- dw_offset_t -DWARFDebugLine::DumpStatementTable(Log *log, const DWARFDataExtractor& debug_line_data, const dw_offset_t debug_line_offset) -{ - if (debug_line_data.ValidOffset(debug_line_offset)) - { - lldb::offset_t offset = debug_line_offset; - log->Printf( "----------------------------------------------------------------------\n" - "debug_line[0x%8.8x]\n" - "----------------------------------------------------------------------\n", debug_line_offset); - - if (ParseStatementTable(debug_line_data, &offset, DumpStateToFile, log)) - return offset; - else - return debug_line_offset + 1; // Skip to next byte in .debug_line section - } +DWARFDebugLine::DumpStatementTable(Log *log, + const DWARFDataExtractor &debug_line_data, + const dw_offset_t debug_line_offset) { + if (debug_line_data.ValidOffset(debug_line_offset)) { + lldb::offset_t offset = debug_line_offset; + log->Printf("--------------------------------------------------------------" + "--------\n" + "debug_line[0x%8.8x]\n" + "--------------------------------------------------------------" + "--------\n", + debug_line_offset); + + if (ParseStatementTable(debug_line_data, &offset, DumpStateToFile, log)) + return offset; + else + return debug_line_offset + 1; // Skip to next byte in .debug_line section + } - return DW_INVALID_OFFSET; + return DW_INVALID_OFFSET; } - //---------------------------------------------------------------------- // DumpOpcodes //---------------------------------------------------------------------- -bool -DWARFDebugLine::DumpOpcodes(Log *log, SymbolFileDWARF* dwarf2Data, dw_offset_t debug_line_offset, uint32_t dump_flags) -{ - const DWARFDataExtractor& debug_line_data = dwarf2Data->get_debug_line_data(); - - if (debug_line_data.GetByteSize() == 0) - { - log->Printf( "< EMPTY >\n"); - return false; - } +bool DWARFDebugLine::DumpOpcodes(Log *log, SymbolFileDWARF *dwarf2Data, + dw_offset_t debug_line_offset, + uint32_t dump_flags) { + const DWARFDataExtractor &debug_line_data = dwarf2Data->get_debug_line_data(); - if (debug_line_offset == DW_INVALID_OFFSET) - { - // Dump line table to a single file only - debug_line_offset = 0; - while (debug_line_data.ValidOffset(debug_line_offset)) - debug_line_offset = DumpStatementOpcodes (log, debug_line_data, debug_line_offset, dump_flags); - } - else - { - // Dump line table to a single file only - DumpStatementOpcodes (log, debug_line_data, debug_line_offset, dump_flags); - } + if (debug_line_data.GetByteSize() == 0) { + log->Printf("< EMPTY >\n"); return false; + } + + if (debug_line_offset == DW_INVALID_OFFSET) { + // Dump line table to a single file only + debug_line_offset = 0; + while (debug_line_data.ValidOffset(debug_line_offset)) + debug_line_offset = DumpStatementOpcodes(log, debug_line_data, + debug_line_offset, dump_flags); + } else { + // Dump line table to a single file only + DumpStatementOpcodes(log, debug_line_data, debug_line_offset, dump_flags); + } + return false; } //---------------------------------------------------------------------- // DumpStatementOpcodes //---------------------------------------------------------------------- -dw_offset_t -DWARFDebugLine::DumpStatementOpcodes(Log *log, const DWARFDataExtractor& debug_line_data, const dw_offset_t debug_line_offset, uint32_t flags) -{ - lldb::offset_t offset = debug_line_offset; - if (debug_line_data.ValidOffset(offset)) - { - Prologue prologue; - - if (ParsePrologue(debug_line_data, &offset, &prologue)) - { - log->PutCString ("----------------------------------------------------------------------"); - log->Printf ("debug_line[0x%8.8x]", debug_line_offset); - log->PutCString ("----------------------------------------------------------------------\n"); - prologue.Dump (log); - } - else - { - offset = debug_line_offset; - log->Printf( "0x%8.8" PRIx64 ": skipping pad byte %2.2x", offset, debug_line_data.GetU8(&offset)); - return offset; - } - - Row row(prologue.default_is_stmt); - const dw_offset_t end_offset = debug_line_offset + prologue.total_length + sizeof(prologue.total_length); +dw_offset_t DWARFDebugLine::DumpStatementOpcodes( + Log *log, const DWARFDataExtractor &debug_line_data, + const dw_offset_t debug_line_offset, uint32_t flags) { + lldb::offset_t offset = debug_line_offset; + if (debug_line_data.ValidOffset(offset)) { + Prologue prologue; - assert(debug_line_data.ValidOffset(end_offset-1)); + if (ParsePrologue(debug_line_data, &offset, &prologue)) { + log->PutCString("--------------------------------------------------------" + "--------------"); + log->Printf("debug_line[0x%8.8x]", debug_line_offset); + log->PutCString("--------------------------------------------------------" + "--------------\n"); + prologue.Dump(log); + } else { + offset = debug_line_offset; + log->Printf("0x%8.8" PRIx64 ": skipping pad byte %2.2x", offset, + debug_line_data.GetU8(&offset)); + return offset; + } - while (offset < end_offset) - { - const uint32_t op_offset = offset; - uint8_t opcode = debug_line_data.GetU8(&offset); - switch (opcode) - { - case 0: // Extended Opcodes always start with a zero opcode followed by - { // a uleb128 length so you can skip ones you don't know about - - dw_offset_t ext_offset = offset; - dw_uleb128_t len = debug_line_data.GetULEB128(&offset); - dw_offset_t arg_size = len - (offset - ext_offset); - uint8_t sub_opcode = debug_line_data.GetU8(&offset); -// if (verbose) -// log->Printf( "Extended: <%u> %2.2x ", len, sub_opcode); - - switch (sub_opcode) - { - case DW_LNE_end_sequence : - log->Printf( "0x%8.8x: DW_LNE_end_sequence", op_offset); - row.Dump(log); - row.Reset(prologue.default_is_stmt); - break; - - case DW_LNE_set_address : - { - row.address = debug_line_data.GetMaxU64(&offset, arg_size); - log->Printf( "0x%8.8x: DW_LNE_set_address (0x%" PRIx64 ")", op_offset, row.address); - } - break; - - case DW_LNE_define_file: - { - FileNameEntry fileEntry; - fileEntry.name = debug_line_data.GetCStr(&offset); - fileEntry.dir_idx = debug_line_data.GetULEB128(&offset); - fileEntry.mod_time = debug_line_data.GetULEB128(&offset); - fileEntry.length = debug_line_data.GetULEB128(&offset); - log->Printf( "0x%8.8x: DW_LNE_define_file('%s', dir=%i, mod_time=0x%8.8x, length=%i )", - op_offset, - fileEntry.name, - fileEntry.dir_idx, - fileEntry.mod_time, - fileEntry.length); - prologue.file_names.push_back(fileEntry); - } - break; - - case DW_LNE_set_discriminator: - { - uint64_t discriminator = debug_line_data.GetULEB128(&offset); - log->Printf( "0x%8.8x: DW_LNE_set_discriminator (0x%" PRIx64 ")", op_offset, discriminator); - } - break; - default: - log->Printf( "0x%8.8x: DW_LNE_??? (%2.2x) - Skipping unknown upcode", op_offset, opcode); - // Length doesn't include the zero opcode byte or the length itself, but - // it does include the sub_opcode, so we have to adjust for that below - offset += arg_size; - break; - } - } - break; - - // Standard Opcodes - case DW_LNS_copy: - log->Printf( "0x%8.8x: DW_LNS_copy", op_offset); - row.Dump (log); - break; - - case DW_LNS_advance_pc: - { - dw_uleb128_t addr_offset_n = debug_line_data.GetULEB128(&offset); - dw_uleb128_t addr_offset = addr_offset_n * prologue.min_inst_length; - log->Printf( "0x%8.8x: DW_LNS_advance_pc (0x%x)", op_offset, addr_offset); - row.address += addr_offset; - } - break; - - case DW_LNS_advance_line: - { - dw_sleb128_t line_offset = debug_line_data.GetSLEB128(&offset); - log->Printf( "0x%8.8x: DW_LNS_advance_line (%i)", op_offset, line_offset); - row.line += line_offset; - } - break; - - case DW_LNS_set_file: - row.file = debug_line_data.GetULEB128(&offset); - log->Printf( "0x%8.8x: DW_LNS_set_file (%u)", op_offset, row.file); - break; - - case DW_LNS_set_column: - row.column = debug_line_data.GetULEB128(&offset); - log->Printf( "0x%8.8x: DW_LNS_set_column (%u)", op_offset, row.column); - break; - - case DW_LNS_negate_stmt: - row.is_stmt = !row.is_stmt; - log->Printf( "0x%8.8x: DW_LNS_negate_stmt", op_offset); - break; - - case DW_LNS_set_basic_block: - row.basic_block = true; - log->Printf( "0x%8.8x: DW_LNS_set_basic_block", op_offset); - break; - - case DW_LNS_const_add_pc: - { - uint8_t adjust_opcode = 255 - prologue.opcode_base; - dw_addr_t addr_offset = (adjust_opcode / prologue.line_range) * prologue.min_inst_length; - log->Printf( "0x%8.8x: DW_LNS_const_add_pc (0x%8.8" PRIx64 ")", op_offset, addr_offset); - row.address += addr_offset; - } - break; - - case DW_LNS_fixed_advance_pc: - { - uint16_t pc_offset = debug_line_data.GetU16(&offset); - log->Printf( "0x%8.8x: DW_LNS_fixed_advance_pc (0x%4.4x)", op_offset, pc_offset); - row.address += pc_offset; - } - break; - - case DW_LNS_set_prologue_end: - row.prologue_end = true; - log->Printf( "0x%8.8x: DW_LNS_set_prologue_end", op_offset); - break; - - case DW_LNS_set_epilogue_begin: - row.epilogue_begin = true; - log->Printf( "0x%8.8x: DW_LNS_set_epilogue_begin", op_offset); - break; - - case DW_LNS_set_isa: - row.isa = debug_line_data.GetULEB128(&offset); - log->Printf( "0x%8.8x: DW_LNS_set_isa (%u)", op_offset, row.isa); - break; - - // Special Opcodes - default: - if (opcode < prologue.opcode_base) - { - // We have an opcode that this parser doesn't know about, skip - // the number of ULEB128 numbers that is says to skip in the - // prologue's standard_opcode_lengths array - uint8_t n = prologue.standard_opcode_lengths[opcode-1]; - log->Printf( "0x%8.8x: Special : Unknown skipping %u ULEB128 values.", op_offset, n); - while (n > 0) - { - debug_line_data.GetULEB128(&offset); - --n; - } - } - else - { - uint8_t adjust_opcode = opcode - prologue.opcode_base; - dw_addr_t addr_offset = (adjust_opcode / prologue.line_range) * prologue.min_inst_length; - int32_t line_offset = prologue.line_base + (adjust_opcode % prologue.line_range); - log->Printf("0x%8.8x: address += 0x%" PRIx64 ", line += %i\n", op_offset, (uint64_t)addr_offset, line_offset); - row.address += addr_offset; - row.line += line_offset; - row.Dump (log); - } - break; - } + Row row(prologue.default_is_stmt); + const dw_offset_t end_offset = debug_line_offset + prologue.total_length + + sizeof(prologue.total_length); + + assert(debug_line_data.ValidOffset(end_offset - 1)); + + while (offset < end_offset) { + const uint32_t op_offset = offset; + uint8_t opcode = debug_line_data.GetU8(&offset); + switch (opcode) { + case 0: // Extended Opcodes always start with a zero opcode followed by + { // a uleb128 length so you can skip ones you don't know about + + dw_offset_t ext_offset = offset; + dw_uleb128_t len = debug_line_data.GetULEB128(&offset); + dw_offset_t arg_size = len - (offset - ext_offset); + uint8_t sub_opcode = debug_line_data.GetU8(&offset); + // if (verbose) + // log->Printf( "Extended: <%u> %2.2x ", len, + // sub_opcode); + + switch (sub_opcode) { + case DW_LNE_end_sequence: + log->Printf("0x%8.8x: DW_LNE_end_sequence", op_offset); + row.Dump(log); + row.Reset(prologue.default_is_stmt); + break; + + case DW_LNE_set_address: { + row.address = debug_line_data.GetMaxU64(&offset, arg_size); + log->Printf("0x%8.8x: DW_LNE_set_address (0x%" PRIx64 ")", op_offset, + row.address); + } break; + + case DW_LNE_define_file: { + FileNameEntry fileEntry; + fileEntry.name = debug_line_data.GetCStr(&offset); + fileEntry.dir_idx = debug_line_data.GetULEB128(&offset); + fileEntry.mod_time = debug_line_data.GetULEB128(&offset); + fileEntry.length = debug_line_data.GetULEB128(&offset); + log->Printf("0x%8.8x: DW_LNE_define_file('%s', dir=%i, " + "mod_time=0x%8.8x, length=%i )", + op_offset, fileEntry.name, fileEntry.dir_idx, + fileEntry.mod_time, fileEntry.length); + prologue.file_names.push_back(fileEntry); + } break; + + case DW_LNE_set_discriminator: { + uint64_t discriminator = debug_line_data.GetULEB128(&offset); + log->Printf("0x%8.8x: DW_LNE_set_discriminator (0x%" PRIx64 ")", + op_offset, discriminator); + } break; + default: + log->Printf("0x%8.8x: DW_LNE_??? (%2.2x) - Skipping unknown upcode", + op_offset, opcode); + // Length doesn't include the zero opcode byte or the length itself, + // but + // it does include the sub_opcode, so we have to adjust for that below + offset += arg_size; + break; + } + } break; + + // Standard Opcodes + case DW_LNS_copy: + log->Printf("0x%8.8x: DW_LNS_copy", op_offset); + row.Dump(log); + break; + + case DW_LNS_advance_pc: { + dw_uleb128_t addr_offset_n = debug_line_data.GetULEB128(&offset); + dw_uleb128_t addr_offset = addr_offset_n * prologue.min_inst_length; + log->Printf("0x%8.8x: DW_LNS_advance_pc (0x%x)", op_offset, + addr_offset); + row.address += addr_offset; + } break; + + case DW_LNS_advance_line: { + dw_sleb128_t line_offset = debug_line_data.GetSLEB128(&offset); + log->Printf("0x%8.8x: DW_LNS_advance_line (%i)", op_offset, + line_offset); + row.line += line_offset; + } break; + + case DW_LNS_set_file: + row.file = debug_line_data.GetULEB128(&offset); + log->Printf("0x%8.8x: DW_LNS_set_file (%u)", op_offset, row.file); + break; + + case DW_LNS_set_column: + row.column = debug_line_data.GetULEB128(&offset); + log->Printf("0x%8.8x: DW_LNS_set_column (%u)", op_offset, row.column); + break; + + case DW_LNS_negate_stmt: + row.is_stmt = !row.is_stmt; + log->Printf("0x%8.8x: DW_LNS_negate_stmt", op_offset); + break; + + case DW_LNS_set_basic_block: + row.basic_block = true; + log->Printf("0x%8.8x: DW_LNS_set_basic_block", op_offset); + break; + + case DW_LNS_const_add_pc: { + uint8_t adjust_opcode = 255 - prologue.opcode_base; + dw_addr_t addr_offset = + (adjust_opcode / prologue.line_range) * prologue.min_inst_length; + log->Printf("0x%8.8x: DW_LNS_const_add_pc (0x%8.8" PRIx64 ")", + op_offset, addr_offset); + row.address += addr_offset; + } break; + + case DW_LNS_fixed_advance_pc: { + uint16_t pc_offset = debug_line_data.GetU16(&offset); + log->Printf("0x%8.8x: DW_LNS_fixed_advance_pc (0x%4.4x)", op_offset, + pc_offset); + row.address += pc_offset; + } break; + + case DW_LNS_set_prologue_end: + row.prologue_end = true; + log->Printf("0x%8.8x: DW_LNS_set_prologue_end", op_offset); + break; + + case DW_LNS_set_epilogue_begin: + row.epilogue_begin = true; + log->Printf("0x%8.8x: DW_LNS_set_epilogue_begin", op_offset); + break; + + case DW_LNS_set_isa: + row.isa = debug_line_data.GetULEB128(&offset); + log->Printf("0x%8.8x: DW_LNS_set_isa (%u)", op_offset, row.isa); + break; + + // Special Opcodes + default: + if (opcode < prologue.opcode_base) { + // We have an opcode that this parser doesn't know about, skip + // the number of ULEB128 numbers that is says to skip in the + // prologue's standard_opcode_lengths array + uint8_t n = prologue.standard_opcode_lengths[opcode - 1]; + log->Printf("0x%8.8x: Special : Unknown skipping %u ULEB128 values.", + op_offset, n); + while (n > 0) { + debug_line_data.GetULEB128(&offset); + --n; + } + } else { + uint8_t adjust_opcode = opcode - prologue.opcode_base; + dw_addr_t addr_offset = + (adjust_opcode / prologue.line_range) * prologue.min_inst_length; + int32_t line_offset = + prologue.line_base + (adjust_opcode % prologue.line_range); + log->Printf("0x%8.8x: address += 0x%" PRIx64 ", line += %i\n", + op_offset, (uint64_t)addr_offset, line_offset); + row.address += addr_offset; + row.line += line_offset; + row.Dump(log); } - return end_offset; + break; + } } - return DW_INVALID_OFFSET; + return end_offset; + } + return DW_INVALID_OFFSET; } - - - //---------------------------------------------------------------------- // Parse // @@ -391,120 +361,112 @@ DWARFDebugLine::DumpStatementOpcodes(Log *log, const DWARFDataExtractor& debug_l // new prologue is parsed and every time a new row is to be added to // the line table. //---------------------------------------------------------------------- -void -DWARFDebugLine::Parse(const DWARFDataExtractor& debug_line_data, DWARFDebugLine::State::Callback callback, void* userData) -{ - lldb::offset_t offset = 0; - if (debug_line_data.ValidOffset(offset)) - { - if (!ParseStatementTable(debug_line_data, &offset, callback, userData)) - ++offset; // Skip to next byte in .debug_line section - } +void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data, + DWARFDebugLine::State::Callback callback, + void *userData) { + lldb::offset_t offset = 0; + if (debug_line_data.ValidOffset(offset)) { + if (!ParseStatementTable(debug_line_data, &offset, callback, userData)) + ++offset; // Skip to next byte in .debug_line section + } } - //---------------------------------------------------------------------- // DWARFDebugLine::ParsePrologue //---------------------------------------------------------------------- -bool -DWARFDebugLine::ParsePrologue(const DWARFDataExtractor& debug_line_data, lldb::offset_t* offset_ptr, Prologue* prologue) -{ - const lldb::offset_t prologue_offset = *offset_ptr; - - //DEBUG_PRINTF("0x%8.8x: ParsePrologue()\n", *offset_ptr); - - prologue->Clear(); - uint32_t i; - 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) - return false; - - prologue->prologue_length = debug_line_data.GetDWARFOffset(offset_ptr); - const lldb::offset_t end_prologue_offset = prologue->prologue_length + *offset_ptr; - prologue->min_inst_length = debug_line_data.GetU8(offset_ptr); - if (prologue->version >= 4) - prologue->maximum_operations_per_instruction = debug_line_data.GetU8(offset_ptr); - else - prologue->maximum_operations_per_instruction = 1; - prologue->default_is_stmt = debug_line_data.GetU8(offset_ptr); - prologue->line_base = debug_line_data.GetU8(offset_ptr); - prologue->line_range = debug_line_data.GetU8(offset_ptr); - prologue->opcode_base = debug_line_data.GetU8(offset_ptr); - - prologue->standard_opcode_lengths.reserve(prologue->opcode_base-1); - - for (i=1; i<prologue->opcode_base; ++i) - { - uint8_t op_len = debug_line_data.GetU8(offset_ptr); - 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; - } - - 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; - } +bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data, + lldb::offset_t *offset_ptr, + Prologue *prologue) { + const lldb::offset_t prologue_offset = *offset_ptr; + + // DEBUG_PRINTF("0x%8.8x: ParsePrologue()\n", *offset_ptr); + + prologue->Clear(); + uint32_t i; + 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) + return false; - // XXX GNU as is broken for 64-Bit DWARF - if (*offset_ptr != end_prologue_offset) - { - Host::SystemLog (Host::eSystemLogWarning, - "warning: parsing line table prologue at 0x%8.8" PRIx64 " should have ended at 0x%8.8" PRIx64 " but it ended at 0x%8.8" PRIx64 "\n", - prologue_offset, - end_prologue_offset, - *offset_ptr); - } - return end_prologue_offset; + prologue->prologue_length = debug_line_data.GetDWARFOffset(offset_ptr); + const lldb::offset_t end_prologue_offset = + prologue->prologue_length + *offset_ptr; + prologue->min_inst_length = debug_line_data.GetU8(offset_ptr); + if (prologue->version >= 4) + prologue->maximum_operations_per_instruction = + debug_line_data.GetU8(offset_ptr); + else + prologue->maximum_operations_per_instruction = 1; + prologue->default_is_stmt = debug_line_data.GetU8(offset_ptr); + prologue->line_base = debug_line_data.GetU8(offset_ptr); + prologue->line_range = debug_line_data.GetU8(offset_ptr); + prologue->opcode_base = debug_line_data.GetU8(offset_ptr); + + prologue->standard_opcode_lengths.reserve(prologue->opcode_base - 1); + + for (i = 1; i < prologue->opcode_base; ++i) { + uint8_t op_len = debug_line_data.GetU8(offset_ptr); + 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; + } + + 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 + if (*offset_ptr != end_prologue_offset) { + Host::SystemLog(Host::eSystemLogWarning, + "warning: parsing line table prologue at 0x%8.8" PRIx64 + " should have ended at 0x%8.8" PRIx64 + " but it ended at 0x%8.8" PRIx64 "\n", + prologue_offset, end_prologue_offset, *offset_ptr); + } + return end_prologue_offset; } -bool -DWARFDebugLine::ParseSupportFiles (const lldb::ModuleSP &module_sp, - const DWARFDataExtractor& debug_line_data, - const char *cu_comp_dir, - dw_offset_t stmt_list, - FileSpecList &support_files) -{ - lldb::offset_t offset = stmt_list; - - Prologue prologue; - if (!ParsePrologue(debug_line_data, &offset, &prologue)) - { - Host::SystemLog (Host::eSystemLogError, "error: parsing line table prologue at 0x%8.8x (parsing ended around 0x%8.8" PRIx64 "\n", stmt_list, offset); - return false; - } - - FileSpec file_spec; - std::string remapped_file; - - for (uint32_t file_idx = 1; prologue.GetFile(file_idx, cu_comp_dir, file_spec); ++file_idx) - { - if (module_sp->RemapSourceFile(file_spec.GetCString(), remapped_file)) - file_spec.SetFile(remapped_file, false); - support_files.Append(file_spec); - - } - return true; +bool DWARFDebugLine::ParseSupportFiles( + const lldb::ModuleSP &module_sp, const DWARFDataExtractor &debug_line_data, + const char *cu_comp_dir, dw_offset_t stmt_list, + FileSpecList &support_files) { + lldb::offset_t offset = stmt_list; + + Prologue prologue; + if (!ParsePrologue(debug_line_data, &offset, &prologue)) { + Host::SystemLog(Host::eSystemLogError, "error: parsing line table prologue " + "at 0x%8.8x (parsing ended around " + "0x%8.8" PRIx64 "\n", + stmt_list, offset); + return false; + } + + FileSpec file_spec; + std::string remapped_file; + + 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); + support_files.Append(file_spec); + } + return true; } //---------------------------------------------------------------------- @@ -514,304 +476,294 @@ DWARFDebugLine::ParseSupportFiles (const lldb::ModuleSP &module_sp, // callback function once for the prologue (row in state will be zero) // and each time a row is to be added to the line table. //---------------------------------------------------------------------- -bool -DWARFDebugLine::ParseStatementTable -( - const DWARFDataExtractor& debug_line_data, - lldb::offset_t* offset_ptr, - DWARFDebugLine::State::Callback callback, - void* userData -) -{ - Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_LINE)); - Prologue::shared_ptr prologue(new Prologue()); - - - const dw_offset_t debug_line_offset = *offset_ptr; - - Timer scoped_timer (__PRETTY_FUNCTION__, - "DWARFDebugLine::ParseStatementTable (.debug_line[0x%8.8x])", - debug_line_offset); - - if (!ParsePrologue(debug_line_data, offset_ptr, prologue.get())) - { - if (log) - log->Error ("failed to parse DWARF line table prologue"); - // Restore our offset and return false to indicate failure! - *offset_ptr = debug_line_offset; - return false; - } +bool DWARFDebugLine::ParseStatementTable( + const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr, + DWARFDebugLine::State::Callback callback, void *userData) { + Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_LINE)); + Prologue::shared_ptr prologue(new Prologue()); - if (log) - prologue->Dump (log); + const dw_offset_t debug_line_offset = *offset_ptr; - const dw_offset_t end_offset = debug_line_offset + prologue->total_length + (debug_line_data.GetDWARFSizeofInitialLength()); + Timer scoped_timer( + LLVM_PRETTY_FUNCTION, + "DWARFDebugLine::ParseStatementTable (.debug_line[0x%8.8x])", + debug_line_offset); - State state(prologue, log, callback, userData); - - while (*offset_ptr < end_offset) - { - //DEBUG_PRINTF("0x%8.8x: ", *offset_ptr); - uint8_t opcode = debug_line_data.GetU8(offset_ptr); - - if (opcode == 0) + if (!ParsePrologue(debug_line_data, offset_ptr, prologue.get())) { + if (log) + log->Error("failed to parse DWARF line table prologue"); + // Restore our offset and return false to indicate failure! + *offset_ptr = debug_line_offset; + return false; + } + + if (log) + prologue->Dump(log); + + const dw_offset_t end_offset = + debug_line_offset + prologue->total_length + + (debug_line_data.GetDWARFSizeofInitialLength()); + + State state(prologue, log, callback, userData); + + while (*offset_ptr < end_offset) { + // DEBUG_PRINTF("0x%8.8x: ", *offset_ptr); + uint8_t opcode = debug_line_data.GetU8(offset_ptr); + + if (opcode == 0) { + // Extended Opcodes always start with a zero opcode followed by + // a uleb128 length so you can skip ones you don't know about + lldb::offset_t ext_offset = *offset_ptr; + dw_uleb128_t len = debug_line_data.GetULEB128(offset_ptr); + dw_offset_t arg_size = len - (*offset_ptr - ext_offset); + + // DEBUG_PRINTF("Extended: <%2u> ", len); + uint8_t sub_opcode = debug_line_data.GetU8(offset_ptr); + switch (sub_opcode) { + case DW_LNE_end_sequence: + // Set the end_sequence register of the state machine to true and + // append a row to the matrix using the current values of the + // state-machine registers. Then reset the registers to the initial + // values specified above. Every statement program sequence must end + // with a DW_LNE_end_sequence instruction which creates a row whose + // address is that of the byte after the last target machine instruction + // of the sequence. + state.end_sequence = true; + state.AppendRowToMatrix(*offset_ptr); + state.Reset(); + break; + + case DW_LNE_set_address: + // Takes a single relocatable address as an operand. The size of the + // operand is the size appropriate to hold an address on the target + // machine. Set the address register to the value given by the + // relocatable address. All of the other statement program opcodes + // that affect the address register add a delta to it. This instruction + // stores a relocatable value into it instead. + if (arg_size == 4) + state.address = debug_line_data.GetU32(offset_ptr); + else // arg_size == 8 + state.address = debug_line_data.GetU64(offset_ptr); + break; + + case DW_LNE_define_file: + // Takes 4 arguments. The first is a null terminated string containing + // a source file name. The second is an unsigned LEB128 number + // representing + // the directory index of the directory in which the file was found. The + // third is an unsigned LEB128 number representing the time of last + // modification of the file. The fourth is an unsigned LEB128 number + // representing the length in bytes of the file. The time and length + // fields may contain LEB128(0) if the information is not available. + // + // The directory index represents an entry in the include_directories + // section of the statement program prologue. The index is LEB128(0) + // if the file was found in the current directory of the compilation, + // LEB128(1) if it was found in the first directory in the + // include_directories section, and so on. The directory index is + // ignored for file names that represent full path names. + // + // The files are numbered, starting at 1, in the order in which they + // appear; the names in the prologue come before names defined by + // the DW_LNE_define_file instruction. These numbers are used in the + // file register of the state machine. { - // Extended Opcodes always start with a zero opcode followed by - // a uleb128 length so you can skip ones you don't know about - lldb::offset_t ext_offset = *offset_ptr; - dw_uleb128_t len = debug_line_data.GetULEB128(offset_ptr); - dw_offset_t arg_size = len - (*offset_ptr - ext_offset); - - //DEBUG_PRINTF("Extended: <%2u> ", len); - uint8_t sub_opcode = debug_line_data.GetU8(offset_ptr); - switch (sub_opcode) - { - case DW_LNE_end_sequence: - // Set the end_sequence register of the state machine to true and - // append a row to the matrix using the current values of the - // state-machine registers. Then reset the registers to the initial - // values specified above. Every statement program sequence must end - // with a DW_LNE_end_sequence instruction which creates a row whose - // address is that of the byte after the last target machine instruction - // of the sequence. - state.end_sequence = true; - state.AppendRowToMatrix(*offset_ptr); - state.Reset(); - break; - - case DW_LNE_set_address: - // Takes a single relocatable address as an operand. The size of the - // operand is the size appropriate to hold an address on the target - // machine. Set the address register to the value given by the - // relocatable address. All of the other statement program opcodes - // that affect the address register add a delta to it. This instruction - // stores a relocatable value into it instead. - if (arg_size == 4) - state.address = debug_line_data.GetU32(offset_ptr); - else // arg_size == 8 - state.address = debug_line_data.GetU64(offset_ptr); - break; - - case DW_LNE_define_file: - // Takes 4 arguments. The first is a null terminated string containing - // a source file name. The second is an unsigned LEB128 number representing - // the directory index of the directory in which the file was found. The - // third is an unsigned LEB128 number representing the time of last - // modification of the file. The fourth is an unsigned LEB128 number - // representing the length in bytes of the file. The time and length - // fields may contain LEB128(0) if the information is not available. - // - // The directory index represents an entry in the include_directories - // section of the statement program prologue. The index is LEB128(0) - // if the file was found in the current directory of the compilation, - // LEB128(1) if it was found in the first directory in the - // include_directories section, and so on. The directory index is - // ignored for file names that represent full path names. - // - // The files are numbered, starting at 1, in the order in which they - // appear; the names in the prologue come before names defined by - // the DW_LNE_define_file instruction. These numbers are used in the - // file register of the state machine. - { - FileNameEntry fileEntry; - fileEntry.name = debug_line_data.GetCStr(offset_ptr); - 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); - state.prologue->file_names.push_back(fileEntry); - } - break; - - default: - // Length doesn't include the zero opcode byte or the length itself, but - // it does include the sub_opcode, so we have to adjust for that below - (*offset_ptr) += arg_size; - break; - } + FileNameEntry fileEntry; + fileEntry.name = debug_line_data.GetCStr(offset_ptr); + 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); + state.prologue->file_names.push_back(fileEntry); } - else if (opcode < prologue->opcode_base) + break; + + default: + // Length doesn't include the zero opcode byte or the length itself, but + // it does include the sub_opcode, so we have to adjust for that below + (*offset_ptr) += arg_size; + break; + } + } else if (opcode < prologue->opcode_base) { + switch (opcode) { + // Standard Opcodes + case DW_LNS_copy: + // Takes no arguments. Append a row to the matrix using the + // current values of the state-machine registers. Then set + // the basic_block register to false. + state.AppendRowToMatrix(*offset_ptr); + break; + + case DW_LNS_advance_pc: + // Takes a single unsigned LEB128 operand, multiplies it by the + // min_inst_length field of the prologue, and adds the + // result to the address register of the state machine. + state.address += + debug_line_data.GetULEB128(offset_ptr) * prologue->min_inst_length; + break; + + case DW_LNS_advance_line: + // Takes a single signed LEB128 operand and adds that value to + // the line register of the state machine. + state.line += debug_line_data.GetSLEB128(offset_ptr); + break; + + case DW_LNS_set_file: + // Takes a single unsigned LEB128 operand and stores it in the file + // register of the state machine. + state.file = debug_line_data.GetULEB128(offset_ptr); + break; + + case DW_LNS_set_column: + // Takes a single unsigned LEB128 operand and stores it in the + // column register of the state machine. + state.column = debug_line_data.GetULEB128(offset_ptr); + break; + + case DW_LNS_negate_stmt: + // Takes no arguments. Set the is_stmt register of the state + // machine to the logical negation of its current value. + state.is_stmt = !state.is_stmt; + break; + + case DW_LNS_set_basic_block: + // Takes no arguments. Set the basic_block register of the + // state machine to true + state.basic_block = true; + break; + + case DW_LNS_const_add_pc: + // Takes no arguments. Add to the address register of the state + // machine the address increment value corresponding to special + // opcode 255. The motivation for DW_LNS_const_add_pc is this: + // when the statement program needs to advance the address by a + // small amount, it can use a single special opcode, which occupies + // a single byte. When it needs to advance the address by up to + // twice the range of the last special opcode, it can use + // DW_LNS_const_add_pc followed by a special opcode, for a total + // of two bytes. Only if it needs to advance the address by more + // than twice that range will it need to use both DW_LNS_advance_pc + // and a special opcode, requiring three or more bytes. { - switch (opcode) - { - // Standard Opcodes - case DW_LNS_copy: - // Takes no arguments. Append a row to the matrix using the - // current values of the state-machine registers. Then set - // the basic_block register to false. - state.AppendRowToMatrix(*offset_ptr); - break; - - case DW_LNS_advance_pc: - // Takes a single unsigned LEB128 operand, multiplies it by the - // min_inst_length field of the prologue, and adds the - // result to the address register of the state machine. - state.address += debug_line_data.GetULEB128(offset_ptr) * prologue->min_inst_length; - break; - - case DW_LNS_advance_line: - // Takes a single signed LEB128 operand and adds that value to - // the line register of the state machine. - state.line += debug_line_data.GetSLEB128(offset_ptr); - break; - - case DW_LNS_set_file: - // Takes a single unsigned LEB128 operand and stores it in the file - // register of the state machine. - state.file = debug_line_data.GetULEB128(offset_ptr); - break; - - case DW_LNS_set_column: - // Takes a single unsigned LEB128 operand and stores it in the - // column register of the state machine. - state.column = debug_line_data.GetULEB128(offset_ptr); - break; - - case DW_LNS_negate_stmt: - // Takes no arguments. Set the is_stmt register of the state - // machine to the logical negation of its current value. - state.is_stmt = !state.is_stmt; - break; - - case DW_LNS_set_basic_block: - // Takes no arguments. Set the basic_block register of the - // state machine to true - state.basic_block = true; - break; - - case DW_LNS_const_add_pc: - // Takes no arguments. Add to the address register of the state - // machine the address increment value corresponding to special - // opcode 255. The motivation for DW_LNS_const_add_pc is this: - // when the statement program needs to advance the address by a - // small amount, it can use a single special opcode, which occupies - // a single byte. When it needs to advance the address by up to - // twice the range of the last special opcode, it can use - // DW_LNS_const_add_pc followed by a special opcode, for a total - // of two bytes. Only if it needs to advance the address by more - // than twice that range will it need to use both DW_LNS_advance_pc - // and a special opcode, requiring three or more bytes. - { - uint8_t adjust_opcode = 255 - prologue->opcode_base; - dw_addr_t addr_offset = (adjust_opcode / prologue->line_range) * prologue->min_inst_length; - state.address += addr_offset; - } - break; - - case DW_LNS_fixed_advance_pc: - // Takes a single uhalf operand. Add to the address register of - // the state machine the value of the (unencoded) operand. This - // is the only extended opcode that takes an argument that is not - // a variable length number. The motivation for DW_LNS_fixed_advance_pc - // is this: existing assemblers cannot emit DW_LNS_advance_pc or - // special opcodes because they cannot encode LEB128 numbers or - // judge when the computation of a special opcode overflows and - // requires the use of DW_LNS_advance_pc. Such assemblers, however, - // can use DW_LNS_fixed_advance_pc instead, sacrificing compression. - state.address += debug_line_data.GetU16(offset_ptr); - break; - - case DW_LNS_set_prologue_end: - // Takes no arguments. Set the prologue_end register of the - // state machine to true - state.prologue_end = true; - break; - - case DW_LNS_set_epilogue_begin: - // Takes no arguments. Set the basic_block register of the - // state machine to true - state.epilogue_begin = true; - break; - - case DW_LNS_set_isa: - // Takes a single unsigned LEB128 operand and stores it in the - // column register of the state machine. - state.isa = debug_line_data.GetULEB128(offset_ptr); - break; - - default: - // Handle any unknown standard opcodes here. We know the lengths - // of such opcodes because they are specified in the prologue - // as a multiple of LEB128 operands for each opcode. - { - uint8_t i; - assert (static_cast<size_t>(opcode - 1) < prologue->standard_opcode_lengths.size()); - const uint8_t opcode_length = prologue->standard_opcode_lengths[opcode - 1]; - for (i=0; i<opcode_length; ++i) - debug_line_data.Skip_LEB128(offset_ptr); - } - break; - } + uint8_t adjust_opcode = 255 - prologue->opcode_base; + dw_addr_t addr_offset = (adjust_opcode / prologue->line_range) * + prologue->min_inst_length; + state.address += addr_offset; } - else + break; + + case DW_LNS_fixed_advance_pc: + // Takes a single uhalf operand. Add to the address register of + // the state machine the value of the (unencoded) operand. This + // is the only extended opcode that takes an argument that is not + // a variable length number. The motivation for DW_LNS_fixed_advance_pc + // is this: existing assemblers cannot emit DW_LNS_advance_pc or + // special opcodes because they cannot encode LEB128 numbers or + // judge when the computation of a special opcode overflows and + // requires the use of DW_LNS_advance_pc. Such assemblers, however, + // can use DW_LNS_fixed_advance_pc instead, sacrificing compression. + state.address += debug_line_data.GetU16(offset_ptr); + break; + + case DW_LNS_set_prologue_end: + // Takes no arguments. Set the prologue_end register of the + // state machine to true + state.prologue_end = true; + break; + + case DW_LNS_set_epilogue_begin: + // Takes no arguments. Set the basic_block register of the + // state machine to true + state.epilogue_begin = true; + break; + + case DW_LNS_set_isa: + // Takes a single unsigned LEB128 operand and stores it in the + // column register of the state machine. + state.isa = debug_line_data.GetULEB128(offset_ptr); + break; + + default: + // Handle any unknown standard opcodes here. We know the lengths + // of such opcodes because they are specified in the prologue + // as a multiple of LEB128 operands for each opcode. { - // Special Opcodes - - // A special opcode value is chosen based on the amount that needs - // to be added to the line and address registers. The maximum line - // increment for a special opcode is the value of the line_base - // field in the header, plus the value of the line_range field, - // minus 1 (line base + line range - 1). If the desired line - // increment is greater than the maximum line increment, a standard - // opcode must be used instead of a special opcode. The "address - // advance" is calculated by dividing the desired address increment - // by the minimum_instruction_length field from the header. The - // special opcode is then calculated using the following formula: - // - // opcode = (desired line increment - line_base) + (line_range * address advance) + opcode_base - // - // If the resulting opcode is greater than 255, a standard opcode - // must be used instead. - // - // To decode a special opcode, subtract the opcode_base from the - // opcode itself to give the adjusted opcode. The amount to - // increment the address register is the result of the adjusted - // opcode divided by the line_range multiplied by the - // minimum_instruction_length field from the header. That is: - // - // address increment = (adjusted opcode / line_range) * minimum_instruction_length - // - // The amount to increment the line register is the line_base plus - // the result of the adjusted opcode modulo the line_range. That is: - // - // line increment = line_base + (adjusted opcode % line_range) - - uint8_t adjust_opcode = opcode - prologue->opcode_base; - dw_addr_t addr_offset = (adjust_opcode / prologue->line_range) * prologue->min_inst_length; - int32_t line_offset = prologue->line_base + (adjust_opcode % prologue->line_range); - state.line += line_offset; - state.address += addr_offset; - state.AppendRowToMatrix(*offset_ptr); + uint8_t i; + assert(static_cast<size_t>(opcode - 1) < + prologue->standard_opcode_lengths.size()); + const uint8_t opcode_length = + prologue->standard_opcode_lengths[opcode - 1]; + for (i = 0; i < opcode_length; ++i) + debug_line_data.Skip_LEB128(offset_ptr); } + break; + } + } else { + // Special Opcodes + + // A special opcode value is chosen based on the amount that needs + // to be added to the line and address registers. The maximum line + // increment for a special opcode is the value of the line_base + // field in the header, plus the value of the line_range field, + // minus 1 (line base + line range - 1). If the desired line + // increment is greater than the maximum line increment, a standard + // opcode must be used instead of a special opcode. The "address + // advance" is calculated by dividing the desired address increment + // by the minimum_instruction_length field from the header. The + // special opcode is then calculated using the following formula: + // + // opcode = (desired line increment - line_base) + (line_range * address + // advance) + opcode_base + // + // If the resulting opcode is greater than 255, a standard opcode + // must be used instead. + // + // To decode a special opcode, subtract the opcode_base from the + // opcode itself to give the adjusted opcode. The amount to + // increment the address register is the result of the adjusted + // opcode divided by the line_range multiplied by the + // minimum_instruction_length field from the header. That is: + // + // address increment = (adjusted opcode / line_range) * + // minimum_instruction_length + // + // The amount to increment the line register is the line_base plus + // the result of the adjusted opcode modulo the line_range. That is: + // + // line increment = line_base + (adjusted opcode % line_range) + + uint8_t adjust_opcode = opcode - prologue->opcode_base; + dw_addr_t addr_offset = + (adjust_opcode / prologue->line_range) * prologue->min_inst_length; + int32_t line_offset = + prologue->line_base + (adjust_opcode % prologue->line_range); + state.line += line_offset; + state.address += addr_offset; + state.AppendRowToMatrix(*offset_ptr); } + } - state.Finalize( *offset_ptr ); + state.Finalize(*offset_ptr); - return end_offset; + return end_offset; } - //---------------------------------------------------------------------- // ParseStatementTableCallback //---------------------------------------------------------------------- -static void -ParseStatementTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData) -{ - DWARFDebugLine::LineTable* line_table = (DWARFDebugLine::LineTable*)userData; - if (state.row == DWARFDebugLine::State::StartParsingLineTable) - { - // Just started parsing the line table, so lets keep a reference to - // the prologue using the supplied shared pointer - line_table->prologue = state.prologue; - } - else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) - { - // Done parsing line table, nothing to do for the cleanup - } - else - { - // We have a new row, lets append it - line_table->AppendRow(state); - } +static void ParseStatementTableCallback(dw_offset_t offset, + const DWARFDebugLine::State &state, + void *userData) { + DWARFDebugLine::LineTable *line_table = (DWARFDebugLine::LineTable *)userData; + if (state.row == DWARFDebugLine::State::StartParsingLineTable) { + // Just started parsing the line table, so lets keep a reference to + // the prologue using the supplied shared pointer + line_table->prologue = state.prologue; + } else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) { + // Done parsing line table, nothing to do for the cleanup + } else { + // We have a new row, lets append it + line_table->AppendRow(state); + } } //---------------------------------------------------------------------- @@ -820,75 +772,65 @@ ParseStatementTableCallback(dw_offset_t offset, const DWARFDebugLine::State& sta // Parse a line table at offset and populate the LineTable class with // the prologue and all rows. //---------------------------------------------------------------------- -bool -DWARFDebugLine::ParseStatementTable(const DWARFDataExtractor& debug_line_data, lldb::offset_t *offset_ptr, LineTable* line_table) -{ - return ParseStatementTable(debug_line_data, offset_ptr, ParseStatementTableCallback, line_table); +bool DWARFDebugLine::ParseStatementTable( + const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr, + LineTable *line_table) { + return ParseStatementTable(debug_line_data, offset_ptr, + ParseStatementTableCallback, line_table); } - -inline bool -DWARFDebugLine::Prologue::IsValid() const -{ - return SymbolFileDWARF::SupportedVersion(version); +inline bool DWARFDebugLine::Prologue::IsValid() const { + return SymbolFileDWARF::SupportedVersion(version); } //---------------------------------------------------------------------- // DWARFDebugLine::Prologue::Dump //---------------------------------------------------------------------- -void -DWARFDebugLine::Prologue::Dump(Log *log) -{ - uint32_t i; - - log->Printf( "Line table prologue:"); - log->Printf( " total_length: 0x%8.8x", total_length); - log->Printf( " version: %u", version); - log->Printf( "prologue_length: 0x%8.8x", prologue_length); - log->Printf( "min_inst_length: %u", min_inst_length); - log->Printf( "default_is_stmt: %u", default_is_stmt); - log->Printf( " line_base: %i", line_base); - log->Printf( " line_range: %u", line_range); - log->Printf( " opcode_base: %u", opcode_base); - - for (i=0; i<standard_opcode_lengths.size(); ++i) - { - log->Printf( "standard_opcode_lengths[%s] = %u", DW_LNS_value_to_name(i+1), standard_opcode_lengths[i]); +void DWARFDebugLine::Prologue::Dump(Log *log) { + uint32_t i; + + log->Printf("Line table prologue:"); + log->Printf(" total_length: 0x%8.8x", total_length); + log->Printf(" version: %u", version); + log->Printf("prologue_length: 0x%8.8x", prologue_length); + log->Printf("min_inst_length: %u", min_inst_length); + log->Printf("default_is_stmt: %u", default_is_stmt); + log->Printf(" line_base: %i", line_base); + log->Printf(" line_range: %u", line_range); + log->Printf(" opcode_base: %u", opcode_base); + + for (i = 0; i < standard_opcode_lengths.size(); ++i) { + log->Printf("standard_opcode_lengths[%s] = %u", DW_LNS_value_to_name(i + 1), + standard_opcode_lengths[i]); + } + + if (!include_directories.empty()) { + for (i = 0; i < include_directories.size(); ++i) { + log->Printf("include_directories[%3u] = '%s'", i + 1, + include_directories[i]); } - - if (!include_directories.empty()) - { - for (i=0; i<include_directories.size(); ++i) - { - log->Printf( "include_directories[%3u] = '%s'", i+1, include_directories[i]); - } - } - - if (!file_names.empty()) - { - log->PutCString (" Dir Mod Time File Len File Name"); - log->PutCString (" ---- ---------- ---------- ---------------------------"); - for (i=0; i<file_names.size(); ++i) - { - const FileNameEntry& fileEntry = file_names[i]; - log->Printf ("file_names[%3u] %4u 0x%8.8x 0x%8.8x %s", - i+1, - fileEntry.dir_idx, - fileEntry.mod_time, - fileEntry.length, - fileEntry.name); - } + } + + if (!file_names.empty()) { + log->PutCString(" Dir Mod Time File Len File Name"); + log->PutCString(" ---- ---------- ---------- " + "---------------------------"); + for (i = 0; i < file_names.size(); ++i) { + const FileNameEntry &fileEntry = file_names[i]; + log->Printf("file_names[%3u] %4u 0x%8.8x 0x%8.8x %s", i + 1, + fileEntry.dir_idx, fileEntry.mod_time, fileEntry.length, + fileEntry.name); } + } } - //---------------------------------------------------------------------- // DWARFDebugLine::ParsePrologue::Append // // Append the contents of the prologue to the binary stream buffer //---------------------------------------------------------------------- -//void -//DWARFDebugLine::Prologue::Append(BinaryStreamBuf& buff) const +// void +// DWARFDebugLine::Prologue::Append(BinaryStreamBuf& buff) const //{ // uint32_t i; // @@ -906,7 +848,8 @@ DWARFDebugLine::Prologue::Dump(Log *log) // // for (i=0; i<include_directories.size(); ++i) // buff.AppendCStr(include_directories[i].c_str()); -// buff.Append8(0); // Terminate the include directory section with empty string +// buff.Append8(0); // Terminate the include directory section with empty +// string // // for (i=0; i<file_names.size(); ++i) // { @@ -918,307 +861,242 @@ DWARFDebugLine::Prologue::Dump(Log *log) // buff.Append8(0); // Terminate the file names section with empty string //} - -bool DWARFDebugLine::Prologue::GetFile(uint32_t file_idx, const char *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); - if (file.IsRelative()) - { - if (file_names[idx].dir_idx > 0) - { - const uint32_t dir_idx = file_names[idx].dir_idx - 1; - if (dir_idx < include_directories.size()) - { - file.PrependPathComponent(include_directories[dir_idx]); - if (!file.IsRelative()) - return true; - } - } - - if (comp_dir && comp_dir[0]) - file.PrependPathComponent(comp_dir); +bool DWARFDebugLine::Prologue::GetFile(uint32_t file_idx, const char *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); + if (file.IsRelative()) { + if (file_names[idx].dir_idx > 0) { + const uint32_t dir_idx = file_names[idx].dir_idx - 1; + if (dir_idx < include_directories.size()) { + file.PrependPathComponent(include_directories[dir_idx]); + if (!file.IsRelative()) + return true; } - return true; + } + + if (comp_dir && comp_dir[0]) + file.PrependPathComponent(comp_dir); } - return false; + return true; + } + return false; } //---------------------------------------------------------------------- // DWARFDebugLine::LineTable::Dump //---------------------------------------------------------------------- -void -DWARFDebugLine::LineTable::Dump(Log *log) const -{ - if (prologue.get()) - prologue->Dump (log); - - if (!rows.empty()) - { - log->PutCString ("Address Line Column File ISA Flags"); - log->PutCString ("------------------ ------ ------ ------ --- -------------"); - Row::const_iterator pos = rows.begin(); - Row::const_iterator end = rows.end(); - while (pos != end) - { - (*pos).Dump (log); - ++pos; - } +void DWARFDebugLine::LineTable::Dump(Log *log) const { + if (prologue.get()) + prologue->Dump(log); + + if (!rows.empty()) { + log->PutCString("Address Line Column File ISA Flags"); + log->PutCString( + "------------------ ------ ------ ------ --- -------------"); + Row::const_iterator pos = rows.begin(); + Row::const_iterator end = rows.end(); + while (pos != end) { + (*pos).Dump(log); + ++pos; } + } } - -void -DWARFDebugLine::LineTable::AppendRow(const DWARFDebugLine::Row& state) -{ - rows.push_back(state); +void DWARFDebugLine::LineTable::AppendRow(const DWARFDebugLine::Row &state) { + rows.push_back(state); } - - //---------------------------------------------------------------------- -// Compare function for the binary search in DWARFDebugLine::LineTable::LookupAddress() +// Compare function for the binary search in +// DWARFDebugLine::LineTable::LookupAddress() //---------------------------------------------------------------------- -static bool FindMatchingAddress (const DWARFDebugLine::Row& row1, const DWARFDebugLine::Row& row2) -{ - return row1.address < row2.address; +static bool FindMatchingAddress(const DWARFDebugLine::Row &row1, + const DWARFDebugLine::Row &row2) { + return row1.address < row2.address; } - //---------------------------------------------------------------------- // DWARFDebugLine::LineTable::LookupAddress //---------------------------------------------------------------------- -uint32_t -DWARFDebugLine::LineTable::LookupAddress(dw_addr_t address, dw_addr_t cu_high_pc) const -{ - uint32_t index = UINT32_MAX; - if (!rows.empty()) - { - // Use the lower_bound algorithm to perform a binary search since we know - // that our line table data is ordered by address. - DWARFDebugLine::Row row; - row.address = address; - Row::const_iterator begin_pos = rows.begin(); - Row::const_iterator end_pos = rows.end(); - Row::const_iterator pos = lower_bound(begin_pos, end_pos, row, FindMatchingAddress); - if (pos == end_pos) - { - if (address < cu_high_pc) - return rows.size()-1; - } +uint32_t DWARFDebugLine::LineTable::LookupAddress(dw_addr_t address, + dw_addr_t cu_high_pc) const { + uint32_t index = UINT32_MAX; + if (!rows.empty()) { + // Use the lower_bound algorithm to perform a binary search since we know + // that our line table data is ordered by address. + DWARFDebugLine::Row row; + row.address = address; + Row::const_iterator begin_pos = rows.begin(); + Row::const_iterator end_pos = rows.end(); + Row::const_iterator pos = + lower_bound(begin_pos, end_pos, row, FindMatchingAddress); + if (pos == end_pos) { + if (address < cu_high_pc) + return rows.size() - 1; + } else { + // Rely on fact that we are using a std::vector and we can do + // pointer arithmetic to find the row index (which will be one less + // that what we found since it will find the first position after + // the current address) since std::vector iterators are just + // pointers to the container type. + index = pos - begin_pos; + if (pos->address > address) { + if (index > 0) + --index; else - { - // Rely on fact that we are using a std::vector and we can do - // pointer arithmetic to find the row index (which will be one less - // that what we found since it will find the first position after - // the current address) since std::vector iterators are just - // pointers to the container type. - index = pos - begin_pos; - if (pos->address > address) - { - if (index > 0) - --index; - else - index = UINT32_MAX; - } - } + index = UINT32_MAX; + } } - return index; // Failed to find address + } + return index; // Failed to find address } - //---------------------------------------------------------------------- // DWARFDebugLine::Row::Row //---------------------------------------------------------------------- -DWARFDebugLine::Row::Row(bool default_is_stmt) : - address(0), - line(1), - column(0), - file(1), - is_stmt(default_is_stmt), - basic_block(false), - end_sequence(false), - prologue_end(false), - epilogue_begin(false), - isa(0) -{ -} +DWARFDebugLine::Row::Row(bool default_is_stmt) + : address(0), line(1), column(0), file(1), is_stmt(default_is_stmt), + basic_block(false), end_sequence(false), prologue_end(false), + epilogue_begin(false), isa(0) {} //---------------------------------------------------------------------- // Called after a row is appended to the matrix //---------------------------------------------------------------------- -void -DWARFDebugLine::Row::PostAppend() -{ - basic_block = false; - prologue_end = false; - epilogue_begin = false; +void DWARFDebugLine::Row::PostAppend() { + basic_block = false; + prologue_end = false; + epilogue_begin = false; } - //---------------------------------------------------------------------- // DWARFDebugLine::Row::Reset //---------------------------------------------------------------------- -void -DWARFDebugLine::Row::Reset(bool default_is_stmt) -{ - address = 0; - line = 1; - column = 0; - file = 1; - is_stmt = default_is_stmt; - basic_block = false; - end_sequence = false; - prologue_end = false; - epilogue_begin = false; - isa = 0; +void DWARFDebugLine::Row::Reset(bool default_is_stmt) { + address = 0; + line = 1; + column = 0; + file = 1; + is_stmt = default_is_stmt; + basic_block = false; + end_sequence = false; + prologue_end = false; + epilogue_begin = false; + isa = 0; } //---------------------------------------------------------------------- // DWARFDebugLine::Row::Dump //---------------------------------------------------------------------- -void -DWARFDebugLine::Row::Dump(Log *log) const -{ - log->Printf( "0x%16.16" PRIx64 " %6u %6u %6u %3u %s%s%s%s%s", - address, - line, - column, - file, - isa, - is_stmt ? " is_stmt" : "", - basic_block ? " basic_block" : "", - prologue_end ? " prologue_end" : "", - epilogue_begin ? " epilogue_begin" : "", - end_sequence ? " end_sequence" : ""); +void DWARFDebugLine::Row::Dump(Log *log) const { + log->Printf("0x%16.16" PRIx64 " %6u %6u %6u %3u %s%s%s%s%s", address, line, + column, file, isa, is_stmt ? " is_stmt" : "", + basic_block ? " basic_block" : "", + prologue_end ? " prologue_end" : "", + epilogue_begin ? " epilogue_begin" : "", + end_sequence ? " end_sequence" : ""); } //---------------------------------------------------------------------- // Compare function LineTable structures //---------------------------------------------------------------------- -static bool AddressLessThan (const DWARFDebugLine::Row& a, const DWARFDebugLine::Row& b) -{ - return a.address < b.address; +static bool AddressLessThan(const DWARFDebugLine::Row &a, + const DWARFDebugLine::Row &b) { + return a.address < b.address; } - - // Insert a row at the correct address if the addresses can be out of // order which can only happen when we are linking a line table that // may have had it's contents rearranged. -void -DWARFDebugLine::Row::Insert(Row::collection& state_coll, const Row& state) -{ - // If we don't have anything yet, or if the address of the last state in our - // line table is less than the current one, just append the current state - if (state_coll.empty() || AddressLessThan(state_coll.back(), state)) - { - state_coll.push_back(state); - } - else - { - // Do a binary search for the correct entry - pair<Row::iterator, Row::iterator> range(equal_range(state_coll.begin(), state_coll.end(), state, AddressLessThan)); - - // If the addresses are equal, we can safely replace the previous entry - // with the current one if the one it is replacing is an end_sequence entry. - // We currently always place an extra end sequence when ever we exit a valid - // address range for a function in case the functions get rearranged by - // optimizations or by order specifications. These extra end sequences will - // disappear by getting replaced with valid consecutive entries within a - // compile unit if there are no gaps. - if (range.first == range.second) - { - state_coll.insert(range.first, state); - } - else - { - if ((distance(range.first, range.second) == 1) && range.first->end_sequence == true) - { - *range.first = state; - } - else - { - state_coll.insert(range.second, state); - } - } +void DWARFDebugLine::Row::Insert(Row::collection &state_coll, + const Row &state) { + // If we don't have anything yet, or if the address of the last state in our + // line table is less than the current one, just append the current state + if (state_coll.empty() || AddressLessThan(state_coll.back(), state)) { + state_coll.push_back(state); + } else { + // Do a binary search for the correct entry + pair<Row::iterator, Row::iterator> range(equal_range( + state_coll.begin(), state_coll.end(), state, AddressLessThan)); + + // If the addresses are equal, we can safely replace the previous entry + // with the current one if the one it is replacing is an end_sequence entry. + // We currently always place an extra end sequence when ever we exit a valid + // address range for a function in case the functions get rearranged by + // optimizations or by order specifications. These extra end sequences will + // disappear by getting replaced with valid consecutive entries within a + // compile unit if there are no gaps. + if (range.first == range.second) { + state_coll.insert(range.first, state); + } else { + if ((distance(range.first, range.second) == 1) && + range.first->end_sequence == true) { + *range.first = state; + } else { + state_coll.insert(range.second, state); + } } + } } -void -DWARFDebugLine::Row::Dump(Log *log, const Row::collection& state_coll) -{ - std::for_each (state_coll.begin(), state_coll.end(), bind2nd(std::mem_fun_ref(&Row::Dump),log)); +void DWARFDebugLine::Row::Dump(Log *log, const Row::collection &state_coll) { + std::for_each(state_coll.begin(), state_coll.end(), + bind2nd(std::mem_fun_ref(&Row::Dump), log)); } - //---------------------------------------------------------------------- // DWARFDebugLine::State::State //---------------------------------------------------------------------- -DWARFDebugLine::State::State(Prologue::shared_ptr& p, Log *l, DWARFDebugLine::State::Callback cb, void* userData) : - Row (p->default_is_stmt), - prologue (p), - log (l), - callback (cb), - callbackUserData (userData), - row (StartParsingLineTable) -{ - // Call the callback with the initial row state of zero for the prologue - if (callback) - callback(0, *this, callbackUserData); +DWARFDebugLine::State::State(Prologue::shared_ptr &p, Log *l, + DWARFDebugLine::State::Callback cb, void *userData) + : Row(p->default_is_stmt), prologue(p), log(l), callback(cb), + callbackUserData(userData), row(StartParsingLineTable) { + // Call the callback with the initial row state of zero for the prologue + if (callback) + callback(0, *this, callbackUserData); } //---------------------------------------------------------------------- // DWARFDebugLine::State::Reset //---------------------------------------------------------------------- -void -DWARFDebugLine::State::Reset() -{ - Row::Reset(prologue->default_is_stmt); -} +void DWARFDebugLine::State::Reset() { Row::Reset(prologue->default_is_stmt); } //---------------------------------------------------------------------- // DWARFDebugLine::State::AppendRowToMatrix //---------------------------------------------------------------------- -void -DWARFDebugLine::State::AppendRowToMatrix(dw_offset_t offset) -{ - // Each time we are to add an entry into the line table matrix - // call the callback function so that someone can do something with - // the current state of the state machine (like build a line table - // or dump the line table!) - if (log) - { - if (row == 0) - { - log->PutCString ("Address Line Column File ISA Flags"); - log->PutCString ("------------------ ------ ------ ------ --- -------------"); - } - Dump (log); +void DWARFDebugLine::State::AppendRowToMatrix(dw_offset_t offset) { + // Each time we are to add an entry into the line table matrix + // call the callback function so that someone can do something with + // the current state of the state machine (like build a line table + // or dump the line table!) + if (log) { + if (row == 0) { + log->PutCString("Address Line Column File ISA Flags"); + log->PutCString( + "------------------ ------ ------ ------ --- -------------"); } + Dump(log); + } - ++row; // Increase the row number before we call our callback for a real row - if (callback) - callback(offset, *this, callbackUserData); - PostAppend(); + ++row; // Increase the row number before we call our callback for a real row + if (callback) + callback(offset, *this, callbackUserData); + PostAppend(); } //---------------------------------------------------------------------- // DWARFDebugLine::State::Finalize //---------------------------------------------------------------------- -void -DWARFDebugLine::State::Finalize(dw_offset_t offset) -{ - // Call the callback with a special row state when we are done parsing a - // line table - row = DoneParsingLineTable; - if (callback) - callback(offset, *this, callbackUserData); +void DWARFDebugLine::State::Finalize(dw_offset_t offset) { + // Call the callback with a special row state when we are done parsing a + // line table + row = DoneParsingLineTable; + if (callback) + callback(offset, *this, callbackUserData); } -//void -//DWARFDebugLine::AppendLineTableData +// void +// DWARFDebugLine::AppendLineTableData //( // const DWARFDebugLine::Prologue* prologue, // const DWARFDebugLine::Row::collection& state_coll, @@ -1240,7 +1118,8 @@ DWARFDebugLine::State::Finalize(dw_offset_t offset) // bool default_is_stmt = prologue->default_is_stmt; // const DWARFDebugLine::Row reset_state(default_is_stmt); // const DWARFDebugLine::Row* prev_state = &reset_state; -// const int32_t max_line_increment_for_special_opcode = prologue->MaxLineIncrementForSpecialOpcode(); +// const int32_t max_line_increment_for_special_opcode = +// prologue->MaxLineIncrementForSpecialOpcode(); // for (pos = state_coll.begin(); pos != end; ++pos) // { // const DWARFDebugLine::Row& curr_state = *pos; @@ -1257,7 +1136,8 @@ DWARFDebugLine::State::Finalize(dw_offset_t offset) // if (prev_state == &reset_state) // { // debug_line_data.Append8(0); // Extended opcode -// debug_line_data.Append32_as_ULEB128(addr_size + 1); // Length of opcode bytes +// debug_line_data.Append32_as_ULEB128(addr_size + 1); // Length of +// opcode bytes // debug_line_data.Append8(DW_LNE_set_address); // debug_line_data.AppendMax64(curr_state.address, addr_size); // addr_advance = 0; @@ -1276,7 +1156,8 @@ DWARFDebugLine::State::Finalize(dw_offset_t offset) // } // // // Don't do anything fancy if we are at the end of a sequence -// // as we don't want to push any extra rows since the DW_LNE_end_sequence +// // as we don't want to push any extra rows since the +// DW_LNE_end_sequence // // will push a row itself! // if (curr_state.end_sequence) // { @@ -1310,26 +1191,38 @@ DWARFDebugLine::State::Finalize(dw_offset_t offset) // line_increment = 0; // } // -// uint32_t special_opcode = (line_increment >= prologue->line_base) ? ((line_increment - prologue->line_base) + (prologue->line_range * addr_advance) + prologue->opcode_base) : 256; +// uint32_t special_opcode = (line_increment >= +// prologue->line_base) ? ((line_increment - +// prologue->line_base) + (prologue->line_range * addr_advance) +// + prologue->opcode_base) : 256; // if (special_opcode > 255) // { -// // Both the address and line won't fit in one special opcode +// // Both the address and line won't fit in one special +// opcode // // check to see if just the line advance will? -// uint32_t special_opcode_line = ((line_increment >= prologue->line_base) && (line_increment != 0)) ? -// ((line_increment - prologue->line_base) + prologue->opcode_base) : 256; +// uint32_t special_opcode_line = ((line_increment >= +// prologue->line_base) && (line_increment != 0)) ? +// ((line_increment - prologue->line_base) + +// prologue->opcode_base) : 256; // // // if (special_opcode_line > 255) // { -// // Nope, the line advance won't fit by itself, check the address increment by itself +// // Nope, the line advance won't fit by itself, check +// the address increment by itself // uint32_t special_opcode_addr = addr_advance ? -// ((0 - prologue->line_base) + (prologue->line_range * addr_advance) + prologue->opcode_base) : 256; +// ((0 - prologue->line_base) + +// (prologue->line_range * addr_advance) + +// prologue->opcode_base) : 256; // // if (special_opcode_addr > 255) // { -// // Neither the address nor the line will fit in a -// // special opcode, we must manually enter both then -// // do a DW_LNS_copy to push a row (special opcode +// // Neither the address nor the line will fit in +// a +// // special opcode, we must manually enter both +// then +// // do a DW_LNS_copy to push a row (special +// opcode // // automatically imply a new row is pushed) // if (line_increment != 0) // { @@ -1349,9 +1242,12 @@ DWARFDebugLine::State::Finalize(dw_offset_t offset) // } // else // { -// // The address increment alone will fit into a special opcode -// // so modify our line change, then issue a special opcode -// // for the address increment and it will push a row into the +// // The address increment alone will fit into a +// special opcode +// // so modify our line change, then issue a +// special opcode +// // for the address increment and it will push a +// row into the // // line table // if (line_increment != 0) // { @@ -1359,16 +1255,21 @@ DWARFDebugLine::State::Finalize(dw_offset_t offset) // debug_line_data.Append32_as_SLEB128(line_increment); // } // -// // Advance of line and address will fit into a single byte special opcode -// // and this will also push a row onto the line table +// // Advance of line and address will fit into a +// single byte special opcode +// // and this will also push a row onto the line +// table // debug_line_data.Append8(special_opcode_addr); // } // } // else // { -// // The line change alone will fit into a special opcode -// // so modify our address increment first, then issue a -// // special opcode for the line change and it will push +// // The line change alone will fit into a special +// opcode +// // so modify our address increment first, then issue +// a +// // special opcode for the line change and it will +// push // // a row into the line table // if (addr_advance > 0) // { @@ -1376,14 +1277,16 @@ DWARFDebugLine::State::Finalize(dw_offset_t offset) // debug_line_data.Append32_as_ULEB128(addr_advance); // } // -// // Advance of line and address will fit into a single byte special opcode +// // Advance of line and address will fit into a +// single byte special opcode // // and this will also push a row onto the line table // debug_line_data.Append8(special_opcode_line); // } // } // else // { -// // Advance of line and address will fit into a single byte special opcode +// // Advance of line and address will fit into a single +// byte special opcode // // and this will also push a row onto the line table // debug_line_data.Append8(special_opcode); // } diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h index 9f2219b01812..ea02cfed6e01 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h @@ -11,8 +11,8 @@ #define SymbolFileDWARF_DWARFDebugLine_h_ #include <map> -#include <vector> #include <string> +#include <vector> #include "lldb/lldb-private.h" @@ -24,199 +24,219 @@ class SymbolFileDWARF; //---------------------------------------------------------------------- // DWARFDebugLine //---------------------------------------------------------------------- -class DWARFDebugLine -{ +class DWARFDebugLine { public: - //------------------------------------------------------------------ - // FileNameEntry - //------------------------------------------------------------------ - struct FileNameEntry - { - FileNameEntry() : - name(nullptr), - dir_idx(0), - mod_time(0), - length(0) - { - } - - const char* name; - dw_sleb128_t dir_idx; - dw_sleb128_t mod_time; - dw_sleb128_t length; - - }; - - //------------------------------------------------------------------ - // Prologue - //------------------------------------------------------------------ - struct Prologue - { - - Prologue() : - total_length(0), - version(0), - prologue_length(0), - min_inst_length(0), - default_is_stmt(0), - line_base(0), - line_range(0), - opcode_base(0), - standard_opcode_lengths(), - include_directories(), - file_names() - { - } - - typedef std::shared_ptr<Prologue> shared_ptr; - - uint32_t total_length; // The size in bytes of the statement information for this compilation unit (not including the total_length field itself). - uint16_t version; // Version identifier for the statement information format. - 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. - uint8_t min_inst_length;// The size in bytes of the smallest target machine instruction. Statement program opcodes that alter the address register first multiply their operands by this value. - uint8_t maximum_operations_per_instruction; // New in DWARF4. The maximum number of individual operations that may be encoded in an instruction. - uint8_t default_is_stmt;// The initial value of theis_stmtregister. - int8_t line_base; // This parameter affects the meaning of the special opcodes. See below. - uint8_t line_range; // This parameter affects the meaning of the special opcodes. See below. - uint8_t opcode_base; // The number assigned to the first special opcode. - std::vector<uint8_t> standard_opcode_lengths; - std::vector<const char *> include_directories; - std::vector<FileNameEntry> file_names; - - int32_t MaxLineIncrementForSpecialOpcode() const { return line_base + (int8_t)line_range - 1; } - bool IsValid() const; -// void Append(BinaryStreamBuf& buff) const; - void Dump (lldb_private::Log *log); - void Clear() - { - total_length = version = prologue_length = min_inst_length = line_base = line_range = opcode_base = 0; - line_base = 0; - standard_opcode_lengths.clear(); - include_directories.clear(); - file_names.clear(); - } - bool GetFile(uint32_t file_idx, const char *comp_dir, lldb_private::FileSpec &file) const; - - }; - - // Standard .debug_line state machine structure - struct Row - { - typedef std::vector<Row> collection; - typedef collection::iterator iterator; - typedef collection::const_iterator const_iterator; - - Row(bool default_is_stmt = false); - virtual ~Row() {} - void PostAppend (); - void Reset(bool default_is_stmt); - void Dump(lldb_private::Log *log) const; - static void Insert(Row::collection& state_coll, const Row& state); - static void Dump(lldb_private::Log *log, const Row::collection& state_coll); - - dw_addr_t address; // The program-counter value corresponding to a machine instruction generated by the compiler. - uint32_t line; // An unsigned integer indicating a source line number. Lines are numbered beginning at 1. The compiler may emit the value 0 in cases where an instruction cannot be attributed to any source line. - uint16_t column; // An unsigned integer indicating a column number within a source line. Columns are numbered beginning at 1. The value 0 is reserved to indicate that a statement begins at the 'left edge' of the line. - uint16_t file; // An unsigned integer indicating the identity of the source file corresponding to a machine instruction. - uint8_t is_stmt:1, // A boolean indicating that the current instruction is the beginning of a statement. - basic_block:1, // A boolean indicating that the current instruction is the beginning of a basic block. - end_sequence:1, // A boolean indicating that the current address is that of the first byte after the end of a sequence of target machine instructions. - prologue_end:1, // A boolean indicating that the current address is one (of possibly many) where execution should be suspended for an entry breakpoint of a function. - epilogue_begin:1;// A boolean indicating that the current address is one (of possibly many) where execution should be suspended for an exit breakpoint of a function. - uint32_t isa; // An unsigned integer whose value encodes the applicable instruction set architecture for the current instruction. - }; - - - //------------------------------------------------------------------ - // LineTable - //------------------------------------------------------------------ - struct LineTable - { - typedef std::shared_ptr<LineTable> shared_ptr; - - LineTable() : - prologue(), - rows() - { - } - - void AppendRow(const DWARFDebugLine::Row& state); - void Clear() - { - prologue.reset(); - rows.clear(); - } - - uint32_t LookupAddress(dw_addr_t address, dw_addr_t cu_high_pc) const; - void Dump(lldb_private::Log *log) const; - - Prologue::shared_ptr prologue; - Row::collection rows; - }; - - //------------------------------------------------------------------ - // State - //------------------------------------------------------------------ - struct State : public Row - { - typedef void (*Callback)(dw_offset_t offset, const State& state, void* userData); - - // Special row codes used when calling the callback - enum - { - StartParsingLineTable = 0, - DoneParsingLineTable = -1 - }; - - State (Prologue::shared_ptr& prologue_sp, - lldb_private::Log *log, - Callback callback, - void* userData); - - void - AppendRowToMatrix (dw_offset_t offset); - - void - Finalize (dw_offset_t offset); - - void - Reset (); - - Prologue::shared_ptr prologue; - lldb_private::Log *log; - Callback callback; // Callback function that gets called each time an entry is to be added to the matrix - void* callbackUserData; - int row; // The row number that starts at zero for the prologue, and increases for each row added to the matrix - private: - DISALLOW_COPY_AND_ASSIGN (State); - }; - - static bool DumpOpcodes(lldb_private::Log *log, SymbolFileDWARF* dwarf2Data, dw_offset_t line_offset = DW_INVALID_OFFSET, uint32_t dump_flags = 0); // If line_offset is invalid, dump everything - static bool DumpLineTableRows(lldb_private::Log *log, SymbolFileDWARF* dwarf2Data, dw_offset_t line_offset = DW_INVALID_OFFSET); // If line_offset is invalid, dump everything - static bool ParseSupportFiles(const lldb::ModuleSP &module_sp, const lldb_private::DWARFDataExtractor& debug_line_data, const char *cu_comp_dir, dw_offset_t stmt_list, lldb_private::FileSpecList &support_files); - static bool ParsePrologue(const lldb_private::DWARFDataExtractor& debug_line_data, lldb::offset_t* offset_ptr, Prologue* prologue); - static bool ParseStatementTable(const lldb_private::DWARFDataExtractor& debug_line_data, lldb::offset_t* offset_ptr, State::Callback callback, void* userData); - static dw_offset_t DumpStatementTable(lldb_private::Log *log, const lldb_private::DWARFDataExtractor& debug_line_data, const dw_offset_t line_offset); - static dw_offset_t DumpStatementOpcodes(lldb_private::Log *log, const lldb_private::DWARFDataExtractor& debug_line_data, 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); - static void Parse(const lldb_private::DWARFDataExtractor& debug_line_data, DWARFDebugLine::State::Callback callback, void* userData); -// static void AppendLineTableData(const DWARFDebugLine::Prologue* prologue, const DWARFDebugLine::Row::collection& state_coll, const uint32_t addr_size, BinaryStreamBuf &debug_line_data); - - DWARFDebugLine() : - m_lineTableMap() - { + //------------------------------------------------------------------ + // FileNameEntry + //------------------------------------------------------------------ + struct FileNameEntry { + FileNameEntry() : name(nullptr), dir_idx(0), mod_time(0), length(0) {} + + const char *name; + dw_sleb128_t dir_idx; + dw_sleb128_t mod_time; + dw_sleb128_t length; + }; + + //------------------------------------------------------------------ + // Prologue + //------------------------------------------------------------------ + struct Prologue { + + Prologue() + : total_length(0), version(0), prologue_length(0), min_inst_length(0), + default_is_stmt(0), line_base(0), line_range(0), opcode_base(0), + standard_opcode_lengths(), include_directories(), file_names() {} + + typedef std::shared_ptr<Prologue> shared_ptr; + + uint32_t total_length; // The size in bytes of the statement information for + // this compilation unit (not including the + // total_length field itself). + uint16_t + version; // Version identifier for the statement information format. + 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. + uint8_t min_inst_length; // The size in bytes of the smallest target machine + // instruction. Statement program opcodes that + // alter the address register first multiply their + // operands by this value. + uint8_t maximum_operations_per_instruction; // New in DWARF4. The maximum + // number of individual + // operations that may be + // encoded in an instruction. + uint8_t default_is_stmt; // The initial value of theis_stmtregister. + int8_t line_base; // This parameter affects the meaning of the special + // opcodes. See below. + uint8_t line_range; // This parameter affects the meaning of the special + // opcodes. See below. + uint8_t opcode_base; // The number assigned to the first special opcode. + std::vector<uint8_t> standard_opcode_lengths; + std::vector<const char *> include_directories; + std::vector<FileNameEntry> file_names; + + int32_t MaxLineIncrementForSpecialOpcode() const { + return line_base + (int8_t)line_range - 1; + } + bool IsValid() const; + // void Append(BinaryStreamBuf& buff) const; + void Dump(lldb_private::Log *log); + void Clear() { + total_length = version = prologue_length = min_inst_length = line_base = + line_range = opcode_base = 0; + line_base = 0; + standard_opcode_lengths.clear(); + include_directories.clear(); + file_names.clear(); + } + bool GetFile(uint32_t file_idx, const char *comp_dir, + lldb_private::FileSpec &file) const; + }; + + // Standard .debug_line state machine structure + struct Row { + typedef std::vector<Row> collection; + typedef collection::iterator iterator; + typedef collection::const_iterator const_iterator; + + Row(bool default_is_stmt = false); + virtual ~Row() {} + void PostAppend(); + void Reset(bool default_is_stmt); + void Dump(lldb_private::Log *log) const; + static void Insert(Row::collection &state_coll, const Row &state); + static void Dump(lldb_private::Log *log, const Row::collection &state_coll); + + dw_addr_t address; // The program-counter value corresponding to a machine + // instruction generated by the compiler. + uint32_t line; // An unsigned integer indicating a source line number. Lines + // are numbered beginning at 1. The compiler may emit the + // value 0 in cases where an instruction cannot be attributed + // to any source line. + uint16_t column; // An unsigned integer indicating a column number within a + // source line. Columns are numbered beginning at 1. The + // value 0 is reserved to indicate that a statement begins + // at the 'left edge' of the line. + uint16_t file; // An unsigned integer indicating the identity of the source + // file corresponding to a machine instruction. + uint8_t is_stmt : 1, // A boolean indicating that the current instruction is + // the beginning of a statement. + basic_block : 1, // A boolean indicating that the current instruction is + // the beginning of a basic block. + end_sequence : 1, // A boolean indicating that the current address is + // that of the first byte after the end of a sequence + // of target machine instructions. + prologue_end : 1, // A boolean indicating that the current address is + // one (of possibly many) where execution should be + // suspended for an entry breakpoint of a function. + epilogue_begin : 1; // A boolean indicating that the current address is + // one (of possibly many) where execution should be + // suspended for an exit breakpoint of a function. + uint32_t isa; // An unsigned integer whose value encodes the applicable + // instruction set architecture for the current instruction. + }; + + //------------------------------------------------------------------ + // LineTable + //------------------------------------------------------------------ + struct LineTable { + typedef std::shared_ptr<LineTable> shared_ptr; + + LineTable() : prologue(), rows() {} + + void AppendRow(const DWARFDebugLine::Row &state); + void Clear() { + prologue.reset(); + rows.clear(); } - void Parse(const lldb_private::DWARFDataExtractor& debug_line_data); - void ParseIfNeeded(const lldb_private::DWARFDataExtractor& debug_line_data); - LineTable::shared_ptr GetLineTable(const dw_offset_t offset) const; + uint32_t LookupAddress(dw_addr_t address, dw_addr_t cu_high_pc) const; + void Dump(lldb_private::Log *log) const; + + Prologue::shared_ptr prologue; + Row::collection rows; + }; + + //------------------------------------------------------------------ + // State + //------------------------------------------------------------------ + struct State : public Row { + typedef void (*Callback)(dw_offset_t offset, const State &state, + void *userData); + + // Special row codes used when calling the callback + enum { StartParsingLineTable = 0, DoneParsingLineTable = -1 }; + + State(Prologue::shared_ptr &prologue_sp, lldb_private::Log *log, + Callback callback, void *userData); + + void AppendRowToMatrix(dw_offset_t offset); + + void Finalize(dw_offset_t offset); + + void Reset(); + + Prologue::shared_ptr prologue; + lldb_private::Log *log; + Callback callback; // Callback function that gets called each time an entry + // is to be added to the matrix + void *callbackUserData; + int row; // The row number that starts at zero for the prologue, and + // increases for each row added to the matrix + private: + DISALLOW_COPY_AND_ASSIGN(State); + }; + + static bool DumpOpcodes( + lldb_private::Log *log, SymbolFileDWARF *dwarf2Data, + dw_offset_t line_offset = DW_INVALID_OFFSET, + uint32_t dump_flags = 0); // If line_offset is invalid, dump everything + static bool DumpLineTableRows( + lldb_private::Log *log, SymbolFileDWARF *dwarf2Data, + dw_offset_t line_offset = + DW_INVALID_OFFSET); // If line_offset is invalid, dump everything + static bool + ParseSupportFiles(const lldb::ModuleSP &module_sp, + const lldb_private::DWARFDataExtractor &debug_line_data, + const char *cu_comp_dir, dw_offset_t stmt_list, + lldb_private::FileSpecList &support_files); + static bool + ParsePrologue(const lldb_private::DWARFDataExtractor &debug_line_data, + lldb::offset_t *offset_ptr, Prologue *prologue); + static bool + ParseStatementTable(const lldb_private::DWARFDataExtractor &debug_line_data, + lldb::offset_t *offset_ptr, State::Callback callback, + void *userData); + static dw_offset_t + DumpStatementTable(lldb_private::Log *log, + const lldb_private::DWARFDataExtractor &debug_line_data, + const dw_offset_t line_offset); + static dw_offset_t + DumpStatementOpcodes(lldb_private::Log *log, + const lldb_private::DWARFDataExtractor &debug_line_data, + 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); + static void Parse(const lldb_private::DWARFDataExtractor &debug_line_data, + DWARFDebugLine::State::Callback callback, void *userData); + // static void AppendLineTableData(const DWARFDebugLine::Prologue* prologue, + // const DWARFDebugLine::Row::collection& state_coll, const uint32_t + // addr_size, BinaryStreamBuf &debug_line_data); + + DWARFDebugLine() : m_lineTableMap() {} + + void Parse(const lldb_private::DWARFDataExtractor &debug_line_data); + void ParseIfNeeded(const lldb_private::DWARFDataExtractor &debug_line_data); + LineTable::shared_ptr GetLineTable(const dw_offset_t offset) const; protected: - typedef std::map<dw_offset_t, LineTable::shared_ptr> LineTableMap; - typedef LineTableMap::iterator LineTableIter; - typedef LineTableMap::const_iterator LineTableConstIter; + typedef std::map<dw_offset_t, LineTable::shared_ptr> LineTableMap; + typedef LineTableMap::iterator LineTableIter; + typedef LineTableMap::const_iterator LineTableConstIter; - LineTableMap m_lineTableMap; + LineTableMap m_lineTableMap; }; -#endif // SymbolFileDWARF_DWARFDebugLine_h_ +#endif // SymbolFileDWARF_DWARFDebugLine_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.cpp index 0e2aaa47e8c9..d56463039a19 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.cpp @@ -17,32 +17,23 @@ using namespace lldb_private; using namespace std; -DWARFDebugMacinfo::DWARFDebugMacinfo() -{ -} +DWARFDebugMacinfo::DWARFDebugMacinfo() {} -DWARFDebugMacinfo::~DWARFDebugMacinfo() -{ -} +DWARFDebugMacinfo::~DWARFDebugMacinfo() {} -void -DWARFDebugMacinfo::Dump(Stream *s, const DWARFDataExtractor& macinfo_data, lldb::offset_t offset) -{ - DWARFDebugMacinfoEntry maninfo_entry; - if (macinfo_data.GetByteSize() == 0) - { - s->PutCString("< EMPTY >\n"); - return; - } - if (offset == LLDB_INVALID_OFFSET) - { - offset = 0; - while (maninfo_entry.Extract(macinfo_data, &offset)) - maninfo_entry.Dump(s); - } - else - { - if (maninfo_entry.Extract(macinfo_data, &offset)) - maninfo_entry.Dump(s); - } +void DWARFDebugMacinfo::Dump(Stream *s, const DWARFDataExtractor &macinfo_data, + lldb::offset_t offset) { + DWARFDebugMacinfoEntry maninfo_entry; + if (macinfo_data.GetByteSize() == 0) { + s->PutCString("< EMPTY >\n"); + return; + } + if (offset == LLDB_INVALID_OFFSET) { + offset = 0; + while (maninfo_entry.Extract(macinfo_data, &offset)) + maninfo_entry.Dump(s); + } else { + if (maninfo_entry.Extract(macinfo_data, &offset)) + maninfo_entry.Dump(s); + } } diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h index 077718cf7db2..ec9dc85669c4 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h @@ -12,18 +12,15 @@ #include "SymbolFileDWARF.h" -class DWARFDebugMacinfo -{ +class DWARFDebugMacinfo { public: - DWARFDebugMacinfo(); + DWARFDebugMacinfo(); - ~DWARFDebugMacinfo(); + ~DWARFDebugMacinfo(); - static void - Dump (lldb_private::Stream *s, - const lldb_private::DWARFDataExtractor& macinfo_data, - lldb::offset_t offset = LLDB_INVALID_OFFSET); + static void Dump(lldb_private::Stream *s, + const lldb_private::DWARFDataExtractor &macinfo_data, + lldb::offset_t offset = LLDB_INVALID_OFFSET); }; - -#endif // SymbolFileDWARF_DWARFDebugMacinfo_h_ +#endif // SymbolFileDWARF_DWARFDebugMacinfo_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.cpp index 4a176bb8aad4..45498590236f 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.cpp @@ -14,119 +14,98 @@ using namespace lldb_private; using namespace std; -DWARFDebugMacinfoEntry::DWARFDebugMacinfoEntry() : - m_type_code(0), - m_line(0), - m_op2() -{ - m_op2.cstr = NULL; +DWARFDebugMacinfoEntry::DWARFDebugMacinfoEntry() + : m_type_code(0), m_line(0), m_op2() { + m_op2.cstr = NULL; } -DWARFDebugMacinfoEntry::~DWARFDebugMacinfoEntry() -{ +DWARFDebugMacinfoEntry::~DWARFDebugMacinfoEntry() {} + +const char *DWARFDebugMacinfoEntry::GetCString() const { + switch (m_type_code) { + case 0: + case DW_MACINFO_start_file: + case DW_MACINFO_end_file: + return NULL; + default: + break; + } + return m_op2.cstr; } -const char* -DWARFDebugMacinfoEntry::GetCString() const -{ - switch (m_type_code) - { - case 0: - case DW_MACINFO_start_file: - case DW_MACINFO_end_file: - return NULL; - default: - break; - } - return m_op2.cstr; -} +void DWARFDebugMacinfoEntry::Dump(Stream *s) const { + if (m_type_code) { + s->PutCString(DW_MACINFO_value_to_name(m_type_code)); + switch (m_type_code) { + case DW_MACINFO_define: + s->Printf(" line:%u #define %s\n", (uint32_t)m_line, m_op2.cstr); + break; + case DW_MACINFO_undef: + s->Printf(" line:%u #undef %s\n", (uint32_t)m_line, m_op2.cstr); + break; -void -DWARFDebugMacinfoEntry::Dump(Stream *s) const -{ - if (m_type_code) - { - s->PutCString(DW_MACINFO_value_to_name(m_type_code)); - - switch (m_type_code) - { - case DW_MACINFO_define: - s->Printf(" line:%u #define %s\n", (uint32_t)m_line, m_op2.cstr); - break; - - case DW_MACINFO_undef: - s->Printf(" line:%u #undef %s\n", (uint32_t)m_line, m_op2.cstr); - break; - - default: - s->Printf(" line:%u str: '%s'\n", (uint32_t)m_line, m_op2.cstr); - break; + default: + s->Printf(" line:%u str: '%s'\n", (uint32_t)m_line, m_op2.cstr); + break; - case DW_MACINFO_start_file: - s->Printf(" line:%u file index: '%u'\n", (uint32_t)m_line, (uint32_t)m_op2.file_idx); - break; + case DW_MACINFO_start_file: + s->Printf(" line:%u file index: '%u'\n", (uint32_t)m_line, + (uint32_t)m_op2.file_idx); + break; - case DW_MACINFO_end_file: - break; - } - } - else - { - s->PutCString(" END\n"); + case DW_MACINFO_end_file: + break; } + } else { + s->PutCString(" END\n"); + } } +bool DWARFDebugMacinfoEntry::Extract(const DWARFDataExtractor &mac_info_data, + lldb::offset_t *offset_ptr) { + if (mac_info_data.ValidOffset(*offset_ptr)) { + m_type_code = mac_info_data.GetU8(offset_ptr); + + switch (m_type_code) { + + case DW_MACINFO_define: + case DW_MACINFO_undef: + // 2 operands: + // Arg 1: operand encodes the line number of the source line on which + // the relevant defining or undefining pre-processor directives + // appeared. + m_line = mac_info_data.GetULEB128(offset_ptr); + // Arg 2: define string + m_op2.cstr = mac_info_data.GetCStr(offset_ptr); + break; -bool -DWARFDebugMacinfoEntry::Extract(const DWARFDataExtractor& mac_info_data, lldb::offset_t* offset_ptr) -{ - if (mac_info_data.ValidOffset(*offset_ptr)) - { - m_type_code = mac_info_data.GetU8(offset_ptr); - - switch (m_type_code) - { - - case DW_MACINFO_define: - case DW_MACINFO_undef: - // 2 operands: - // Arg 1: operand encodes the line number of the source line on which - // the relevant defining or undefining pre-processor directives - // appeared. - m_line = mac_info_data.GetULEB128(offset_ptr); - // Arg 2: define string - m_op2.cstr = mac_info_data.GetCStr(offset_ptr); - break; - - case DW_MACINFO_start_file: - // 2 operands: - // Op 1: line number of the source line on which the inclusion - // pre-processor directive occurred. - m_line = mac_info_data.GetULEB128(offset_ptr); - // Op 2: a source file name index to a file number in the statement - // information table for the relevant compilation unit. - m_op2.file_idx = mac_info_data.GetULEB128(offset_ptr); - break; - - case 0: // End of list - case DW_MACINFO_end_file: - // No operands - m_line = DW_INVALID_OFFSET; - m_op2.cstr = NULL; - break; - default: - // Vendor specific entries always have a ULEB128 and a string - m_line = mac_info_data.GetULEB128(offset_ptr); - m_op2.cstr = mac_info_data.GetCStr(offset_ptr); - break; - } - return true; + case DW_MACINFO_start_file: + // 2 operands: + // Op 1: line number of the source line on which the inclusion + // pre-processor directive occurred. + m_line = mac_info_data.GetULEB128(offset_ptr); + // Op 2: a source file name index to a file number in the statement + // information table for the relevant compilation unit. + m_op2.file_idx = mac_info_data.GetULEB128(offset_ptr); + break; + + case 0: // End of list + case DW_MACINFO_end_file: + // No operands + m_line = DW_INVALID_OFFSET; + m_op2.cstr = NULL; + break; + default: + // Vendor specific entries always have a ULEB128 and a string + m_line = mac_info_data.GetULEB128(offset_ptr); + m_op2.cstr = mac_info_data.GetCStr(offset_ptr); + break; } - else - m_type_code = 0; + return true; + } else + m_type_code = 0; - return false; + return false; } - diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h index 72318d86e1ca..96829c2fc09b 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h @@ -12,46 +12,31 @@ #include "SymbolFileDWARF.h" -class DWARFDebugMacinfoEntry -{ +class DWARFDebugMacinfoEntry { public: - DWARFDebugMacinfoEntry(); + DWARFDebugMacinfoEntry(); - ~DWARFDebugMacinfoEntry(); + ~DWARFDebugMacinfoEntry(); - uint8_t - TypeCode() const - { - return m_type_code; - } + uint8_t TypeCode() const { return m_type_code; } - uint8_t - GetLineNumber() const - { - return m_line; - } + uint8_t GetLineNumber() const { return m_line; } - void - Dump(lldb_private::Stream *s) const; + void Dump(lldb_private::Stream *s) const; - const char* - GetCString() const; + const char *GetCString() const; - bool - Extract(const lldb_private::DWARFDataExtractor& mac_info_data, - lldb::offset_t* offset_ptr); + bool Extract(const lldb_private::DWARFDataExtractor &mac_info_data, + lldb::offset_t *offset_ptr); protected: - private: - uint8_t m_type_code; - dw_uleb128_t m_line; - union - { - dw_uleb128_t file_idx; - const char* cstr; - } m_op2; + uint8_t m_type_code; + dw_uleb128_t m_line; + union { + dw_uleb128_t file_idx; + const char *cstr; + } m_op2; }; - -#endif // SymbolFileDWARF_DWARFDebugMacinfoEntry_h_ +#endif // SymbolFileDWARF_DWARFDebugMacinfoEntry_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp index 75c812e6e79d..1c31d1c42598 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp @@ -17,112 +17,111 @@ using namespace lldb_private; DWARFDebugMacroHeader -DWARFDebugMacroHeader::ParseHeader(const DWARFDataExtractor &debug_macro_data, lldb::offset_t *offset) -{ - DWARFDebugMacroHeader header; +DWARFDebugMacroHeader::ParseHeader(const DWARFDataExtractor &debug_macro_data, + lldb::offset_t *offset) { + DWARFDebugMacroHeader header; - // Skip over the version field in header. - header.m_version = debug_macro_data.GetU16(offset); + // Skip over the version field in header. + 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; + uint8_t flags = debug_macro_data.GetU8(offset); + header.m_offset_is_64_bit = flags & OFFSET_SIZE_MASK ? true : false; - if (flags & DEBUG_LINE_OFFSET_MASK) - { - if (header.m_offset_is_64_bit) - header.m_debug_line_offset = debug_macro_data.GetU64(offset); - else - header.m_debug_line_offset = debug_macro_data.GetU32(offset); - } + if (flags & DEBUG_LINE_OFFSET_MASK) { + if (header.m_offset_is_64_bit) + header.m_debug_line_offset = debug_macro_data.GetU64(offset); + else + header.m_debug_line_offset = debug_macro_data.GetU32(offset); + } - // Skip over the operands table if it is present. - if (flags & OPCODE_OPERANDS_TABLE_MASK) - SkipOperandTable(debug_macro_data, offset); + // Skip over the operands table if it is present. + if (flags & OPCODE_OPERANDS_TABLE_MASK) + SkipOperandTable(debug_macro_data, offset); - return header; + return header; } -void -DWARFDebugMacroHeader::SkipOperandTable(const DWARFDataExtractor &debug_macro_data, lldb::offset_t *offset) -{ - uint8_t entry_count = debug_macro_data.GetU8(offset); - for (uint8_t i = 0; i < entry_count; i++) - { - // Skip over the opcode number. - debug_macro_data.GetU8(offset); +void DWARFDebugMacroHeader::SkipOperandTable( + const DWARFDataExtractor &debug_macro_data, lldb::offset_t *offset) { + uint8_t entry_count = debug_macro_data.GetU8(offset); + for (uint8_t i = 0; i < entry_count; i++) { + // Skip over the opcode number. + debug_macro_data.GetU8(offset); - uint64_t operand_count = debug_macro_data.GetULEB128(offset); + uint64_t operand_count = debug_macro_data.GetULEB128(offset); - for (uint64_t j = 0; j < operand_count; j++) - { - // Skip over the operand form - debug_macro_data.GetU8(offset); - } + for (uint64_t j = 0; j < operand_count; j++) { + // Skip over the operand form + debug_macro_data.GetU8(offset); } + } } -void -DWARFDebugMacroEntry::ReadMacroEntries(const DWARFDataExtractor &debug_macro_data, - const DWARFDataExtractor &debug_str_data, - const bool offset_is_64_bit, - lldb::offset_t *offset, - SymbolFileDWARF *sym_file_dwarf, - DebugMacrosSP &debug_macros_sp) -{ - llvm::dwarf::MacroEntryType type = static_cast<llvm::dwarf::MacroEntryType>(debug_macro_data.GetU8(offset)); - while (type != 0) - { - lldb::offset_t new_offset = 0, str_offset = 0; - uint32_t line = 0; - const char *macro_str = nullptr; - uint32_t debug_line_file_idx = 0; +void DWARFDebugMacroEntry::ReadMacroEntries( + const DWARFDataExtractor &debug_macro_data, + const DWARFDataExtractor &debug_str_data, const bool offset_is_64_bit, + lldb::offset_t *offset, SymbolFileDWARF *sym_file_dwarf, + DebugMacrosSP &debug_macros_sp) { + llvm::dwarf::MacroEntryType type = + static_cast<llvm::dwarf::MacroEntryType>(debug_macro_data.GetU8(offset)); + while (type != 0) { + lldb::offset_t new_offset = 0, str_offset = 0; + uint32_t line = 0; + const char *macro_str = nullptr; + uint32_t debug_line_file_idx = 0; - switch (type) - { - case DW_MACRO_define: - case DW_MACRO_undef: - line = debug_macro_data.GetULEB128(offset); - macro_str = debug_macro_data.GetCStr(offset); - if (type == DW_MACRO_define) - debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateDefineEntry(line, macro_str)); - else - debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateUndefEntry(line, macro_str)); - break; - case DW_MACRO_define_indirect: - case DW_MACRO_undef_indirect: - line = debug_macro_data.GetULEB128(offset); - if (offset_is_64_bit) - str_offset = debug_macro_data.GetU64(offset); - else - str_offset = debug_macro_data.GetU32(offset); - macro_str = debug_str_data.GetCStr(&str_offset); - if (type == DW_MACRO_define_indirect) - debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateDefineEntry(line, macro_str)); - else - debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateUndefEntry(line, macro_str)); - break; - case DW_MACRO_start_file: - line = debug_macro_data.GetULEB128(offset); - debug_line_file_idx = debug_macro_data.GetULEB128(offset); - debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateStartFileEntry(line, debug_line_file_idx)); - break; - case DW_MACRO_end_file: - // This operation has no operands. - debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateEndFileEntry()); - break; - case DW_MACRO_transparent_include: - if (offset_is_64_bit) - new_offset = debug_macro_data.GetU64(offset); - else - new_offset = debug_macro_data.GetU32(offset); - debug_macros_sp->AddMacroEntry( - DebugMacroEntry::CreateIndirectEntry(sym_file_dwarf->ParseDebugMacros(&new_offset))); - break; - default: - // TODO: Add support for other standard operations. - // TODO: Provide mechanism to hook handling of non-standard/extension operands. - return; - } - type = static_cast<llvm::dwarf::MacroEntryType>(debug_macro_data.GetU8(offset)); + switch (type) { + case DW_MACRO_define: + case DW_MACRO_undef: + line = debug_macro_data.GetULEB128(offset); + macro_str = debug_macro_data.GetCStr(offset); + if (type == DW_MACRO_define) + debug_macros_sp->AddMacroEntry( + DebugMacroEntry::CreateDefineEntry(line, macro_str)); + else + debug_macros_sp->AddMacroEntry( + DebugMacroEntry::CreateUndefEntry(line, macro_str)); + break; + case DW_MACRO_define_strp: + case DW_MACRO_undef_strp: + line = debug_macro_data.GetULEB128(offset); + if (offset_is_64_bit) + str_offset = debug_macro_data.GetU64(offset); + else + str_offset = debug_macro_data.GetU32(offset); + macro_str = debug_str_data.GetCStr(&str_offset); + if (type == DW_MACRO_define_strp) + debug_macros_sp->AddMacroEntry( + DebugMacroEntry::CreateDefineEntry(line, macro_str)); + else + debug_macros_sp->AddMacroEntry( + DebugMacroEntry::CreateUndefEntry(line, macro_str)); + break; + case DW_MACRO_start_file: + line = debug_macro_data.GetULEB128(offset); + debug_line_file_idx = debug_macro_data.GetULEB128(offset); + debug_macros_sp->AddMacroEntry( + DebugMacroEntry::CreateStartFileEntry(line, debug_line_file_idx)); + break; + case DW_MACRO_end_file: + // This operation has no operands. + debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateEndFileEntry()); + break; + case DW_MACRO_import: + if (offset_is_64_bit) + new_offset = debug_macro_data.GetU64(offset); + else + new_offset = debug_macro_data.GetU32(offset); + debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateIndirectEntry( + sym_file_dwarf->ParseDebugMacros(&new_offset))); + break; + default: + // TODO: Add support for other standard operations. + // TODO: Provide mechanism to hook handling of non-standard/extension + // operands. + return; } + type = static_cast<llvm::dwarf::MacroEntryType>( + debug_macro_data.GetU8(offset)); + } } diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h index c60b9749b005..021b434cd457 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h @@ -1,4 +1,5 @@ -//===-- DWARFDebugMacro.h ----------------------------------------*- C++ -*-===// +//===-- DWARFDebugMacro.h ----------------------------------------*- C++ +//-*-===// // // The LLVM Compiler Infrastructure // @@ -12,12 +13,11 @@ #include <map> -#include "lldb/lldb-types.h" #include "lldb/Core/dwarf.h" #include "lldb/Symbol/DebugMacros.h" +#include "lldb/lldb-types.h" -namespace lldb_private -{ +namespace lldb_private { class DWARFDataExtractor; @@ -25,44 +25,38 @@ class DWARFDataExtractor; class SymbolFileDWARF; -class DWARFDebugMacroHeader -{ +class DWARFDebugMacroHeader { public: - enum HeaderFlagMask - { - OFFSET_SIZE_MASK = 0x1, - DEBUG_LINE_OFFSET_MASK = 0x2, - OPCODE_OPERANDS_TABLE_MASK = 0x4 - }; + enum HeaderFlagMask { + OFFSET_SIZE_MASK = 0x1, + DEBUG_LINE_OFFSET_MASK = 0x2, + OPCODE_OPERANDS_TABLE_MASK = 0x4 + }; - static DWARFDebugMacroHeader - ParseHeader(const lldb_private::DWARFDataExtractor &debug_macro_data, lldb::offset_t *offset); + static DWARFDebugMacroHeader + ParseHeader(const lldb_private::DWARFDataExtractor &debug_macro_data, + lldb::offset_t *offset); - bool - OffsetIs64Bit() const - { - return m_offset_is_64_bit; - } + bool OffsetIs64Bit() const { return m_offset_is_64_bit; } private: - static void - SkipOperandTable(const lldb_private::DWARFDataExtractor &debug_macro_data, lldb::offset_t *offset); + static void + SkipOperandTable(const lldb_private::DWARFDataExtractor &debug_macro_data, + lldb::offset_t *offset); - uint16_t m_version; - bool m_offset_is_64_bit; - uint64_t m_debug_line_offset; + uint16_t m_version; + bool m_offset_is_64_bit; + uint64_t m_debug_line_offset; }; -class DWARFDebugMacroEntry -{ +class DWARFDebugMacroEntry { public: - static void - ReadMacroEntries(const lldb_private::DWARFDataExtractor &debug_macro_data, - const lldb_private::DWARFDataExtractor &debug_str_data, - const bool offset_is_64_bit, - lldb::offset_t *sect_offset, - SymbolFileDWARF *sym_file_dwarf, - lldb_private::DebugMacrosSP &debug_macros_sp); + static void + ReadMacroEntries(const lldb_private::DWARFDataExtractor &debug_macro_data, + const lldb_private::DWARFDataExtractor &debug_str_data, + const bool offset_is_64_bit, lldb::offset_t *sect_offset, + SymbolFileDWARF *sym_file_dwarf, + lldb_private::DebugMacrosSP &debug_macros_sp); }; #endif // SymbolFileDWARF_DWARFDebugMacro_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp index 547bd0cd1a5a..d4281bac79a1 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp @@ -12,268 +12,242 @@ #include "lldb/Core/Stream.h" #include "lldb/Core/Timer.h" -#include "DWARFDebugInfo.h" +#include "DWARFCompileUnit.h" #include "DWARFDIECollection.h" +#include "DWARFDebugInfo.h" #include "DWARFFormValue.h" -#include "DWARFCompileUnit.h" #include "LogChannelDWARF.h" #include "SymbolFileDWARF.h" - using namespace lldb; using namespace lldb_private; -DWARFDebugPubnames::DWARFDebugPubnames() : - m_sets() -{ -} - -bool -DWARFDebugPubnames::Extract(const DWARFDataExtractor& data) -{ - Timer scoped_timer (__PRETTY_FUNCTION__, - "DWARFDebugPubnames::Extract (byte_size = %" PRIu64 ")", - (uint64_t)data.GetByteSize()); - Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_PUBNAMES)); - if (log) - log->Printf("DWARFDebugPubnames::Extract (byte_size = %" PRIu64 ")", (uint64_t)data.GetByteSize()); - - if (data.ValidOffset(0)) - { - lldb::offset_t offset = 0; - - DWARFDebugPubnamesSet set; - while (data.ValidOffset(offset)) - { - if (set.Extract(data, &offset)) - { - m_sets.push_back(set); - offset = set.GetOffsetOfNextEntry(); - } - else - break; - } - if (log) - Dump (log); - return true; +DWARFDebugPubnames::DWARFDebugPubnames() : m_sets() {} + +bool DWARFDebugPubnames::Extract(const DWARFDataExtractor &data) { + Timer scoped_timer(LLVM_PRETTY_FUNCTION, + "DWARFDebugPubnames::Extract (byte_size = %" PRIu64 ")", + (uint64_t)data.GetByteSize()); + Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_PUBNAMES)); + if (log) + log->Printf("DWARFDebugPubnames::Extract (byte_size = %" PRIu64 ")", + (uint64_t)data.GetByteSize()); + + if (data.ValidOffset(0)) { + lldb::offset_t offset = 0; + + DWARFDebugPubnamesSet set; + while (data.ValidOffset(offset)) { + if (set.Extract(data, &offset)) { + m_sets.push_back(set); + offset = set.GetOffsetOfNextEntry(); + } else + break; } - return false; -} - - -bool -DWARFDebugPubnames::GeneratePubnames(SymbolFileDWARF* dwarf2Data) -{ - Timer scoped_timer (__PRETTY_FUNCTION__, - "DWARFDebugPubnames::GeneratePubnames (data = %p)", - static_cast<void*>(dwarf2Data)); - - Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_PUBNAMES)); if (log) - log->Printf("DWARFDebugPubnames::GeneratePubnames (data = %p)", - static_cast<void*>(dwarf2Data)); - - m_sets.clear(); - DWARFDebugInfo* debug_info = dwarf2Data->DebugInfo(); - if (debug_info) - { - uint32_t cu_idx = 0; - const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits(); - for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) - { - - DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx); - - DWARFFormValue::FixedFormSizes fixed_form_sizes = - DWARFFormValue::GetFixedFormSizesForAddressSize (cu->GetAddressByteSize(), - cu->IsDWARF64()); - - bool clear_dies = cu->ExtractDIEsIfNeeded (false) > 1; - - DWARFDIECollection dies; - const size_t die_count = cu->AppendDIEsWithTag (DW_TAG_subprogram, dies) + - cu->AppendDIEsWithTag (DW_TAG_variable, dies); - - dw_offset_t cu_offset = cu->GetOffset(); - DWARFDebugPubnamesSet pubnames_set(DW_INVALID_OFFSET, cu_offset, cu->GetNextCompileUnitOffset() - cu_offset); - - size_t die_idx; - for (die_idx = 0; die_idx < die_count; ++die_idx) - { - DWARFDIE die = dies.GetDIEAtIndex(die_idx); - DWARFAttributes attributes; - const char *name = NULL; - const char *mangled = NULL; - bool add_die = false; - const size_t num_attributes = die.GetDIE()->GetAttributes(die.GetCU(), fixed_form_sizes, attributes); - if (num_attributes > 0) - { - uint32_t i; - - dw_tag_t tag = die.Tag(); - - for (i=0; i<num_attributes; ++i) - { - dw_attr_t attr = attributes.AttributeAtIndex(i); - DWARFFormValue form_value; - switch (attr) - { - case DW_AT_name: - if (attributes.ExtractFormValueAtIndex(i, form_value)) - name = form_value.AsCString(); - break; - - case DW_AT_MIPS_linkage_name: - case DW_AT_linkage_name: - if (attributes.ExtractFormValueAtIndex(i, form_value)) - mangled = form_value.AsCString(); - break; - - case DW_AT_low_pc: - case DW_AT_ranges: - case DW_AT_entry_pc: - if (tag == DW_TAG_subprogram) - add_die = true; - break; - - case DW_AT_location: - if (tag == DW_TAG_variable) - { - DWARFDIE parent_die = die.GetParent(); - while ( parent_die ) - { - switch (parent_die.Tag()) - { - case DW_TAG_subprogram: - case DW_TAG_lexical_block: - case DW_TAG_inlined_subroutine: - // Even if this is a function level static, we don't add it. We could theoretically - // add these if we wanted to by introspecting into the DW_AT_location and seeing - // if the location describes a hard coded address, but we don't want the performance - // penalty of that right now. - add_die = false; - parent_die.Clear(); // Terminate the while loop. - break; - - case DW_TAG_compile_unit: - add_die = true; - parent_die.Clear(); // Terminate the while loop. - break; - - default: - parent_die = parent_die.GetParent(); // Keep going in the while loop. - break; - } - } - } - break; - } - } - } + Dump(log); + return true; + } + return false; +} - if (add_die && (name || mangled)) - { - pubnames_set.AddDescriptor(die.GetCompileUnitRelativeOffset(), mangled ? mangled : name); +bool DWARFDebugPubnames::GeneratePubnames(SymbolFileDWARF *dwarf2Data) { + Timer scoped_timer(LLVM_PRETTY_FUNCTION, + "DWARFDebugPubnames::GeneratePubnames (data = %p)", + static_cast<void *>(dwarf2Data)); + + Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_PUBNAMES)); + if (log) + log->Printf("DWARFDebugPubnames::GeneratePubnames (data = %p)", + static_cast<void *>(dwarf2Data)); + + m_sets.clear(); + DWARFDebugInfo *debug_info = dwarf2Data->DebugInfo(); + if (debug_info) { + uint32_t cu_idx = 0; + const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits(); + for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) { + + DWARFCompileUnit *cu = debug_info->GetCompileUnitAtIndex(cu_idx); + + DWARFFormValue::FixedFormSizes fixed_form_sizes = + DWARFFormValue::GetFixedFormSizesForAddressSize( + cu->GetAddressByteSize(), cu->IsDWARF64()); + + bool clear_dies = cu->ExtractDIEsIfNeeded(false) > 1; + + DWARFDIECollection dies; + const size_t die_count = cu->AppendDIEsWithTag(DW_TAG_subprogram, dies) + + cu->AppendDIEsWithTag(DW_TAG_variable, dies); + + dw_offset_t cu_offset = cu->GetOffset(); + DWARFDebugPubnamesSet pubnames_set(DW_INVALID_OFFSET, cu_offset, + cu->GetNextCompileUnitOffset() - + cu_offset); + + size_t die_idx; + for (die_idx = 0; die_idx < die_count; ++die_idx) { + DWARFDIE die = dies.GetDIEAtIndex(die_idx); + DWARFAttributes attributes; + const char *name = NULL; + const char *mangled = NULL; + bool add_die = false; + const size_t num_attributes = die.GetDIE()->GetAttributes( + die.GetCU(), fixed_form_sizes, attributes); + if (num_attributes > 0) { + uint32_t i; + + dw_tag_t tag = die.Tag(); + + for (i = 0; i < num_attributes; ++i) { + dw_attr_t attr = attributes.AttributeAtIndex(i); + DWARFFormValue form_value; + switch (attr) { + case DW_AT_name: + if (attributes.ExtractFormValueAtIndex(i, form_value)) + name = form_value.AsCString(); + break; + + case DW_AT_MIPS_linkage_name: + case DW_AT_linkage_name: + if (attributes.ExtractFormValueAtIndex(i, form_value)) + mangled = form_value.AsCString(); + break; + + case DW_AT_low_pc: + case DW_AT_ranges: + case DW_AT_entry_pc: + if (tag == DW_TAG_subprogram) + add_die = true; + break; + + case DW_AT_location: + if (tag == DW_TAG_variable) { + DWARFDIE parent_die = die.GetParent(); + while (parent_die) { + switch (parent_die.Tag()) { + case DW_TAG_subprogram: + case DW_TAG_lexical_block: + case DW_TAG_inlined_subroutine: + // Even if this is a function level static, we don't add it. + // We could theoretically + // add these if we wanted to by introspecting into the + // DW_AT_location and seeing + // if the location describes a hard coded address, but we + // don't want the performance + // penalty of that right now. + add_die = false; + parent_die.Clear(); // Terminate the while loop. + break; + + case DW_TAG_compile_unit: + add_die = true; + parent_die.Clear(); // Terminate the while loop. + break; + + default: + parent_die = + parent_die.GetParent(); // Keep going in the while loop. + break; + } } + } + break; } + } + } - if (pubnames_set.NumDescriptors() > 0) - { - m_sets.push_back(pubnames_set); - } - - // Keep memory down by clearing DIEs if this generate function - // caused them to be parsed - if (clear_dies) - cu->ClearDIEs (true); + if (add_die && (name || mangled)) { + pubnames_set.AddDescriptor(die.GetCompileUnitRelativeOffset(), + mangled ? mangled : name); } - } - if (m_sets.empty()) - return false; - if (log) - Dump (log); - return true; -} + } -bool -DWARFDebugPubnames::GeneratePubBaseTypes(SymbolFileDWARF* dwarf2Data) -{ - m_sets.clear(); - DWARFDebugInfo* debug_info = dwarf2Data->DebugInfo(); - if (debug_info) - { - uint32_t cu_idx = 0; - const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits(); - for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) - { - DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx); - DWARFDIECollection dies; - const size_t die_count = cu->AppendDIEsWithTag (DW_TAG_base_type, dies); - dw_offset_t cu_offset = cu->GetOffset(); - DWARFDebugPubnamesSet pubnames_set(DW_INVALID_OFFSET, cu_offset, cu->GetNextCompileUnitOffset() - cu_offset); - - size_t die_idx; - for (die_idx = 0; die_idx < die_count; ++die_idx) - { - DWARFDIE die = dies.GetDIEAtIndex (die_idx); - const char *name = die.GetName(); - - if (name) - pubnames_set.AddDescriptor(die.GetCompileUnitRelativeOffset(), name); - } + if (pubnames_set.NumDescriptors() > 0) { + m_sets.push_back(pubnames_set); + } - if (pubnames_set.NumDescriptors() > 0) - { - m_sets.push_back(pubnames_set); - } - } + // Keep memory down by clearing DIEs if this generate function + // caused them to be parsed + if (clear_dies) + cu->ClearDIEs(true); } - return !m_sets.empty(); + } + if (m_sets.empty()) + return false; + if (log) + Dump(log); + return true; } -void -DWARFDebugPubnames::Dump(Log *s) const -{ - if (m_sets.empty()) - s->PutCString("< EMPTY >\n"); - else - { - const_iterator pos; - const_iterator end = m_sets.end(); - - for (pos = m_sets.begin(); pos != end; ++pos) - (*pos).Dump(s); +bool DWARFDebugPubnames::GeneratePubBaseTypes(SymbolFileDWARF *dwarf2Data) { + m_sets.clear(); + DWARFDebugInfo *debug_info = dwarf2Data->DebugInfo(); + if (debug_info) { + uint32_t cu_idx = 0; + const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits(); + for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) { + DWARFCompileUnit *cu = debug_info->GetCompileUnitAtIndex(cu_idx); + DWARFDIECollection dies; + const size_t die_count = cu->AppendDIEsWithTag(DW_TAG_base_type, dies); + dw_offset_t cu_offset = cu->GetOffset(); + DWARFDebugPubnamesSet pubnames_set(DW_INVALID_OFFSET, cu_offset, + cu->GetNextCompileUnitOffset() - + cu_offset); + + size_t die_idx; + for (die_idx = 0; die_idx < die_count; ++die_idx) { + DWARFDIE die = dies.GetDIEAtIndex(die_idx); + const char *name = die.GetName(); + + if (name) + pubnames_set.AddDescriptor(die.GetCompileUnitRelativeOffset(), name); + } + + if (pubnames_set.NumDescriptors() > 0) { + m_sets.push_back(pubnames_set); + } } + } + return !m_sets.empty(); } -bool -DWARFDebugPubnames::Find(const char* name, bool ignore_case, std::vector<dw_offset_t>& die_offsets) const -{ +void DWARFDebugPubnames::Dump(Log *s) const { + if (m_sets.empty()) + s->PutCString("< EMPTY >\n"); + else { const_iterator pos; const_iterator end = m_sets.end(); - die_offsets.clear(); - for (pos = m_sets.begin(); pos != end; ++pos) - { - (*pos).Find(name, ignore_case, die_offsets); - } + (*pos).Dump(s); + } +} + +bool DWARFDebugPubnames::Find(const char *name, bool ignore_case, + std::vector<dw_offset_t> &die_offsets) const { + const_iterator pos; + const_iterator end = m_sets.end(); + + die_offsets.clear(); + + for (pos = m_sets.begin(); pos != end; ++pos) { + (*pos).Find(name, ignore_case, die_offsets); + } - return !die_offsets.empty(); + return !die_offsets.empty(); } -bool -DWARFDebugPubnames::Find(const RegularExpression& regex, std::vector<dw_offset_t>& die_offsets) const -{ - const_iterator pos; - const_iterator end = m_sets.end(); +bool DWARFDebugPubnames::Find(const RegularExpression ®ex, + std::vector<dw_offset_t> &die_offsets) const { + const_iterator pos; + const_iterator end = m_sets.end(); - die_offsets.clear(); + die_offsets.clear(); - for (pos = m_sets.begin(); pos != end; ++pos) - { - (*pos).Find(regex, die_offsets); - } + for (pos = m_sets.begin(); pos != end; ++pos) { + (*pos).Find(regex, die_offsets); + } - return !die_offsets.empty(); + return !die_offsets.empty(); } diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.h index cacb1ea109bf..57dabade012c 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.h @@ -16,23 +16,25 @@ #include "DWARFDebugPubnamesSet.h" -class DWARFDebugPubnames -{ +class DWARFDebugPubnames { public: - DWARFDebugPubnames(); - bool Extract(const lldb_private::DWARFDataExtractor& data); - bool GeneratePubnames(SymbolFileDWARF* dwarf2Data); - bool GeneratePubBaseTypes(SymbolFileDWARF* dwarf2Data); - - void Dump(lldb_private::Log *s) const; - bool Find(const char* name, bool ignore_case, std::vector<dw_offset_t>& die_offset_coll) const; - bool Find(const lldb_private::RegularExpression& regex, std::vector<dw_offset_t>& die_offsets) const; + DWARFDebugPubnames(); + bool Extract(const lldb_private::DWARFDataExtractor &data); + bool GeneratePubnames(SymbolFileDWARF *dwarf2Data); + bool GeneratePubBaseTypes(SymbolFileDWARF *dwarf2Data); + + void Dump(lldb_private::Log *s) const; + bool Find(const char *name, bool ignore_case, + std::vector<dw_offset_t> &die_offset_coll) const; + bool Find(const lldb_private::RegularExpression ®ex, + std::vector<dw_offset_t> &die_offsets) const; + protected: - typedef std::list<DWARFDebugPubnamesSet> collection; - typedef collection::iterator iterator; - typedef collection::const_iterator const_iterator; + typedef std::list<DWARFDebugPubnamesSet> collection; + typedef collection::iterator iterator; + typedef collection::const_iterator const_iterator; - collection m_sets; + collection m_sets; }; -#endif // SymbolFileDWARF_DWARFDebugPubnames_h_ +#endif // SymbolFileDWARF_DWARFDebugPubnames_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp index b7e1b27d1501..4518d65811b5 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp @@ -9,158 +9,138 @@ #include "DWARFDebugPubnamesSet.h" -#include "lldb/Core/RegularExpression.h" #include "lldb/Core/Log.h" +#include "lldb/Core/RegularExpression.h" #include "SymbolFileDWARF.h" using namespace lldb_private; -DWARFDebugPubnamesSet::DWARFDebugPubnamesSet() : - m_offset(DW_INVALID_OFFSET), - m_header(), - m_descriptors(), - m_name_to_descriptor_index() -{ +DWARFDebugPubnamesSet::DWARFDebugPubnamesSet() + : m_offset(DW_INVALID_OFFSET), m_header(), m_descriptors(), + m_name_to_descriptor_index() {} + +DWARFDebugPubnamesSet::DWARFDebugPubnamesSet(dw_offset_t debug_aranges_offset, + dw_offset_t cu_die_offset, + dw_offset_t cu_die_length) + : m_offset(debug_aranges_offset), m_header(), m_descriptors(), + m_name_to_descriptor_index() { + m_header.length = + 10; // set the length to only include the header right for now + m_header.version = 2; // The DWARF version number + m_header.die_offset = cu_die_offset; // compile unit .debug_info offset + m_header.die_length = cu_die_length; // compile unit .debug_info length } -DWARFDebugPubnamesSet::DWARFDebugPubnamesSet(dw_offset_t debug_aranges_offset, dw_offset_t cu_die_offset, dw_offset_t cu_die_length) : - m_offset(debug_aranges_offset), - m_header(), - m_descriptors(), - m_name_to_descriptor_index() -{ - m_header.length = 10; // set the length to only include the header right for now - m_header.version = 2; // The DWARF version number - m_header.die_offset = cu_die_offset;// compile unit .debug_info offset - m_header.die_length = cu_die_length;// compile unit .debug_info length -} - -void -DWARFDebugPubnamesSet::AddDescriptor(dw_offset_t cu_rel_offset, const char* name) -{ - if (name && name[0]) - { - // Adjust our header length - m_header.length += strlen(name) + 1 + sizeof(dw_offset_t); - Descriptor pubnameDesc(cu_rel_offset, name); - m_descriptors.push_back(pubnameDesc); - } +void DWARFDebugPubnamesSet::AddDescriptor(dw_offset_t cu_rel_offset, + const char *name) { + if (name && name[0]) { + // Adjust our header length + m_header.length += strlen(name) + 1 + sizeof(dw_offset_t); + Descriptor pubnameDesc(cu_rel_offset, name); + m_descriptors.push_back(pubnameDesc); + } } -void -DWARFDebugPubnamesSet::Clear() -{ - m_offset = DW_INVALID_OFFSET; - m_header.length = 10; - m_header.version = 2; - m_header.die_offset = DW_INVALID_OFFSET; - m_header.die_length = 0; - m_descriptors.clear(); +void DWARFDebugPubnamesSet::Clear() { + m_offset = DW_INVALID_OFFSET; + m_header.length = 10; + m_header.version = 2; + m_header.die_offset = DW_INVALID_OFFSET; + m_header.die_length = 0; + m_descriptors.clear(); } - //---------------------------------------------------------------------- // InitNameIndexes //---------------------------------------------------------------------- -void -DWARFDebugPubnamesSet::InitNameIndexes() const -{ - // Create the name index vector to be able to quickly search by name - const size_t count = m_descriptors.size(); - for (uint32_t idx = 0; idx < count; ++idx) - { - const char* name = m_descriptors[idx].name.c_str(); - if (name && name[0]) - m_name_to_descriptor_index.insert(cstr_to_index_mmap::value_type(name, idx)); - } +void DWARFDebugPubnamesSet::InitNameIndexes() const { + // Create the name index vector to be able to quickly search by name + const size_t count = m_descriptors.size(); + for (uint32_t idx = 0; idx < count; ++idx) { + const char *name = m_descriptors[idx].name.c_str(); + if (name && name[0]) + m_name_to_descriptor_index.insert( + cstr_to_index_mmap::value_type(name, idx)); + } } - -bool -DWARFDebugPubnamesSet::Extract(const DWARFDataExtractor& data, lldb::offset_t *offset_ptr) -{ - if (data.ValidOffset(*offset_ptr)) - { - m_descriptors.clear(); - m_offset = *offset_ptr; - m_header.length = data.GetDWARFInitialLength(offset_ptr); - m_header.version = data.GetU16(offset_ptr); - m_header.die_offset = data.GetDWARFOffset(offset_ptr); - m_header.die_length = data.GetDWARFOffset(offset_ptr); - - Descriptor pubnameDesc; - while (data.ValidOffset(*offset_ptr)) - { - pubnameDesc.offset = data.GetDWARFOffset(offset_ptr); - - if (pubnameDesc.offset) - { - const char* name = data.GetCStr(offset_ptr); - if (name && name[0]) - { - pubnameDesc.name = name; - m_descriptors.push_back(pubnameDesc); - } - } - else - break; // We are done if we get a zero 4 byte offset +bool DWARFDebugPubnamesSet::Extract(const DWARFDataExtractor &data, + lldb::offset_t *offset_ptr) { + if (data.ValidOffset(*offset_ptr)) { + m_descriptors.clear(); + m_offset = *offset_ptr; + m_header.length = data.GetDWARFInitialLength(offset_ptr); + m_header.version = data.GetU16(offset_ptr); + m_header.die_offset = data.GetDWARFOffset(offset_ptr); + m_header.die_length = data.GetDWARFOffset(offset_ptr); + + Descriptor pubnameDesc; + while (data.ValidOffset(*offset_ptr)) { + pubnameDesc.offset = data.GetDWARFOffset(offset_ptr); + + if (pubnameDesc.offset) { + const char *name = data.GetCStr(offset_ptr); + if (name && name[0]) { + pubnameDesc.name = name; + m_descriptors.push_back(pubnameDesc); } - - return !m_descriptors.empty(); + } else + break; // We are done if we get a zero 4 byte offset } - return false; -} -dw_offset_t -DWARFDebugPubnamesSet::GetOffsetOfNextEntry() const -{ - return m_offset + m_header.length + 4; + return !m_descriptors.empty(); + } + return false; } -void -DWARFDebugPubnamesSet::Dump(Log *log) const -{ - log->Printf("Pubnames Header: length = 0x%8.8x, version = 0x%4.4x, die_offset = 0x%8.8x, die_length = 0x%8.8x", - m_header.length, - m_header.version, - m_header.die_offset, - m_header.die_length); - - bool verbose = log->GetVerbose(); - - DescriptorConstIter pos; - DescriptorConstIter end = m_descriptors.end(); - for (pos = m_descriptors.begin(); pos != end; ++pos) - { - if (verbose) - log->Printf("0x%8.8x + 0x%8.8x = 0x%8.8x: %s", pos->offset, m_header.die_offset, pos->offset + m_header.die_offset, pos->name.c_str()); - else - log->Printf("0x%8.8x: %s", pos->offset + m_header.die_offset, pos->name.c_str()); - } +dw_offset_t DWARFDebugPubnamesSet::GetOffsetOfNextEntry() const { + return m_offset + m_header.length + 4; } - -void -DWARFDebugPubnamesSet::Find(const char* name, bool ignore_case, std::vector<dw_offset_t>& die_offset_coll) const -{ - if (!m_descriptors.empty() && m_name_to_descriptor_index.empty()) - InitNameIndexes(); - - std::pair<cstr_to_index_mmap::const_iterator, cstr_to_index_mmap::const_iterator> range(m_name_to_descriptor_index.equal_range(name)); - for (cstr_to_index_mmap::const_iterator pos = range.first; pos != range.second; ++pos) - die_offset_coll.push_back(m_header.die_offset + m_descriptors[(*pos).second].offset); +void DWARFDebugPubnamesSet::Dump(Log *log) const { + log->Printf("Pubnames Header: length = 0x%8.8x, version = 0x%4.4x, " + "die_offset = 0x%8.8x, die_length = 0x%8.8x", + m_header.length, m_header.version, m_header.die_offset, + m_header.die_length); + + bool verbose = log->GetVerbose(); + + DescriptorConstIter pos; + DescriptorConstIter end = m_descriptors.end(); + for (pos = m_descriptors.begin(); pos != end; ++pos) { + if (verbose) + log->Printf("0x%8.8x + 0x%8.8x = 0x%8.8x: %s", pos->offset, + m_header.die_offset, pos->offset + m_header.die_offset, + pos->name.c_str()); + else + log->Printf("0x%8.8x: %s", pos->offset + m_header.die_offset, + pos->name.c_str()); + } } -void -DWARFDebugPubnamesSet::Find(const RegularExpression& regex, std::vector<dw_offset_t>& die_offset_coll) const -{ - DescriptorConstIter pos; - DescriptorConstIter end = m_descriptors.end(); - for (pos = m_descriptors.begin(); pos != end; ++pos) - { - if ( regex.Execute(pos->name.c_str()) ) - die_offset_coll.push_back(m_header.die_offset + pos->offset); - } +void DWARFDebugPubnamesSet::Find( + const char *name, bool ignore_case, + std::vector<dw_offset_t> &die_offset_coll) const { + if (!m_descriptors.empty() && m_name_to_descriptor_index.empty()) + InitNameIndexes(); + + std::pair<cstr_to_index_mmap::const_iterator, + cstr_to_index_mmap::const_iterator> + range(m_name_to_descriptor_index.equal_range(name)); + for (cstr_to_index_mmap::const_iterator pos = range.first; + pos != range.second; ++pos) + die_offset_coll.push_back(m_header.die_offset + + m_descriptors[(*pos).second].offset); } +void DWARFDebugPubnamesSet::Find( + const RegularExpression ®ex, + std::vector<dw_offset_t> &die_offset_coll) const { + DescriptorConstIter pos; + DescriptorConstIter end = m_descriptors.end(); + for (pos = m_descriptors.begin(); pos != end; ++pos) { + if (regex.Execute(pos->name)) + die_offset_coll.push_back(m_header.die_offset + pos->offset); + } +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h index 075807b2dcc3..9654ee3d6da7 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h @@ -19,81 +19,74 @@ #include <ext/hash_map> #endif -class DWARFDebugPubnamesSet -{ +class DWARFDebugPubnamesSet { public: - struct Header - { - uint32_t length; // length of the set of entries for this compilation unit, not including the length field itself - uint16_t version; // The DWARF version number - uint32_t die_offset; // compile unit .debug_info offset - uint32_t die_length; // compile unit .debug_info length - Header() : - length(10), - version(2), - die_offset(DW_INVALID_OFFSET), - die_length(0) - { - } - }; + struct Header { + uint32_t length; // length of the set of entries for this compilation unit, + // not including the length field itself + uint16_t version; // The DWARF version number + uint32_t die_offset; // compile unit .debug_info offset + uint32_t die_length; // compile unit .debug_info length + Header() + : length(10), version(2), die_offset(DW_INVALID_OFFSET), die_length(0) { + } + }; - struct Descriptor - { - Descriptor() : - offset(), - name() - { - } + struct Descriptor { + Descriptor() : offset(), name() {} - Descriptor(dw_offset_t the_offset, const char *the_name) : - offset(the_offset), - name(the_name ? the_name : "") - { - } - - dw_offset_t offset; - std::string name; - }; - - DWARFDebugPubnamesSet(); - DWARFDebugPubnamesSet(dw_offset_t debug_aranges_offset, dw_offset_t cu_die_offset, dw_offset_t die_length); - dw_offset_t GetOffset() const { return m_offset; } - void SetOffset(dw_offset_t offset) { m_offset = offset; } - DWARFDebugPubnamesSet::Header& GetHeader() { return m_header; } - const DWARFDebugPubnamesSet::Header& GetHeader() const { return m_header; } - const DWARFDebugPubnamesSet::Descriptor* GetDescriptor(uint32_t i) const - { - if (i < m_descriptors.size()) - return &m_descriptors[i]; - return NULL; - } - uint32_t NumDescriptors() const { return m_descriptors.size(); } - void AddDescriptor(dw_offset_t cu_rel_offset, const char* name); - void Clear(); - bool Extract(const lldb_private::DWARFDataExtractor& debug_pubnames_data, lldb::offset_t *offset_ptr); - void Dump(lldb_private::Log *s) const; - void InitNameIndexes() const; - void Find(const char* name, bool ignore_case, std::vector<dw_offset_t>& die_offset_coll) const; - void Find(const lldb_private::RegularExpression& regex, std::vector<dw_offset_t>& die_offsets) const; - dw_offset_t GetOffsetOfNextEntry() const; + Descriptor(dw_offset_t the_offset, const char *the_name) + : offset(the_offset), name(the_name ? the_name : "") {} + dw_offset_t offset; + std::string name; + }; + DWARFDebugPubnamesSet(); + DWARFDebugPubnamesSet(dw_offset_t debug_aranges_offset, + dw_offset_t cu_die_offset, dw_offset_t die_length); + dw_offset_t GetOffset() const { return m_offset; } + void SetOffset(dw_offset_t offset) { m_offset = offset; } + DWARFDebugPubnamesSet::Header &GetHeader() { return m_header; } + const DWARFDebugPubnamesSet::Header &GetHeader() const { return m_header; } + const DWARFDebugPubnamesSet::Descriptor *GetDescriptor(uint32_t i) const { + if (i < m_descriptors.size()) + return &m_descriptors[i]; + return NULL; + } + uint32_t NumDescriptors() const { return m_descriptors.size(); } + void AddDescriptor(dw_offset_t cu_rel_offset, const char *name); + void Clear(); + bool Extract(const lldb_private::DWARFDataExtractor &debug_pubnames_data, + lldb::offset_t *offset_ptr); + void Dump(lldb_private::Log *s) const; + void InitNameIndexes() const; + void Find(const char *name, bool ignore_case, + std::vector<dw_offset_t> &die_offset_coll) const; + void Find(const lldb_private::RegularExpression ®ex, + std::vector<dw_offset_t> &die_offsets) const; + dw_offset_t GetOffsetOfNextEntry() const; protected: - typedef std::vector<Descriptor> DescriptorColl; - typedef DescriptorColl::iterator DescriptorIter; - typedef DescriptorColl::const_iterator DescriptorConstIter; - + typedef std::vector<Descriptor> DescriptorColl; + typedef DescriptorColl::iterator DescriptorIter; + typedef DescriptorColl::const_iterator DescriptorConstIter; - dw_offset_t m_offset; - Header m_header; + dw_offset_t m_offset; + Header m_header; #if __cplusplus >= 201103L || defined(_MSC_VER) - typedef std::unordered_multimap<const char*, uint32_t, std::hash<const char*>, CStringEqualBinaryPredicate> cstr_to_index_mmap; + typedef std::unordered_multimap<const char *, uint32_t, + std::hash<const char *>, + CStringEqualBinaryPredicate> + cstr_to_index_mmap; #else - typedef __gnu_cxx::hash_multimap<const char*, uint32_t, __gnu_cxx::hash<const char*>, CStringEqualBinaryPredicate> cstr_to_index_mmap; + typedef __gnu_cxx::hash_multimap<const char *, uint32_t, + __gnu_cxx::hash<const char *>, + CStringEqualBinaryPredicate> + cstr_to_index_mmap; #endif - DescriptorColl m_descriptors; - mutable cstr_to_index_mmap m_name_to_descriptor_index; + DescriptorColl m_descriptors; + mutable cstr_to_index_mmap m_name_to_descriptor_index; }; -#endif // SymbolFileDWARF_DWARFDebugPubnamesSet_h_ +#endif // SymbolFileDWARF_DWARFDebugPubnamesSet_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp index fc2831f22438..78fe571c50cf 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp @@ -15,135 +15,117 @@ using namespace lldb_private; using namespace std; -DWARFDebugRanges::DWARFDebugRanges() : - m_range_map() -{ +DWARFDebugRanges::DWARFDebugRanges() : m_range_map() {} + +DWARFDebugRanges::~DWARFDebugRanges() {} + +void DWARFDebugRanges::Extract(SymbolFileDWARF *dwarf2Data) { + DWARFRangeList range_list; + lldb::offset_t offset = 0; + dw_offset_t debug_ranges_offset = offset; + while (Extract(dwarf2Data, &offset, range_list)) { + range_list.Sort(); + m_range_map[debug_ranges_offset] = range_list; + debug_ranges_offset = offset; + } } -DWARFDebugRanges::~DWARFDebugRanges() -{ -} - -void -DWARFDebugRanges::Extract(SymbolFileDWARF* dwarf2Data) -{ - DWARFRangeList range_list; - lldb::offset_t offset = 0; - dw_offset_t debug_ranges_offset = offset; - while (Extract(dwarf2Data, &offset, range_list)) - { - range_list.Sort(); - m_range_map[debug_ranges_offset] = range_list; - debug_ranges_offset = offset; +bool DWARFDebugRanges::Extract(SymbolFileDWARF *dwarf2Data, + lldb::offset_t *offset_ptr, + DWARFRangeList &range_list) { + range_list.Clear(); + + lldb::offset_t range_offset = *offset_ptr; + const DWARFDataExtractor &debug_ranges_data = + dwarf2Data->get_debug_ranges_data(); + uint32_t addr_size = debug_ranges_data.GetAddressByteSize(); + + while ( + debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size)) { + dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); + dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); + if (!begin && !end) { + // End of range list + break; } -} - -bool -DWARFDebugRanges::Extract(SymbolFileDWARF* dwarf2Data, lldb::offset_t *offset_ptr, DWARFRangeList &range_list) -{ - range_list.Clear(); - - lldb::offset_t range_offset = *offset_ptr; - const DWARFDataExtractor& debug_ranges_data = dwarf2Data->get_debug_ranges_data(); - uint32_t addr_size = debug_ranges_data.GetAddressByteSize(); - - while (debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size)) - { - dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); - dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); - if (!begin && !end) - { - // End of range list - break; - } - // Extend 4 byte addresses that consists of 32 bits of 1's to be 64 bits - // of ones - switch (addr_size) - { - case 2: - if (begin == 0xFFFFull) - begin = LLDB_INVALID_ADDRESS; - break; - - case 4: - if (begin == 0xFFFFFFFFull) - begin = LLDB_INVALID_ADDRESS; - break; - - case 8: - break; - - default: - assert(!"DWARFRangeList::Extract() unsupported address size."); - break; - } - - // Filter out empty ranges - if (begin < end) - range_list.Append(DWARFRangeList::Entry(begin, end - begin)); + // Extend 4 byte addresses that consists of 32 bits of 1's to be 64 bits + // of ones + switch (addr_size) { + case 2: + if (begin == 0xFFFFull) + begin = LLDB_INVALID_ADDRESS; + break; + + case 4: + if (begin == 0xFFFFFFFFull) + begin = LLDB_INVALID_ADDRESS; + break; + + case 8: + break; + + default: + assert(!"DWARFRangeList::Extract() unsupported address size."); + break; } - // Make sure we consumed at least something - return range_offset != *offset_ptr; -} + // Filter out empty ranges + if (begin < end) + range_list.Append(DWARFRangeList::Entry(begin, end - begin)); + } + // Make sure we consumed at least something + return range_offset != *offset_ptr; +} -void -DWARFDebugRanges::Dump(Stream &s, const DWARFDataExtractor& debug_ranges_data, lldb::offset_t *offset_ptr, dw_addr_t cu_base_addr) -{ - uint32_t addr_size = s.GetAddressByteSize(); - bool verbose = s.GetVerbose(); - - dw_addr_t base_addr = cu_base_addr; - while (debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size)) - { - dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); - dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); - // Extend 4 byte addresses that consists of 32 bits of 1's to be 64 bits - // of ones - if (begin == 0xFFFFFFFFull && addr_size == 4) - begin = LLDB_INVALID_ADDRESS; - - s.Indent(); - if (verbose) - { - s.AddressRange(begin, end, sizeof (dw_addr_t), " offsets = "); - } - - - if (begin == 0 && end == 0) - { - s.PutCString(" End"); - break; - } - else if (begin == LLDB_INVALID_ADDRESS) - { - // A base address selection entry - base_addr = end; - s.Address(base_addr, sizeof (dw_addr_t), " Base address = "); - } - else - { - // Convert from offset to an address - dw_addr_t begin_addr = begin + base_addr; - dw_addr_t end_addr = end + base_addr; - - s.AddressRange(begin_addr, end_addr, sizeof (dw_addr_t), verbose ? " ==> addrs = " : NULL); - } +void DWARFDebugRanges::Dump(Stream &s, + const DWARFDataExtractor &debug_ranges_data, + lldb::offset_t *offset_ptr, + dw_addr_t cu_base_addr) { + uint32_t addr_size = s.GetAddressByteSize(); + bool verbose = s.GetVerbose(); + + dw_addr_t base_addr = cu_base_addr; + while ( + debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size)) { + dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); + dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); + // Extend 4 byte addresses that consists of 32 bits of 1's to be 64 bits + // of ones + if (begin == 0xFFFFFFFFull && addr_size == 4) + begin = LLDB_INVALID_ADDRESS; + + s.Indent(); + if (verbose) { + s.AddressRange(begin, end, sizeof(dw_addr_t), " offsets = "); } -} -bool -DWARFDebugRanges::FindRanges(dw_offset_t debug_ranges_offset, DWARFRangeList& range_list) const -{ - range_map_const_iterator pos = m_range_map.find(debug_ranges_offset); - if (pos != m_range_map.end()) - { - range_list = pos->second; - return true; + if (begin == 0 && end == 0) { + s.PutCString(" End"); + break; + } else if (begin == LLDB_INVALID_ADDRESS) { + // A base address selection entry + base_addr = end; + s.Address(base_addr, sizeof(dw_addr_t), " Base address = "); + } else { + // Convert from offset to an address + dw_addr_t begin_addr = begin + base_addr; + dw_addr_t end_addr = end + base_addr; + + s.AddressRange(begin_addr, end_addr, sizeof(dw_addr_t), + verbose ? " ==> addrs = " : NULL); } - return false; + } } - - +bool DWARFDebugRanges::FindRanges(dw_addr_t debug_ranges_base, + dw_offset_t debug_ranges_offset, + DWARFRangeList &range_list) const { + dw_addr_t debug_ranges_address = debug_ranges_base + 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; + return true; + } + return false; +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h index 3ff4ea3502c9..f514359e00a4 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h @@ -10,33 +10,31 @@ #ifndef SymbolFileDWARF_DWARFDebugRanges_h_ #define SymbolFileDWARF_DWARFDebugRanges_h_ -#include "SymbolFileDWARF.h" #include "DWARFDIE.h" +#include "SymbolFileDWARF.h" #include <map> -class DWARFDebugRanges -{ +class DWARFDebugRanges { public: - - DWARFDebugRanges(); - ~DWARFDebugRanges(); - void Extract(SymbolFileDWARF* dwarf2Data); - 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_offset_t debug_ranges_offset, DWARFRangeList& range_list) const; + DWARFDebugRanges(); + ~DWARFDebugRanges(); + void Extract(SymbolFileDWARF *dwarf2Data); + 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, + DWARFRangeList &range_list); - bool - Extract (SymbolFileDWARF* dwarf2Data, - lldb::offset_t *offset_ptr, - DWARFRangeList &range_list); - - typedef std::map<dw_offset_t, DWARFRangeList> range_map; - typedef range_map::iterator range_map_iterator; - typedef range_map::const_iterator range_map_const_iterator; - range_map m_range_map; + typedef std::map<dw_offset_t, DWARFRangeList> range_map; + typedef range_map::iterator range_map_iterator; + typedef range_map::const_iterator range_map_const_iterator; + range_map m_range_map; }; - -#endif // SymbolFileDWARF_DWARFDebugRanges_h_ +#endif // SymbolFileDWARF_DWARFDebugRanges_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp index 5512072529fc..79f2f221696b 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp @@ -9,96 +9,80 @@ #include "DWARFDeclContext.h" -const char * -DWARFDeclContext::GetQualifiedName () const -{ - if (m_qualified_name.empty()) - { - // The declaration context array for a class named "foo" in namespace - // "a::b::c" will be something like: - // [0] DW_TAG_class_type "foo" - // [1] DW_TAG_namespace "c" - // [2] DW_TAG_namespace "b" - // [3] DW_TAG_namespace "a" - if (!m_entries.empty()) - { - if (m_entries.size() == 1) - { - if (m_entries[0].name) - { - m_qualified_name.append("::"); - m_qualified_name.append(m_entries[0].name); - } - } +const char *DWARFDeclContext::GetQualifiedName() const { + if (m_qualified_name.empty()) { + // The declaration context array for a class named "foo" in namespace + // "a::b::c" will be something like: + // [0] DW_TAG_class_type "foo" + // [1] DW_TAG_namespace "c" + // [2] DW_TAG_namespace "b" + // [3] DW_TAG_namespace "a" + if (!m_entries.empty()) { + if (m_entries.size() == 1) { + if (m_entries[0].name) { + m_qualified_name.append("::"); + m_qualified_name.append(m_entries[0].name); + } + } else { + collection::const_reverse_iterator pos; + collection::const_reverse_iterator begin = m_entries.rbegin(); + collection::const_reverse_iterator end = m_entries.rend(); + for (pos = begin; pos != end; ++pos) { + if (pos != begin) + m_qualified_name.append("::"); + if (pos->name == NULL) { + if (pos->tag == DW_TAG_namespace) + m_qualified_name.append("(anonymous namespace)"); + else if (pos->tag == DW_TAG_class_type) + m_qualified_name.append("(anonymous class)"); + else if (pos->tag == DW_TAG_structure_type) + m_qualified_name.append("(anonymous struct)"); + else if (pos->tag == DW_TAG_union_type) + m_qualified_name.append("(anonymous union)"); else - { - collection::const_reverse_iterator pos; - collection::const_reverse_iterator begin = m_entries.rbegin(); - collection::const_reverse_iterator end = m_entries.rend(); - for (pos = begin; pos != end; ++pos) - { - if (pos != begin) - m_qualified_name.append("::"); - if (pos->name == NULL) - { - if (pos->tag == DW_TAG_namespace) - m_qualified_name.append ("(anonymous namespace)"); - else if (pos->tag == DW_TAG_class_type) - m_qualified_name.append ("(anonymous class)"); - else if (pos->tag == DW_TAG_structure_type) - m_qualified_name.append ("(anonymous struct)"); - else if (pos->tag == DW_TAG_union_type) - m_qualified_name.append ("(anonymous union)"); - else - m_qualified_name.append ("(anonymous)"); - } - else - m_qualified_name.append(pos->name); - } - } + m_qualified_name.append("(anonymous)"); + } else + m_qualified_name.append(pos->name); } + } } - if (m_qualified_name.empty()) - return NULL; - return m_qualified_name.c_str(); + } + if (m_qualified_name.empty()) + return NULL; + return m_qualified_name.c_str(); } +bool DWARFDeclContext::operator==(const DWARFDeclContext &rhs) const { + if (m_entries.size() != rhs.m_entries.size()) + return false; -bool -DWARFDeclContext::operator==(const DWARFDeclContext& rhs) const -{ - if (m_entries.size() != rhs.m_entries.size()) - return false; - - collection::const_iterator pos; - collection::const_iterator begin = m_entries.begin(); - collection::const_iterator end = m_entries.end(); + collection::const_iterator pos; + collection::const_iterator begin = m_entries.begin(); + collection::const_iterator end = m_entries.end(); - collection::const_iterator rhs_pos; - collection::const_iterator rhs_begin = rhs.m_entries.begin(); - // The two entry arrays have the same size - - // First compare the tags before we do expensive name compares - for (pos = begin, rhs_pos = rhs_begin; pos != end; ++pos, ++rhs_pos) - { - if (pos->tag != rhs_pos->tag) - { - // Check for DW_TAG_structure_type and DW_TAG_class_type as they are often - // used interchangeably in GCC - if (pos->tag == DW_TAG_structure_type && rhs_pos->tag == DW_TAG_class_type) - continue; - if (pos->tag == DW_TAG_class_type && rhs_pos->tag == DW_TAG_structure_type) - continue; - return false; - } - } - // The tags all match, now compare the names - for (pos = begin, rhs_pos = rhs_begin; pos != end; ++pos, ++rhs_pos) - { - if (!pos->NameMatches (*rhs_pos)) - return false; + collection::const_iterator rhs_pos; + collection::const_iterator rhs_begin = rhs.m_entries.begin(); + // The two entry arrays have the same size + + // First compare the tags before we do expensive name compares + for (pos = begin, rhs_pos = rhs_begin; pos != end; ++pos, ++rhs_pos) { + if (pos->tag != rhs_pos->tag) { + // Check for DW_TAG_structure_type and DW_TAG_class_type as they are often + // used interchangeably in GCC + if (pos->tag == DW_TAG_structure_type && + rhs_pos->tag == DW_TAG_class_type) + continue; + if (pos->tag == DW_TAG_class_type && + rhs_pos->tag == DW_TAG_structure_type) + continue; + return false; } - // All tags and names match - return true; + } + // The tags all match, now compare the names + for (pos = begin, rhs_pos = rhs_begin; pos != end; ++pos, ++rhs_pos) { + if (!pos->NameMatches(*rhs_pos)) + return false; + } + // All tags and names match + return true; } - diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h index 2452274a293b..0d0a5a317262 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h @@ -27,112 +27,69 @@ // in another DWARF file. //---------------------------------------------------------------------- -class DWARFDeclContext -{ +class DWARFDeclContext { public: - struct Entry - { - Entry () : - tag(0), - name(NULL) - { - } - Entry (dw_tag_t t, const char *n) : - tag(t), - name(n) - { - } - - bool - NameMatches (const Entry& rhs) const - { - if (name == rhs.name) - return true; - else if (name && rhs.name) - return strcmp(name, rhs.name) == 0; - return false; - } - - // Test operator - explicit operator bool() const - { - return tag != 0; - } - - dw_tag_t tag; - const char *name; - }; - - DWARFDeclContext () : - m_entries(), - m_language(lldb::eLanguageTypeUnknown) - { + struct Entry { + Entry() : tag(0), name(NULL) {} + Entry(dw_tag_t t, const char *n) : tag(t), name(n) {} + + bool NameMatches(const Entry &rhs) const { + if (name == rhs.name) + return true; + else if (name && rhs.name) + return strcmp(name, rhs.name) == 0; + return false; } - void - AppendDeclContext (dw_tag_t tag, const char *name) - { - m_entries.push_back(Entry(tag, name)); - } + // Test operator + explicit operator bool() const { return tag != 0; } - bool - operator ==(const DWARFDeclContext& rhs) const; + dw_tag_t tag; + const char *name; + }; - uint32_t - GetSize() const - { - return m_entries.size(); - } + DWARFDeclContext() : m_entries(), m_language(lldb::eLanguageTypeUnknown) {} - Entry & - operator[] (uint32_t idx) - { - // "idx" must be valid - return m_entries[idx]; - } + void AppendDeclContext(dw_tag_t tag, const char *name) { + m_entries.push_back(Entry(tag, name)); + } - const Entry & - operator[] (uint32_t idx) const - { - // "idx" must be valid - return m_entries[idx]; - } + bool operator==(const DWARFDeclContext &rhs) const; - const char * - GetQualifiedName () const; + uint32_t GetSize() const { return m_entries.size(); } - // Same as GetQaulifiedName, but the life time of the returned string will - // be that of the LLDB session. - lldb_private::ConstString - GetQualifiedNameAsConstString () const - { - return lldb_private::ConstString (GetQualifiedName ()); - } + Entry &operator[](uint32_t idx) { + // "idx" must be valid + return m_entries[idx]; + } - void - Clear() - { - m_entries.clear(); - m_qualified_name.clear(); - } + const Entry &operator[](uint32_t idx) const { + // "idx" must be valid + return m_entries[idx]; + } - lldb::LanguageType - GetLanguage() const - { - return m_language; - } + const char *GetQualifiedName() const; - void - SetLanguage(lldb::LanguageType language) - { - m_language = language; - } + // Same as GetQaulifiedName, but the life time of the returned string will + // be that of the LLDB session. + lldb_private::ConstString GetQualifiedNameAsConstString() const { + return lldb_private::ConstString(GetQualifiedName()); + } + + void Clear() { + m_entries.clear(); + m_qualified_name.clear(); + } + + lldb::LanguageType GetLanguage() const { return m_language; } + + void SetLanguage(lldb::LanguageType language) { m_language = language; } protected: - typedef std::vector<Entry> collection; - collection m_entries; - mutable std::string m_qualified_name; - lldb::LanguageType m_language; + typedef std::vector<Entry> collection; + collection m_entries; + mutable std::string m_qualified_name; + lldb::LanguageType m_language; }; -#endif // SymbolFileDWARF_DWARFDeclContext_h_ +#endif // SymbolFileDWARF_DWARFDeclContext_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp index fe4093bc130e..c5260bb1cb1a 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp @@ -1,4 +1,4 @@ -//===-- DWARFDefines.c ------------------------------------------*- C++ -*-===// +//===-- DWARFDefines.cpp ----------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -8,490 +8,640 @@ //===----------------------------------------------------------------------===// #include "DWARFDefines.h" +#include "lldb/Core/ConstString.h" #include <cstdio> #include <cstring> #include <string> -#include "lldb/Core/ConstString.h" namespace lldb_private { -const char * -DW_TAG_value_to_name (uint32_t val) -{ +const char *DW_TAG_value_to_name(uint32_t val) { static char invalid[100]; if (val == 0) - return "NULL"; + return "NULL"; - const char *llvmstr = llvm::dwarf::TagString (val); - if (llvmstr == NULL) - { - snprintf (invalid, sizeof (invalid), "Unknown DW_TAG constant: 0x%x", val); - return invalid; + llvm::StringRef llvmstr = llvm::dwarf::TagString(val); + if (llvmstr.empty()) { + snprintf(invalid, sizeof(invalid), "Unknown DW_TAG constant: 0x%x", val); + return invalid; } - return llvmstr; -} + return llvmstr.data(); +} -const char * -DW_CHILDREN_value_to_name (uint8_t val) -{ +const char *DW_CHILDREN_value_to_name(uint8_t val) { static char invalid[100]; - const char *llvmstr = llvm::dwarf::ChildrenString (val); - if (llvmstr == NULL) - { - snprintf (invalid, sizeof (invalid), "Unknown DW_CHILDREN constant: 0x%x", val); - return invalid; + llvm::StringRef llvmstr = llvm::dwarf::ChildrenString(val); + if (llvmstr.empty()) { + snprintf(invalid, sizeof(invalid), "Unknown DW_CHILDREN constant: 0x%x", + val); + return invalid; } - return llvmstr; + return llvmstr.data(); } -const char * -DW_AT_value_to_name (uint32_t val) -{ +const char *DW_AT_value_to_name(uint32_t val) { static char invalid[100]; - const char *llvmstr = llvm::dwarf::AttributeString (val); - if (llvmstr == NULL) - { - snprintf (invalid, sizeof (invalid), "Unknown DW_AT constant: 0x%x", val); - return invalid; + llvm::StringRef llvmstr = llvm::dwarf::AttributeString(val); + if (llvmstr.empty()) { + snprintf(invalid, sizeof(invalid), "Unknown DW_AT constant: 0x%x", val); + return invalid; } - return llvmstr; + return llvmstr.data(); } -const char * -DW_FORM_value_to_name (uint32_t val) -{ +const char *DW_FORM_value_to_name(uint32_t val) { static char invalid[100]; - const char *llvmstr = llvm::dwarf::FormEncodingString (val); - if (llvmstr == NULL) - { - snprintf (invalid, sizeof (invalid), "Unknown DW_FORM constant: 0x%x", val); - return invalid; + llvm::StringRef llvmstr = llvm::dwarf::FormEncodingString(val); + if (llvmstr.empty()) { + snprintf(invalid, sizeof(invalid), "Unknown DW_FORM constant: 0x%x", val); + return invalid; } - return llvmstr; + return llvmstr.data(); } -const char * -DW_OP_value_to_name (uint32_t val) -{ +const char *DW_OP_value_to_name(uint32_t val) { static char invalid[100]; - const char *llvmstr = llvm::dwarf::OperationEncodingString (val); - if (llvmstr == NULL) - { - snprintf (invalid, sizeof (invalid), "Unknown DW_OP constant: 0x%x", val); - return invalid; + llvm::StringRef llvmstr = llvm::dwarf::OperationEncodingString(val); + if (llvmstr.empty()) { + snprintf(invalid, sizeof(invalid), "Unknown DW_OP constant: 0x%x", val); + return invalid; } - return llvmstr; + return llvmstr.data(); } -DRC_class -DW_OP_value_to_class (uint32_t val) -{ +DRC_class DW_OP_value_to_class(uint32_t val) { switch (val) { - case 0x03: return DRC_ONEOPERAND; - case 0x06: return DRC_ZEROOPERANDS; - case 0x08: return DRC_ONEOPERAND; - case 0x09: return DRC_ONEOPERAND; - case 0x0a: return DRC_ONEOPERAND; - case 0x0b: return DRC_ONEOPERAND; - case 0x0c: return DRC_ONEOPERAND; - case 0x0d: return DRC_ONEOPERAND; - case 0x0e: return DRC_ONEOPERAND; - case 0x0f: return DRC_ONEOPERAND; - case 0x10: return DRC_ONEOPERAND; - case 0x11: return DRC_ONEOPERAND; - case 0x12: return DRC_ZEROOPERANDS; - case 0x13: return DRC_ZEROOPERANDS; - case 0x14: return DRC_ZEROOPERANDS; - case 0x15: return DRC_ONEOPERAND; - case 0x16: return DRC_ZEROOPERANDS; - case 0x17: return DRC_ZEROOPERANDS; - case 0x18: return DRC_ZEROOPERANDS; - case 0x19: return DRC_ZEROOPERANDS; - case 0x1a: return DRC_ZEROOPERANDS; - case 0x1b: return DRC_ZEROOPERANDS; - case 0x1c: return DRC_ZEROOPERANDS; - case 0x1d: return DRC_ZEROOPERANDS; - case 0x1e: return DRC_ZEROOPERANDS; - case 0x1f: return DRC_ZEROOPERANDS; - case 0x20: return DRC_ZEROOPERANDS; - case 0x21: return DRC_ZEROOPERANDS; - case 0x22: return DRC_ZEROOPERANDS; - case 0x23: return DRC_ONEOPERAND; - case 0x24: return DRC_ZEROOPERANDS; - case 0x25: return DRC_ZEROOPERANDS; - case 0x26: return DRC_ZEROOPERANDS; - case 0x27: return DRC_ZEROOPERANDS; - case 0x2f: return DRC_ONEOPERAND; - case 0x28: return DRC_ONEOPERAND; - case 0x29: return DRC_ZEROOPERANDS; - case 0x2a: return DRC_ZEROOPERANDS; - case 0x2b: return DRC_ZEROOPERANDS; - case 0x2c: return DRC_ZEROOPERANDS; - case 0x2d: return DRC_ZEROOPERANDS; - case 0x2e: return DRC_ZEROOPERANDS; - case 0x30: return DRC_ZEROOPERANDS; - case 0x31: return DRC_ZEROOPERANDS; - case 0x32: return DRC_ZEROOPERANDS; - case 0x33: return DRC_ZEROOPERANDS; - case 0x34: return DRC_ZEROOPERANDS; - case 0x35: return DRC_ZEROOPERANDS; - case 0x36: return DRC_ZEROOPERANDS; - case 0x37: return DRC_ZEROOPERANDS; - case 0x38: return DRC_ZEROOPERANDS; - case 0x39: return DRC_ZEROOPERANDS; - case 0x3a: return DRC_ZEROOPERANDS; - case 0x3b: return DRC_ZEROOPERANDS; - case 0x3c: return DRC_ZEROOPERANDS; - case 0x3d: return DRC_ZEROOPERANDS; - case 0x3e: return DRC_ZEROOPERANDS; - case 0x3f: return DRC_ZEROOPERANDS; - case 0x40: return DRC_ZEROOPERANDS; - case 0x41: return DRC_ZEROOPERANDS; - case 0x42: return DRC_ZEROOPERANDS; - case 0x43: return DRC_ZEROOPERANDS; - case 0x44: return DRC_ZEROOPERANDS; - case 0x45: return DRC_ZEROOPERANDS; - case 0x46: return DRC_ZEROOPERANDS; - case 0x47: return DRC_ZEROOPERANDS; - case 0x48: return DRC_ZEROOPERANDS; - case 0x49: return DRC_ZEROOPERANDS; - case 0x4a: return DRC_ZEROOPERANDS; - case 0x4b: return DRC_ZEROOPERANDS; - case 0x4c: return DRC_ZEROOPERANDS; - case 0x4d: return DRC_ZEROOPERANDS; - case 0x4e: return DRC_ZEROOPERANDS; - case 0x4f: return DRC_ZEROOPERANDS; - case 0x50: return DRC_ZEROOPERANDS; - case 0x51: return DRC_ZEROOPERANDS; - case 0x52: return DRC_ZEROOPERANDS; - case 0x53: return DRC_ZEROOPERANDS; - case 0x54: return DRC_ZEROOPERANDS; - case 0x55: return DRC_ZEROOPERANDS; - case 0x56: return DRC_ZEROOPERANDS; - case 0x57: return DRC_ZEROOPERANDS; - case 0x58: return DRC_ZEROOPERANDS; - case 0x59: return DRC_ZEROOPERANDS; - case 0x5a: return DRC_ZEROOPERANDS; - case 0x5b: return DRC_ZEROOPERANDS; - case 0x5c: return DRC_ZEROOPERANDS; - case 0x5d: return DRC_ZEROOPERANDS; - case 0x5e: return DRC_ZEROOPERANDS; - case 0x5f: return DRC_ZEROOPERANDS; - case 0x60: return DRC_ZEROOPERANDS; - case 0x61: return DRC_ZEROOPERANDS; - case 0x62: return DRC_ZEROOPERANDS; - case 0x63: return DRC_ZEROOPERANDS; - case 0x64: return DRC_ZEROOPERANDS; - case 0x65: return DRC_ZEROOPERANDS; - case 0x66: return DRC_ZEROOPERANDS; - case 0x67: return DRC_ZEROOPERANDS; - case 0x68: return DRC_ZEROOPERANDS; - case 0x69: return DRC_ZEROOPERANDS; - case 0x6a: return DRC_ZEROOPERANDS; - case 0x6b: return DRC_ZEROOPERANDS; - case 0x6c: return DRC_ZEROOPERANDS; - case 0x6d: return DRC_ZEROOPERANDS; - case 0x6e: return DRC_ZEROOPERANDS; - case 0x6f: return DRC_ZEROOPERANDS; - case 0x70: return DRC_ONEOPERAND; - case 0x71: return DRC_ONEOPERAND; - case 0x72: return DRC_ONEOPERAND; - case 0x73: return DRC_ONEOPERAND; - case 0x74: return DRC_ONEOPERAND; - case 0x75: return DRC_ONEOPERAND; - case 0x76: return DRC_ONEOPERAND; - case 0x77: return DRC_ONEOPERAND; - case 0x78: return DRC_ONEOPERAND; - case 0x79: return DRC_ONEOPERAND; - case 0x7a: return DRC_ONEOPERAND; - case 0x7b: return DRC_ONEOPERAND; - case 0x7c: return DRC_ONEOPERAND; - case 0x7d: return DRC_ONEOPERAND; - case 0x7e: return DRC_ONEOPERAND; - case 0x7f: return DRC_ONEOPERAND; - case 0x80: return DRC_ONEOPERAND; - case 0x81: return DRC_ONEOPERAND; - case 0x82: return DRC_ONEOPERAND; - case 0x83: return DRC_ONEOPERAND; - case 0x84: return DRC_ONEOPERAND; - case 0x85: return DRC_ONEOPERAND; - case 0x86: return DRC_ONEOPERAND; - case 0x87: return DRC_ONEOPERAND; - case 0x88: return DRC_ONEOPERAND; - case 0x89: return DRC_ONEOPERAND; - case 0x8a: return DRC_ONEOPERAND; - case 0x8b: return DRC_ONEOPERAND; - case 0x8c: return DRC_ONEOPERAND; - case 0x8d: return DRC_ONEOPERAND; - case 0x8e: return DRC_ONEOPERAND; - case 0x8f: return DRC_ONEOPERAND; - case 0x90: return DRC_ONEOPERAND; - case 0x91: return DRC_ONEOPERAND; - case 0x92: return DRC_TWOOPERANDS; - case 0x93: return DRC_ONEOPERAND; - case 0x94: return DRC_ONEOPERAND; - case 0x95: return DRC_ONEOPERAND; - case 0x96: return DRC_ZEROOPERANDS; - case 0x97: return DRC_DWARFv3 | DRC_ZEROOPERANDS; - case 0x98: return DRC_DWARFv3 | DRC_ONEOPERAND; - case 0x99: return DRC_DWARFv3 | DRC_ONEOPERAND; - case 0x9a: return DRC_DWARFv3 | DRC_ONEOPERAND; - case 0xf0: return DRC_ZEROOPERANDS; /* DW_OP_APPLE_uninit */ - case 0xe0: return 0; - case 0xff: return 0; - default: return 0; + case 0x03: + return DRC_ONEOPERAND; + case 0x06: + return DRC_ZEROOPERANDS; + case 0x08: + return DRC_ONEOPERAND; + case 0x09: + return DRC_ONEOPERAND; + case 0x0a: + return DRC_ONEOPERAND; + case 0x0b: + return DRC_ONEOPERAND; + case 0x0c: + return DRC_ONEOPERAND; + case 0x0d: + return DRC_ONEOPERAND; + case 0x0e: + return DRC_ONEOPERAND; + case 0x0f: + return DRC_ONEOPERAND; + case 0x10: + return DRC_ONEOPERAND; + case 0x11: + return DRC_ONEOPERAND; + case 0x12: + return DRC_ZEROOPERANDS; + case 0x13: + return DRC_ZEROOPERANDS; + case 0x14: + return DRC_ZEROOPERANDS; + case 0x15: + return DRC_ONEOPERAND; + case 0x16: + return DRC_ZEROOPERANDS; + case 0x17: + return DRC_ZEROOPERANDS; + case 0x18: + return DRC_ZEROOPERANDS; + case 0x19: + return DRC_ZEROOPERANDS; + case 0x1a: + return DRC_ZEROOPERANDS; + case 0x1b: + return DRC_ZEROOPERANDS; + case 0x1c: + return DRC_ZEROOPERANDS; + case 0x1d: + return DRC_ZEROOPERANDS; + case 0x1e: + return DRC_ZEROOPERANDS; + case 0x1f: + return DRC_ZEROOPERANDS; + case 0x20: + return DRC_ZEROOPERANDS; + case 0x21: + return DRC_ZEROOPERANDS; + case 0x22: + return DRC_ZEROOPERANDS; + case 0x23: + return DRC_ONEOPERAND; + case 0x24: + return DRC_ZEROOPERANDS; + case 0x25: + return DRC_ZEROOPERANDS; + case 0x26: + return DRC_ZEROOPERANDS; + case 0x27: + return DRC_ZEROOPERANDS; + case 0x2f: + return DRC_ONEOPERAND; + case 0x28: + return DRC_ONEOPERAND; + case 0x29: + return DRC_ZEROOPERANDS; + case 0x2a: + return DRC_ZEROOPERANDS; + case 0x2b: + return DRC_ZEROOPERANDS; + case 0x2c: + return DRC_ZEROOPERANDS; + case 0x2d: + return DRC_ZEROOPERANDS; + case 0x2e: + return DRC_ZEROOPERANDS; + case 0x30: + return DRC_ZEROOPERANDS; + case 0x31: + return DRC_ZEROOPERANDS; + case 0x32: + return DRC_ZEROOPERANDS; + case 0x33: + return DRC_ZEROOPERANDS; + case 0x34: + return DRC_ZEROOPERANDS; + case 0x35: + return DRC_ZEROOPERANDS; + case 0x36: + return DRC_ZEROOPERANDS; + case 0x37: + return DRC_ZEROOPERANDS; + case 0x38: + return DRC_ZEROOPERANDS; + case 0x39: + return DRC_ZEROOPERANDS; + case 0x3a: + return DRC_ZEROOPERANDS; + case 0x3b: + return DRC_ZEROOPERANDS; + case 0x3c: + return DRC_ZEROOPERANDS; + case 0x3d: + return DRC_ZEROOPERANDS; + case 0x3e: + return DRC_ZEROOPERANDS; + case 0x3f: + return DRC_ZEROOPERANDS; + case 0x40: + return DRC_ZEROOPERANDS; + case 0x41: + return DRC_ZEROOPERANDS; + case 0x42: + return DRC_ZEROOPERANDS; + case 0x43: + return DRC_ZEROOPERANDS; + case 0x44: + return DRC_ZEROOPERANDS; + case 0x45: + return DRC_ZEROOPERANDS; + case 0x46: + return DRC_ZEROOPERANDS; + case 0x47: + return DRC_ZEROOPERANDS; + case 0x48: + return DRC_ZEROOPERANDS; + case 0x49: + return DRC_ZEROOPERANDS; + case 0x4a: + return DRC_ZEROOPERANDS; + case 0x4b: + return DRC_ZEROOPERANDS; + case 0x4c: + return DRC_ZEROOPERANDS; + case 0x4d: + return DRC_ZEROOPERANDS; + case 0x4e: + return DRC_ZEROOPERANDS; + case 0x4f: + return DRC_ZEROOPERANDS; + case 0x50: + return DRC_ZEROOPERANDS; + case 0x51: + return DRC_ZEROOPERANDS; + case 0x52: + return DRC_ZEROOPERANDS; + case 0x53: + return DRC_ZEROOPERANDS; + case 0x54: + return DRC_ZEROOPERANDS; + case 0x55: + return DRC_ZEROOPERANDS; + case 0x56: + return DRC_ZEROOPERANDS; + case 0x57: + return DRC_ZEROOPERANDS; + case 0x58: + return DRC_ZEROOPERANDS; + case 0x59: + return DRC_ZEROOPERANDS; + case 0x5a: + return DRC_ZEROOPERANDS; + case 0x5b: + return DRC_ZEROOPERANDS; + case 0x5c: + return DRC_ZEROOPERANDS; + case 0x5d: + return DRC_ZEROOPERANDS; + case 0x5e: + return DRC_ZEROOPERANDS; + case 0x5f: + return DRC_ZEROOPERANDS; + case 0x60: + return DRC_ZEROOPERANDS; + case 0x61: + return DRC_ZEROOPERANDS; + case 0x62: + return DRC_ZEROOPERANDS; + case 0x63: + return DRC_ZEROOPERANDS; + case 0x64: + return DRC_ZEROOPERANDS; + case 0x65: + return DRC_ZEROOPERANDS; + case 0x66: + return DRC_ZEROOPERANDS; + case 0x67: + return DRC_ZEROOPERANDS; + case 0x68: + return DRC_ZEROOPERANDS; + case 0x69: + return DRC_ZEROOPERANDS; + case 0x6a: + return DRC_ZEROOPERANDS; + case 0x6b: + return DRC_ZEROOPERANDS; + case 0x6c: + return DRC_ZEROOPERANDS; + case 0x6d: + return DRC_ZEROOPERANDS; + case 0x6e: + return DRC_ZEROOPERANDS; + case 0x6f: + return DRC_ZEROOPERANDS; + case 0x70: + return DRC_ONEOPERAND; + case 0x71: + return DRC_ONEOPERAND; + case 0x72: + return DRC_ONEOPERAND; + case 0x73: + return DRC_ONEOPERAND; + case 0x74: + return DRC_ONEOPERAND; + case 0x75: + return DRC_ONEOPERAND; + case 0x76: + return DRC_ONEOPERAND; + case 0x77: + return DRC_ONEOPERAND; + case 0x78: + return DRC_ONEOPERAND; + case 0x79: + return DRC_ONEOPERAND; + case 0x7a: + return DRC_ONEOPERAND; + case 0x7b: + return DRC_ONEOPERAND; + case 0x7c: + return DRC_ONEOPERAND; + case 0x7d: + return DRC_ONEOPERAND; + case 0x7e: + return DRC_ONEOPERAND; + case 0x7f: + return DRC_ONEOPERAND; + case 0x80: + return DRC_ONEOPERAND; + case 0x81: + return DRC_ONEOPERAND; + case 0x82: + return DRC_ONEOPERAND; + case 0x83: + return DRC_ONEOPERAND; + case 0x84: + return DRC_ONEOPERAND; + case 0x85: + return DRC_ONEOPERAND; + case 0x86: + return DRC_ONEOPERAND; + case 0x87: + return DRC_ONEOPERAND; + case 0x88: + return DRC_ONEOPERAND; + case 0x89: + return DRC_ONEOPERAND; + case 0x8a: + return DRC_ONEOPERAND; + case 0x8b: + return DRC_ONEOPERAND; + case 0x8c: + return DRC_ONEOPERAND; + case 0x8d: + return DRC_ONEOPERAND; + case 0x8e: + return DRC_ONEOPERAND; + case 0x8f: + return DRC_ONEOPERAND; + case 0x90: + return DRC_ONEOPERAND; + case 0x91: + return DRC_ONEOPERAND; + case 0x92: + return DRC_TWOOPERANDS; + case 0x93: + return DRC_ONEOPERAND; + case 0x94: + return DRC_ONEOPERAND; + case 0x95: + return DRC_ONEOPERAND; + case 0x96: + return DRC_ZEROOPERANDS; + case 0x97: + return DRC_DWARFv3 | DRC_ZEROOPERANDS; + case 0x98: + return DRC_DWARFv3 | DRC_ONEOPERAND; + case 0x99: + return DRC_DWARFv3 | DRC_ONEOPERAND; + case 0x9a: + return DRC_DWARFv3 | DRC_ONEOPERAND; + case 0xf0: + return DRC_ZEROOPERANDS; /* DW_OP_APPLE_uninit */ + case 0xe0: + return 0; + case 0xff: + return 0; + default: + return 0; } } -const char * -DW_ATE_value_to_name (uint32_t val) -{ +const char *DW_ATE_value_to_name(uint32_t val) { static char invalid[100]; - const char *llvmstr = llvm::dwarf::AttributeEncodingString (val); - if (llvmstr == NULL) - { - snprintf (invalid, sizeof (invalid), "Unknown DW_ATE constant: 0x%x", val); - return invalid; + llvm::StringRef llvmstr = llvm::dwarf::AttributeEncodingString(val); + if (llvmstr.empty()) { + snprintf(invalid, sizeof(invalid), "Unknown DW_ATE constant: 0x%x", val); + return invalid; } - return llvmstr; + return llvmstr.data(); } -const char * -DW_ACCESS_value_to_name (uint32_t val) -{ +const char *DW_ACCESS_value_to_name(uint32_t val) { static char invalid[100]; - const char *llvmstr = llvm::dwarf::AccessibilityString (val); - if (llvmstr == NULL) - { - snprintf (invalid, sizeof (invalid), "Unknown DW_ACCESS constant: 0x%x", val); - return invalid; + llvm::StringRef llvmstr = llvm::dwarf::AccessibilityString(val); + if (llvmstr.empty()) { + snprintf(invalid, sizeof(invalid), "Unknown DW_ACCESS constant: 0x%x", val); + return invalid; } - return llvmstr; + return llvmstr.data(); } -const char * -DW_VIS_value_to_name (uint32_t val) -{ +const char *DW_VIS_value_to_name(uint32_t val) { static char invalid[100]; - const char *llvmstr = llvm::dwarf::VisibilityString (val); - if (llvmstr == NULL) - { - snprintf (invalid, sizeof (invalid), "Unknown DW_VIS constant: 0x%x", val); - return invalid; + llvm::StringRef llvmstr = llvm::dwarf::VisibilityString(val); + if (llvmstr.empty()) { + snprintf(invalid, sizeof(invalid), "Unknown DW_VIS constant: 0x%x", val); + return invalid; } - return llvmstr; + return llvmstr.data(); } -const char * -DW_VIRTUALITY_value_to_name (uint32_t val) -{ +const char *DW_VIRTUALITY_value_to_name(uint32_t val) { static char invalid[100]; - const char *llvmstr = llvm::dwarf::VirtualityString (val); - if (llvmstr == NULL) - { - snprintf (invalid, sizeof (invalid), "Unknown DW_VIRTUALITY constant: 0x%x", val); - return invalid; + llvm::StringRef llvmstr = llvm::dwarf::VirtualityString(val); + if (llvmstr.empty()) { + snprintf(invalid, sizeof(invalid), "Unknown DW_VIRTUALITY constant: 0x%x", + val); + return invalid; } - return llvmstr; + return llvmstr.data(); } -const char * -DW_LANG_value_to_name (uint32_t val) -{ +const char *DW_LANG_value_to_name(uint32_t val) { static char invalid[100]; - const char *llvmstr = llvm::dwarf::LanguageString (val); - if (llvmstr == NULL) - { - snprintf (invalid, sizeof (invalid), "Unknown DW_LANG constant: 0x%x", val); - return invalid; + llvm::StringRef llvmstr = llvm::dwarf::LanguageString(val); + if (llvmstr.empty()) { + snprintf(invalid, sizeof(invalid), "Unknown DW_LANG constant: 0x%x", val); + return invalid; } - return llvmstr; + return llvmstr.data(); } -const char * -DW_ID_value_to_name (uint32_t val) -{ +const char *DW_ID_value_to_name(uint32_t val) { static char invalid[100]; - const char *llvmstr = llvm::dwarf::CaseString (val); - if (llvmstr == NULL) - { - snprintf (invalid, sizeof (invalid), "Unknown DW_ID constant: 0x%x", val); - return invalid; + llvm::StringRef llvmstr = llvm::dwarf::CaseString(val); + if (llvmstr.empty()) { + snprintf(invalid, sizeof(invalid), "Unknown DW_ID constant: 0x%x", val); + return invalid; } - return llvmstr; + return llvmstr.data(); } -const char * -DW_CC_value_to_name (uint32_t val) -{ +const char *DW_CC_value_to_name(uint32_t val) { static char invalid[100]; - const char *llvmstr = llvm::dwarf::ConventionString (val); - if (llvmstr == NULL) - { - snprintf (invalid, sizeof (invalid), "Unknown DW_CC constant: 0x%x", val); - return invalid; + llvm::StringRef llvmstr = llvm::dwarf::ConventionString(val); + if (llvmstr.empty()) { + snprintf(invalid, sizeof(invalid), "Unknown DW_CC constant: 0x%x", val); + return invalid; } - return llvmstr; + return llvmstr.data(); } -const char * -DW_INL_value_to_name (uint32_t val) -{ +const char *DW_INL_value_to_name(uint32_t val) { static char invalid[100]; - const char *llvmstr = llvm::dwarf::InlineCodeString (val); - if (llvmstr == NULL) - { - snprintf (invalid, sizeof (invalid), "Unknown DW_INL constant: 0x%x", val); - return invalid; + llvm::StringRef llvmstr = llvm::dwarf::InlineCodeString(val); + if (llvmstr.empty()) { + snprintf(invalid, sizeof(invalid), "Unknown DW_INL constant: 0x%x", val); + return invalid; } - return llvmstr; + return llvmstr.data(); } -const char * -DW_ORD_value_to_name (uint32_t val) -{ +const char *DW_ORD_value_to_name(uint32_t val) { static char invalid[100]; - const char *llvmstr = llvm::dwarf::ArrayOrderString (val); - if (llvmstr == NULL) - { - snprintf (invalid, sizeof (invalid), "Unknown DW_ORD constant: 0x%x", val); - return invalid; + llvm::StringRef llvmstr = llvm::dwarf::ArrayOrderString(val); + if (llvmstr.empty()) { + snprintf(invalid, sizeof(invalid), "Unknown DW_ORD constant: 0x%x", val); + return invalid; } - return llvmstr; + return llvmstr.data(); } -const char * -DW_DSC_value_to_name (uint32_t val) -{ +const char *DW_DSC_value_to_name(uint32_t val) { static char invalid[100]; - const char *llvmstr = llvm::dwarf::DiscriminantString (val); - if (llvmstr == NULL) - { - snprintf (invalid, sizeof (invalid), "Unknown DW_DSC constant: 0x%x", val); - return invalid; + llvm::StringRef llvmstr = llvm::dwarf::DiscriminantString(val); + if (llvmstr.empty()) { + snprintf(invalid, sizeof(invalid), "Unknown DW_DSC constant: 0x%x", val); + return invalid; } - return llvmstr; + return llvmstr.data(); } -const char * -DW_LNS_value_to_name (uint32_t val) -{ +const char *DW_LNS_value_to_name(uint32_t val) { static char invalid[100]; - const char *llvmstr = llvm::dwarf::LNStandardString (val); - if (llvmstr == NULL) - { - snprintf (invalid, sizeof (invalid), "Unknown DW_LNS constant: 0x%x", val); - return invalid; + llvm::StringRef llvmstr = llvm::dwarf::LNStandardString(val); + if (llvmstr.empty()) { + snprintf(invalid, sizeof(invalid), "Unknown DW_LNS constant: 0x%x", val); + return invalid; } - return llvmstr; + return llvmstr.data(); } -const char * -DW_LNE_value_to_name (uint32_t val) -{ +const char *DW_LNE_value_to_name(uint32_t val) { static char invalid[100]; - const char *llvmstr = llvm::dwarf::LNExtendedString (val); - if (llvmstr == NULL) - { - snprintf (invalid, sizeof (invalid), "Unknown DW_LNE constant: 0x%x", val); - return invalid; + llvm::StringRef llvmstr = llvm::dwarf::LNExtendedString(val); + if (llvmstr.empty()) { + snprintf(invalid, sizeof(invalid), "Unknown DW_LNE constant: 0x%x", val); + return invalid; } - return llvmstr; + return llvmstr.data(); } -const char * -DW_MACINFO_value_to_name (uint32_t val) -{ +const char *DW_MACINFO_value_to_name(uint32_t val) { static char invalid[100]; - const char *llvmstr = llvm::dwarf::MacinfoString (val); - if (llvmstr == NULL) - { - snprintf (invalid, sizeof (invalid), "Unknown DW_MACINFO constant: 0x%x", val); - return invalid; + llvm::StringRef llvmstr = llvm::dwarf::MacinfoString(val); + if (llvmstr.empty()) { + snprintf(invalid, sizeof(invalid), "Unknown DW_MACINFO constant: 0x%x", + val); + return invalid; } - return llvmstr; + return llvmstr.data(); } -const char * -DW_CFA_value_to_name (uint32_t val) -{ +const char *DW_CFA_value_to_name(uint32_t val) { static char invalid[100]; - const char *llvmstr = llvm::dwarf::CallFrameString (val); - if (llvmstr == NULL) - { - snprintf (invalid, sizeof (invalid), "Unknown DW_CFA constant: 0x%x", val); - return invalid; + llvm::StringRef llvmstr = llvm::dwarf::CallFrameString(val); + if (llvmstr.empty()) { + snprintf(invalid, sizeof(invalid), "Unknown DW_CFA constant: 0x%x", val); + return invalid; } - return llvmstr; + return llvmstr.data(); } -DW_TAG_CategoryEnum -get_tag_category (uint16_t tag) -{ - switch (tag) - { - case DW_TAG_array_type : return TagCategoryType; - case DW_TAG_class_type : return TagCategoryType; - case DW_TAG_entry_point : return TagCategoryProgram; - case DW_TAG_enumeration_type : return TagCategoryType; - case DW_TAG_formal_parameter : return TagCategoryVariable; - case DW_TAG_imported_declaration : return TagCategoryProgram; - case DW_TAG_label : return TagCategoryProgram; - case DW_TAG_lexical_block : return TagCategoryProgram; - case DW_TAG_member : return TagCategoryType; - case DW_TAG_pointer_type : return TagCategoryType; - case DW_TAG_reference_type : return TagCategoryType; - case DW_TAG_compile_unit : return TagCategoryProgram; - case DW_TAG_string_type : return TagCategoryType; - case DW_TAG_structure_type : return TagCategoryType; - case DW_TAG_subroutine_type : return TagCategoryType; - case DW_TAG_typedef : return TagCategoryType; - case DW_TAG_union_type : return TagCategoryType; - case DW_TAG_unspecified_parameters : return TagCategoryVariable; - case DW_TAG_variant : return TagCategoryType; - case DW_TAG_common_block : return TagCategoryProgram; - case DW_TAG_common_inclusion : return TagCategoryProgram; - case DW_TAG_inheritance : return TagCategoryType; - case DW_TAG_inlined_subroutine : return TagCategoryProgram; - case DW_TAG_module : return TagCategoryProgram; - case DW_TAG_ptr_to_member_type : return TagCategoryType; - case DW_TAG_set_type : return TagCategoryType; - case DW_TAG_subrange_type : return TagCategoryType; - case DW_TAG_with_stmt : return TagCategoryProgram; - case DW_TAG_access_declaration : return TagCategoryProgram; - case DW_TAG_base_type : return TagCategoryType; - case DW_TAG_catch_block : return TagCategoryProgram; - case DW_TAG_const_type : return TagCategoryType; - case DW_TAG_constant : return TagCategoryVariable; - case DW_TAG_enumerator : return TagCategoryType; - case DW_TAG_file_type : return TagCategoryType; - case DW_TAG_friend : return TagCategoryType; - case DW_TAG_namelist : return TagCategoryVariable; - case DW_TAG_namelist_item : return TagCategoryVariable; - case DW_TAG_packed_type : return TagCategoryType; - case DW_TAG_subprogram : return TagCategoryProgram; - case DW_TAG_template_type_parameter : return TagCategoryType; - case DW_TAG_template_value_parameter : return TagCategoryType; - case DW_TAG_thrown_type : return TagCategoryType; - case DW_TAG_try_block : return TagCategoryProgram; - case DW_TAG_variant_part : return TagCategoryType; - case DW_TAG_variable : return TagCategoryVariable; - case DW_TAG_volatile_type : return TagCategoryType; - case DW_TAG_dwarf_procedure : return TagCategoryProgram; - case DW_TAG_restrict_type : return TagCategoryType; - case DW_TAG_interface_type : return TagCategoryType; - case DW_TAG_namespace : return TagCategoryProgram; - case DW_TAG_imported_module : return TagCategoryProgram; - case DW_TAG_unspecified_type : return TagCategoryType; - case DW_TAG_partial_unit : return TagCategoryProgram; - case DW_TAG_imported_unit : return TagCategoryProgram; - case DW_TAG_shared_type : return TagCategoryType; - default: break; - } +DW_TAG_CategoryEnum get_tag_category(uint16_t tag) { + switch (tag) { + case DW_TAG_array_type: + return TagCategoryType; + case DW_TAG_class_type: + return TagCategoryType; + case DW_TAG_entry_point: + return TagCategoryProgram; + case DW_TAG_enumeration_type: + return TagCategoryType; + case DW_TAG_formal_parameter: + return TagCategoryVariable; + case DW_TAG_imported_declaration: + return TagCategoryProgram; + case DW_TAG_label: + return TagCategoryProgram; + case DW_TAG_lexical_block: + return TagCategoryProgram; + case DW_TAG_member: + return TagCategoryType; + case DW_TAG_pointer_type: + return TagCategoryType; + case DW_TAG_reference_type: + return TagCategoryType; + case DW_TAG_compile_unit: + return TagCategoryProgram; + case DW_TAG_string_type: + return TagCategoryType; + case DW_TAG_structure_type: + return TagCategoryType; + case DW_TAG_subroutine_type: + return TagCategoryType; + case DW_TAG_typedef: + return TagCategoryType; + case DW_TAG_union_type: + return TagCategoryType; + case DW_TAG_unspecified_parameters: + return TagCategoryVariable; + case DW_TAG_variant: + return TagCategoryType; + case DW_TAG_common_block: + return TagCategoryProgram; + case DW_TAG_common_inclusion: + return TagCategoryProgram; + case DW_TAG_inheritance: + return TagCategoryType; + case DW_TAG_inlined_subroutine: + return TagCategoryProgram; + case DW_TAG_module: + return TagCategoryProgram; + case DW_TAG_ptr_to_member_type: + return TagCategoryType; + case DW_TAG_set_type: + return TagCategoryType; + case DW_TAG_subrange_type: + return TagCategoryType; + case DW_TAG_with_stmt: return TagCategoryProgram; + case DW_TAG_access_declaration: + return TagCategoryProgram; + case DW_TAG_base_type: + return TagCategoryType; + case DW_TAG_catch_block: + return TagCategoryProgram; + case DW_TAG_const_type: + return TagCategoryType; + case DW_TAG_constant: + return TagCategoryVariable; + case DW_TAG_enumerator: + return TagCategoryType; + case DW_TAG_file_type: + return TagCategoryType; + case DW_TAG_friend: + return TagCategoryType; + case DW_TAG_namelist: + return TagCategoryVariable; + case DW_TAG_namelist_item: + return TagCategoryVariable; + case DW_TAG_packed_type: + return TagCategoryType; + case DW_TAG_subprogram: + return TagCategoryProgram; + case DW_TAG_template_type_parameter: + return TagCategoryType; + case DW_TAG_template_value_parameter: + return TagCategoryType; + case DW_TAG_thrown_type: + return TagCategoryType; + case DW_TAG_try_block: + return TagCategoryProgram; + case DW_TAG_variant_part: + return TagCategoryType; + case DW_TAG_variable: + return TagCategoryVariable; + case DW_TAG_volatile_type: + return TagCategoryType; + case DW_TAG_dwarf_procedure: + return TagCategoryProgram; + case DW_TAG_restrict_type: + return TagCategoryType; + case DW_TAG_interface_type: + return TagCategoryType; + case DW_TAG_namespace: + return TagCategoryProgram; + case DW_TAG_imported_module: + return TagCategoryProgram; + case DW_TAG_unspecified_type: + return TagCategoryType; + case DW_TAG_partial_unit: + return TagCategoryProgram; + case DW_TAG_imported_unit: + return TagCategoryProgram; + case DW_TAG_shared_type: + return TagCategoryType; + default: + break; + } + return TagCategoryProgram; } } // namespace lldb_private - diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h index d47e6a350c93..038f5706c060 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h @@ -10,106 +10,104 @@ #ifndef SymbolFileDWARF_DWARFDefines_h_ #define SymbolFileDWARF_DWARFDefines_h_ -#include <stdint.h> #include "lldb/Core/dwarf.h" +#include <stdint.h> namespace lldb_private { -typedef uint32_t DRC_class; // Holds DRC_* class bitfields +typedef uint32_t DRC_class; // Holds DRC_* class bitfields -enum DW_TAG_Category -{ - TagCategoryVariable, - TagCategoryType, - TagCategoryProgram, - kNumTagCategories +enum DW_TAG_Category { + TagCategoryVariable, + TagCategoryType, + TagCategoryProgram, + kNumTagCategories }; typedef enum DW_TAG_Category DW_TAG_CategoryEnum; -const char *DW_TAG_value_to_name (uint32_t val); +const char *DW_TAG_value_to_name(uint32_t val); -DW_TAG_CategoryEnum get_tag_category (uint16_t tag); +DW_TAG_CategoryEnum get_tag_category(uint16_t tag); -const char *DW_CHILDREN_value_to_name (uint8_t val); +const char *DW_CHILDREN_value_to_name(uint8_t val); -const char *DW_AT_value_to_name (uint32_t val); +const char *DW_AT_value_to_name(uint32_t val); -const char *DW_FORM_value_to_name (uint32_t val); +const char *DW_FORM_value_to_name(uint32_t val); -const char *DW_OP_value_to_name (uint32_t val); +const char *DW_OP_value_to_name(uint32_t val); -DRC_class DW_OP_value_to_class (uint32_t val); +DRC_class DW_OP_value_to_class(uint32_t val); -const char *DW_ATE_value_to_name (uint32_t val); +const char *DW_ATE_value_to_name(uint32_t val); -const char *DW_ACCESS_value_to_name (uint32_t val); +const char *DW_ACCESS_value_to_name(uint32_t val); -const char *DW_VIS_value_to_name (uint32_t val); +const char *DW_VIS_value_to_name(uint32_t val); -const char *DW_VIRTUALITY_value_to_name (uint32_t val); +const char *DW_VIRTUALITY_value_to_name(uint32_t val); -const char *DW_LANG_value_to_name (uint32_t val); +const char *DW_LANG_value_to_name(uint32_t val); -const char *DW_ID_value_to_name (uint32_t val); +const char *DW_ID_value_to_name(uint32_t val); -const char *DW_CC_value_to_name (uint32_t val); +const char *DW_CC_value_to_name(uint32_t val); -const char *DW_INL_value_to_name (uint32_t val); +const char *DW_INL_value_to_name(uint32_t val); -const char *DW_ORD_value_to_name (uint32_t val); +const char *DW_ORD_value_to_name(uint32_t val); -const char *DW_DSC_value_to_name (uint32_t val); +const char *DW_DSC_value_to_name(uint32_t val); -const char *DW_LNS_value_to_name (uint32_t val); +const char *DW_LNS_value_to_name(uint32_t val); -const char *DW_LNE_value_to_name (uint32_t val); +const char *DW_LNE_value_to_name(uint32_t val); -const char *DW_MACINFO_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); -const char *DW_GNU_EH_PE_value_to_name (uint32_t val); +const char *DW_GNU_EH_PE_value_to_name(uint32_t val); /* These DRC are entirely our own construction, although they are derived from various comments in the DWARF standard. Most of these are not useful to the parser, but the DW_AT and DW_FORM classes should prove to be usable in some fashion. */ -#define DRC_0x65 0x1 -#define DRC_ADDRESS 0x2 -#define DRC_BLOCK 0x4 -#define DRC_CONSTANT 0x8 -#define DRC_DWARFv3 0x10 -#define DRC_FLAG 0x20 -#define DRC_INDIRECT_SPECIAL 0x40 -#define DRC_LINEPTR 0x80 -#define DRC_LOCEXPR 0x100 -#define DRC_LOCLISTPTR 0x200 -#define DRC_MACPTR 0x400 -#define DRC_ONEOPERAND 0x800 -#define DRC_OPERANDONE_1BYTE_DELTA 0x1000 -#define DRC_OPERANDONE_2BYTE_DELTA 0x2000 -#define DRC_OPERANDONE_4BYTE_DELTA 0x4000 -#define DRC_OPERANDONE_ADDRESS 0x8000 -#define DRC_OPERANDONE_BLOCK 0x10000 -#define DRC_OPERANDONE_SLEB128_OFFSET 0x20000 -#define DRC_OPERANDONE_ULEB128_OFFSET 0x40000 -#define DRC_OPERANDONE_ULEB128_REGISTER 0x80000 -#define DRC_OPERANDTWO_BLOCK 0x100000 -#define DRC_OPERANDTWO_SLEB128_OFFSET 0x200000 -#define DRC_OPERANDTWO_ULEB128_OFFSET 0x400000 -#define DRC_OPERANDTWO_ULEB128_REGISTER 0x800000 -#define DRC_OPERNADONE_ULEB128_REGISTER 0x1000000 -#define DRC_RANGELISTPTR 0x2000000 -#define DRC_REFERENCE 0x4000000 -#define DRC_STRING 0x8000000 -#define DRC_TWOOPERANDS 0x10000000 -#define DRC_VENDOR_GNU 0x20000000 -#define DRC_VENDOR_MIPS 0x40000000 -#define DRC_ZEROOPERANDS 0x80000000 +#define DRC_0x65 0x1 +#define DRC_ADDRESS 0x2 +#define DRC_BLOCK 0x4 +#define DRC_CONSTANT 0x8 +#define DRC_DWARFv3 0x10 +#define DRC_FLAG 0x20 +#define DRC_INDIRECT_SPECIAL 0x40 +#define DRC_LINEPTR 0x80 +#define DRC_LOCEXPR 0x100 +#define DRC_LOCLISTPTR 0x200 +#define DRC_MACPTR 0x400 +#define DRC_ONEOPERAND 0x800 +#define DRC_OPERANDONE_1BYTE_DELTA 0x1000 +#define DRC_OPERANDONE_2BYTE_DELTA 0x2000 +#define DRC_OPERANDONE_4BYTE_DELTA 0x4000 +#define DRC_OPERANDONE_ADDRESS 0x8000 +#define DRC_OPERANDONE_BLOCK 0x10000 +#define DRC_OPERANDONE_SLEB128_OFFSET 0x20000 +#define DRC_OPERANDONE_ULEB128_OFFSET 0x40000 +#define DRC_OPERANDONE_ULEB128_REGISTER 0x80000 +#define DRC_OPERANDTWO_BLOCK 0x100000 +#define DRC_OPERANDTWO_SLEB128_OFFSET 0x200000 +#define DRC_OPERANDTWO_ULEB128_OFFSET 0x400000 +#define DRC_OPERANDTWO_ULEB128_REGISTER 0x800000 +#define DRC_OPERNADONE_ULEB128_REGISTER 0x1000000 +#define DRC_RANGELISTPTR 0x2000000 +#define DRC_REFERENCE 0x4000000 +#define DRC_STRING 0x8000000 +#define DRC_TWOOPERANDS 0x10000000 +#define DRC_VENDOR_GNU 0x20000000 +#define DRC_VENDOR_MIPS 0x40000000 +#define DRC_ZEROOPERANDS 0x80000000 } // namespace lldb_private - -#endif // SymbolFileDWARF_DWARFDefines_h_ +#endif // SymbolFileDWARF_DWARFDefines_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp index addc14858461..ad18c56b3300 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp @@ -9,19 +9,17 @@ #include <assert.h> -#include "lldb/Core/dwarf.h" #include "lldb/Core/Stream.h" +#include "lldb/Core/dwarf.h" -#include "DWARFFormValue.h" #include "DWARFCompileUnit.h" +#include "DWARFFormValue.h" class DWARFCompileUnit; using namespace lldb_private; - -static uint8_t g_form_sizes_addr4[] = -{ +static uint8_t g_form_sizes_addr4[] = { 0, // 0x00 unused 4, // 0x01 DW_FORM_addr 0, // 0x02 unused @@ -38,7 +36,8 @@ static uint8_t g_form_sizes_addr4[] = 0, // 0x0d DW_FORM_sdata 4, // 0x0e DW_FORM_strp 0, // 0x0f DW_FORM_udata - 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for DWARF32, 8 bytes for DWARF32 in DWARF 3 and later + 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for + // DWARF32, 8 bytes for DWARF32 in DWARF 3 and later 1, // 0x11 DW_FORM_ref1 2, // 0x12 DW_FORM_ref2 4, // 0x13 DW_FORM_ref4 @@ -58,9 +57,7 @@ static uint8_t g_form_sizes_addr4[] = }; -static uint8_t -g_form_sizes_addr8[] = -{ +static uint8_t g_form_sizes_addr8[] = { 0, // 0x00 unused 8, // 0x01 DW_FORM_addr 0, // 0x02 unused @@ -77,7 +74,8 @@ g_form_sizes_addr8[] = 0, // 0x0d DW_FORM_sdata 4, // 0x0e DW_FORM_strp 0, // 0x0f DW_FORM_udata - 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for DWARF32, 8 bytes for DWARF32 in DWARF 3 and later + 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for + // DWARF32, 8 bytes for DWARF32 in DWARF 3 and later 1, // 0x11 DW_FORM_ref1 2, // 0x12 DW_FORM_ref2 4, // 0x13 DW_FORM_ref4 @@ -98,9 +96,7 @@ g_form_sizes_addr8[] = // Difference with g_form_sizes_addr8: // DW_FORM_strp and DW_FORM_sec_offset are 8 instead of 4 -static uint8_t -g_form_sizes_addr8_dwarf64[] = -{ +static uint8_t g_form_sizes_addr8_dwarf64[] = { 0, // 0x00 unused 8, // 0x01 DW_FORM_addr 0, // 0x02 unused @@ -117,7 +113,8 @@ g_form_sizes_addr8_dwarf64[] = 0, // 0x0d DW_FORM_sdata 8, // 0x0e DW_FORM_strp 0, // 0x0f DW_FORM_udata - 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for DWARF32, 8 bytes for DWARF32 in DWARF 3 and later + 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for + // DWARF32, 8 bytes for DWARF32 in DWARF 3 and later 1, // 0x11 DW_FORM_ref1 2, // 0x12 DW_FORM_ref2 4, // 0x13 DW_FORM_ref4 @@ -137,552 +134,612 @@ g_form_sizes_addr8_dwarf64[] = }; DWARFFormValue::FixedFormSizes -DWARFFormValue::GetFixedFormSizesForAddressSize (uint8_t addr_size, bool is_dwarf64) -{ - if (!is_dwarf64) { - switch (addr_size) - { - case 4: return FixedFormSizes(g_form_sizes_addr4, sizeof(g_form_sizes_addr4)); - case 8: return FixedFormSizes(g_form_sizes_addr8, sizeof(g_form_sizes_addr8)); - } - } else { - if (addr_size == 8) - return FixedFormSizes(g_form_sizes_addr8_dwarf64, sizeof(g_form_sizes_addr8_dwarf64)); - // is_dwarf64 && addr_size == 4 : no provider does this. +DWARFFormValue::GetFixedFormSizesForAddressSize(uint8_t addr_size, + bool is_dwarf64) { + if (!is_dwarf64) { + switch (addr_size) { + case 4: + return FixedFormSizes(g_form_sizes_addr4, sizeof(g_form_sizes_addr4)); + case 8: + return FixedFormSizes(g_form_sizes_addr8, sizeof(g_form_sizes_addr8)); } - return FixedFormSizes(); -} - -DWARFFormValue::DWARFFormValue() : - m_cu (NULL), - m_form(0), - m_value() -{ -} - -DWARFFormValue::DWARFFormValue(const DWARFCompileUnit* cu, dw_form_t form) : - m_cu (cu), - m_form(form), - m_value() -{ -} - -void -DWARFFormValue::Clear() -{ - m_cu = nullptr; - m_form = 0; - memset(&m_value, 0, sizeof(m_value)); + } else { + if (addr_size == 8) + return FixedFormSizes(g_form_sizes_addr8_dwarf64, + sizeof(g_form_sizes_addr8_dwarf64)); + // is_dwarf64 && addr_size == 4 : no provider does this. + } + return FixedFormSizes(); } -bool -DWARFFormValue::ExtractValue(const DWARFDataExtractor& data, lldb::offset_t* offset_ptr) -{ - bool indirect = false; - bool is_block = false; - m_value.data = NULL; - uint8_t ref_addr_size; - // Read the value for the form into value and follow and DW_FORM_indirect instances we run into - do - { - indirect = false; - switch (m_form) - { - case DW_FORM_addr: assert(m_cu); - m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::GetAddressByteSize(m_cu)); break; - case DW_FORM_block2: m_value.value.uval = data.GetU16(offset_ptr); is_block = true; break; - case DW_FORM_block4: 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); 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); break; - case DW_FORM_sdata: m_value.value.sval = data.GetSLEB128(offset_ptr); break; - case DW_FORM_strp: assert(m_cu); - m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::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_ref1: m_value.value.uval = data.GetU8(offset_ptr); break; - case DW_FORM_ref2: m_value.value.uval = data.GetU16(offset_ptr); break; - case DW_FORM_ref4: m_value.value.uval = data.GetU32(offset_ptr); break; - case DW_FORM_ref8: m_value.value.uval = data.GetU64(offset_ptr); break; - case DW_FORM_ref_udata: m_value.value.uval = data.GetULEB128(offset_ptr); 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, DWARFCompileUnit::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); - - if (is_block) - { - m_value.data = data.PeekData(*offset_ptr, m_value.value.uval); - if (m_value.data != NULL) - { - *offset_ptr += m_value.value.uval; - } - } +DWARFFormValue::DWARFFormValue() : m_cu(NULL), m_form(0), m_value() {} - return true; -} +DWARFFormValue::DWARFFormValue(const DWARFCompileUnit *cu, dw_form_t form) + : m_cu(cu), m_form(form), m_value() {} -bool -DWARFFormValue::SkipValue(const DWARFDataExtractor& debug_info_data, lldb::offset_t *offset_ptr) const -{ - return DWARFFormValue::SkipValue(m_form, debug_info_data, offset_ptr, m_cu); +void DWARFFormValue::Clear() { + m_cu = nullptr; + m_form = 0; + memset(&m_value, 0, sizeof(m_value)); } -bool -DWARFFormValue::SkipValue(dw_form_t form, const DWARFDataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu) -{ - uint8_t ref_addr_size; - switch (form) - { - // Blocks if inlined data that have a length field and the data bytes - // inlined in the .debug_info - case DW_FORM_exprloc: - case DW_FORM_block: { dw_uleb128_t size = debug_info_data.GetULEB128(offset_ptr); *offset_ptr += size; } return true; - case DW_FORM_block1: { dw_uleb128_t size = debug_info_data.GetU8(offset_ptr); *offset_ptr += size; } return true; - case DW_FORM_block2: { dw_uleb128_t size = debug_info_data.GetU16(offset_ptr); *offset_ptr += size; } return true; - case DW_FORM_block4: { dw_uleb128_t size = debug_info_data.GetU32(offset_ptr); *offset_ptr += size; } return true; - - // Inlined NULL terminated C-strings - case DW_FORM_string: - debug_info_data.GetCStr(offset_ptr); - return true; - - // Compile unit address sized values +bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data, + lldb::offset_t *offset_ptr) { + bool indirect = false; + bool is_block = false; + m_value.data = NULL; + uint8_t ref_addr_size; + // Read the value for the form into value and follow and DW_FORM_indirect + // instances we run into + do { + indirect = false; + switch (m_form) { case DW_FORM_addr: - *offset_ptr += DWARFCompileUnit::GetAddressByteSize(cu); - return true; - - case DW_FORM_ref_addr: - ref_addr_size = 4; - assert (cu); // CU must be valid for DW_FORM_ref_addr objects or we will get this wrong - if (cu->GetVersion() <= 2) - ref_addr_size = cu->GetAddressByteSize(); - else - ref_addr_size = cu->IsDWARF64() ? 8 : 4; - *offset_ptr += ref_addr_size; - return true; - - // 0 bytes values (implied from DW_FORM) - case DW_FORM_flag_present: - return true; - - // 1 byte values + assert(m_cu); + m_value.value.uval = data.GetMaxU64( + offset_ptr, DWARFCompileUnit::GetAddressByteSize(m_cu)); + break; + case DW_FORM_block2: + m_value.value.uval = data.GetU16(offset_ptr); + is_block = true; + break; + case DW_FORM_block4: + 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); + 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); + break; + case DW_FORM_sdata: + m_value.value.sval = data.GetSLEB128(offset_ptr); + break; + case DW_FORM_strp: + assert(m_cu); + m_value.value.uval = + data.GetMaxU64(offset_ptr, DWARFCompileUnit::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_ref1: - *offset_ptr += 1; - return true; - - // 2 byte values - case DW_FORM_data2: + m_value.value.uval = data.GetU8(offset_ptr); + break; case DW_FORM_ref2: - *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; - - // 4 byte values - case DW_FORM_data4: + m_value.value.uval = data.GetU16(offset_ptr); + break; case DW_FORM_ref4: - *offset_ptr += 4; - return true; - - // 8 byte values - case DW_FORM_data8: + m_value.value.uval = data.GetU32(offset_ptr); + break; case DW_FORM_ref8: - case DW_FORM_ref_sig8: - *offset_ptr += 8; - return true; - - // signed or unsigned LEB 128 values - case DW_FORM_sdata: - case DW_FORM_udata: + m_value.value.uval = data.GetU64(offset_ptr); + break; 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; - + m_value.value.uval = data.GetULEB128(offset_ptr); + break; case DW_FORM_indirect: - { - dw_form_t indirect_form = debug_info_data.GetULEB128(offset_ptr); - return DWARFFormValue::SkipValue (indirect_form, - debug_info_data, - offset_ptr, - cu); - } + 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, DWARFCompileUnit::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: - break; + return false; + break; } - return false; -} + } while (indirect); + if (is_block) { + m_value.data = data.PeekData(*offset_ptr, m_value.value.uval); + if (m_value.data != NULL) { + *offset_ptr += m_value.value.uval; + } + } -void -DWARFFormValue::Dump(Stream &s) const -{ - uint64_t uvalue = Unsigned(); - bool cu_relative_offset = false; + return true; +} - bool verbose = s.GetVerbose(); +bool DWARFFormValue::SkipValue(const DWARFDataExtractor &debug_info_data, + lldb::offset_t *offset_ptr) const { + return DWARFFormValue::SkipValue(m_form, debug_info_data, offset_ptr, m_cu); +} - switch (m_form) - { - case DW_FORM_addr: s.Address(uvalue, sizeof (uint64_t)); break; - case DW_FORM_flag: - case DW_FORM_data1: s.PutHex8(uvalue); break; - case DW_FORM_data2: s.PutHex16(uvalue); break; - case DW_FORM_sec_offset: - case DW_FORM_data4: s.PutHex32(uvalue); break; - case DW_FORM_ref_sig8: - case DW_FORM_data8: s.PutHex64(uvalue); break; - case DW_FORM_string: s.QuotedCString(AsCString()); break; - case DW_FORM_exprloc: - case DW_FORM_block: - case DW_FORM_block1: - case DW_FORM_block2: - case DW_FORM_block4: - if (uvalue > 0) - { - switch (m_form) - { - case DW_FORM_exprloc: - case DW_FORM_block: s.Printf("<0x%" PRIx64 "> ", uvalue); break; - case DW_FORM_block1: s.Printf("<0x%2.2x> ", (uint8_t)uvalue); break; - case DW_FORM_block2: s.Printf("<0x%4.4x> ", (uint16_t)uvalue); break; - case DW_FORM_block4: s.Printf("<0x%8.8x> ", (uint32_t)uvalue); break; - default: break; - } - - const uint8_t* data_ptr = m_value.data; - if (data_ptr) - { - const uint8_t* end_data_ptr = data_ptr + uvalue; // uvalue contains size of block - while (data_ptr < end_data_ptr) - { - s.Printf("%2.2x ", *data_ptr); - ++data_ptr; - } - } - else - s.PutCString("NULL"); - } - break; +bool DWARFFormValue::SkipValue(dw_form_t form, + const DWARFDataExtractor &debug_info_data, + lldb::offset_t *offset_ptr, + const DWARFCompileUnit *cu) { + uint8_t ref_addr_size; + switch (form) { + // Blocks if inlined data that have a length field and the data bytes + // inlined in the .debug_info + case DW_FORM_exprloc: + case DW_FORM_block: { + dw_uleb128_t size = debug_info_data.GetULEB128(offset_ptr); + *offset_ptr += size; + } + return true; + case DW_FORM_block1: { + dw_uleb128_t size = debug_info_data.GetU8(offset_ptr); + *offset_ptr += size; + } + return true; + case DW_FORM_block2: { + dw_uleb128_t size = debug_info_data.GetU16(offset_ptr); + *offset_ptr += size; + } + return true; + case DW_FORM_block4: { + dw_uleb128_t size = debug_info_data.GetU32(offset_ptr); + *offset_ptr += size; + } + return true; - case DW_FORM_sdata: s.PutSLEB128(uvalue); break; - case DW_FORM_udata: s.PutULEB128(uvalue); break; - case DW_FORM_strp: - { - const char* dbg_str = AsCString(); - if (dbg_str) - { - if (verbose) - s.Printf(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue); - s.QuotedCString(dbg_str); - } - else - { - s.PutHex32(uvalue); - } - } - break; + // Inlined NULL terminated C-strings + case DW_FORM_string: + debug_info_data.GetCStr(offset_ptr); + return true; - case DW_FORM_ref_addr: - { - assert (m_cu); // CU must be valid for DW_FORM_ref_addr objects or we will get this wrong - if (m_cu->GetVersion() <= 2) - s.Address(uvalue, sizeof (uint64_t) * 2); - else - s.Address(uvalue, 4 * 2);// 4 for DWARF32, 8 for DWARF64, but we don't support DWARF64 yet - break; - } - case DW_FORM_ref1: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%2.2x", (uint8_t)uvalue); break; - case DW_FORM_ref2: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%4.4x", (uint16_t)uvalue); break; - case DW_FORM_ref4: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%4.4x", (uint32_t)uvalue); break; - case DW_FORM_ref8: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%8.8" PRIx64, uvalue); break; - case DW_FORM_ref_udata: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%" PRIx64, uvalue); break; - - // All DW_FORM_indirect attributes should be resolved prior to calling this function - case DW_FORM_indirect: s.PutCString("DW_FORM_indirect"); break; - case DW_FORM_flag_present: break; - default: - s.Printf("DW_FORM(0x%4.4x)", m_form); - break; - } + // Compile unit address sized values + case DW_FORM_addr: + *offset_ptr += DWARFCompileUnit::GetAddressByteSize(cu); + return true; - if (cu_relative_offset) - { - assert (m_cu); // CU must be valid for DW_FORM_ref forms that are compile unit relative or we will get this wrong - if (verbose) - s.PutCString(" => "); + case DW_FORM_ref_addr: + ref_addr_size = 4; + assert(cu); // CU must be valid for DW_FORM_ref_addr objects or we will get + // this wrong + if (cu->GetVersion() <= 2) + ref_addr_size = cu->GetAddressByteSize(); + else + ref_addr_size = cu->IsDWARF64() ? 8 : 4; + *offset_ptr += ref_addr_size; + return true; - s.Printf("{0x%8.8" PRIx64 "}", uvalue + m_cu->GetOffset()); - } -} + // 0 bytes values (implied from DW_FORM) + case DW_FORM_flag_present: + return true; -const char* -DWARFFormValue::AsCString() const -{ - SymbolFileDWARF* symbol_file = m_cu->GetSymbolFileDWARF(); + // 1 byte values + case DW_FORM_data1: + case DW_FORM_flag: + case DW_FORM_ref1: + *offset_ptr += 1; + return true; - if (m_form == DW_FORM_string) - { - return m_value.value.cstr; - } - else if (m_form == DW_FORM_strp) - { - if (!symbol_file) - return nullptr; + // 2 byte values + case DW_FORM_data2: + case DW_FORM_ref2: + *offset_ptr += 2; + return true; - return symbol_file->get_debug_str_data().PeekCStr(m_value.value.uval); - } - else if (m_form == DW_FORM_GNU_str_index) - { - if (!symbol_file) - return nullptr; - - uint32_t index_size = m_cu->IsDWARF64() ? 8 : 4; - lldb::offset_t offset = m_value.value.uval * index_size; - dw_offset_t str_offset = symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset, index_size); - return symbol_file->get_debug_str_data().PeekCStr(str_offset); - } - return nullptr; -} + // 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; -dw_addr_t -DWARFFormValue::Address() const -{ - SymbolFileDWARF* symbol_file = m_cu->GetSymbolFileDWARF(); + // 4 byte values + case DW_FORM_data4: + case DW_FORM_ref4: + *offset_ptr += 4; + return true; - if (m_form == DW_FORM_addr) - return Unsigned(); + // 8 byte values + case DW_FORM_data8: + case DW_FORM_ref8: + case DW_FORM_ref_sig8: + *offset_ptr += 8; + return true; - assert(m_cu); - assert(m_form == DW_FORM_GNU_addr_index); + // 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; - if (!symbol_file) - return 0; + case DW_FORM_indirect: { + dw_form_t indirect_form = debug_info_data.GetULEB128(offset_ptr); + return DWARFFormValue::SkipValue(indirect_form, debug_info_data, offset_ptr, + cu); + } - uint32_t index_size = m_cu->GetAddressByteSize(); - dw_offset_t addr_base = m_cu->GetAddrBase(); - lldb::offset_t offset = addr_base + m_value.value.uval * index_size; - return symbol_file->get_debug_addr_data().GetMaxU64(&offset, index_size); + default: + break; + } + return false; } -uint64_t -DWARFFormValue::Reference() const -{ - uint64_t die_offset = 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: - 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(); +void DWARFFormValue::Dump(Stream &s) const { + uint64_t uvalue = Unsigned(); + bool cu_relative_offset = false; + + bool verbose = s.GetVerbose(); + + switch (m_form) { + case DW_FORM_addr: + s.Address(uvalue, sizeof(uint64_t)); + break; + case DW_FORM_flag: + case DW_FORM_data1: + s.PutHex8(uvalue); + break; + case DW_FORM_data2: + s.PutHex16(uvalue); + break; + case DW_FORM_sec_offset: + case DW_FORM_data4: + s.PutHex32(uvalue); + break; + case DW_FORM_ref_sig8: + case DW_FORM_data8: + s.PutHex64(uvalue); + break; + case DW_FORM_string: + s.QuotedCString(AsCString()); + break; + case DW_FORM_exprloc: + case DW_FORM_block: + case DW_FORM_block1: + case DW_FORM_block2: + case DW_FORM_block4: + if (uvalue > 0) { + switch (m_form) { + case DW_FORM_exprloc: + case DW_FORM_block: + s.Printf("<0x%" PRIx64 "> ", uvalue); break; - - default: + case DW_FORM_block1: + s.Printf("<0x%2.2x> ", (uint8_t)uvalue); + break; + case DW_FORM_block2: + s.Printf("<0x%4.4x> ", (uint16_t)uvalue); break; + case DW_FORM_block4: + s.Printf("<0x%8.8x> ", (uint32_t)uvalue); + break; + default: + break; + } + + const uint8_t *data_ptr = m_value.data; + if (data_ptr) { + const uint8_t *end_data_ptr = + data_ptr + uvalue; // uvalue contains size of block + while (data_ptr < end_data_ptr) { + s.Printf("%2.2x ", *data_ptr); + ++data_ptr; + } + } else + s.PutCString("NULL"); } - - return die_offset; -} - -uint64_t -DWARFFormValue::Reference (dw_offset_t base_offset) const -{ - uint64_t die_offset = 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; - - default: - break; + break; + + case DW_FORM_sdata: + s.PutSLEB128(uvalue); + break; + case DW_FORM_udata: + s.PutULEB128(uvalue); + break; + case DW_FORM_strp: { + const char *dbg_str = AsCString(); + if (dbg_str) { + if (verbose) + s.Printf(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue); + s.QuotedCString(dbg_str); + } else { + s.PutHex32(uvalue); } - - return die_offset; + } break; + + case DW_FORM_ref_addr: { + assert(m_cu); // CU must be valid for DW_FORM_ref_addr objects or we will + // get this wrong + if (m_cu->GetVersion() <= 2) + s.Address(uvalue, sizeof(uint64_t) * 2); + else + s.Address(uvalue, 4 * 2); // 4 for DWARF32, 8 for DWARF64, but we don't + // support DWARF64 yet + break; + } + case DW_FORM_ref1: + cu_relative_offset = true; + if (verbose) + s.Printf("cu + 0x%2.2x", (uint8_t)uvalue); + break; + case DW_FORM_ref2: + cu_relative_offset = true; + if (verbose) + s.Printf("cu + 0x%4.4x", (uint16_t)uvalue); + break; + case DW_FORM_ref4: + cu_relative_offset = true; + if (verbose) + s.Printf("cu + 0x%4.4x", (uint32_t)uvalue); + break; + case DW_FORM_ref8: + cu_relative_offset = true; + if (verbose) + s.Printf("cu + 0x%8.8" PRIx64, uvalue); + break; + case DW_FORM_ref_udata: + cu_relative_offset = true; + if (verbose) + s.Printf("cu + 0x%" PRIx64, uvalue); + break; + + // All DW_FORM_indirect attributes should be resolved prior to calling this + // function + case DW_FORM_indirect: + s.PutCString("DW_FORM_indirect"); + break; + case DW_FORM_flag_present: + break; + default: + s.Printf("DW_FORM(0x%4.4x)", m_form); + break; + } + + if (cu_relative_offset) { + assert(m_cu); // CU must be valid for DW_FORM_ref forms that are compile + // unit relative or we will get this wrong + if (verbose) + s.PutCString(" => "); + + s.Printf("{0x%8.8" PRIx64 "}", uvalue + m_cu->GetOffset()); + } } +const char *DWARFFormValue::AsCString() const { + SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF(); + + if (m_form == DW_FORM_string) { + return m_value.value.cstr; + } else if (m_form == DW_FORM_strp) { + if (!symbol_file) + return nullptr; -const uint8_t* -DWARFFormValue::BlockData() const -{ - return m_value.data; + return symbol_file->get_debug_str_data().PeekCStr(m_value.value.uval); + } else if (m_form == DW_FORM_GNU_str_index) { + if (!symbol_file) + return nullptr; + + uint32_t index_size = m_cu->IsDWARF64() ? 8 : 4; + lldb::offset_t offset = m_value.value.uval * index_size; + dw_offset_t str_offset = + symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset, + index_size); + return symbol_file->get_debug_str_data().PeekCStr(str_offset); + } + return nullptr; } +dw_addr_t DWARFFormValue::Address() const { + SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF(); -bool -DWARFFormValue::IsBlockForm(const dw_form_t form) -{ - switch (form) - { - case DW_FORM_block: - case DW_FORM_block1: - case DW_FORM_block2: - case DW_FORM_block4: - return true; - } - return false; -} + if (m_form == DW_FORM_addr) + return Unsigned(); -bool -DWARFFormValue::IsDataForm(const dw_form_t form) -{ - switch (form) - { - case DW_FORM_sdata: - case DW_FORM_udata: - case DW_FORM_data1: - case DW_FORM_data2: - case DW_FORM_data4: - case DW_FORM_data8: - return true; - } - return false; -} + assert(m_cu); + assert(m_form == DW_FORM_GNU_addr_index); -int -DWARFFormValue::Compare (const DWARFFormValue& a_value, - const DWARFFormValue& b_value) -{ - dw_form_t a_form = a_value.Form(); - dw_form_t b_form = b_value.Form(); - if (a_form < b_form) - return -1; - if (a_form > b_form) - return 1; - switch (a_form) - { - case DW_FORM_addr: - case DW_FORM_flag: - case DW_FORM_data1: - case DW_FORM_data2: - case DW_FORM_data4: - case DW_FORM_data8: - case DW_FORM_udata: - case DW_FORM_ref_addr: - case DW_FORM_sec_offset: - case DW_FORM_flag_present: - case DW_FORM_ref_sig8: - case DW_FORM_GNU_addr_index: - { - uint64_t a = a_value.Unsigned(); - uint64_t b = b_value.Unsigned(); - if (a < b) - return -1; - if (a > b) - return 1; - return 0; - } + if (!symbol_file) + return 0; - case DW_FORM_sdata: - { - int64_t a = a_value.Signed(); - int64_t b = b_value.Signed(); - if (a < b) - return -1; - if (a > b) - return 1; - return 0; - } + uint32_t index_size = m_cu->GetAddressByteSize(); + dw_offset_t addr_base = m_cu->GetAddrBase(); + lldb::offset_t offset = addr_base + m_value.value.uval * index_size; + return symbol_file->get_debug_addr_data().GetMaxU64(&offset, index_size); +} - case DW_FORM_string: - case DW_FORM_strp: - case DW_FORM_GNU_str_index: - { - const char *a_string = a_value.AsCString(); - const char *b_string = b_value.AsCString(); - if (a_string == b_string) - return 0; - else if (a_string && b_string) - return strcmp(a_string, b_string); - else if (a_string == NULL) - return -1; // A string is NULL, and B is valid - else - return 1; // A string valid, and B is NULL - } +uint64_t DWARFFormValue::Reference() const { + uint64_t die_offset = 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: + 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; + + default: + break; + } + + return die_offset; +} +uint64_t DWARFFormValue::Reference(dw_offset_t base_offset) const { + uint64_t die_offset = 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; + + default: + break; + } + + return die_offset; +} - case DW_FORM_block: - case DW_FORM_block1: - case DW_FORM_block2: - case DW_FORM_block4: - case DW_FORM_exprloc: - { - uint64_t a_len = a_value.Unsigned(); - uint64_t b_len = b_value.Unsigned(); - if (a_len < b_len) - return -1; - if (a_len > b_len) - return 1; - // The block lengths are the same - return memcmp(a_value.BlockData(), b_value.BlockData(), a_value.Unsigned()); - } - break; +const uint8_t *DWARFFormValue::BlockData() const { return m_value.data; } - case DW_FORM_ref1: - case DW_FORM_ref2: - case DW_FORM_ref4: - case DW_FORM_ref8: - case DW_FORM_ref_udata: - { - uint64_t a = a_value.Reference(); - uint64_t b = b_value.Reference(); - if (a < b) - return -1; - if (a > b) - return 1; - return 0; - } +bool DWARFFormValue::IsBlockForm(const dw_form_t form) { + switch (form) { + case DW_FORM_exprloc: + case DW_FORM_block: + case DW_FORM_block1: + case DW_FORM_block2: + case DW_FORM_block4: + return true; + } + return false; +} - case DW_FORM_indirect: - assert(!"This shouldn't happen after the form has been extracted..."); - break; +bool DWARFFormValue::IsDataForm(const dw_form_t form) { + switch (form) { + case DW_FORM_sdata: + case DW_FORM_udata: + case DW_FORM_data1: + case DW_FORM_data2: + case DW_FORM_data4: + case DW_FORM_data8: + return true; + } + return false; +} - default: - assert(!"Unhandled DW_FORM"); - break; - } +int DWARFFormValue::Compare(const DWARFFormValue &a_value, + const DWARFFormValue &b_value) { + dw_form_t a_form = a_value.Form(); + dw_form_t b_form = b_value.Form(); + if (a_form < b_form) return -1; + if (a_form > b_form) + return 1; + switch (a_form) { + case DW_FORM_addr: + case DW_FORM_flag: + case DW_FORM_data1: + case DW_FORM_data2: + case DW_FORM_data4: + case DW_FORM_data8: + case DW_FORM_udata: + case DW_FORM_ref_addr: + case DW_FORM_sec_offset: + case DW_FORM_flag_present: + case DW_FORM_ref_sig8: + case DW_FORM_GNU_addr_index: { + uint64_t a = a_value.Unsigned(); + uint64_t b = b_value.Unsigned(); + if (a < b) + return -1; + if (a > b) + return 1; + return 0; + } + + case DW_FORM_sdata: { + int64_t a = a_value.Signed(); + int64_t b = b_value.Signed(); + if (a < b) + return -1; + if (a > b) + return 1; + return 0; + } + + case DW_FORM_string: + case DW_FORM_strp: + case DW_FORM_GNU_str_index: { + const char *a_string = a_value.AsCString(); + const char *b_string = b_value.AsCString(); + if (a_string == b_string) + return 0; + else if (a_string && b_string) + return strcmp(a_string, b_string); + else if (a_string == NULL) + return -1; // A string is NULL, and B is valid + else + return 1; // A string valid, and B is NULL + } + + case DW_FORM_block: + case DW_FORM_block1: + case DW_FORM_block2: + case DW_FORM_block4: + case DW_FORM_exprloc: { + uint64_t a_len = a_value.Unsigned(); + uint64_t b_len = b_value.Unsigned(); + if (a_len < b_len) + return -1; + if (a_len > b_len) + return 1; + // The block lengths are the same + return memcmp(a_value.BlockData(), b_value.BlockData(), a_value.Unsigned()); + } break; + + case DW_FORM_ref1: + case DW_FORM_ref2: + case DW_FORM_ref4: + case DW_FORM_ref8: + case DW_FORM_ref_udata: { + uint64_t a = a_value.Reference(); + uint64_t b = b_value.Reference(); + if (a < b) + return -1; + if (a > b) + return 1; + return 0; + } + + case DW_FORM_indirect: + assert(!"This shouldn't happen after the form has been extracted..."); + break; + + default: + assert(!"Unhandled DW_FORM"); + break; + } + return -1; } - diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h index 07bd038d9486..8d6af3d65b33 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h @@ -10,103 +10,87 @@ #ifndef SymbolFileDWARF_DWARFFormValue_h_ #define SymbolFileDWARF_DWARFFormValue_h_ -#include <stddef.h> // for NULL #include "DWARFDataExtractor.h" +#include <stddef.h> // for NULL class DWARFCompileUnit; -class DWARFFormValue -{ +class DWARFFormValue { public: - typedef struct ValueTypeTag - { - ValueTypeTag() : - value(), - data(NULL) - { - value.uval = 0; - } + typedef struct ValueTypeTag { + ValueTypeTag() : value(), data(NULL) { value.uval = 0; } + + union { + uint64_t uval; + int64_t sval; + const char *cstr; + } value; + const uint8_t *data; + } ValueType; - union - { - uint64_t uval; - int64_t sval; - const char* cstr; - } value; - const uint8_t* data; - } ValueType; - - class FixedFormSizes - { - public: - FixedFormSizes() : - m_fix_sizes(nullptr), m_size(0) - {} + class FixedFormSizes { + public: + FixedFormSizes() : m_fix_sizes(nullptr), m_size(0) {} - FixedFormSizes(const uint8_t* fix_sizes, size_t size) : - m_fix_sizes(fix_sizes), m_size(size) - {} + FixedFormSizes(const uint8_t *fix_sizes, size_t size) + : m_fix_sizes(fix_sizes), m_size(size) {} - uint8_t - GetSize(uint32_t index) const - { - return index < m_size ? m_fix_sizes[index] : 0; - } + uint8_t GetSize(uint32_t index) const { + return index < m_size ? m_fix_sizes[index] : 0; + } - bool - Empty() const - { - return m_size == 0; - } + bool Empty() const { return m_size == 0; } - private: - const uint8_t* m_fix_sizes; - size_t m_size; - }; + private: + const uint8_t *m_fix_sizes; + size_t m_size; + }; - enum - { - eValueTypeInvalid = 0, - eValueTypeUnsigned, - eValueTypeSigned, - eValueTypeCStr, - eValueTypeBlock - }; + enum { + eValueTypeInvalid = 0, + eValueTypeUnsigned, + eValueTypeSigned, + eValueTypeCStr, + eValueTypeBlock + }; + + DWARFFormValue(); + DWARFFormValue(const DWARFCompileUnit *cu, dw_form_t form); + const DWARFCompileUnit *GetCompileUnit() const { return m_cu; } + void SetCompileUnit(const DWARFCompileUnit *cu) { m_cu = cu; } + dw_form_t Form() const { return m_form; } + void SetForm(dw_form_t form) { m_form = form; } + const ValueType &Value() const { return m_value; } + void Dump(lldb_private::Stream &s) const; + bool ExtractValue(const lldb_private::DWARFDataExtractor &data, + lldb::offset_t *offset_ptr); + const uint8_t *BlockData() const; + uint64_t Reference() const; + uint64_t Reference(dw_offset_t offset) const; + bool Boolean() const { return m_value.value.uval != 0; } + uint64_t Unsigned() const { return m_value.value.uval; } + void SetUnsigned(uint64_t uval) { m_value.value.uval = uval; } + int64_t Signed() const { return m_value.value.sval; } + void SetSigned(int64_t sval) { m_value.value.sval = sval; } + const char *AsCString() const; + dw_addr_t Address() const; + bool IsValid() const { return m_form != 0; } + bool SkipValue(const lldb_private::DWARFDataExtractor &debug_info_data, + lldb::offset_t *offset_ptr) const; + static bool SkipValue(const dw_form_t form, + const lldb_private::DWARFDataExtractor &debug_info_data, + lldb::offset_t *offset_ptr, const DWARFCompileUnit *cu); + static bool IsBlockForm(const dw_form_t form); + static bool IsDataForm(const dw_form_t form); + static FixedFormSizes GetFixedFormSizesForAddressSize(uint8_t addr_size, + bool is_dwarf64); + static int Compare(const DWARFFormValue &a, const DWARFFormValue &b); + void Clear(); - DWARFFormValue(); - DWARFFormValue(const DWARFCompileUnit* cu, dw_form_t form); - const DWARFCompileUnit* GetCompileUnit () const { return m_cu; } - void SetCompileUnit (const DWARFCompileUnit* cu) { m_cu = cu; } - dw_form_t Form() const { return m_form; } - void SetForm(dw_form_t form) { m_form = form; } - const ValueType& Value() const { return m_value; } - void Dump(lldb_private::Stream &s) const; - bool ExtractValue(const lldb_private::DWARFDataExtractor& data, - lldb::offset_t* offset_ptr); - const uint8_t* BlockData() const; - uint64_t Reference() const; - uint64_t Reference (dw_offset_t offset) const; - bool Boolean() const { return m_value.value.uval != 0; } - uint64_t Unsigned() const { return m_value.value.uval; } - void SetUnsigned(uint64_t uval) { m_value.value.uval = uval; } - int64_t Signed() const { return m_value.value.sval; } - void SetSigned(int64_t sval) { m_value.value.sval = sval; } - const char* AsCString() const; - dw_addr_t Address() const; - bool IsValid() const { return m_form != 0; } - bool SkipValue(const lldb_private::DWARFDataExtractor& debug_info_data, lldb::offset_t *offset_ptr) const; - static bool SkipValue(const dw_form_t form, const lldb_private::DWARFDataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu); - static bool IsBlockForm(const dw_form_t form); - static bool IsDataForm(const dw_form_t form); - static FixedFormSizes GetFixedFormSizesForAddressSize (uint8_t addr_size, bool is_dwarf64); - static int Compare (const DWARFFormValue& a, - const DWARFFormValue& b); - void Clear(); protected: - const DWARFCompileUnit* m_cu; // Compile unit for this form - dw_form_t m_form; // Form for this value - ValueType m_value; // Contains all data for the form + const DWARFCompileUnit *m_cu; // Compile unit for this form + dw_form_t m_form; // Form for this value + ValueType m_value; // Contains all data for the form }; - -#endif // SymbolFileDWARF_DWARFFormValue_h_ +#endif // SymbolFileDWARF_DWARFFormValue_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp index 12e1e89c36bd..afdb1d6afed3 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp @@ -8,747 +8,637 @@ //===----------------------------------------------------------------------===// #include "HashedNameToDIE.h" - -void -DWARFMappedHash::ExtractDIEArray (const DIEInfoArray &die_info_array, DIEArray &die_offsets) -{ +#include "llvm/ADT/StringRef.h" + +void DWARFMappedHash::ExtractDIEArray(const DIEInfoArray &die_info_array, + DIEArray &die_offsets) { + const size_t count = die_info_array.size(); + for (size_t i = 0; i < count; ++i) + die_offsets.emplace_back(die_info_array[i].cu_offset, + die_info_array[i].offset); +} + +void DWARFMappedHash::ExtractDIEArray(const DIEInfoArray &die_info_array, + const dw_tag_t tag, + DIEArray &die_offsets) { + if (tag == 0) { + ExtractDIEArray(die_info_array, die_offsets); + } else { const size_t count = die_info_array.size(); - for (size_t i=0; i<count; ++i) - die_offsets.emplace_back(die_info_array[i].cu_offset, die_info_array[i].offset); -} - -void -DWARFMappedHash::ExtractDIEArray (const DIEInfoArray &die_info_array, - const dw_tag_t tag, - DIEArray &die_offsets) -{ - if (tag == 0) - { - ExtractDIEArray (die_info_array, die_offsets); - } - else - { - const size_t count = die_info_array.size(); - for (size_t i=0; i<count; ++i) - { - const dw_tag_t die_tag = die_info_array[i].tag; - bool tag_matches = die_tag == 0 || tag == die_tag; - if (!tag_matches) - { - if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type) - tag_matches = tag == DW_TAG_structure_type || tag == DW_TAG_class_type; - } - if (tag_matches) - die_offsets.emplace_back(die_info_array[i].cu_offset, die_info_array[i].offset); - } + for (size_t i = 0; i < count; ++i) { + const dw_tag_t die_tag = die_info_array[i].tag; + bool tag_matches = die_tag == 0 || tag == die_tag; + if (!tag_matches) { + if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type) + tag_matches = + tag == DW_TAG_structure_type || tag == DW_TAG_class_type; + } + if (tag_matches) + die_offsets.emplace_back(die_info_array[i].cu_offset, + die_info_array[i].offset); } + } } -void -DWARFMappedHash::ExtractDIEArray (const DIEInfoArray &die_info_array, - const dw_tag_t tag, - const uint32_t qualified_name_hash, - DIEArray &die_offsets) -{ - if (tag == 0) - { - ExtractDIEArray (die_info_array, die_offsets); - } - else - { - const size_t count = die_info_array.size(); - for (size_t i=0; i<count; ++i) - { - if (qualified_name_hash != die_info_array[i].qualified_name_hash) - continue; - const dw_tag_t die_tag = die_info_array[i].tag; - bool tag_matches = die_tag == 0 || tag == die_tag; - if (!tag_matches) - { - if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type) - tag_matches = tag == DW_TAG_structure_type || tag == DW_TAG_class_type; - } - if (tag_matches) - die_offsets.emplace_back(die_info_array[i].cu_offset, die_info_array[i].offset); - } - } -} - -void -DWARFMappedHash::ExtractClassOrStructDIEArray (const DIEInfoArray &die_info_array, - bool return_implementation_only_if_available, - DIEArray &die_offsets) -{ +void DWARFMappedHash::ExtractDIEArray(const DIEInfoArray &die_info_array, + const dw_tag_t tag, + const uint32_t qualified_name_hash, + DIEArray &die_offsets) { + if (tag == 0) { + ExtractDIEArray(die_info_array, die_offsets); + } else { const size_t count = die_info_array.size(); - for (size_t i=0; i<count; ++i) - { - const dw_tag_t die_tag = die_info_array[i].tag; - if (die_tag == 0 || die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type) - { - if (die_info_array[i].type_flags & eTypeFlagClassIsImplementation) - { - if (return_implementation_only_if_available) - { - // We found the one true definition for this class, so - // only return that - die_offsets.clear(); - die_offsets.emplace_back(die_info_array[i].cu_offset, die_info_array[i].offset); - return; - } - else - { - // Put the one true definition as the first entry so it - // matches first - die_offsets.emplace(die_offsets.begin(), die_info_array[i].cu_offset, die_info_array[i].offset); - } - } - else - { - die_offsets.emplace_back(die_info_array[i].cu_offset, die_info_array[i].offset); - } - } + for (size_t i = 0; i < count; ++i) { + if (qualified_name_hash != die_info_array[i].qualified_name_hash) + continue; + const dw_tag_t die_tag = die_info_array[i].tag; + bool tag_matches = die_tag == 0 || tag == die_tag; + if (!tag_matches) { + if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type) + tag_matches = + tag == DW_TAG_structure_type || tag == DW_TAG_class_type; + } + if (tag_matches) + die_offsets.emplace_back(die_info_array[i].cu_offset, + die_info_array[i].offset); } -} - -void -DWARFMappedHash::ExtractTypesFromDIEArray (const DIEInfoArray &die_info_array, - uint32_t type_flag_mask, - uint32_t type_flag_value, - DIEArray &die_offsets) -{ - const size_t count = die_info_array.size(); - for (size_t i=0; i<count; ++i) - { - if ((die_info_array[i].type_flags & type_flag_mask) == type_flag_value) - die_offsets.emplace_back(die_info_array[i].cu_offset, die_info_array[i].offset); + } +} + +void DWARFMappedHash::ExtractClassOrStructDIEArray( + const DIEInfoArray &die_info_array, + bool return_implementation_only_if_available, DIEArray &die_offsets) { + const size_t count = die_info_array.size(); + for (size_t i = 0; i < count; ++i) { + const dw_tag_t die_tag = die_info_array[i].tag; + if (die_tag == 0 || die_tag == DW_TAG_class_type || + die_tag == DW_TAG_structure_type) { + if (die_info_array[i].type_flags & eTypeFlagClassIsImplementation) { + if (return_implementation_only_if_available) { + // We found the one true definition for this class, so + // only return that + die_offsets.clear(); + die_offsets.emplace_back(die_info_array[i].cu_offset, + die_info_array[i].offset); + return; + } else { + // Put the one true definition as the first entry so it + // matches first + die_offsets.emplace(die_offsets.begin(), die_info_array[i].cu_offset, + die_info_array[i].offset); + } + } else { + die_offsets.emplace_back(die_info_array[i].cu_offset, + die_info_array[i].offset); + } } + } +} + +void DWARFMappedHash::ExtractTypesFromDIEArray( + const DIEInfoArray &die_info_array, uint32_t type_flag_mask, + uint32_t type_flag_value, DIEArray &die_offsets) { + const size_t count = die_info_array.size(); + for (size_t i = 0; i < count; ++i) { + if ((die_info_array[i].type_flags & type_flag_mask) == type_flag_value) + die_offsets.emplace_back(die_info_array[i].cu_offset, + die_info_array[i].offset); + } +} + +const char *DWARFMappedHash::GetAtomTypeName(uint16_t atom) { + switch (atom) { + case eAtomTypeNULL: + return "NULL"; + case eAtomTypeDIEOffset: + return "die-offset"; + case eAtomTypeCUOffset: + return "cu-offset"; + case eAtomTypeTag: + return "die-tag"; + case eAtomTypeNameFlags: + return "name-flags"; + case eAtomTypeTypeFlags: + return "type-flags"; + case eAtomTypeQualNameHash: + return "qualified-name-hash"; + } + return "<invalid>"; +} + +DWARFMappedHash::DIEInfo::DIEInfo() + : cu_offset(DW_INVALID_OFFSET), offset(DW_INVALID_OFFSET), tag(0), + type_flags(0), qualified_name_hash(0) {} + +DWARFMappedHash::DIEInfo::DIEInfo(dw_offset_t c, dw_offset_t o, dw_tag_t t, + uint32_t f, uint32_t h) + : cu_offset(c), offset(o), tag(t), type_flags(f), qualified_name_hash(h) {} + +DWARFMappedHash::Prologue::Prologue(dw_offset_t _die_base_offset) + : die_base_offset(_die_base_offset), atoms(), atom_mask(0), + min_hash_data_byte_size(0), hash_data_has_fixed_byte_size(true) { + // Define an array of DIE offsets by first defining an array, + // and then define the atom type for the array, in this case + // we have an array of DIE offsets + AppendAtom(eAtomTypeDIEOffset, DW_FORM_data4); +} + +void DWARFMappedHash::Prologue::ClearAtoms() { + hash_data_has_fixed_byte_size = true; + min_hash_data_byte_size = 0; + atom_mask = 0; + atoms.clear(); +} + +bool DWARFMappedHash::Prologue::ContainsAtom(AtomType atom_type) const { + return (atom_mask & (1u << atom_type)) != 0; +} + +void DWARFMappedHash::Prologue::Clear() { + die_base_offset = 0; + ClearAtoms(); +} + +void DWARFMappedHash::Prologue::AppendAtom(AtomType type, dw_form_t form) { + atoms.push_back({type, form}); + atom_mask |= 1u << type; + switch (form) { + case DW_FORM_indirect: + case DW_FORM_exprloc: + case DW_FORM_flag_present: + case DW_FORM_ref_sig8: + assert(!"Unhandled atom form"); + break; + + case DW_FORM_string: + case DW_FORM_block: + case DW_FORM_block1: + 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: + hash_data_has_fixed_byte_size = false; + LLVM_FALLTHROUGH; + case DW_FORM_flag: + case DW_FORM_data1: + case DW_FORM_ref1: + case DW_FORM_sec_offset: + min_hash_data_byte_size += 1; + break; + + case DW_FORM_block2: + hash_data_has_fixed_byte_size = false; + LLVM_FALLTHROUGH; + case DW_FORM_data2: + case DW_FORM_ref2: + min_hash_data_byte_size += 2; + break; + + case DW_FORM_block4: + hash_data_has_fixed_byte_size = false; + LLVM_FALLTHROUGH; + case DW_FORM_data4: + case DW_FORM_ref4: + case DW_FORM_addr: + case DW_FORM_ref_addr: + case DW_FORM_strp: + min_hash_data_byte_size += 4; + break; + + case DW_FORM_data8: + case DW_FORM_ref8: + min_hash_data_byte_size += 8; + break; + } } -const char * -DWARFMappedHash::GetAtomTypeName (uint16_t atom) -{ - switch (atom) - { - case eAtomTypeNULL: return "NULL"; - case eAtomTypeDIEOffset: return "die-offset"; - case eAtomTypeCUOffset: return "cu-offset"; - case eAtomTypeTag: return "die-tag"; - case eAtomTypeNameFlags: return "name-flags"; - case eAtomTypeTypeFlags: return "type-flags"; - case eAtomTypeQualNameHash: return "qualified-name-hash"; +lldb::offset_t +DWARFMappedHash::Prologue::Read(const lldb_private::DataExtractor &data, + lldb::offset_t offset) { + ClearAtoms(); + + die_base_offset = data.GetU32(&offset); + + const uint32_t atom_count = data.GetU32(&offset); + if (atom_count == 0x00060003u) { + // Old format, deal with contents of old pre-release format + while (data.GetU32(&offset)) + /* do nothing */; + + // Hardcode to the only known value for now. + AppendAtom(eAtomTypeDIEOffset, DW_FORM_data4); + } else { + for (uint32_t i = 0; i < atom_count; ++i) { + AtomType type = (AtomType)data.GetU16(&offset); + dw_form_t form = (dw_form_t)data.GetU16(&offset); + AppendAtom(type, form); } - return "<invalid>"; + } + return offset; } -DWARFMappedHash::DIEInfo::DIEInfo () : - cu_offset (DW_INVALID_OFFSET), - offset (DW_INVALID_OFFSET), - tag (0), - type_flags (0), - qualified_name_hash (0) -{ +size_t DWARFMappedHash::Prologue::GetByteSize() const { + // Add an extra count to the atoms size for the zero termination Atom that + // gets + // written to disk + return sizeof(die_base_offset) + sizeof(uint32_t) + + atoms.size() * sizeof(Atom); } -DWARFMappedHash::DIEInfo::DIEInfo (dw_offset_t c, - dw_offset_t o, - dw_tag_t t, - uint32_t f, - uint32_t h) : - cu_offset (c), - offset (o), - tag (t), - type_flags (f), - qualified_name_hash (h) -{ +size_t DWARFMappedHash::Prologue::GetMinimumHashDataByteSize() const { + return min_hash_data_byte_size; } -DWARFMappedHash::Prologue::Prologue (dw_offset_t _die_base_offset) : - die_base_offset (_die_base_offset), - atoms(), - atom_mask (0), - min_hash_data_byte_size(0), - hash_data_has_fixed_byte_size(true) -{ - // Define an array of DIE offsets by first defining an array, - // and then define the atom type for the array, in this case - // we have an array of DIE offsets - AppendAtom (eAtomTypeDIEOffset, DW_FORM_data4); +bool DWARFMappedHash::Prologue::HashDataHasFixedByteSize() const { + return hash_data_has_fixed_byte_size; } -void -DWARFMappedHash::Prologue::ClearAtoms () -{ - hash_data_has_fixed_byte_size = true; - min_hash_data_byte_size = 0; - atom_mask = 0; - atoms.clear(); +size_t DWARFMappedHash::Header::GetByteSize(const HeaderData &header_data) { + return header_data.GetByteSize(); } -bool -DWARFMappedHash::Prologue::ContainsAtom (AtomType atom_type) const -{ - return (atom_mask & (1u << atom_type)) != 0; +lldb::offset_t DWARFMappedHash::Header::Read(lldb_private::DataExtractor &data, + lldb::offset_t offset) { + offset = MappedHash::Header<Prologue>::Read(data, offset); + if (offset != UINT32_MAX) { + offset = header_data.Read(data, offset); + } + return offset; } -void -DWARFMappedHash::Prologue::Clear () -{ - die_base_offset = 0; - ClearAtoms (); -} +bool DWARFMappedHash::Header::Read(const lldb_private::DWARFDataExtractor &data, + lldb::offset_t *offset_ptr, + DIEInfo &hash_data) const { + const size_t num_atoms = header_data.atoms.size(); + if (num_atoms == 0) + return false; -void -DWARFMappedHash::Prologue::AppendAtom (AtomType type, dw_form_t form) -{ - atoms.push_back ({type, form}); - atom_mask |= 1u << type; - switch (form) - { - case DW_FORM_indirect: - case DW_FORM_exprloc: - case DW_FORM_flag_present: - case DW_FORM_ref_sig8: - assert (!"Unhandled atom form"); - break; - - case DW_FORM_string: - case DW_FORM_block: - case DW_FORM_block1: - 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: - hash_data_has_fixed_byte_size = false; - LLVM_FALLTHROUGH; - case DW_FORM_flag: - case DW_FORM_data1: - case DW_FORM_ref1: - case DW_FORM_sec_offset: - min_hash_data_byte_size += 1; - break; - - case DW_FORM_block2: - hash_data_has_fixed_byte_size = false; - LLVM_FALLTHROUGH; - case DW_FORM_data2: - case DW_FORM_ref2: - min_hash_data_byte_size += 2; - break; - - case DW_FORM_block4: - hash_data_has_fixed_byte_size = false; - LLVM_FALLTHROUGH; - case DW_FORM_data4: - case DW_FORM_ref4: - case DW_FORM_addr: - case DW_FORM_ref_addr: - case DW_FORM_strp: - min_hash_data_byte_size += 4; - break; - - case DW_FORM_data8: - case DW_FORM_ref8: - min_hash_data_byte_size += 8; - break; - - } -} + for (size_t i = 0; i < num_atoms; ++i) { + DWARFFormValue form_value(NULL, header_data.atoms[i].form); -lldb::offset_t -DWARFMappedHash::Prologue::Read (const lldb_private::DataExtractor &data, - lldb::offset_t offset) -{ - ClearAtoms (); - - die_base_offset = data.GetU32 (&offset); - - const uint32_t atom_count = data.GetU32 (&offset); - if (atom_count == 0x00060003u) - { - // Old format, deal with contents of old pre-release format - while (data.GetU32(&offset)) - /* do nothing */; - - // Hardcode to the only known value for now. - AppendAtom (eAtomTypeDIEOffset, DW_FORM_data4); - } - else - { - for (uint32_t i=0; i<atom_count; ++i) - { - AtomType type = (AtomType)data.GetU16 (&offset); - dw_form_t form = (dw_form_t)data.GetU16 (&offset); - AppendAtom (type, form); - } - } - return offset; -} + if (!form_value.ExtractValue(data, offset_ptr)) + return false; -size_t -DWARFMappedHash::Prologue::GetByteSize () const -{ - // Add an extra count to the atoms size for the zero termination Atom that gets - // written to disk - return sizeof(die_base_offset) + sizeof(uint32_t) + atoms.size() * sizeof(Atom); -} + 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); + break; -size_t -DWARFMappedHash::Prologue::GetMinimumHashDataByteSize () const -{ - return min_hash_data_byte_size; -} + case eAtomTypeTag: // DW_TAG value for the DIE + hash_data.tag = (dw_tag_t)form_value.Unsigned(); + break; -bool -DWARFMappedHash::Prologue::HashDataHasFixedByteSize() const -{ - return hash_data_has_fixed_byte_size; -} + case eAtomTypeTypeFlags: // Flags from enum TypeFlags + hash_data.type_flags = (uint32_t)form_value.Unsigned(); + break; -size_t -DWARFMappedHash::Header::GetByteSize (const HeaderData &header_data) -{ - return header_data.GetByteSize(); -} + case eAtomTypeQualNameHash: // Flags from enum TypeFlags + hash_data.qualified_name_hash = form_value.Unsigned(); + break; -lldb::offset_t -DWARFMappedHash::Header::Read (lldb_private::DataExtractor &data, lldb::offset_t offset) -{ - offset = MappedHash::Header<Prologue>::Read (data, offset); - if (offset != UINT32_MAX) - { - offset = header_data.Read (data, offset); + default: + // We can always skip atoms we don't know about + break; } - return offset; + } + return true; } -bool -DWARFMappedHash::Header::Read (const lldb_private::DWARFDataExtractor &data, - lldb::offset_t *offset_ptr, - DIEInfo &hash_data) const -{ - const size_t num_atoms = header_data.atoms.size(); - if (num_atoms == 0) - return false; - - for (size_t i=0; i<num_atoms; ++i) - { - DWARFFormValue form_value (NULL, header_data.atoms[i].form); - - if (!form_value.ExtractValue(data, offset_ptr)) - return false; - - 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); - break; - - case eAtomTypeTag: // DW_TAG value for the DIE - hash_data.tag = (dw_tag_t)form_value.Unsigned (); - break; - - case eAtomTypeTypeFlags: // Flags from enum TypeFlags - hash_data.type_flags = (uint32_t)form_value.Unsigned (); - break; - - case eAtomTypeQualNameHash: // Flags from enum TypeFlags - hash_data.qualified_name_hash = form_value.Unsigned (); - break; - - default: - // We can always skip atoms we don't know about - break; - } - } - return true; -} +void DWARFMappedHash::Header::Dump(lldb_private::Stream &strm, + const DIEInfo &hash_data) const { + const size_t num_atoms = header_data.atoms.size(); + for (size_t i = 0; i < num_atoms; ++i) { + if (i > 0) + strm.PutCString(", "); + + DWARFFormValue form_value(NULL, header_data.atoms[i].form); + switch (header_data.atoms[i].type) { + case eAtomTypeDIEOffset: // DIE offset, check form for encoding + strm.Printf("{0x%8.8x}", hash_data.offset); + break; -void -DWARFMappedHash::Header::Dump (lldb_private::Stream& strm, const DIEInfo &hash_data) const -{ - const size_t num_atoms = header_data.atoms.size(); - for (size_t i=0; i<num_atoms; ++i) + case eAtomTypeTag: // DW_TAG value for the DIE { - if (i > 0) - strm.PutCString (", "); - - DWARFFormValue form_value (NULL, header_data.atoms[i].form); - switch (header_data.atoms[i].type) - { - case eAtomTypeDIEOffset: // DIE offset, check form for encoding - strm.Printf ("{0x%8.8x}", hash_data.offset); - break; - - case eAtomTypeTag: // DW_TAG value for the DIE - { - const char *tag_cstr = lldb_private::DW_TAG_value_to_name (hash_data.tag); - if (tag_cstr) - strm.PutCString (tag_cstr); - else - strm.Printf ("DW_TAG_(0x%4.4x)", hash_data.tag); - } - break; - - case eAtomTypeTypeFlags: // Flags from enum TypeFlags - strm.Printf ("0x%2.2x", hash_data.type_flags); - if (hash_data.type_flags) - { - strm.PutCString (" ("); - if (hash_data.type_flags & eTypeFlagClassIsImplementation) - strm.PutCString (" implementation"); - strm.PutCString (" )"); - } - break; - - case eAtomTypeQualNameHash: // Flags from enum TypeFlags - strm.Printf ("0x%8.8x", hash_data.qualified_name_hash); - break; - - default: - strm.Printf ("AtomType(0x%x)", header_data.atoms[i].type); - break; - } + const char *tag_cstr = lldb_private::DW_TAG_value_to_name(hash_data.tag); + if (tag_cstr) + strm.PutCString(tag_cstr); + else + strm.Printf("DW_TAG_(0x%4.4x)", hash_data.tag); + } break; + + case eAtomTypeTypeFlags: // Flags from enum TypeFlags + strm.Printf("0x%2.2x", hash_data.type_flags); + if (hash_data.type_flags) { + strm.PutCString(" ("); + if (hash_data.type_flags & eTypeFlagClassIsImplementation) + strm.PutCString(" implementation"); + strm.PutCString(" )"); + } + break; + + case eAtomTypeQualNameHash: // Flags from enum TypeFlags + strm.Printf("0x%8.8x", hash_data.qualified_name_hash); + break; + + default: + strm.Printf("AtomType(0x%x)", header_data.atoms[i].type); + break; } + } } -DWARFMappedHash::MemoryTable::MemoryTable (lldb_private::DWARFDataExtractor &table_data, - const lldb_private::DWARFDataExtractor &string_table, - const char *name) : - MappedHash::MemoryTable<uint32_t, Header, DIEInfoArray> (table_data), - m_data (table_data), - m_string_table (string_table), - m_name (name) -{ -} +DWARFMappedHash::MemoryTable::MemoryTable( + lldb_private::DWARFDataExtractor &table_data, + const lldb_private::DWARFDataExtractor &string_table, const char *name) + : MappedHash::MemoryTable<uint32_t, Header, DIEInfoArray>(table_data), + m_data(table_data), m_string_table(string_table), m_name(name) {} const char * -DWARFMappedHash::MemoryTable::GetStringForKeyType (KeyType key) const -{ - // The key in the DWARF table is the .debug_str offset for the string - return m_string_table.PeekCStr (key); -} - -bool -DWARFMappedHash::MemoryTable::ReadHashData (uint32_t hash_data_offset, HashData &hash_data) const -{ - lldb::offset_t offset = hash_data_offset; - offset += 4; // Skip string table offset that contains offset of hash name in .debug_str - const uint32_t count = m_data.GetU32 (&offset); - if (count > 0) - { - hash_data.resize(count); - for (uint32_t i=0; i<count; ++i) - { - if (!m_header.Read(m_data, &offset, hash_data[i])) - return false; - } +DWARFMappedHash::MemoryTable::GetStringForKeyType(KeyType key) const { + // The key in the DWARF table is the .debug_str offset for the string + return m_string_table.PeekCStr(key); +} + +bool DWARFMappedHash::MemoryTable::ReadHashData(uint32_t hash_data_offset, + HashData &hash_data) const { + lldb::offset_t offset = hash_data_offset; + offset += 4; // Skip string table offset that contains offset of hash name in + // .debug_str + const uint32_t count = m_data.GetU32(&offset); + if (count > 0) { + hash_data.resize(count); + for (uint32_t i = 0; i < count; ++i) { + if (!m_header.Read(m_data, &offset, hash_data[i])) + return false; } - else - hash_data.clear(); - return true; + } else + hash_data.clear(); + return true; } DWARFMappedHash::MemoryTable::Result -DWARFMappedHash::MemoryTable::GetHashDataForName (const char *name, - lldb::offset_t* hash_data_offset_ptr, - Pair &pair) const -{ - pair.key = m_data.GetU32 (hash_data_offset_ptr); - pair.value.clear(); - - // If the key is zero, this terminates our chain of HashData objects - // for this hash value. - if (pair.key == 0) - return eResultEndOfHashData; - - // There definitely should be a string for this string offset, if - // there isn't, there is something wrong, return and error - const char *strp_cstr = m_string_table.PeekCStr (pair.key); - if (strp_cstr == NULL) - { - *hash_data_offset_ptr = UINT32_MAX; - return eResultError; - } - - const uint32_t count = m_data.GetU32 (hash_data_offset_ptr); - const size_t min_total_hash_data_size = count * m_header.header_data.GetMinimumHashDataByteSize(); - if (count > 0 && m_data.ValidOffsetForDataOfSize (*hash_data_offset_ptr, min_total_hash_data_size)) - { - // We have at least one HashData entry, and we have enough - // data to parse at least "count" HashData entries. - - // First make sure the entire C string matches... - const bool match = strcmp (name, strp_cstr) == 0; - - if (!match && m_header.header_data.HashDataHasFixedByteSize()) - { - // If the string doesn't match and we have fixed size data, - // we can just add the total byte size of all HashData objects - // to the hash data offset and be done... - *hash_data_offset_ptr += min_total_hash_data_size; +DWARFMappedHash::MemoryTable::GetHashDataForName( + const char *name, lldb::offset_t *hash_data_offset_ptr, Pair &pair) const { + pair.key = m_data.GetU32(hash_data_offset_ptr); + pair.value.clear(); + + // If the key is zero, this terminates our chain of HashData objects + // for this hash value. + if (pair.key == 0) + return eResultEndOfHashData; + + // There definitely should be a string for this string offset, if + // there isn't, there is something wrong, return and error + const char *strp_cstr = m_string_table.PeekCStr(pair.key); + if (strp_cstr == NULL) { + *hash_data_offset_ptr = UINT32_MAX; + return eResultError; + } + + const uint32_t count = m_data.GetU32(hash_data_offset_ptr); + const size_t min_total_hash_data_size = + count * m_header.header_data.GetMinimumHashDataByteSize(); + if (count > 0 && + m_data.ValidOffsetForDataOfSize(*hash_data_offset_ptr, + min_total_hash_data_size)) { + // We have at least one HashData entry, and we have enough + // data to parse at least "count" HashData entries. + + // First make sure the entire C string matches... + const bool match = strcmp(name, strp_cstr) == 0; + + if (!match && m_header.header_data.HashDataHasFixedByteSize()) { + // If the string doesn't match and we have fixed size data, + // we can just add the total byte size of all HashData objects + // to the hash data offset and be done... + *hash_data_offset_ptr += min_total_hash_data_size; + } else { + // If the string does match, or we don't have fixed size data + // then we need to read the hash data as a stream. If the + // string matches we also append all HashData objects to the + // value array. + for (uint32_t i = 0; i < count; ++i) { + DIEInfo die_info; + if (m_header.Read(m_data, hash_data_offset_ptr, die_info)) { + // Only happened if the HashData of the string matched... + if (match) + pair.value.push_back(die_info); + } else { + // Something went wrong while reading the data + *hash_data_offset_ptr = UINT32_MAX; + return eResultError; } - else - { - // If the string does match, or we don't have fixed size data - // then we need to read the hash data as a stream. If the - // string matches we also append all HashData objects to the - // value array. - for (uint32_t i=0; i<count; ++i) - { - DIEInfo die_info; - if (m_header.Read(m_data, hash_data_offset_ptr, die_info)) - { - // Only happened if the HashData of the string matched... - if (match) - pair.value.push_back (die_info); - } - else - { - // Something went wrong while reading the data - *hash_data_offset_ptr = UINT32_MAX; - return eResultError; - } - } - } - // Return the correct response depending on if the string matched - // or not... - if (match) - return eResultKeyMatch; // The key (cstring) matches and we have lookup results! - else - return eResultKeyMismatch; // The key doesn't match, this function will get called - // again for the next key/value or the key terminator - // which in our case is a zero .debug_str offset. + } } + // Return the correct response depending on if the string matched + // or not... + if (match) + return eResultKeyMatch; // The key (cstring) matches and we have lookup + // results! else - { - *hash_data_offset_ptr = UINT32_MAX; - return eResultError; - } + return eResultKeyMismatch; // The key doesn't match, this function will + // get called + // again for the next key/value or the key terminator + // which in our case is a zero .debug_str offset. + } else { + *hash_data_offset_ptr = UINT32_MAX; + return eResultError; + } } DWARFMappedHash::MemoryTable::Result -DWARFMappedHash::MemoryTable::AppendHashDataForRegularExpression ( - const lldb_private::RegularExpression& regex, - lldb::offset_t* hash_data_offset_ptr, - Pair &pair) const -{ - pair.key = m_data.GetU32 (hash_data_offset_ptr); - // If the key is zero, this terminates our chain of HashData objects - // for this hash value. - if (pair.key == 0) - return eResultEndOfHashData; - - // There definitely should be a string for this string offset, if - // there isn't, there is something wrong, return and error - const char *strp_cstr = m_string_table.PeekCStr (pair.key); - if (strp_cstr == NULL) - return eResultError; - - const uint32_t count = m_data.GetU32 (hash_data_offset_ptr); - const size_t min_total_hash_data_size = count * m_header.header_data.GetMinimumHashDataByteSize(); - if (count > 0 && m_data.ValidOffsetForDataOfSize (*hash_data_offset_ptr, min_total_hash_data_size)) - { - const bool match = regex.Execute(strp_cstr); - - if (!match && m_header.header_data.HashDataHasFixedByteSize()) - { - // If the regex doesn't match and we have fixed size data, - // we can just add the total byte size of all HashData objects - // to the hash data offset and be done... - *hash_data_offset_ptr += min_total_hash_data_size; - } - else - { - // If the string does match, or we don't have fixed size data - // then we need to read the hash data as a stream. If the - // string matches we also append all HashData objects to the - // value array. - for (uint32_t i=0; i<count; ++i) - { - DIEInfo die_info; - if (m_header.Read(m_data, hash_data_offset_ptr, die_info)) - { - // Only happened if the HashData of the string matched... - if (match) - pair.value.push_back (die_info); - } - else - { - // Something went wrong while reading the data - *hash_data_offset_ptr = UINT32_MAX; - return eResultError; - } - } +DWARFMappedHash::MemoryTable::AppendHashDataForRegularExpression( + const lldb_private::RegularExpression ®ex, + lldb::offset_t *hash_data_offset_ptr, Pair &pair) const { + pair.key = m_data.GetU32(hash_data_offset_ptr); + // If the key is zero, this terminates our chain of HashData objects + // for this hash value. + if (pair.key == 0) + return eResultEndOfHashData; + + // There definitely should be a string for this string offset, if + // there isn't, there is something wrong, return and error + const char *strp_cstr = m_string_table.PeekCStr(pair.key); + if (strp_cstr == NULL) + return eResultError; + + const uint32_t count = m_data.GetU32(hash_data_offset_ptr); + const size_t min_total_hash_data_size = + count * m_header.header_data.GetMinimumHashDataByteSize(); + if (count > 0 && + m_data.ValidOffsetForDataOfSize(*hash_data_offset_ptr, + min_total_hash_data_size)) { + const bool match = regex.Execute(llvm::StringRef(strp_cstr)); + + if (!match && m_header.header_data.HashDataHasFixedByteSize()) { + // If the regex doesn't match and we have fixed size data, + // we can just add the total byte size of all HashData objects + // to the hash data offset and be done... + *hash_data_offset_ptr += min_total_hash_data_size; + } else { + // If the string does match, or we don't have fixed size data + // then we need to read the hash data as a stream. If the + // string matches we also append all HashData objects to the + // value array. + for (uint32_t i = 0; i < count; ++i) { + DIEInfo die_info; + if (m_header.Read(m_data, hash_data_offset_ptr, die_info)) { + // Only happened if the HashData of the string matched... + if (match) + pair.value.push_back(die_info); + } else { + // Something went wrong while reading the data + *hash_data_offset_ptr = UINT32_MAX; + return eResultError; } - // Return the correct response depending on if the string matched - // or not... - if (match) - return eResultKeyMatch; // The key (cstring) matches and we have lookup results! - else - return eResultKeyMismatch; // The key doesn't match, this function will get called - // again for the next key/value or the key terminator - // which in our case is a zero .debug_str offset. + } } + // Return the correct response depending on if the string matched + // or not... + if (match) + return eResultKeyMatch; // The key (cstring) matches and we have lookup + // results! else - { - *hash_data_offset_ptr = UINT32_MAX; - return eResultError; + return eResultKeyMismatch; // The key doesn't match, this function will + // get called + // again for the next key/value or the key terminator + // which in our case is a zero .debug_str offset. + } else { + *hash_data_offset_ptr = UINT32_MAX; + return eResultError; + } +} + +size_t DWARFMappedHash::MemoryTable::AppendAllDIEsThatMatchingRegex( + const lldb_private::RegularExpression ®ex, + DIEInfoArray &die_info_array) const { + const uint32_t hash_count = m_header.hashes_count; + Pair pair; + for (uint32_t offset_idx = 0; offset_idx < hash_count; ++offset_idx) { + lldb::offset_t hash_data_offset = GetHashDataOffset(offset_idx); + while (hash_data_offset != UINT32_MAX) { + const lldb::offset_t prev_hash_data_offset = hash_data_offset; + Result hash_result = + AppendHashDataForRegularExpression(regex, &hash_data_offset, pair); + if (prev_hash_data_offset == hash_data_offset) + break; + + // Check the result of getting our hash data + switch (hash_result) { + case eResultKeyMatch: + case eResultKeyMismatch: + // Whether we matches or not, it doesn't matter, we + // keep looking. + break; + + case eResultEndOfHashData: + case eResultError: + hash_data_offset = UINT32_MAX; + break; + } } -} - -size_t -DWARFMappedHash::MemoryTable::AppendAllDIEsThatMatchingRegex ( - const lldb_private::RegularExpression& regex, - DIEInfoArray &die_info_array) const -{ - const uint32_t hash_count = m_header.hashes_count; - Pair pair; - for (uint32_t offset_idx=0; offset_idx<hash_count; ++offset_idx) - { - lldb::offset_t hash_data_offset = GetHashDataOffset (offset_idx); - while (hash_data_offset != UINT32_MAX) - { - const lldb::offset_t prev_hash_data_offset = hash_data_offset; - Result hash_result = AppendHashDataForRegularExpression (regex, &hash_data_offset, pair); - if (prev_hash_data_offset == hash_data_offset) - break; - - // Check the result of getting our hash data - switch (hash_result) - { - case eResultKeyMatch: - case eResultKeyMismatch: - // Whether we matches or not, it doesn't matter, we - // keep looking. - break; - - case eResultEndOfHashData: - case eResultError: - hash_data_offset = UINT32_MAX; - break; - } + } + die_info_array.swap(pair.value); + return die_info_array.size(); +} + +size_t DWARFMappedHash::MemoryTable::AppendAllDIEsInRange( + const uint32_t die_offset_start, const uint32_t die_offset_end, + DIEInfoArray &die_info_array) const { + const uint32_t hash_count = m_header.hashes_count; + for (uint32_t offset_idx = 0; offset_idx < hash_count; ++offset_idx) { + bool done = false; + lldb::offset_t hash_data_offset = GetHashDataOffset(offset_idx); + while (!done && hash_data_offset != UINT32_MAX) { + KeyType key = m_data.GetU32(&hash_data_offset); + // If the key is zero, this terminates our chain of HashData objects + // for this hash value. + if (key == 0) + break; + + const uint32_t count = m_data.GetU32(&hash_data_offset); + for (uint32_t i = 0; i < count; ++i) { + DIEInfo die_info; + if (m_header.Read(m_data, &hash_data_offset, die_info)) { + if (die_info.offset == 0) + done = true; + if (die_offset_start <= die_info.offset && + die_info.offset < die_offset_end) + die_info_array.push_back(die_info); } + } } - die_info_array.swap (pair.value); - return die_info_array.size(); -} - -size_t -DWARFMappedHash::MemoryTable::AppendAllDIEsInRange (const uint32_t die_offset_start, - const uint32_t die_offset_end, - DIEInfoArray &die_info_array) const -{ - const uint32_t hash_count = m_header.hashes_count; - for (uint32_t offset_idx=0; offset_idx<hash_count; ++offset_idx) - { - bool done = false; - lldb::offset_t hash_data_offset = GetHashDataOffset (offset_idx); - while (!done && hash_data_offset != UINT32_MAX) - { - KeyType key = m_data.GetU32 (&hash_data_offset); - // If the key is zero, this terminates our chain of HashData objects - // for this hash value. - if (key == 0) - break; - - const uint32_t count = m_data.GetU32 (&hash_data_offset); - for (uint32_t i=0; i<count; ++i) - { - DIEInfo die_info; - if (m_header.Read(m_data, &hash_data_offset, die_info)) - { - if (die_info.offset == 0) - done = true; - if (die_offset_start <= die_info.offset && die_info.offset < die_offset_end) - die_info_array.push_back(die_info); - } - } - } - } - return die_info_array.size(); -} - -size_t -DWARFMappedHash::MemoryTable::FindByName (const char *name, DIEArray &die_offsets) -{ - if (!name || !name[0]) - return 0; - - DIEInfoArray die_info_array; - if (FindByName(name, die_info_array)) - DWARFMappedHash::ExtractDIEArray (die_info_array, die_offsets); - return die_info_array.size(); + } + return die_info_array.size(); } -size_t -DWARFMappedHash::MemoryTable::FindByNameAndTag (const char *name, - const dw_tag_t tag, - DIEArray &die_offsets) -{ - DIEInfoArray die_info_array; - if (FindByName(name, die_info_array)) - DWARFMappedHash::ExtractDIEArray (die_info_array, tag, die_offsets); - return die_info_array.size(); -} - -size_t -DWARFMappedHash::MemoryTable::FindByNameAndTagAndQualifiedNameHash (const char *name, - const dw_tag_t tag, - const uint32_t qualified_name_hash, - DIEArray &die_offsets) -{ - DIEInfoArray die_info_array; - if (FindByName(name, die_info_array)) - DWARFMappedHash::ExtractDIEArray (die_info_array, tag, qualified_name_hash, die_offsets); - return die_info_array.size(); -} +size_t DWARFMappedHash::MemoryTable::FindByName(const char *name, + DIEArray &die_offsets) { + if (!name || !name[0]) + return 0; -size_t -DWARFMappedHash::MemoryTable::FindCompleteObjCClassByName (const char *name, - DIEArray &die_offsets, - bool must_be_implementation) -{ - DIEInfoArray die_info_array; - if (FindByName(name, die_info_array)) - { - if (must_be_implementation && GetHeader().header_data.ContainsAtom (eAtomTypeTypeFlags)) - { - // If we have two atoms, then we have the DIE offset and - // the type flags so we can find the objective C class - // efficiently. - DWARFMappedHash::ExtractTypesFromDIEArray (die_info_array, - UINT32_MAX, - eTypeFlagClassIsImplementation, - die_offsets); - } - else - { - // We don't only want the one true definition, so try and see - // what we can find, and only return class or struct DIEs. - // If we do have the full implementation, then return it alone, - // else return all possible matches. - const bool return_implementation_only_if_available = true; - DWARFMappedHash::ExtractClassOrStructDIEArray (die_info_array, - return_implementation_only_if_available, - die_offsets); - } + DIEInfoArray die_info_array; + if (FindByName(name, die_info_array)) + DWARFMappedHash::ExtractDIEArray(die_info_array, die_offsets); + return die_info_array.size(); +} + +size_t DWARFMappedHash::MemoryTable::FindByNameAndTag(const char *name, + const dw_tag_t tag, + DIEArray &die_offsets) { + DIEInfoArray die_info_array; + if (FindByName(name, die_info_array)) + DWARFMappedHash::ExtractDIEArray(die_info_array, tag, die_offsets); + return die_info_array.size(); +} + +size_t DWARFMappedHash::MemoryTable::FindByNameAndTagAndQualifiedNameHash( + const char *name, const dw_tag_t tag, const uint32_t qualified_name_hash, + DIEArray &die_offsets) { + DIEInfoArray die_info_array; + if (FindByName(name, die_info_array)) + DWARFMappedHash::ExtractDIEArray(die_info_array, tag, qualified_name_hash, + die_offsets); + return die_info_array.size(); +} + +size_t DWARFMappedHash::MemoryTable::FindCompleteObjCClassByName( + const char *name, DIEArray &die_offsets, bool must_be_implementation) { + DIEInfoArray die_info_array; + if (FindByName(name, die_info_array)) { + if (must_be_implementation && + GetHeader().header_data.ContainsAtom(eAtomTypeTypeFlags)) { + // If we have two atoms, then we have the DIE offset and + // the type flags so we can find the objective C class + // efficiently. + DWARFMappedHash::ExtractTypesFromDIEArray(die_info_array, UINT32_MAX, + eTypeFlagClassIsImplementation, + die_offsets); + } else { + // We don't only want the one true definition, so try and see + // what we can find, and only return class or struct DIEs. + // If we do have the full implementation, then return it alone, + // else return all possible matches. + const bool return_implementation_only_if_available = true; + DWARFMappedHash::ExtractClassOrStructDIEArray( + die_info_array, return_implementation_only_if_available, die_offsets); } - return die_offsets.size(); + } + return die_offsets.size(); } -size_t -DWARFMappedHash::MemoryTable::FindByName (const char *name, DIEInfoArray &die_info_array) -{ - if (!name || !name[0]) - return 0; - - Pair kv_pair; - size_t old_size = die_info_array.size(); - if (Find (name, kv_pair)) - { - die_info_array.swap(kv_pair.value); - return die_info_array.size() - old_size; - } +size_t DWARFMappedHash::MemoryTable::FindByName(const char *name, + DIEInfoArray &die_info_array) { + if (!name || !name[0]) return 0; + + Pair kv_pair; + size_t old_size = die_info_array.size(); + if (Find(name, kv_pair)) { + die_info_array.swap(kv_pair.value); + return die_info_array.size() - old_size; + } + return 0; } diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h index bcde558ae449..c1cb30b60045 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h @@ -12,10 +12,10 @@ #include <vector> -#include "lldb/lldb-defines.h" -#include "lldb/Core/dwarf.h" -#include "lldb/Core/RegularExpression.h" #include "lldb/Core/MappedHash.h" +#include "lldb/Core/RegularExpression.h" +#include "lldb/Core/dwarf.h" +#include "lldb/lldb-defines.h" #include "DWARFDefines.h" #include "DWARFFormValue.h" @@ -25,195 +25,169 @@ class SymbolFileDWARF; class DWARFCompileUnit; class DWARFDebugInfoEntry; -class DWARFMappedHash -{ +class DWARFMappedHash { public: - enum AtomType : uint16_t - { - eAtomTypeNULL = 0u, - eAtomTypeDIEOffset = 1u, // DIE offset, check form for encoding - eAtomTypeCUOffset = 2u, // DIE offset of the compiler unit header that contains the item in question - eAtomTypeTag = 3u, // DW_TAG_xxx value, should be encoded as DW_FORM_data1 (if no tags exceed 255) or DW_FORM_data2 - eAtomTypeNameFlags = 4u, // Flags from enum NameFlags - eAtomTypeTypeFlags = 5u, // Flags from enum TypeFlags, - eAtomTypeQualNameHash = 6u // A 32 bit hash of the full qualified name (since all hash entries are basename only) - // For example a type like "std::vector<int>::iterator" would have a name of "iterator" - // and a 32 bit hash for "std::vector<int>::iterator" to allow us to not have to pull - // in debug info for a type when we know the fully qualified name. - }; - - // Bit definitions for the eAtomTypeTypeFlags flags - enum TypeFlags - { - // Always set for C++, only set for ObjC if this is the - // @implementation for class - eTypeFlagClassIsImplementation = ( 1u << 1 ) - }; - - struct DIEInfo - { - dw_offset_t cu_offset; - dw_offset_t offset; // The DIE offset - dw_tag_t tag; - uint32_t type_flags; // Any flags for this DIEInfo - uint32_t qualified_name_hash; // A 32 bit hash of the fully qualified name - - DIEInfo (); - DIEInfo (dw_offset_t c, dw_offset_t o, dw_tag_t t, uint32_t f, uint32_t h); - }; - - struct Atom - { - AtomType type; - dw_form_t form; - }; - - typedef std::vector<DIEInfo> DIEInfoArray; - typedef std::vector<Atom> AtomArray; - - class Prologue - { - public: - Prologue (dw_offset_t _die_base_offset = 0); - - void - ClearAtoms (); - - bool - ContainsAtom (AtomType atom_type) const; - - void - Clear (); - - void - AppendAtom (AtomType type, dw_form_t form); - - lldb::offset_t - Read (const lldb_private::DataExtractor &data, lldb::offset_t offset); - - size_t - GetByteSize () const; - - size_t - GetMinimumHashDataByteSize () const; - - bool - HashDataHasFixedByteSize() const; - - // DIE offset base so die offsets in hash_data can be CU relative - dw_offset_t die_base_offset; - AtomArray atoms; - uint32_t atom_mask; - size_t min_hash_data_byte_size; - bool hash_data_has_fixed_byte_size; - }; - - class Header : public MappedHash::Header<Prologue> - { - public: - size_t - GetByteSize (const HeaderData &header_data) override; - - lldb::offset_t - Read (lldb_private::DataExtractor &data, lldb::offset_t offset) override; - - bool - Read (const lldb_private::DWARFDataExtractor &data, - lldb::offset_t *offset_ptr, - DIEInfo &hash_data) const; - - void - Dump (lldb_private::Stream& strm, const DIEInfo &hash_data) const; - }; - - // A class for reading and using a saved hash table from a block of data - // in memory - class MemoryTable : public MappedHash::MemoryTable<uint32_t, DWARFMappedHash::Header, DIEInfoArray> - { - public: - MemoryTable (lldb_private::DWARFDataExtractor &table_data, - const lldb_private::DWARFDataExtractor &string_table, - const char *name); - - const char * - GetStringForKeyType (KeyType key) const override; - - bool - ReadHashData (uint32_t hash_data_offset, HashData &hash_data) const override; - - size_t - AppendAllDIEsThatMatchingRegex (const lldb_private::RegularExpression& regex, - DIEInfoArray &die_info_array) const; - - size_t - AppendAllDIEsInRange (const uint32_t die_offset_start, - const uint32_t die_offset_end, - DIEInfoArray &die_info_array) const; - - size_t - FindByName (const char *name, DIEArray &die_offsets); - - size_t - FindByNameAndTag (const char *name, const dw_tag_t tag, DIEArray &die_offsets); - - size_t - FindByNameAndTagAndQualifiedNameHash (const char *name, - const dw_tag_t tag, - const uint32_t qualified_name_hash, - DIEArray &die_offsets); - - size_t - FindCompleteObjCClassByName (const char *name, - DIEArray &die_offsets, - bool must_be_implementation); - - protected: - Result - AppendHashDataForRegularExpression (const lldb_private::RegularExpression& regex, - lldb::offset_t* hash_data_offset_ptr, - Pair &pair) const; - - size_t - FindByName (const char *name, DIEInfoArray &die_info_array); - - Result - GetHashDataForName (const char *name, - lldb::offset_t* hash_data_offset_ptr, - Pair &pair) const override; - - const lldb_private::DWARFDataExtractor &m_data; - const lldb_private::DWARFDataExtractor &m_string_table; - std::string m_name; - }; - - static void - ExtractDIEArray (const DIEInfoArray &die_info_array, DIEArray &die_offsets); + enum AtomType : uint16_t { + eAtomTypeNULL = 0u, + eAtomTypeDIEOffset = 1u, // DIE offset, check form for encoding + eAtomTypeCUOffset = 2u, // DIE offset of the compiler unit header that + // contains the item in question + eAtomTypeTag = 3u, // DW_TAG_xxx value, should be encoded as DW_FORM_data1 + // (if no tags exceed 255) or DW_FORM_data2 + eAtomTypeNameFlags = 4u, // Flags from enum NameFlags + eAtomTypeTypeFlags = 5u, // Flags from enum TypeFlags, + eAtomTypeQualNameHash = 6u // A 32 bit hash of the full qualified name + // (since all hash entries are basename only) + // For example a type like "std::vector<int>::iterator" would have a name of + // "iterator" + // and a 32 bit hash for "std::vector<int>::iterator" to allow us to not + // have to pull + // in debug info for a type when we know the fully qualified name. + }; + + // Bit definitions for the eAtomTypeTypeFlags flags + enum TypeFlags { + // Always set for C++, only set for ObjC if this is the + // @implementation for class + eTypeFlagClassIsImplementation = (1u << 1) + }; + + struct DIEInfo { + dw_offset_t cu_offset; + dw_offset_t offset; // The DIE offset + dw_tag_t tag; + uint32_t type_flags; // Any flags for this DIEInfo + uint32_t qualified_name_hash; // A 32 bit hash of the fully qualified name + + DIEInfo(); + DIEInfo(dw_offset_t c, dw_offset_t o, dw_tag_t t, uint32_t f, uint32_t h); + }; + + struct Atom { + AtomType type; + dw_form_t form; + }; + + typedef std::vector<DIEInfo> DIEInfoArray; + typedef std::vector<Atom> AtomArray; + + class Prologue { + public: + Prologue(dw_offset_t _die_base_offset = 0); + + void ClearAtoms(); + + bool ContainsAtom(AtomType atom_type) const; + + void Clear(); + + void AppendAtom(AtomType type, dw_form_t form); + + lldb::offset_t Read(const lldb_private::DataExtractor &data, + lldb::offset_t offset); + + size_t GetByteSize() const; + + size_t GetMinimumHashDataByteSize() const; + + bool HashDataHasFixedByteSize() const; + + // DIE offset base so die offsets in hash_data can be CU relative + dw_offset_t die_base_offset; + AtomArray atoms; + uint32_t atom_mask; + size_t min_hash_data_byte_size; + bool hash_data_has_fixed_byte_size; + }; + + class Header : public MappedHash::Header<Prologue> { + public: + size_t GetByteSize(const HeaderData &header_data) override; + + lldb::offset_t Read(lldb_private::DataExtractor &data, + lldb::offset_t offset) override; + + bool Read(const lldb_private::DWARFDataExtractor &data, + lldb::offset_t *offset_ptr, DIEInfo &hash_data) const; + + void Dump(lldb_private::Stream &strm, const DIEInfo &hash_data) const; + }; + + // A class for reading and using a saved hash table from a block of data + // in memory + class MemoryTable + : public MappedHash::MemoryTable<uint32_t, DWARFMappedHash::Header, + DIEInfoArray> { + public: + MemoryTable(lldb_private::DWARFDataExtractor &table_data, + const lldb_private::DWARFDataExtractor &string_table, + const char *name); + + const char *GetStringForKeyType(KeyType key) const override; + + bool ReadHashData(uint32_t hash_data_offset, + HashData &hash_data) const override; + + size_t + AppendAllDIEsThatMatchingRegex(const lldb_private::RegularExpression ®ex, + DIEInfoArray &die_info_array) const; + + size_t AppendAllDIEsInRange(const uint32_t die_offset_start, + const uint32_t die_offset_end, + DIEInfoArray &die_info_array) const; + + size_t FindByName(const char *name, DIEArray &die_offsets); + + size_t FindByNameAndTag(const char *name, const dw_tag_t tag, + DIEArray &die_offsets); + + size_t + FindByNameAndTagAndQualifiedNameHash(const char *name, const dw_tag_t tag, + const uint32_t qualified_name_hash, + DIEArray &die_offsets); + + size_t FindCompleteObjCClassByName(const char *name, DIEArray &die_offsets, + bool must_be_implementation); + + protected: + Result AppendHashDataForRegularExpression( + const lldb_private::RegularExpression ®ex, + lldb::offset_t *hash_data_offset_ptr, Pair &pair) const; + + size_t FindByName(const char *name, DIEInfoArray &die_info_array); + + Result GetHashDataForName(const char *name, + lldb::offset_t *hash_data_offset_ptr, + Pair &pair) const override; + + const lldb_private::DWARFDataExtractor &m_data; + const lldb_private::DWARFDataExtractor &m_string_table; + std::string m_name; + }; + + static void ExtractDIEArray(const DIEInfoArray &die_info_array, + DIEArray &die_offsets); protected: - static void - ExtractDIEArray (const DIEInfoArray &die_info_array, - const dw_tag_t tag, - DIEArray &die_offsets); - - static void - ExtractDIEArray (const DIEInfoArray &die_info_array, - const dw_tag_t tag, - const uint32_t qualified_name_hash, - DIEArray &die_offsets); - - static void - ExtractClassOrStructDIEArray (const DIEInfoArray &die_info_array, - bool return_implementation_only_if_available, - DIEArray &die_offsets); - - static void - ExtractTypesFromDIEArray (const DIEInfoArray &die_info_array, - uint32_t type_flag_mask, - uint32_t type_flag_value, + static void ExtractDIEArray(const DIEInfoArray &die_info_array, + const dw_tag_t tag, DIEArray &die_offsets); + + static void ExtractDIEArray(const DIEInfoArray &die_info_array, + const dw_tag_t tag, + const uint32_t qualified_name_hash, DIEArray &die_offsets); - static const char * - GetAtomTypeName (uint16_t atom); + static void + ExtractClassOrStructDIEArray(const DIEInfoArray &die_info_array, + bool return_implementation_only_if_available, + DIEArray &die_offsets); + + static void ExtractTypesFromDIEArray(const DIEInfoArray &die_info_array, + uint32_t type_flag_mask, + uint32_t type_flag_value, + DIEArray &die_offsets); + + static const char *GetAtomTypeName(uint16_t atom); }; -#endif // SymbolFileDWARF_HashedNameToDIE_h_ +#endif // SymbolFileDWARF_HashedNameToDIE_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp index fbbc03c94625..1385e3dd28de 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp @@ -9,227 +9,195 @@ #include "LogChannelDWARF.h" -#include "lldb/Interpreter/Args.h" +#include "SymbolFileDWARF.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/StreamFile.h" -#include "SymbolFileDWARF.h" +#include "lldb/Interpreter/Args.h" using namespace lldb; using namespace lldb_private; - // when the one and only logging channel is enabled, then this will be non NULL. -static LogChannelDWARF* g_log_channel = NULL; - -LogChannelDWARF::LogChannelDWARF () : - LogChannel () -{ -} - -LogChannelDWARF::~LogChannelDWARF () -{ -} +static LogChannelDWARF *g_log_channel = NULL; +LogChannelDWARF::LogChannelDWARF() : LogChannel() {} -void -LogChannelDWARF::Initialize() -{ - PluginManager::RegisterPlugin (GetPluginNameStatic(), - GetPluginDescriptionStatic(), - LogChannelDWARF::CreateInstance); -} +LogChannelDWARF::~LogChannelDWARF() {} -void -LogChannelDWARF::Terminate() -{ - PluginManager::UnregisterPlugin (LogChannelDWARF::CreateInstance); +void LogChannelDWARF::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + GetPluginDescriptionStatic(), + LogChannelDWARF::CreateInstance); } -LogChannel* -LogChannelDWARF::CreateInstance () -{ - return new LogChannelDWARF (); +void LogChannelDWARF::Terminate() { + PluginManager::UnregisterPlugin(LogChannelDWARF::CreateInstance); } -lldb_private::ConstString -LogChannelDWARF::GetPluginNameStatic() -{ - return SymbolFileDWARF::GetPluginNameStatic(); -} +LogChannel *LogChannelDWARF::CreateInstance() { return new LogChannelDWARF(); } -const char * -LogChannelDWARF::GetPluginDescriptionStatic() -{ - return "DWARF log channel for debugging plug-in issues."; +lldb_private::ConstString LogChannelDWARF::GetPluginNameStatic() { + return SymbolFileDWARF::GetPluginNameStatic(); } -lldb_private::ConstString -LogChannelDWARF::GetPluginName() -{ - return GetPluginNameStatic(); +const char *LogChannelDWARF::GetPluginDescriptionStatic() { + return "DWARF log channel for debugging plug-in issues."; } -uint32_t -LogChannelDWARF::GetPluginVersion() -{ - return 1; -} - - -void -LogChannelDWARF::Delete () -{ - g_log_channel = NULL; +lldb_private::ConstString LogChannelDWARF::GetPluginName() { + return GetPluginNameStatic(); } +uint32_t LogChannelDWARF::GetPluginVersion() { return 1; } -void -LogChannelDWARF::Disable (const char **categories, Stream *feedback_strm) -{ - if (m_log_ap.get() == NULL) - return; - - uint32_t flag_bits = m_log_ap->GetMask().Get(); - for (size_t i = 0; categories[i] != NULL; ++i) - { - const char *arg = categories[i]; - - if (::strcasecmp (arg, "all") == 0) flag_bits &= ~DWARF_LOG_ALL; - else if (::strcasecmp (arg, "info") == 0) flag_bits &= ~DWARF_LOG_DEBUG_INFO; - else if (::strcasecmp (arg, "line") == 0) flag_bits &= ~DWARF_LOG_DEBUG_LINE; - else if (::strcasecmp (arg, "pubnames") == 0) flag_bits &= ~DWARF_LOG_DEBUG_PUBNAMES; - else if (::strcasecmp (arg, "pubtypes") == 0) flag_bits &= ~DWARF_LOG_DEBUG_PUBTYPES; - else if (::strcasecmp (arg, "aranges") == 0) flag_bits &= ~DWARF_LOG_DEBUG_ARANGES; - else if (::strcasecmp (arg, "lookups") == 0) flag_bits &= ~DWARF_LOG_LOOKUPS; - else if (::strcasecmp (arg, "map") == 0) flag_bits &= ~DWARF_LOG_DEBUG_MAP; - else if (::strcasecmp (arg, "default") == 0) flag_bits &= ~DWARF_LOG_DEFAULT; - else if (::strcasecmp (arg, "verbose") == 0) flag_bits &= ~DWARF_LOG_VERBOSE; - else if (::strncasecmp(arg, "comp", 4) == 0) flag_bits &= ~DWARF_LOG_TYPE_COMPLETION; - else - { - feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); - ListCategories (feedback_strm); - } - } - - if (flag_bits == 0) - Delete (); - else - m_log_ap->GetMask().Reset (flag_bits); +void LogChannelDWARF::Delete() { g_log_channel = NULL; } +void LogChannelDWARF::Disable(const char **categories, Stream *feedback_strm) { + if (m_log_ap.get() == NULL) return; -} -bool -LogChannelDWARF::Enable -( - StreamSP &log_stream_sp, - uint32_t log_options, - Stream *feedback_strm, // Feedback stream for argument errors etc - const char **categories // The categories to enable within this logging stream, if empty, enable default set -) -{ - Delete (); - - if (m_log_ap) - m_log_ap->SetStream(log_stream_sp); - else - m_log_ap.reset(new Log (log_stream_sp)); - - g_log_channel = this; - uint32_t flag_bits = 0; - bool got_unknown_category = false; - for (size_t i = 0; categories[i] != NULL; ++i) - { - const char *arg = categories[i]; - - if (::strcasecmp (arg, "all") == 0) flag_bits |= DWARF_LOG_ALL; - else if (::strcasecmp (arg, "info") == 0) flag_bits |= DWARF_LOG_DEBUG_INFO; - else if (::strcasecmp (arg, "line") == 0) flag_bits |= DWARF_LOG_DEBUG_LINE; - else if (::strcasecmp (arg, "pubnames") == 0) flag_bits |= DWARF_LOG_DEBUG_PUBNAMES; - else if (::strcasecmp (arg, "pubtypes") == 0) flag_bits |= DWARF_LOG_DEBUG_PUBTYPES; - else if (::strcasecmp (arg, "aranges") == 0) flag_bits |= DWARF_LOG_DEBUG_ARANGES; - else if (::strcasecmp (arg, "lookups") == 0) flag_bits |= DWARF_LOG_LOOKUPS; - else if (::strcasecmp (arg, "map") == 0) flag_bits |= DWARF_LOG_DEBUG_MAP; - else if (::strcasecmp (arg, "default") == 0) flag_bits |= DWARF_LOG_DEFAULT; - else if (::strcasecmp (arg, "verbose") == 0) flag_bits |= DWARF_LOG_VERBOSE; - else if (::strncasecmp(arg, "comp", 4) == 0) flag_bits |= DWARF_LOG_TYPE_COMPLETION; - else - { - feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); - if (got_unknown_category == false) - { - got_unknown_category = true; - ListCategories (feedback_strm); - } - } + uint32_t flag_bits = m_log_ap->GetMask().Get(); + for (size_t i = 0; categories[i] != NULL; ++i) { + const char *arg = categories[i]; + + if (::strcasecmp(arg, "all") == 0) + flag_bits &= ~DWARF_LOG_ALL; + else if (::strcasecmp(arg, "info") == 0) + flag_bits &= ~DWARF_LOG_DEBUG_INFO; + else if (::strcasecmp(arg, "line") == 0) + flag_bits &= ~DWARF_LOG_DEBUG_LINE; + else if (::strcasecmp(arg, "pubnames") == 0) + flag_bits &= ~DWARF_LOG_DEBUG_PUBNAMES; + else if (::strcasecmp(arg, "pubtypes") == 0) + flag_bits &= ~DWARF_LOG_DEBUG_PUBTYPES; + else if (::strcasecmp(arg, "aranges") == 0) + flag_bits &= ~DWARF_LOG_DEBUG_ARANGES; + else if (::strcasecmp(arg, "lookups") == 0) + flag_bits &= ~DWARF_LOG_LOOKUPS; + else if (::strcasecmp(arg, "map") == 0) + flag_bits &= ~DWARF_LOG_DEBUG_MAP; + else if (::strcasecmp(arg, "default") == 0) + flag_bits &= ~DWARF_LOG_DEFAULT; + else if (::strcasecmp(arg, "verbose") == 0) + flag_bits &= ~DWARF_LOG_VERBOSE; + else if (::strncasecmp(arg, "comp", 4) == 0) + flag_bits &= ~DWARF_LOG_TYPE_COMPLETION; + else { + feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); + ListCategories(feedback_strm); } - if (flag_bits == 0) - flag_bits = DWARF_LOG_DEFAULT; - m_log_ap->GetMask().Reset(flag_bits); - m_log_ap->GetOptions().Reset(log_options); - return m_log_ap.get() != NULL; -} - -void -LogChannelDWARF::ListCategories (Stream *strm) -{ - strm->Printf ("Logging categories for '%s':\n" - " all - turn on all available logging categories\n" - " info - log the parsing of .debug_info\n" - " line - log the parsing of .debug_line\n" - " pubnames - log the parsing of .debug_pubnames\n" - " pubtypes - log the parsing of .debug_pubtypes\n" - " aranges - log the parsing of .debug_aranges\n" - " lookups - log any lookups that happen by name, regex, or address\n" - " completion - log struct/unions/class type completions\n" - " map - log insertions of object files into DWARF debug maps\n", - SymbolFileDWARF::GetPluginNameStatic().GetCString()); -} - -Log * -LogChannelDWARF::GetLog () -{ - if (g_log_channel) - return g_log_channel->m_log_ap.get(); + } - return NULL; -} + if (flag_bits == 0) + Delete(); + else + m_log_ap->GetMask().Reset(flag_bits); -Log * -LogChannelDWARF::GetLogIfAll (uint32_t mask) -{ - if (g_log_channel && g_log_channel->m_log_ap.get()) - { - if (g_log_channel->m_log_ap->GetMask().AllSet(mask)) - return g_log_channel->m_log_ap.get(); - } - return NULL; + return; } -Log * -LogChannelDWARF::GetLogIfAny (uint32_t mask) -{ - if (g_log_channel && g_log_channel->m_log_ap.get()) - { - if (g_log_channel->m_log_ap->GetMask().AnySet(mask)) - return g_log_channel->m_log_ap.get(); +bool LogChannelDWARF::Enable( + StreamSP &log_stream_sp, uint32_t log_options, + Stream *feedback_strm, // Feedback stream for argument errors etc + const char **categories // The categories to enable within this logging + // stream, if empty, enable default set + ) { + Delete(); + + if (m_log_ap) + m_log_ap->SetStream(log_stream_sp); + else + m_log_ap.reset(new Log(log_stream_sp)); + + g_log_channel = this; + uint32_t flag_bits = 0; + bool got_unknown_category = false; + for (size_t i = 0; categories[i] != NULL; ++i) { + const char *arg = categories[i]; + + if (::strcasecmp(arg, "all") == 0) + flag_bits |= DWARF_LOG_ALL; + else if (::strcasecmp(arg, "info") == 0) + flag_bits |= DWARF_LOG_DEBUG_INFO; + else if (::strcasecmp(arg, "line") == 0) + flag_bits |= DWARF_LOG_DEBUG_LINE; + else if (::strcasecmp(arg, "pubnames") == 0) + flag_bits |= DWARF_LOG_DEBUG_PUBNAMES; + else if (::strcasecmp(arg, "pubtypes") == 0) + flag_bits |= DWARF_LOG_DEBUG_PUBTYPES; + else if (::strcasecmp(arg, "aranges") == 0) + flag_bits |= DWARF_LOG_DEBUG_ARANGES; + else if (::strcasecmp(arg, "lookups") == 0) + flag_bits |= DWARF_LOG_LOOKUPS; + else if (::strcasecmp(arg, "map") == 0) + flag_bits |= DWARF_LOG_DEBUG_MAP; + else if (::strcasecmp(arg, "default") == 0) + flag_bits |= DWARF_LOG_DEFAULT; + else if (::strcasecmp(arg, "verbose") == 0) + flag_bits |= DWARF_LOG_VERBOSE; + else if (::strncasecmp(arg, "comp", 4) == 0) + flag_bits |= DWARF_LOG_TYPE_COMPLETION; + else { + feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); + if (got_unknown_category == false) { + got_unknown_category = true; + ListCategories(feedback_strm); + } } - return NULL; -} - -void -LogChannelDWARF::LogIf (uint32_t mask, const char *format, ...) -{ - if (g_log_channel) - { - Log *log = g_log_channel->m_log_ap.get(); - if (log && log->GetMask().AnySet(mask)) - { - va_list args; - va_start (args, format); - log->VAPrintf (format, args); - va_end (args); - } + } + if (flag_bits == 0) + flag_bits = DWARF_LOG_DEFAULT; + m_log_ap->GetMask().Reset(flag_bits); + m_log_ap->GetOptions().Reset(log_options); + return m_log_ap.get() != NULL; +} + +void LogChannelDWARF::ListCategories(Stream *strm) { + strm->Printf( + "Logging categories for '%s':\n" + " all - turn on all available logging categories\n" + " info - log the parsing of .debug_info\n" + " line - log the parsing of .debug_line\n" + " pubnames - log the parsing of .debug_pubnames\n" + " pubtypes - log the parsing of .debug_pubtypes\n" + " aranges - log the parsing of .debug_aranges\n" + " lookups - log any lookups that happen by name, regex, or address\n" + " completion - log struct/unions/class type completions\n" + " map - log insertions of object files into DWARF debug maps\n", + SymbolFileDWARF::GetPluginNameStatic().GetCString()); +} + +Log *LogChannelDWARF::GetLog() { + if (g_log_channel) + return g_log_channel->m_log_ap.get(); + + return NULL; +} + +Log *LogChannelDWARF::GetLogIfAll(uint32_t mask) { + if (g_log_channel && g_log_channel->m_log_ap.get()) { + if (g_log_channel->m_log_ap->GetMask().AllSet(mask)) + return g_log_channel->m_log_ap.get(); + } + return NULL; +} + +Log *LogChannelDWARF::GetLogIfAny(uint32_t mask) { + if (g_log_channel && g_log_channel->m_log_ap.get()) { + if (g_log_channel->m_log_ap->GetMask().AnySet(mask)) + return g_log_channel->m_log_ap.get(); + } + return NULL; +} + +void LogChannelDWARF::LogIf(uint32_t mask, const char *format, ...) { + if (g_log_channel) { + Log *log = g_log_channel->m_log_ap.get(); + if (log && log->GetMask().AnySet(mask)) { + va_list args; + va_start(args, format); + log->VAPrintf(format, args); + va_end(args); } + } } diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h index 24fa7d148cd3..4802f858f3a1 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h @@ -16,72 +16,59 @@ // Project includes #include "lldb/Core/Log.h" -#define DWARF_LOG_VERBOSE (1u << 0) -#define DWARF_LOG_DEBUG_INFO (1u << 1) -#define DWARF_LOG_DEBUG_LINE (1u << 2) -#define DWARF_LOG_DEBUG_PUBNAMES (1u << 3) -#define DWARF_LOG_DEBUG_PUBTYPES (1u << 4) -#define DWARF_LOG_DEBUG_ARANGES (1u << 5) -#define DWARF_LOG_LOOKUPS (1u << 6) -#define DWARF_LOG_TYPE_COMPLETION (1u << 7) -#define DWARF_LOG_DEBUG_MAP (1u << 8) -#define DWARF_LOG_ALL (UINT32_MAX) -#define DWARF_LOG_DEFAULT (DWARF_LOG_DEBUG_INFO) - -class LogChannelDWARF : public lldb_private::LogChannel -{ +#define DWARF_LOG_VERBOSE (1u << 0) +#define DWARF_LOG_DEBUG_INFO (1u << 1) +#define DWARF_LOG_DEBUG_LINE (1u << 2) +#define DWARF_LOG_DEBUG_PUBNAMES (1u << 3) +#define DWARF_LOG_DEBUG_PUBTYPES (1u << 4) +#define DWARF_LOG_DEBUG_ARANGES (1u << 5) +#define DWARF_LOG_LOOKUPS (1u << 6) +#define DWARF_LOG_TYPE_COMPLETION (1u << 7) +#define DWARF_LOG_DEBUG_MAP (1u << 8) +#define DWARF_LOG_ALL (UINT32_MAX) +#define DWARF_LOG_DEFAULT (DWARF_LOG_DEBUG_INFO) + +class LogChannelDWARF : public lldb_private::LogChannel { public: - LogChannelDWARF (); + LogChannelDWARF(); - ~LogChannelDWARF() override; + ~LogChannelDWARF() override; - static void - Initialize(); + static void Initialize(); - static void - Terminate(); + static void Terminate(); - static lldb_private::ConstString - GetPluginNameStatic(); + static lldb_private::ConstString GetPluginNameStatic(); - static const char * - GetPluginDescriptionStatic(); + static const char *GetPluginDescriptionStatic(); - static lldb_private::LogChannel * - CreateInstance (); + static lldb_private::LogChannel *CreateInstance(); - lldb_private::ConstString - GetPluginName() override; + lldb_private::ConstString GetPluginName() override; - uint32_t - GetPluginVersion() override; + uint32_t GetPluginVersion() override; - void - Disable(const char** categories, lldb_private::Stream *feedback_strm) override; + void Disable(const char **categories, + lldb_private::Stream *feedback_strm) override; - void - Delete (); + void Delete(); - bool - Enable(lldb::StreamSP &log_stream_sp, - uint32_t log_options, - lldb_private::Stream *feedback_strm, // Feedback stream for argument errors etc - const char **categories) override; // The categories to enable within this logging stream, if empty, enable default set + bool Enable(lldb::StreamSP &log_stream_sp, uint32_t log_options, + lldb_private::Stream + *feedback_strm, // Feedback stream for argument errors etc + const char **categories) override; // The categories to enable + // within this logging stream, + // if empty, enable default set - void - ListCategories(lldb_private::Stream *strm) override; + void ListCategories(lldb_private::Stream *strm) override; - static lldb_private::Log * - GetLog (); + static lldb_private::Log *GetLog(); - static lldb_private::Log * - GetLogIfAll (uint32_t mask); - - static lldb_private::Log * - GetLogIfAny (uint32_t mask); - - static void - LogIf (uint32_t mask, const char *format, ...); + static lldb_private::Log *GetLogIfAll(uint32_t mask); + + static lldb_private::Log *GetLogIfAny(uint32_t mask); + + static void LogIf(uint32_t mask, const char *format, ...); }; #endif // SymbolFileDWARF_LogChannelDWARF_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp index fe02adbb6c87..c3d90d171b79 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp @@ -9,9 +9,9 @@ #include "NameToDIE.h" #include "lldb/Core/ConstString.h" +#include "lldb/Core/RegularExpression.h" #include "lldb/Core/Stream.h" #include "lldb/Core/StreamString.h" -#include "lldb/Core/RegularExpression.h" #include "lldb/Symbol/ObjectFile.h" #include "DWARFCompileUnit.h" @@ -22,75 +22,61 @@ using namespace lldb; using namespace lldb_private; -void -NameToDIE::Finalize() -{ - m_map.Sort (); - m_map.SizeToFit (); +void NameToDIE::Finalize() { + m_map.Sort(); + m_map.SizeToFit(); } -void -NameToDIE::Insert (const ConstString& name, const DIERef& die_ref) -{ - m_map.Append(name.GetCString(), die_ref); +void NameToDIE::Insert(const ConstString &name, const DIERef &die_ref) { + m_map.Append(name.GetStringRef(), die_ref); } -size_t -NameToDIE::Find (const ConstString &name, DIEArray &info_array) const -{ - return m_map.GetValues (name.GetCString(), info_array); +size_t NameToDIE::Find(const ConstString &name, DIEArray &info_array) const { + return m_map.GetValues(name.GetStringRef(), info_array); } -size_t -NameToDIE::Find (const RegularExpression& regex, DIEArray &info_array) const -{ - return m_map.GetValues (regex, info_array); +size_t NameToDIE::Find(const RegularExpression ®ex, + DIEArray &info_array) const { + return m_map.GetValues(regex, info_array); } -size_t -NameToDIE::FindAllEntriesForCompileUnit (dw_offset_t cu_offset, DIEArray &info_array) const -{ - const size_t initial_size = info_array.size(); - const uint32_t size = m_map.GetSize(); - for (uint32_t i=0; i<size; ++i) - { - const DIERef& die_ref = m_map.GetValueAtIndexUnchecked(i); - if (cu_offset == die_ref.cu_offset) - info_array.push_back (die_ref); - } - return info_array.size() - initial_size; +size_t NameToDIE::FindAllEntriesForCompileUnit(dw_offset_t cu_offset, + DIEArray &info_array) const { + const size_t initial_size = info_array.size(); + const uint32_t size = m_map.GetSize(); + for (uint32_t i = 0; i < size; ++i) { + const DIERef &die_ref = m_map.GetValueAtIndexUnchecked(i); + if (cu_offset == die_ref.cu_offset) + info_array.push_back(die_ref); + } + return info_array.size() - initial_size; } -void -NameToDIE::Dump (Stream *s) -{ - const uint32_t size = m_map.GetSize(); - for (uint32_t i=0; i<size; ++i) - { - const char *cstr = m_map.GetCStringAtIndex(i); - const DIERef& die_ref = m_map.GetValueAtIndexUnchecked(i); - s->Printf("%p: {0x%8.8x/0x%8.8x} \"%s\"\n", (const void*) cstr, die_ref.cu_offset, die_ref.die_offset, cstr); - } +void NameToDIE::Dump(Stream *s) { + const uint32_t size = m_map.GetSize(); + for (uint32_t i = 0; i < size; ++i) { + llvm::StringRef cstr = m_map.GetCStringAtIndex(i); + const DIERef &die_ref = m_map.GetValueAtIndexUnchecked(i); + s->Printf("%p: {0x%8.8x/0x%8.8x} \"%s\"\n", (const void *)cstr.data(), + die_ref.cu_offset, die_ref.die_offset, cstr.str().c_str()); + } } -void -NameToDIE::ForEach (std::function <bool(const char *name, const DIERef& die_ref)> const &callback) const -{ - const uint32_t size = m_map.GetSize(); - for (uint32_t i=0; i<size; ++i) - { - if (!callback(m_map.GetCStringAtIndexUnchecked(i), m_map.GetValueAtIndexUnchecked (i))) - break; - } +void NameToDIE::ForEach( + std::function<bool(llvm::StringRef name, const DIERef &die_ref)> const + &callback) const { + const uint32_t size = m_map.GetSize(); + for (uint32_t i = 0; i < size; ++i) { + if (!callback(m_map.GetCStringAtIndexUnchecked(i), + m_map.GetValueAtIndexUnchecked(i))) + break; + } } -void -NameToDIE::Append (const NameToDIE& other) -{ - const uint32_t size = other.m_map.GetSize(); - for (uint32_t i = 0; i < size; ++i) - { - m_map.Append(other.m_map.GetCStringAtIndexUnchecked (i), - other.m_map.GetValueAtIndexUnchecked (i)); - } +void NameToDIE::Append(const NameToDIE &other) { + const uint32_t size = other.m_map.GetSize(); + for (uint32_t i = 0; i < size; ++i) { + m_map.Append(other.m_map.GetCStringAtIndexUnchecked(i), + other.m_map.GetValueAtIndexUnchecked(i)); + } } diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h index 7fc66138f51e..e3fe321338a2 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h @@ -12,51 +12,42 @@ #include <functional> -#include "lldb/Core/dwarf.h" +#include "DIERef.h" #include "lldb/Core/UniqueCStringMap.h" +#include "lldb/Core/dwarf.h" #include "lldb/lldb-defines.h" -#include "DIERef.h" class SymbolFileDWARF; -class NameToDIE -{ +class NameToDIE { public: - NameToDIE () : - m_map() - { - } + NameToDIE() : m_map() {} + + ~NameToDIE() {} - ~NameToDIE () - { - } + void Dump(lldb_private::Stream *s); - void - Dump (lldb_private::Stream *s); + void Insert(const lldb_private::ConstString &name, const DIERef &die_ref); - void - Insert (const lldb_private::ConstString& name, const DIERef& die_ref); + void Append(const NameToDIE &other); - void - Append (const NameToDIE& other); + void Finalize(); - void - Finalize(); + size_t Find(const lldb_private::ConstString &name, + DIEArray &info_array) const; - size_t - Find (const lldb_private::ConstString &name, DIEArray &info_array) const; - - size_t - Find (const lldb_private::RegularExpression& regex, DIEArray &info_array) const; + size_t Find(const lldb_private::RegularExpression ®ex, + DIEArray &info_array) const; - size_t - FindAllEntriesForCompileUnit (dw_offset_t cu_offset, DIEArray &info_array) const; + size_t FindAllEntriesForCompileUnit(dw_offset_t cu_offset, + DIEArray &info_array) const; - void - ForEach (std::function <bool(const char *name, const DIERef& die_ref)> const &callback) const; + void + ForEach(std::function<bool(llvm::StringRef name, const DIERef &die_ref)> const + &callback) const; protected: - lldb_private::UniqueCStringMap<DIERef> m_map; + lldb_private::UniqueCStringMap<DIERef> m_map; }; -#endif // SymbolFileDWARF_NameToDIE_h_ +#endif // SymbolFileDWARF_NameToDIE_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 942a5d62d9b4..5c44ee03b02c 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -88,8 +88,8 @@ using namespace lldb; using namespace lldb_private; -//static inline bool -//child_requires_parent_class_union_or_struct_to_be_completed (dw_tag_t tag) +// static inline bool +// child_requires_parent_class_union_or_struct_to_be_completed (dw_tag_t tag) //{ // switch (tag) // { @@ -108,4713 +108,4174 @@ using namespace lldb_private; namespace { - 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." }, - { nullptr , OptionValue::eTypeInvalid , false, 0, nullptr, nullptr, nullptr } - }; - - enum - { - ePropertySymLinkPaths - }; - - - class PluginProperties : public Properties - { - public: - static ConstString - GetSettingName() - { - return SymbolFileDWARF::GetPluginNameStatic(); - } +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."}, + {nullptr, OptionValue::eTypeInvalid, false, 0, nullptr, nullptr, nullptr}}; + +enum { ePropertySymLinkPaths }; + +class PluginProperties : public Properties { +public: + static ConstString GetSettingName() { + return SymbolFileDWARF::GetPluginNameStatic(); + } + + PluginProperties() { + m_collection_sp.reset(new OptionValueProperties(GetSettingName())); + m_collection_sp->Initialize(g_properties); + } + + FileSpecList &GetSymLinkPaths() { + OptionValueFileSpecList *option_value = + m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList( + nullptr, true, ePropertySymLinkPaths); + assert(option_value); + return option_value->GetCurrentValue(); + } +}; - PluginProperties() - { - m_collection_sp.reset (new OptionValueProperties(GetSettingName())); - m_collection_sp->Initialize(g_properties); - } +typedef std::shared_ptr<PluginProperties> SymbolFileDWARFPropertiesSP; - FileSpecList& - GetSymLinkPaths() - { - OptionValueFileSpecList *option_value = m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr, true, ePropertySymLinkPaths); - assert(option_value); - return option_value->GetCurrentValue(); - } +static const SymbolFileDWARFPropertiesSP &GetGlobalPluginProperties() { + static const auto g_settings_sp(std::make_shared<PluginProperties>()); + return g_settings_sp; +} - }; +} // anonymous namespace end - typedef std::shared_ptr<PluginProperties> SymbolFileDWARFPropertiesSP; +static const char *removeHostnameFromPathname(const char *path_from_dwarf) { + if (!path_from_dwarf || !path_from_dwarf[0]) { + return path_from_dwarf; + } - static const SymbolFileDWARFPropertiesSP& - GetGlobalPluginProperties() - { - static const auto g_settings_sp(std::make_shared<PluginProperties>()); - return g_settings_sp; - } + const char *colon_pos = strchr(path_from_dwarf, ':'); + if (nullptr == colon_pos) { + return path_from_dwarf; + } -} // anonymous namespace end + const char *slash_pos = strchr(path_from_dwarf, '/'); + if (slash_pos && (slash_pos < colon_pos)) { + return path_from_dwarf; + } + // check whether we have a windows path, and so the first character + // is a drive-letter not a hostname. + if (colon_pos == path_from_dwarf + 1 && isalpha(*path_from_dwarf) && + strlen(path_from_dwarf) > 2 && '\\' == path_from_dwarf[2]) { + return path_from_dwarf; + } -static const char* -removeHostnameFromPathname(const char* path_from_dwarf) -{ - if (!path_from_dwarf || !path_from_dwarf[0]) - { - return path_from_dwarf; - } - - const char *colon_pos = strchr(path_from_dwarf, ':'); - if (nullptr == colon_pos) - { - return path_from_dwarf; - } - - const char *slash_pos = strchr(path_from_dwarf, '/'); - if (slash_pos && (slash_pos < colon_pos)) - { - return path_from_dwarf; - } - - // check whether we have a windows path, and so the first character - // is a drive-letter not a hostname. - if ( - colon_pos == path_from_dwarf + 1 && - isalpha(*path_from_dwarf) && - strlen(path_from_dwarf) > 2 && - '\\' == path_from_dwarf[2]) - { - return path_from_dwarf; - } - - return colon_pos + 1; + return colon_pos + 1; } -static const char* -resolveCompDir(const char* path_from_dwarf) -{ - if (!path_from_dwarf) - return nullptr; +static const char *resolveCompDir(const char *path_from_dwarf) { + if (!path_from_dwarf) + return nullptr; - // DWARF2/3 suggests the form hostname:pathname for compilation directory. - // Remove the host part if present. - const char* local_path = removeHostnameFromPathname(path_from_dwarf); - if (!local_path) - return nullptr; + // DWARF2/3 suggests the form hostname:pathname for compilation directory. + // Remove the host part if present. + const char *local_path = removeHostnameFromPathname(path_from_dwarf); + if (!local_path) + return nullptr; - bool is_symlink = false; - FileSpec local_path_spec(local_path, false); - 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), local_path_spec, true); + bool is_symlink = false; + FileSpec local_path_spec(local_path, false); + 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), + local_path_spec, true); - if (!is_symlink) - return local_path; + if (!is_symlink) + return local_path; - if (!local_path_spec.IsSymbolicLink()) - return local_path; + if (!local_path_spec.IsSymbolicLink()) + return local_path; - FileSpec resolved_local_path_spec; - const auto error = FileSystem::Readlink(local_path_spec, resolved_local_path_spec); - if (error.Success()) - return resolved_local_path_spec.GetCString(); + FileSpec resolved_local_path_spec; + const auto error = + FileSystem::Readlink(local_path_spec, resolved_local_path_spec); + if (error.Success()) + return resolved_local_path_spec.GetCString(); - return nullptr; + return nullptr; } - -void -SymbolFileDWARF::Initialize() -{ - LogChannelDWARF::Initialize(); - PluginManager::RegisterPlugin (GetPluginNameStatic(), - GetPluginDescriptionStatic(), - CreateInstance, - DebuggerInitialize); +void SymbolFileDWARF::Initialize() { + LogChannelDWARF::Initialize(); + PluginManager::RegisterPlugin(GetPluginNameStatic(), + GetPluginDescriptionStatic(), CreateInstance, + DebuggerInitialize); } -void -SymbolFileDWARF::DebuggerInitialize(Debugger &debugger) -{ - if (!PluginManager::GetSettingForSymbolFilePlugin(debugger, PluginProperties::GetSettingName())) - { - const bool is_global_setting = true; - PluginManager::CreateSettingForSymbolFilePlugin(debugger, - GetGlobalPluginProperties()->GetValueProperties(), - ConstString ("Properties for the dwarf symbol-file plug-in."), - is_global_setting); - } +void SymbolFileDWARF::DebuggerInitialize(Debugger &debugger) { + if (!PluginManager::GetSettingForSymbolFilePlugin( + debugger, PluginProperties::GetSettingName())) { + const bool is_global_setting = true; + PluginManager::CreateSettingForSymbolFilePlugin( + debugger, GetGlobalPluginProperties()->GetValueProperties(), + ConstString("Properties for the dwarf symbol-file plug-in."), + is_global_setting); + } } -void -SymbolFileDWARF::Terminate() -{ - PluginManager::UnregisterPlugin (CreateInstance); - LogChannelDWARF::Initialize(); +void SymbolFileDWARF::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); + LogChannelDWARF::Initialize(); } - -lldb_private::ConstString -SymbolFileDWARF::GetPluginNameStatic() -{ - static ConstString g_name("dwarf"); - return g_name; +lldb_private::ConstString SymbolFileDWARF::GetPluginNameStatic() { + static ConstString g_name("dwarf"); + return g_name; } -const char * -SymbolFileDWARF::GetPluginDescriptionStatic() -{ - return "DWARF and DWARF3 debug symbol file reader."; +const char *SymbolFileDWARF::GetPluginDescriptionStatic() { + return "DWARF and DWARF3 debug symbol file reader."; } - -SymbolFile* -SymbolFileDWARF::CreateInstance (ObjectFile* obj_file) -{ - return new SymbolFileDWARF(obj_file); +SymbolFile *SymbolFileDWARF::CreateInstance(ObjectFile *obj_file) { + return new SymbolFileDWARF(obj_file); } -TypeList * -SymbolFileDWARF::GetTypeList () -{ - SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile(); - if (debug_map_symfile) - return debug_map_symfile->GetTypeList(); - else - return m_obj_file->GetModule()->GetTypeList(); - +TypeList *SymbolFileDWARF::GetTypeList() { + SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile(); + if (debug_map_symfile) + return debug_map_symfile->GetTypeList(); + else + return m_obj_file->GetModule()->GetTypeList(); } -void -SymbolFileDWARF::GetTypes (const DWARFDIE &die, - dw_offset_t min_die_offset, - dw_offset_t max_die_offset, - uint32_t type_mask, - TypeSet &type_set) -{ - if (die) - { - const dw_offset_t die_offset = die.GetOffset(); - - if (die_offset >= max_die_offset) - return; - - if (die_offset >= min_die_offset) - { - const dw_tag_t tag = die.Tag(); - - bool add_type = false; - - switch (tag) - { - case DW_TAG_array_type: add_type = (type_mask & eTypeClassArray ) != 0; break; - case DW_TAG_unspecified_type: - case DW_TAG_base_type: add_type = (type_mask & eTypeClassBuiltin ) != 0; break; - case DW_TAG_class_type: add_type = (type_mask & eTypeClassClass ) != 0; break; - case DW_TAG_structure_type: add_type = (type_mask & eTypeClassStruct ) != 0; break; - case DW_TAG_union_type: add_type = (type_mask & eTypeClassUnion ) != 0; break; - case DW_TAG_enumeration_type: add_type = (type_mask & eTypeClassEnumeration ) != 0; break; - case DW_TAG_subroutine_type: - case DW_TAG_subprogram: - case DW_TAG_inlined_subroutine: add_type = (type_mask & eTypeClassFunction ) != 0; break; - case DW_TAG_pointer_type: add_type = (type_mask & eTypeClassPointer ) != 0; break; - case DW_TAG_rvalue_reference_type: - case DW_TAG_reference_type: add_type = (type_mask & eTypeClassReference ) != 0; break; - case DW_TAG_typedef: add_type = (type_mask & eTypeClassTypedef ) != 0; break; - case DW_TAG_ptr_to_member_type: add_type = (type_mask & eTypeClassMemberPointer ) != 0; break; - } - - if (add_type) - { - const bool assert_not_being_parsed = true; - Type *type = ResolveTypeUID (die, assert_not_being_parsed); - if (type) - { - if (type_set.find(type) == type_set.end()) - type_set.insert(type); - } - } - } - - for (DWARFDIE child_die = die.GetFirstChild(); - child_die.IsValid(); - child_die = child_die.GetSibling()) - { - GetTypes (child_die, min_die_offset, max_die_offset, type_mask, type_set); +void SymbolFileDWARF::GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset, + dw_offset_t max_die_offset, uint32_t type_mask, + TypeSet &type_set) { + if (die) { + const dw_offset_t die_offset = die.GetOffset(); + + if (die_offset >= max_die_offset) + return; + + if (die_offset >= min_die_offset) { + const dw_tag_t tag = die.Tag(); + + bool add_type = false; + + switch (tag) { + case DW_TAG_array_type: + add_type = (type_mask & eTypeClassArray) != 0; + break; + case DW_TAG_unspecified_type: + case DW_TAG_base_type: + add_type = (type_mask & eTypeClassBuiltin) != 0; + break; + case DW_TAG_class_type: + add_type = (type_mask & eTypeClassClass) != 0; + break; + case DW_TAG_structure_type: + add_type = (type_mask & eTypeClassStruct) != 0; + break; + case DW_TAG_union_type: + add_type = (type_mask & eTypeClassUnion) != 0; + break; + case DW_TAG_enumeration_type: + add_type = (type_mask & eTypeClassEnumeration) != 0; + break; + case DW_TAG_subroutine_type: + case DW_TAG_subprogram: + case DW_TAG_inlined_subroutine: + add_type = (type_mask & eTypeClassFunction) != 0; + break; + case DW_TAG_pointer_type: + add_type = (type_mask & eTypeClassPointer) != 0; + break; + case DW_TAG_rvalue_reference_type: + case DW_TAG_reference_type: + add_type = (type_mask & eTypeClassReference) != 0; + break; + case DW_TAG_typedef: + add_type = (type_mask & eTypeClassTypedef) != 0; + break; + case DW_TAG_ptr_to_member_type: + add_type = (type_mask & eTypeClassMemberPointer) != 0; + break; + } + + if (add_type) { + const bool assert_not_being_parsed = true; + Type *type = ResolveTypeUID(die, assert_not_being_parsed); + if (type) { + if (type_set.find(type) == type_set.end()) + type_set.insert(type); } + } } + + for (DWARFDIE child_die = die.GetFirstChild(); child_die.IsValid(); + child_die = child_die.GetSibling()) { + GetTypes(child_die, min_die_offset, max_die_offset, type_mask, type_set); + } + } } -size_t -SymbolFileDWARF::GetTypes (SymbolContextScope *sc_scope, - uint32_t type_mask, - TypeList &type_list) +size_t SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope, + uint32_t type_mask, TypeList &type_list) { - TypeSet type_set; - - CompileUnit *comp_unit = NULL; - DWARFCompileUnit* dwarf_cu = NULL; - if (sc_scope) - comp_unit = sc_scope->CalculateSymbolContextCompileUnit(); - - if (comp_unit) - { - dwarf_cu = GetDWARFCompileUnit(comp_unit); - if (dwarf_cu == 0) - return 0; - GetTypes (dwarf_cu->DIE(), - dwarf_cu->GetOffset(), - dwarf_cu->GetNextCompileUnitOffset(), - type_mask, - type_set); - } - else - { - DWARFDebugInfo* info = DebugInfo(); - if (info) - { - const size_t num_cus = info->GetNumCompileUnits(); - for (size_t cu_idx=0; cu_idx<num_cus; ++cu_idx) - { - dwarf_cu = info->GetCompileUnitAtIndex(cu_idx); - if (dwarf_cu) - { - GetTypes (dwarf_cu->DIE(), - 0, - UINT32_MAX, - type_mask, - type_set); - } - } + TypeSet type_set; + + CompileUnit *comp_unit = NULL; + DWARFCompileUnit *dwarf_cu = NULL; + if (sc_scope) + comp_unit = sc_scope->CalculateSymbolContextCompileUnit(); + + if (comp_unit) { + dwarf_cu = GetDWARFCompileUnit(comp_unit); + if (dwarf_cu == 0) + return 0; + GetTypes(dwarf_cu->DIE(), dwarf_cu->GetOffset(), + dwarf_cu->GetNextCompileUnitOffset(), type_mask, type_set); + } else { + DWARFDebugInfo *info = DebugInfo(); + if (info) { + const size_t num_cus = info->GetNumCompileUnits(); + for (size_t cu_idx = 0; cu_idx < num_cus; ++cu_idx) { + dwarf_cu = info->GetCompileUnitAtIndex(cu_idx); + if (dwarf_cu) { + GetTypes(dwarf_cu->DIE(), 0, UINT32_MAX, type_mask, type_set); } + } } - - std::set<CompilerType> compiler_type_set; - size_t num_types_added = 0; - for (Type *type : type_set) - { - CompilerType compiler_type = type->GetForwardCompilerType (); - if (compiler_type_set.find(compiler_type) == compiler_type_set.end()) - { - compiler_type_set.insert(compiler_type); - type_list.Insert (type->shared_from_this()); - ++num_types_added; - } + } + + std::set<CompilerType> compiler_type_set; + size_t num_types_added = 0; + for (Type *type : type_set) { + CompilerType compiler_type = type->GetForwardCompilerType(); + if (compiler_type_set.find(compiler_type) == compiler_type_set.end()) { + compiler_type_set.insert(compiler_type); + type_list.Insert(type->shared_from_this()); + ++num_types_added; } - return num_types_added; + } + return num_types_added; } - //---------------------------------------------------------------------- // Gets the first parent that is a lexical block, function or inlined // subroutine, or compile unit. //---------------------------------------------------------------------- DWARFDIE -SymbolFileDWARF::GetParentSymbolContextDIE(const DWARFDIE &child_die) -{ - DWARFDIE die; - for (die = child_die.GetParent(); die; die = die.GetParent()) - { - dw_tag_t tag = die.Tag(); - - switch (tag) - { - case DW_TAG_compile_unit: - case DW_TAG_subprogram: - case DW_TAG_inlined_subroutine: - case DW_TAG_lexical_block: - return die; - } +SymbolFileDWARF::GetParentSymbolContextDIE(const DWARFDIE &child_die) { + DWARFDIE die; + for (die = child_die.GetParent(); die; die = die.GetParent()) { + dw_tag_t tag = die.Tag(); + + switch (tag) { + case DW_TAG_compile_unit: + case DW_TAG_subprogram: + case DW_TAG_inlined_subroutine: + case DW_TAG_lexical_block: + return die; } - return DWARFDIE(); + } + return DWARFDIE(); } - -SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) : - SymbolFile (objfile), - UserID (0), // Used by SymbolFileDWARFDebugMap to when this class parses .o files to contain the .o file index/ID - 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_apple_names_ap (), - m_apple_types_ap (), - m_apple_namespaces_ap (), - m_apple_objc_ap (), - m_function_basename_index(), - m_function_fullname_index(), - m_function_method_index(), - m_function_selector_index(), - m_objc_class_selectors_index(), - m_global_index(), - m_type_index(), - m_namespace_index(), - m_indexed (false), - m_using_apple_tables (false), - m_fetched_external_modules (false), - m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate), - m_ranges(), - m_unique_ast_type_map () -{ +SymbolFileDWARF::SymbolFileDWARF(ObjectFile *objfile) + : SymbolFile(objfile), UserID(0), // Used by SymbolFileDWARFDebugMap to when + // this class parses .o files to contain + // the .o file index/ID + 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_apple_names_ap(), m_apple_types_ap(), m_apple_namespaces_ap(), + m_apple_objc_ap(), m_function_basename_index(), + m_function_fullname_index(), m_function_method_index(), + m_function_selector_index(), m_objc_class_selectors_index(), + m_global_index(), m_type_index(), m_namespace_index(), m_indexed(false), + m_using_apple_tables(false), m_fetched_external_modules(false), + m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate), m_ranges(), + m_unique_ast_type_map() {} + +SymbolFileDWARF::~SymbolFileDWARF() {} + +static const ConstString &GetDWARFMachOSegmentName() { + static ConstString g_dwarf_section_name("__DWARF"); + return g_dwarf_section_name; } -SymbolFileDWARF::~SymbolFileDWARF() -{ +UniqueDWARFASTTypeMap &SymbolFileDWARF::GetUniqueDWARFASTTypeMap() { + SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile(); + if (debug_map_symfile) + return debug_map_symfile->GetUniqueDWARFASTTypeMap(); + else + return m_unique_ast_type_map; } -static const ConstString & -GetDWARFMachOSegmentName () -{ - static ConstString g_dwarf_section_name ("__DWARF"); - return g_dwarf_section_name; +TypeSystem *SymbolFileDWARF::GetTypeSystemForLanguage(LanguageType language) { + SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile(); + TypeSystem *type_system; + if (debug_map_symfile) { + type_system = debug_map_symfile->GetTypeSystemForLanguage(language); + } else { + type_system = m_obj_file->GetModule()->GetTypeSystemForLanguage(language); + if (type_system) + type_system->SetSymbolFile(this); + } + return type_system; } -UniqueDWARFASTTypeMap & -SymbolFileDWARF::GetUniqueDWARFASTTypeMap () -{ - SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile(); - if (debug_map_symfile) - return debug_map_symfile->GetUniqueDWARFASTTypeMap (); +void SymbolFileDWARF::InitializeObject() { + ModuleSP module_sp(m_obj_file->GetModule()); + if (module_sp) { + const SectionList *section_list = module_sp->GetSectionList(); + const Section *section = + section_list->FindSectionByName(GetDWARFMachOSegmentName()).get(); + + // Memory map the DWARF mach-o segment so we have everything mmap'ed + // to keep our heap memory usage down. + if (section) + m_obj_file->MemoryMapSectionData(section, m_dwarf_data); + } + + get_apple_names_data(); + if (m_data_apple_names.m_data.GetByteSize() > 0) { + m_apple_names_ap.reset(new DWARFMappedHash::MemoryTable( + m_data_apple_names.m_data, get_debug_str_data(), ".apple_names")); + if (m_apple_names_ap->IsValid()) + m_using_apple_tables = true; else - return m_unique_ast_type_map; -} - -TypeSystem * -SymbolFileDWARF::GetTypeSystemForLanguage (LanguageType language) -{ - SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile(); - TypeSystem *type_system; - if (debug_map_symfile) - { - type_system = debug_map_symfile->GetTypeSystemForLanguage(language); - } + m_apple_names_ap.reset(); + } + get_apple_types_data(); + if (m_data_apple_types.m_data.GetByteSize() > 0) { + m_apple_types_ap.reset(new DWARFMappedHash::MemoryTable( + m_data_apple_types.m_data, get_debug_str_data(), ".apple_types")); + if (m_apple_types_ap->IsValid()) + m_using_apple_tables = true; else - { - type_system = m_obj_file->GetModule()->GetTypeSystemForLanguage(language); - if (type_system) - type_system->SetSymbolFile(this); - } - return type_system; -} - -void -SymbolFileDWARF::InitializeObject() -{ - ModuleSP module_sp (m_obj_file->GetModule()); - if (module_sp) - { - const SectionList *section_list = module_sp->GetSectionList(); - const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get(); - - // Memory map the DWARF mach-o segment so we have everything mmap'ed - // to keep our heap memory usage down. - if (section) - m_obj_file->MemoryMapSectionData(section, m_dwarf_data); - } - - get_apple_names_data(); - if (m_data_apple_names.m_data.GetByteSize() > 0) - { - m_apple_names_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_names.m_data, - get_debug_str_data(), - ".apple_names")); - if (m_apple_names_ap->IsValid()) - m_using_apple_tables = true; - else - m_apple_names_ap.reset(); - } - get_apple_types_data(); - if (m_data_apple_types.m_data.GetByteSize() > 0) - { - m_apple_types_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_types.m_data, - get_debug_str_data(), - ".apple_types")); - if (m_apple_types_ap->IsValid()) - m_using_apple_tables = true; - else - m_apple_types_ap.reset(); - } - - get_apple_namespaces_data(); - if (m_data_apple_namespaces.m_data.GetByteSize() > 0) - { - m_apple_namespaces_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_namespaces.m_data, - get_debug_str_data(), - ".apple_namespaces")); - if (m_apple_namespaces_ap->IsValid()) - m_using_apple_tables = true; - else - m_apple_namespaces_ap.reset(); - } - - get_apple_objc_data(); - if (m_data_apple_objc.m_data.GetByteSize() > 0) - { - m_apple_objc_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_objc.m_data, - get_debug_str_data(), - ".apple_objc")); - if (m_apple_objc_ap->IsValid()) - m_using_apple_tables = true; - else - m_apple_objc_ap.reset(); - } + m_apple_types_ap.reset(); + } + + get_apple_namespaces_data(); + if (m_data_apple_namespaces.m_data.GetByteSize() > 0) { + m_apple_namespaces_ap.reset(new DWARFMappedHash::MemoryTable( + m_data_apple_namespaces.m_data, get_debug_str_data(), + ".apple_namespaces")); + if (m_apple_namespaces_ap->IsValid()) + m_using_apple_tables = true; + else + m_apple_namespaces_ap.reset(); + } + + get_apple_objc_data(); + if (m_data_apple_objc.m_data.GetByteSize() > 0) { + m_apple_objc_ap.reset(new DWARFMappedHash::MemoryTable( + m_data_apple_objc.m_data, get_debug_str_data(), ".apple_objc")); + if (m_apple_objc_ap->IsValid()) + m_using_apple_tables = true; + else + m_apple_objc_ap.reset(); + } } -bool -SymbolFileDWARF::SupportedVersion(uint16_t version) -{ - return version == 2 || version == 3 || version == 4; +bool SymbolFileDWARF::SupportedVersion(uint16_t version) { + return version == 2 || version == 3 || version == 4; } -uint32_t -SymbolFileDWARF::CalculateAbilities () -{ - uint32_t abilities = 0; - if (m_obj_file != NULL) - { - const Section* section = NULL; - const SectionList *section_list = m_obj_file->GetSectionList(); - if (section_list == NULL) - return 0; - - uint64_t debug_abbrev_file_size = 0; - uint64_t debug_info_file_size = 0; - uint64_t debug_line_file_size = 0; - - section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get(); - - if (section) - section_list = §ion->GetChildren (); - - section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get(); - if (section != NULL) - { - debug_info_file_size = section->GetFileSize(); - - section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get(); - if (section) - debug_abbrev_file_size = section->GetFileSize(); - - section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get(); - if (section) - debug_line_file_size = section->GetFileSize(); - } - else - { - const char *symfile_dir_cstr = m_obj_file->GetFileSpec().GetDirectory().GetCString(); - if (symfile_dir_cstr) - { - if (strcasestr(symfile_dir_cstr, ".dsym")) - { - if (m_obj_file->GetType() == ObjectFile::eTypeDebugInfo) - { - // We have a dSYM file that didn't have a any debug info. - // If the string table has a size of 1, then it was made from - // an executable with no debug info, or from an executable that - // was stripped. - section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get(); - if (section && section->GetFileSize() == 1) - { - m_obj_file->GetModule()->ReportWarning ("empty dSYM file detected, dSYM was created with an executable with no debug info."); - } - } - } +uint32_t SymbolFileDWARF::CalculateAbilities() { + uint32_t abilities = 0; + if (m_obj_file != NULL) { + const Section *section = NULL; + const SectionList *section_list = m_obj_file->GetSectionList(); + if (section_list == NULL) + return 0; + + uint64_t debug_abbrev_file_size = 0; + uint64_t debug_info_file_size = 0; + uint64_t debug_line_file_size = 0; + + section = section_list->FindSectionByName(GetDWARFMachOSegmentName()).get(); + + if (section) + section_list = §ion->GetChildren(); + + section = + section_list->FindSectionByType(eSectionTypeDWARFDebugInfo, true).get(); + if (section != NULL) { + debug_info_file_size = section->GetFileSize(); + + section = + section_list->FindSectionByType(eSectionTypeDWARFDebugAbbrev, true) + .get(); + if (section) + debug_abbrev_file_size = section->GetFileSize(); + + section = + section_list->FindSectionByType(eSectionTypeDWARFDebugLine, true) + .get(); + if (section) + debug_line_file_size = section->GetFileSize(); + } else { + const char *symfile_dir_cstr = + m_obj_file->GetFileSpec().GetDirectory().GetCString(); + if (symfile_dir_cstr) { + if (strcasestr(symfile_dir_cstr, ".dsym")) { + if (m_obj_file->GetType() == ObjectFile::eTypeDebugInfo) { + // We have a dSYM file that didn't have a any debug info. + // If the string table has a size of 1, then it was made from + // an executable with no debug info, or from an executable that + // was stripped. + section = + section_list->FindSectionByType(eSectionTypeDWARFDebugStr, true) + .get(); + if (section && section->GetFileSize() == 1) { + m_obj_file->GetModule()->ReportWarning( + "empty dSYM file detected, dSYM was created with an " + "executable with no debug info."); } + } } + } + } - if (debug_abbrev_file_size > 0 && debug_info_file_size > 0) - abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes; + if (debug_abbrev_file_size > 0 && debug_info_file_size > 0) + abilities |= CompileUnits | Functions | Blocks | GlobalVariables | + LocalVariables | VariableTypes; - if (debug_line_file_size > 0) - abilities |= LineTables; - } - return abilities; + if (debug_line_file_size > 0) + abilities |= LineTables; + } + return abilities; } -const DWARFDataExtractor& -SymbolFileDWARF::GetCachedSectionData (lldb::SectionType sect_type, DWARFDataSegment& data_segment) -{ - std::call_once(data_segment.m_flag, - &SymbolFileDWARF::LoadSectionData, - this, - sect_type, - std::ref(data_segment.m_data)); - return data_segment.m_data; +const DWARFDataExtractor & +SymbolFileDWARF::GetCachedSectionData(lldb::SectionType sect_type, + DWARFDataSegment &data_segment) { + std::call_once(data_segment.m_flag, &SymbolFileDWARF::LoadSectionData, this, + sect_type, std::ref(data_segment.m_data)); + return data_segment.m_data; } -void -SymbolFileDWARF::LoadSectionData (lldb::SectionType sect_type, DWARFDataExtractor& data) -{ - ModuleSP module_sp (m_obj_file->GetModule()); - const SectionList *section_list = module_sp->GetSectionList(); - if (section_list) - { - SectionSP section_sp (section_list->FindSectionByType(sect_type, true)); - if (section_sp) - { - // See if we memory mapped the DWARF segment? - if (m_dwarf_data.GetByteSize()) - { - data.SetData(m_dwarf_data, section_sp->GetOffset(), section_sp->GetFileSize()); - } - else - { - if (m_obj_file->ReadSectionData(section_sp.get(), data) == 0) - data.Clear(); - } - } +void SymbolFileDWARF::LoadSectionData(lldb::SectionType sect_type, + DWARFDataExtractor &data) { + ModuleSP module_sp(m_obj_file->GetModule()); + const SectionList *section_list = module_sp->GetSectionList(); + if (section_list) { + SectionSP section_sp(section_list->FindSectionByType(sect_type, true)); + if (section_sp) { + // See if we memory mapped the DWARF segment? + if (m_dwarf_data.GetByteSize()) { + data.SetData(m_dwarf_data, section_sp->GetOffset(), + section_sp->GetFileSize()); + } else { + if (m_obj_file->ReadSectionData(section_sp.get(), data) == 0) + data.Clear(); + } } + } } -const DWARFDataExtractor& -SymbolFileDWARF::get_debug_abbrev_data() -{ - return GetCachedSectionData (eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev); +const DWARFDataExtractor &SymbolFileDWARF::get_debug_abbrev_data() { + return GetCachedSectionData(eSectionTypeDWARFDebugAbbrev, + m_data_debug_abbrev); } -const DWARFDataExtractor& -SymbolFileDWARF::get_debug_addr_data() -{ - return GetCachedSectionData (eSectionTypeDWARFDebugAddr, m_data_debug_addr); +const DWARFDataExtractor &SymbolFileDWARF::get_debug_addr_data() { + return GetCachedSectionData(eSectionTypeDWARFDebugAddr, m_data_debug_addr); } -const DWARFDataExtractor& -SymbolFileDWARF::get_debug_aranges_data() -{ - return GetCachedSectionData (eSectionTypeDWARFDebugAranges, m_data_debug_aranges); +const DWARFDataExtractor &SymbolFileDWARF::get_debug_aranges_data() { + return GetCachedSectionData(eSectionTypeDWARFDebugAranges, + m_data_debug_aranges); } -const DWARFDataExtractor& -SymbolFileDWARF::get_debug_frame_data() -{ - return GetCachedSectionData (eSectionTypeDWARFDebugFrame, m_data_debug_frame); +const DWARFDataExtractor &SymbolFileDWARF::get_debug_frame_data() { + return GetCachedSectionData(eSectionTypeDWARFDebugFrame, m_data_debug_frame); } -const DWARFDataExtractor& -SymbolFileDWARF::get_debug_info_data() -{ - return GetCachedSectionData (eSectionTypeDWARFDebugInfo, m_data_debug_info); +const DWARFDataExtractor &SymbolFileDWARF::get_debug_info_data() { + return GetCachedSectionData(eSectionTypeDWARFDebugInfo, m_data_debug_info); } -const DWARFDataExtractor& -SymbolFileDWARF::get_debug_line_data() -{ - return GetCachedSectionData (eSectionTypeDWARFDebugLine, m_data_debug_line); +const DWARFDataExtractor &SymbolFileDWARF::get_debug_line_data() { + return GetCachedSectionData(eSectionTypeDWARFDebugLine, m_data_debug_line); } -const DWARFDataExtractor& -SymbolFileDWARF::get_debug_macro_data() -{ - return GetCachedSectionData (eSectionTypeDWARFDebugMacro, m_data_debug_macro); +const DWARFDataExtractor &SymbolFileDWARF::get_debug_macro_data() { + return GetCachedSectionData(eSectionTypeDWARFDebugMacro, m_data_debug_macro); } -const DWARFDataExtractor& -SymbolFileDWARF::get_debug_loc_data() -{ - return GetCachedSectionData (eSectionTypeDWARFDebugLoc, m_data_debug_loc); +const DWARFDataExtractor &SymbolFileDWARF::get_debug_loc_data() { + return GetCachedSectionData(eSectionTypeDWARFDebugLoc, m_data_debug_loc); } -const DWARFDataExtractor& -SymbolFileDWARF::get_debug_ranges_data() -{ - return GetCachedSectionData (eSectionTypeDWARFDebugRanges, m_data_debug_ranges); +const DWARFDataExtractor &SymbolFileDWARF::get_debug_ranges_data() { + return GetCachedSectionData(eSectionTypeDWARFDebugRanges, + m_data_debug_ranges); } -const DWARFDataExtractor& -SymbolFileDWARF::get_debug_str_data() -{ - return GetCachedSectionData (eSectionTypeDWARFDebugStr, m_data_debug_str); +const DWARFDataExtractor &SymbolFileDWARF::get_debug_str_data() { + return GetCachedSectionData(eSectionTypeDWARFDebugStr, m_data_debug_str); } -const DWARFDataExtractor& -SymbolFileDWARF::get_debug_str_offsets_data() -{ - return GetCachedSectionData (eSectionTypeDWARFDebugStrOffsets, m_data_debug_str_offsets); +const DWARFDataExtractor &SymbolFileDWARF::get_debug_str_offsets_data() { + return GetCachedSectionData(eSectionTypeDWARFDebugStrOffsets, + m_data_debug_str_offsets); } -const DWARFDataExtractor& -SymbolFileDWARF::get_apple_names_data() -{ - return GetCachedSectionData (eSectionTypeDWARFAppleNames, m_data_apple_names); +const DWARFDataExtractor &SymbolFileDWARF::get_apple_names_data() { + return GetCachedSectionData(eSectionTypeDWARFAppleNames, m_data_apple_names); } -const DWARFDataExtractor& -SymbolFileDWARF::get_apple_types_data() -{ - return GetCachedSectionData (eSectionTypeDWARFAppleTypes, m_data_apple_types); +const DWARFDataExtractor &SymbolFileDWARF::get_apple_types_data() { + return GetCachedSectionData(eSectionTypeDWARFAppleTypes, m_data_apple_types); } -const DWARFDataExtractor& -SymbolFileDWARF::get_apple_namespaces_data() -{ - return GetCachedSectionData (eSectionTypeDWARFAppleNamespaces, m_data_apple_namespaces); +const DWARFDataExtractor &SymbolFileDWARF::get_apple_namespaces_data() { + return GetCachedSectionData(eSectionTypeDWARFAppleNamespaces, + m_data_apple_namespaces); } -const DWARFDataExtractor& -SymbolFileDWARF::get_apple_objc_data() -{ - return GetCachedSectionData (eSectionTypeDWARFAppleObjC, m_data_apple_objc); +const DWARFDataExtractor &SymbolFileDWARF::get_apple_objc_data() { + return GetCachedSectionData(eSectionTypeDWARFAppleObjC, m_data_apple_objc); } - -DWARFDebugAbbrev* -SymbolFileDWARF::DebugAbbrev() -{ - if (m_abbr.get() == NULL) - { - const DWARFDataExtractor &debug_abbrev_data = get_debug_abbrev_data(); - if (debug_abbrev_data.GetByteSize() > 0) - { - m_abbr.reset(new DWARFDebugAbbrev()); - if (m_abbr.get()) - m_abbr->Parse(debug_abbrev_data); - } +DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() { + if (m_abbr.get() == NULL) { + const DWARFDataExtractor &debug_abbrev_data = get_debug_abbrev_data(); + if (debug_abbrev_data.GetByteSize() > 0) { + m_abbr.reset(new DWARFDebugAbbrev()); + if (m_abbr.get()) + m_abbr->Parse(debug_abbrev_data); } - return m_abbr.get(); + } + return m_abbr.get(); } -const DWARFDebugAbbrev* -SymbolFileDWARF::DebugAbbrev() const -{ - return m_abbr.get(); +const DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() const { + return m_abbr.get(); } - -DWARFDebugInfo* -SymbolFileDWARF::DebugInfo() -{ - if (m_info.get() == NULL) - { - Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", - __PRETTY_FUNCTION__, static_cast<void*>(this)); - if (get_debug_info_data().GetByteSize() > 0) - { - m_info.reset(new DWARFDebugInfo()); - if (m_info.get()) - { - m_info->SetDwarfData(this); - } - } +DWARFDebugInfo *SymbolFileDWARF::DebugInfo() { + if (m_info.get() == NULL) { + Timer scoped_timer(LLVM_PRETTY_FUNCTION, "%s this = %p", + LLVM_PRETTY_FUNCTION, static_cast<void *>(this)); + if (get_debug_info_data().GetByteSize() > 0) { + m_info.reset(new DWARFDebugInfo()); + if (m_info.get()) { + m_info->SetDwarfData(this); + } } - return m_info.get(); + } + return m_info.get(); } -const DWARFDebugInfo* -SymbolFileDWARF::DebugInfo() const -{ - return m_info.get(); +const DWARFDebugInfo *SymbolFileDWARF::DebugInfo() const { + return m_info.get(); } -DWARFCompileUnit* -SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) -{ - if (!comp_unit) - return nullptr; - - DWARFDebugInfo* info = DebugInfo(); - if (info) - { - // Just a normal DWARF file whose user ID for the compile unit is - // the DWARF offset itself - - DWARFCompileUnit *dwarf_cu = info->GetCompileUnit((dw_offset_t)comp_unit->GetID()); - if (dwarf_cu && dwarf_cu->GetUserData() == NULL) - dwarf_cu->SetUserData(comp_unit); - return dwarf_cu; - } - return NULL; -} +DWARFCompileUnit * +SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) { + if (!comp_unit) + return nullptr; + DWARFDebugInfo *info = DebugInfo(); + if (info) { + // Just a normal DWARF file whose user ID for the compile unit is + // the DWARF offset itself + + DWARFCompileUnit *dwarf_cu = + info->GetCompileUnit((dw_offset_t)comp_unit->GetID()); + if (dwarf_cu && dwarf_cu->GetUserData() == NULL) + dwarf_cu->SetUserData(comp_unit); + return dwarf_cu; + } + return NULL; +} -DWARFDebugRanges* -SymbolFileDWARF::DebugRanges() -{ - if (m_ranges.get() == NULL) - { - Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", - __PRETTY_FUNCTION__, static_cast<void*>(this)); - if (get_debug_ranges_data().GetByteSize() > 0) - { - m_ranges.reset(new DWARFDebugRanges()); - if (m_ranges.get()) - m_ranges->Extract(this); - } +DWARFDebugRanges *SymbolFileDWARF::DebugRanges() { + if (m_ranges.get() == NULL) { + Timer scoped_timer(LLVM_PRETTY_FUNCTION, "%s this = %p", + LLVM_PRETTY_FUNCTION, static_cast<void *>(this)); + if (get_debug_ranges_data().GetByteSize() > 0) { + m_ranges.reset(new DWARFDebugRanges()); + if (m_ranges.get()) + m_ranges->Extract(this); } - return m_ranges.get(); + } + return m_ranges.get(); } -const DWARFDebugRanges* -SymbolFileDWARF::DebugRanges() const -{ - return m_ranges.get(); +const DWARFDebugRanges *SymbolFileDWARF::DebugRanges() const { + return m_ranges.get(); } -lldb::CompUnitSP -SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx) -{ - CompUnitSP cu_sp; - if (dwarf_cu) - { - CompileUnit *comp_unit = (CompileUnit*)dwarf_cu->GetUserData(); - if (comp_unit) - { - // We already parsed this compile unit, had out a shared pointer to it - cu_sp = comp_unit->shared_from_this(); - } - else - { - if (dwarf_cu->GetSymbolFileDWARF() != this) - { - return dwarf_cu->GetSymbolFileDWARF()->ParseCompileUnit(dwarf_cu, cu_idx); - } - else if (dwarf_cu->GetOffset() == 0 && GetDebugMapSymfile ()) - { - // Let the debug map create the compile unit - cu_sp = m_debug_map_symfile->GetCompileUnit(this); - dwarf_cu->SetUserData(cu_sp.get()); +lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit *dwarf_cu, + uint32_t cu_idx) { + CompUnitSP cu_sp; + if (dwarf_cu) { + CompileUnit *comp_unit = (CompileUnit *)dwarf_cu->GetUserData(); + if (comp_unit) { + // We already parsed this compile unit, had out a shared pointer to it + cu_sp = comp_unit->shared_from_this(); + } else { + if (dwarf_cu->GetSymbolFileDWARF() != this) { + return dwarf_cu->GetSymbolFileDWARF()->ParseCompileUnit(dwarf_cu, + cu_idx); + } else if (dwarf_cu->GetOffset() == 0 && GetDebugMapSymfile()) { + // Let the debug map create the compile unit + cu_sp = m_debug_map_symfile->GetCompileUnit(this); + dwarf_cu->SetUserData(cu_sp.get()); + } else { + ModuleSP module_sp(m_obj_file->GetModule()); + if (module_sp) { + const DWARFDIE cu_die = dwarf_cu->GetCompileUnitDIEOnly(); + if (cu_die) { + FileSpec cu_file_spec{cu_die.GetName(), false}; + 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 files are + // NFS mounted. + if (cu_file_spec.IsRelative()) { + const char *cu_comp_dir{ + cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr)}; + cu_file_spec.PrependPathComponent(resolveCompDir(cu_comp_dir)); + } + + std::string remapped_file; + if (module_sp->RemapSourceFile(cu_file_spec.GetPath(), + remapped_file)) + cu_file_spec.SetFile(remapped_file, false); } - else - { - ModuleSP module_sp (m_obj_file->GetModule()); - if (module_sp) - { - const DWARFDIE cu_die = dwarf_cu->GetCompileUnitDIEOnly (); - if (cu_die) - { - FileSpec cu_file_spec{cu_die.GetName(), false}; - 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 files are NFS mounted. - if (cu_file_spec.IsRelative()) - { - const char *cu_comp_dir{cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr)}; - cu_file_spec.PrependPathComponent(resolveCompDir(cu_comp_dir)); - } - - std::string remapped_file; - if (module_sp->RemapSourceFile(cu_file_spec.GetCString(), remapped_file)) - cu_file_spec.SetFile(remapped_file, false); - } - LanguageType cu_language = DWARFCompileUnit::LanguageTypeFromDWARF(cu_die.GetAttributeValueAsUnsigned(DW_AT_language, 0)); - - bool is_optimized = dwarf_cu->GetIsOptimized (); - cu_sp.reset(new CompileUnit(module_sp, dwarf_cu, cu_file_spec, dwarf_cu->GetID(), cu_language, - is_optimized ? eLazyBoolYes : eLazyBoolNo)); - if (cu_sp) - { - // If we just created a compile unit with an invalid file spec, try and get the - // first entry in the supports files from the line table as that should be the - // compile unit. - if (!cu_file_spec) - { - cu_file_spec = cu_sp->GetSupportFiles().GetFileSpecAtIndex(1); - if (cu_file_spec) - { - (FileSpec &)(*cu_sp) = cu_file_spec; - // Also fix the invalid file spec which was copied from the compile unit. - cu_sp->GetSupportFiles().Replace(0, cu_file_spec); - } - } - - dwarf_cu->SetUserData(cu_sp.get()); - - // Figure out the compile unit index if we weren't given one - if (cu_idx == UINT32_MAX) - DebugInfo()->GetCompileUnit(dwarf_cu->GetOffset(), &cu_idx); - - m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp); - } - } + LanguageType cu_language = DWARFCompileUnit::LanguageTypeFromDWARF( + cu_die.GetAttributeValueAsUnsigned(DW_AT_language, 0)); + + bool is_optimized = dwarf_cu->GetIsOptimized(); + cu_sp.reset(new CompileUnit( + module_sp, dwarf_cu, cu_file_spec, dwarf_cu->GetID(), + cu_language, is_optimized ? eLazyBoolYes : eLazyBoolNo)); + if (cu_sp) { + // If we just created a compile unit with an invalid file spec, + // try and get the + // first entry in the supports files from the line table as that + // should be the + // compile unit. + if (!cu_file_spec) { + cu_file_spec = cu_sp->GetSupportFiles().GetFileSpecAtIndex(1); + if (cu_file_spec) { + (FileSpec &)(*cu_sp) = cu_file_spec; + // Also fix the invalid file spec which was copied from the + // compile unit. + cu_sp->GetSupportFiles().Replace(0, cu_file_spec); } + } + + dwarf_cu->SetUserData(cu_sp.get()); + + // Figure out the compile unit index if we weren't given one + if (cu_idx == UINT32_MAX) + DebugInfo()->GetCompileUnit(dwarf_cu->GetOffset(), &cu_idx); + + m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex( + cu_idx, cu_sp); } + } } + } } - return cu_sp; + } + return cu_sp; } -uint32_t -SymbolFileDWARF::GetNumCompileUnits() -{ - DWARFDebugInfo* info = DebugInfo(); - if (info) - return info->GetNumCompileUnits(); - return 0; +uint32_t SymbolFileDWARF::GetNumCompileUnits() { + DWARFDebugInfo *info = DebugInfo(); + if (info) + return info->GetNumCompileUnits(); + return 0; } -CompUnitSP -SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) -{ - CompUnitSP cu_sp; - DWARFDebugInfo* info = DebugInfo(); - if (info) - { - DWARFCompileUnit* dwarf_cu = info->GetCompileUnitAtIndex(cu_idx); - if (dwarf_cu) - cu_sp = ParseCompileUnit(dwarf_cu, cu_idx); - } - return cu_sp; +CompUnitSP SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) { + CompUnitSP cu_sp; + DWARFDebugInfo *info = DebugInfo(); + if (info) { + DWARFCompileUnit *dwarf_cu = info->GetCompileUnitAtIndex(cu_idx); + if (dwarf_cu) + cu_sp = ParseCompileUnit(dwarf_cu, cu_idx); + } + return cu_sp; } -Function * -SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, const DWARFDIE &die) -{ - if (die.IsValid()) - { - TypeSystem *type_system = GetTypeSystemForLanguage(die.GetCU()->GetLanguageType()); - - if (type_system) - { - DWARFASTParser *dwarf_ast = type_system->GetDWARFParser(); - if (dwarf_ast) - return dwarf_ast->ParseFunctionFromDWARF(sc, die); - } +Function *SymbolFileDWARF::ParseCompileUnitFunction(const SymbolContext &sc, + const DWARFDIE &die) { + if (die.IsValid()) { + TypeSystem *type_system = + GetTypeSystemForLanguage(die.GetCU()->GetLanguageType()); + + if (type_system) { + DWARFASTParser *dwarf_ast = type_system->GetDWARFParser(); + if (dwarf_ast) + return dwarf_ast->ParseFunctionFromDWARF(sc, die); } - return nullptr; + } + return nullptr; } -bool -SymbolFileDWARF::FixupAddress (Address &addr) -{ - SymbolFileDWARFDebugMap * debug_map_symfile = GetDebugMapSymfile(); - if (debug_map_symfile) - { - return debug_map_symfile->LinkOSOAddress(addr); - } - // This is a normal DWARF file, no address fixups need to happen - return true; +bool SymbolFileDWARF::FixupAddress(Address &addr) { + SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile(); + if (debug_map_symfile) { + return debug_map_symfile->LinkOSOAddress(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); - DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); - if (dwarf_cu) - return dwarf_cu->GetLanguageType(); - else - return eLanguageTypeUnknown; +SymbolFileDWARF::ParseCompileUnitLanguage(const SymbolContext &sc) { + assert(sc.comp_unit); + DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.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 functions_added = 0; - DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); - if (dwarf_cu) - { - DWARFDIECollection function_dies; - const size_t num_functions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies); - 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)) - ++functions_added; - } - } - //FixupTypes(); +size_t SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc) { + assert(sc.comp_unit); + size_t functions_added = 0; + DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); + if (dwarf_cu) { + DWARFDIECollection function_dies; + const size_t num_functions = + dwarf_cu->AppendDIEsWithTag(DW_TAG_subprogram, function_dies); + 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)) + ++functions_added; + } } - return functions_added; + // FixupTypes(); + } + return functions_added; } -bool -SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files) -{ - assert (sc.comp_unit); - DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); - if (dwarf_cu) - { - const DWARFDIE cu_die = dwarf_cu->GetCompileUnitDIEOnly(); - - if (cu_die) - { - const char * cu_comp_dir = resolveCompDir(cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr)); - const dw_offset_t stmt_list = cu_die.GetAttributeValueAsUnsigned(DW_AT_stmt_list, DW_INVALID_OFFSET); - 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); - return DWARFDebugLine::ParseSupportFiles(sc.comp_unit->GetModule(), - get_debug_line_data(), - cu_comp_dir, - stmt_list, - support_files); - } - } +bool SymbolFileDWARF::ParseCompileUnitSupportFiles( + const SymbolContext &sc, FileSpecList &support_files) { + assert(sc.comp_unit); + DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); + if (dwarf_cu) { + const DWARFDIE cu_die = dwarf_cu->GetCompileUnitDIEOnly(); + + if (cu_die) { + const char *cu_comp_dir = resolveCompDir( + cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr)); + const dw_offset_t stmt_list = cu_die.GetAttributeValueAsUnsigned( + DW_AT_stmt_list, DW_INVALID_OFFSET); + 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); + return DWARFDebugLine::ParseSupportFiles( + sc.comp_unit->GetModule(), get_debug_line_data(), cu_comp_dir, + stmt_list, support_files); + } } - return false; + } + return false; } -bool -SymbolFileDWARF::ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc) -{ - DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); - if (dwarf_cu) - return dwarf_cu->GetIsOptimized(); - return false; +bool SymbolFileDWARF::ParseCompileUnitIsOptimized( + const lldb_private::SymbolContext &sc) { + DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); + if (dwarf_cu) + return dwarf_cu->GetIsOptimized(); + return false; } -bool -SymbolFileDWARF::ParseImportedModules(const lldb_private::SymbolContext &sc, - std::vector<lldb_private::ConstString> &imported_modules) -{ - assert (sc.comp_unit); - DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); - if (dwarf_cu) - { - if (ClangModulesDeclVendor::LanguageSupportsClangModules(sc.comp_unit->GetLanguage())) - { - UpdateExternalModuleListIfNeeded(); - - if (sc.comp_unit) - { - const DWARFDIE die = dwarf_cu->GetCompileUnitDIEOnly(); - - if (die) - { - for (DWARFDIE child_die = die.GetFirstChild(); - child_die; - child_die = child_die.GetSibling()) - { - if (child_die.Tag() == DW_TAG_imported_declaration) - { - if (DWARFDIE module_die = child_die.GetReferencedDIE(DW_AT_import)) - { - if (module_die.Tag() == DW_TAG_module) - { - if (const char *name = module_die.GetAttributeValueAsString(DW_AT_name, nullptr)) - { - ConstString const_name(name); - imported_modules.push_back(const_name); - } - } - } - } - } - } - } - else - { - for (const auto &pair : m_external_type_modules) - { - imported_modules.push_back(pair.first); +bool SymbolFileDWARF::ParseImportedModules( + const lldb_private::SymbolContext &sc, + std::vector<lldb_private::ConstString> &imported_modules) { + assert(sc.comp_unit); + DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); + if (dwarf_cu) { + if (ClangModulesDeclVendor::LanguageSupportsClangModules( + sc.comp_unit->GetLanguage())) { + UpdateExternalModuleListIfNeeded(); + + if (sc.comp_unit) { + const DWARFDIE die = dwarf_cu->GetCompileUnitDIEOnly(); + + if (die) { + for (DWARFDIE child_die = die.GetFirstChild(); child_die; + child_die = child_die.GetSibling()) { + if (child_die.Tag() == DW_TAG_imported_declaration) { + if (DWARFDIE module_die = + child_die.GetReferencedDIE(DW_AT_import)) { + if (module_die.Tag() == DW_TAG_module) { + if (const char *name = module_die.GetAttributeValueAsString( + DW_AT_name, nullptr)) { + ConstString const_name(name); + imported_modules.push_back(const_name); + } } + } } + } + } + } else { + for (const auto &pair : m_external_type_modules) { + imported_modules.push_back(pair.first); } + } } - return false; + } + return false; } -struct ParseDWARFLineTableCallbackInfo -{ - LineTable* line_table; - std::unique_ptr<LineSequence> sequence_ap; - lldb::addr_t addr_mask; +struct ParseDWARFLineTableCallbackInfo { + LineTable *line_table; + std::unique_ptr<LineSequence> sequence_ap; + lldb::addr_t addr_mask; }; //---------------------------------------------------------------------- // ParseStatementTableCallback //---------------------------------------------------------------------- -static void -ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData) -{ - if (state.row == DWARFDebugLine::State::StartParsingLineTable) - { - // Just started parsing the line table +static void ParseDWARFLineTableCallback(dw_offset_t offset, + const DWARFDebugLine::State &state, + void *userData) { + if (state.row == DWARFDebugLine::State::StartParsingLineTable) { + // Just started parsing the line table + } else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) { + // Done parsing line table, nothing to do for the cleanup + } else { + ParseDWARFLineTableCallbackInfo *info = + (ParseDWARFLineTableCallbackInfo *)userData; + LineTable *line_table = info->line_table; + + // If this is our first time here, we need to create a + // sequence container. + if (!info->sequence_ap.get()) { + info->sequence_ap.reset(line_table->CreateLineSequenceContainer()); + assert(info->sequence_ap.get()); } - else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) - { - // Done parsing line table, nothing to do for the cleanup - } - else - { - ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData; - LineTable* line_table = info->line_table; - - // If this is our first time here, we need to create a - // sequence container. - if (!info->sequence_ap.get()) - { - info->sequence_ap.reset(line_table->CreateLineSequenceContainer()); - assert(info->sequence_ap.get()); - } - line_table->AppendLineEntryToSequence (info->sequence_ap.get(), - state.address & info->addr_mask, - state.line, - state.column, - state.file, - state.is_stmt, - state.basic_block, - state.prologue_end, - state.epilogue_begin, - state.end_sequence); - if (state.end_sequence) - { - // First, put the current sequence into the line table. - line_table->InsertSequence(info->sequence_ap.get()); - // Then, empty it to prepare for the next sequence. - info->sequence_ap->Clear(); - } + line_table->AppendLineEntryToSequence( + info->sequence_ap.get(), state.address & info->addr_mask, state.line, + state.column, state.file, state.is_stmt, state.basic_block, + state.prologue_end, state.epilogue_begin, state.end_sequence); + if (state.end_sequence) { + // First, put the current sequence into the line table. + line_table->InsertSequence(info->sequence_ap.get()); + // Then, empty it to prepare for the next sequence. + info->sequence_ap->Clear(); } + } } -bool -SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc) -{ - assert (sc.comp_unit); - if (sc.comp_unit->GetLineTable() != NULL) - return true; - - DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); - if (dwarf_cu) - { - const DWARFDIE dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly(); - if (dwarf_cu_die) - { - const dw_offset_t cu_line_offset = 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)); - if (line_table_ap.get()) - { - ParseDWARFLineTableCallbackInfo info; - info.line_table = line_table_ap.get(); - - /* - * MIPS: - * The SymbolContext may not have a valid target, thus we may not be able - * to call Address::GetOpcodeLoadAddress() which would clear the bit #0 - * for MIPS. Use ArchSpec to clear the bit #0. - */ - ArchSpec arch; - GetObjectFile()->GetArchitecture(arch); - switch (arch.GetMachine()) - { - case llvm::Triple::mips: - case llvm::Triple::mipsel: - case llvm::Triple::mips64: - case llvm::Triple::mips64el: - info.addr_mask = ~((lldb::addr_t)1); - break; - default: - info.addr_mask = ~((lldb::addr_t)0); - break; - } +bool SymbolFileDWARF::ParseCompileUnitLineTable(const SymbolContext &sc) { + assert(sc.comp_unit); + if (sc.comp_unit->GetLineTable() != NULL) + return true; - lldb::offset_t offset = cu_line_offset; - DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info); - 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 (debug_map_symfile->LinkOSOLineTable (this, line_table_ap.get())); - } - else - { - sc.comp_unit->SetLineTable(line_table_ap.release()); - return true; - } - } - } + DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); + if (dwarf_cu) { + const DWARFDIE dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly(); + if (dwarf_cu_die) { + const dw_offset_t cu_line_offset = + 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)); + if (line_table_ap.get()) { + ParseDWARFLineTableCallbackInfo info; + info.line_table = line_table_ap.get(); + + /* + * MIPS: + * The SymbolContext may not have a valid target, thus we may not be + * able + * to call Address::GetOpcodeLoadAddress() which would clear the bit + * #0 + * for MIPS. Use ArchSpec to clear the bit #0. + */ + ArchSpec arch; + GetObjectFile()->GetArchitecture(arch); + switch (arch.GetMachine()) { + case llvm::Triple::mips: + case llvm::Triple::mipsel: + case llvm::Triple::mips64: + case llvm::Triple::mips64el: + info.addr_mask = ~((lldb::addr_t)1); + break; + default: + info.addr_mask = ~((lldb::addr_t)0); + break; + } + + lldb::offset_t offset = cu_line_offset; + DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, + ParseDWARFLineTableCallback, + &info); + 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( + debug_map_symfile->LinkOSOLineTable(this, line_table_ap.get())); + } else { + sc.comp_unit->SetLineTable(line_table_ap.release()); + return true; + } } + } } - return false; + } + return false; } lldb_private::DebugMacrosSP -SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset) -{ - auto iter = m_debug_macros_map.find(*offset); - if (iter != m_debug_macros_map.end()) - return iter->second; +SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset) { + auto iter = m_debug_macros_map.find(*offset); + if (iter != m_debug_macros_map.end()) + return iter->second; - const DWARFDataExtractor &debug_macro_data = get_debug_macro_data(); - if (debug_macro_data.GetByteSize() == 0) - return DebugMacrosSP(); + const DWARFDataExtractor &debug_macro_data = get_debug_macro_data(); + if (debug_macro_data.GetByteSize() == 0) + return DebugMacrosSP(); - lldb_private::DebugMacrosSP debug_macros_sp(new lldb_private::DebugMacros()); - m_debug_macros_map[*offset] = debug_macros_sp; + lldb_private::DebugMacrosSP debug_macros_sp(new lldb_private::DebugMacros()); + m_debug_macros_map[*offset] = debug_macros_sp; - const DWARFDebugMacroHeader &header = DWARFDebugMacroHeader::ParseHeader(debug_macro_data, offset); - DWARFDebugMacroEntry::ReadMacroEntries( - debug_macro_data, get_debug_str_data(), header.OffsetIs64Bit(), offset, this, debug_macros_sp); + const DWARFDebugMacroHeader &header = + DWARFDebugMacroHeader::ParseHeader(debug_macro_data, offset); + DWARFDebugMacroEntry::ReadMacroEntries(debug_macro_data, get_debug_str_data(), + header.OffsetIs64Bit(), offset, this, + debug_macros_sp); - return debug_macros_sp; + return debug_macros_sp; } -bool -SymbolFileDWARF::ParseCompileUnitDebugMacros(const SymbolContext& sc) -{ - assert (sc.comp_unit); +bool SymbolFileDWARF::ParseCompileUnitDebugMacros(const SymbolContext &sc) { + assert(sc.comp_unit); - DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); - if (dwarf_cu == nullptr) - return false; + DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); + if (dwarf_cu == nullptr) + return false; - const DWARFDIE dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly(); - if (!dwarf_cu_die) - return false; + const DWARFDIE dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly(); + if (!dwarf_cu_die) + return false; - lldb::offset_t sect_offset = dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_macros, DW_INVALID_OFFSET); - if (sect_offset == DW_INVALID_OFFSET) - sect_offset = dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_GNU_macros, DW_INVALID_OFFSET); - if (sect_offset == DW_INVALID_OFFSET) - return false; + lldb::offset_t sect_offset = + dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_macros, DW_INVALID_OFFSET); + if (sect_offset == DW_INVALID_OFFSET) + sect_offset = dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_GNU_macros, + DW_INVALID_OFFSET); + if (sect_offset == DW_INVALID_OFFSET) + return false; - sc.comp_unit->SetDebugMacros(ParseDebugMacros(§_offset)); + sc.comp_unit->SetDebugMacros(ParseDebugMacros(§_offset)); - return true; + 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 blocks_added = 0; - DWARFDIE die = orig_die; - while (die) - { - dw_tag_t tag = die.Tag(); - - switch (tag) - { - case DW_TAG_inlined_subroutine: - case DW_TAG_subprogram: - case DW_TAG_lexical_block: - { - Block *block = NULL; - if (tag == DW_TAG_subprogram) - { - // Skip any DW_TAG_subprogram DIEs that are inside - // of a normal or inlined functions. These will be - // parsed on their own as separate entities. - - if (depth > 0) - break; - - block = parent_block; - } - else - { - BlockSP block_sp(new Block (die.GetID())); - parent_block->AddChild(block_sp); - block = block_sp.get(); - } - DWARFRangeList ranges; - const char *name = NULL; - const char *mangled_name = 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; - if (die.GetDIENamesAndRanges (name, - mangled_name, - ranges, - decl_file, decl_line, decl_column, - call_file, call_line, call_column, nullptr)) - { - if (tag == DW_TAG_subprogram) - { - assert (subprogram_low_pc == LLDB_INVALID_ADDRESS); - subprogram_low_pc = ranges.GetMinRangeBase(0); - } - else if (tag == DW_TAG_inlined_subroutine) - { - // We get called here for inlined subroutines in two ways. - // The first time is when we are making the Function object - // for this inlined concrete instance. Since we're creating a top level block at - // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we need to - // adjust the containing address. - // The second time is when we are parsing the blocks inside the function that contains - // the inlined concrete instance. Since these will be blocks inside the containing "real" - // function the offset will be for that function. - if (subprogram_low_pc == LLDB_INVALID_ADDRESS) - { - subprogram_low_pc = ranges.GetMinRangeBase(0); - } - } - - const size_t num_ranges = ranges.GetSize(); - for (size_t i = 0; i<num_ranges; ++i) - { - const DWARFRangeList::Entry &range = ranges.GetEntryRef (i); - const addr_t range_base = range.GetRangeBase(); - if (range_base >= subprogram_low_pc) - block->AddRange(Block::Range (range_base - subprogram_low_pc, range.GetByteSize())); - else - { - GetObjectFile()->GetModule()->ReportError ("0x%8.8" PRIx64 ": adding range [0x%" PRIx64 "-0x%" PRIx64 ") which has a base that is less than the function's low PC 0x%" PRIx64 ". Please file a bug and attach the file at the start of this error message", - block->GetID(), - range_base, - range.GetRangeEnd(), - subprogram_low_pc); - } - } - block->FinalizeRanges (); - - if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL)) - { - 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)); - - 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), - call_line, call_column)); +size_t SymbolFileDWARF::ParseFunctionBlocks(const SymbolContext &sc, + 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) { + dw_tag_t tag = die.Tag(); + + switch (tag) { + case DW_TAG_inlined_subroutine: + case DW_TAG_subprogram: + case DW_TAG_lexical_block: { + Block *block = NULL; + if (tag == DW_TAG_subprogram) { + // Skip any DW_TAG_subprogram DIEs that are inside + // of a normal or inlined functions. These will be + // parsed on their own as separate entities. + + if (depth > 0) + break; + + block = parent_block; + } else { + BlockSP block_sp(new Block(die.GetID())); + parent_block->AddChild(block_sp); + block = block_sp.get(); + } + DWARFRangeList ranges; + const char *name = NULL; + const char *mangled_name = 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; + if (die.GetDIENamesAndRanges(name, mangled_name, ranges, decl_file, + decl_line, decl_column, call_file, call_line, + call_column, nullptr)) { + if (tag == DW_TAG_subprogram) { + assert(subprogram_low_pc == LLDB_INVALID_ADDRESS); + subprogram_low_pc = ranges.GetMinRangeBase(0); + } else if (tag == DW_TAG_inlined_subroutine) { + // We get called here for inlined subroutines in two ways. + // The first time is when we are making the Function object + // for this inlined concrete instance. Since we're creating a top + // level block at + // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we + // need to + // adjust the containing address. + // The second time is when we are parsing the blocks inside the + // function that contains + // the inlined concrete instance. Since these will be blocks inside + // the containing "real" + // function the offset will be for that function. + if (subprogram_low_pc == LLDB_INVALID_ADDRESS) { + subprogram_low_pc = ranges.GetMinRangeBase(0); + } + } - block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get()); - } + const size_t num_ranges = ranges.GetSize(); + for (size_t i = 0; i < num_ranges; ++i) { + const DWARFRangeList::Entry &range = ranges.GetEntryRef(i); + const addr_t range_base = range.GetRangeBase(); + if (range_base >= subprogram_low_pc) + block->AddRange(Block::Range(range_base - subprogram_low_pc, + range.GetByteSize())); + else { + GetObjectFile()->GetModule()->ReportError( + "0x%8.8" PRIx64 ": adding range [0x%" PRIx64 "-0x%" PRIx64 + ") which has a base that is less than the function's low PC " + "0x%" PRIx64 ". Please file a bug and attach the file at the " + "start of this error message", + block->GetID(), range_base, range.GetRangeEnd(), + subprogram_low_pc); + } + } + block->FinalizeRanges(); + + if (tag != DW_TAG_subprogram && + (name != NULL || mangled_name != NULL)) { + 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)); + + 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), + call_line, call_column)); + + block->SetInlinedFunctionInfo(name, mangled_name, decl_ap.get(), + call_ap.get()); + } - ++blocks_added; + ++blocks_added; - if (die.HasChildren()) - { - blocks_added += ParseFunctionBlocks (sc, - block, - die.GetFirstChild(), - subprogram_low_pc, - depth + 1); - } - } - } - break; - default: - break; + if (die.HasChildren()) { + blocks_added += ParseFunctionBlocks(sc, block, die.GetFirstChild(), + subprogram_low_pc, depth + 1); } - - // Only parse siblings of the block if we are not at depth zero. A depth - // of zero indicates we are currently parsing the top level - // DW_TAG_subprogram DIE - - if (depth == 0) - die.Clear(); - else - die = die.GetSibling(); + } + } break; + default: + break; } - return blocks_added; + + // Only parse siblings of the block if we are not at depth zero. A depth + // of zero indicates we are currently parsing the top level + // DW_TAG_subprogram DIE + + if (depth == 0) + die.Clear(); + else + die = die.GetSibling(); + } + return blocks_added; } -bool -SymbolFileDWARF::ClassOrStructIsVirtual (const DWARFDIE &parent_die) -{ - if (parent_die) - { - for (DWARFDIE die = parent_die.GetFirstChild(); die; die = die.GetSibling()) - { - dw_tag_t tag = die.Tag(); - bool check_virtuality = false; - switch (tag) - { - case DW_TAG_inheritance: - case DW_TAG_subprogram: - check_virtuality = true; - break; - default: - break; - } - if (check_virtuality) - { - if (die.GetAttributeValueAsUnsigned(DW_AT_virtuality, 0) != 0) - return true; - } - } +bool SymbolFileDWARF::ClassOrStructIsVirtual(const DWARFDIE &parent_die) { + if (parent_die) { + for (DWARFDIE die = parent_die.GetFirstChild(); die; + die = die.GetSibling()) { + dw_tag_t tag = die.Tag(); + bool check_virtuality = false; + switch (tag) { + case DW_TAG_inheritance: + case DW_TAG_subprogram: + check_virtuality = true; + break; + default: + break; + } + if (check_virtuality) { + if (die.GetAttributeValueAsUnsigned(DW_AT_virtuality, 0) != 0) + return true; + } } - return false; + } + return false; } -void -SymbolFileDWARF::ParseDeclsForContext (CompilerDeclContext decl_ctx) -{ - TypeSystem *type_system = decl_ctx.GetTypeSystem(); - DWARFASTParser *ast_parser = type_system->GetDWARFParser(); - std::vector<DWARFDIE> decl_ctx_die_list = ast_parser->GetDIEForDeclContext(decl_ctx); +void SymbolFileDWARF::ParseDeclsForContext(CompilerDeclContext decl_ctx) { + TypeSystem *type_system = decl_ctx.GetTypeSystem(); + DWARFASTParser *ast_parser = type_system->GetDWARFParser(); + std::vector<DWARFDIE> decl_ctx_die_list = + ast_parser->GetDIEForDeclContext(decl_ctx); - for (DWARFDIE decl_ctx_die : decl_ctx_die_list) - for (DWARFDIE decl = decl_ctx_die.GetFirstChild(); decl; decl = decl.GetSibling()) - ast_parser->GetDeclForUIDFromDWARF(decl); + for (DWARFDIE decl_ctx_die : decl_ctx_die_list) + for (DWARFDIE decl = decl_ctx_die.GetFirstChild(); decl; + decl = decl.GetSibling()) + ast_parser->GetDeclForUIDFromDWARF(decl); } -SymbolFileDWARF * -SymbolFileDWARF::GetDWARFForUID (lldb::user_id_t uid) -{ - // 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 - // SymbolFileDWARF classes, one for each .o file. We can often end up - // with references to other DWARF objects and we must be ready to receive - // a "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF - // instance. - SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile(); - if (debug_map) - return debug_map->GetSymbolFileByOSOIndex(debug_map->GetOSOIndexFromUserID(uid)); - return this; +SymbolFileDWARF *SymbolFileDWARF::GetDWARFForUID(lldb::user_id_t uid) { + // 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 + // SymbolFileDWARF classes, one for each .o file. We can often end up + // with references to other DWARF objects and we must be ready to receive + // a "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF + // instance. + SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile(); + if (debug_map) + return debug_map->GetSymbolFileByOSOIndex( + debug_map->GetOSOIndexFromUserID(uid)); + return this; } DWARFDIE -SymbolFileDWARF::GetDIEFromUID (lldb::user_id_t uid) -{ - // 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 - // SymbolFileDWARF classes, one for each .o file. We can often end up - // with references to other DWARF objects and we must be ready to receive - // a "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF - // instance. - SymbolFileDWARF *dwarf = GetDWARFForUID(uid); - if (dwarf) - return dwarf->GetDIE(DIERef(uid, dwarf)); - return DWARFDIE(); +SymbolFileDWARF::GetDIEFromUID(lldb::user_id_t uid) { + // 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 + // SymbolFileDWARF classes, one for each .o file. We can often end up + // with references to other DWARF objects and we must be ready to receive + // a "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF + // instance. + SymbolFileDWARF *dwarf = GetDWARFForUID(uid); + if (dwarf) + return dwarf->GetDIE(DIERef(uid, dwarf)); + return DWARFDIE(); } -CompilerDecl -SymbolFileDWARF::GetDeclForUID (lldb::user_id_t type_uid) -{ - // 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. - DWARFDIE die = GetDIEFromUID(type_uid); - if (die) - return die.GetDecl(); - return CompilerDecl(); +CompilerDecl SymbolFileDWARF::GetDeclForUID(lldb::user_id_t type_uid) { + // 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. + DWARFDIE die = GetDIEFromUID(type_uid); + if (die) + return die.GetDecl(); + return CompilerDecl(); } CompilerDeclContext -SymbolFileDWARF::GetDeclContextForUID (lldb::user_id_t type_uid) -{ - // 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. - DWARFDIE die = GetDIEFromUID(type_uid); - if (die) - return die.GetDeclContext(); - return CompilerDeclContext(); +SymbolFileDWARF::GetDeclContextForUID(lldb::user_id_t type_uid) { + // 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. + DWARFDIE die = GetDIEFromUID(type_uid); + if (die) + return die.GetDeclContext(); + return CompilerDeclContext(); } CompilerDeclContext -SymbolFileDWARF::GetDeclContextContainingUID (lldb::user_id_t type_uid) -{ - // 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. - DWARFDIE die = GetDIEFromUID(type_uid); - if (die) - return die.GetContainingDeclContext(); - return CompilerDeclContext(); +SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid) { + // 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. + DWARFDIE die = GetDIEFromUID(type_uid); + if (die) + return die.GetContainingDeclContext(); + return CompilerDeclContext(); } - -Type* -SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid) -{ - // 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. - DWARFDIE type_die = GetDIEFromUID(type_uid); - if (type_die) - return type_die.ResolveType(); - else - return nullptr; +Type *SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid) { + // 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. + DWARFDIE type_die = GetDIEFromUID(type_uid); + if (type_die) + return type_die.ResolveType(); + else + return nullptr; } -Type* -SymbolFileDWARF::ResolveTypeUID (const DIERef &die_ref) -{ - return ResolveType (GetDIE(die_ref), true); +Type *SymbolFileDWARF::ResolveTypeUID(const DIERef &die_ref) { + return ResolveType(GetDIE(die_ref), true); } -Type* -SymbolFileDWARF::ResolveTypeUID (const DWARFDIE &die, bool assert_not_being_parsed) -{ - if (die) - { - Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO)); - if (log) - GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s'", - die.GetOffset(), - die.GetTagAsCString(), - die.GetName()); - - // We might be coming in in the middle of a type tree (a class - // withing a class, an enum within a class), so parse any needed - // parent DIEs before we get to this one... - DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE (die); - if (decl_ctx_die) - { - if (log) - { - switch (decl_ctx_die.Tag()) - { - case DW_TAG_structure_type: - case DW_TAG_union_type: - case DW_TAG_class_type: - { - // Get the type, which could be a forward declaration - if (log) - GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' resolve parent forward type for 0x%8.8x", - die.GetOffset(), - die.GetTagAsCString(), - die.GetName(), - decl_ctx_die.GetOffset()); - } - break; +Type *SymbolFileDWARF::ResolveTypeUID(const DWARFDIE &die, + bool assert_not_being_parsed) { + if (die) { + Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO)); + if (log) + GetObjectFile()->GetModule()->LogMessage( + log, "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s'", + die.GetOffset(), die.GetTagAsCString(), die.GetName()); + + // We might be coming in in the middle of a type tree (a class + // within a class, an enum within a class), so parse any needed + // parent DIEs before we get to this one... + DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(die); + if (decl_ctx_die) { + if (log) { + switch (decl_ctx_die.Tag()) { + case DW_TAG_structure_type: + case DW_TAG_union_type: + case DW_TAG_class_type: { + // Get the type, which could be a forward declaration + if (log) + GetObjectFile()->GetModule()->LogMessage( + log, "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' " + "resolve parent forward type for 0x%8.8x", + die.GetOffset(), die.GetTagAsCString(), die.GetName(), + decl_ctx_die.GetOffset()); + } break; - default: - break; - } - } + default: + break; } - return ResolveType (die); + } } - return NULL; + return ResolveType(die); + } + return NULL; } // This function is used when SymbolFileDWARFDebugMap owns a bunch of // SymbolFileDWARF objects to detect if this DWARF file is the one that // can resolve a compiler_type. -bool -SymbolFileDWARF::HasForwardDeclForClangType (const CompilerType &compiler_type) -{ - CompilerType compiler_type_no_qualifiers = ClangUtil::RemoveFastQualifiers(compiler_type); - if (GetForwardDeclClangTypeToDie().count (compiler_type_no_qualifiers.GetOpaqueQualType())) - { - return true; - } - TypeSystem *type_system = compiler_type.GetTypeSystem(); +bool SymbolFileDWARF::HasForwardDeclForClangType( + const CompilerType &compiler_type) { + CompilerType compiler_type_no_qualifiers = + ClangUtil::RemoveFastQualifiers(compiler_type); + if (GetForwardDeclClangTypeToDie().count( + compiler_type_no_qualifiers.GetOpaqueQualType())) { + return true; + } + TypeSystem *type_system = compiler_type.GetTypeSystem(); - ClangASTContext *clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(type_system); - if (!clang_type_system) - return false; - DWARFASTParserClang *ast_parser = static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser()); - return ast_parser->GetClangASTImporter().CanImport(compiler_type); + ClangASTContext *clang_type_system = + llvm::dyn_cast_or_null<ClangASTContext>(type_system); + if (!clang_type_system) + return false; + DWARFASTParserClang *ast_parser = + static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser()); + return ast_parser->GetClangASTImporter().CanImport(compiler_type); } +bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) { + std::lock_guard<std::recursive_mutex> guard( + GetObjectFile()->GetModule()->GetMutex()); + + ClangASTContext *clang_type_system = + llvm::dyn_cast_or_null<ClangASTContext>(compiler_type.GetTypeSystem()); + if (clang_type_system) { + DWARFASTParserClang *ast_parser = + static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser()); + if (ast_parser && + ast_parser->GetClangASTImporter().CanImport(compiler_type)) + return ast_parser->GetClangASTImporter().CompleteType(compiler_type); + } + + // We have a struct/union/class/enum that needs to be fully resolved. + CompilerType compiler_type_no_qualifiers = + ClangUtil::RemoveFastQualifiers(compiler_type); + auto die_it = GetForwardDeclClangTypeToDie().find( + compiler_type_no_qualifiers.GetOpaqueQualType()); + if (die_it == GetForwardDeclClangTypeToDie().end()) { + // We have already resolved this type... + return true; + } + + DWARFDIE dwarf_die = GetDIE(die_it->getSecond()); + if (dwarf_die) { + // Once we start resolving this type, remove it from the forward declaration + // map in case anyone child members or other types require this type to get + // resolved. + // The type will get resolved when all of the calls to + // SymbolFileDWARF::ResolveClangOpaqueTypeDefinition + // are done. + GetForwardDeclClangTypeToDie().erase(die_it); + + Type *type = GetDIEToType().lookup(dwarf_die.GetDIE()); + + Log *log(LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO | + DWARF_LOG_TYPE_COMPLETION)); + if (log) + GetObjectFile()->GetModule()->LogMessageVerboseBacktrace( + log, "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...", + dwarf_die.GetID(), dwarf_die.GetTagAsCString(), + type->GetName().AsCString()); + assert(compiler_type); + DWARFASTParser *dwarf_ast = dwarf_die.GetDWARFParser(); + if (dwarf_ast) + return dwarf_ast->CompleteTypeFromDWARF(dwarf_die, type, compiler_type); + } + return false; +} -bool -SymbolFileDWARF::CompleteType (CompilerType &compiler_type) -{ - std::lock_guard<std::recursive_mutex> guard(GetObjectFile()->GetModule()->GetMutex()); - - ClangASTContext *clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(compiler_type.GetTypeSystem()); - if (clang_type_system) - { - DWARFASTParserClang *ast_parser = static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser()); - if (ast_parser && ast_parser->GetClangASTImporter().CanImport(compiler_type)) - return ast_parser->GetClangASTImporter().CompleteType(compiler_type); - } - - // We have a struct/union/class/enum that needs to be fully resolved. - CompilerType compiler_type_no_qualifiers = ClangUtil::RemoveFastQualifiers(compiler_type); - auto die_it = GetForwardDeclClangTypeToDie().find (compiler_type_no_qualifiers.GetOpaqueQualType()); - if (die_it == GetForwardDeclClangTypeToDie().end()) - { - // We have already resolved this type... - return true; - } +Type *SymbolFileDWARF::ResolveType(const DWARFDIE &die, + bool assert_not_being_parsed, + bool resolve_function_context) { + if (die) { + Type *type = GetTypeForDIE(die, resolve_function_context).get(); - DWARFDIE dwarf_die = GetDIE(die_it->getSecond()); - if (dwarf_die) - { - // Once we start resolving this type, remove it from the forward declaration - // map in case anyone child members or other types require this type to get resolved. - // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition - // are done. - GetForwardDeclClangTypeToDie().erase (die_it); - - Type *type = GetDIEToType().lookup (dwarf_die.GetDIE()); - - Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION)); - if (log) - GetObjectFile()->GetModule()->LogMessageVerboseBacktrace (log, - "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...", - dwarf_die.GetID(), - dwarf_die.GetTagAsCString(), - type->GetName().AsCString()); - assert (compiler_type); - DWARFASTParser *dwarf_ast = dwarf_die.GetDWARFParser(); - if (dwarf_ast) - return dwarf_ast->CompleteTypeFromDWARF (dwarf_die, type, compiler_type); - } - return false; -} + if (assert_not_being_parsed) { + if (type != DIE_IS_BEING_PARSED) + return type; -Type* -SymbolFileDWARF::ResolveType (const DWARFDIE &die, bool assert_not_being_parsed, bool resolve_function_context) -{ - if (die) - { - Type *type = GetTypeForDIE (die, resolve_function_context).get(); - - if (assert_not_being_parsed) - { - if (type != DIE_IS_BEING_PARSED) - return type; - - GetObjectFile()->GetModule()->ReportError ("Parsing a die that is being parsed die: 0x%8.8x: %s %s", - die.GetOffset(), - die.GetTagAsCString(), - die.GetName()); + GetObjectFile()->GetModule()->ReportError( + "Parsing a die that is being parsed die: 0x%8.8x: %s %s", + die.GetOffset(), die.GetTagAsCString(), die.GetName()); - } - else - return type; - } - return nullptr; + } else + return type; + } + return nullptr; } -CompileUnit* -SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx) -{ - // Check if the symbol vendor already knows about this compile unit? - if (dwarf_cu->GetUserData() == NULL) - { - // The symbol vendor doesn't know about this compile unit, we - // need to parse and add it to the symbol vendor object. - return ParseCompileUnit(dwarf_cu, cu_idx).get(); - } - return (CompileUnit*)dwarf_cu->GetUserData(); +CompileUnit * +SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFCompileUnit *dwarf_cu, + uint32_t cu_idx) { + // Check if the symbol vendor already knows about this compile unit? + if (dwarf_cu->GetUserData() == NULL) { + // The symbol vendor doesn't know about this compile unit, we + // need to parse and add it to the symbol vendor object. + return ParseCompileUnit(dwarf_cu, cu_idx).get(); + } + return (CompileUnit *)dwarf_cu->GetUserData(); } -size_t -SymbolFileDWARF::GetObjCMethodDIEOffsets (ConstString class_name, DIEArray &method_die_offsets) -{ - method_die_offsets.clear(); - if (m_using_apple_tables) - { - if (m_apple_objc_ap.get()) - m_apple_objc_ap->FindByName(class_name.GetCString(), method_die_offsets); - } - else - { - if (!m_indexed) - Index (); - - m_objc_class_selectors_index.Find (class_name, method_die_offsets); - } - return method_die_offsets.size(); +size_t SymbolFileDWARF::GetObjCMethodDIEOffsets(ConstString class_name, + DIEArray &method_die_offsets) { + method_die_offsets.clear(); + if (m_using_apple_tables) { + if (m_apple_objc_ap.get()) + m_apple_objc_ap->FindByName(class_name.GetCString(), method_die_offsets); + } else { + if (!m_indexed) + Index(); + + m_objc_class_selectors_index.Find(class_name, method_die_offsets); + } + return method_die_offsets.size(); } -bool -SymbolFileDWARF::GetFunction (const DWARFDIE &die, SymbolContext& sc) -{ - sc.Clear(false); +bool SymbolFileDWARF::GetFunction(const DWARFDIE &die, SymbolContext &sc) { + sc.Clear(false); - if (die) - { - // Check if the symbol vendor already knows about this compile unit? - sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX); + if (die) { + // Check if the symbol vendor already knows about this compile unit? + sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX); - sc.function = sc.comp_unit->FindFunctionByUID (die.GetID()).get(); - if (sc.function == NULL) - sc.function = ParseCompileUnitFunction(sc, die); - - if (sc.function) - { - sc.module_sp = sc.function->CalculateSymbolContextModule(); - return true; - } + sc.function = sc.comp_unit->FindFunctionByUID(die.GetID()).get(); + if (sc.function == NULL) + sc.function = ParseCompileUnitFunction(sc, die); + + if (sc.function) { + sc.module_sp = sc.function->CalculateSymbolContextModule(); + return true; } - - return false; + } + + return false; } -lldb::ModuleSP -SymbolFileDWARF::GetDWOModule (ConstString name) -{ - UpdateExternalModuleListIfNeeded(); - const auto &pos = m_external_type_modules.find(name); - if (pos != m_external_type_modules.end()) - return pos->second; - else - return lldb::ModuleSP(); +lldb::ModuleSP SymbolFileDWARF::GetDWOModule(ConstString name) { + UpdateExternalModuleListIfNeeded(); + const auto &pos = m_external_type_modules.find(name); + if (pos != m_external_type_modules.end()) + return pos->second; + else + return lldb::ModuleSP(); } DWARFDIE -SymbolFileDWARF::GetDIE (const DIERef &die_ref) -{ - DWARFDebugInfo * debug_info = DebugInfo(); - if (debug_info) - return debug_info->GetDIE(die_ref); - else - return DWARFDIE(); +SymbolFileDWARF::GetDIE(const DIERef &die_ref) { + DWARFDebugInfo *debug_info = DebugInfo(); + if (debug_info) + return debug_info->GetDIE(die_ref); + else + return DWARFDIE(); } - std::unique_ptr<SymbolFileDWARFDwo> -SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(DWARFCompileUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die) -{ - // If we are using a dSYM file, we never want the standard DWO files since - // the -gmodule support uses the same DWO machanism to specify full debug - // info files for modules. - if (GetDebugMapSymfile()) - return nullptr; - - const char *dwo_name = cu_die.GetAttributeValueAsString(this, &dwarf_cu, DW_AT_GNU_dwo_name, nullptr); - if (!dwo_name) - return nullptr; - - FileSpec dwo_file(dwo_name, true); - 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); - dwo_file.AppendPathComponent(dwo_name); - } +SymbolFileDWARF::GetDwoSymbolFileForCompileUnit( + DWARFCompileUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die) { + // If we are using a dSYM file, we never want the standard DWO files since + // the -gmodule support uses the same DWO machanism to specify full debug + // info files for modules. + if (GetDebugMapSymfile()) + return nullptr; - if (!dwo_file.Exists()) - return nullptr; + const char *dwo_name = cu_die.GetAttributeValueAsString( + this, &dwarf_cu, DW_AT_GNU_dwo_name, nullptr); + if (!dwo_name) + return nullptr; - const lldb::offset_t file_offset = 0; - DataBufferSP dwo_file_data_sp; - 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); - if (dwo_obj_file == nullptr) - return nullptr; + FileSpec dwo_file(dwo_name, true); + if (dwo_file.IsRelative()) { + const char *comp_dir = cu_die.GetAttributeValueAsString( + this, &dwarf_cu, DW_AT_comp_dir, nullptr); + if (!comp_dir) + return nullptr; - return llvm::make_unique<SymbolFileDWARFDwo>(dwo_obj_file, &dwarf_cu); -} + dwo_file.SetFile(comp_dir, true); + dwo_file.AppendPathComponent(dwo_name); + } -void -SymbolFileDWARF::UpdateExternalModuleListIfNeeded() -{ - if (m_fetched_external_modules) - return; - m_fetched_external_modules = true; - - DWARFDebugInfo * debug_info = DebugInfo(); + if (!dwo_file.Exists()) + return nullptr; - const uint32_t num_compile_units = GetNumCompileUnits(); - for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) - { - DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx); - - const DWARFDIE die = dwarf_cu->GetCompileUnitDIEOnly(); - if (die && die.HasChildren() == false) - { - const char *name = die.GetAttributeValueAsString(DW_AT_name, nullptr); - - if (name) - { - ConstString const_name(name); - if (m_external_type_modules.find(const_name) == m_external_type_modules.end()) - { - ModuleSP module_sp; - const char *dwo_path = die.GetAttributeValueAsString(DW_AT_GNU_dwo_name, nullptr); - if (dwo_path) - { - ModuleSpec dwo_module_spec; - dwo_module_spec.GetFileSpec().SetFile(dwo_path, false); - 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().AppendPathComponent(dwo_path); - } - } - dwo_module_spec.GetArchitecture() = m_obj_file->GetModule()->GetArchitecture(); - //printf ("Loading dwo = '%s'\n", dwo_path); - Error error = ModuleList::GetSharedModule (dwo_module_spec, module_sp, NULL, NULL, NULL); - if (!module_sp) - { - GetObjectFile()->GetModule()->ReportWarning ("0x%8.8x: unable to locate module needed for external types: %s\nerror: %s\nDebugging will be degraded due to missing types. Rebuilding your project will regenerate the needed module files.", - die.GetOffset(), - dwo_module_spec.GetFileSpec().GetPath().c_str(), - error.AsCString("unknown error")); - } - } - m_external_type_modules[const_name] = module_sp; - } + const lldb::offset_t file_offset = 0; + DataBufferSP dwo_file_data_sp; + 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); + if (dwo_obj_file == nullptr) + return nullptr; + + return llvm::make_unique<SymbolFileDWARFDwo>(dwo_obj_file, &dwarf_cu); +} + +void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() { + if (m_fetched_external_modules) + return; + m_fetched_external_modules = true; + + DWARFDebugInfo *debug_info = DebugInfo(); + + const uint32_t num_compile_units = GetNumCompileUnits(); + for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) { + DWARFCompileUnit *dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx); + + const DWARFDIE die = dwarf_cu->GetCompileUnitDIEOnly(); + if (die && die.HasChildren() == false) { + const char *name = die.GetAttributeValueAsString(DW_AT_name, nullptr); + + if (name) { + ConstString const_name(name); + if (m_external_type_modules.find(const_name) == + m_external_type_modules.end()) { + ModuleSP module_sp; + const char *dwo_path = + die.GetAttributeValueAsString(DW_AT_GNU_dwo_name, nullptr); + if (dwo_path) { + ModuleSpec dwo_module_spec; + dwo_module_spec.GetFileSpec().SetFile(dwo_path, false); + 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().AppendPathComponent(dwo_path); + } + } + dwo_module_spec.GetArchitecture() = + m_obj_file->GetModule()->GetArchitecture(); + // printf ("Loading dwo = '%s'\n", dwo_path); + Error error = ModuleList::GetSharedModule( + dwo_module_spec, module_sp, NULL, NULL, NULL); + if (!module_sp) { + GetObjectFile()->GetModule()->ReportWarning( + "0x%8.8x: unable to locate module needed for external types: " + "%s\nerror: %s\nDebugging will be degraded due to missing " + "types. Rebuilding your project will regenerate the needed " + "module files.", + die.GetOffset(), + dwo_module_spec.GetFileSpec().GetPath().c_str(), + error.AsCString("unknown error")); } + } + m_external_type_modules[const_name] = module_sp; } + } } + } } -SymbolFileDWARF::GlobalVariableMap & -SymbolFileDWARF::GetGlobalAranges() -{ - if (!m_global_aranges_ap) - { - m_global_aranges_ap.reset (new GlobalVariableMap()); - - ModuleSP module_sp = GetObjectFile()->GetModule(); - if (module_sp) - { - const size_t num_cus = module_sp->GetNumCompileUnits(); - for (size_t i = 0; i < num_cus; ++i) - { - CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(i); - if (cu_sp) - { - VariableListSP globals_sp = cu_sp->GetVariableList(true); - if (globals_sp) - { - const size_t num_globals = globals_sp->GetSize(); - for (size_t g = 0; g < num_globals; ++g) - { - VariableSP var_sp = globals_sp->GetVariableAtIndex(g); - if (var_sp && !var_sp->GetLocationIsConstantValueData()) - { - const DWARFExpression &location = var_sp->LocationExpression(); - Value location_result; - Error error; - if (location.Evaluate(nullptr, nullptr, nullptr, LLDB_INVALID_ADDRESS, nullptr, nullptr, location_result, &error)) - { - if (location_result.GetValueType() == Value::eValueTypeFileAddress) - { - lldb::addr_t file_addr = location_result.GetScalar().ULongLong(); - lldb::addr_t byte_size = 1; - if (var_sp->GetType()) - byte_size = var_sp->GetType()->GetByteSize(); - m_global_aranges_ap->Append(GlobalVariableMap::Entry(file_addr, byte_size, var_sp.get())); - } - } - } - } - } +SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() { + if (!m_global_aranges_ap) { + m_global_aranges_ap.reset(new GlobalVariableMap()); + + ModuleSP module_sp = GetObjectFile()->GetModule(); + if (module_sp) { + const size_t num_cus = module_sp->GetNumCompileUnits(); + for (size_t i = 0; i < num_cus; ++i) { + CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(i); + if (cu_sp) { + VariableListSP globals_sp = cu_sp->GetVariableList(true); + if (globals_sp) { + const size_t num_globals = globals_sp->GetSize(); + for (size_t g = 0; g < num_globals; ++g) { + VariableSP var_sp = globals_sp->GetVariableAtIndex(g); + if (var_sp && !var_sp->GetLocationIsConstantValueData()) { + const DWARFExpression &location = var_sp->LocationExpression(); + Value location_result; + Error error; + if (location.Evaluate(nullptr, nullptr, nullptr, + LLDB_INVALID_ADDRESS, nullptr, nullptr, + location_result, &error)) { + if (location_result.GetValueType() == + Value::eValueTypeFileAddress) { + lldb::addr_t file_addr = + location_result.GetScalar().ULongLong(); + lldb::addr_t byte_size = 1; + if (var_sp->GetType()) + byte_size = var_sp->GetType()->GetByteSize(); + m_global_aranges_ap->Append(GlobalVariableMap::Entry( + file_addr, byte_size, var_sp.get())); + } } + } } + } } - m_global_aranges_ap->Sort(); + } } - return *m_global_aranges_ap; + m_global_aranges_ap->Sort(); + } + return *m_global_aranges_ap; } - -uint32_t -SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) -{ - Timer scoped_timer(__PRETTY_FUNCTION__, - "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%" PRIx64 " }, resolve_scope = 0x%8.8x)", - static_cast<void*>(so_addr.GetSection().get()), - so_addr.GetOffset(), resolve_scope); - uint32_t resolved = 0; - if (resolve_scope & ( eSymbolContextCompUnit | - eSymbolContextFunction | - eSymbolContextBlock | - eSymbolContextLineEntry | - eSymbolContextVariable )) - { - lldb::addr_t file_vm_addr = so_addr.GetFileAddress(); - - DWARFDebugInfo* debug_info = DebugInfo(); - if (debug_info) - { - const dw_offset_t cu_offset = debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr); - if (cu_offset == DW_INVALID_OFFSET) - { - // Global variables are not in the compile unit address ranges. The only way to - // currently find global variables is to iterate over the .debug_pubnames or the - // __apple_names table and find all items in there that point to DW_TAG_variable - // DIEs and then find the address that matches. - if (resolve_scope & eSymbolContextVariable) - { - GlobalVariableMap &map = GetGlobalAranges(); - const GlobalVariableMap::Entry *entry = map.FindEntryThatContains(file_vm_addr); - if (entry && entry->data) - { - Variable *variable = entry->data; - SymbolContextScope *scc = variable->GetSymbolContextScope(); - if (scc) - { - scc->CalculateSymbolContext(&sc); - sc.variable = variable; - } - return sc.GetResolvedMask(); - } +uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr, + uint32_t resolve_scope, + SymbolContext &sc) { + Timer scoped_timer(LLVM_PRETTY_FUNCTION, "SymbolFileDWARF::" + "ResolveSymbolContext (so_addr = { " + "section = %p, offset = 0x%" PRIx64 + " }, resolve_scope = 0x%8.8x)", + static_cast<void *>(so_addr.GetSection().get()), + so_addr.GetOffset(), resolve_scope); + uint32_t resolved = 0; + if (resolve_scope & + (eSymbolContextCompUnit | eSymbolContextFunction | eSymbolContextBlock | + eSymbolContextLineEntry | eSymbolContextVariable)) { + lldb::addr_t file_vm_addr = so_addr.GetFileAddress(); + + DWARFDebugInfo *debug_info = DebugInfo(); + if (debug_info) { + const dw_offset_t cu_offset = + debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr); + if (cu_offset == DW_INVALID_OFFSET) { + // Global variables are not in the compile unit address ranges. The only + // way to + // currently find global variables is to iterate over the + // .debug_pubnames or the + // __apple_names table and find all items in there that point to + // DW_TAG_variable + // DIEs and then find the address that matches. + if (resolve_scope & eSymbolContextVariable) { + GlobalVariableMap &map = GetGlobalAranges(); + const GlobalVariableMap::Entry *entry = + map.FindEntryThatContains(file_vm_addr); + if (entry && entry->data) { + Variable *variable = entry->data; + SymbolContextScope *scc = variable->GetSymbolContextScope(); + if (scc) { + scc->CalculateSymbolContext(&sc); + sc.variable = variable; + } + return sc.GetResolvedMask(); + } + } + } else { + uint32_t cu_idx = DW_INVALID_INDEX; + DWARFCompileUnit *dwarf_cu = + debug_info->GetCompileUnit(cu_offset, &cu_idx); + if (dwarf_cu) { + sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx); + if (sc.comp_unit) { + resolved |= eSymbolContextCompUnit; + + bool force_check_line_table = false; + if (resolve_scope & + (eSymbolContextFunction | eSymbolContextBlock)) { + DWARFDIE function_die = dwarf_cu->LookupAddress(file_vm_addr); + DWARFDIE block_die; + if (function_die) { + sc.function = + sc.comp_unit->FindFunctionByUID(function_die.GetID()).get(); + if (sc.function == NULL) + sc.function = ParseCompileUnitFunction(sc, function_die); + + if (sc.function && (resolve_scope & eSymbolContextBlock)) + block_die = function_die.LookupDeepestBlock(file_vm_addr); + } else { + // We might have had a compile unit that had discontiguous + // address ranges where the gaps are symbols that don't have + // any debug info. Discontiguous compile unit address ranges + // should only happen when there aren't other functions from + // other compile units in these gaps. This helps keep the size + // of the aranges down. + force_check_line_table = true; + } + + if (sc.function != NULL) { + resolved |= eSymbolContextFunction; + + if (resolve_scope & eSymbolContextBlock) { + Block &block = sc.function->GetBlock(true); + + if (block_die) + sc.block = block.FindBlockByID(block_die.GetID()); + else + sc.block = block.FindBlockByID(function_die.GetID()); + if (sc.block) + resolved |= eSymbolContextBlock; } + } } - else - { - uint32_t cu_idx = DW_INVALID_INDEX; - DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx); - if (dwarf_cu) - { - sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx); - if (sc.comp_unit) - { - resolved |= eSymbolContextCompUnit; - - bool force_check_line_table = false; - if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) - { - DWARFDIE function_die = dwarf_cu->LookupAddress(file_vm_addr); - DWARFDIE block_die; - if (function_die) - { - sc.function = sc.comp_unit->FindFunctionByUID (function_die.GetID()).get(); - if (sc.function == NULL) - sc.function = ParseCompileUnitFunction(sc, function_die); - - if (sc.function && (resolve_scope & eSymbolContextBlock)) - block_die = function_die.LookupDeepestBlock(file_vm_addr); - } - else - { - // We might have had a compile unit that had discontiguous - // address ranges where the gaps are symbols that don't have - // any debug info. Discontiguous compile unit address ranges - // should only happen when there aren't other functions from - // other compile units in these gaps. This helps keep the size - // of the aranges down. - force_check_line_table = true; - } - - if (sc.function != NULL) - { - resolved |= eSymbolContextFunction; - - if (resolve_scope & eSymbolContextBlock) - { - Block& block = sc.function->GetBlock (true); - - if (block_die) - sc.block = block.FindBlockByID (block_die.GetID()); - else - sc.block = block.FindBlockByID (function_die.GetID()); - if (sc.block) - resolved |= eSymbolContextBlock; - } - } - } - - if ((resolve_scope & eSymbolContextLineEntry) || force_check_line_table) - { - LineTable *line_table = sc.comp_unit->GetLineTable(); - if (line_table != NULL) - { - // And address that makes it into this function should be in terms - // of this debug file if there is no debug map, or it will be an - // address in the .o file which needs to be fixed up to be in terms - // of the debug map executable. Either way, calling FixupAddress() - // will work for us. - Address exe_so_addr (so_addr); - if (FixupAddress(exe_so_addr)) - { - if (line_table->FindLineEntryByAddress (exe_so_addr, sc.line_entry)) - { - resolved |= eSymbolContextLineEntry; - } - } - } - } - - if (force_check_line_table && !(resolved & eSymbolContextLineEntry)) - { - // We might have had a compile unit that had discontiguous - // address ranges where the gaps are symbols that don't have - // any debug info. Discontiguous compile unit address ranges - // should only happen when there aren't other functions from - // other compile units in these gaps. This helps keep the size - // of the aranges down. - sc.comp_unit = NULL; - resolved &= ~eSymbolContextCompUnit; - } - } - else - { - GetObjectFile()->GetModule()->ReportWarning ("0x%8.8x: compile unit %u failed to create a valid lldb_private::CompileUnit class.", - cu_offset, - cu_idx); - } + + if ((resolve_scope & eSymbolContextLineEntry) || + force_check_line_table) { + LineTable *line_table = sc.comp_unit->GetLineTable(); + if (line_table != NULL) { + // And address that makes it into this function should be in + // terms + // of this debug file if there is no debug map, or it will be an + // address in the .o file which needs to be fixed up to be in + // terms + // of the debug map executable. Either way, calling + // FixupAddress() + // will work for us. + Address exe_so_addr(so_addr); + if (FixupAddress(exe_so_addr)) { + if (line_table->FindLineEntryByAddress(exe_so_addr, + sc.line_entry)) { + resolved |= eSymbolContextLineEntry; + } } + } } + + if (force_check_line_table && + !(resolved & eSymbolContextLineEntry)) { + // We might have had a compile unit that had discontiguous + // address ranges where the gaps are symbols that don't have + // any debug info. Discontiguous compile unit address ranges + // should only happen when there aren't other functions from + // other compile units in these gaps. This helps keep the size + // of the aranges down. + sc.comp_unit = NULL; + resolved &= ~eSymbolContextCompUnit; + } + } else { + GetObjectFile()->GetModule()->ReportWarning( + "0x%8.8x: compile unit %u failed to create a valid " + "lldb_private::CompileUnit class.", + cu_offset, cu_idx); + } } + } } - return resolved; + } + return resolved; } +uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec, + uint32_t line, + bool check_inlines, + uint32_t resolve_scope, + SymbolContextList &sc_list) { + const uint32_t prev_size = sc_list.GetSize(); + if (resolve_scope & eSymbolContextCompUnit) { + DWARFDebugInfo *debug_info = DebugInfo(); + if (debug_info) { + uint32_t cu_idx; + DWARFCompileUnit *dwarf_cu = NULL; + + for (cu_idx = 0; + (dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; + ++cu_idx) { + CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx); + const bool full_match = (bool)file_spec.GetDirectory(); + bool file_spec_matches_cu_file_spec = + dc_cu != NULL && FileSpec::Equal(file_spec, *dc_cu, full_match); + if (check_inlines || file_spec_matches_cu_file_spec) { + SymbolContext sc(m_obj_file->GetModule()); + sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx); + if (sc.comp_unit) { + uint32_t file_idx = UINT32_MAX; + + // If we are looking for inline functions only and we don't + // find it in the support files, we are done. + if (check_inlines) { + file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex( + 1, file_spec, true); + if (file_idx == UINT32_MAX) + continue; + } - -uint32_t -SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) -{ - const uint32_t prev_size = sc_list.GetSize(); - if (resolve_scope & eSymbolContextCompUnit) - { - DWARFDebugInfo* debug_info = DebugInfo(); - if (debug_info) - { - uint32_t cu_idx; - DWARFCompileUnit* dwarf_cu = NULL; - - for (cu_idx = 0; (dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx) - { - CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx); - const bool full_match = (bool)file_spec.GetDirectory(); - bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Equal(file_spec, *dc_cu, full_match); - if (check_inlines || file_spec_matches_cu_file_spec) - { - SymbolContext sc (m_obj_file->GetModule()); - sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx); - if (sc.comp_unit) - { - uint32_t file_idx = UINT32_MAX; - - // If we are looking for inline functions only and we don't - // find it in the support files, we are done. - if (check_inlines) - { - file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true); - if (file_idx == UINT32_MAX) - continue; + if (line != 0) { + LineTable *line_table = sc.comp_unit->GetLineTable(); + + if (line_table != NULL && line != 0) { + // We will have already looked up the file index if + // we are searching for inline entries. + if (!check_inlines) + file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex( + 1, file_spec, true); + + if (file_idx != UINT32_MAX) { + uint32_t found_line; + uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex( + 0, file_idx, line, false, &sc.line_entry); + found_line = sc.line_entry.line; + + while (line_idx != UINT32_MAX) { + sc.function = NULL; + sc.block = NULL; + if (resolve_scope & + (eSymbolContextFunction | eSymbolContextBlock)) { + const lldb::addr_t file_vm_addr = + sc.line_entry.range.GetBaseAddress().GetFileAddress(); + if (file_vm_addr != LLDB_INVALID_ADDRESS) { + DWARFDIE function_die = + dwarf_cu->LookupAddress(file_vm_addr); + DWARFDIE block_die; + if (function_die) { + sc.function = + sc.comp_unit + ->FindFunctionByUID(function_die.GetID()) + .get(); + if (sc.function == NULL) + sc.function = + ParseCompileUnitFunction(sc, function_die); + + if (sc.function && + (resolve_scope & eSymbolContextBlock)) + block_die = + function_die.LookupDeepestBlock(file_vm_addr); } - if (line != 0) - { - LineTable *line_table = sc.comp_unit->GetLineTable(); - - if (line_table != NULL && line != 0) - { - // We will have already looked up the file index if - // we are searching for inline entries. - if (!check_inlines) - file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true); - - if (file_idx != UINT32_MAX) - { - uint32_t found_line; - uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry); - found_line = sc.line_entry.line; - - while (line_idx != UINT32_MAX) - { - sc.function = NULL; - sc.block = NULL; - if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) - { - const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress(); - if (file_vm_addr != LLDB_INVALID_ADDRESS) - { - DWARFDIE function_die = dwarf_cu->LookupAddress(file_vm_addr); - DWARFDIE block_die; - if (function_die) - { - sc.function = sc.comp_unit->FindFunctionByUID (function_die.GetID()).get(); - if (sc.function == NULL) - sc.function = ParseCompileUnitFunction(sc, function_die); - - if (sc.function && (resolve_scope & eSymbolContextBlock)) - block_die = function_die.LookupDeepestBlock(file_vm_addr); - } - - if (sc.function != NULL) - { - Block& block = sc.function->GetBlock (true); - - if (block_die) - sc.block = block.FindBlockByID (block_die.GetID()); - else if (function_die) - sc.block = block.FindBlockByID (function_die.GetID()); - } - } - } - - sc_list.Append(sc); - line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry); - } - } - } - else if (file_spec_matches_cu_file_spec && !check_inlines) - { - // only append the context if we aren't looking for inline call sites - // by file and line and if the file spec matches that of the compile unit - sc_list.Append(sc); - } - } - else if (file_spec_matches_cu_file_spec && !check_inlines) - { - // only append the context if we aren't looking for inline call sites - // by file and line and if the file spec matches that of the compile unit - sc_list.Append(sc); - } + if (sc.function != NULL) { + Block &block = sc.function->GetBlock(true); - if (!check_inlines) - break; + if (block_die) + sc.block = block.FindBlockByID(block_die.GetID()); + else if (function_die) + sc.block = + block.FindBlockByID(function_die.GetID()); + } + } } + + sc_list.Append(sc); + line_idx = line_table->FindLineEntryIndexByFileIndex( + line_idx + 1, file_idx, found_line, true, + &sc.line_entry); + } } + } else if (file_spec_matches_cu_file_spec && !check_inlines) { + // only append the context if we aren't looking for inline call + // sites + // by file and line and if the file spec matches that of the + // compile unit + sc_list.Append(sc); + } + } else if (file_spec_matches_cu_file_spec && !check_inlines) { + // only append the context if we aren't looking for inline call + // sites + // by file and line and if the file spec matches that of the + // compile unit + sc_list.Append(sc); } + + if (!check_inlines) + break; + } } + } } - return sc_list.GetSize() - prev_size; + } + return sc_list.GetSize() - prev_size; } -void -SymbolFileDWARF::Index () -{ - if (m_indexed) - return; - m_indexed = true; - Timer scoped_timer (__PRETTY_FUNCTION__, - "SymbolFileDWARF::Index (%s)", - GetObjectFile()->GetFileSpec().GetFilename().AsCString("<Unknown>")); - - DWARFDebugInfo* debug_info = DebugInfo(); - if (debug_info) - { - const uint32_t num_compile_units = GetNumCompileUnits(); - if (num_compile_units == 0) - return; - - std::vector<NameToDIE> function_basename_index(num_compile_units); - std::vector<NameToDIE> function_fullname_index(num_compile_units); - std::vector<NameToDIE> function_method_index(num_compile_units); - std::vector<NameToDIE> function_selector_index(num_compile_units); - std::vector<NameToDIE> objc_class_selectors_index(num_compile_units); - std::vector<NameToDIE> global_index(num_compile_units); - std::vector<NameToDIE> type_index(num_compile_units); - std::vector<NameToDIE> namespace_index(num_compile_units); - - std::vector<bool> clear_cu_dies(num_compile_units, false); - auto parser_fn = [this, - debug_info, - &function_basename_index, - &function_fullname_index, - &function_method_index, - &function_selector_index, - &objc_class_selectors_index, - &global_index, - &type_index, - &namespace_index](uint32_t cu_idx) - { - DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx); - if (dwarf_cu) - { - dwarf_cu->Index(function_basename_index[cu_idx], - function_fullname_index[cu_idx], - function_method_index[cu_idx], - function_selector_index[cu_idx], - objc_class_selectors_index[cu_idx], - global_index[cu_idx], - type_index[cu_idx], - namespace_index[cu_idx]); - } - return cu_idx; - }; - - auto extract_fn = [this, - debug_info, - num_compile_units](uint32_t cu_idx) - { - DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx); - if (dwarf_cu) - { - // dwarf_cu->ExtractDIEsIfNeeded(false) will return zero if the - // DIEs for a compile unit have already been parsed. - return std::make_pair(cu_idx, dwarf_cu->ExtractDIEsIfNeeded(false) > 1); - } - return std::make_pair(cu_idx, false); - }; - - // Create a task runner that extracts dies for each DWARF compile unit in a separate thread - TaskRunner<std::pair<uint32_t, bool>> task_runner_extract; - for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) - task_runner_extract.AddTask(extract_fn, cu_idx); - - //---------------------------------------------------------------------- - // First figure out which compile units didn't have their DIEs already - // parsed and remember this. If no DIEs were parsed prior to this index - // function call, we are going to want to clear the CU dies after we - // are done indexing to make sure we don't pull in all DWARF dies, but - // we need to wait until all compile units have been indexed in case - // a DIE in one compile unit refers to another and the indexes accesses - // those DIEs. - //---------------------------------------------------------------------- - while (true) - { - auto f = task_runner_extract.WaitForNextCompletedTask(); - if (!f.valid()) - break; - unsigned cu_idx; - bool clear; - std::tie(cu_idx, clear) = f.get(); - clear_cu_dies[cu_idx] = clear; - } +void SymbolFileDWARF::Index() { + if (m_indexed) + return; + m_indexed = true; + Timer scoped_timer( + LLVM_PRETTY_FUNCTION, "SymbolFileDWARF::Index (%s)", + GetObjectFile()->GetFileSpec().GetFilename().AsCString("<Unknown>")); - // Now create a task runner that can index each DWARF compile unit in a separate - // thread so we can index quickly. + DWARFDebugInfo *debug_info = DebugInfo(); + if (debug_info) { + const uint32_t num_compile_units = GetNumCompileUnits(); + if (num_compile_units == 0) + return; + + std::vector<NameToDIE> function_basename_index(num_compile_units); + std::vector<NameToDIE> function_fullname_index(num_compile_units); + std::vector<NameToDIE> function_method_index(num_compile_units); + std::vector<NameToDIE> function_selector_index(num_compile_units); + std::vector<NameToDIE> objc_class_selectors_index(num_compile_units); + std::vector<NameToDIE> global_index(num_compile_units); + std::vector<NameToDIE> type_index(num_compile_units); + std::vector<NameToDIE> namespace_index(num_compile_units); + + std::vector<bool> clear_cu_dies(num_compile_units, false); + auto parser_fn = [this, debug_info, &function_basename_index, + &function_fullname_index, &function_method_index, + &function_selector_index, &objc_class_selectors_index, + &global_index, &type_index, + &namespace_index](uint32_t cu_idx) { + DWARFCompileUnit *dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx); + if (dwarf_cu) { + dwarf_cu->Index( + function_basename_index[cu_idx], function_fullname_index[cu_idx], + function_method_index[cu_idx], function_selector_index[cu_idx], + objc_class_selectors_index[cu_idx], global_index[cu_idx], + type_index[cu_idx], namespace_index[cu_idx]); + } + return cu_idx; + }; - TaskRunner<uint32_t> task_runner; - for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) - task_runner.AddTask(parser_fn, cu_idx); + auto extract_fn = [this, debug_info, num_compile_units](uint32_t cu_idx) { + DWARFCompileUnit *dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx); + if (dwarf_cu) { + // dwarf_cu->ExtractDIEsIfNeeded(false) will return zero if the + // DIEs for a compile unit have already been parsed. + return std::make_pair(cu_idx, dwarf_cu->ExtractDIEsIfNeeded(false) > 1); + } + return std::make_pair(cu_idx, false); + }; - while (true) - { - std::future<uint32_t> f = task_runner.WaitForNextCompletedTask(); - if (!f.valid()) - break; - uint32_t cu_idx = f.get(); - - m_function_basename_index.Append(function_basename_index[cu_idx]); - m_function_fullname_index.Append(function_fullname_index[cu_idx]); - m_function_method_index.Append(function_method_index[cu_idx]); - m_function_selector_index.Append(function_selector_index[cu_idx]); - m_objc_class_selectors_index.Append(objc_class_selectors_index[cu_idx]); - m_global_index.Append(global_index[cu_idx]); - m_type_index.Append(type_index[cu_idx]); - m_namespace_index.Append(namespace_index[cu_idx]); - } + // Create a task runner that extracts dies for each DWARF compile unit in a + // separate thread + TaskRunner<std::pair<uint32_t, bool>> task_runner_extract; + for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) + task_runner_extract.AddTask(extract_fn, cu_idx); + + //---------------------------------------------------------------------- + // First figure out which compile units didn't have their DIEs already + // parsed and remember this. If no DIEs were parsed prior to this index + // function call, we are going to want to clear the CU dies after we + // are done indexing to make sure we don't pull in all DWARF dies, but + // we need to wait until all compile units have been indexed in case + // a DIE in one compile unit refers to another and the indexes accesses + // those DIEs. + //---------------------------------------------------------------------- + while (true) { + auto f = task_runner_extract.WaitForNextCompletedTask(); + if (!f.valid()) + break; + unsigned cu_idx; + bool clear; + std::tie(cu_idx, clear) = f.get(); + clear_cu_dies[cu_idx] = clear; + } - TaskPool::RunTasks( - [&]() { m_function_basename_index.Finalize(); }, - [&]() { m_function_fullname_index.Finalize(); }, - [&]() { m_function_method_index.Finalize(); }, - [&]() { m_function_selector_index.Finalize(); }, - [&]() { m_objc_class_selectors_index.Finalize(); }, - [&]() { m_global_index.Finalize(); }, - [&]() { m_type_index.Finalize(); }, - [&]() { m_namespace_index.Finalize(); }); - - //---------------------------------------------------------------------- - // Keep memory down by clearing DIEs for any compile units if indexing - // caused us to load the compile unit's DIEs. - //---------------------------------------------------------------------- - for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) - { - if (clear_cu_dies[cu_idx]) - debug_info->GetCompileUnitAtIndex(cu_idx)->ClearDIEs(true); - } + // Now create a task runner that can index each DWARF compile unit in a + // separate + // thread so we can index quickly. -#if defined (ENABLE_DEBUG_PRINTF) - StreamFile s(stdout, false); - s.Printf ("DWARF index for '%s':", - GetObjectFile()->GetFileSpec().GetPath().c_str()); - s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s); - s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s); - s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s); - s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s); - s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s); - s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s); - s.Printf("\nTypes:\n"); m_type_index.Dump (&s); - s.Printf("\nNamespaces:\n") m_namespace_index.Dump (&s); -#endif + TaskRunner<uint32_t> task_runner; + for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) + task_runner.AddTask(parser_fn, cu_idx); + + while (true) { + std::future<uint32_t> f = task_runner.WaitForNextCompletedTask(); + if (!f.valid()) + break; + uint32_t cu_idx = f.get(); + + m_function_basename_index.Append(function_basename_index[cu_idx]); + m_function_fullname_index.Append(function_fullname_index[cu_idx]); + m_function_method_index.Append(function_method_index[cu_idx]); + m_function_selector_index.Append(function_selector_index[cu_idx]); + m_objc_class_selectors_index.Append(objc_class_selectors_index[cu_idx]); + m_global_index.Append(global_index[cu_idx]); + m_type_index.Append(type_index[cu_idx]); + m_namespace_index.Append(namespace_index[cu_idx]); } -} -bool -SymbolFileDWARF::DeclContextMatchesThisSymbolFile (const lldb_private::CompilerDeclContext *decl_ctx) -{ - if (decl_ctx == nullptr || !decl_ctx->IsValid()) - { - // Invalid namespace decl which means we aren't matching only things - // in this symbol file, so return true to indicate it matches this - // symbol file. - return true; + TaskPool::RunTasks([&]() { m_function_basename_index.Finalize(); }, + [&]() { m_function_fullname_index.Finalize(); }, + [&]() { m_function_method_index.Finalize(); }, + [&]() { m_function_selector_index.Finalize(); }, + [&]() { m_objc_class_selectors_index.Finalize(); }, + [&]() { m_global_index.Finalize(); }, + [&]() { m_type_index.Finalize(); }, + [&]() { m_namespace_index.Finalize(); }); + + //---------------------------------------------------------------------- + // Keep memory down by clearing DIEs for any compile units if indexing + // caused us to load the compile unit's DIEs. + //---------------------------------------------------------------------- + for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) { + if (clear_cu_dies[cu_idx]) + debug_info->GetCompileUnitAtIndex(cu_idx)->ClearDIEs(true); } - TypeSystem *decl_ctx_type_system = decl_ctx->GetTypeSystem(); - TypeSystem *type_system = GetTypeSystemForLanguage(decl_ctx_type_system->GetMinimumLanguage(nullptr)); - if (decl_ctx_type_system == type_system) - return true; // The type systems match, return true - - // The namespace AST was valid, and it does not match... - Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); +#if defined(ENABLE_DEBUG_PRINTF) + StreamFile s(stdout, false); + s.Printf("DWARF index for '%s':", + GetObjectFile()->GetFileSpec().GetPath().c_str()); + s.Printf("\nFunction basenames:\n"); + m_function_basename_index.Dump(&s); + s.Printf("\nFunction fullnames:\n"); + m_function_fullname_index.Dump(&s); + s.Printf("\nFunction methods:\n"); + m_function_method_index.Dump(&s); + s.Printf("\nFunction selectors:\n"); + m_function_selector_index.Dump(&s); + s.Printf("\nObjective C class selectors:\n"); + m_objc_class_selectors_index.Dump(&s); + s.Printf("\nGlobals and statics:\n"); + m_global_index.Dump(&s); + s.Printf("\nTypes:\n"); + m_type_index.Dump(&s); + s.Printf("\nNamespaces:\n"); + m_namespace_index.Dump(&s); +#endif + } +} - if (log) - GetObjectFile()->GetModule()->LogMessage(log, "Valid namespace does not match symbol file"); - - return false; +bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile( + const lldb_private::CompilerDeclContext *decl_ctx) { + if (decl_ctx == nullptr || !decl_ctx->IsValid()) { + // Invalid namespace decl which means we aren't matching only things + // in this symbol file, so return true to indicate it matches this + // symbol file. + return true; + } + + TypeSystem *decl_ctx_type_system = decl_ctx->GetTypeSystem(); + TypeSystem *type_system = GetTypeSystemForLanguage( + decl_ctx_type_system->GetMinimumLanguage(nullptr)); + if (decl_ctx_type_system == type_system) + return true; // The type systems match, return true + + // The namespace AST was valid, and it does not match... + Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); + + if (log) + GetObjectFile()->GetModule()->LogMessage( + log, "Valid namespace does not match symbol file"); + + return false; } -uint32_t -SymbolFileDWARF::FindGlobalVariables (const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, VariableList& variables) -{ - Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); +uint32_t SymbolFileDWARF::FindGlobalVariables( + const ConstString &name, const CompilerDeclContext *parent_decl_ctx, + bool append, uint32_t max_matches, VariableList &variables) { + Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); - if (log) - GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", parent_decl_ctx=%p, append=%u, max_matches=%u, variables)", - name.GetCString(), - static_cast<const void*>(parent_decl_ctx), - append, max_matches); + if (log) + GetObjectFile()->GetModule()->LogMessage( + log, "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", " + "parent_decl_ctx=%p, append=%u, max_matches=%u, variables)", + name.GetCString(), static_cast<const void *>(parent_decl_ctx), append, + max_matches); - if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) - return 0; + if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) + return 0; - DWARFDebugInfo* info = DebugInfo(); - if (info == NULL) - return 0; + DWARFDebugInfo *info = DebugInfo(); + if (info == NULL) + return 0; - // If we aren't appending the results to this list, then clear the list - if (!append) - variables.Clear(); + // If we aren't appending the results to this list, then clear the list + if (!append) + variables.Clear(); - // Remember how many variables are in the list before we search in case - // we are appending the results to a variable list. - const uint32_t original_size = variables.GetSize(); + // Remember how many variables are in the list before we search in case + // we are appending the results to a variable list. + const uint32_t original_size = variables.GetSize(); - DIEArray die_offsets; + DIEArray die_offsets; - if (m_using_apple_tables) - { - if (m_apple_names_ap.get()) - { - const char *name_cstr = name.GetCString(); - llvm::StringRef basename; - llvm::StringRef context; + if (m_using_apple_tables) { + if (m_apple_names_ap.get()) { + const char *name_cstr = name.GetCString(); + llvm::StringRef basename; + llvm::StringRef context; - if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context, basename)) - basename = name_cstr; + if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context, + basename)) + basename = name_cstr; - m_apple_names_ap->FindByName (basename.data(), die_offsets); - } + m_apple_names_ap->FindByName(basename.data(), die_offsets); } - else - { - // Index the DWARF if we haven't already - if (!m_indexed) - Index (); + } else { + // Index the DWARF if we haven't already + if (!m_indexed) + Index(); - m_global_index.Find (name, die_offsets); - } + m_global_index.Find(name, die_offsets); + } - const size_t num_die_matches = die_offsets.size(); - if (num_die_matches) - { - SymbolContext sc; - sc.module_sp = m_obj_file->GetModule(); - assert (sc.module_sp); - - bool done = false; - for (size_t i=0; i<num_die_matches && !done; ++i) - { - const DIERef& die_ref = die_offsets[i]; - DWARFDIE die = GetDIE (die_ref); - - if (die) - { - switch (die.Tag()) - { - default: - case DW_TAG_subprogram: - case DW_TAG_inlined_subroutine: - case DW_TAG_try_block: - case DW_TAG_catch_block: - break; - - case DW_TAG_variable: - { - sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX); - - if (parent_decl_ctx) - { - DWARFASTParser *dwarf_ast = die.GetDWARFParser(); - if (dwarf_ast) - { - CompilerDeclContext actual_parent_decl_ctx = dwarf_ast->GetDeclContextContainingUIDFromDWARF (die); - if (!actual_parent_decl_ctx || actual_parent_decl_ctx != *parent_decl_ctx) - continue; - } - } - - ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables); - - if (variables.GetSize() - original_size >= max_matches) - done = true; - } - break; - } - } - else - { - if (m_using_apple_tables) - { - GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')\n", - die_ref.die_offset, name.GetCString()); - } + const size_t num_die_matches = die_offsets.size(); + if (num_die_matches) { + SymbolContext sc; + sc.module_sp = m_obj_file->GetModule(); + assert(sc.module_sp); + + bool done = false; + for (size_t i = 0; i < num_die_matches && !done; ++i) { + const DIERef &die_ref = die_offsets[i]; + DWARFDIE die = GetDIE(die_ref); + + if (die) { + switch (die.Tag()) { + default: + case DW_TAG_subprogram: + case DW_TAG_inlined_subroutine: + case DW_TAG_try_block: + case DW_TAG_catch_block: + break; + + case DW_TAG_variable: { + sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX); + + if (parent_decl_ctx) { + DWARFASTParser *dwarf_ast = die.GetDWARFParser(); + if (dwarf_ast) { + CompilerDeclContext actual_parent_decl_ctx = + dwarf_ast->GetDeclContextContainingUIDFromDWARF(die); + if (!actual_parent_decl_ctx || + actual_parent_decl_ctx != *parent_decl_ctx) + continue; } - } - } + } - // Return the number of variable that were appended to the list - const uint32_t num_matches = variables.GetSize() - original_size; - if (log && num_matches > 0) - { - GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", parent_decl_ctx=%p, append=%u, max_matches=%u, variables) => %u", - name.GetCString(), - static_cast<const void*>(parent_decl_ctx), - append, max_matches, - num_matches); + ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, + &variables); + + if (variables.GetSize() - original_size >= max_matches) + done = true; + } break; + } + } else { + if (m_using_apple_tables) { + GetObjectFile()->GetModule()->ReportErrorIfModifyDetected( + "the DWARF debug information has been modified (.apple_names " + "accelerator table had bad die 0x%8.8x for '%s')\n", + die_ref.die_offset, name.GetCString()); + } + } } - return num_matches; + } + + // Return the number of variable that were appended to the list + const uint32_t num_matches = variables.GetSize() - original_size; + if (log && num_matches > 0) { + GetObjectFile()->GetModule()->LogMessage( + log, "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", " + "parent_decl_ctx=%p, append=%u, max_matches=%u, variables) => %u", + name.GetCString(), static_cast<const void *>(parent_decl_ctx), append, + max_matches, num_matches); + } + return num_matches; } -uint32_t -SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables) -{ - Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); +uint32_t SymbolFileDWARF::FindGlobalVariables(const RegularExpression ®ex, + bool append, uint32_t max_matches, + VariableList &variables) { + Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); - if (log) - { - GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF::FindGlobalVariables (regex=\"%s\", append=%u, max_matches=%u, variables)", - regex.GetText(), append, - max_matches); - } + if (log) { + GetObjectFile()->GetModule()->LogMessage( + log, "SymbolFileDWARF::FindGlobalVariables (regex=\"%s\", append=%u, " + "max_matches=%u, variables)", + regex.GetText().str().c_str(), append, max_matches); + } - DWARFDebugInfo* info = DebugInfo(); - if (info == NULL) - return 0; + DWARFDebugInfo *info = DebugInfo(); + if (info == NULL) + return 0; - // If we aren't appending the results to this list, then clear the list - if (!append) - variables.Clear(); + // If we aren't appending the results to this list, then clear the list + if (!append) + variables.Clear(); - // Remember how many variables are in the list before we search in case - // we are appending the results to a variable list. - const uint32_t original_size = variables.GetSize(); + // Remember how many variables are in the list before we search in case + // we are appending the results to a variable list. + const uint32_t original_size = variables.GetSize(); - DIEArray die_offsets; + DIEArray die_offsets; - if (m_using_apple_tables) - { - if (m_apple_names_ap.get()) - { - DWARFMappedHash::DIEInfoArray hash_data_array; - if (m_apple_names_ap->AppendAllDIEsThatMatchingRegex (regex, hash_data_array)) - DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets); - } - } - else - { - // Index the DWARF if we haven't already - if (!m_indexed) - Index (); - - m_global_index.Find (regex, die_offsets); + if (m_using_apple_tables) { + if (m_apple_names_ap.get()) { + DWARFMappedHash::DIEInfoArray hash_data_array; + if (m_apple_names_ap->AppendAllDIEsThatMatchingRegex(regex, + hash_data_array)) + DWARFMappedHash::ExtractDIEArray(hash_data_array, die_offsets); } + } else { + // Index the DWARF if we haven't already + if (!m_indexed) + Index(); - SymbolContext sc; - sc.module_sp = m_obj_file->GetModule(); - assert (sc.module_sp); - - const size_t num_matches = die_offsets.size(); - if (num_matches) - { - for (size_t i=0; i<num_matches; ++i) - { - const DIERef& die_ref = die_offsets[i]; - DWARFDIE die = GetDIE (die_ref); - - if (die) - { - sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX); - - ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables); - - if (variables.GetSize() - original_size >= max_matches) - break; - } - else - { - if (m_using_apple_tables) - { - GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for regex '%s')\n", - die_ref.die_offset, regex.GetText()); - } - } + m_global_index.Find(regex, die_offsets); + } + + SymbolContext sc; + sc.module_sp = m_obj_file->GetModule(); + assert(sc.module_sp); + + const size_t num_matches = die_offsets.size(); + if (num_matches) { + for (size_t i = 0; i < num_matches; ++i) { + const DIERef &die_ref = die_offsets[i]; + DWARFDIE die = GetDIE(die_ref); + + if (die) { + sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX); + + ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables); + + if (variables.GetSize() - original_size >= max_matches) + break; + } else { + if (m_using_apple_tables) { + GetObjectFile()->GetModule()->ReportErrorIfModifyDetected( + "the DWARF debug information has been modified (.apple_names " + "accelerator table had bad die 0x%8.8x for regex '%s')\n", + die_ref.die_offset, regex.GetText().str().c_str()); } + } } + } - // Return the number of variable that were appended to the list - return variables.GetSize() - original_size; + // Return the number of variable that were appended to the list + return variables.GetSize() - original_size; } - -bool -SymbolFileDWARF::ResolveFunction (const DIERef& die_ref, - bool include_inlines, - SymbolContextList& sc_list) -{ - DWARFDIE die = DebugInfo()->GetDIE (die_ref); - return ResolveFunction (die, include_inlines, sc_list); +bool SymbolFileDWARF::ResolveFunction(const DIERef &die_ref, + bool include_inlines, + SymbolContextList &sc_list) { + DWARFDIE die = DebugInfo()->GetDIE(die_ref); + return ResolveFunction(die, include_inlines, sc_list); } - -bool -SymbolFileDWARF::ResolveFunction (const DWARFDIE &orig_die, - bool include_inlines, - SymbolContextList& sc_list) -{ - SymbolContext sc; +bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die, + bool include_inlines, + SymbolContextList &sc_list) { + SymbolContext sc; - if (!orig_die) - return false; + if (!orig_die) + return false; - // If we were passed a die that is not a function, just return false... - if (!(orig_die.Tag() == DW_TAG_subprogram || (include_inlines && orig_die.Tag() == DW_TAG_inlined_subroutine))) - return false; + // If we were passed a die that is not a function, just return false... + if (!(orig_die.Tag() == DW_TAG_subprogram || + (include_inlines && orig_die.Tag() == DW_TAG_inlined_subroutine))) + return false; - DWARFDIE die = orig_die; - DWARFDIE inlined_die; - if (die.Tag() == DW_TAG_inlined_subroutine) - { - inlined_die = die; - - while (1) - { - die = die.GetParent(); - - if (die) - { - if (die.Tag() == DW_TAG_subprogram) - break; - } - else - break; - } - } - assert (die && die.Tag() == DW_TAG_subprogram); - if (GetFunction (die, sc)) - { - Address addr; - // Parse all blocks if needed - if (inlined_die) - { - Block &function_block = sc.function->GetBlock (true); - 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) - addr.Clear(); - } - else - { - sc.block = NULL; - addr = sc.function->GetAddressRange().GetBaseAddress(); - } + DWARFDIE die = orig_die; + DWARFDIE inlined_die; + if (die.Tag() == DW_TAG_inlined_subroutine) { + inlined_die = die; - if (addr.IsValid()) - { - sc_list.Append(sc); - return true; - } + while (1) { + die = die.GetParent(); + + if (die) { + if (die.Tag() == DW_TAG_subprogram) + break; + } else + break; + } + } + assert(die && die.Tag() == DW_TAG_subprogram); + if (GetFunction(die, sc)) { + Address addr; + // Parse all blocks if needed + if (inlined_die) { + Block &function_block = sc.function->GetBlock(true); + 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) + addr.Clear(); + } else { + sc.block = NULL; + addr = sc.function->GetAddressRange().GetBaseAddress(); } - - return false; -} -void -SymbolFileDWARF::FindFunctions (const ConstString &name, - const NameToDIE &name_to_die, - bool include_inlines, - SymbolContextList& sc_list) -{ - DIEArray die_offsets; - if (name_to_die.Find (name, die_offsets)) - { - ParseFunctions (die_offsets, include_inlines, sc_list); + if (addr.IsValid()) { + sc_list.Append(sc); + return true; } -} + } + return false; +} -void -SymbolFileDWARF::FindFunctions (const RegularExpression ®ex, - const NameToDIE &name_to_die, - bool include_inlines, - SymbolContextList& sc_list) -{ - DIEArray die_offsets; - if (name_to_die.Find (regex, die_offsets)) - { - ParseFunctions (die_offsets, include_inlines, sc_list); - } +void SymbolFileDWARF::FindFunctions(const ConstString &name, + const NameToDIE &name_to_die, + bool include_inlines, + SymbolContextList &sc_list) { + DIEArray die_offsets; + if (name_to_die.Find(name, die_offsets)) { + ParseFunctions(die_offsets, include_inlines, sc_list); + } } +void SymbolFileDWARF::FindFunctions(const RegularExpression ®ex, + const NameToDIE &name_to_die, + bool include_inlines, + SymbolContextList &sc_list) { + DIEArray die_offsets; + if (name_to_die.Find(regex, die_offsets)) { + ParseFunctions(die_offsets, include_inlines, sc_list); + } +} -void -SymbolFileDWARF::FindFunctions (const RegularExpression ®ex, - const DWARFMappedHash::MemoryTable &memory_table, - bool include_inlines, - SymbolContextList& sc_list) -{ - DIEArray die_offsets; - DWARFMappedHash::DIEInfoArray hash_data_array; - if (memory_table.AppendAllDIEsThatMatchingRegex (regex, hash_data_array)) - { - DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets); - ParseFunctions (die_offsets, include_inlines, sc_list); - } +void SymbolFileDWARF::FindFunctions( + const RegularExpression ®ex, + const DWARFMappedHash::MemoryTable &memory_table, bool include_inlines, + SymbolContextList &sc_list) { + DIEArray die_offsets; + DWARFMappedHash::DIEInfoArray hash_data_array; + if (memory_table.AppendAllDIEsThatMatchingRegex(regex, hash_data_array)) { + DWARFMappedHash::ExtractDIEArray(hash_data_array, die_offsets); + ParseFunctions(die_offsets, include_inlines, sc_list); + } } -void -SymbolFileDWARF::ParseFunctions (const DIEArray &die_offsets, - bool include_inlines, - SymbolContextList& sc_list) -{ - const size_t num_matches = die_offsets.size(); - if (num_matches) - { - for (size_t i=0; i<num_matches; ++i) - ResolveFunction (die_offsets[i], include_inlines, sc_list); - } +void SymbolFileDWARF::ParseFunctions(const DIEArray &die_offsets, + bool include_inlines, + SymbolContextList &sc_list) { + const size_t num_matches = die_offsets.size(); + if (num_matches) { + for (size_t i = 0; i < num_matches; ++i) + ResolveFunction(die_offsets[i], include_inlines, sc_list); + } } -bool -SymbolFileDWARF::DIEInDeclContext (const CompilerDeclContext *decl_ctx, - const DWARFDIE &die) -{ - // If we have no parent decl context to match this DIE matches, and if the parent - // decl context isn't valid, we aren't trying to look for any particular decl - // context so any die matches. - if (decl_ctx == nullptr || !decl_ctx->IsValid()) - return true; - - if (die) - { - DWARFASTParser *dwarf_ast = die.GetDWARFParser(); - if (dwarf_ast) - { - CompilerDeclContext actual_decl_ctx = dwarf_ast->GetDeclContextContainingUIDFromDWARF (die); - if (actual_decl_ctx) - return actual_decl_ctx == *decl_ctx; - } +bool SymbolFileDWARF::DIEInDeclContext(const CompilerDeclContext *decl_ctx, + const DWARFDIE &die) { + // If we have no parent decl context to match this DIE matches, and if the + // parent + // decl context isn't valid, we aren't trying to look for any particular decl + // context so any die matches. + if (decl_ctx == nullptr || !decl_ctx->IsValid()) + return true; + + if (die) { + DWARFASTParser *dwarf_ast = die.GetDWARFParser(); + if (dwarf_ast) { + CompilerDeclContext actual_decl_ctx = + dwarf_ast->GetDeclContextContainingUIDFromDWARF(die); + if (actual_decl_ctx) + return actual_decl_ctx == *decl_ctx; } - return false; + } + 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) -{ - Timer scoped_timer (__PRETTY_FUNCTION__, - "SymbolFileDWARF::FindFunctions (name = '%s')", - name.AsCString()); - - // eFunctionNameTypeAuto should be pre-resolved by a call to Module::PrepareForFunctionNameLookup() - assert ((name_type_mask & eFunctionNameTypeAuto) == 0); - - Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); - - if (log) - { - GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, append=%u, sc_list)", - name.GetCString(), - name_type_mask, - append); - } +SymbolFileDWARF::FindFunctions(const ConstString &name, + const CompilerDeclContext *parent_decl_ctx, + uint32_t name_type_mask, bool include_inlines, + bool append, SymbolContextList &sc_list) { + Timer scoped_timer(LLVM_PRETTY_FUNCTION, + "SymbolFileDWARF::FindFunctions (name = '%s')", + name.AsCString()); + + // eFunctionNameTypeAuto should be pre-resolved by a call to + // Module::LookupInfo::LookupInfo() + assert((name_type_mask & eFunctionNameTypeAuto) == 0); + + Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); + + if (log) { + GetObjectFile()->GetModule()->LogMessage( + log, "SymbolFileDWARF::FindFunctions (name=\"%s\", " + "name_type_mask=0x%x, append=%u, sc_list)", + name.GetCString(), name_type_mask, append); + } + + // If we aren't appending the results to this list, then clear the list + if (!append) + sc_list.Clear(); + + if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) + return 0; - // If we aren't appending the results to this list, then clear the list - if (!append) - sc_list.Clear(); - - if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) - return 0; - - // If name is empty then we won't find anything. - if (name.IsEmpty()) - return 0; + // If name is empty then we won't find anything. + if (name.IsEmpty()) + return 0; - // Remember how many sc_list are in the list before we search in case - // we are appending the results to a variable list. + // Remember how many sc_list are in the list before we search in case + // we are appending the results to a variable list. - const char *name_cstr = name.GetCString(); + const char *name_cstr = name.GetCString(); - const uint32_t original_size = sc_list.GetSize(); - - DWARFDebugInfo* info = DebugInfo(); - if (info == NULL) - return 0; + const uint32_t original_size = sc_list.GetSize(); - std::set<const DWARFDebugInfoEntry *> resolved_dies; - if (m_using_apple_tables) - { - if (m_apple_names_ap.get()) - { - - DIEArray die_offsets; - - uint32_t num_matches = 0; - - if (name_type_mask & eFunctionNameTypeFull) - { - // If they asked for the full name, match what they typed. At some point we may - // want to canonicalize this (strip double spaces, etc. For now, we just add all the - // dies that we find by exact match. - num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets); - for (uint32_t i = 0; i < num_matches; i++) - { - const DIERef& die_ref = die_offsets[i]; - DWARFDIE die = info->GetDIE (die_ref); - if (die) - { - if (!DIEInDeclContext(parent_decl_ctx, die)) - continue; // The containing decl contexts don't match - - if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) - { - if (ResolveFunction (die, include_inlines, sc_list)) - resolved_dies.insert(die.GetDIE()); - } - } - else - { - GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')", - die_ref.die_offset, name_cstr); - } - } - } + DWARFDebugInfo *info = DebugInfo(); + if (info == NULL) + return 0; - if (name_type_mask & eFunctionNameTypeSelector) - { - if (parent_decl_ctx && parent_decl_ctx->IsValid()) - return 0; // no selectors in namespaces - - num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets); - // Now make sure these are actually ObjC methods. In this case we can simply look up the name, - // and if it is an ObjC method name, we're good. - - for (uint32_t i = 0; i < num_matches; i++) - { - const DIERef& die_ref = die_offsets[i]; - DWARFDIE die = info->GetDIE (die_ref); - if (die) - { - const char *die_name = die.GetName(); - if (ObjCLanguage::IsPossibleObjCMethodName(die_name)) - { - if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) - { - if (ResolveFunction (die, include_inlines, sc_list)) - resolved_dies.insert(die.GetDIE()); - } - } - } - else - { - GetObjectFile()->GetModule()->ReportError ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')", - die_ref.die_offset, name_cstr); - } - } - die_offsets.clear(); + std::set<const DWARFDebugInfoEntry *> resolved_dies; + if (m_using_apple_tables) { + if (m_apple_names_ap.get()) { + + DIEArray die_offsets; + + uint32_t num_matches = 0; + + if (name_type_mask & eFunctionNameTypeFull) { + // If they asked for the full name, match what they typed. At some + // point we may + // want to canonicalize this (strip double spaces, etc. For now, we + // just add all the + // dies that we find by exact match. + num_matches = m_apple_names_ap->FindByName(name_cstr, die_offsets); + for (uint32_t i = 0; i < num_matches; i++) { + const DIERef &die_ref = die_offsets[i]; + DWARFDIE die = info->GetDIE(die_ref); + if (die) { + if (!DIEInDeclContext(parent_decl_ctx, die)) + continue; // The containing decl contexts don't match + + if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) { + if (ResolveFunction(die, include_inlines, sc_list)) + resolved_dies.insert(die.GetDIE()); } - - if (((name_type_mask & eFunctionNameTypeMethod) && !parent_decl_ctx) || name_type_mask & eFunctionNameTypeBase) - { - // The apple_names table stores just the "base name" of C++ methods in the table. So we have to - // extract the base name, look that up, and if there is any other information in the name we were - // passed in we have to post-filter based on that. - - // FIXME: Arrange the logic above so that we don't calculate the base name twice: - num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets); - - for (uint32_t i = 0; i < num_matches; i++) - { - const DIERef& die_ref = die_offsets[i]; - DWARFDIE die = info->GetDIE (die_ref); - if (die) - { - if (!DIEInDeclContext(parent_decl_ctx, die)) - continue; // The containing decl contexts don't match - - - // If we get to here, the die is good, and we should add it: - if (resolved_dies.find(die.GetDIE()) == resolved_dies.end() && ResolveFunction (die, include_inlines, sc_list)) - { - bool keep_die = true; - if ((name_type_mask & (eFunctionNameTypeBase|eFunctionNameTypeMethod)) != (eFunctionNameTypeBase|eFunctionNameTypeMethod)) - { - // We are looking for either basenames or methods, so we need to - // trim out the ones we won't want by looking at the type - SymbolContext sc; - if (sc_list.GetLastContext(sc)) - { - if (sc.block) - { - // We have an inlined function - } - else if (sc.function) - { - Type *type = sc.function->GetType(); - - if (type) - { - CompilerDeclContext decl_ctx = GetDeclContextContainingUID (type->GetID()); - if (decl_ctx.IsStructUnionOrClass()) - { - if (name_type_mask & eFunctionNameTypeBase) - { - sc_list.RemoveContextAtIndex(sc_list.GetSize()-1); - keep_die = false; - } - } - else - { - if (name_type_mask & eFunctionNameTypeMethod) - { - sc_list.RemoveContextAtIndex(sc_list.GetSize()-1); - keep_die = false; - } - } - } - else - { - GetObjectFile()->GetModule()->ReportWarning ("function at die offset 0x%8.8x had no function type", - die_ref.die_offset); - } - } - } - } - if (keep_die) - resolved_dies.insert(die.GetDIE()); - } - } - else - { - GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')", - die_ref.die_offset, name_cstr); - } - } - die_offsets.clear(); + } else { + GetObjectFile()->GetModule()->ReportErrorIfModifyDetected( + "the DWARF debug information has been modified (.apple_names " + "accelerator table had bad die 0x%8.8x for '%s')", + die_ref.die_offset, name_cstr); + } + } + } + + if (name_type_mask & eFunctionNameTypeSelector) { + if (parent_decl_ctx && parent_decl_ctx->IsValid()) + return 0; // no selectors in namespaces + + num_matches = m_apple_names_ap->FindByName(name_cstr, die_offsets); + // Now make sure these are actually ObjC methods. In this case we can + // simply look up the name, + // and if it is an ObjC method name, we're good. + + for (uint32_t i = 0; i < num_matches; i++) { + const DIERef &die_ref = die_offsets[i]; + DWARFDIE die = info->GetDIE(die_ref); + if (die) { + const char *die_name = die.GetName(); + if (ObjCLanguage::IsPossibleObjCMethodName(die_name)) { + if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) { + if (ResolveFunction(die, include_inlines, sc_list)) + resolved_dies.insert(die.GetDIE()); + } } + } else { + GetObjectFile()->GetModule()->ReportError( + "the DWARF debug information has been modified (.apple_names " + "accelerator table had bad die 0x%8.8x for '%s')", + die_ref.die_offset, name_cstr); + } } - } - else - { - - // Index the DWARF if we haven't already - if (!m_indexed) - Index (); - - if (name_type_mask & eFunctionNameTypeFull) - { - FindFunctions (name, m_function_fullname_index, include_inlines, sc_list); - - // FIXME Temporary workaround for global/anonymous namespace - // functions debugging FreeBSD and Linux binaries. - // If we didn't find any functions in the global namespace try - // looking in the basename index but ignore any returned - // functions that have a namespace but keep functions which - // have an anonymous namespace - // TODO: The arch in the object file isn't correct for MSVC - // binaries on windows, we should find a way to make it - // correct and handle those symbols as well. - if (sc_list.GetSize() == original_size) - { - ArchSpec arch; - if (!parent_decl_ctx && - GetObjectFile()->GetArchitecture(arch) && - (arch.GetTriple().isOSFreeBSD() || arch.GetTriple().isOSLinux() || - arch.GetMachine() == llvm::Triple::hexagon)) - { - SymbolContextList temp_sc_list; - FindFunctions (name, m_function_basename_index, include_inlines, temp_sc_list); - SymbolContext sc; - for (uint32_t i = 0; i < temp_sc_list.GetSize(); i++) - { - if (temp_sc_list.GetContextAtIndex(i, sc)) - { - ConstString mangled_name = sc.GetFunctionName(Mangled::ePreferMangled); - ConstString demangled_name = sc.GetFunctionName(Mangled::ePreferDemangled); - // Mangled names on Linux and FreeBSD are of the form: - // _ZN18function_namespace13function_nameEv. - if (strncmp(mangled_name.GetCString(), "_ZN", 3) || - !strncmp(demangled_name.GetCString(), "(anonymous namespace)", 21)) - { - sc_list.Append(sc); - } + die_offsets.clear(); + } + + if (((name_type_mask & eFunctionNameTypeMethod) && !parent_decl_ctx) || + name_type_mask & eFunctionNameTypeBase) { + // The apple_names table stores just the "base name" of C++ methods in + // the table. So we have to + // extract the base name, look that up, and if there is any other + // information in the name we were + // passed in we have to post-filter based on that. + + // FIXME: Arrange the logic above so that we don't calculate the base + // name twice: + num_matches = m_apple_names_ap->FindByName(name_cstr, die_offsets); + + for (uint32_t i = 0; i < num_matches; i++) { + const DIERef &die_ref = die_offsets[i]; + DWARFDIE die = info->GetDIE(die_ref); + if (die) { + if (!DIEInDeclContext(parent_decl_ctx, die)) + continue; // The containing decl contexts don't match + + // If we get to here, the die is good, and we should add it: + if (resolved_dies.find(die.GetDIE()) == resolved_dies.end() && + ResolveFunction(die, include_inlines, sc_list)) { + bool keep_die = true; + if ((name_type_mask & + (eFunctionNameTypeBase | eFunctionNameTypeMethod)) != + (eFunctionNameTypeBase | eFunctionNameTypeMethod)) { + // We are looking for either basenames or methods, so we need to + // trim out the ones we won't want by looking at the type + SymbolContext sc; + if (sc_list.GetLastContext(sc)) { + if (sc.block) { + // We have an inlined function + } else if (sc.function) { + Type *type = sc.function->GetType(); + + if (type) { + CompilerDeclContext decl_ctx = + GetDeclContextContainingUID(type->GetID()); + if (decl_ctx.IsStructUnionOrClass()) { + if (name_type_mask & eFunctionNameTypeBase) { + sc_list.RemoveContextAtIndex(sc_list.GetSize() - 1); + keep_die = false; + } + } else { + if (name_type_mask & eFunctionNameTypeMethod) { + sc_list.RemoveContextAtIndex(sc_list.GetSize() - 1); + keep_die = false; } + } + } else { + GetObjectFile()->GetModule()->ReportWarning( + "function at die offset 0x%8.8x had no function type", + die_ref.die_offset); } + } } + } + if (keep_die) + resolved_dies.insert(die.GetDIE()); } + } else { + GetObjectFile()->GetModule()->ReportErrorIfModifyDetected( + "the DWARF debug information has been modified (.apple_names " + "accelerator table had bad die 0x%8.8x for '%s')", + die_ref.die_offset, name_cstr); + } } - DIEArray die_offsets; - if (name_type_mask & eFunctionNameTypeBase) - { - uint32_t num_base = m_function_basename_index.Find(name, die_offsets); - for (uint32_t i = 0; i < num_base; i++) - { - DWARFDIE die = info->GetDIE (die_offsets[i]); - if (die) - { - if (!DIEInDeclContext(parent_decl_ctx, die)) - continue; // The containing decl contexts don't match - - // If we get to here, the die is good, and we should add it: - if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) - { - if (ResolveFunction (die, include_inlines, sc_list)) - resolved_dies.insert(die.GetDIE()); - } - } + die_offsets.clear(); + } + } + } else { + + // Index the DWARF if we haven't already + if (!m_indexed) + Index(); + + if (name_type_mask & eFunctionNameTypeFull) { + FindFunctions(name, m_function_fullname_index, include_inlines, sc_list); + + // FIXME Temporary workaround for global/anonymous namespace + // functions debugging FreeBSD and Linux binaries. + // If we didn't find any functions in the global namespace try + // looking in the basename index but ignore any returned + // functions that have a namespace but keep functions which + // have an anonymous namespace + // TODO: The arch in the object file isn't correct for MSVC + // binaries on windows, we should find a way to make it + // correct and handle those symbols as well. + if (sc_list.GetSize() == original_size) { + ArchSpec arch; + if (!parent_decl_ctx && GetObjectFile()->GetArchitecture(arch) && + arch.GetTriple().isOSBinFormatELF()) { + SymbolContextList temp_sc_list; + FindFunctions(name, m_function_basename_index, include_inlines, + temp_sc_list); + SymbolContext sc; + for (uint32_t i = 0; i < temp_sc_list.GetSize(); i++) { + if (temp_sc_list.GetContextAtIndex(i, sc)) { + ConstString mangled_name = + sc.GetFunctionName(Mangled::ePreferMangled); + ConstString demangled_name = + sc.GetFunctionName(Mangled::ePreferDemangled); + // Mangled names on Linux and FreeBSD are of the form: + // _ZN18function_namespace13function_nameEv. + if (strncmp(mangled_name.GetCString(), "_ZN", 3) || + !strncmp(demangled_name.GetCString(), "(anonymous namespace)", + 21)) { + sc_list.Append(sc); + } } - die_offsets.clear(); + } } - - if (name_type_mask & eFunctionNameTypeMethod) - { - if (parent_decl_ctx && parent_decl_ctx->IsValid()) - return 0; // no methods in namespaces - - uint32_t num_base = m_function_method_index.Find(name, die_offsets); - { - for (uint32_t i = 0; i < num_base; i++) - { - DWARFDIE die = info->GetDIE (die_offsets[i]); - if (die) - { - // If we get to here, the die is good, and we should add it: - if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) - { - if (ResolveFunction (die, include_inlines, sc_list)) - resolved_dies.insert(die.GetDIE()); - } - } - } - } - die_offsets.clear(); + } + } + DIEArray die_offsets; + if (name_type_mask & eFunctionNameTypeBase) { + uint32_t num_base = m_function_basename_index.Find(name, die_offsets); + for (uint32_t i = 0; i < num_base; i++) { + DWARFDIE die = info->GetDIE(die_offsets[i]); + if (die) { + if (!DIEInDeclContext(parent_decl_ctx, die)) + continue; // The containing decl contexts don't match + + // If we get to here, the die is good, and we should add it: + if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) { + if (ResolveFunction(die, include_inlines, sc_list)) + resolved_dies.insert(die.GetDIE()); + } } + } + die_offsets.clear(); + } - if ((name_type_mask & eFunctionNameTypeSelector) && (!parent_decl_ctx || !parent_decl_ctx->IsValid())) - { - FindFunctions (name, m_function_selector_index, include_inlines, sc_list); + if (name_type_mask & eFunctionNameTypeMethod) { + if (parent_decl_ctx && parent_decl_ctx->IsValid()) + return 0; // no methods in namespaces + + uint32_t num_base = m_function_method_index.Find(name, die_offsets); + { + for (uint32_t i = 0; i < num_base; i++) { + DWARFDIE die = info->GetDIE(die_offsets[i]); + if (die) { + // If we get to here, the die is good, and we should add it: + if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) { + if (ResolveFunction(die, include_inlines, sc_list)) + resolved_dies.insert(die.GetDIE()); + } + } } - + } + die_offsets.clear(); } - // Return the number of variable that were appended to the list - const uint32_t num_matches = sc_list.GetSize() - original_size; - - if (log && num_matches > 0) - { - GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, include_inlines=%d, append=%u, sc_list) => %u", - name.GetCString(), - name_type_mask, - include_inlines, - append, - num_matches); + if ((name_type_mask & eFunctionNameTypeSelector) && + (!parent_decl_ctx || !parent_decl_ctx->IsValid())) { + FindFunctions(name, m_function_selector_index, include_inlines, sc_list); } - return num_matches; + } + + // Return the number of variable that were appended to the list + const uint32_t num_matches = sc_list.GetSize() - original_size; + + if (log && num_matches > 0) { + GetObjectFile()->GetModule()->LogMessage( + log, "SymbolFileDWARF::FindFunctions (name=\"%s\", " + "name_type_mask=0x%x, include_inlines=%d, append=%u, sc_list) => " + "%u", + name.GetCString(), name_type_mask, include_inlines, append, + num_matches); + } + return num_matches; } -uint32_t -SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list) -{ - Timer scoped_timer (__PRETTY_FUNCTION__, - "SymbolFileDWARF::FindFunctions (regex = '%s')", - regex.GetText()); - - Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); - - if (log) - { - GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF::FindFunctions (regex=\"%s\", append=%u, sc_list)", - regex.GetText(), - append); - } - - - // If we aren't appending the results to this list, then clear the list - if (!append) - sc_list.Clear(); - - // Remember how many sc_list are in the list before we search in case - // we are appending the results to a variable list. - uint32_t original_size = sc_list.GetSize(); - - if (m_using_apple_tables) - { - if (m_apple_names_ap.get()) - FindFunctions (regex, *m_apple_names_ap, include_inlines, sc_list); - } - else - { - // Index the DWARF if we haven't already - if (!m_indexed) - Index (); - - FindFunctions (regex, m_function_basename_index, include_inlines, sc_list); - - FindFunctions (regex, m_function_fullname_index, include_inlines, sc_list); - } - - // Return the number of variable that were appended to the list - return sc_list.GetSize() - original_size; +uint32_t SymbolFileDWARF::FindFunctions(const RegularExpression ®ex, + bool include_inlines, bool append, + SymbolContextList &sc_list) { + Timer scoped_timer(LLVM_PRETTY_FUNCTION, + "SymbolFileDWARF::FindFunctions (regex = '%s')", + regex.GetText().str().c_str()); + + Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); + + if (log) { + GetObjectFile()->GetModule()->LogMessage( + log, + "SymbolFileDWARF::FindFunctions (regex=\"%s\", append=%u, sc_list)", + regex.GetText().str().c_str(), append); + } + + // If we aren't appending the results to this list, then clear the list + if (!append) + sc_list.Clear(); + + // Remember how many sc_list are in the list before we search in case + // we are appending the results to a variable list. + uint32_t original_size = sc_list.GetSize(); + + if (m_using_apple_tables) { + if (m_apple_names_ap.get()) + FindFunctions(regex, *m_apple_names_ap, include_inlines, sc_list); + } else { + // Index the DWARF if we haven't already + if (!m_indexed) + Index(); + + FindFunctions(regex, m_function_basename_index, include_inlines, sc_list); + + FindFunctions(regex, m_function_fullname_index, include_inlines, sc_list); + } + + // Return the number of variable that were appended to the list + return sc_list.GetSize() - original_size; } -void -SymbolFileDWARF::GetMangledNamesForFunction (const std::string &scope_qualified_name, - std::vector<ConstString> &mangled_names) -{ - DWARFDebugInfo* info = DebugInfo(); - uint32_t num_comp_units = 0; - if (info) - num_comp_units = info->GetNumCompileUnits(); - - for (uint32_t i = 0; i < num_comp_units; i++) - { - DWARFCompileUnit *cu = info->GetCompileUnitAtIndex(i); - if (cu == nullptr) - continue; - - SymbolFileDWARFDwo *dwo = cu->GetDwoSymbolFile(); - if (dwo) - dwo->GetMangledNamesForFunction(scope_qualified_name, mangled_names); - } - - NameToOffsetMap::iterator iter = m_function_scope_qualified_name_map.find(scope_qualified_name); - if (iter == m_function_scope_qualified_name_map.end()) - return; - - DIERefSetSP set_sp = (*iter).second; - std::set<DIERef>::iterator set_iter; - for (set_iter = set_sp->begin(); set_iter != set_sp->end(); set_iter++) - { - DWARFDIE die = DebugInfo()->GetDIE (*set_iter); - mangled_names.push_back(ConstString(die.GetMangledName())); - } +void SymbolFileDWARF::GetMangledNamesForFunction( + const std::string &scope_qualified_name, + std::vector<ConstString> &mangled_names) { + DWARFDebugInfo *info = DebugInfo(); + uint32_t num_comp_units = 0; + if (info) + num_comp_units = info->GetNumCompileUnits(); + + for (uint32_t i = 0; i < num_comp_units; i++) { + DWARFCompileUnit *cu = info->GetCompileUnitAtIndex(i); + if (cu == nullptr) + continue; + + SymbolFileDWARFDwo *dwo = cu->GetDwoSymbolFile(); + if (dwo) + dwo->GetMangledNamesForFunction(scope_qualified_name, mangled_names); + } + + NameToOffsetMap::iterator iter = + m_function_scope_qualified_name_map.find(scope_qualified_name); + if (iter == m_function_scope_qualified_name_map.end()) + return; + + DIERefSetSP set_sp = (*iter).second; + std::set<DIERef>::iterator set_iter; + for (set_iter = set_sp->begin(); set_iter != set_sp->end(); set_iter++) { + DWARFDIE die = DebugInfo()->GetDIE(*set_iter); + mangled_names.push_back(ConstString(die.GetMangledName())); + } } +uint32_t SymbolFileDWARF::FindTypes( + const SymbolContext &sc, 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 + if (!append) + types.Clear(); + + // Make sure we haven't already searched this SymbolFile before... + if (searched_symbol_files.count(this)) + return 0; + else + searched_symbol_files.insert(this); -uint32_t -SymbolFileDWARF::FindTypes (const SymbolContext& sc, - 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 - if (!append) - types.Clear(); + DWARFDebugInfo *info = DebugInfo(); + if (info == NULL) + return 0; - // Make sure we haven't already searched this SymbolFile before... - if (searched_symbol_files.count(this)) - return 0; + Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); + + if (log) { + if (parent_decl_ctx) + GetObjectFile()->GetModule()->LogMessage( + log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = " + "%p (\"%s\"), append=%u, max_matches=%u, type_list)", + name.GetCString(), static_cast<const void *>(parent_decl_ctx), + parent_decl_ctx->GetName().AsCString("<NULL>"), append, max_matches); else - searched_symbol_files.insert(this); + GetObjectFile()->GetModule()->LogMessage( + log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = " + "NULL, append=%u, max_matches=%u, type_list)", + name.GetCString(), append, max_matches); + } - DWARFDebugInfo* info = DebugInfo(); - if (info == NULL) - return 0; + if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) + return 0; - Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); + DIEArray die_offsets; - if (log) - { - if (parent_decl_ctx) - GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = %p (\"%s\"), append=%u, max_matches=%u, type_list)", - name.GetCString(), - static_cast<const void*>(parent_decl_ctx), - parent_decl_ctx->GetName().AsCString("<NULL>"), - append, max_matches); - else - GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = NULL, append=%u, max_matches=%u, type_list)", - name.GetCString(), append, - max_matches); + if (m_using_apple_tables) { + if (m_apple_types_ap.get()) { + const char *name_cstr = name.GetCString(); + m_apple_types_ap->FindByName(name_cstr, die_offsets); } - - if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) - return 0; - - DIEArray die_offsets; - - if (m_using_apple_tables) - { - if (m_apple_types_ap.get()) - { - const char *name_cstr = name.GetCString(); - m_apple_types_ap->FindByName (name_cstr, die_offsets); + } else { + if (!m_indexed) + Index(); + + m_type_index.Find(name, die_offsets); + } + + const size_t num_die_matches = die_offsets.size(); + + if (num_die_matches) { + const uint32_t initial_types_size = types.GetSize(); + for (size_t i = 0; i < num_die_matches; ++i) { + const DIERef &die_ref = die_offsets[i]; + DWARFDIE die = GetDIE(die_ref); + + if (die) { + if (!DIEInDeclContext(parent_decl_ctx, die)) + continue; // The containing decl contexts don't match + + Type *matching_type = ResolveType(die, true, true); + if (matching_type) { + // We found a type pointer, now find the shared pointer form our type + // list + types.InsertUnique(matching_type->shared_from_this()); + if (types.GetSize() >= max_matches) + break; + } + } else { + if (m_using_apple_tables) { + GetObjectFile()->GetModule()->ReportErrorIfModifyDetected( + "the DWARF debug information has been modified (.apple_types " + "accelerator table had bad die 0x%8.8x for '%s')\n", + die_ref.die_offset, name.GetCString()); } + } } - else - { - if (!m_indexed) - Index (); - - m_type_index.Find (name, die_offsets); + const uint32_t num_matches = types.GetSize() - initial_types_size; + if (log && num_matches) { + if (parent_decl_ctx) { + GetObjectFile()->GetModule()->LogMessage( + log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx " + "= %p (\"%s\"), append=%u, max_matches=%u, type_list) => %u", + name.GetCString(), static_cast<const void *>(parent_decl_ctx), + parent_decl_ctx->GetName().AsCString("<NULL>"), append, max_matches, + num_matches); + } else { + GetObjectFile()->GetModule()->LogMessage( + log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx " + "= NULL, append=%u, max_matches=%u, type_list) => %u", + name.GetCString(), append, max_matches, num_matches); + } } + return num_matches; + } else { + UpdateExternalModuleListIfNeeded(); - const size_t num_die_matches = die_offsets.size(); - - if (num_die_matches) - { - const uint32_t initial_types_size = types.GetSize(); - for (size_t i=0; i<num_die_matches; ++i) - { - const DIERef& die_ref = die_offsets[i]; - DWARFDIE die = GetDIE (die_ref); - - if (die) - { - if (!DIEInDeclContext(parent_decl_ctx, die)) - continue; // The containing decl contexts don't match - - Type *matching_type = ResolveType (die, true, true); - if (matching_type) - { - // We found a type pointer, now find the shared pointer form our type list - types.InsertUnique (matching_type->shared_from_this()); - if (types.GetSize() >= max_matches) - break; - } - } - else - { - if (m_using_apple_tables) - { - GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n", - die_ref.die_offset, name.GetCString()); - } - } - - } - const uint32_t num_matches = types.GetSize() - initial_types_size; - if (log && num_matches) - { - if (parent_decl_ctx) - { - GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = %p (\"%s\"), append=%u, max_matches=%u, type_list) => %u", - name.GetCString(), - static_cast<const void*>(parent_decl_ctx), - parent_decl_ctx->GetName().AsCString("<NULL>"), - append, max_matches, - num_matches); - } - else - { - GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = NULL, append=%u, max_matches=%u, type_list) => %u", - name.GetCString(), - append, max_matches, - num_matches); - } - } - return num_matches; - } - else - { - UpdateExternalModuleListIfNeeded(); - - for (const auto &pair : m_external_type_modules) - { - ModuleSP external_module_sp = pair.second; - if (external_module_sp) - { - 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); - if (num_external_matches) - return num_external_matches; - } - } + for (const auto &pair : m_external_type_modules) { + ModuleSP external_module_sp = pair.second; + if (external_module_sp) { + 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); + if (num_external_matches) + return num_external_matches; } + } } + } - return 0; + return 0; } +size_t SymbolFileDWARF::FindTypes(const std::vector<CompilerContext> &context, + bool append, TypeMap &types) { + if (!append) + types.Clear(); -size_t -SymbolFileDWARF::FindTypes (const std::vector<CompilerContext> &context, - bool append, - TypeMap& types) -{ - if (!append) - types.Clear(); - - if (context.empty()) - return 0; - - DIEArray die_offsets; + if (context.empty()) + return 0; - ConstString name = context.back().name; + DIEArray die_offsets; - if (!name) - return 0; + ConstString name = context.back().name; - if (m_using_apple_tables) - { - if (m_apple_types_ap.get()) - { - const char *name_cstr = name.GetCString(); - m_apple_types_ap->FindByName (name_cstr, die_offsets); - } - } - else - { - if (!m_indexed) - Index (); + if (!name) + return 0; - m_type_index.Find (name, die_offsets); + if (m_using_apple_tables) { + if (m_apple_types_ap.get()) { + const char *name_cstr = name.GetCString(); + m_apple_types_ap->FindByName(name_cstr, die_offsets); } - - const size_t num_die_matches = die_offsets.size(); - - if (num_die_matches) - { - size_t num_matches = 0; - for (size_t i=0; i<num_die_matches; ++i) - { - const DIERef& die_ref = die_offsets[i]; - DWARFDIE die = GetDIE (die_ref); - - if (die) - { - std::vector<CompilerContext> die_context; - die.GetDWOContext(die_context); - if (die_context != context) - continue; - - Type *matching_type = ResolveType (die, true, true); - if (matching_type) - { - // We found a type pointer, now find the shared pointer form our type list - types.InsertUnique (matching_type->shared_from_this()); - ++num_matches; - } - } - else - { - if (m_using_apple_tables) - { - GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n", - die_ref.die_offset, name.GetCString()); - } - } - + } else { + if (!m_indexed) + Index(); + + m_type_index.Find(name, die_offsets); + } + + const size_t num_die_matches = die_offsets.size(); + + if (num_die_matches) { + size_t num_matches = 0; + for (size_t i = 0; i < num_die_matches; ++i) { + const DIERef &die_ref = die_offsets[i]; + DWARFDIE die = GetDIE(die_ref); + + if (die) { + std::vector<CompilerContext> die_context; + die.GetDWOContext(die_context); + if (die_context != context) + continue; + + Type *matching_type = ResolveType(die, true, true); + if (matching_type) { + // We found a type pointer, now find the shared pointer form our type + // list + types.InsertUnique(matching_type->shared_from_this()); + ++num_matches; + } + } else { + if (m_using_apple_tables) { + GetObjectFile()->GetModule()->ReportErrorIfModifyDetected( + "the DWARF debug information has been modified (.apple_types " + "accelerator table had bad die 0x%8.8x for '%s')\n", + die_ref.die_offset, name.GetCString()); } - return num_matches; + } } - return 0; + return num_matches; + } + return 0; } - CompilerDeclContext -SymbolFileDWARF::FindNamespace (const SymbolContext& sc, - const ConstString &name, - const CompilerDeclContext *parent_decl_ctx) -{ - Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); - - if (log) - { - GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF::FindNamespace (sc, name=\"%s\")", - name.GetCString()); - } - - CompilerDeclContext namespace_decl_ctx; +SymbolFileDWARF::FindNamespace(const SymbolContext &sc, const ConstString &name, + const CompilerDeclContext *parent_decl_ctx) { + Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); - if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) - return namespace_decl_ctx; + if (log) { + GetObjectFile()->GetModule()->LogMessage( + log, "SymbolFileDWARF::FindNamespace (sc, name=\"%s\")", + name.GetCString()); + } + CompilerDeclContext namespace_decl_ctx; - DWARFDebugInfo* info = DebugInfo(); - if (info) - { - DIEArray die_offsets; + if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) + return namespace_decl_ctx; - // Index if we already haven't to make sure the compile units - // get indexed and make their global DIE index list - if (m_using_apple_tables) - { - if (m_apple_namespaces_ap.get()) - { - const char *name_cstr = name.GetCString(); - m_apple_namespaces_ap->FindByName (name_cstr, die_offsets); - } - } - else - { - if (!m_indexed) - Index (); + DWARFDebugInfo *info = DebugInfo(); + if (info) { + DIEArray die_offsets; - m_namespace_index.Find (name, die_offsets); - } - - const size_t num_matches = die_offsets.size(); - if (num_matches) - { - for (size_t i=0; i<num_matches; ++i) - { - const DIERef& die_ref = die_offsets[i]; - DWARFDIE die = GetDIE (die_ref); - - if (die) - { - if (!DIEInDeclContext (parent_decl_ctx, die)) - continue; // The containing decl contexts don't match - - DWARFASTParser *dwarf_ast = die.GetDWARFParser(); - if (dwarf_ast) - { - namespace_decl_ctx = dwarf_ast->GetDeclContextForUIDFromDWARF (die); - if (namespace_decl_ctx) - break; - } - } - else - { - if (m_using_apple_tables) - { - GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_namespaces accelerator table had bad die 0x%8.8x for '%s')\n", - die_ref.die_offset, name.GetCString()); - } - } + // Index if we already haven't to make sure the compile units + // get indexed and make their global DIE index list + if (m_using_apple_tables) { + if (m_apple_namespaces_ap.get()) { + const char *name_cstr = name.GetCString(); + m_apple_namespaces_ap->FindByName(name_cstr, die_offsets); + } + } else { + if (!m_indexed) + Index(); + + m_namespace_index.Find(name, die_offsets); + } - } + const size_t num_matches = die_offsets.size(); + if (num_matches) { + for (size_t i = 0; i < num_matches; ++i) { + const DIERef &die_ref = die_offsets[i]; + DWARFDIE die = GetDIE(die_ref); + + if (die) { + if (!DIEInDeclContext(parent_decl_ctx, die)) + continue; // The containing decl contexts don't match + + DWARFASTParser *dwarf_ast = die.GetDWARFParser(); + if (dwarf_ast) { + namespace_decl_ctx = dwarf_ast->GetDeclContextForUIDFromDWARF(die); + if (namespace_decl_ctx) + break; + } + } else { + if (m_using_apple_tables) { + GetObjectFile()->GetModule()->ReportErrorIfModifyDetected( + "the DWARF debug information has been modified " + "(.apple_namespaces accelerator table had bad die 0x%8.8x for " + "'%s')\n", + die_ref.die_offset, name.GetCString()); + } } + } } - if (log && namespace_decl_ctx) - { - GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF::FindNamespace (sc, name=\"%s\") => CompilerDeclContext(%p/%p) \"%s\"", - name.GetCString(), - static_cast<const void*>(namespace_decl_ctx.GetTypeSystem()), - static_cast<const void*>(namespace_decl_ctx.GetOpaqueDeclContext()), - namespace_decl_ctx.GetName().AsCString("<NULL>")); - } - - return namespace_decl_ctx; + } + if (log && namespace_decl_ctx) { + GetObjectFile()->GetModule()->LogMessage( + log, "SymbolFileDWARF::FindNamespace (sc, name=\"%s\") => " + "CompilerDeclContext(%p/%p) \"%s\"", + name.GetCString(), + static_cast<const void *>(namespace_decl_ctx.GetTypeSystem()), + static_cast<const void *>(namespace_decl_ctx.GetOpaqueDeclContext()), + namespace_decl_ctx.GetName().AsCString("<NULL>")); + } + + return namespace_decl_ctx; } -TypeSP -SymbolFileDWARF::GetTypeForDIE (const DWARFDIE &die, bool resolve_function_context) -{ - TypeSP type_sp; - if (die) - { - Type *type_ptr = GetDIEToType().lookup (die.GetDIE()); - if (type_ptr == NULL) - { - CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(die.GetCU()); - assert (lldb_cu); - SymbolContext sc(lldb_cu); - const DWARFDebugInfoEntry* parent_die = die.GetParent().GetDIE(); - while (parent_die != nullptr) - { - if (parent_die->Tag() == DW_TAG_subprogram) - break; - parent_die = parent_die->GetParent(); - } - SymbolContext sc_backup = sc; - if (resolve_function_context && parent_die != nullptr && !GetFunction(DWARFDIE(die.GetCU(),parent_die), sc)) - sc = sc_backup; - - type_sp = ParseType(sc, die, NULL); - } - else if (type_ptr != DIE_IS_BEING_PARSED) - { - // Grab the existing type from the master types lists - type_sp = type_ptr->shared_from_this(); - } - +TypeSP SymbolFileDWARF::GetTypeForDIE(const DWARFDIE &die, + bool resolve_function_context) { + TypeSP type_sp; + if (die) { + Type *type_ptr = GetDIEToType().lookup(die.GetDIE()); + if (type_ptr == NULL) { + CompileUnit *lldb_cu = GetCompUnitForDWARFCompUnit(die.GetCU()); + assert(lldb_cu); + SymbolContext sc(lldb_cu); + const DWARFDebugInfoEntry *parent_die = die.GetParent().GetDIE(); + while (parent_die != nullptr) { + if (parent_die->Tag() == DW_TAG_subprogram) + break; + parent_die = parent_die->GetParent(); + } + SymbolContext sc_backup = sc; + if (resolve_function_context && parent_die != nullptr && + !GetFunction(DWARFDIE(die.GetCU(), parent_die), sc)) + sc = sc_backup; + + type_sp = ParseType(sc, die, NULL); + } else if (type_ptr != DIE_IS_BEING_PARSED) { + // Grab the existing type from the master types lists + type_sp = type_ptr->shared_from_this(); } - return type_sp; + } + return type_sp; } - DWARFDIE -SymbolFileDWARF::GetDeclContextDIEContainingDIE (const DWARFDIE &orig_die) -{ - if (orig_die) - { - DWARFDIE die = orig_die; - - while (die) - { - // If this is the original DIE that we are searching for a declaration - // for, then don't look in the cache as we don't want our own decl - // context to be our decl context... - if (orig_die != die) - { - switch (die.Tag()) - { - case DW_TAG_compile_unit: - case DW_TAG_namespace: - case DW_TAG_structure_type: - case DW_TAG_union_type: - case DW_TAG_class_type: - case DW_TAG_lexical_block: - case DW_TAG_subprogram: - return die; - - default: - break; - } - } - - DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification); - if (spec_die) - { - DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(spec_die); - if (decl_ctx_die) - return decl_ctx_die; - } +SymbolFileDWARF::GetDeclContextDIEContainingDIE(const DWARFDIE &orig_die) { + if (orig_die) { + DWARFDIE die = orig_die; - DWARFDIE abs_die = die.GetReferencedDIE(DW_AT_abstract_origin); - if (abs_die) - { - DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(abs_die); - if (decl_ctx_die) - return decl_ctx_die; - } + while (die) { + // If this is the original DIE that we are searching for a declaration + // for, then don't look in the cache as we don't want our own decl + // context to be our decl context... + if (orig_die != die) { + switch (die.Tag()) { + case DW_TAG_compile_unit: + case DW_TAG_namespace: + case DW_TAG_structure_type: + case DW_TAG_union_type: + case DW_TAG_class_type: + case DW_TAG_lexical_block: + case DW_TAG_subprogram: + return die; - die = die.GetParent(); + default: + break; } + } + + DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification); + if (spec_die) { + DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(spec_die); + if (decl_ctx_die) + return decl_ctx_die; + } + + DWARFDIE abs_die = die.GetReferencedDIE(DW_AT_abstract_origin); + if (abs_die) { + DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(abs_die); + if (decl_ctx_die) + return decl_ctx_die; + } + + die = die.GetParent(); } - return DWARFDIE(); + } + return DWARFDIE(); } - Symbol * -SymbolFileDWARF::GetObjCClassSymbol (const ConstString &objc_class_name) -{ - Symbol *objc_class_symbol = NULL; - if (m_obj_file) - { - Symtab *symtab = m_obj_file->GetSymtab (); - if (symtab) - { - objc_class_symbol = symtab->FindFirstSymbolWithNameAndType (objc_class_name, - eSymbolTypeObjCClass, - Symtab::eDebugNo, - Symtab::eVisibilityAny); - } +SymbolFileDWARF::GetObjCClassSymbol(const ConstString &objc_class_name) { + Symbol *objc_class_symbol = NULL; + if (m_obj_file) { + Symtab *symtab = m_obj_file->GetSymtab(); + if (symtab) { + objc_class_symbol = symtab->FindFirstSymbolWithNameAndType( + objc_class_name, eSymbolTypeObjCClass, Symtab::eDebugNo, + Symtab::eVisibilityAny); } - return objc_class_symbol; + } + return objc_class_symbol; } -// Some compilers don't emit the DW_AT_APPLE_objc_complete_type attribute. If they don't -// then we can end up looking through all class types for a complete type and never find -// the full definition. We need to know if this attribute is supported, so we determine -// this here and cache th result. We also need to worry about the debug map DWARF file +// Some compilers don't emit the DW_AT_APPLE_objc_complete_type attribute. If +// they don't +// then we can end up looking through all class types for a complete type and +// never find +// the full definition. We need to know if this attribute is supported, so we +// determine +// this here and cache th result. We also need to worry about the debug map +// DWARF file // if we are doing darwin DWARF in .o file debugging. -bool -SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type (DWARFCompileUnit *cu) -{ - if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate) - { - m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo; - if (cu && cu->Supports_DW_AT_APPLE_objc_complete_type()) - m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes; - else - { - DWARFDebugInfo* debug_info = DebugInfo(); - const uint32_t num_compile_units = GetNumCompileUnits(); - for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) - { - DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx); - if (dwarf_cu != cu && dwarf_cu->Supports_DW_AT_APPLE_objc_complete_type()) - { - m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes; - break; - } - } +bool SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type( + DWARFCompileUnit *cu) { + if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate) { + m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo; + if (cu && cu->Supports_DW_AT_APPLE_objc_complete_type()) + m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes; + else { + DWARFDebugInfo *debug_info = DebugInfo(); + const uint32_t num_compile_units = GetNumCompileUnits(); + for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) { + DWARFCompileUnit *dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx); + if (dwarf_cu != cu && + dwarf_cu->Supports_DW_AT_APPLE_objc_complete_type()) { + m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes; + break; } - if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolNo && GetDebugMapSymfile ()) - return m_debug_map_symfile->Supports_DW_AT_APPLE_objc_complete_type (this); + } } - return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes; + if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolNo && + GetDebugMapSymfile()) + return m_debug_map_symfile->Supports_DW_AT_APPLE_objc_complete_type(this); + } + return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes; } // This function can be used when a DIE is found that is a forward declaration // DIE and we want to try and find a type that has the complete definition. -TypeSP -SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE (const DWARFDIE &die, - const ConstString &type_name, - bool must_be_implementation) -{ - - TypeSP type_sp; - - if (!type_name || (must_be_implementation && !GetObjCClassSymbol (type_name))) - return type_sp; - - DIEArray die_offsets; - - if (m_using_apple_tables) - { - if (m_apple_types_ap.get()) - { - const char *name_cstr = type_name.GetCString(); - m_apple_types_ap->FindCompleteObjCClassByName (name_cstr, die_offsets, must_be_implementation); - } - } - else - { - if (!m_indexed) - Index (); - - m_type_index.Find (type_name, die_offsets); +TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE( + const DWARFDIE &die, const ConstString &type_name, + bool must_be_implementation) { + + TypeSP type_sp; + + if (!type_name || (must_be_implementation && !GetObjCClassSymbol(type_name))) + return type_sp; + + DIEArray die_offsets; + + if (m_using_apple_tables) { + if (m_apple_types_ap.get()) { + const char *name_cstr = type_name.GetCString(); + m_apple_types_ap->FindCompleteObjCClassByName(name_cstr, die_offsets, + must_be_implementation); } - - const size_t num_matches = die_offsets.size(); - - if (num_matches) - { - for (size_t i=0; i<num_matches; ++i) - { - const DIERef& die_ref = die_offsets[i]; - DWARFDIE type_die = GetDIE (die_ref); - - if (type_die) - { - bool try_resolving_type = false; - - // Don't try and resolve the DIE we are looking for with the DIE itself! - if (type_die != die) - { - switch (type_die.Tag()) - { - case DW_TAG_class_type: - case DW_TAG_structure_type: - try_resolving_type = true; - break; - default: - break; - } - } - - if (try_resolving_type) - { - if (must_be_implementation && type_die.Supports_DW_AT_APPLE_objc_complete_type()) - try_resolving_type = type_die.GetAttributeValueAsUnsigned (DW_AT_APPLE_objc_complete_type, 0); - - if (try_resolving_type) - { - Type *resolved_type = ResolveType (type_die, false, true); - if (resolved_type && resolved_type != DIE_IS_BEING_PARSED) - { - DEBUG_PRINTF ("resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64 " (cu 0x%8.8" PRIx64 ")\n", - die.GetID(), - m_obj_file->GetFileSpec().GetFilename().AsCString("<Unknown>"), - type_die.GetID(), - type_cu->GetID()); - - if (die) - GetDIEToType()[die.GetDIE()] = resolved_type; - type_sp = resolved_type->shared_from_this(); - break; - } - } - } + } else { + if (!m_indexed) + Index(); + + m_type_index.Find(type_name, die_offsets); + } + + const size_t num_matches = die_offsets.size(); + + if (num_matches) { + for (size_t i = 0; i < num_matches; ++i) { + const DIERef &die_ref = die_offsets[i]; + DWARFDIE type_die = GetDIE(die_ref); + + if (type_die) { + bool try_resolving_type = false; + + // Don't try and resolve the DIE we are looking for with the DIE itself! + if (type_die != die) { + switch (type_die.Tag()) { + case DW_TAG_class_type: + case DW_TAG_structure_type: + try_resolving_type = true; + break; + default: + break; + } + } + + if (try_resolving_type) { + if (must_be_implementation && + type_die.Supports_DW_AT_APPLE_objc_complete_type()) + try_resolving_type = type_die.GetAttributeValueAsUnsigned( + DW_AT_APPLE_objc_complete_type, 0); + + if (try_resolving_type) { + Type *resolved_type = ResolveType(type_die, false, true); + if (resolved_type && resolved_type != DIE_IS_BEING_PARSED) { + DEBUG_PRINTF("resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64 + " (cu 0x%8.8" PRIx64 ")\n", + die.GetID(), + m_obj_file->GetFileSpec().GetFilename().AsCString( + "<Unknown>"), + type_die.GetID(), type_cu->GetID()); + + if (die) + GetDIEToType()[die.GetDIE()] = resolved_type; + type_sp = resolved_type->shared_from_this(); + break; } - else - { - if (m_using_apple_tables) - { - GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n", - die_ref.die_offset, type_name.GetCString()); - } - } - + } + } + } else { + if (m_using_apple_tables) { + GetObjectFile()->GetModule()->ReportErrorIfModifyDetected( + "the DWARF debug information has been modified (.apple_types " + "accelerator table had bad die 0x%8.8x for '%s')\n", + die_ref.die_offset, type_name.GetCString()); } + } } - return type_sp; + } + return type_sp; } - //---------------------------------------------------------------------- // This function helps to ensure that the declaration contexts match for -// two different DIEs. Often times debug information will refer to a +// two different DIEs. Often times debug information will refer to a // forward declaration of a type (the equivalent of "struct my_struct;". // There will often be a declaration of that type elsewhere that has the // full definition. When we go looking for the full type "my_struct", we // will find one or more matches in the accelerator tables and we will -// then need to make sure the type was in the same declaration context +// then need to make sure the type was in the same declaration context // as the original DIE. This function can efficiently compare two DIEs // and will return true when the declaration context matches, and false -// when they don't. +// when they don't. //---------------------------------------------------------------------- -bool -SymbolFileDWARF::DIEDeclContextsMatch (const DWARFDIE &die1, - const DWARFDIE &die2) -{ - if (die1 == die2) - return true; - - DWARFDIECollection decl_ctx_1; - DWARFDIECollection decl_ctx_2; - //The declaration DIE stack is a stack of the declaration context - // DIEs all the way back to the compile unit. If a type "T" is - // declared inside a class "B", and class "B" is declared inside - // a class "A" and class "A" is in a namespace "lldb", and the - // namespace is in a compile unit, there will be a stack of DIEs: - // - // [0] DW_TAG_class_type for "B" - // [1] DW_TAG_class_type for "A" - // [2] DW_TAG_namespace for "lldb" - // [3] DW_TAG_compile_unit for the source file. - // - // We grab both contexts and make sure that everything matches - // all the way back to the compiler unit. - - // First lets grab the decl contexts for both DIEs - die1.GetDeclContextDIEs (decl_ctx_1); - die2.GetDeclContextDIEs (decl_ctx_2); - // Make sure the context arrays have the same size, otherwise - // we are done - const size_t count1 = decl_ctx_1.Size(); - const size_t count2 = decl_ctx_2.Size(); - if (count1 != count2) - return false; - - // Make sure the DW_TAG values match all the way back up the - // compile unit. If they don't, then we are done. - DWARFDIE decl_ctx_die1; - DWARFDIE decl_ctx_die2; - size_t i; - for (i=0; i<count1; i++) - { - decl_ctx_die1 = decl_ctx_1.GetDIEAtIndex (i); - decl_ctx_die2 = decl_ctx_2.GetDIEAtIndex (i); - if (decl_ctx_die1.Tag() != decl_ctx_die2.Tag()) - return false; - } +bool SymbolFileDWARF::DIEDeclContextsMatch(const DWARFDIE &die1, + const DWARFDIE &die2) { + if (die1 == die2) + return true; + + DWARFDIECollection decl_ctx_1; + DWARFDIECollection decl_ctx_2; + // The declaration DIE stack is a stack of the declaration context + // DIEs all the way back to the compile unit. If a type "T" is + // declared inside a class "B", and class "B" is declared inside + // a class "A" and class "A" is in a namespace "lldb", and the + // namespace is in a compile unit, there will be a stack of DIEs: + // + // [0] DW_TAG_class_type for "B" + // [1] DW_TAG_class_type for "A" + // [2] DW_TAG_namespace for "lldb" + // [3] DW_TAG_compile_unit for the source file. + // + // We grab both contexts and make sure that everything matches + // all the way back to the compiler unit. + + // First lets grab the decl contexts for both DIEs + die1.GetDeclContextDIEs(decl_ctx_1); + die2.GetDeclContextDIEs(decl_ctx_2); + // Make sure the context arrays have the same size, otherwise + // we are done + const size_t count1 = decl_ctx_1.Size(); + const size_t count2 = decl_ctx_2.Size(); + if (count1 != count2) + return false; + + // Make sure the DW_TAG values match all the way back up the + // compile unit. If they don't, then we are done. + DWARFDIE decl_ctx_die1; + DWARFDIE decl_ctx_die2; + size_t i; + for (i = 0; i < count1; i++) { + decl_ctx_die1 = decl_ctx_1.GetDIEAtIndex(i); + decl_ctx_die2 = decl_ctx_2.GetDIEAtIndex(i); + if (decl_ctx_die1.Tag() != decl_ctx_die2.Tag()) + return false; + } #if defined LLDB_CONFIGURATION_DEBUG - // Make sure the top item in the decl context die array is always - // DW_TAG_compile_unit. If it isn't then something went wrong in - // the DWARFDIE::GetDeclContextDIEs() function... - assert (decl_ctx_1.GetDIEAtIndex (count1 - 1).Tag() == DW_TAG_compile_unit); + // Make sure the top item in the decl context die array is always + // DW_TAG_compile_unit. If it isn't then something went wrong in + // the DWARFDIE::GetDeclContextDIEs() function... + assert(decl_ctx_1.GetDIEAtIndex(count1 - 1).Tag() == DW_TAG_compile_unit); #endif - // Always skip the compile unit when comparing by only iterating up to - // "count - 1". Here we compare the names as we go. - for (i=0; i<count1 - 1; i++) - { - decl_ctx_die1 = decl_ctx_1.GetDIEAtIndex (i); - decl_ctx_die2 = decl_ctx_2.GetDIEAtIndex (i); - const char *name1 = decl_ctx_die1.GetName(); - const char *name2 = decl_ctx_die2.GetName(); - // If the string was from a DW_FORM_strp, then the pointer will often - // be the same! - if (name1 == name2) - continue; - - // Name pointers are not equal, so only compare the strings - // if both are not NULL. - if (name1 && name2) - { - // If the strings don't compare, we are done... - if (strcmp(name1, name2) != 0) - return false; - } - else - { - // One name was NULL while the other wasn't - return false; - } + // Always skip the compile unit when comparing by only iterating up to + // "count - 1". Here we compare the names as we go. + for (i = 0; i < count1 - 1; i++) { + decl_ctx_die1 = decl_ctx_1.GetDIEAtIndex(i); + decl_ctx_die2 = decl_ctx_2.GetDIEAtIndex(i); + const char *name1 = decl_ctx_die1.GetName(); + const char *name2 = decl_ctx_die2.GetName(); + // If the string was from a DW_FORM_strp, then the pointer will often + // be the same! + if (name1 == name2) + continue; + + // Name pointers are not equal, so only compare the strings + // if both are not NULL. + if (name1 && name2) { + // If the strings don't compare, we are done... + if (strcmp(name1, name2) != 0) + return false; + } else { + // One name was NULL while the other wasn't + return false; } - // We made it through all of the checks and the declaration contexts - // are equal. - return true; + } + // We made it through all of the checks and the declaration contexts + // are equal. + return true; } - - -TypeSP -SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &dwarf_decl_ctx) -{ - TypeSP type_sp; - - const uint32_t dwarf_decl_ctx_count = dwarf_decl_ctx.GetSize(); - if (dwarf_decl_ctx_count > 0) - { - const ConstString type_name(dwarf_decl_ctx[0].name); - const dw_tag_t tag = dwarf_decl_ctx[0].tag; - if (type_name) - { - Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION|DWARF_LOG_LOOKUPS)); +TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext( + const DWARFDeclContext &dwarf_decl_ctx) { + TypeSP type_sp; + + const uint32_t dwarf_decl_ctx_count = dwarf_decl_ctx.GetSize(); + if (dwarf_decl_ctx_count > 0) { + const ConstString type_name(dwarf_decl_ctx[0].name); + const dw_tag_t tag = dwarf_decl_ctx[0].tag; + + if (type_name) { + Log *log(LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION | + DWARF_LOG_LOOKUPS)); + if (log) { + GetObjectFile()->GetModule()->LogMessage( + log, "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%" + "s, qualified-name='%s')", + DW_TAG_value_to_name(dwarf_decl_ctx[0].tag), + dwarf_decl_ctx.GetQualifiedName()); + } + + DIEArray die_offsets; + + if (m_using_apple_tables) { + if (m_apple_types_ap.get()) { + const bool has_tag = + m_apple_types_ap->GetHeader().header_data.ContainsAtom( + DWARFMappedHash::eAtomTypeTag); + const bool has_qualified_name_hash = + m_apple_types_ap->GetHeader().header_data.ContainsAtom( + DWARFMappedHash::eAtomTypeQualNameHash); + if (has_tag && has_qualified_name_hash) { + const char *qualified_name = dwarf_decl_ctx.GetQualifiedName(); + const uint32_t qualified_name_hash = + MappedHash::HashStringUsingDJB(qualified_name); if (log) - { - GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s')", - DW_TAG_value_to_name(dwarf_decl_ctx[0].tag), - dwarf_decl_ctx.GetQualifiedName()); + GetObjectFile()->GetModule()->LogMessage( + log, "FindByNameAndTagAndQualifiedNameHash()"); + m_apple_types_ap->FindByNameAndTagAndQualifiedNameHash( + type_name.GetCString(), tag, qualified_name_hash, die_offsets); + } else if (has_tag) { + if (log) + GetObjectFile()->GetModule()->LogMessage(log, + "FindByNameAndTag()"); + m_apple_types_ap->FindByNameAndTag(type_name.GetCString(), tag, + die_offsets); + } else { + m_apple_types_ap->FindByName(type_name.GetCString(), die_offsets); + } + } + } else { + if (!m_indexed) + Index(); + + m_type_index.Find(type_name, die_offsets); + } + + const size_t num_matches = die_offsets.size(); + + // Get the type system that we are looking to find a type for. We will use + // this + // to ensure any matches we find are in a language that this type system + // supports + const LanguageType language = dwarf_decl_ctx.GetLanguage(); + TypeSystem *type_system = (language == eLanguageTypeUnknown) + ? nullptr + : GetTypeSystemForLanguage(language); + + if (num_matches) { + for (size_t i = 0; i < num_matches; ++i) { + const DIERef &die_ref = die_offsets[i]; + DWARFDIE type_die = GetDIE(die_ref); + + if (type_die) { + // Make sure type_die's langauge matches the type system we are + // looking for. + // We don't want to find a "Foo" type from Java if we are looking + // for a "Foo" + // type for C, C++, ObjC, or ObjC++. + if (type_system && + !type_system->SupportsLanguage(type_die.GetLanguage())) + continue; + bool try_resolving_type = false; + + // Don't try and resolve the DIE we are looking for with the DIE + // itself! + const dw_tag_t type_tag = type_die.Tag(); + // Make sure the tags match + if (type_tag == tag) { + // The tags match, lets try resolving this type + try_resolving_type = true; + } else { + // The tags don't match, but we need to watch our for a + // forward declaration for a struct and ("struct foo") + // ends up being a class ("class foo { ... };") or + // vice versa. + switch (type_tag) { + case DW_TAG_class_type: + // We had a "class foo", see if we ended up with a "struct foo { + // ... };" + try_resolving_type = (tag == DW_TAG_structure_type); + break; + case DW_TAG_structure_type: + // We had a "struct foo", see if we ended up with a "class foo { + // ... };" + try_resolving_type = (tag == DW_TAG_class_type); + break; + default: + // Tags don't match, don't event try to resolve + // using this type whose name matches.... + break; + } } - - DIEArray die_offsets; - - if (m_using_apple_tables) - { - if (m_apple_types_ap.get()) - { - const bool has_tag = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeTag); - const bool has_qualified_name_hash = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeQualNameHash); - if (has_tag && has_qualified_name_hash) - { - const char *qualified_name = dwarf_decl_ctx.GetQualifiedName(); - const uint32_t qualified_name_hash = MappedHash::HashStringUsingDJB (qualified_name); - if (log) - GetObjectFile()->GetModule()->LogMessage (log,"FindByNameAndTagAndQualifiedNameHash()"); - m_apple_types_ap->FindByNameAndTagAndQualifiedNameHash (type_name.GetCString(), tag, qualified_name_hash, die_offsets); - } - else if (has_tag) - { - if (log) - GetObjectFile()->GetModule()->LogMessage (log,"FindByNameAndTag()"); - m_apple_types_ap->FindByNameAndTag (type_name.GetCString(), tag, die_offsets); - } - else - { - m_apple_types_ap->FindByName (type_name.GetCString(), die_offsets); - } + + if (try_resolving_type) { + DWARFDeclContext type_dwarf_decl_ctx; + type_die.GetDWARFDeclContext(type_dwarf_decl_ctx); + + if (log) { + GetObjectFile()->GetModule()->LogMessage( + log, "SymbolFileDWARF::" + "FindDefinitionTypeForDWARFDeclContext(tag=%s, " + "qualified-name='%s') trying die=0x%8.8x (%s)", + DW_TAG_value_to_name(dwarf_decl_ctx[0].tag), + dwarf_decl_ctx.GetQualifiedName(), type_die.GetOffset(), + type_dwarf_decl_ctx.GetQualifiedName()); + } + + // Make sure the decl contexts match all the way up + if (dwarf_decl_ctx == type_dwarf_decl_ctx) { + Type *resolved_type = ResolveType(type_die, false); + if (resolved_type && resolved_type != DIE_IS_BEING_PARSED) { + type_sp = resolved_type->shared_from_this(); + break; } + } + } else { + if (log) { + std::string qualified_name; + type_die.GetQualifiedName(qualified_name); + GetObjectFile()->GetModule()->LogMessage( + log, "SymbolFileDWARF::" + "FindDefinitionTypeForDWARFDeclContext(tag=%s, " + "qualified-name='%s') ignoring die=0x%8.8x (%s)", + DW_TAG_value_to_name(dwarf_decl_ctx[0].tag), + dwarf_decl_ctx.GetQualifiedName(), type_die.GetOffset(), + qualified_name.c_str()); + } } - else - { - if (!m_indexed) - Index (); - - m_type_index.Find (type_name, die_offsets); - } - - const size_t num_matches = die_offsets.size(); - - // Get the type system that we are looking to find a type for. We will use this - // to ensure any matches we find are in a language that this type system supports - const LanguageType language = dwarf_decl_ctx.GetLanguage(); - TypeSystem *type_system = (language == eLanguageTypeUnknown) ? nullptr : GetTypeSystemForLanguage(language); - - if (num_matches) - { - for (size_t i=0; i<num_matches; ++i) - { - const DIERef& die_ref = die_offsets[i]; - DWARFDIE type_die = GetDIE (die_ref); - - if (type_die) - { - // Make sure type_die's langauge matches the type system we are looking for. - // We don't want to find a "Foo" type from Java if we are looking for a "Foo" - // type for C, C++, ObjC, or ObjC++. - if (type_system && !type_system->SupportsLanguage(type_die.GetLanguage())) - continue; - bool try_resolving_type = false; - - // Don't try and resolve the DIE we are looking for with the DIE itself! - const dw_tag_t type_tag = type_die.Tag(); - // Make sure the tags match - if (type_tag == tag) - { - // The tags match, lets try resolving this type - try_resolving_type = true; - } - else - { - // The tags don't match, but we need to watch our for a - // forward declaration for a struct and ("struct foo") - // ends up being a class ("class foo { ... };") or - // vice versa. - switch (type_tag) - { - case DW_TAG_class_type: - // We had a "class foo", see if we ended up with a "struct foo { ... };" - try_resolving_type = (tag == DW_TAG_structure_type); - break; - case DW_TAG_structure_type: - // We had a "struct foo", see if we ended up with a "class foo { ... };" - try_resolving_type = (tag == DW_TAG_class_type); - break; - default: - // Tags don't match, don't event try to resolve - // using this type whose name matches.... - break; - } - } - - if (try_resolving_type) - { - DWARFDeclContext type_dwarf_decl_ctx; - type_die.GetDWARFDeclContext (type_dwarf_decl_ctx); - - if (log) - { - GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') trying die=0x%8.8x (%s)", - DW_TAG_value_to_name(dwarf_decl_ctx[0].tag), - dwarf_decl_ctx.GetQualifiedName(), - type_die.GetOffset(), - type_dwarf_decl_ctx.GetQualifiedName()); - } - - // Make sure the decl contexts match all the way up - if (dwarf_decl_ctx == type_dwarf_decl_ctx) - { - Type *resolved_type = ResolveType (type_die, false); - if (resolved_type && resolved_type != DIE_IS_BEING_PARSED) - { - type_sp = resolved_type->shared_from_this(); - break; - } - } - } - else - { - if (log) - { - std::string qualified_name; - type_die.GetQualifiedName(qualified_name); - GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') ignoring die=0x%8.8x (%s)", - DW_TAG_value_to_name(dwarf_decl_ctx[0].tag), - dwarf_decl_ctx.GetQualifiedName(), - type_die.GetOffset(), - qualified_name.c_str()); - } - } - } - else - { - if (m_using_apple_tables) - { - GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n", - die_ref.die_offset, type_name.GetCString()); - } - } - - } + } else { + if (m_using_apple_tables) { + GetObjectFile()->GetModule()->ReportErrorIfModifyDetected( + "the DWARF debug information has been modified (.apple_types " + "accelerator table had bad die 0x%8.8x for '%s')\n", + die_ref.die_offset, type_name.GetCString()); } + } } + } } - return type_sp; + } + return type_sp; } -TypeSP -SymbolFileDWARF::ParseType (const SymbolContext& sc, const DWARFDIE &die, bool *type_is_new_ptr) -{ - TypeSP type_sp; - - if (die) - { - TypeSystem *type_system = GetTypeSystemForLanguage(die.GetCU()->GetLanguageType()); - - if (type_system) - { - DWARFASTParser *dwarf_ast = type_system->GetDWARFParser(); - if (dwarf_ast) - { - Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO); - type_sp = dwarf_ast->ParseTypeFromDWARF (sc, die, log, type_is_new_ptr); - if (type_sp) - { - TypeList* type_list = GetTypeList(); - if (type_list) - type_list->Insert(type_sp); - - if (die.Tag() == DW_TAG_subprogram) - { - DIERef die_ref = die.GetDIERef(); - std::string scope_qualified_name(GetDeclContextForUID(die.GetID()).GetScopeQualifiedName().AsCString("")); - if (scope_qualified_name.size()) - { - NameToOffsetMap::iterator iter = m_function_scope_qualified_name_map.find(scope_qualified_name); - if (iter != m_function_scope_qualified_name_map.end()) - (*iter).second->insert(die_ref); - else - { - DIERefSetSP new_set(new std::set<DIERef>); - new_set->insert(die_ref); - m_function_scope_qualified_name_map.emplace(std::make_pair(scope_qualified_name, new_set)); - } - } - } - } +TypeSP SymbolFileDWARF::ParseType(const SymbolContext &sc, const DWARFDIE &die, + bool *type_is_new_ptr) { + TypeSP type_sp; + + if (die) { + TypeSystem *type_system = + GetTypeSystemForLanguage(die.GetCU()->GetLanguageType()); + + if (type_system) { + DWARFASTParser *dwarf_ast = type_system->GetDWARFParser(); + if (dwarf_ast) { + Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO); + type_sp = dwarf_ast->ParseTypeFromDWARF(sc, die, log, type_is_new_ptr); + if (type_sp) { + TypeList *type_list = GetTypeList(); + if (type_list) + type_list->Insert(type_sp); + + if (die.Tag() == DW_TAG_subprogram) { + DIERef die_ref = die.GetDIERef(); + std::string scope_qualified_name(GetDeclContextForUID(die.GetID()) + .GetScopeQualifiedName() + .AsCString("")); + if (scope_qualified_name.size()) { + NameToOffsetMap::iterator iter = + m_function_scope_qualified_name_map.find( + scope_qualified_name); + if (iter != m_function_scope_qualified_name_map.end()) + (*iter).second->insert(die_ref); + else { + DIERefSetSP new_set(new std::set<DIERef>); + new_set->insert(die_ref); + m_function_scope_qualified_name_map.emplace( + std::make_pair(scope_qualified_name, new_set)); + } } + } } + } } - - return type_sp; -} + } -size_t -SymbolFileDWARF::ParseTypes -( - const SymbolContext& sc, - const DWARFDIE &orig_die, - bool parse_siblings, - bool parse_children -) -{ - size_t types_added = 0; - DWARFDIE die = orig_die; - while (die) - { - bool type_is_new = false; - if (ParseType(sc, die, &type_is_new).get()) - { - if (type_is_new) - ++types_added; - } + return type_sp; +} - if (parse_children && die.HasChildren()) - { - if (die.Tag() == DW_TAG_subprogram) - { - SymbolContext child_sc(sc); - child_sc.function = sc.comp_unit->FindFunctionByUID(die.GetID()).get(); - types_added += ParseTypes(child_sc, die.GetFirstChild(), true, true); - } - else - types_added += ParseTypes(sc, die.GetFirstChild(), true, true); - } +size_t SymbolFileDWARF::ParseTypes(const SymbolContext &sc, + const DWARFDIE &orig_die, + bool parse_siblings, bool parse_children) { + size_t types_added = 0; + DWARFDIE die = orig_die; + while (die) { + bool type_is_new = false; + if (ParseType(sc, die, &type_is_new).get()) { + if (type_is_new) + ++types_added; + } - if (parse_siblings) - die = die.GetSibling(); - else - die.Clear(); + if (parse_children && die.HasChildren()) { + if (die.Tag() == DW_TAG_subprogram) { + SymbolContext child_sc(sc); + child_sc.function = sc.comp_unit->FindFunctionByUID(die.GetID()).get(); + types_added += ParseTypes(child_sc, die.GetFirstChild(), true, true); + } else + types_added += ParseTypes(sc, die.GetFirstChild(), true, true); } - return types_added; -} + if (parse_siblings) + die = die.GetSibling(); + else + die.Clear(); + } + return types_added; +} -size_t -SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc) -{ - assert(sc.comp_unit && sc.function); - size_t functions_added = 0; - DWARFCompileUnit* 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); - } +size_t SymbolFileDWARF::ParseFunctionBlocks(const SymbolContext &sc) { + assert(sc.comp_unit && sc.function); + size_t functions_added = 0; + DWARFCompileUnit *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); } + } - return functions_added; + return functions_added; } - -size_t -SymbolFileDWARF::ParseTypes (const SymbolContext &sc) -{ - // At least a compile unit must be valid - assert(sc.comp_unit); - size_t types_added = 0; - DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.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); - } - } +size_t SymbolFileDWARF::ParseTypes(const SymbolContext &sc) { + // At least a compile unit must be valid + assert(sc.comp_unit); + size_t types_added = 0; + DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.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); + } } + } - return types_added; + return types_added; } -size_t -SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc) -{ - if (sc.comp_unit != NULL) - { - DWARFDebugInfo* info = DebugInfo(); - if (info == NULL) - return 0; - - if (sc.function) - { - DWARFDIE function_die = info->GetDIE(DIERef(sc.function->GetID(), this)); - - const dw_addr_t func_lo_pc = function_die.GetAttributeValueAsAddress (DW_AT_low_pc, LLDB_INVALID_ADDRESS); - if (func_lo_pc != LLDB_INVALID_ADDRESS) - { - const size_t num_variables = ParseVariables(sc, function_die.GetFirstChild(), func_lo_pc, true, true); - - // Let all blocks know they have parse all their variables - sc.function->GetBlock (false).SetDidParseVariables (true, true); - return num_variables; +size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) { + if (sc.comp_unit != NULL) { + DWARFDebugInfo *info = DebugInfo(); + if (info == NULL) + return 0; + + if (sc.function) { + DWARFDIE function_die = info->GetDIE(DIERef(sc.function->GetID(), this)); + + const dw_addr_t func_lo_pc = function_die.GetAttributeValueAsAddress( + DW_AT_low_pc, LLDB_INVALID_ADDRESS); + if (func_lo_pc != LLDB_INVALID_ADDRESS) { + const size_t num_variables = ParseVariables( + sc, function_die.GetFirstChild(), func_lo_pc, true, true); + + // Let all blocks know they have parse all their variables + sc.function->GetBlock(false).SetDidParseVariables(true, true); + return num_variables; + } + } else if (sc.comp_unit) { + DWARFCompileUnit *dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID()); + + if (dwarf_cu == NULL) + return 0; + + uint32_t vars_added = 0; + VariableListSP variables(sc.comp_unit->GetVariableList(false)); + + if (variables.get() == NULL) { + variables.reset(new VariableList()); + sc.comp_unit->SetVariableList(variables); + + DIEArray die_offsets; + if (m_using_apple_tables) { + if (m_apple_names_ap.get()) { + DWARFMappedHash::DIEInfoArray hash_data_array; + if (m_apple_names_ap->AppendAllDIEsInRange( + dwarf_cu->GetOffset(), dwarf_cu->GetNextCompileUnitOffset(), + hash_data_array)) { + DWARFMappedHash::ExtractDIEArray(hash_data_array, die_offsets); } + } + } else { + // Index if we already haven't to make sure the compile units + // get indexed and make their global DIE index list + if (!m_indexed) + Index(); + + m_global_index.FindAllEntriesForCompileUnit(dwarf_cu->GetOffset(), + die_offsets); } - else if (sc.comp_unit) - { - DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID()); - - if (dwarf_cu == NULL) - return 0; - - uint32_t vars_added = 0; - VariableListSP variables (sc.comp_unit->GetVariableList(false)); - - if (variables.get() == NULL) - { - variables.reset(new VariableList()); - sc.comp_unit->SetVariableList(variables); - - DIEArray die_offsets; - if (m_using_apple_tables) - { - if (m_apple_names_ap.get()) - { - DWARFMappedHash::DIEInfoArray hash_data_array; - if (m_apple_names_ap->AppendAllDIEsInRange (dwarf_cu->GetOffset(), - dwarf_cu->GetNextCompileUnitOffset(), - hash_data_array)) - { - DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets); - } - } - } - else - { - // Index if we already haven't to make sure the compile units - // get indexed and make their global DIE index list - if (!m_indexed) - Index (); - - m_global_index.FindAllEntriesForCompileUnit (dwarf_cu->GetOffset(), - die_offsets); - } - - const size_t num_matches = die_offsets.size(); - if (num_matches) - { - for (size_t i=0; i<num_matches; ++i) - { - const DIERef& die_ref = die_offsets[i]; - DWARFDIE die = GetDIE (die_ref); - if (die) - { - VariableSP var_sp (ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS)); - if (var_sp) - { - variables->AddVariableIfUnique (var_sp); - ++vars_added; - } - } - else - { - if (m_using_apple_tables) - { - GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x)\n", die_ref.die_offset); - } - } - } - } + const size_t num_matches = die_offsets.size(); + if (num_matches) { + for (size_t i = 0; i < num_matches; ++i) { + const DIERef &die_ref = die_offsets[i]; + DWARFDIE die = GetDIE(die_ref); + if (die) { + VariableSP var_sp( + ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS)); + if (var_sp) { + variables->AddVariableIfUnique(var_sp); + ++vars_added; + } + } else { + if (m_using_apple_tables) { + GetObjectFile()->GetModule()->ReportErrorIfModifyDetected( + "the DWARF debug information has been modified " + "(.apple_names accelerator table had bad die 0x%8.8x)\n", + die_ref.die_offset); + } } - return vars_added; + } } + } + return vars_added; } - return 0; + } + return 0; } -VariableSP -SymbolFileDWARF::ParseVariableDIE -( - const SymbolContext& sc, - const DWARFDIE &die, - const lldb::addr_t func_low_pc -) -{ - if (die.GetDWARF() != this) - return die.GetDWARF()->ParseVariableDIE(sc, die, func_low_pc); +VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, + const DWARFDIE &die, + const lldb::addr_t func_low_pc) { + if (die.GetDWARF() != this) + return die.GetDWARF()->ParseVariableDIE(sc, die, func_low_pc); - VariableSP var_sp; - if (!die) - return var_sp; + VariableSP var_sp; + if (!die) + return var_sp; - var_sp = GetDIEToVariable()[die.GetDIE()]; - if (var_sp) - return var_sp; // Already been parsed! - - const dw_tag_t tag = die.Tag(); - ModuleSP module = GetObjectFile()->GetModule(); - - if ((tag == DW_TAG_variable) || - (tag == DW_TAG_constant) || - (tag == DW_TAG_formal_parameter && sc.function)) - { - DWARFAttributes attributes; - const size_t num_attributes = die.GetAttributes(attributes); - DWARFDIE spec_die; - if (num_attributes > 0) - { - const char *name = NULL; - const char *mangled = NULL; - Declaration decl; - uint32_t i; - DWARFFormValue type_die_form; - DWARFExpression location(die.GetCU()); - bool is_external = false; - bool is_artificial = false; - bool location_is_const_value_data = false; - bool has_explicit_location = false; - DWARFFormValue const_value; - Variable::RangeList scope_ranges; - //AccessType accessibility = eAccessNone; - - for (i=0; i<num_attributes; ++i) - { - dw_attr_t attr = attributes.AttributeAtIndex(i); - DWARFFormValue form_value; - - if (attributes.ExtractFormValueAtIndex(i, form_value)) - { - switch (attr) - { - case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; - case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; - case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; - case DW_AT_name: name = form_value.AsCString(); break; - case DW_AT_linkage_name: - case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(); break; - case DW_AT_type: type_die_form = form_value; break; - case DW_AT_external: is_external = form_value.Boolean(); break; - case DW_AT_const_value: - // If we have already found a DW_AT_location attribute, ignore this attribute. - if (!has_explicit_location) - { - location_is_const_value_data = true; - // The constant value will be either a block, a data value or a string. - const DWARFDataExtractor& debug_info_data = get_debug_info_data(); - if (DWARFFormValue::IsBlockForm(form_value.Form())) - { - // Retrieve the value as a block expression. - uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); - uint32_t block_length = form_value.Unsigned(); - location.CopyOpcodeData(module, debug_info_data, block_offset, block_length); - } - else if (DWARFFormValue::IsDataForm(form_value.Form())) - { - // Retrieve the value as a data expression. - DWARFFormValue::FixedFormSizes fixed_form_sizes = - DWARFFormValue::GetFixedFormSizesForAddressSize ( - attributes.CompileUnitAtIndex(i)->GetAddressByteSize(), - attributes.CompileUnitAtIndex(i)->IsDWARF64()); - uint32_t data_offset = attributes.DIEOffsetAtIndex(i); - uint32_t data_length = fixed_form_sizes.GetSize(form_value.Form()); - if (data_length == 0) - { - const uint8_t *data_pointer = form_value.BlockData(); - if (data_pointer) - { - form_value.Unsigned(); - } - else if (DWARFFormValue::IsDataForm(form_value.Form())) - { - // we need to get the byte size of the type later after we create the variable - const_value = form_value; - } - } - else - location.CopyOpcodeData(module, debug_info_data, data_offset, data_length); - } - else - { - // Retrieve the value as a string expression. - if (form_value.Form() == DW_FORM_strp) - { - DWARFFormValue::FixedFormSizes fixed_form_sizes = - DWARFFormValue::GetFixedFormSizesForAddressSize ( - attributes.CompileUnitAtIndex(i)->GetAddressByteSize(), - attributes.CompileUnitAtIndex(i)->IsDWARF64()); - uint32_t data_offset = attributes.DIEOffsetAtIndex(i); - uint32_t data_length = fixed_form_sizes.GetSize(form_value.Form()); - location.CopyOpcodeData(module, debug_info_data, data_offset, data_length); - } - else - { - const char *str = form_value.AsCString(); - uint32_t string_offset = str - (const char *)debug_info_data.GetDataStart(); - uint32_t string_length = strlen(str) + 1; - location.CopyOpcodeData(module, debug_info_data, string_offset, string_length); - } - } - } - break; - case DW_AT_location: - { - location_is_const_value_data = false; - has_explicit_location = true; - if (form_value.BlockData()) - { - const DWARFDataExtractor& debug_info_data = get_debug_info_data(); - - uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); - uint32_t block_length = form_value.Unsigned(); - location.CopyOpcodeData(module, get_debug_info_data(), block_offset, block_length); - } - else - { - const DWARFDataExtractor& debug_loc_data = get_debug_loc_data(); - const dw_offset_t debug_loc_offset = form_value.Unsigned(); - - size_t loc_list_length = DWARFExpression::LocationListSize(die.GetCU(), debug_loc_data, debug_loc_offset); - if (loc_list_length > 0) - { - location.CopyOpcodeData(module, debug_loc_data, debug_loc_offset, loc_list_length); - assert (func_low_pc != LLDB_INVALID_ADDRESS); - location.SetLocationListSlide (func_low_pc - attributes.CompileUnitAtIndex(i)->GetBaseAddress()); - } - } - } - break; - case DW_AT_specification: - spec_die = GetDIE(DIERef(form_value)); - break; - 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(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 - // dwarf spec is a bit ambiguous about what is the expected behavior in - // case the enclosing block have a non coninious address range and the - // DW_AT_start_scope entry have a form constant. - GetObjectFile()->GetModule()->ReportWarning ("0x%8.8" PRIx64 ": DW_AT_start_scope has unsupported form type (0x%x)\n", - die.GetID(), - form_value.Form()); - } - - scope_ranges.Sort(); - scope_ranges.CombineConsecutiveRanges(); - } - break; - case DW_AT_artificial: is_artificial = form_value.Boolean(); break; - case DW_AT_accessibility: break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; - case DW_AT_declaration: - case DW_AT_description: - case DW_AT_endianity: - case DW_AT_segment: - case DW_AT_visibility: - default: - case DW_AT_abstract_origin: - case DW_AT_sibling: - break; - } + var_sp = GetDIEToVariable()[die.GetDIE()]; + if (var_sp) + return var_sp; // Already been parsed! + + const dw_tag_t tag = die.Tag(); + ModuleSP module = GetObjectFile()->GetModule(); + + if ((tag == DW_TAG_variable) || (tag == DW_TAG_constant) || + (tag == DW_TAG_formal_parameter && sc.function)) { + DWARFAttributes attributes; + const size_t num_attributes = die.GetAttributes(attributes); + DWARFDIE spec_die; + if (num_attributes > 0) { + const char *name = NULL; + const char *mangled = NULL; + Declaration decl; + uint32_t i; + DWARFFormValue type_die_form; + DWARFExpression location(die.GetCU()); + bool is_external = false; + bool is_artificial = false; + bool location_is_const_value_data = false; + bool has_explicit_location = false; + DWARFFormValue const_value; + Variable::RangeList scope_ranges; + // AccessType accessibility = eAccessNone; + + for (i = 0; i < num_attributes; ++i) { + dw_attr_t attr = attributes.AttributeAtIndex(i); + DWARFFormValue form_value; + + if (attributes.ExtractFormValueAtIndex(i, form_value)) { + switch (attr) { + case DW_AT_decl_file: + decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex( + form_value.Unsigned())); + break; + case DW_AT_decl_line: + decl.SetLine(form_value.Unsigned()); + break; + case DW_AT_decl_column: + decl.SetColumn(form_value.Unsigned()); + break; + case DW_AT_name: + name = form_value.AsCString(); + break; + case DW_AT_linkage_name: + case DW_AT_MIPS_linkage_name: + mangled = form_value.AsCString(); + break; + case DW_AT_type: + type_die_form = form_value; + break; + case DW_AT_external: + is_external = form_value.Boolean(); + break; + case DW_AT_const_value: + // If we have already found a DW_AT_location attribute, ignore this + // attribute. + if (!has_explicit_location) { + location_is_const_value_data = true; + // The constant value will be either a block, a data value or a + // string. + const DWARFDataExtractor &debug_info_data = get_debug_info_data(); + if (DWARFFormValue::IsBlockForm(form_value.Form())) { + // Retrieve the value as a block expression. + uint32_t block_offset = + form_value.BlockData() - debug_info_data.GetDataStart(); + uint32_t block_length = form_value.Unsigned(); + location.CopyOpcodeData(module, debug_info_data, block_offset, + block_length); + } else if (DWARFFormValue::IsDataForm(form_value.Form())) { + // Retrieve the value as a data expression. + DWARFFormValue::FixedFormSizes fixed_form_sizes = + DWARFFormValue::GetFixedFormSizesForAddressSize( + attributes.CompileUnitAtIndex(i)->GetAddressByteSize(), + attributes.CompileUnitAtIndex(i)->IsDWARF64()); + uint32_t data_offset = attributes.DIEOffsetAtIndex(i); + uint32_t data_length = + fixed_form_sizes.GetSize(form_value.Form()); + if (data_length == 0) { + const uint8_t *data_pointer = form_value.BlockData(); + if (data_pointer) { + form_value.Unsigned(); + } else if (DWARFFormValue::IsDataForm(form_value.Form())) { + // we need to get the byte size of the type later after we + // create the variable + const_value = form_value; + } + } else + location.CopyOpcodeData(module, debug_info_data, data_offset, + data_length); + } else { + // Retrieve the value as a string expression. + if (form_value.Form() == DW_FORM_strp) { + DWARFFormValue::FixedFormSizes fixed_form_sizes = + DWARFFormValue::GetFixedFormSizesForAddressSize( + attributes.CompileUnitAtIndex(i) + ->GetAddressByteSize(), + attributes.CompileUnitAtIndex(i)->IsDWARF64()); + uint32_t data_offset = attributes.DIEOffsetAtIndex(i); + uint32_t data_length = + fixed_form_sizes.GetSize(form_value.Form()); + location.CopyOpcodeData(module, debug_info_data, data_offset, + data_length); + } else { + const char *str = form_value.AsCString(); + uint32_t string_offset = + str - (const char *)debug_info_data.GetDataStart(); + uint32_t string_length = strlen(str) + 1; + location.CopyOpcodeData(module, debug_info_data, + string_offset, string_length); } + } } - - const DWARFDIE parent_context_die = GetDeclContextDIEContainingDIE(die); - const dw_tag_t parent_tag = die.GetParent().Tag(); - bool is_static_member = parent_tag == DW_TAG_compile_unit && (parent_context_die.Tag() == DW_TAG_class_type || parent_context_die.Tag() == DW_TAG_structure_type); - - ValueType scope = eValueTypeInvalid; - - const DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die); - SymbolContextScope * symbol_context_scope = NULL; - - if (!mangled) - { - // LLDB relies on the mangled name (DW_TAG_linkage_name or DW_AT_MIPS_linkage_name) to - // generate fully qualified names of global variables with commands like "frame var j". - // For example, if j were an int variable holding a value 4 and declared in a namespace - // B which in turn is contained in a namespace A, the command "frame var j" returns - // "(int) A::B::j = 4". If the compiler does not emit a linkage name, we should be able - // to generate a fully qualified name from the declaration context. - if (parent_tag == DW_TAG_compile_unit && - Language::LanguageIsCPlusPlus(die.GetLanguage())) - { - DWARFDeclContext decl_ctx; - - die.GetDWARFDeclContext(decl_ctx); - mangled = decl_ctx.GetQualifiedNameAsConstString().GetCString(); - } + break; + case DW_AT_location: { + location_is_const_value_data = false; + has_explicit_location = true; + if (DWARFFormValue::IsBlockForm(form_value.Form())) { + const DWARFDataExtractor &debug_info_data = get_debug_info_data(); + + uint32_t block_offset = + form_value.BlockData() - debug_info_data.GetDataStart(); + uint32_t block_length = form_value.Unsigned(); + location.CopyOpcodeData(module, get_debug_info_data(), + block_offset, block_length); + } else { + const DWARFDataExtractor &debug_loc_data = get_debug_loc_data(); + const dw_offset_t debug_loc_offset = form_value.Unsigned(); + + size_t loc_list_length = DWARFExpression::LocationListSize( + die.GetCU(), debug_loc_data, debug_loc_offset); + if (loc_list_length > 0) { + location.CopyOpcodeData(module, debug_loc_data, + debug_loc_offset, loc_list_length); + assert(func_low_pc != LLDB_INVALID_ADDRESS); + location.SetLocationListSlide( + func_low_pc - + attributes.CompileUnitAtIndex(i)->GetBaseAddress()); + } } - - // DWARF doesn't specify if a DW_TAG_variable is a local, global - // or static variable, so we have to do a little digging by - // looking at the location of a variable to see if it contains - // a DW_OP_addr opcode _somewhere_ in the definition. I say - // somewhere because clang likes to combine small global variables - // into the same symbol and have locations like: - // DW_OP_addr(0x1000), DW_OP_constu(2), DW_OP_plus - // So if we don't have a DW_TAG_formal_parameter, we can look at - // the location to see if it contains a DW_OP_addr opcode, and - // then we can correctly classify our variables. - if (tag == DW_TAG_formal_parameter) - scope = eValueTypeVariableArgument; - else - { - bool op_error = false; - // Check if the location has a DW_OP_addr with any address value... - lldb::addr_t location_DW_OP_addr = LLDB_INVALID_ADDRESS; - if (!location_is_const_value_data) - { - location_DW_OP_addr = location.GetLocation_DW_OP_addr (0, op_error); - if (op_error) - { - StreamString strm; - location.DumpLocationForAddress (&strm, eDescriptionLevelFull, 0, 0, NULL); - GetObjectFile()->GetModule()->ReportError ("0x%8.8x: %s has an invalid location: %s", die.GetOffset(), die.GetTagAsCString(), strm.GetString().c_str()); - } - } - SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile(); - - if (location_DW_OP_addr != LLDB_INVALID_ADDRESS) - { - if (is_external) - scope = eValueTypeVariableGlobal; - else - scope = eValueTypeVariableStatic; - - if (debug_map_symfile) - { - // When leaving the DWARF in the .o files on darwin, - // when we have a global variable that wasn't initialized, - // the .o file might not have allocated a virtual - // address for the global variable. In this case it will - // have created a symbol for the global variable - // that is undefined/data and external and the value will - // be the byte size of the variable. When we do the - // address map in SymbolFileDWARFDebugMap we rely on - // having an address, we need to do some magic here - // so we can get the correct address for our global - // variable. The address for all of these entries - // will be zero, and there will be an undefined symbol - // in this object file, and the executable will have - // a matching symbol with a good address. So here we - // dig up the correct address and replace it in the - // location for the variable, and set the variable's - // symbol context scope to be that of the main executable - // so the file address will resolve correctly. - bool linked_oso_file_addr = false; - if (is_external && location_DW_OP_addr == 0) - { - // we have a possible uninitialized extern global - ConstString const_name(mangled ? mangled : name); - ObjectFile *debug_map_objfile = debug_map_symfile->GetObjectFile(); - if (debug_map_objfile) - { - Symtab *debug_map_symtab = debug_map_objfile->GetSymtab(); - if (debug_map_symtab) - { - Symbol *exe_symbol = debug_map_symtab->FindFirstSymbolWithNameAndType (const_name, - eSymbolTypeData, - Symtab::eDebugYes, - Symtab::eVisibilityExtern); - if (exe_symbol) - { - if (exe_symbol->ValueIsAddress()) - { - const addr_t exe_file_addr = exe_symbol->GetAddressRef().GetFileAddress(); - if (exe_file_addr != LLDB_INVALID_ADDRESS) - { - if (location.Update_DW_OP_addr (exe_file_addr)) - { - linked_oso_file_addr = true; - symbol_context_scope = exe_symbol; - } - } - } - } - } - } - } - - if (!linked_oso_file_addr) - { - // The DW_OP_addr is not zero, but it contains a .o file address which - // needs to be linked up correctly. - const lldb::addr_t exe_file_addr = debug_map_symfile->LinkOSOFileAddress(this, location_DW_OP_addr); - if (exe_file_addr != LLDB_INVALID_ADDRESS) - { - // Update the file address for this variable - location.Update_DW_OP_addr (exe_file_addr); - } - else - { - // Variable didn't make it into the final executable - return var_sp; - } - } - } - } - else - { - if (location_is_const_value_data) - scope = eValueTypeVariableStatic; - else - { - scope = eValueTypeVariableLocal; - if (debug_map_symfile) - { - // We need to check for TLS addresses that we need to fixup - if (location.ContainsThreadLocalStorage()) - { - location.LinkThreadLocalStorage( - debug_map_symfile->GetObjectFile()->GetModule(), - [this, debug_map_symfile](lldb::addr_t unlinked_file_addr) -> lldb::addr_t { - return debug_map_symfile->LinkOSOFileAddress(this, unlinked_file_addr); - }); - scope = eValueTypeVariableThreadLocal; - } - } - } - } + } break; + case DW_AT_specification: + spec_die = GetDIE(DIERef(form_value)); + break; + 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(), + 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 + // dwarf spec is a bit ambiguous about what is the expected + // behavior in + // case the enclosing block have a non coninious address range and + // the + // DW_AT_start_scope entry have a form constant. + GetObjectFile()->GetModule()->ReportWarning( + "0x%8.8" PRIx64 + ": DW_AT_start_scope has unsupported form type (0x%x)\n", + die.GetID(), form_value.Form()); } - if (symbol_context_scope == NULL) - { - switch (parent_tag) - { - case DW_TAG_subprogram: - case DW_TAG_inlined_subroutine: - case DW_TAG_lexical_block: - if (sc.function) - { - symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID()); - if (symbol_context_scope == NULL) - symbol_context_scope = sc.function; + scope_ranges.Sort(); + scope_ranges.CombineConsecutiveRanges(); + } break; + case DW_AT_artificial: + is_artificial = form_value.Boolean(); + break; + case DW_AT_accessibility: + break; // accessibility = + // DW_ACCESS_to_AccessType(form_value.Unsigned()); break; + case DW_AT_declaration: + case DW_AT_description: + case DW_AT_endianity: + case DW_AT_segment: + case DW_AT_visibility: + default: + case DW_AT_abstract_origin: + case DW_AT_sibling: + break; + } + } + } + + const DWARFDIE parent_context_die = GetDeclContextDIEContainingDIE(die); + const dw_tag_t parent_tag = die.GetParent().Tag(); + bool is_static_member = + parent_tag == DW_TAG_compile_unit && + (parent_context_die.Tag() == DW_TAG_class_type || + parent_context_die.Tag() == DW_TAG_structure_type); + + ValueType scope = eValueTypeInvalid; + + const DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die); + SymbolContextScope *symbol_context_scope = NULL; + + bool has_explicit_mangled = mangled != nullptr; + if (!mangled) { + // LLDB relies on the mangled name (DW_TAG_linkage_name or + // DW_AT_MIPS_linkage_name) to + // generate fully qualified names of global variables with commands like + // "frame var j". + // For example, if j were an int variable holding a value 4 and declared + // in a namespace + // B which in turn is contained in a namespace A, the command "frame var + // j" returns + // "(int) A::B::j = 4". If the compiler does not emit a linkage name, we + // should be able + // to generate a fully qualified name from the declaration context. + if (parent_tag == DW_TAG_compile_unit && + Language::LanguageIsCPlusPlus(die.GetLanguage())) { + DWARFDeclContext decl_ctx; + + die.GetDWARFDeclContext(decl_ctx); + mangled = decl_ctx.GetQualifiedNameAsConstString().GetCString(); + } + } + + if (tag == DW_TAG_formal_parameter) + scope = eValueTypeVariableArgument; + else { + // DWARF doesn't specify if a DW_TAG_variable is a local, global + // or static variable, so we have to do a little digging: + // 1) DW_AT_linkage_name implies static lifetime (but may be missing) + // 2) An empty DW_AT_location is an (optimized-out) static lifetime var. + // 3) DW_AT_location containing a DW_OP_addr implies static lifetime. + // Clang likes to combine small global variables into the same symbol + // with locations like: DW_OP_addr(0x1000), DW_OP_constu(2), DW_OP_plus + // so we need to look through the whole expression. + bool is_static_lifetime = + has_explicit_mangled || + (has_explicit_location && !location.IsValid()); + // Check if the location has a DW_OP_addr with any address value... + lldb::addr_t location_DW_OP_addr = LLDB_INVALID_ADDRESS; + if (!location_is_const_value_data) { + bool op_error = false; + location_DW_OP_addr = location.GetLocation_DW_OP_addr(0, op_error); + if (op_error) { + StreamString strm; + location.DumpLocationForAddress(&strm, eDescriptionLevelFull, 0, 0, + NULL); + GetObjectFile()->GetModule()->ReportError( + "0x%8.8x: %s has an invalid location: %s", die.GetOffset(), + die.GetTagAsCString(), strm.GetData()); + } + if (location_DW_OP_addr != LLDB_INVALID_ADDRESS) + is_static_lifetime = true; + } + SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile(); + + if (is_static_lifetime) { + if (is_external) + scope = eValueTypeVariableGlobal; + else + scope = eValueTypeVariableStatic; + + if (debug_map_symfile) { + // When leaving the DWARF in the .o files on darwin, + // when we have a global variable that wasn't initialized, + // the .o file might not have allocated a virtual + // address for the global variable. In this case it will + // have created a symbol for the global variable + // that is undefined/data and external and the value will + // be the byte size of the variable. When we do the + // address map in SymbolFileDWARFDebugMap we rely on + // having an address, we need to do some magic here + // so we can get the correct address for our global + // variable. The address for all of these entries + // will be zero, and there will be an undefined symbol + // in this object file, and the executable will have + // a matching symbol with a good address. So here we + // dig up the correct address and replace it in the + // location for the variable, and set the variable's + // symbol context scope to be that of the main executable + // so the file address will resolve correctly. + bool linked_oso_file_addr = false; + if (is_external && location_DW_OP_addr == 0) { + // we have a possible uninitialized extern global + ConstString const_name(mangled ? mangled : name); + ObjectFile *debug_map_objfile = + debug_map_symfile->GetObjectFile(); + if (debug_map_objfile) { + Symtab *debug_map_symtab = debug_map_objfile->GetSymtab(); + if (debug_map_symtab) { + Symbol *exe_symbol = + debug_map_symtab->FindFirstSymbolWithNameAndType( + const_name, eSymbolTypeData, Symtab::eDebugYes, + Symtab::eVisibilityExtern); + if (exe_symbol) { + if (exe_symbol->ValueIsAddress()) { + const addr_t exe_file_addr = + exe_symbol->GetAddressRef().GetFileAddress(); + if (exe_file_addr != LLDB_INVALID_ADDRESS) { + if (location.Update_DW_OP_addr(exe_file_addr)) { + linked_oso_file_addr = true; + symbol_context_scope = exe_symbol; + } + } } - break; - - default: - symbol_context_scope = sc.comp_unit; - break; + } } + } } - if (symbol_context_scope) - { - SymbolFileTypeSP type_sp(new SymbolFileType(*this, DIERef(type_die_form).GetUID(this))); - - if (const_value.Form() && type_sp && type_sp->GetType()) - location.CopyOpcodeData(const_value.Unsigned(), type_sp->GetType()->GetByteSize(), die.GetCU()->GetAddressByteSize()); - - var_sp.reset (new Variable (die.GetID(), - name, - mangled, - type_sp, - scope, - symbol_context_scope, - scope_ranges, - &decl, - location, - is_external, - is_artificial, - is_static_member)); - - var_sp->SetLocationIsConstantValueData (location_is_const_value_data); - } - else - { - // Not ready to parse this variable yet. It might be a global - // or static variable that is in a function scope and the function - // in the symbol context wasn't filled in yet + if (!linked_oso_file_addr) { + // The DW_OP_addr is not zero, but it contains a .o file address + // which + // needs to be linked up correctly. + const lldb::addr_t exe_file_addr = + debug_map_symfile->LinkOSOFileAddress(this, + location_DW_OP_addr); + if (exe_file_addr != LLDB_INVALID_ADDRESS) { + // Update the file address for this variable + location.Update_DW_OP_addr(exe_file_addr); + } else { + // Variable didn't make it into the final executable return var_sp; + } + } + } + } else { + if (location_is_const_value_data) + scope = eValueTypeVariableStatic; + else { + scope = eValueTypeVariableLocal; + if (debug_map_symfile) { + // We need to check for TLS addresses that we need to fixup + if (location.ContainsThreadLocalStorage()) { + location.LinkThreadLocalStorage( + debug_map_symfile->GetObjectFile()->GetModule(), + [this, debug_map_symfile]( + lldb::addr_t unlinked_file_addr) -> lldb::addr_t { + return debug_map_symfile->LinkOSOFileAddress( + this, unlinked_file_addr); + }); + scope = eValueTypeVariableThreadLocal; + } } + } + } + } + + if (symbol_context_scope == NULL) { + switch (parent_tag) { + case DW_TAG_subprogram: + case DW_TAG_inlined_subroutine: + case DW_TAG_lexical_block: + if (sc.function) { + symbol_context_scope = sc.function->GetBlock(true).FindBlockByID( + sc_parent_die.GetID()); + if (symbol_context_scope == NULL) + symbol_context_scope = sc.function; + } + break; + + default: + symbol_context_scope = sc.comp_unit; + break; } - // Cache var_sp even if NULL (the variable was just a specification or - // was missing vital information to be able to be displayed in the debugger - // (missing location due to optimization, etc)) so we don't re-parse - // this DIE over and over later... - GetDIEToVariable()[die.GetDIE()] = var_sp; - if (spec_die) - GetDIEToVariable()[spec_die.GetDIE()] = var_sp; + } + + if (symbol_context_scope) { + SymbolFileTypeSP type_sp( + new SymbolFileType(*this, DIERef(type_die_form).GetUID(this))); + + if (const_value.Form() && type_sp && type_sp->GetType()) + location.CopyOpcodeData(const_value.Unsigned(), + type_sp->GetType()->GetByteSize(), + die.GetCU()->GetAddressByteSize()); + + var_sp.reset(new Variable(die.GetID(), name, mangled, type_sp, scope, + symbol_context_scope, scope_ranges, &decl, + location, is_external, is_artificial, + is_static_member)); + + var_sp->SetLocationIsConstantValueData(location_is_const_value_data); + } else { + // Not ready to parse this variable yet. It might be a global + // or static variable that is in a function scope and the function + // in the symbol context wasn't filled in yet + return var_sp; + } } - return var_sp; + // Cache var_sp even if NULL (the variable was just a specification or + // was missing vital information to be able to be displayed in the debugger + // (missing location due to optimization, etc)) so we don't re-parse + // this DIE over and over later... + GetDIEToVariable()[die.GetDIE()] = var_sp; + if (spec_die) + GetDIEToVariable()[spec_die.GetDIE()] = var_sp; + } + return var_sp; } +DWARFDIE +SymbolFileDWARF::FindBlockContainingSpecification( + const DIERef &func_die_ref, dw_offset_t spec_block_die_offset) { + // Give the concrete function die specified by "func_die_offset", find the + // concrete block whose DW_AT_specification or DW_AT_abstract_origin points + // to "spec_block_die_offset" + return FindBlockContainingSpecification(DebugInfo()->GetDIE(func_die_ref), + spec_block_die_offset); +} DWARFDIE -SymbolFileDWARF::FindBlockContainingSpecification (const DIERef& func_die_ref, - dw_offset_t spec_block_die_offset) -{ - // Give the concrete function die specified by "func_die_offset", find the +SymbolFileDWARF::FindBlockContainingSpecification( + const DWARFDIE &die, dw_offset_t spec_block_die_offset) { + if (die) { + switch (die.Tag()) { + case DW_TAG_subprogram: + case DW_TAG_inlined_subroutine: + case DW_TAG_lexical_block: { + if (die.GetAttributeValueAsReference( + DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset) + return die; + + if (die.GetAttributeValueAsReference(DW_AT_abstract_origin, + DW_INVALID_OFFSET) == + spec_block_die_offset) + return die; + } break; + } + + // Give the concrete function die specified by "func_die_offset", find the // concrete block whose DW_AT_specification or DW_AT_abstract_origin points // to "spec_block_die_offset" - return FindBlockContainingSpecification (DebugInfo()->GetDIE (func_die_ref), spec_block_die_offset); + for (DWARFDIE child_die = die.GetFirstChild(); child_die; + child_die = child_die.GetSibling()) { + DWARFDIE result_die = + FindBlockContainingSpecification(child_die, spec_block_die_offset); + if (result_die) + return result_die; + } + } + + return DWARFDIE(); } +size_t SymbolFileDWARF::ParseVariables(const SymbolContext &sc, + const DWARFDIE &orig_die, + const lldb::addr_t func_low_pc, + bool parse_siblings, bool parse_children, + VariableList *cc_variable_list) { + if (!orig_die) + return 0; -DWARFDIE -SymbolFileDWARF::FindBlockContainingSpecification(const DWARFDIE &die, - dw_offset_t spec_block_die_offset) -{ - if (die) - { - switch (die.Tag()) - { - case DW_TAG_subprogram: - case DW_TAG_inlined_subroutine: - case DW_TAG_lexical_block: - { - if (die.GetAttributeValueAsReference (DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset) - return die; + VariableListSP variable_list_sp; + + size_t vars_added = 0; + DWARFDIE die = orig_die; + while (die) { + dw_tag_t tag = die.Tag(); + + // Check to see if we have already parsed this variable or constant? + VariableSP var_sp = GetDIEToVariable()[die.GetDIE()]; + if (var_sp) { + if (cc_variable_list) + cc_variable_list->AddVariableIfUnique(var_sp); + } else { + // We haven't already parsed it, lets do that now. + if ((tag == DW_TAG_variable) || (tag == DW_TAG_constant) || + (tag == DW_TAG_formal_parameter && sc.function)) { + if (variable_list_sp.get() == NULL) { + DWARFDIE sc_parent_die = GetParentSymbolContextDIE(orig_die); + dw_tag_t parent_tag = sc_parent_die.Tag(); + switch (parent_tag) { + case DW_TAG_compile_unit: + if (sc.comp_unit != NULL) { + variable_list_sp = sc.comp_unit->GetVariableList(false); + if (variable_list_sp.get() == NULL) { + variable_list_sp.reset(new VariableList()); + sc.comp_unit->SetVariableList(variable_list_sp); + } + } else { + GetObjectFile()->GetModule()->ReportError( + "parent 0x%8.8" PRIx64 " %s with no valid compile unit in " + "symbol context for 0x%8.8" PRIx64 + " %s.\n", + sc_parent_die.GetID(), sc_parent_die.GetTagAsCString(), + orig_die.GetID(), orig_die.GetTagAsCString()); + } + break; - if (die.GetAttributeValueAsReference (DW_AT_abstract_origin, DW_INVALID_OFFSET) == spec_block_die_offset) - return die; + case DW_TAG_subprogram: + case DW_TAG_inlined_subroutine: + case DW_TAG_lexical_block: + if (sc.function != NULL) { + // Check to see if we already have parsed the variables for the + // given scope + + Block *block = sc.function->GetBlock(true).FindBlockByID( + sc_parent_die.GetID()); + if (block == NULL) { + // This must be a specification or abstract origin with + // a concrete block counterpart in the current function. We need + // to find the concrete block so we can correctly add the + // variable to it + const DWARFDIE concrete_block_die = + FindBlockContainingSpecification( + DIERef(sc.function->GetID(), this), + sc_parent_die.GetOffset()); + if (concrete_block_die) + block = sc.function->GetBlock(true).FindBlockByID( + concrete_block_die.GetID()); + } + + if (block != NULL) { + const bool can_create = false; + variable_list_sp = block->GetBlockVariableList(can_create); + if (variable_list_sp.get() == NULL) { + variable_list_sp.reset(new VariableList()); + block->SetVariableList(variable_list_sp); + } + } } break; - } - // Give the concrete function die specified by "func_die_offset", find the - // concrete block whose DW_AT_specification or DW_AT_abstract_origin points - // to "spec_block_die_offset" - for (DWARFDIE child_die = die.GetFirstChild(); child_die; child_die = child_die.GetSibling()) - { - DWARFDIE result_die = FindBlockContainingSpecification (child_die, spec_block_die_offset); - if (result_die) - return result_die; + default: + GetObjectFile()->GetModule()->ReportError( + "didn't find appropriate parent DIE for variable list for " + "0x%8.8" PRIx64 " %s.\n", + orig_die.GetID(), orig_die.GetTagAsCString()); + break; + } } - } - - return DWARFDIE(); -} - -size_t -SymbolFileDWARF::ParseVariables (const SymbolContext& sc, - const DWARFDIE &orig_die, - const lldb::addr_t func_low_pc, - bool parse_siblings, - bool parse_children, - VariableList* cc_variable_list) -{ - if (!orig_die) - return 0; - VariableListSP variable_list_sp; - - size_t vars_added = 0; - DWARFDIE die = orig_die; - while (die) - { - dw_tag_t tag = die.Tag(); - - // Check to see if we have already parsed this variable or constant? - VariableSP var_sp = GetDIEToVariable()[die.GetDIE()]; - if (var_sp) - { + if (variable_list_sp) { + VariableSP var_sp(ParseVariableDIE(sc, die, func_low_pc)); + if (var_sp) { + variable_list_sp->AddVariableIfUnique(var_sp); if (cc_variable_list) - cc_variable_list->AddVariableIfUnique (var_sp); + cc_variable_list->AddVariableIfUnique(var_sp); + ++vars_added; + } } - else - { - // We haven't already parsed it, lets do that now. - if ((tag == DW_TAG_variable) || - (tag == DW_TAG_constant) || - (tag == DW_TAG_formal_parameter && sc.function)) - { - if (variable_list_sp.get() == NULL) - { - DWARFDIE sc_parent_die = GetParentSymbolContextDIE(orig_die); - dw_tag_t parent_tag = sc_parent_die.Tag(); - switch (parent_tag) - { - case DW_TAG_compile_unit: - if (sc.comp_unit != NULL) - { - variable_list_sp = sc.comp_unit->GetVariableList(false); - if (variable_list_sp.get() == NULL) - { - variable_list_sp.reset(new VariableList()); - sc.comp_unit->SetVariableList(variable_list_sp); - } - } - else - { - GetObjectFile()->GetModule()->ReportError ("parent 0x%8.8" PRIx64 " %s with no valid compile unit in symbol context for 0x%8.8" PRIx64 " %s.\n", - sc_parent_die.GetID(), - sc_parent_die.GetTagAsCString(), - orig_die.GetID(), - orig_die.GetTagAsCString()); - } - break; - - case DW_TAG_subprogram: - case DW_TAG_inlined_subroutine: - case DW_TAG_lexical_block: - if (sc.function != NULL) - { - // Check to see if we already have parsed the variables for the given scope - - Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID()); - if (block == NULL) - { - // This must be a specification or abstract origin with - // a concrete block counterpart in the current function. We need - // to find the concrete block so we can correctly add the - // variable to it - const DWARFDIE concrete_block_die = FindBlockContainingSpecification (DIERef(sc.function->GetID(), this), - sc_parent_die.GetOffset()); - if (concrete_block_die) - block = sc.function->GetBlock(true).FindBlockByID(concrete_block_die.GetID()); - } - - if (block != NULL) - { - const bool can_create = false; - variable_list_sp = block->GetBlockVariableList (can_create); - if (variable_list_sp.get() == NULL) - { - variable_list_sp.reset(new VariableList()); - block->SetVariableList(variable_list_sp); - } - } - } - break; - - default: - GetObjectFile()->GetModule()->ReportError ("didn't find appropriate parent DIE for variable list for 0x%8.8" PRIx64 " %s.\n", - orig_die.GetID(), - orig_die.GetTagAsCString()); - break; - } - } - - if (variable_list_sp) - { - VariableSP var_sp (ParseVariableDIE(sc, die, func_low_pc)); - if (var_sp) - { - variable_list_sp->AddVariableIfUnique (var_sp); - if (cc_variable_list) - cc_variable_list->AddVariableIfUnique (var_sp); - ++vars_added; - } - } - } - } - - bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram); + } + } - if (!skip_children && parse_children && die.HasChildren()) - { - vars_added += ParseVariables(sc, die.GetFirstChild(), func_low_pc, true, true, cc_variable_list); - } + bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram); - if (parse_siblings) - die = die.GetSibling(); - else - die.Clear(); + if (!skip_children && parse_children && die.HasChildren()) { + vars_added += ParseVariables(sc, die.GetFirstChild(), func_low_pc, true, + true, cc_variable_list); } - return vars_added; + + if (parse_siblings) + die = die.GetSibling(); + else + die.Clear(); + } + return vars_added; } //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ -ConstString -SymbolFileDWARF::GetPluginName() -{ - return GetPluginNameStatic(); +ConstString SymbolFileDWARF::GetPluginName() { return GetPluginNameStatic(); } + +uint32_t SymbolFileDWARF::GetPluginVersion() { return 1; } + +void SymbolFileDWARF::DumpIndexes() { + StreamFile s(stdout, false); + + s.Printf( + "DWARF index for (%s) '%s':", + GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(), + GetObjectFile()->GetFileSpec().GetPath().c_str()); + s.Printf("\nFunction basenames:\n"); + m_function_basename_index.Dump(&s); + s.Printf("\nFunction fullnames:\n"); + m_function_fullname_index.Dump(&s); + s.Printf("\nFunction methods:\n"); + m_function_method_index.Dump(&s); + s.Printf("\nFunction selectors:\n"); + m_function_selector_index.Dump(&s); + s.Printf("\nObjective C class selectors:\n"); + m_objc_class_selectors_index.Dump(&s); + s.Printf("\nGlobals and statics:\n"); + m_global_index.Dump(&s); + s.Printf("\nTypes:\n"); + m_type_index.Dump(&s); + s.Printf("\nNamespaces:\n"); + m_namespace_index.Dump(&s); } -uint32_t -SymbolFileDWARF::GetPluginVersion() -{ - return 1; -} - -void -SymbolFileDWARF::DumpIndexes () -{ - StreamFile s(stdout, false); - - s.Printf ("DWARF index for (%s) '%s':", - GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(), - GetObjectFile()->GetFileSpec().GetPath().c_str()); - s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s); - s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s); - s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s); - s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s); - s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s); - s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s); - s.Printf("\nTypes:\n"); m_type_index.Dump (&s); - s.Printf("\nNamespaces:\n"); m_namespace_index.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()); - if (module_sp) - { - SymbolVendor *sym_vendor = module_sp->GetSymbolVendor(); - if (sym_vendor) - m_debug_map_symfile = (SymbolFileDWARFDebugMap *)sym_vendor->GetSymbolFile(); - } +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()); + if (module_sp) { + SymbolVendor *sym_vendor = module_sp->GetSymbolVendor(); + if (sym_vendor) + m_debug_map_symfile = + (SymbolFileDWARFDebugMap *)sym_vendor->GetSymbolFile(); } - return m_debug_map_symfile; + } + return m_debug_map_symfile; } DWARFExpression::LocationListFormat -SymbolFileDWARF::GetLocationListFormat() const -{ - return DWARFExpression::RegularLocationList; +SymbolFileDWARF::GetLocationListFormat() const { + return DWARFExpression::RegularLocationList; } diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index 865e58962700..52937697500f 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -22,20 +22,20 @@ // Other libraries and framework includes #include "llvm/ADT/DenseMap.h" -#include "lldb/lldb-private.h" #include "lldb/Core/ConstString.h" -#include "lldb/Core/dwarf.h" #include "lldb/Core/Flags.h" #include "lldb/Core/RangeMap.h" #include "lldb/Core/UniqueCStringMap.h" +#include "lldb/Core/dwarf.h" #include "lldb/Expression/DWARFExpression.h" #include "lldb/Symbol/DebugMacros.h" -#include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/SymbolContext.h" +#include "lldb/Symbol/SymbolFile.h" +#include "lldb/lldb-private.h" // Project includes -#include "DWARFDefines.h" #include "DWARFDataExtractor.h" +#include "DWARFDefines.h" #include "HashedNameToDIE.h" #include "NameToDIE.h" #include "UniqueDWARFASTType.h" @@ -60,543 +60,465 @@ class DWARFFormValue; class SymbolFileDWARFDebugMap; class SymbolFileDWARFDwo; -#define DIE_IS_BEING_PARSED ((lldb_private::Type*)1) +#define DIE_IS_BEING_PARSED ((lldb_private::Type *)1) -class SymbolFileDWARF : public lldb_private::SymbolFile, public lldb_private::UserID -{ +class SymbolFileDWARF : public lldb_private::SymbolFile, + public lldb_private::UserID { public: - friend class SymbolFileDWARFDebugMap; - friend class SymbolFileDWARFDwo; - friend class DebugMapModule; - friend struct DIERef; - friend class DWARFCompileUnit; - friend class DWARFDIE; - friend class DWARFASTParserClang; - friend class DWARFASTParserGo; - friend class DWARFASTParserJava; + friend class SymbolFileDWARFDebugMap; + friend class SymbolFileDWARFDwo; + friend class DebugMapModule; + friend struct DIERef; + friend class DWARFCompileUnit; + friend class DWARFDIE; + friend class DWARFASTParserClang; + friend class DWARFASTParserGo; + friend class DWARFASTParserJava; + friend class DWARFASTParserOCaml; + + //------------------------------------------------------------------ + // Static Functions + //------------------------------------------------------------------ + static void Initialize(); + + static void Terminate(); + + static void DebuggerInitialize(lldb_private::Debugger &debugger); + + static lldb_private::ConstString GetPluginNameStatic(); + + static const char *GetPluginDescriptionStatic(); + + static lldb_private::SymbolFile * + CreateInstance(lldb_private::ObjectFile *obj_file); + + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ - //------------------------------------------------------------------ - // Static Functions - //------------------------------------------------------------------ - static void - Initialize(); + SymbolFileDWARF(lldb_private::ObjectFile *ofile); - static void - Terminate(); + ~SymbolFileDWARF() override; - static void - DebuggerInitialize(lldb_private::Debugger &debugger); + uint32_t CalculateAbilities() override; - static lldb_private::ConstString - GetPluginNameStatic(); + void InitializeObject() override; - static const char * - GetPluginDescriptionStatic(); + //------------------------------------------------------------------ + // Compile Unit function calls + //------------------------------------------------------------------ - static lldb_private::SymbolFile* - CreateInstance (lldb_private::ObjectFile* obj_file); + uint32_t GetNumCompileUnits() override; - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ + lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override; - SymbolFileDWARF(lldb_private::ObjectFile* ofile); + lldb::LanguageType + ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) override; - ~SymbolFileDWARF() override; + size_t + ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc) override; - uint32_t - CalculateAbilities () override; + bool + ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc) override; - void - InitializeObject() override; + bool + ParseCompileUnitDebugMacros(const lldb_private::SymbolContext &sc) override; - //------------------------------------------------------------------ - // Compile Unit function calls - //------------------------------------------------------------------ + bool ParseCompileUnitSupportFiles( + const lldb_private::SymbolContext &sc, + lldb_private::FileSpecList &support_files) override; - uint32_t - GetNumCompileUnits() override; + bool + ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc) override; - lldb::CompUnitSP - ParseCompileUnitAtIndex(uint32_t index) override; + bool ParseImportedModules( + const lldb_private::SymbolContext &sc, + std::vector<lldb_private::ConstString> &imported_modules) override; - lldb::LanguageType - ParseCompileUnitLanguage (const lldb_private::SymbolContext& sc) override; + size_t ParseFunctionBlocks(const lldb_private::SymbolContext &sc) override; - size_t - ParseCompileUnitFunctions (const lldb_private::SymbolContext& sc) override; + size_t ParseTypes(const lldb_private::SymbolContext &sc) override; - bool - ParseCompileUnitLineTable (const lldb_private::SymbolContext& sc) override; + size_t + ParseVariablesForContext(const lldb_private::SymbolContext &sc) override; - bool - ParseCompileUnitDebugMacros (const lldb_private::SymbolContext& sc) override; + lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override; - bool - ParseCompileUnitSupportFiles (const lldb_private::SymbolContext& sc, - lldb_private::FileSpecList& support_files) override; + bool CompleteType(lldb_private::CompilerType &compiler_type) override; - bool - ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc) override; + lldb_private::Type *ResolveType(const DWARFDIE &die, + bool assert_not_being_parsed = true, + bool resolve_function_context = false); - bool - ParseImportedModules(const lldb_private::SymbolContext &sc, - std::vector<lldb_private::ConstString> &imported_modules) override; + SymbolFileDWARF *GetDWARFForUID(lldb::user_id_t uid); - size_t - ParseFunctionBlocks (const lldb_private::SymbolContext& sc) override; - - size_t - ParseTypes (const lldb_private::SymbolContext& sc) override; - - size_t - ParseVariablesForContext (const lldb_private::SymbolContext& sc) override; + DWARFDIE + GetDIEFromUID(lldb::user_id_t uid); - lldb_private::Type * - ResolveTypeUID(lldb::user_id_t type_uid) override; + lldb_private::CompilerDecl GetDeclForUID(lldb::user_id_t uid) override; - bool - CompleteType (lldb_private::CompilerType& compiler_type) override; + lldb_private::CompilerDeclContext + GetDeclContextForUID(lldb::user_id_t uid) override; - lldb_private::Type * - ResolveType (const DWARFDIE &die, - bool assert_not_being_parsed = true, - bool resolve_function_context = false); + lldb_private::CompilerDeclContext + GetDeclContextContainingUID(lldb::user_id_t uid) override; - SymbolFileDWARF * - GetDWARFForUID (lldb::user_id_t uid); + void + ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override; - DWARFDIE - GetDIEFromUID (lldb::user_id_t uid); + uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr, + uint32_t resolve_scope, + lldb_private::SymbolContext &sc) override; - lldb_private::CompilerDecl - GetDeclForUID (lldb::user_id_t uid) override; + uint32_t + ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line, + bool check_inlines, uint32_t resolve_scope, + lldb_private::SymbolContextList &sc_list) override; - lldb_private::CompilerDeclContext - GetDeclContextForUID (lldb::user_id_t uid) override; + uint32_t + FindGlobalVariables(const lldb_private::ConstString &name, + const lldb_private::CompilerDeclContext *parent_decl_ctx, + bool append, uint32_t max_matches, + lldb_private::VariableList &variables) override; - lldb_private::CompilerDeclContext - GetDeclContextContainingUID (lldb::user_id_t uid) override; - - void - ParseDeclsForContext (lldb_private::CompilerDeclContext decl_ctx) override; - + uint32_t FindGlobalVariables(const lldb_private::RegularExpression ®ex, + bool append, uint32_t max_matches, + lldb_private::VariableList &variables) override; - uint32_t - ResolveSymbolContext (const lldb_private::Address& so_addr, - uint32_t resolve_scope, - lldb_private::SymbolContext& sc) override; + 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; - uint32_t - ResolveSymbolContext (const lldb_private::FileSpec& file_spec, - uint32_t line, - bool check_inlines, - uint32_t resolve_scope, - 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 - FindGlobalVariables (const lldb_private::ConstString &name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, - bool append, - uint32_t max_matches, - lldb_private::VariableList& variables) override; + void GetMangledNamesForFunction( + const std::string &scope_qualified_name, + std::vector<lldb_private::ConstString> &mangled_names) override; - uint32_t - FindGlobalVariables (const lldb_private::RegularExpression& regex, - bool append, - uint32_t max_matches, - lldb_private::VariableList& variables) override; + uint32_t + FindTypes(const lldb_private::SymbolContext &sc, + 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; - 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; - - uint32_t - FindFunctions (const lldb_private::RegularExpression& regex, - bool include_inlines, - bool append, - lldb_private::SymbolContextList& sc_list) override; - - void - GetMangledNamesForFunction (const std::string &scope_qualified_name, - std::vector<lldb_private::ConstString> &mangled_names) override; - - uint32_t - FindTypes (const lldb_private::SymbolContext& sc, - 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; - - size_t - FindTypes (const std::vector<lldb_private::CompilerContext> &context, - bool append, - lldb_private::TypeMap& types) override; + size_t FindTypes(const std::vector<lldb_private::CompilerContext> &context, + bool append, lldb_private::TypeMap &types) override; - lldb_private::TypeList * - GetTypeList () override; + lldb_private::TypeList *GetTypeList() override; - size_t - GetTypes (lldb_private::SymbolContextScope *sc_scope, - uint32_t type_mask, - lldb_private::TypeList &type_list) override; + size_t GetTypes(lldb_private::SymbolContextScope *sc_scope, + uint32_t 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; + 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; - //------------------------------------------------------------------ - // PluginInterface protocol - //------------------------------------------------------------------ - lldb_private::ConstString - GetPluginName() override; - - uint32_t - GetPluginVersion() override; - - const lldb_private::DWARFDataExtractor& get_debug_abbrev_data (); - 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 (); - const lldb_private::DWARFDataExtractor& get_debug_line_data (); - const lldb_private::DWARFDataExtractor& get_debug_macro_data (); - const lldb_private::DWARFDataExtractor& get_debug_loc_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_apple_names_data (); - const lldb_private::DWARFDataExtractor& get_apple_types_data (); - const lldb_private::DWARFDataExtractor& get_apple_namespaces_data (); - const lldb_private::DWARFDataExtractor& get_apple_objc_data (); - - - DWARFDebugAbbrev* - DebugAbbrev(); - - const DWARFDebugAbbrev* - DebugAbbrev() const; - - DWARFDebugInfo* - DebugInfo(); - - const DWARFDebugInfo* - DebugInfo() const; - - DWARFDebugRanges* - DebugRanges(); - - const DWARFDebugRanges* - DebugRanges() const; - - static bool - SupportedVersion(uint16_t version); + //------------------------------------------------------------------ + // PluginInterface protocol + //------------------------------------------------------------------ + lldb_private::ConstString GetPluginName() override; - DWARFDIE - GetDeclContextDIEContainingDIE (const DWARFDIE &die); + uint32_t GetPluginVersion() override; - bool - HasForwardDeclForClangType (const lldb_private::CompilerType &compiler_type); + const lldb_private::DWARFDataExtractor &get_debug_abbrev_data(); + 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(); + const lldb_private::DWARFDataExtractor &get_debug_line_data(); + const lldb_private::DWARFDataExtractor &get_debug_macro_data(); + const lldb_private::DWARFDataExtractor &get_debug_loc_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_apple_names_data(); + const lldb_private::DWARFDataExtractor &get_apple_types_data(); + const lldb_private::DWARFDataExtractor &get_apple_namespaces_data(); + const lldb_private::DWARFDataExtractor &get_apple_objc_data(); - lldb_private::CompileUnit* - GetCompUnitForDWARFCompUnit(DWARFCompileUnit* dwarf_cu, - uint32_t cu_idx = UINT32_MAX); + DWARFDebugAbbrev *DebugAbbrev(); - size_t - GetObjCMethodDIEOffsets (lldb_private::ConstString class_name, - DIEArray &method_die_offsets); + const DWARFDebugAbbrev *DebugAbbrev() const; - bool - Supports_DW_AT_APPLE_objc_complete_type (DWARFCompileUnit *cu); + DWARFDebugInfo *DebugInfo(); - lldb_private::DebugMacrosSP - ParseDebugMacros(lldb::offset_t *offset); + const DWARFDebugInfo *DebugInfo() const; - static DWARFDIE - GetParentSymbolContextDIE(const DWARFDIE &die); + DWARFDebugRanges *DebugRanges(); - virtual lldb::CompUnitSP - ParseCompileUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx); + const DWARFDebugRanges *DebugRanges() const; - virtual lldb_private::DWARFExpression::LocationListFormat - GetLocationListFormat() const; + static bool SupportedVersion(uint16_t version); - lldb::ModuleSP - GetDWOModule (lldb_private::ConstString name); + DWARFDIE + GetDeclContextDIEContainingDIE(const DWARFDIE &die); - virtual DWARFDIE - GetDIE(const DIERef &die_ref); + bool + HasForwardDeclForClangType(const lldb_private::CompilerType &compiler_type); - virtual std::unique_ptr<SymbolFileDWARFDwo> - GetDwoSymbolFileForCompileUnit(DWARFCompileUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die); + lldb_private::CompileUnit * + GetCompUnitForDWARFCompUnit(DWARFCompileUnit *dwarf_cu, + uint32_t cu_idx = UINT32_MAX); + + size_t GetObjCMethodDIEOffsets(lldb_private::ConstString class_name, + DIEArray &method_die_offsets); + + bool Supports_DW_AT_APPLE_objc_complete_type(DWARFCompileUnit *cu); + + lldb_private::DebugMacrosSP ParseDebugMacros(lldb::offset_t *offset); + + static DWARFDIE GetParentSymbolContextDIE(const DWARFDIE &die); + + virtual lldb::CompUnitSP ParseCompileUnit(DWARFCompileUnit *dwarf_cu, + uint32_t cu_idx); + + virtual lldb_private::DWARFExpression::LocationListFormat + GetLocationListFormat() const; + + lldb::ModuleSP GetDWOModule(lldb_private::ConstString name); + + virtual DWARFDIE GetDIE(const DIERef &die_ref); + + virtual std::unique_ptr<SymbolFileDWARFDwo> + GetDwoSymbolFileForCompileUnit(DWARFCompileUnit &dwarf_cu, + const DWARFDebugInfoEntry &cu_die); protected: - typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *> DIEToTypePtr; - typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb::VariableSP> DIEToVariableSP; - typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb::opaque_compiler_type_t> DIEToClangType; - typedef llvm::DenseMap<lldb::opaque_compiler_type_t, DIERef> ClangTypeToDIE; - - struct DWARFDataSegment - { - std::once_flag m_flag; - lldb_private::DWARFDataExtractor m_data; - }; - - DISALLOW_COPY_AND_ASSIGN (SymbolFileDWARF); - - const lldb_private::DWARFDataExtractor& - GetCachedSectionData (lldb::SectionType sect_type, DWARFDataSegment& data_segment); - - virtual void - LoadSectionData (lldb::SectionType sect_type, lldb_private::DWARFDataExtractor& data); - - bool - DeclContextMatchesThisSymbolFile (const lldb_private::CompilerDeclContext *decl_ctx); - - bool - DIEInDeclContext (const lldb_private::CompilerDeclContext *parent_decl_ctx, - const DWARFDIE &die); - - virtual DWARFCompileUnit* - GetDWARFCompileUnit (lldb_private::CompileUnit *comp_unit); - - DWARFCompileUnit* - GetNextUnparsedDWARFCompileUnit (DWARFCompileUnit* prev_cu); - - bool - GetFunction (const DWARFDIE &die, - lldb_private::SymbolContext& sc); - - lldb_private::Function * - ParseCompileUnitFunction (const lldb_private::SymbolContext& sc, - 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 - ParseTypes (const lldb_private::SymbolContext& sc, - const DWARFDIE &die, - bool parse_siblings, - bool parse_children); - - lldb::TypeSP - ParseType (const lldb_private::SymbolContext& sc, - const DWARFDIE &die, - bool *type_is_new); - - lldb_private::Type * - ResolveTypeUID(const DWARFDIE &die, bool assert_not_being_parsed); - - lldb_private::Type * - ResolveTypeUID(const DIERef &die_ref); - - lldb::VariableSP - ParseVariableDIE(const lldb_private::SymbolContext& sc, - const DWARFDIE &die, - const lldb::addr_t func_low_pc); - - size_t - ParseVariables (const lldb_private::SymbolContext& sc, - const DWARFDIE &orig_die, - const lldb::addr_t func_low_pc, - bool parse_siblings, - bool parse_children, - lldb_private::VariableList* cc_variable_list = NULL); - - bool - ClassOrStructIsVirtual (const DWARFDIE &die); - - // Given a die_offset, figure out the symbol context representing that die. - bool - ResolveFunction (const DIERef& die_ref, - bool include_inlines, - lldb_private::SymbolContextList& sc_list); + typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *> + DIEToTypePtr; + typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb::VariableSP> + DIEToVariableSP; + typedef llvm::DenseMap<const DWARFDebugInfoEntry *, + lldb::opaque_compiler_type_t> + DIEToClangType; + typedef llvm::DenseMap<lldb::opaque_compiler_type_t, DIERef> ClangTypeToDIE; + + struct DWARFDataSegment { + std::once_flag m_flag; + lldb_private::DWARFDataExtractor m_data; + }; + + DISALLOW_COPY_AND_ASSIGN(SymbolFileDWARF); + + const lldb_private::DWARFDataExtractor & + GetCachedSectionData(lldb::SectionType sect_type, + DWARFDataSegment &data_segment); + + virtual void LoadSectionData(lldb::SectionType sect_type, + lldb_private::DWARFDataExtractor &data); - bool - ResolveFunction (const DWARFDIE &die, + bool DeclContextMatchesThisSymbolFile( + const lldb_private::CompilerDeclContext *decl_ctx); + + bool + DIEInDeclContext(const lldb_private::CompilerDeclContext *parent_decl_ctx, + const DWARFDIE &die); + + virtual DWARFCompileUnit * + GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit); + + DWARFCompileUnit *GetNextUnparsedDWARFCompileUnit(DWARFCompileUnit *prev_cu); + + bool GetFunction(const DWARFDIE &die, lldb_private::SymbolContext &sc); + + lldb_private::Function * + ParseCompileUnitFunction(const lldb_private::SymbolContext &sc, + 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 ParseTypes(const lldb_private::SymbolContext &sc, const DWARFDIE &die, + bool parse_siblings, bool parse_children); + + lldb::TypeSP ParseType(const lldb_private::SymbolContext &sc, + const DWARFDIE &die, bool *type_is_new); + + lldb_private::Type *ResolveTypeUID(const DWARFDIE &die, + bool assert_not_being_parsed); + + lldb_private::Type *ResolveTypeUID(const DIERef &die_ref); + + lldb::VariableSP ParseVariableDIE(const lldb_private::SymbolContext &sc, + const DWARFDIE &die, + const lldb::addr_t func_low_pc); + + size_t ParseVariables(const lldb_private::SymbolContext &sc, + const DWARFDIE &orig_die, + const lldb::addr_t func_low_pc, bool parse_siblings, + bool parse_children, + lldb_private::VariableList *cc_variable_list = NULL); + + bool ClassOrStructIsVirtual(const DWARFDIE &die); + + // Given a die_offset, figure out the symbol context representing that die. + bool ResolveFunction(const DIERef &die_ref, bool include_inlines, + lldb_private::SymbolContextList &sc_list); + + bool ResolveFunction(const DWARFDIE &die, bool include_inlines, + lldb_private::SymbolContextList &sc_list); + + void FindFunctions(const lldb_private::ConstString &name, + const NameToDIE &name_to_die, bool include_inlines, + lldb_private::SymbolContextList &sc_list); + + void FindFunctions(const lldb_private::RegularExpression ®ex, + const NameToDIE &name_to_die, bool include_inlines, + lldb_private::SymbolContextList &sc_list); + + void FindFunctions(const lldb_private::RegularExpression ®ex, + const DWARFMappedHash::MemoryTable &memory_table, bool include_inlines, - lldb_private::SymbolContextList& sc_list); - - void - FindFunctions(const lldb_private::ConstString &name, - const NameToDIE &name_to_die, - bool include_inlines, - lldb_private::SymbolContextList& sc_list); - - void - FindFunctions (const lldb_private::RegularExpression ®ex, - const NameToDIE &name_to_die, - bool include_inlines, - lldb_private::SymbolContextList& sc_list); - - void - FindFunctions (const lldb_private::RegularExpression ®ex, - const DWARFMappedHash::MemoryTable &memory_table, - bool include_inlines, - lldb_private::SymbolContextList& sc_list); - - virtual lldb::TypeSP - FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx); - - lldb::TypeSP - FindCompleteObjCDefinitionTypeForDIE (const DWARFDIE &die, - const lldb_private::ConstString &type_name, - bool must_be_implementation); - - lldb::TypeSP - FindCompleteObjCDefinitionType (const lldb_private::ConstString &type_name, - bool header_definition_ok); - - lldb_private::Symbol * - GetObjCClassSymbol (const lldb_private::ConstString &objc_class_name); - - void - ParseFunctions (const DIEArray &die_offsets, - bool include_inlines, - lldb_private::SymbolContextList& sc_list); - - lldb::TypeSP - GetTypeForDIE (const DWARFDIE &die, bool resolve_function_context = false); - - void - Index(); - - void - DumpIndexes(); - - void - SetDebugMapModule (const lldb::ModuleSP &module_sp) - { - m_debug_map_module_wp = module_sp; - } - - SymbolFileDWARFDebugMap * - GetDebugMapSymfile (); - - DWARFDIE - FindBlockContainingSpecification (const DIERef& func_die_ref, dw_offset_t spec_block_die_offset); - - DWARFDIE - FindBlockContainingSpecification (const DWARFDIE &die, dw_offset_t spec_block_die_offset); - - virtual UniqueDWARFASTTypeMap & - GetUniqueDWARFASTTypeMap (); - - bool - DIEDeclContextsMatch (const DWARFDIE &die1, - const DWARFDIE &die2); - - bool - ClassContainsSelector (const DWARFDIE &class_die, - const lldb_private::ConstString &selector); - - bool - FixupAddress (lldb_private::Address &addr); - - typedef std::set<lldb_private::Type *> TypeSet; - - typedef std::map<lldb_private::ConstString, lldb::ModuleSP> ExternalTypeModuleMap; - - void - GetTypes (const DWARFDIE &die, - dw_offset_t min_die_offset, - dw_offset_t max_die_offset, - uint32_t type_mask, - TypeSet &type_set); - - typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, lldb_private::Variable *> GlobalVariableMap; - - GlobalVariableMap & - GetGlobalAranges(); - - void - UpdateExternalModuleListIfNeeded(); - - virtual DIEToTypePtr& - GetDIEToType() { return m_die_to_type; } - - virtual DIEToVariableSP& - GetDIEToVariable() { return m_die_to_variable_sp; } - - virtual DIEToClangType& - GetForwardDeclDieToClangType() { return m_forward_decl_die_to_clang_type; } - - virtual ClangTypeToDIE& - GetForwardDeclClangTypeToDie() { return m_forward_decl_clang_type_to_die; } - - lldb::ModuleWP m_debug_map_module_wp; - SymbolFileDWARFDebugMap * m_debug_map_symfile; - lldb_private::DWARFDataExtractor m_dwarf_data; - - DWARFDataSegment m_data_debug_abbrev; - DWARFDataSegment m_data_debug_addr; - DWARFDataSegment m_data_debug_aranges; - DWARFDataSegment m_data_debug_frame; - DWARFDataSegment m_data_debug_info; - DWARFDataSegment m_data_debug_line; - DWARFDataSegment m_data_debug_macro; - DWARFDataSegment m_data_debug_loc; - DWARFDataSegment m_data_debug_ranges; - DWARFDataSegment m_data_debug_str; - DWARFDataSegment m_data_debug_str_offsets; - DWARFDataSegment m_data_apple_names; - DWARFDataSegment m_data_apple_types; - DWARFDataSegment m_data_apple_namespaces; - DWARFDataSegment m_data_apple_objc; - - // The unique pointer items below are generated on demand if and when someone accesses - // them through a non const version of this class. - std::unique_ptr<DWARFDebugAbbrev> m_abbr; - std::unique_ptr<DWARFDebugInfo> m_info; - std::unique_ptr<DWARFDebugLine> m_line; - std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_names_ap; - std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_types_ap; - std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_namespaces_ap; - std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_objc_ap; - std::unique_ptr<GlobalVariableMap> m_global_aranges_ap; - - typedef std::unordered_map<lldb::offset_t, lldb_private::DebugMacrosSP> DebugMacrosMap; - DebugMacrosMap m_debug_macros_map; - - ExternalTypeModuleMap m_external_type_modules; - NameToDIE m_function_basename_index; // All concrete functions - NameToDIE m_function_fullname_index; // All concrete functions - NameToDIE m_function_method_index; // All inlined functions - NameToDIE m_function_selector_index; // All method names for functions of classes - NameToDIE m_objc_class_selectors_index; // Given a class name, find all selectors for the class - NameToDIE m_global_index; // Global and static variables - NameToDIE m_type_index; // All type DIE offsets - NameToDIE m_namespace_index; // All type DIE offsets - bool m_indexed:1, - m_using_apple_tables:1, - m_fetched_external_modules:1; - lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type; - - 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; - UniqueDWARFASTTypeMap m_unique_ast_type_map; - DIEToTypePtr m_die_to_type; - DIEToVariableSP m_die_to_variable_sp; - DIEToClangType m_forward_decl_die_to_clang_type; - ClangTypeToDIE m_forward_decl_clang_type_to_die; + lldb_private::SymbolContextList &sc_list); + + virtual lldb::TypeSP + FindDefinitionTypeForDWARFDeclContext(const DWARFDeclContext &die_decl_ctx); + + lldb::TypeSP FindCompleteObjCDefinitionTypeForDIE( + const DWARFDIE &die, const lldb_private::ConstString &type_name, + bool must_be_implementation); + + lldb::TypeSP + FindCompleteObjCDefinitionType(const lldb_private::ConstString &type_name, + bool header_definition_ok); + + lldb_private::Symbol * + GetObjCClassSymbol(const lldb_private::ConstString &objc_class_name); + + void ParseFunctions(const DIEArray &die_offsets, bool include_inlines, + lldb_private::SymbolContextList &sc_list); + + lldb::TypeSP GetTypeForDIE(const DWARFDIE &die, + bool resolve_function_context = false); + + void Index(); + + void DumpIndexes(); + + void SetDebugMapModule(const lldb::ModuleSP &module_sp) { + m_debug_map_module_wp = module_sp; + } + + SymbolFileDWARFDebugMap *GetDebugMapSymfile(); + + DWARFDIE + FindBlockContainingSpecification(const DIERef &func_die_ref, + dw_offset_t spec_block_die_offset); + + DWARFDIE + FindBlockContainingSpecification(const DWARFDIE &die, + dw_offset_t spec_block_die_offset); + + virtual UniqueDWARFASTTypeMap &GetUniqueDWARFASTTypeMap(); + + bool DIEDeclContextsMatch(const DWARFDIE &die1, const DWARFDIE &die2); + + bool ClassContainsSelector(const DWARFDIE &class_die, + const lldb_private::ConstString &selector); + + bool FixupAddress(lldb_private::Address &addr); + + typedef std::set<lldb_private::Type *> TypeSet; + + typedef std::map<lldb_private::ConstString, lldb::ModuleSP> + ExternalTypeModuleMap; + + void GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset, + dw_offset_t max_die_offset, uint32_t type_mask, + TypeSet &type_set); + + typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, + lldb_private::Variable *> + GlobalVariableMap; + + GlobalVariableMap &GetGlobalAranges(); + + void UpdateExternalModuleListIfNeeded(); + + virtual DIEToTypePtr &GetDIEToType() { return m_die_to_type; } + + virtual DIEToVariableSP &GetDIEToVariable() { return m_die_to_variable_sp; } + + virtual DIEToClangType &GetForwardDeclDieToClangType() { + return m_forward_decl_die_to_clang_type; + } + + virtual ClangTypeToDIE &GetForwardDeclClangTypeToDie() { + return m_forward_decl_clang_type_to_die; + } + + lldb::ModuleWP m_debug_map_module_wp; + SymbolFileDWARFDebugMap *m_debug_map_symfile; + lldb_private::DWARFDataExtractor m_dwarf_data; + + DWARFDataSegment m_data_debug_abbrev; + DWARFDataSegment m_data_debug_addr; + DWARFDataSegment m_data_debug_aranges; + DWARFDataSegment m_data_debug_frame; + DWARFDataSegment m_data_debug_info; + DWARFDataSegment m_data_debug_line; + DWARFDataSegment m_data_debug_macro; + DWARFDataSegment m_data_debug_loc; + DWARFDataSegment m_data_debug_ranges; + DWARFDataSegment m_data_debug_str; + DWARFDataSegment m_data_debug_str_offsets; + DWARFDataSegment m_data_apple_names; + DWARFDataSegment m_data_apple_types; + DWARFDataSegment m_data_apple_namespaces; + DWARFDataSegment m_data_apple_objc; + + // The unique pointer items below are generated on demand if and when someone + // accesses + // them through a non const version of this class. + std::unique_ptr<DWARFDebugAbbrev> m_abbr; + std::unique_ptr<DWARFDebugInfo> m_info; + std::unique_ptr<DWARFDebugLine> m_line; + std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_names_ap; + std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_types_ap; + std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_namespaces_ap; + std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_objc_ap; + std::unique_ptr<GlobalVariableMap> m_global_aranges_ap; + + typedef std::unordered_map<lldb::offset_t, lldb_private::DebugMacrosSP> + DebugMacrosMap; + DebugMacrosMap m_debug_macros_map; + + ExternalTypeModuleMap m_external_type_modules; + NameToDIE m_function_basename_index; // All concrete functions + NameToDIE m_function_fullname_index; // All concrete functions + NameToDIE m_function_method_index; // All inlined functions + NameToDIE + m_function_selector_index; // All method names for functions of classes + NameToDIE m_objc_class_selectors_index; // Given a class name, find all + // selectors for the class + NameToDIE m_global_index; // Global and static variables + NameToDIE m_type_index; // All type DIE offsets + NameToDIE m_namespace_index; // All type DIE offsets + bool m_indexed : 1, m_using_apple_tables : 1, m_fetched_external_modules : 1; + lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type; + + 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; + UniqueDWARFASTTypeMap m_unique_ast_type_map; + DIEToTypePtr m_die_to_type; + DIEToVariableSP m_die_to_variable_sp; + DIEToClangType m_forward_decl_die_to_clang_type; + ClangTypeToDIE m_forward_decl_clang_type_to_die; }; -#endif // SymbolFileDWARF_SymbolFileDWARF_h_ +#endif // SymbolFileDWARF_SymbolFileDWARF_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp index ca819624c715..567ac88fdf07 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -15,12 +15,13 @@ #include "DWARFDebugAranges.h" -#include "lldb/Core/RangeMap.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleList.h" #include "lldb/Core/PluginManager.h" +#include "lldb/Core/RangeMap.h" #include "lldb/Core/RegularExpression.h" #include "lldb/Core/Section.h" +#include "lldb/Host/FileSystem.h" //#define DEBUG_OSO_DMAP // DO NOT CHECKIN WITH THIS NOT COMMENTED OUT #if defined(DEBUG_OSO_DMAP) @@ -34,6 +35,7 @@ #include "lldb/Symbol/SymbolVendor.h" #include "lldb/Symbol/TypeMap.h" #include "lldb/Symbol/VariableList.h" +#include "llvm/Support/ScopedPrinter.h" #include "LogChannelDWARF.h" #include "SymbolFileDWARF.h" @@ -41,1550 +43,1399 @@ using namespace lldb; using namespace lldb_private; -// Subclass lldb_private::Module so we can intercept the "Module::GetObjectFile()" -// (so we can fixup the object file sections) and also for "Module::GetSymbolVendor()" +// Subclass lldb_private::Module so we can intercept the +// "Module::GetObjectFile()" +// (so we can fixup the object file sections) and also for +// "Module::GetSymbolVendor()" // (so we can fixup the symbol file id. const SymbolFileDWARFDebugMap::FileRangeMap & -SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile) -{ - if (file_range_map_valid) - return file_range_map; - - file_range_map_valid = true; - - Module *oso_module = exe_symfile->GetModuleByCompUnitInfo (this); - if (!oso_module) - return file_range_map; - - ObjectFile *oso_objfile = oso_module->GetObjectFile(); - if (!oso_objfile) - return file_range_map; - - Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP)); - if (log) - { - ConstString object_name (oso_module->GetObjectName()); - log->Printf("%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s')", - static_cast<void*>(this), - oso_module->GetSpecificationDescription().c_str()); - } - - std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos; - if (exe_symfile->GetCompUnitInfosForModule(oso_module, cu_infos)) - { - for (auto comp_unit_info : cu_infos) - { - Symtab *exe_symtab = exe_symfile->GetObjectFile()->GetSymtab(); - ModuleSP oso_module_sp (oso_objfile->GetModule()); - Symtab *oso_symtab = oso_objfile->GetSymtab(); - - ///const uint32_t fun_resolve_flags = SymbolContext::Module | eSymbolContextCompUnit | eSymbolContextFunction; - //SectionList *oso_sections = oso_objfile->Sections(); - // Now we need to make sections that map from zero based object - // file addresses to where things ended up in the main executable. - - assert (comp_unit_info->first_symbol_index != UINT32_MAX); - // End index is one past the last valid symbol index - 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) - { - Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx); - if (exe_symbol) - { - if (exe_symbol->IsDebug() == false) - continue; - - switch (exe_symbol->GetType()) - { - default: - break; - - case eSymbolTypeCode: - { - // For each N_FUN, or function that we run into in the debug map - // we make a new section that we add to the sections found in the - // .o file. This new section has the file address set to what the - // addresses are in the .o file, and the load address is adjusted - // to match where it ended up in the final executable! We do this - // before we parse any dwarf info so that when it goes get parsed - // all section/offset addresses that get registered will resolve - // correctly to the new addresses in the main executable. - - // First we find the original symbol in the .o file's symbol table - Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled), - eSymbolTypeCode, - Symtab::eDebugNo, - Symtab::eVisibilityAny); - if (oso_fun_symbol) - { - // Add the inverse OSO file address to debug map entry mapping - exe_symfile->AddOSOFileRange (this, - exe_symbol->GetAddressRef().GetFileAddress(), - exe_symbol->GetByteSize(), - oso_fun_symbol->GetAddressRef().GetFileAddress(), - oso_fun_symbol->GetByteSize()); - - } - } - break; - - case eSymbolTypeData: - { - // For each N_GSYM we remap the address for the global by making - // a new section that we add to the sections found in the .o file. - // This new section has the file address set to what the - // addresses are in the .o file, and the load address is adjusted - // to match where it ended up in the final executable! We do this - // before we parse any dwarf info so that when it goes get parsed - // all section/offset addresses that get registered will resolve - // correctly to the new addresses in the main executable. We - // initially set the section size to be 1 byte, but will need to - // fix up these addresses further after all globals have been - // parsed to span the gaps, or we can find the global variable - // sizes from the DWARF info as we are parsing. - - // Next we find the non-stab entry that corresponds to the N_GSYM in the .o file - Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled), - eSymbolTypeData, - Symtab::eDebugNo, - Symtab::eVisibilityAny); - if (exe_symbol && oso_gsym_symbol && - exe_symbol->ValueIsAddress() && - oso_gsym_symbol->ValueIsAddress()) - { - // Add the inverse OSO file address to debug map entry mapping - exe_symfile->AddOSOFileRange (this, - exe_symbol->GetAddressRef().GetFileAddress(), - exe_symbol->GetByteSize(), - oso_gsym_symbol->GetAddressRef().GetFileAddress(), - oso_gsym_symbol->GetByteSize()); - } - } - break; - } - } - } - - exe_symfile->FinalizeOSOFileRanges (this); - // We don't need the symbols anymore for the .o files - oso_objfile->ClearSymtab(); - } - } +SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap( + SymbolFileDWARFDebugMap *exe_symfile) { + if (file_range_map_valid) return file_range_map; -} -class DebugMapModule : public Module -{ -public: - DebugMapModule (const ModuleSP &exe_module_sp, - uint32_t cu_idx, - const FileSpec& file_spec, - const ArchSpec& arch, - const ConstString *object_name, - off_t object_offset, - const TimeValue *object_mod_time_ptr) : - Module (file_spec, arch, object_name, object_offset, object_mod_time_ptr), - m_exe_module_wp (exe_module_sp), - m_cu_idx (cu_idx) - { - } + file_range_map_valid = true; - ~DebugMapModule() override = default; - - SymbolVendor* - GetSymbolVendor(bool can_create = true, lldb_private::Stream *feedback_strm = NULL) override - { - // Scope for locker - if (m_symfile_ap.get() || can_create == false) - return m_symfile_ap.get(); - - ModuleSP exe_module_sp (m_exe_module_wp.lock()); - if (exe_module_sp) - { - // Now get the object file outside of a locking scope - ObjectFile *oso_objfile = GetObjectFile (); - if (oso_objfile) - { - std::lock_guard<std::recursive_mutex> guard(m_mutex); - SymbolVendor* symbol_vendor = Module::GetSymbolVendor(can_create, feedback_strm); - if (symbol_vendor) - { - // Set a pointer to this class to set our OSO DWARF file know - // that the DWARF is being used along with a debug map and that - // it will have the remapped sections that we do below. - SymbolFileDWARF *oso_symfile = SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(symbol_vendor->GetSymbolFile()); - - if (!oso_symfile) - return NULL; - - ObjectFile *exe_objfile = exe_module_sp->GetObjectFile(); - SymbolVendor *exe_sym_vendor = exe_module_sp->GetSymbolVendor(); - - if (exe_objfile && exe_sym_vendor) - { - oso_symfile->SetDebugMapModule(exe_module_sp); - // Set the ID of the symbol file DWARF to the index of the OSO - // shifted left by 32 bits to provide a unique prefix for any - // UserID's that get created in the symbol file. - oso_symfile->SetID (((uint64_t)m_cu_idx + 1ull) << 32ull); - } - return symbol_vendor; - } - } - } - return NULL; - } + Module *oso_module = exe_symfile->GetModuleByCompUnitInfo(this); + if (!oso_module) + return file_range_map; -protected: - ModuleWP m_exe_module_wp; - const uint32_t m_cu_idx; -}; + ObjectFile *oso_objfile = oso_module->GetObjectFile(); + if (!oso_objfile) + return file_range_map; -void -SymbolFileDWARFDebugMap::Initialize() -{ - PluginManager::RegisterPlugin (GetPluginNameStatic(), - GetPluginDescriptionStatic(), - CreateInstance); -} - -void -SymbolFileDWARFDebugMap::Terminate() -{ - PluginManager::UnregisterPlugin (CreateInstance); -} - -lldb_private::ConstString -SymbolFileDWARFDebugMap::GetPluginNameStatic() -{ - static ConstString g_name("dwarf-debugmap"); - return g_name; -} - -const char * -SymbolFileDWARFDebugMap::GetPluginDescriptionStatic() -{ - return "DWARF and DWARF3 debug symbol file reader (debug map)."; -} - -SymbolFile* -SymbolFileDWARFDebugMap::CreateInstance (ObjectFile* obj_file) -{ - return new SymbolFileDWARFDebugMap (obj_file); -} - -SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap (ObjectFile* ofile) : - SymbolFile(ofile), - m_flags(), - m_compile_unit_infos(), - m_func_indexes(), - m_glob_indexes(), - m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate) -{ -} - -SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap() -{ -} - -void -SymbolFileDWARFDebugMap::InitializeObject() -{ -} - -void -SymbolFileDWARFDebugMap::InitOSO() -{ - if (m_flags.test(kHaveInitializedOSOs)) - return; - - m_flags.set(kHaveInitializedOSOs); - - // If the object file has been stripped, there is no sense in looking further - // as all of the debug symbols for the debug map will not be available - if (m_obj_file->IsStripped()) - return; - - // Also make sure the file type is some sort of executable. Core files, debug - // info files (dSYM), object files (.o files), and stub libraries all can - switch (m_obj_file->GetType()) - { - case ObjectFile::eTypeInvalid: - case ObjectFile::eTypeCoreFile: - case ObjectFile::eTypeDebugInfo: - case ObjectFile::eTypeObjectFile: - case ObjectFile::eTypeStubLibrary: - case ObjectFile::eTypeUnknown: - case ObjectFile::eTypeJIT: - return; - - case ObjectFile::eTypeExecutable: - case ObjectFile::eTypeDynamicLinker: - case ObjectFile::eTypeSharedLibrary: + Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP)); + if (log) { + ConstString object_name(oso_module->GetObjectName()); + log->Printf( + "%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s')", + static_cast<void *>(this), + oso_module->GetSpecificationDescription().c_str()); + } + + std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos; + if (exe_symfile->GetCompUnitInfosForModule(oso_module, cu_infos)) { + for (auto comp_unit_info : cu_infos) { + Symtab *exe_symtab = exe_symfile->GetObjectFile()->GetSymtab(); + ModuleSP oso_module_sp(oso_objfile->GetModule()); + Symtab *oso_symtab = oso_objfile->GetSymtab(); + + /// const uint32_t fun_resolve_flags = SymbolContext::Module | + /// eSymbolContextCompUnit | eSymbolContextFunction; + // SectionList *oso_sections = oso_objfile->Sections(); + // Now we need to make sections that map from zero based object + // file addresses to where things ended up in the main executable. + + assert(comp_unit_info->first_symbol_index != UINT32_MAX); + // End index is one past the last valid symbol index + 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) { + Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx); + if (exe_symbol) { + if (exe_symbol->IsDebug() == false) + continue; + + switch (exe_symbol->GetType()) { + default: break; - } - // In order to get the abilities of this plug-in, we look at the list of - // N_OSO entries (object files) from the symbol table and make sure that - // these files exist and also contain valid DWARF. If we get any of that - // then we return the abilities of the first N_OSO's DWARF. - - Symtab* symtab = m_obj_file->GetSymtab(); - if (symtab) - { - Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP)); - - std::vector<uint32_t> oso_indexes; - // When a mach-o symbol is encoded, the n_type field is encoded in bits - // 23:16, and the n_desc field is encoded in bits 15:0. - // - // To find all N_OSO entries that are part of the DWARF + debug map - // we find only object file symbols with the flags value as follows: - // bits 23:16 == 0x66 (N_OSO) - // bits 15: 0 == 0x0001 (specifies this is a debug map object file) - const uint32_t k_oso_symbol_flags_value = 0x660001u; - - const uint32_t oso_index_count = symtab->AppendSymbolIndexesWithTypeAndFlagsValue(eSymbolTypeObjectFile, k_oso_symbol_flags_value, oso_indexes); - - if (oso_index_count > 0) - { - symtab->AppendSymbolIndexesWithType (eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, m_func_indexes); - symtab->AppendSymbolIndexesWithType (eSymbolTypeData, Symtab::eDebugYes, Symtab::eVisibilityAny, m_glob_indexes); - - symtab->SortSymbolIndexesByValue(m_func_indexes, true); - symtab->SortSymbolIndexesByValue(m_glob_indexes, true); - - for (uint32_t sym_idx : m_func_indexes) - { - const Symbol *symbol = symtab->SymbolAtIndex(sym_idx); - lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress(); - lldb::addr_t byte_size = symbol->GetByteSize(); - DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS)); - m_debug_map.Append(debug_map_entry); - } - for (uint32_t sym_idx : m_glob_indexes) - { - const Symbol *symbol = symtab->SymbolAtIndex(sym_idx); - lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress(); - lldb::addr_t byte_size = symbol->GetByteSize(); - DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS)); - m_debug_map.Append(debug_map_entry); + case eSymbolTypeCode: { + // For each N_FUN, or function that we run into in the debug map + // we make a new section that we add to the sections found in the + // .o file. This new section has the file address set to what the + // addresses are in the .o file, and the load address is adjusted + // to match where it ended up in the final executable! We do this + // before we parse any dwarf info so that when it goes get parsed + // all section/offset addresses that get registered will resolve + // correctly to the new addresses in the main executable. + + // First we find the original symbol in the .o file's symbol table + Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType( + exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, + Mangled::ePreferMangled), + eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny); + if (oso_fun_symbol) { + // Add the inverse OSO file address to debug map entry mapping + exe_symfile->AddOSOFileRange( + this, exe_symbol->GetAddressRef().GetFileAddress(), + exe_symbol->GetByteSize(), + oso_fun_symbol->GetAddressRef().GetFileAddress(), + oso_fun_symbol->GetByteSize()); } - m_debug_map.Sort(); - - m_compile_unit_infos.resize(oso_index_count); - - for (uint32_t i=0; i<oso_index_count; ++i) - { - const uint32_t so_idx = oso_indexes[i] - 1; - const uint32_t oso_idx = oso_indexes[i]; - const Symbol *so_symbol = symtab->SymbolAtIndex(so_idx); - const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_idx); - if (so_symbol && - oso_symbol && - so_symbol->GetType() == eSymbolTypeSourceFile && - oso_symbol->GetType() == eSymbolTypeObjectFile) - { - m_compile_unit_infos[i].so_file.SetFile(so_symbol->GetName().AsCString(), false); - m_compile_unit_infos[i].oso_path = oso_symbol->GetName(); - TimeValue oso_mod_time; - oso_mod_time.OffsetWithSeconds(oso_symbol->GetIntegerValue(0)); - m_compile_unit_infos[i].oso_mod_time = oso_mod_time; - uint32_t sibling_idx = so_symbol->GetSiblingIndex(); - // The sibling index can't be less that or equal to the current index "i" - if (sibling_idx == UINT32_MAX) - { - m_obj_file->GetModule()->ReportError ("N_SO in symbol with UID %u has invalid sibling in debug map, please file a bug and attach the binary listed in this error", so_symbol->GetID()); - } - else - { - const Symbol* last_symbol = symtab->SymbolAtIndex (sibling_idx - 1); - m_compile_unit_infos[i].first_symbol_index = so_idx; - m_compile_unit_infos[i].last_symbol_index = sibling_idx - 1; - m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID(); - m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID(); - - if (log) - log->Printf("Initialized OSO 0x%8.8x: file=%s", i, oso_symbol->GetName().GetCString()); - } - } - else - { - if (oso_symbol == NULL) - m_obj_file->GetModule()->ReportError ("N_OSO symbol[%u] can't be found, please file a bug and attach the binary listed in this error", oso_idx); - else if (so_symbol == NULL) - m_obj_file->GetModule()->ReportError ("N_SO not found for N_OSO symbol[%u], please file a bug and attach the binary listed in this error", oso_idx); - else if (so_symbol->GetType() != eSymbolTypeSourceFile) - m_obj_file->GetModule()->ReportError ("N_SO has incorrect symbol type (%u) for N_OSO symbol[%u], please file a bug and attach the binary listed in this error", so_symbol->GetType(), oso_idx); - else if (oso_symbol->GetType() != eSymbolTypeSourceFile) - m_obj_file->GetModule()->ReportError ("N_OSO has incorrect symbol type (%u) for N_OSO symbol[%u], please file a bug and attach the binary listed in this error", oso_symbol->GetType(), oso_idx); - } + } break; + + case eSymbolTypeData: { + // For each N_GSYM we remap the address for the global by making + // a new section that we add to the sections found in the .o file. + // This new section has the file address set to what the + // addresses are in the .o file, and the load address is adjusted + // to match where it ended up in the final executable! We do this + // before we parse any dwarf info so that when it goes get parsed + // all section/offset addresses that get registered will resolve + // correctly to the new addresses in the main executable. We + // initially set the section size to be 1 byte, but will need to + // fix up these addresses further after all globals have been + // parsed to span the gaps, or we can find the global variable + // sizes from the DWARF info as we are parsing. + + // Next we find the non-stab entry that corresponds to the N_GSYM in + // the .o file + Symbol *oso_gsym_symbol = + oso_symtab->FindFirstSymbolWithNameAndType( + exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, + Mangled::ePreferMangled), + eSymbolTypeData, Symtab::eDebugNo, Symtab::eVisibilityAny); + if (exe_symbol && oso_gsym_symbol && exe_symbol->ValueIsAddress() && + oso_gsym_symbol->ValueIsAddress()) { + // Add the inverse OSO file address to debug map entry mapping + exe_symfile->AddOSOFileRange( + this, exe_symbol->GetAddressRef().GetFileAddress(), + exe_symbol->GetByteSize(), + oso_gsym_symbol->GetAddressRef().GetFileAddress(), + oso_gsym_symbol->GetByteSize()); } + } break; + } } + } + + exe_symfile->FinalizeOSOFileRanges(this); + // We don't need the symbols anymore for the .o files + oso_objfile->ClearSymtab(); } + } + return file_range_map; } -Module * -SymbolFileDWARFDebugMap::GetModuleByOSOIndex (uint32_t oso_idx) -{ - const uint32_t cu_count = GetNumCompileUnits(); - if (oso_idx < cu_count) - return GetModuleByCompUnitInfo (&m_compile_unit_infos[oso_idx]); +class DebugMapModule : public Module { +public: + DebugMapModule(const ModuleSP &exe_module_sp, uint32_t cu_idx, + const FileSpec &file_spec, const ArchSpec &arch, + const ConstString *object_name, off_t object_offset, + const llvm::sys::TimePoint<> object_mod_time) + : Module(file_spec, arch, object_name, object_offset, object_mod_time), + m_exe_module_wp(exe_module_sp), m_cu_idx(cu_idx) {} + + ~DebugMapModule() override = default; + + SymbolVendor * + GetSymbolVendor(bool can_create = true, + lldb_private::Stream *feedback_strm = NULL) override { + // Scope for locker + if (m_symfile_ap.get() || can_create == false) + return m_symfile_ap.get(); + + ModuleSP exe_module_sp(m_exe_module_wp.lock()); + if (exe_module_sp) { + // Now get the object file outside of a locking scope + ObjectFile *oso_objfile = GetObjectFile(); + if (oso_objfile) { + std::lock_guard<std::recursive_mutex> guard(m_mutex); + SymbolVendor *symbol_vendor = + Module::GetSymbolVendor(can_create, feedback_strm); + if (symbol_vendor) { + // Set a pointer to this class to set our OSO DWARF file know + // that the DWARF is being used along with a debug map and that + // it will have the remapped sections that we do below. + SymbolFileDWARF *oso_symfile = + SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF( + symbol_vendor->GetSymbolFile()); + + if (!oso_symfile) + return NULL; + + ObjectFile *exe_objfile = exe_module_sp->GetObjectFile(); + SymbolVendor *exe_sym_vendor = exe_module_sp->GetSymbolVendor(); + + if (exe_objfile && exe_sym_vendor) { + oso_symfile->SetDebugMapModule(exe_module_sp); + // Set the ID of the symbol file DWARF to the index of the OSO + // shifted left by 32 bits to provide a unique prefix for any + // UserID's that get created in the symbol file. + oso_symfile->SetID(((uint64_t)m_cu_idx + 1ull) << 32ull); + } + return symbol_vendor; + } + } + } return NULL; -} + } -Module * -SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo (CompileUnitInfo *comp_unit_info) -{ - if (!comp_unit_info->oso_sp) - { - auto pos = m_oso_map.find (comp_unit_info->oso_path); - if (pos != m_oso_map.end()) - { - comp_unit_info->oso_sp = pos->second; - } - else - { - ObjectFile *obj_file = GetObjectFile(); - comp_unit_info->oso_sp.reset (new OSOInfo()); - m_oso_map[comp_unit_info->oso_path] = comp_unit_info->oso_sp; - const char *oso_path = comp_unit_info->oso_path.GetCString(); - FileSpec oso_file (oso_path, false); - ConstString oso_object; - if (oso_file.Exists()) - { - TimeValue oso_mod_time (oso_file.GetModificationTime()); - if (oso_mod_time != comp_unit_info->oso_mod_time) - { - obj_file->GetModule()->ReportError ("debug map object file '%s' has changed (actual time is 0x%" PRIx64 ", debug map time is 0x%" PRIx64 ") since this executable was linked, file will be ignored", - oso_file.GetPath().c_str(), - oso_mod_time.GetAsSecondsSinceJan1_1970(), - comp_unit_info->oso_mod_time.GetAsSecondsSinceJan1_1970()); - return NULL; - } +protected: + ModuleWP m_exe_module_wp; + const uint32_t m_cu_idx; +}; - } - else - { - const bool must_exist = true; - - if (!ObjectFile::SplitArchivePathWithObject (oso_path, - oso_file, - oso_object, - must_exist)) - { - return NULL; - } - } - // Always create a new module for .o files. Why? Because we - // use the debug map, to add new sections to each .o file and - // even though a .o file might not have changed, the sections - // that get added to the .o file can change. - ArchSpec oso_arch; - // Only adopt the architecture from the module (not the vendor or OS) - // since .o files for "i386-apple-ios" will historically show up as "i386-apple-macosx" - // due to the lack of a LC_VERSION_MIN_MACOSX or LC_VERSION_MIN_IPHONEOS - // load command... - oso_arch.SetTriple(m_obj_file->GetModule()->GetArchitecture().GetTriple().getArchName().str().c_str()); - comp_unit_info->oso_sp->module_sp.reset (new DebugMapModule (obj_file->GetModule(), - GetCompUnitInfoIndex(comp_unit_info), - oso_file, - oso_arch, - oso_object ? &oso_object : NULL, - 0, - oso_object ? &comp_unit_info->oso_mod_time : NULL)); +void SymbolFileDWARFDebugMap::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + GetPluginDescriptionStatic(), CreateInstance); +} + +void SymbolFileDWARFDebugMap::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +lldb_private::ConstString SymbolFileDWARFDebugMap::GetPluginNameStatic() { + static ConstString g_name("dwarf-debugmap"); + return g_name; +} + +const char *SymbolFileDWARFDebugMap::GetPluginDescriptionStatic() { + return "DWARF and DWARF3 debug symbol file reader (debug map)."; +} + +SymbolFile *SymbolFileDWARFDebugMap::CreateInstance(ObjectFile *obj_file) { + return new SymbolFileDWARFDebugMap(obj_file); +} + +SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap(ObjectFile *ofile) + : SymbolFile(ofile), m_flags(), m_compile_unit_infos(), m_func_indexes(), + m_glob_indexes(), + m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {} + +SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap() {} + +void SymbolFileDWARFDebugMap::InitializeObject() {} + +void SymbolFileDWARFDebugMap::InitOSO() { + if (m_flags.test(kHaveInitializedOSOs)) + return; + + m_flags.set(kHaveInitializedOSOs); + + // If the object file has been stripped, there is no sense in looking further + // as all of the debug symbols for the debug map will not be available + if (m_obj_file->IsStripped()) + return; + + // Also make sure the file type is some sort of executable. Core files, debug + // info files (dSYM), object files (.o files), and stub libraries all can + switch (m_obj_file->GetType()) { + case ObjectFile::eTypeInvalid: + case ObjectFile::eTypeCoreFile: + case ObjectFile::eTypeDebugInfo: + case ObjectFile::eTypeObjectFile: + case ObjectFile::eTypeStubLibrary: + case ObjectFile::eTypeUnknown: + case ObjectFile::eTypeJIT: + return; + + case ObjectFile::eTypeExecutable: + case ObjectFile::eTypeDynamicLinker: + case ObjectFile::eTypeSharedLibrary: + break; + } + + // In order to get the abilities of this plug-in, we look at the list of + // N_OSO entries (object files) from the symbol table and make sure that + // these files exist and also contain valid DWARF. If we get any of that + // then we return the abilities of the first N_OSO's DWARF. + + Symtab *symtab = m_obj_file->GetSymtab(); + if (symtab) { + Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP)); + + std::vector<uint32_t> oso_indexes; + // When a mach-o symbol is encoded, the n_type field is encoded in bits + // 23:16, and the n_desc field is encoded in bits 15:0. + // + // To find all N_OSO entries that are part of the DWARF + debug map + // we find only object file symbols with the flags value as follows: + // bits 23:16 == 0x66 (N_OSO) + // bits 15: 0 == 0x0001 (specifies this is a debug map object file) + const uint32_t k_oso_symbol_flags_value = 0x660001u; + + const uint32_t oso_index_count = + symtab->AppendSymbolIndexesWithTypeAndFlagsValue( + eSymbolTypeObjectFile, k_oso_symbol_flags_value, oso_indexes); + + if (oso_index_count > 0) { + symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugYes, + Symtab::eVisibilityAny, + m_func_indexes); + symtab->AppendSymbolIndexesWithType(eSymbolTypeData, Symtab::eDebugYes, + Symtab::eVisibilityAny, + m_glob_indexes); + + symtab->SortSymbolIndexesByValue(m_func_indexes, true); + symtab->SortSymbolIndexesByValue(m_glob_indexes, true); + + for (uint32_t sym_idx : m_func_indexes) { + const Symbol *symbol = symtab->SymbolAtIndex(sym_idx); + lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress(); + lldb::addr_t byte_size = symbol->GetByteSize(); + DebugMap::Entry debug_map_entry( + file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS)); + m_debug_map.Append(debug_map_entry); + } + for (uint32_t sym_idx : m_glob_indexes) { + const Symbol *symbol = symtab->SymbolAtIndex(sym_idx); + lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress(); + lldb::addr_t byte_size = symbol->GetByteSize(); + DebugMap::Entry debug_map_entry( + file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS)); + m_debug_map.Append(debug_map_entry); + } + m_debug_map.Sort(); + + m_compile_unit_infos.resize(oso_index_count); + + for (uint32_t i = 0; i < oso_index_count; ++i) { + const uint32_t so_idx = oso_indexes[i] - 1; + const uint32_t oso_idx = oso_indexes[i]; + const Symbol *so_symbol = symtab->SymbolAtIndex(so_idx); + const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_idx); + if (so_symbol && oso_symbol && + so_symbol->GetType() == eSymbolTypeSourceFile && + oso_symbol->GetType() == eSymbolTypeObjectFile) { + m_compile_unit_infos[i].so_file.SetFile( + so_symbol->GetName().AsCString(), false); + 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)); + uint32_t sibling_idx = so_symbol->GetSiblingIndex(); + // The sibling index can't be less that or equal to the current index + // "i" + if (sibling_idx == UINT32_MAX) { + m_obj_file->GetModule()->ReportError( + "N_SO in symbol with UID %u has invalid sibling in debug map, " + "please file a bug and attach the binary listed in this error", + so_symbol->GetID()); + } else { + const Symbol *last_symbol = symtab->SymbolAtIndex(sibling_idx - 1); + m_compile_unit_infos[i].first_symbol_index = so_idx; + m_compile_unit_infos[i].last_symbol_index = sibling_idx - 1; + m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID(); + m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID(); + + if (log) + log->Printf("Initialized OSO 0x%8.8x: file=%s", i, + oso_symbol->GetName().GetCString()); + } + } else { + if (oso_symbol == NULL) + m_obj_file->GetModule()->ReportError( + "N_OSO symbol[%u] can't be found, please file a bug and attach " + "the binary listed in this error", + oso_idx); + else if (so_symbol == NULL) + m_obj_file->GetModule()->ReportError( + "N_SO not found for N_OSO symbol[%u], please file a bug and " + "attach the binary listed in this error", + oso_idx); + else if (so_symbol->GetType() != eSymbolTypeSourceFile) + m_obj_file->GetModule()->ReportError( + "N_SO has incorrect symbol type (%u) for N_OSO symbol[%u], " + "please file a bug and attach the binary listed in this error", + so_symbol->GetType(), oso_idx); + else if (oso_symbol->GetType() != eSymbolTypeSourceFile) + m_obj_file->GetModule()->ReportError( + "N_OSO has incorrect symbol type (%u) for N_OSO symbol[%u], " + "please file a bug and attach the binary listed in this error", + oso_symbol->GetType(), oso_idx); } + } } - if (comp_unit_info->oso_sp) - return comp_unit_info->oso_sp->module_sp.get(); - return NULL; -} + } +} + +Module *SymbolFileDWARFDebugMap::GetModuleByOSOIndex(uint32_t oso_idx) { + const uint32_t cu_count = GetNumCompileUnits(); + if (oso_idx < cu_count) + return GetModuleByCompUnitInfo(&m_compile_unit_infos[oso_idx]); + return NULL; +} + +Module *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo( + CompileUnitInfo *comp_unit_info) { + if (!comp_unit_info->oso_sp) { + auto pos = m_oso_map.find(comp_unit_info->oso_path); + if (pos != m_oso_map.end()) { + comp_unit_info->oso_sp = pos->second; + } else { + ObjectFile *obj_file = GetObjectFile(); + comp_unit_info->oso_sp.reset(new OSOInfo()); + m_oso_map[comp_unit_info->oso_path] = comp_unit_info->oso_sp; + const char *oso_path = comp_unit_info->oso_path.GetCString(); + FileSpec oso_file(oso_path, false); + ConstString oso_object; + if (oso_file.Exists()) { + auto oso_mod_time = FileSystem::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 " + "%s, debug map time is %s" + ") since this executable was linked, file will be ignored", + oso_file.GetPath().c_str(), llvm::to_string(oso_mod_time).c_str(), + llvm::to_string(comp_unit_info->oso_mod_time).c_str()); + return NULL; + } + + } else { + const bool must_exist = true; -bool -SymbolFileDWARFDebugMap::GetFileSpecForSO (uint32_t oso_idx, FileSpec &file_spec) -{ - if (oso_idx < m_compile_unit_infos.size()) - { - if (m_compile_unit_infos[oso_idx].so_file) - { - file_spec = m_compile_unit_infos[oso_idx].so_file; - return true; + if (!ObjectFile::SplitArchivePathWithObject(oso_path, oso_file, + oso_object, must_exist)) { + return NULL; } + } + // Always create a new module for .o files. Why? Because we + // use the debug map, to add new sections to each .o file and + // even though a .o file might not have changed, the sections + // that get added to the .o file can change. + ArchSpec oso_arch; + // Only adopt the architecture from the module (not the vendor or OS) + // since .o files for "i386-apple-ios" will historically show up as + // "i386-apple-macosx" + // due to the lack of a LC_VERSION_MIN_MACOSX or LC_VERSION_MIN_IPHONEOS + // load command... + oso_arch.SetTriple(m_obj_file->GetModule() + ->GetArchitecture() + .GetTriple() + .getArchName() + .str() + .c_str()); + comp_unit_info->oso_sp->module_sp.reset(new DebugMapModule( + obj_file->GetModule(), GetCompUnitInfoIndex(comp_unit_info), oso_file, + oso_arch, oso_object ? &oso_object : NULL, 0, + oso_object ? comp_unit_info->oso_mod_time + : llvm::sys::TimePoint<>())); } - return false; + } + if (comp_unit_info->oso_sp) + return comp_unit_info->oso_sp->module_sp.get(); + return NULL; +} + +bool SymbolFileDWARFDebugMap::GetFileSpecForSO(uint32_t oso_idx, + FileSpec &file_spec) { + if (oso_idx < m_compile_unit_infos.size()) { + if (m_compile_unit_infos[oso_idx].so_file) { + file_spec = m_compile_unit_infos[oso_idx].so_file; + return true; + } + } + return false; } -ObjectFile * -SymbolFileDWARFDebugMap::GetObjectFileByOSOIndex (uint32_t oso_idx) -{ - Module *oso_module = GetModuleByOSOIndex (oso_idx); - if (oso_module) - return oso_module->GetObjectFile(); - return NULL; +ObjectFile *SymbolFileDWARFDebugMap::GetObjectFileByOSOIndex(uint32_t oso_idx) { + Module *oso_module = GetModuleByOSOIndex(oso_idx); + if (oso_module) + return oso_module->GetObjectFile(); + return NULL; } SymbolFileDWARF * -SymbolFileDWARFDebugMap::GetSymbolFile (const SymbolContext& sc) -{ - CompileUnitInfo *comp_unit_info = GetCompUnitInfo (sc); - if (comp_unit_info) - return GetSymbolFileByCompUnitInfo (comp_unit_info); - return NULL; +SymbolFileDWARFDebugMap::GetSymbolFile(const SymbolContext &sc) { + CompileUnitInfo *comp_unit_info = GetCompUnitInfo(sc); + if (comp_unit_info) + return GetSymbolFileByCompUnitInfo(comp_unit_info); + return NULL; } -ObjectFile * -SymbolFileDWARFDebugMap::GetObjectFileByCompUnitInfo (CompileUnitInfo *comp_unit_info) -{ - Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info); - if (oso_module) - return oso_module->GetObjectFile(); - return NULL; +ObjectFile *SymbolFileDWARFDebugMap::GetObjectFileByCompUnitInfo( + CompileUnitInfo *comp_unit_info) { + Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info); + if (oso_module) + return oso_module->GetObjectFile(); + return NULL; } -uint32_t -SymbolFileDWARFDebugMap::GetCompUnitInfoIndex (const CompileUnitInfo *comp_unit_info) -{ - if (!m_compile_unit_infos.empty()) - { - const CompileUnitInfo *first_comp_unit_info = &m_compile_unit_infos.front(); - const CompileUnitInfo *last_comp_unit_info = &m_compile_unit_infos.back(); - if (first_comp_unit_info <= comp_unit_info && comp_unit_info <= last_comp_unit_info) - return comp_unit_info - first_comp_unit_info; - } - return UINT32_MAX; -} - -SymbolFileDWARF * -SymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex (uint32_t oso_idx) -{ - if (oso_idx < m_compile_unit_infos.size()) - return GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[oso_idx]); - return NULL; +uint32_t SymbolFileDWARFDebugMap::GetCompUnitInfoIndex( + const CompileUnitInfo *comp_unit_info) { + if (!m_compile_unit_infos.empty()) { + const CompileUnitInfo *first_comp_unit_info = &m_compile_unit_infos.front(); + const CompileUnitInfo *last_comp_unit_info = &m_compile_unit_infos.back(); + if (first_comp_unit_info <= comp_unit_info && + comp_unit_info <= last_comp_unit_info) + return comp_unit_info - first_comp_unit_info; + } + return UINT32_MAX; } SymbolFileDWARF * -SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF (SymbolFile *sym_file) -{ - if (sym_file && sym_file->GetPluginName() == SymbolFileDWARF::GetPluginNameStatic()) - return (SymbolFileDWARF *)sym_file; - return NULL; +SymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex(uint32_t oso_idx) { + if (oso_idx < m_compile_unit_infos.size()) + return GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[oso_idx]); + return NULL; } SymbolFileDWARF * -SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo (CompileUnitInfo *comp_unit_info) -{ - Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info); - if (oso_module) - { - SymbolVendor *sym_vendor = oso_module->GetSymbolVendor(); - if (sym_vendor) - return GetSymbolFileAsSymbolFileDWARF (sym_vendor->GetSymbolFile()); +SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(SymbolFile *sym_file) { + if (sym_file && + sym_file->GetPluginName() == SymbolFileDWARF::GetPluginNameStatic()) + return (SymbolFileDWARF *)sym_file; + return NULL; +} + +SymbolFileDWARF *SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo( + CompileUnitInfo *comp_unit_info) { + Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info); + if (oso_module) { + SymbolVendor *sym_vendor = oso_module->GetSymbolVendor(); + if (sym_vendor) + return GetSymbolFileAsSymbolFileDWARF(sym_vendor->GetSymbolFile()); + } + return NULL; +} + +uint32_t SymbolFileDWARFDebugMap::CalculateAbilities() { + // In order to get the abilities of this plug-in, we look at the list of + // N_OSO entries (object files) from the symbol table and make sure that + // these files exist and also contain valid DWARF. If we get any of that + // then we return the abilities of the first N_OSO's DWARF. + + const uint32_t oso_index_count = GetNumCompileUnits(); + if (oso_index_count > 0) { + InitOSO(); + if (!m_compile_unit_infos.empty()) { + return SymbolFile::CompileUnits | SymbolFile::Functions | + SymbolFile::Blocks | SymbolFile::GlobalVariables | + SymbolFile::LocalVariables | SymbolFile::VariableTypes | + SymbolFile::LineTables; } - return NULL; -} - -uint32_t -SymbolFileDWARFDebugMap::CalculateAbilities () -{ - // In order to get the abilities of this plug-in, we look at the list of - // N_OSO entries (object files) from the symbol table and make sure that - // these files exist and also contain valid DWARF. If we get any of that - // then we return the abilities of the first N_OSO's DWARF. - - const uint32_t oso_index_count = GetNumCompileUnits(); - if (oso_index_count > 0) - { - InitOSO(); - if (!m_compile_unit_infos.empty()) - { - return SymbolFile::CompileUnits | - SymbolFile::Functions | - SymbolFile::Blocks | - SymbolFile::GlobalVariables | - SymbolFile::LocalVariables | - SymbolFile::VariableTypes | - SymbolFile::LineTables ; - } - } - return 0; -} - -uint32_t -SymbolFileDWARFDebugMap::GetNumCompileUnits() -{ - InitOSO (); - return m_compile_unit_infos.size(); -} - -CompUnitSP -SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx) -{ - CompUnitSP comp_unit_sp; - const uint32_t cu_count = GetNumCompileUnits(); - - if (cu_idx < cu_count) - { - Module *oso_module = GetModuleByCompUnitInfo (&m_compile_unit_infos[cu_idx]); - if (oso_module) - { - FileSpec so_file_spec; - if (GetFileSpecForSO (cu_idx, so_file_spec)) - { - // User zero as the ID to match the compile unit at offset - // zero in each .o file since each .o file can only have - // one compile unit for now. - lldb::user_id_t cu_id = 0; - m_compile_unit_infos[cu_idx].compile_unit_sp.reset(new CompileUnit( - m_obj_file->GetModule(), NULL, so_file_spec, cu_id, eLanguageTypeUnknown, eLazyBoolCalculate)); - - if (m_compile_unit_infos[cu_idx].compile_unit_sp) - { - // Let our symbol vendor know about this compile unit - m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex (cu_idx, m_compile_unit_infos[cu_idx].compile_unit_sp); - } - } + } + return 0; +} + +uint32_t SymbolFileDWARFDebugMap::GetNumCompileUnits() { + InitOSO(); + return m_compile_unit_infos.size(); +} + +CompUnitSP SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx) { + CompUnitSP comp_unit_sp; + const uint32_t cu_count = GetNumCompileUnits(); + + if (cu_idx < cu_count) { + Module *oso_module = GetModuleByCompUnitInfo(&m_compile_unit_infos[cu_idx]); + if (oso_module) { + FileSpec so_file_spec; + if (GetFileSpecForSO(cu_idx, so_file_spec)) { + // User zero as the ID to match the compile unit at offset + // zero in each .o file since each .o file can only have + // one compile unit for now. + lldb::user_id_t cu_id = 0; + m_compile_unit_infos[cu_idx].compile_unit_sp.reset( + new CompileUnit(m_obj_file->GetModule(), NULL, so_file_spec, cu_id, + eLanguageTypeUnknown, eLazyBoolCalculate)); + + if (m_compile_unit_infos[cu_idx].compile_unit_sp) { + // Let our symbol vendor know about this compile unit + m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex( + cu_idx, m_compile_unit_infos[cu_idx].compile_unit_sp); } - comp_unit_sp = m_compile_unit_infos[cu_idx].compile_unit_sp; + } } + comp_unit_sp = m_compile_unit_infos[cu_idx].compile_unit_sp; + } - return comp_unit_sp; + return comp_unit_sp; } SymbolFileDWARFDebugMap::CompileUnitInfo * -SymbolFileDWARFDebugMap::GetCompUnitInfo (const SymbolContext& sc) -{ - 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()) - return &m_compile_unit_infos[i]; - } - return NULL; -} - -size_t -SymbolFileDWARFDebugMap::GetCompUnitInfosForModule (const lldb_private::Module *module, std::vector<CompileUnitInfo *>& cu_infos) -{ - const uint32_t cu_count = GetNumCompileUnits(); - for (uint32_t i=0; i<cu_count; ++i) - { - if (module == GetModuleByCompUnitInfo (&m_compile_unit_infos[i])) - cu_infos.push_back (&m_compile_unit_infos[i]); - } - return cu_infos.size(); +SymbolFileDWARFDebugMap::GetCompUnitInfo(const SymbolContext &sc) { + 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()) + return &m_compile_unit_infos[i]; + } + return NULL; +} + +size_t SymbolFileDWARFDebugMap::GetCompUnitInfosForModule( + const lldb_private::Module *module, + std::vector<CompileUnitInfo *> &cu_infos) { + const uint32_t cu_count = GetNumCompileUnits(); + for (uint32_t i = 0; i < cu_count; ++i) { + if (module == GetModuleByCompUnitInfo(&m_compile_unit_infos[i])) + cu_infos.push_back(&m_compile_unit_infos[i]); + } + return cu_infos.size(); } lldb::LanguageType -SymbolFileDWARFDebugMap::ParseCompileUnitLanguage (const SymbolContext& sc) -{ - SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); - if (oso_dwarf) - return oso_dwarf->ParseCompileUnitLanguage (sc); - return eLanguageTypeUnknown; +SymbolFileDWARFDebugMap::ParseCompileUnitLanguage(const SymbolContext &sc) { + SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); + if (oso_dwarf) + return oso_dwarf->ParseCompileUnitLanguage(sc); + return eLanguageTypeUnknown; } size_t -SymbolFileDWARFDebugMap::ParseCompileUnitFunctions (const SymbolContext& sc) -{ - SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); - if (oso_dwarf) - return oso_dwarf->ParseCompileUnitFunctions (sc); - return 0; +SymbolFileDWARFDebugMap::ParseCompileUnitFunctions(const SymbolContext &sc) { + SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); + if (oso_dwarf) + return oso_dwarf->ParseCompileUnitFunctions(sc); + return 0; } -bool -SymbolFileDWARFDebugMap::ParseCompileUnitLineTable (const SymbolContext& sc) -{ - SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); - if (oso_dwarf) - return oso_dwarf->ParseCompileUnitLineTable (sc); - return false; +bool SymbolFileDWARFDebugMap::ParseCompileUnitLineTable( + const SymbolContext &sc) { + SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); + if (oso_dwarf) + return oso_dwarf->ParseCompileUnitLineTable(sc); + return false; } -bool -SymbolFileDWARFDebugMap::ParseCompileUnitDebugMacros (const SymbolContext& sc) -{ - SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); - if (oso_dwarf) - return oso_dwarf->ParseCompileUnitDebugMacros (sc); - return false; +bool SymbolFileDWARFDebugMap::ParseCompileUnitDebugMacros( + const SymbolContext &sc) { + SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); + if (oso_dwarf) + return oso_dwarf->ParseCompileUnitDebugMacros(sc); + return false; } -bool -SymbolFileDWARFDebugMap::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files) -{ - SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); - if (oso_dwarf) - return oso_dwarf->ParseCompileUnitSupportFiles (sc, support_files); - return false; +bool SymbolFileDWARFDebugMap::ParseCompileUnitSupportFiles( + const SymbolContext &sc, FileSpecList &support_files) { + SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); + if (oso_dwarf) + return oso_dwarf->ParseCompileUnitSupportFiles(sc, support_files); + return false; } -bool -SymbolFileDWARFDebugMap::ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc) -{ - SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); - if (oso_dwarf) - return oso_dwarf->ParseCompileUnitIsOptimized(sc); - return false; +bool SymbolFileDWARFDebugMap::ParseCompileUnitIsOptimized( + const lldb_private::SymbolContext &sc) { + SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); + if (oso_dwarf) + return oso_dwarf->ParseCompileUnitIsOptimized(sc); + return false; } -bool -SymbolFileDWARFDebugMap::ParseImportedModules(const SymbolContext &sc, std::vector<ConstString> &imported_modules) -{ - SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); - if (oso_dwarf) - return oso_dwarf->ParseImportedModules(sc, imported_modules); - return false; +bool SymbolFileDWARFDebugMap::ParseImportedModules( + const SymbolContext &sc, std::vector<ConstString> &imported_modules) { + SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); + if (oso_dwarf) + return oso_dwarf->ParseImportedModules(sc, imported_modules); + return false; } -size_t -SymbolFileDWARFDebugMap::ParseFunctionBlocks (const SymbolContext& sc) -{ - SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); - if (oso_dwarf) - return oso_dwarf->ParseFunctionBlocks (sc); - return 0; +size_t SymbolFileDWARFDebugMap::ParseFunctionBlocks(const SymbolContext &sc) { + SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); + if (oso_dwarf) + return oso_dwarf->ParseFunctionBlocks(sc); + return 0; } -size_t -SymbolFileDWARFDebugMap::ParseTypes (const SymbolContext& sc) -{ - SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); - if (oso_dwarf) - return oso_dwarf->ParseTypes (sc); - return 0; +size_t SymbolFileDWARFDebugMap::ParseTypes(const SymbolContext &sc) { + SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); + if (oso_dwarf) + return oso_dwarf->ParseTypes(sc); + return 0; } size_t -SymbolFileDWARFDebugMap::ParseVariablesForContext (const SymbolContext& sc) -{ - SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); - if (oso_dwarf) - return oso_dwarf->ParseVariablesForContext (sc); - return 0; +SymbolFileDWARFDebugMap::ParseVariablesForContext(const SymbolContext &sc) { + SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); + if (oso_dwarf) + return oso_dwarf->ParseVariablesForContext(sc); + return 0; } -Type* -SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid) -{ - const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid); - SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx); - if (oso_dwarf) - return oso_dwarf->ResolveTypeUID (type_uid); - return NULL; +Type *SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid) { + const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid); + SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx); + if (oso_dwarf) + return oso_dwarf->ResolveTypeUID(type_uid); + return NULL; } -bool -SymbolFileDWARFDebugMap::CompleteType (CompilerType& compiler_type) -{ - bool success = false; - if (compiler_type) - { - ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { - if (oso_dwarf->HasForwardDeclForClangType (compiler_type)) - { - oso_dwarf->CompleteType (compiler_type); - success = true; - return true; +bool SymbolFileDWARFDebugMap::CompleteType(CompilerType &compiler_type) { + bool success = false; + if (compiler_type) { + ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { + if (oso_dwarf->HasForwardDeclForClangType(compiler_type)) { + oso_dwarf->CompleteType(compiler_type); + success = true; + return true; + } + return false; + }); + } + return success; +} + +uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext( + const Address &exe_so_addr, uint32_t resolve_scope, SymbolContext &sc) { + uint32_t resolved_flags = 0; + Symtab *symtab = m_obj_file->GetSymtab(); + if (symtab) { + const addr_t exe_file_addr = exe_so_addr.GetFileAddress(); + + const DebugMap::Entry *debug_map_entry = + m_debug_map.FindEntryThatContains(exe_file_addr); + if (debug_map_entry) { + + sc.symbol = + symtab->SymbolAtIndex(debug_map_entry->data.GetExeSymbolIndex()); + + if (sc.symbol != NULL) { + resolved_flags |= eSymbolContextSymbol; + + uint32_t oso_idx = 0; + CompileUnitInfo *comp_unit_info = + GetCompileUnitInfoForSymbolWithID(sc.symbol->GetID(), &oso_idx); + if (comp_unit_info) { + comp_unit_info->GetFileRangeMap(this); + Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info); + if (oso_module) { + lldb::addr_t oso_file_addr = + exe_file_addr - debug_map_entry->GetRangeBase() + + debug_map_entry->data.GetOSOFileAddress(); + Address oso_so_addr; + if (oso_module->ResolveFileAddress(oso_file_addr, oso_so_addr)) { + resolved_flags |= + oso_module->GetSymbolVendor()->ResolveSymbolContext( + oso_so_addr, resolve_scope, sc); } - return false; - }); + } + } + } + } + } + return resolved_flags; +} + +uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext( + const FileSpec &file_spec, uint32_t line, bool check_inlines, + uint32_t resolve_scope, SymbolContextList &sc_list) { + const uint32_t initial = sc_list.GetSize(); + const uint32_t cu_count = GetNumCompileUnits(); + + for (uint32_t i = 0; i < cu_count; ++i) { + // If we are checking for inlines, then we need to look through all + // compile units no matter if "file_spec" matches. + bool resolve = check_inlines; + + if (!resolve) { + FileSpec so_file_spec; + if (GetFileSpecForSO(i, so_file_spec)) { + // Match the full path if the incoming file_spec has a directory (not + // just a basename) + const bool full_match = (bool)file_spec.GetDirectory(); + resolve = FileSpec::Equal(file_spec, so_file_spec, full_match); + } } - return success; + if (resolve) { + SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(i); + if (oso_dwarf) + oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines, + resolve_scope, sc_list); + } + } + return sc_list.GetSize() - initial; } -uint32_t -SymbolFileDWARFDebugMap::ResolveSymbolContext (const Address& exe_so_addr, uint32_t resolve_scope, SymbolContext& sc) -{ - uint32_t resolved_flags = 0; - Symtab* symtab = m_obj_file->GetSymtab(); - if (symtab) - { - const addr_t exe_file_addr = exe_so_addr.GetFileAddress(); - - const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains (exe_file_addr); - if (debug_map_entry) - { - - sc.symbol = symtab->SymbolAtIndex(debug_map_entry->data.GetExeSymbolIndex()); - - if (sc.symbol != NULL) - { - resolved_flags |= eSymbolContextSymbol; - - uint32_t oso_idx = 0; - CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithID (sc.symbol->GetID(), &oso_idx); - if (comp_unit_info) - { - comp_unit_info->GetFileRangeMap(this); - Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info); - if (oso_module) - { - lldb::addr_t oso_file_addr = exe_file_addr - debug_map_entry->GetRangeBase() + debug_map_entry->data.GetOSOFileAddress(); - Address oso_so_addr; - if (oso_module->ResolveFileAddress(oso_file_addr, oso_so_addr)) - { - resolved_flags |= oso_module->GetSymbolVendor()->ResolveSymbolContext (oso_so_addr, resolve_scope, sc); - } - } - } - } - } +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) { + const uint32_t original_size = variables.GetSize(); + const size_t match_count = indexes.size(); + for (size_t i = 0; i < match_count; ++i) { + uint32_t oso_idx; + CompileUnitInfo *comp_unit_info = + GetCompileUnitInfoForSymbolWithIndex(indexes[i], &oso_idx); + if (comp_unit_info) { + SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx); + if (oso_dwarf) { + if (oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, true, + max_matches, variables)) + if (variables.GetSize() > max_matches) + break; + } } - return resolved_flags; + } + return variables.GetSize() - original_size; } -uint32_t -SymbolFileDWARFDebugMap::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) -{ - const uint32_t initial = sc_list.GetSize(); - const uint32_t cu_count = GetNumCompileUnits(); +uint32_t SymbolFileDWARFDebugMap::FindGlobalVariables( + const ConstString &name, const CompilerDeclContext *parent_decl_ctx, + bool append, uint32_t max_matches, VariableList &variables) { - for (uint32_t i=0; i<cu_count; ++i) - { - // If we are checking for inlines, then we need to look through all - // compile units no matter if "file_spec" matches. - bool resolve = check_inlines; - - if (!resolve) - { - FileSpec so_file_spec; - if (GetFileSpecForSO (i, so_file_spec)) - { - // Match the full path if the incoming file_spec has a directory (not just a basename) - const bool full_match = (bool)file_spec.GetDirectory(); - resolve = FileSpec::Equal (file_spec, so_file_spec, full_match); - } - } - if (resolve) - { - SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (i); - if (oso_dwarf) - oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope, sc_list); - } - } - return sc_list.GetSize() - initial; -} + // If we aren't appending the results to this list, then clear the list + if (!append) + variables.Clear(); -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 -) -{ - const uint32_t original_size = variables.GetSize(); - const size_t match_count = indexes.size(); - for (size_t i=0; i<match_count; ++i) - { - uint32_t oso_idx; - CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithIndex (indexes[i], &oso_idx); - if (comp_unit_info) - { - SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx); - if (oso_dwarf) - { - if (oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, true, max_matches, variables)) - if (variables.GetSize() > max_matches) - break; - } - } + // Remember how many variables are in the list before we search in case + // we are appending the results to a variable list. + const uint32_t original_size = variables.GetSize(); + + uint32_t total_matches = 0; + + ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { + const uint32_t oso_matches = oso_dwarf->FindGlobalVariables( + name, parent_decl_ctx, true, max_matches, variables); + if (oso_matches > 0) { + total_matches += oso_matches; + + // Are we getting all matches? + if (max_matches == UINT32_MAX) + return false; // Yep, continue getting everything + + // If we have found enough matches, lets get out + if (max_matches >= total_matches) + return true; + + // Update the max matches for any subsequent calls to find globals + // in any other object files with DWARF + max_matches -= oso_matches; } - return variables.GetSize() - original_size; -} -uint32_t -SymbolFileDWARFDebugMap::FindGlobalVariables (const ConstString &name, - const CompilerDeclContext *parent_decl_ctx, - bool append, - uint32_t max_matches, - VariableList& variables) -{ - - // If we aren't appending the results to this list, then clear the list - if (!append) - variables.Clear(); - - // Remember how many variables are in the list before we search in case - // we are appending the results to a variable list. - const uint32_t original_size = variables.GetSize(); - - uint32_t total_matches = 0; - - ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { - const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (name, - parent_decl_ctx, - true, - max_matches, - variables); - if (oso_matches > 0) - { - total_matches += oso_matches; - - // Are we getting all matches? - if (max_matches == UINT32_MAX) - return false; // Yep, continue getting everything - - // If we have found enough matches, lets get out - if (max_matches >= total_matches) - return true; - - // Update the max matches for any subsequent calls to find globals - // in any other object files with DWARF - max_matches -= oso_matches; - } - - return false; - }); + return false; + }); - // Return the number of variable that were appended to the list - return variables.GetSize() - original_size; + // Return the number of variable that were appended to the list + return variables.GetSize() - original_size; } uint32_t -SymbolFileDWARFDebugMap::FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables) -{ - // If we aren't appending the results to this list, then clear the list - if (!append) - variables.Clear(); +SymbolFileDWARFDebugMap::FindGlobalVariables(const RegularExpression ®ex, + bool append, uint32_t max_matches, + VariableList &variables) { + // If we aren't appending the results to this list, then clear the list + if (!append) + variables.Clear(); + + // Remember how many variables are in the list before we search in case + // we are appending the results to a variable list. + const uint32_t original_size = variables.GetSize(); + + uint32_t total_matches = 0; + ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { + const uint32_t oso_matches = + oso_dwarf->FindGlobalVariables(regex, true, max_matches, variables); + if (oso_matches > 0) { + total_matches += oso_matches; + + // Are we getting all matches? + if (max_matches == UINT32_MAX) + return false; // Yep, continue getting everything + + // If we have found enough matches, lets get out + if (max_matches >= total_matches) + return true; - // Remember how many variables are in the list before we search in case - // we are appending the results to a variable list. - const uint32_t original_size = variables.GetSize(); + // Update the max matches for any subsequent calls to find globals + // in any other object files with DWARF + max_matches -= oso_matches; + } - uint32_t total_matches = 0; - ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { - const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (regex, - true, - max_matches, - variables); - if (oso_matches > 0) - { - total_matches += oso_matches; - - // Are we getting all matches? - if (max_matches == UINT32_MAX) - return false; // Yep, continue getting everything - - // If we have found enough matches, lets get out - if (max_matches >= total_matches) - return true; - - // Update the max matches for any subsequent calls to find globals - // in any other object files with DWARF - max_matches -= oso_matches; - } - - return false; - }); - - // Return the number of variable that were appended to the list - return variables.GetSize() - original_size; + return false; + }); + + // Return the number of variable that were appended to the list + return variables.GetSize() - original_size; } -int -SymbolFileDWARFDebugMap::SymbolContainsSymbolWithIndex (uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info) -{ - const uint32_t symbol_idx = *symbol_idx_ptr; +int SymbolFileDWARFDebugMap::SymbolContainsSymbolWithIndex( + uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info) { + const uint32_t symbol_idx = *symbol_idx_ptr; - if (symbol_idx < comp_unit_info->first_symbol_index) - return -1; + if (symbol_idx < comp_unit_info->first_symbol_index) + return -1; - if (symbol_idx <= comp_unit_info->last_symbol_index) - return 0; + if (symbol_idx <= comp_unit_info->last_symbol_index) + return 0; - return 1; + return 1; } -int -SymbolFileDWARFDebugMap::SymbolContainsSymbolWithID (user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info) -{ - const user_id_t symbol_id = *symbol_idx_ptr; +int SymbolFileDWARFDebugMap::SymbolContainsSymbolWithID( + user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info) { + const user_id_t symbol_id = *symbol_idx_ptr; - if (symbol_id < comp_unit_info->first_symbol_id) - return -1; + if (symbol_id < comp_unit_info->first_symbol_id) + return -1; - if (symbol_id <= comp_unit_info->last_symbol_id) - return 0; + if (symbol_id <= comp_unit_info->last_symbol_id) + return 0; - return 1; + return 1; } -SymbolFileDWARFDebugMap::CompileUnitInfo* -SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithIndex (uint32_t symbol_idx, uint32_t *oso_idx_ptr) -{ - const uint32_t oso_index_count = m_compile_unit_infos.size(); - CompileUnitInfo *comp_unit_info = NULL; - if (oso_index_count) - { - comp_unit_info = (CompileUnitInfo*)bsearch(&symbol_idx, - &m_compile_unit_infos[0], - m_compile_unit_infos.size(), - sizeof(CompileUnitInfo), - (ComparisonFunction)SymbolContainsSymbolWithIndex); - } +SymbolFileDWARFDebugMap::CompileUnitInfo * +SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithIndex( + uint32_t symbol_idx, uint32_t *oso_idx_ptr) { + const uint32_t oso_index_count = m_compile_unit_infos.size(); + CompileUnitInfo *comp_unit_info = NULL; + if (oso_index_count) { + comp_unit_info = (CompileUnitInfo *)bsearch( + &symbol_idx, &m_compile_unit_infos[0], m_compile_unit_infos.size(), + sizeof(CompileUnitInfo), + (ComparisonFunction)SymbolContainsSymbolWithIndex); + } + + if (oso_idx_ptr) { + if (comp_unit_info != NULL) + *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0]; + else + *oso_idx_ptr = UINT32_MAX; + } + return comp_unit_info; +} - if (oso_idx_ptr) - { - if (comp_unit_info != NULL) - *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0]; - else - *oso_idx_ptr = UINT32_MAX; +SymbolFileDWARFDebugMap::CompileUnitInfo * +SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithID( + user_id_t symbol_id, uint32_t *oso_idx_ptr) { + const uint32_t oso_index_count = m_compile_unit_infos.size(); + CompileUnitInfo *comp_unit_info = NULL; + if (oso_index_count) { + comp_unit_info = (CompileUnitInfo *)::bsearch( + &symbol_id, &m_compile_unit_infos[0], m_compile_unit_infos.size(), + sizeof(CompileUnitInfo), + (ComparisonFunction)SymbolContainsSymbolWithID); + } + + if (oso_idx_ptr) { + if (comp_unit_info != NULL) + *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0]; + else + *oso_idx_ptr = UINT32_MAX; + } + return comp_unit_info; +} + +static void RemoveFunctionsWithModuleNotEqualTo(const ModuleSP &module_sp, + SymbolContextList &sc_list, + uint32_t start_idx) { + // We found functions in .o files. Not all functions in the .o files + // will have made it into the final output file. The ones that did + // make it into the final output file will have a section whose module + // matches the module from the ObjectFile for this SymbolFile. When + // the modules don't match, then we have something that was in a + // .o file, but doesn't map to anything in the final executable. + uint32_t i = start_idx; + while (i < sc_list.GetSize()) { + SymbolContext sc; + sc_list.GetContextAtIndex(i, sc); + if (sc.function) { + const SectionSP section_sp( + sc.function->GetAddressRange().GetBaseAddress().GetSection()); + if (section_sp->GetModule() != module_sp) { + sc_list.RemoveContextAtIndex(i); + continue; + } } - return comp_unit_info; -} - -SymbolFileDWARFDebugMap::CompileUnitInfo* -SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithID (user_id_t symbol_id, uint32_t *oso_idx_ptr) -{ - const uint32_t oso_index_count = m_compile_unit_infos.size(); - CompileUnitInfo *comp_unit_info = NULL; - if (oso_index_count) - { - comp_unit_info = (CompileUnitInfo*)::bsearch (&symbol_id, - &m_compile_unit_infos[0], - m_compile_unit_infos.size(), - sizeof(CompileUnitInfo), - (ComparisonFunction)SymbolContainsSymbolWithID); + ++i; + } +} + +uint32_t SymbolFileDWARFDebugMap::FindFunctions( + const ConstString &name, const CompilerDeclContext *parent_decl_ctx, + uint32_t name_type_mask, bool include_inlines, bool append, + SymbolContextList &sc_list) { + Timer scoped_timer(LLVM_PRETTY_FUNCTION, + "SymbolFileDWARFDebugMap::FindFunctions (name = %s)", + name.GetCString()); + + uint32_t initial_size = 0; + if (append) + initial_size = sc_list.GetSize(); + else + sc_list.Clear(); + + ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { + uint32_t sc_idx = sc_list.GetSize(); + if (oso_dwarf->FindFunctions(name, parent_decl_ctx, name_type_mask, + include_inlines, true, sc_list)) { + RemoveFunctionsWithModuleNotEqualTo(m_obj_file->GetModule(), sc_list, + sc_idx); } + return false; + }); - if (oso_idx_ptr) - { - if (comp_unit_info != NULL) - *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0]; - else - *oso_idx_ptr = UINT32_MAX; - } - return comp_unit_info; -} - -static void -RemoveFunctionsWithModuleNotEqualTo (const ModuleSP &module_sp, SymbolContextList &sc_list, uint32_t start_idx) -{ - // We found functions in .o files. Not all functions in the .o files - // will have made it into the final output file. The ones that did - // make it into the final output file will have a section whose module - // matches the module from the ObjectFile for this SymbolFile. When - // the modules don't match, then we have something that was in a - // .o file, but doesn't map to anything in the final executable. - uint32_t i=start_idx; - while (i < sc_list.GetSize()) - { - SymbolContext sc; - sc_list.GetContextAtIndex(i, sc); - if (sc.function) - { - const SectionSP section_sp (sc.function->GetAddressRange().GetBaseAddress().GetSection()); - if (section_sp->GetModule() != module_sp) - { - sc_list.RemoveContextAtIndex(i); - continue; - } - } - ++i; - } + return sc_list.GetSize() - initial_size; } -uint32_t -SymbolFileDWARFDebugMap::FindFunctions(const ConstString &name, - const CompilerDeclContext *parent_decl_ctx, - uint32_t name_type_mask, - bool include_inlines, - bool append, - SymbolContextList& sc_list) -{ - Timer scoped_timer (__PRETTY_FUNCTION__, - "SymbolFileDWARFDebugMap::FindFunctions (name = %s)", - name.GetCString()); - - uint32_t initial_size = 0; - if (append) - initial_size = sc_list.GetSize(); - else - sc_list.Clear(); +uint32_t SymbolFileDWARFDebugMap::FindFunctions(const RegularExpression ®ex, + bool include_inlines, + bool append, + SymbolContextList &sc_list) { + Timer scoped_timer(LLVM_PRETTY_FUNCTION, + "SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')", + regex.GetText().str().c_str()); - ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { - uint32_t sc_idx = sc_list.GetSize(); - if (oso_dwarf->FindFunctions(name, parent_decl_ctx, name_type_mask, include_inlines, true, sc_list)) - { - RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx); - } - return false; - }); + uint32_t initial_size = 0; + if (append) + initial_size = sc_list.GetSize(); + else + sc_list.Clear(); - return sc_list.GetSize() - initial_size; + ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { + uint32_t sc_idx = sc_list.GetSize(); + + if (oso_dwarf->FindFunctions(regex, include_inlines, true, sc_list)) { + RemoveFunctionsWithModuleNotEqualTo(m_obj_file->GetModule(), sc_list, + sc_idx); + } + return false; + }); + + return sc_list.GetSize() - initial_size; } -uint32_t -SymbolFileDWARFDebugMap::FindFunctions (const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list) -{ - Timer scoped_timer (__PRETTY_FUNCTION__, - "SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')", - regex.GetText()); - - uint32_t initial_size = 0; - if (append) - initial_size = sc_list.GetSize(); - else - sc_list.Clear(); +size_t SymbolFileDWARFDebugMap::GetTypes(SymbolContextScope *sc_scope, + uint32_t type_mask, + TypeList &type_list) { + Timer scoped_timer(LLVM_PRETTY_FUNCTION, + "SymbolFileDWARFDebugMap::GetTypes (type_mask = 0x%8.8x)", + type_mask); + uint32_t initial_size = type_list.GetSize(); + SymbolFileDWARF *oso_dwarf = NULL; + if (sc_scope) { + SymbolContext sc; + sc_scope->CalculateSymbolContext(&sc); + + CompileUnitInfo *cu_info = GetCompUnitInfo(sc); + if (cu_info) { + oso_dwarf = GetSymbolFileByCompUnitInfo(cu_info); + if (oso_dwarf) + oso_dwarf->GetTypes(sc_scope, type_mask, type_list); + } + } else { ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { - uint32_t sc_idx = sc_list.GetSize(); - - if (oso_dwarf->FindFunctions(regex, include_inlines, true, sc_list)) - { - RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx); - } - return false; + oso_dwarf->GetTypes(sc_scope, type_mask, type_list); + return false; }); - - return sc_list.GetSize() - initial_size; + } + return type_list.GetSize() - initial_size; } -size_t -SymbolFileDWARFDebugMap::GetTypes (SymbolContextScope *sc_scope, - uint32_t type_mask, - TypeList &type_list) -{ - Timer scoped_timer (__PRETTY_FUNCTION__, - "SymbolFileDWARFDebugMap::GetTypes (type_mask = 0x%8.8x)", - type_mask); - - uint32_t initial_size = type_list.GetSize(); - SymbolFileDWARF *oso_dwarf = NULL; - if (sc_scope) - { - SymbolContext sc; - sc_scope->CalculateSymbolContext(&sc); - - CompileUnitInfo *cu_info = GetCompUnitInfo (sc); - if (cu_info) - { - oso_dwarf = GetSymbolFileByCompUnitInfo (cu_info); - if (oso_dwarf) - oso_dwarf->GetTypes (sc_scope, type_mask, type_list); - } - } - else - { - ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { - oso_dwarf->GetTypes (sc_scope, type_mask, type_list); - return false; - }); - } - return type_list.GetSize() - initial_size; +TypeSP SymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext( + const DWARFDeclContext &die_decl_ctx) { + TypeSP type_sp; + ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { + type_sp = oso_dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx); + return ((bool)type_sp); + }); + return type_sp; } -TypeSP -SymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx) -{ - TypeSP type_sp; +bool SymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type( + SymbolFileDWARF *skip_dwarf_oso) { + if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate) { + m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo; ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { - type_sp = oso_dwarf->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx); - return ((bool)type_sp); + if (skip_dwarf_oso != oso_dwarf && + oso_dwarf->Supports_DW_AT_APPLE_objc_complete_type(NULL)) { + m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes; + return true; + } + return false; }); - return type_sp; -} - -bool -SymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type (SymbolFileDWARF *skip_dwarf_oso) -{ - if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate) - { - m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo; - ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { - if (skip_dwarf_oso != oso_dwarf && oso_dwarf->Supports_DW_AT_APPLE_objc_complete_type(NULL)) - { - m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes; - return true; - } - return false; - }); - } - return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes; -} - -TypeSP -SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE (const DWARFDIE &die, - const ConstString &type_name, - bool must_be_implementation) -{ - // If we have a debug map, we will have an Objective C symbol whose name is - // the type name and whose type is eSymbolTypeObjCClass. If we can find that - // symbol and find its containing parent, we can locate the .o file that will - // contain the implementation definition since it will be scoped inside the N_SO - // and we can then locate the SymbolFileDWARF that corresponds to that N_SO. - SymbolFileDWARF *oso_dwarf = NULL; - TypeSP type_sp; - ObjectFile *module_objfile = m_obj_file->GetModule()->GetObjectFile(); - if (module_objfile) - { - Symtab *symtab = module_objfile->GetSymtab(); - if (symtab) - { - Symbol *objc_class_symbol = symtab->FindFirstSymbolWithNameAndType(type_name, eSymbolTypeObjCClass, Symtab::eDebugAny, Symtab::eVisibilityAny); - if (objc_class_symbol) - { - // Get the N_SO symbol that contains the objective C class symbol as this - // should be the .o file that contains the real definition... - const Symbol *source_file_symbol = symtab->GetParent(objc_class_symbol); - - if (source_file_symbol && source_file_symbol->GetType() == eSymbolTypeSourceFile) - { - const uint32_t source_file_symbol_idx = symtab->GetIndexForSymbol(source_file_symbol); - if (source_file_symbol_idx != UINT32_MAX) - { - CompileUnitInfo *compile_unit_info = GetCompileUnitInfoForSymbolWithIndex (source_file_symbol_idx, NULL); - if (compile_unit_info) - { - oso_dwarf = GetSymbolFileByCompUnitInfo (compile_unit_info); - if (oso_dwarf) - { - TypeSP type_sp (oso_dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name, must_be_implementation)); - if (type_sp) - { - return type_sp; - } - } - } - } + } + return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes; +} + +TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE( + const DWARFDIE &die, const ConstString &type_name, + bool must_be_implementation) { + // If we have a debug map, we will have an Objective C symbol whose name is + // the type name and whose type is eSymbolTypeObjCClass. If we can find that + // symbol and find its containing parent, we can locate the .o file that will + // contain the implementation definition since it will be scoped inside the + // N_SO + // and we can then locate the SymbolFileDWARF that corresponds to that N_SO. + SymbolFileDWARF *oso_dwarf = NULL; + TypeSP type_sp; + ObjectFile *module_objfile = m_obj_file->GetModule()->GetObjectFile(); + if (module_objfile) { + Symtab *symtab = module_objfile->GetSymtab(); + if (symtab) { + Symbol *objc_class_symbol = symtab->FindFirstSymbolWithNameAndType( + type_name, eSymbolTypeObjCClass, Symtab::eDebugAny, + Symtab::eVisibilityAny); + if (objc_class_symbol) { + // Get the N_SO symbol that contains the objective C class symbol as + // this + // should be the .o file that contains the real definition... + const Symbol *source_file_symbol = symtab->GetParent(objc_class_symbol); + + if (source_file_symbol && + source_file_symbol->GetType() == eSymbolTypeSourceFile) { + const uint32_t source_file_symbol_idx = + symtab->GetIndexForSymbol(source_file_symbol); + if (source_file_symbol_idx != UINT32_MAX) { + CompileUnitInfo *compile_unit_info = + GetCompileUnitInfoForSymbolWithIndex(source_file_symbol_idx, + NULL); + if (compile_unit_info) { + oso_dwarf = GetSymbolFileByCompUnitInfo(compile_unit_info); + if (oso_dwarf) { + TypeSP type_sp(oso_dwarf->FindCompleteObjCDefinitionTypeForDIE( + die, type_name, must_be_implementation)); + if (type_sp) { + return type_sp; } + } } + } } + } } + } + + // 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) { + TypeSP type_sp; - // 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) - { - TypeSP type_sp; - - ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { - type_sp = oso_dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name, must_be_implementation); - return (bool)type_sp; - }); - - return type_sp; - } - return TypeSP(); + ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { + type_sp = oso_dwarf->FindCompleteObjCDefinitionTypeForDIE( + die, type_name, must_be_implementation); + return (bool)type_sp; + }); + + return type_sp; + } + return TypeSP(); } -uint32_t -SymbolFileDWARFDebugMap::FindTypes -( - const SymbolContext& sc, - const ConstString &name, - const CompilerDeclContext *parent_decl_ctx, - bool append, +uint32_t SymbolFileDWARFDebugMap::FindTypes( + const SymbolContext &sc, 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; - }); - } + TypeMap &types) { + if (!append) + types.Clear(); + + const uint32_t initial_types_size = types.GetSize(); + SymbolFileDWARF *oso_dwarf; - return types.GetSize() - initial_types_size; + 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; + }); + } + + return types.GetSize() - initial_types_size; } // -//uint32_t -//SymbolFileDWARFDebugMap::FindTypes (const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types) +// uint32_t +// SymbolFileDWARFDebugMap::FindTypes (const SymbolContext& sc, const +// RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding +// encoding, lldb::user_id_t udt_uid, TypeList& types) //{ // SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); // if (oso_dwarf) -// return oso_dwarf->FindTypes (sc, regex, append, max_matches, encoding, udt_uid, types); +// return oso_dwarf->FindTypes (sc, regex, append, max_matches, encoding, +// udt_uid, types); // return 0; //} +CompilerDeclContext SymbolFileDWARFDebugMap::FindNamespace( + const lldb_private::SymbolContext &sc, + const lldb_private::ConstString &name, + const CompilerDeclContext *parent_decl_ctx) { + CompilerDeclContext matching_namespace; + SymbolFileDWARF *oso_dwarf; -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); + 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); - return (bool)matching_namespace; - }); - } + return (bool)matching_namespace; + }); + } - return matching_namespace; + return matching_namespace; } //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ -lldb_private::ConstString -SymbolFileDWARFDebugMap::GetPluginName() -{ - return GetPluginNameStatic(); +lldb_private::ConstString SymbolFileDWARFDebugMap::GetPluginName() { + return GetPluginNameStatic(); } -uint32_t -SymbolFileDWARFDebugMap::GetPluginVersion() -{ - return 1; -} +uint32_t SymbolFileDWARFDebugMap::GetPluginVersion() { return 1; } lldb::CompUnitSP -SymbolFileDWARFDebugMap::GetCompileUnit (SymbolFileDWARF *oso_dwarf) -{ - if (oso_dwarf) - { - const uint32_t cu_count = GetNumCompileUnits(); - for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx) - { - SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]); - if (oso_symfile == oso_dwarf) - { - if (!m_compile_unit_infos[cu_idx].compile_unit_sp) - m_compile_unit_infos[cu_idx].compile_unit_sp = ParseCompileUnitAtIndex (cu_idx); - - return m_compile_unit_infos[cu_idx].compile_unit_sp; - } - } +SymbolFileDWARFDebugMap::GetCompileUnit(SymbolFileDWARF *oso_dwarf) { + if (oso_dwarf) { + const uint32_t cu_count = GetNumCompileUnits(); + for (uint32_t cu_idx = 0; cu_idx < cu_count; ++cu_idx) { + SymbolFileDWARF *oso_symfile = + GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[cu_idx]); + if (oso_symfile == oso_dwarf) { + if (!m_compile_unit_infos[cu_idx].compile_unit_sp) + m_compile_unit_infos[cu_idx].compile_unit_sp = + ParseCompileUnitAtIndex(cu_idx); + + return m_compile_unit_infos[cu_idx].compile_unit_sp; + } } - assert(!"this shouldn't happen"); - return lldb::CompUnitSP(); + } + assert(!"this shouldn't happen"); + return lldb::CompUnitSP(); } SymbolFileDWARFDebugMap::CompileUnitInfo * -SymbolFileDWARFDebugMap::GetCompileUnitInfo (SymbolFileDWARF *oso_dwarf) -{ - if (oso_dwarf) - { - const uint32_t cu_count = GetNumCompileUnits(); - for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx) - { - SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]); - if (oso_symfile == oso_dwarf) - { - return &m_compile_unit_infos[cu_idx]; - } - } +SymbolFileDWARFDebugMap::GetCompileUnitInfo(SymbolFileDWARF *oso_dwarf) { + if (oso_dwarf) { + const uint32_t cu_count = GetNumCompileUnits(); + for (uint32_t cu_idx = 0; cu_idx < cu_count; ++cu_idx) { + SymbolFileDWARF *oso_symfile = + GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[cu_idx]); + if (oso_symfile == oso_dwarf) { + return &m_compile_unit_infos[cu_idx]; + } } - return NULL; + } + return NULL; } -void -SymbolFileDWARFDebugMap::SetCompileUnit (SymbolFileDWARF *oso_dwarf, const CompUnitSP &cu_sp) -{ - if (oso_dwarf) - { - const uint32_t cu_count = GetNumCompileUnits(); - for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx) - { - SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]); - if (oso_symfile == oso_dwarf) - { - if (m_compile_unit_infos[cu_idx].compile_unit_sp) - { - assert (m_compile_unit_infos[cu_idx].compile_unit_sp.get() == cu_sp.get()); - } - else - { - m_compile_unit_infos[cu_idx].compile_unit_sp = cu_sp; - m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp); - } - } +void SymbolFileDWARFDebugMap::SetCompileUnit(SymbolFileDWARF *oso_dwarf, + const CompUnitSP &cu_sp) { + if (oso_dwarf) { + const uint32_t cu_count = GetNumCompileUnits(); + for (uint32_t cu_idx = 0; cu_idx < cu_count; ++cu_idx) { + SymbolFileDWARF *oso_symfile = + GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[cu_idx]); + if (oso_symfile == oso_dwarf) { + if (m_compile_unit_infos[cu_idx].compile_unit_sp) { + assert(m_compile_unit_infos[cu_idx].compile_unit_sp.get() == + cu_sp.get()); + } else { + m_compile_unit_infos[cu_idx].compile_unit_sp = cu_sp; + m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex( + cu_idx, cu_sp); } + } } + } } CompilerDeclContext -SymbolFileDWARFDebugMap::GetDeclContextForUID (lldb::user_id_t type_uid) -{ - const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid); - SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx); - if (oso_dwarf) - return oso_dwarf->GetDeclContextForUID (type_uid); - return CompilerDeclContext(); +SymbolFileDWARFDebugMap::GetDeclContextForUID(lldb::user_id_t type_uid) { + const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid); + SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx); + if (oso_dwarf) + return oso_dwarf->GetDeclContextForUID(type_uid); + return CompilerDeclContext(); } CompilerDeclContext -SymbolFileDWARFDebugMap::GetDeclContextContainingUID (lldb::user_id_t type_uid) -{ - const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid); - SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx); - if (oso_dwarf) - return oso_dwarf->GetDeclContextContainingUID (type_uid); - return CompilerDeclContext(); -} - -void -SymbolFileDWARFDebugMap::ParseDeclsForContext (lldb_private::CompilerDeclContext decl_ctx) -{ - ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { - oso_dwarf->ParseDeclsForContext (decl_ctx); - return true; // Keep iterating - }); -} - -bool -SymbolFileDWARFDebugMap::AddOSOFileRange (CompileUnitInfo *cu_info, - lldb::addr_t exe_file_addr, - lldb::addr_t exe_byte_size, - lldb::addr_t oso_file_addr, - lldb::addr_t oso_byte_size) -{ - const uint32_t debug_map_idx = m_debug_map.FindEntryIndexThatContains(exe_file_addr); - if (debug_map_idx != UINT32_MAX) - { - DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(exe_file_addr); - debug_map_entry->data.SetOSOFileAddress(oso_file_addr); - addr_t range_size = std::min<addr_t>(exe_byte_size, oso_byte_size); - if (range_size == 0) - { - range_size = std::max<addr_t>(exe_byte_size, oso_byte_size); - if (range_size == 0) - range_size = 1; - } - cu_info->file_range_map.Append(FileRangeMap::Entry(oso_file_addr, range_size, exe_file_addr)); - return true; +SymbolFileDWARFDebugMap::GetDeclContextContainingUID(lldb::user_id_t type_uid) { + const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid); + SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx); + if (oso_dwarf) + return oso_dwarf->GetDeclContextContainingUID(type_uid); + return CompilerDeclContext(); +} + +void SymbolFileDWARFDebugMap::ParseDeclsForContext( + lldb_private::CompilerDeclContext decl_ctx) { + ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { + oso_dwarf->ParseDeclsForContext(decl_ctx); + return true; // Keep iterating + }); +} + +bool SymbolFileDWARFDebugMap::AddOSOFileRange(CompileUnitInfo *cu_info, + lldb::addr_t exe_file_addr, + lldb::addr_t exe_byte_size, + lldb::addr_t oso_file_addr, + lldb::addr_t oso_byte_size) { + const uint32_t debug_map_idx = + m_debug_map.FindEntryIndexThatContains(exe_file_addr); + if (debug_map_idx != UINT32_MAX) { + DebugMap::Entry *debug_map_entry = + m_debug_map.FindEntryThatContains(exe_file_addr); + debug_map_entry->data.SetOSOFileAddress(oso_file_addr); + addr_t range_size = std::min<addr_t>(exe_byte_size, oso_byte_size); + if (range_size == 0) { + range_size = std::max<addr_t>(exe_byte_size, oso_byte_size); + if (range_size == 0) + range_size = 1; } - return false; + cu_info->file_range_map.Append( + FileRangeMap::Entry(oso_file_addr, range_size, exe_file_addr)); + return true; + } + return false; } -void -SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (CompileUnitInfo *cu_info) -{ - cu_info->file_range_map.Sort(); +void SymbolFileDWARFDebugMap::FinalizeOSOFileRanges(CompileUnitInfo *cu_info) { + cu_info->file_range_map.Sort(); #if defined(DEBUG_OSO_DMAP) - const FileRangeMap &oso_file_range_map = cu_info->GetFileRangeMap(this); - const size_t n = oso_file_range_map.GetSize(); - printf ("SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (cu_info = %p) %s\n", - cu_info, - cu_info->oso_sp->module_sp->GetFileSpec().GetPath().c_str()); - for (size_t i=0; i<n; ++i) - { - const FileRangeMap::Entry &entry = oso_file_range_map.GetEntryRef(i); - printf ("oso [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") ==> exe [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n", - entry.GetRangeBase(), entry.GetRangeEnd(), - entry.data, entry.data + entry.GetByteSize()); - } + const FileRangeMap &oso_file_range_map = cu_info->GetFileRangeMap(this); + const size_t n = oso_file_range_map.GetSize(); + printf("SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (cu_info = %p) %s\n", + cu_info, cu_info->oso_sp->module_sp->GetFileSpec().GetPath().c_str()); + for (size_t i = 0; i < n; ++i) { + const FileRangeMap::Entry &entry = oso_file_range_map.GetEntryRef(i); + printf("oso [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 + ") ==> exe [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n", + entry.GetRangeBase(), entry.GetRangeEnd(), entry.data, + entry.data + entry.GetByteSize()); + } #endif } lldb::addr_t -SymbolFileDWARFDebugMap::LinkOSOFileAddress (SymbolFileDWARF *oso_symfile, lldb::addr_t oso_file_addr) -{ - CompileUnitInfo *cu_info = GetCompileUnitInfo (oso_symfile); - if (cu_info) - { - const FileRangeMap::Entry *oso_range_entry = cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr); - if (oso_range_entry) - { - const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(oso_range_entry->data); - if (debug_map_entry) - { - const lldb::addr_t offset = oso_file_addr - oso_range_entry->GetRangeBase(); - const lldb::addr_t exe_file_addr = debug_map_entry->GetRangeBase() + offset; - return exe_file_addr; - } - } +SymbolFileDWARFDebugMap::LinkOSOFileAddress(SymbolFileDWARF *oso_symfile, + lldb::addr_t oso_file_addr) { + CompileUnitInfo *cu_info = GetCompileUnitInfo(oso_symfile); + if (cu_info) { + const FileRangeMap::Entry *oso_range_entry = + cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr); + if (oso_range_entry) { + const DebugMap::Entry *debug_map_entry = + m_debug_map.FindEntryThatContains(oso_range_entry->data); + if (debug_map_entry) { + const lldb::addr_t offset = + oso_file_addr - oso_range_entry->GetRangeBase(); + const lldb::addr_t exe_file_addr = + debug_map_entry->GetRangeBase() + offset; + return exe_file_addr; + } } - return LLDB_INVALID_ADDRESS; -} - -bool -SymbolFileDWARFDebugMap::LinkOSOAddress (Address &addr) -{ - // Make sure this address hasn't been fixed already - Module *exe_module = GetObjectFile()->GetModule().get(); - Module *addr_module = addr.GetModule().get(); - if (addr_module == exe_module) - return true; // Address is already in terms of the main executable module - - CompileUnitInfo *cu_info = GetCompileUnitInfo (GetSymbolFileAsSymbolFileDWARF(addr_module->GetSymbolVendor()->GetSymbolFile())); - if (cu_info) - { - const lldb::addr_t oso_file_addr = addr.GetFileAddress(); - const FileRangeMap::Entry *oso_range_entry = cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr); - if (oso_range_entry) - { - const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(oso_range_entry->data); - if (debug_map_entry) - { - const lldb::addr_t offset = oso_file_addr - oso_range_entry->GetRangeBase(); - const lldb::addr_t exe_file_addr = debug_map_entry->GetRangeBase() + offset; - return exe_module->ResolveFileAddress(exe_file_addr, addr); - } - } + } + return LLDB_INVALID_ADDRESS; +} + +bool SymbolFileDWARFDebugMap::LinkOSOAddress(Address &addr) { + // Make sure this address hasn't been fixed already + Module *exe_module = GetObjectFile()->GetModule().get(); + Module *addr_module = addr.GetModule().get(); + if (addr_module == exe_module) + return true; // Address is already in terms of the main executable module + + CompileUnitInfo *cu_info = GetCompileUnitInfo(GetSymbolFileAsSymbolFileDWARF( + addr_module->GetSymbolVendor()->GetSymbolFile())); + if (cu_info) { + const lldb::addr_t oso_file_addr = addr.GetFileAddress(); + const FileRangeMap::Entry *oso_range_entry = + cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr); + if (oso_range_entry) { + const DebugMap::Entry *debug_map_entry = + m_debug_map.FindEntryThatContains(oso_range_entry->data); + if (debug_map_entry) { + const lldb::addr_t offset = + oso_file_addr - oso_range_entry->GetRangeBase(); + const lldb::addr_t exe_file_addr = + debug_map_entry->GetRangeBase() + offset; + return exe_module->ResolveFileAddress(exe_file_addr, addr); + } } - return true; + } + return true; } -LineTable * -SymbolFileDWARFDebugMap::LinkOSOLineTable (SymbolFileDWARF *oso_dwarf, LineTable *line_table) -{ - CompileUnitInfo *cu_info = GetCompileUnitInfo (oso_dwarf); - if (cu_info) - return line_table->LinkLineTable(cu_info->GetFileRangeMap(this)); - return NULL; +LineTable *SymbolFileDWARFDebugMap::LinkOSOLineTable(SymbolFileDWARF *oso_dwarf, + LineTable *line_table) { + CompileUnitInfo *cu_info = GetCompileUnitInfo(oso_dwarf); + if (cu_info) + return line_table->LinkLineTable(cu_info->GetFileRangeMap(this)); + return NULL; } size_t -SymbolFileDWARFDebugMap::AddOSOARanges (SymbolFileDWARF* dwarf2Data, DWARFDebugAranges* debug_aranges) -{ - size_t num_line_entries_added = 0; - if (debug_aranges && dwarf2Data) - { - CompileUnitInfo *compile_unit_info = GetCompileUnitInfo(dwarf2Data); - if (compile_unit_info) - { - const FileRangeMap &file_range_map = compile_unit_info->GetFileRangeMap(this); - for (size_t idx = 0; - idx < file_range_map.GetSize(); - idx++) - { - const FileRangeMap::Entry* entry = file_range_map.GetEntryAtIndex(idx); - if (entry) - { - debug_aranges->AppendRange(dwarf2Data->GetID(), entry->GetRangeBase(), entry->GetRangeEnd()); - num_line_entries_added++; - } - } +SymbolFileDWARFDebugMap::AddOSOARanges(SymbolFileDWARF *dwarf2Data, + DWARFDebugAranges *debug_aranges) { + size_t num_line_entries_added = 0; + if (debug_aranges && dwarf2Data) { + CompileUnitInfo *compile_unit_info = GetCompileUnitInfo(dwarf2Data); + if (compile_unit_info) { + const FileRangeMap &file_range_map = + compile_unit_info->GetFileRangeMap(this); + for (size_t idx = 0; idx < file_range_map.GetSize(); idx++) { + const FileRangeMap::Entry *entry = file_range_map.GetEntryAtIndex(idx); + if (entry) { + debug_aranges->AppendRange(dwarf2Data->GetID(), entry->GetRangeBase(), + entry->GetRangeEnd()); + num_line_entries_added++; } + } } - return num_line_entries_added; + } + return num_line_entries_added; } diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h index fcf02975a58f..109da631d771 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h @@ -10,12 +10,12 @@ #ifndef SymbolFileDWARF_SymbolFileDWARFDebugMap_h_ #define SymbolFileDWARF_SymbolFileDWARFDebugMap_h_ - -#include <vector> #include <bitset> +#include <vector> #include "lldb/Core/RangeMap.h" #include "lldb/Symbol/SymbolFile.h" +#include "llvm/Support/Chrono.h" #include "UniqueDWARFASTType.h" @@ -23,398 +23,355 @@ class SymbolFileDWARF; class DWARFDebugAranges; class DWARFDeclContext; -class SymbolFileDWARFDebugMap : public lldb_private::SymbolFile -{ +class SymbolFileDWARFDebugMap : public lldb_private::SymbolFile { public: - - //------------------------------------------------------------------ - // Static Functions - //------------------------------------------------------------------ - static void - Initialize(); - - static void - Terminate(); - - static lldb_private::ConstString - GetPluginNameStatic(); - - static const char * - GetPluginDescriptionStatic(); - - static lldb_private::SymbolFile * - CreateInstance (lldb_private::ObjectFile* obj_file); - - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - SymbolFileDWARFDebugMap (lldb_private::ObjectFile* ofile); - ~SymbolFileDWARFDebugMap () override; - - uint32_t CalculateAbilities () override; - void InitializeObject() override; - - //------------------------------------------------------------------ - // Compile Unit function calls - //------------------------------------------------------------------ - uint32_t GetNumCompileUnits () override; - 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; - 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 ParseVariablesForContext (const lldb_private::SymbolContext& sc) override; - - lldb_private::Type* ResolveTypeUID (lldb::user_id_t type_uid) override; - lldb_private::CompilerDeclContext GetDeclContextForUID (lldb::user_id_t uid) override; - lldb_private::CompilerDeclContext GetDeclContextContainingUID (lldb::user_id_t uid) override; - void ParseDeclsForContext (lldb_private::CompilerDeclContext decl_ctx) override; - - bool CompleteType (lldb_private::CompilerType& compiler_type) override; - uint32_t ResolveSymbolContext (const lldb_private::Address& so_addr, uint32_t 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, lldb_private::SymbolContextList& sc_list) override; - uint32_t FindGlobalVariables (const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, lldb_private::VariableList& variables) override; - uint32_t FindGlobalVariables (const lldb_private::RegularExpression& regex, bool append, uint32_t max_matches, lldb_private::VariableList& variables) override; - 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; - uint32_t FindFunctions (const lldb_private::RegularExpression& regex, bool include_inlines, bool append, lldb_private::SymbolContextList& sc_list) override; - uint32_t FindTypes (const lldb_private::SymbolContext& sc, 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_private::TypeList &type_list) override; - - //------------------------------------------------------------------ - // PluginInterface protocol - //------------------------------------------------------------------ - lldb_private::ConstString - GetPluginName() override; - - uint32_t - GetPluginVersion() override; + //------------------------------------------------------------------ + // Static Functions + //------------------------------------------------------------------ + static void Initialize(); + + static void Terminate(); + + static lldb_private::ConstString GetPluginNameStatic(); + + static const char *GetPluginDescriptionStatic(); + + static lldb_private::SymbolFile * + CreateInstance(lldb_private::ObjectFile *obj_file); + + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + SymbolFileDWARFDebugMap(lldb_private::ObjectFile *ofile); + ~SymbolFileDWARFDebugMap() override; + + uint32_t CalculateAbilities() override; + void InitializeObject() override; + + //------------------------------------------------------------------ + // Compile Unit function calls + //------------------------------------------------------------------ + uint32_t GetNumCompileUnits() override; + 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; + 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 + ParseVariablesForContext(const lldb_private::SymbolContext &sc) override; + + lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override; + lldb_private::CompilerDeclContext + GetDeclContextForUID(lldb::user_id_t uid) override; + lldb_private::CompilerDeclContext + GetDeclContextContainingUID(lldb::user_id_t uid) override; + void + ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override; + + bool CompleteType(lldb_private::CompilerType &compiler_type) override; + uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr, + uint32_t 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, + lldb_private::SymbolContextList &sc_list) override; + uint32_t + FindGlobalVariables(const lldb_private::ConstString &name, + const lldb_private::CompilerDeclContext *parent_decl_ctx, + bool append, uint32_t max_matches, + lldb_private::VariableList &variables) override; + uint32_t FindGlobalVariables(const lldb_private::RegularExpression ®ex, + bool append, uint32_t max_matches, + lldb_private::VariableList &variables) override; + 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; + 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, + 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_private::TypeList &type_list) override; + + //------------------------------------------------------------------ + // PluginInterface protocol + //------------------------------------------------------------------ + lldb_private::ConstString GetPluginName() override; + + uint32_t GetPluginVersion() override; protected: - enum - { - kHaveInitializedOSOs = (1 << 0), - kNumFlags - }; - - friend class DebugMapModule; - friend struct DIERef; - friend class DWARFASTParserClang; - friend class DWARFCompileUnit; - friend class SymbolFileDWARF; - struct OSOInfo - { - lldb::ModuleSP module_sp; - - OSOInfo() : - module_sp () - { - } - }; - - typedef std::shared_ptr<OSOInfo> OSOInfoSP; - - typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, lldb::addr_t> FileRangeMap; - - //------------------------------------------------------------------ - // Class specific types - //------------------------------------------------------------------ - struct CompileUnitInfo - { - lldb_private::FileSpec so_file; - lldb_private::ConstString oso_path; - lldb_private::TimeValue oso_mod_time; - OSOInfoSP oso_sp; - lldb::CompUnitSP compile_unit_sp; - uint32_t first_symbol_index; - uint32_t last_symbol_index; - uint32_t first_symbol_id; - uint32_t last_symbol_id; - FileRangeMap file_range_map; - bool file_range_map_valid; - - - CompileUnitInfo() : - so_file (), - oso_path (), - oso_mod_time (), - oso_sp (), - compile_unit_sp (), - first_symbol_index (UINT32_MAX), - last_symbol_index (UINT32_MAX), - first_symbol_id (UINT32_MAX), - last_symbol_id (UINT32_MAX), - file_range_map (), - file_range_map_valid (false) - { - } - - const FileRangeMap & - GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile); - }; - - //------------------------------------------------------------------ - // Protected Member Functions - //------------------------------------------------------------------ - void - InitOSO (); - - static uint32_t - GetOSOIndexFromUserID (lldb::user_id_t uid) - { - return (uint32_t)((uid >> 32ull) - 1ull); - } - - static SymbolFileDWARF * - GetSymbolFileAsSymbolFileDWARF (SymbolFile *sym_file); - - bool - GetFileSpecForSO (uint32_t oso_idx, lldb_private::FileSpec &file_spec); - - CompileUnitInfo * - GetCompUnitInfo (const lldb_private::SymbolContext& sc); - - size_t - GetCompUnitInfosForModule (const lldb_private::Module *oso_module, - std::vector<CompileUnitInfo *>& cu_infos); - - lldb_private::Module * - GetModuleByCompUnitInfo (CompileUnitInfo *comp_unit_info); - - lldb_private::Module * - GetModuleByOSOIndex (uint32_t oso_idx); - - lldb_private::ObjectFile * - GetObjectFileByCompUnitInfo (CompileUnitInfo *comp_unit_info); - - lldb_private::ObjectFile * - GetObjectFileByOSOIndex (uint32_t oso_idx); - - uint32_t - GetCompUnitInfoIndex (const CompileUnitInfo *comp_unit_info); - - SymbolFileDWARF * - GetSymbolFile (const lldb_private::SymbolContext& sc); - - SymbolFileDWARF * - GetSymbolFileByCompUnitInfo (CompileUnitInfo *comp_unit_info); - - SymbolFileDWARF * - GetSymbolFileByOSOIndex (uint32_t oso_idx); - - // If closure returns "false", iteration continues. If it returns - // "true", iteration terminates. - void - ForEachSymbolFile (std::function<bool (SymbolFileDWARF *)> closure) - { - for (uint32_t oso_idx = 0, num_oso_idxs = m_compile_unit_infos.size(); - oso_idx < num_oso_idxs; - ++oso_idx) - { - if (SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) - { - if (closure(oso_dwarf)) - return; - } - } + enum { kHaveInitializedOSOs = (1 << 0), kNumFlags }; + + friend class DebugMapModule; + friend struct DIERef; + friend class DWARFASTParserClang; + friend class DWARFCompileUnit; + friend class SymbolFileDWARF; + struct OSOInfo { + lldb::ModuleSP module_sp; + + OSOInfo() : module_sp() {} + }; + + typedef std::shared_ptr<OSOInfo> OSOInfoSP; + + typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, + lldb::addr_t> + FileRangeMap; + + //------------------------------------------------------------------ + // Class specific types + //------------------------------------------------------------------ + struct CompileUnitInfo { + lldb_private::FileSpec so_file; + lldb_private::ConstString oso_path; + llvm::sys::TimePoint<> oso_mod_time; + OSOInfoSP oso_sp; + lldb::CompUnitSP compile_unit_sp; + uint32_t first_symbol_index; + uint32_t last_symbol_index; + uint32_t first_symbol_id; + uint32_t last_symbol_id; + FileRangeMap file_range_map; + bool file_range_map_valid; + + CompileUnitInfo() + : so_file(), oso_path(), oso_mod_time(), oso_sp(), compile_unit_sp(), + first_symbol_index(UINT32_MAX), last_symbol_index(UINT32_MAX), + first_symbol_id(UINT32_MAX), last_symbol_id(UINT32_MAX), + file_range_map(), file_range_map_valid(false) {} + + const FileRangeMap &GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile); + }; + + //------------------------------------------------------------------ + // Protected Member Functions + //------------------------------------------------------------------ + void InitOSO(); + + static uint32_t GetOSOIndexFromUserID(lldb::user_id_t uid) { + return (uint32_t)((uid >> 32ull) - 1ull); + } + + static SymbolFileDWARF *GetSymbolFileAsSymbolFileDWARF(SymbolFile *sym_file); + + bool GetFileSpecForSO(uint32_t oso_idx, lldb_private::FileSpec &file_spec); + + CompileUnitInfo *GetCompUnitInfo(const lldb_private::SymbolContext &sc); + + size_t GetCompUnitInfosForModule(const lldb_private::Module *oso_module, + std::vector<CompileUnitInfo *> &cu_infos); + + lldb_private::Module * + GetModuleByCompUnitInfo(CompileUnitInfo *comp_unit_info); + + lldb_private::Module *GetModuleByOSOIndex(uint32_t oso_idx); + + lldb_private::ObjectFile * + GetObjectFileByCompUnitInfo(CompileUnitInfo *comp_unit_info); + + lldb_private::ObjectFile *GetObjectFileByOSOIndex(uint32_t oso_idx); + + uint32_t GetCompUnitInfoIndex(const CompileUnitInfo *comp_unit_info); + + SymbolFileDWARF *GetSymbolFile(const lldb_private::SymbolContext &sc); + + SymbolFileDWARF *GetSymbolFileByCompUnitInfo(CompileUnitInfo *comp_unit_info); + + SymbolFileDWARF *GetSymbolFileByOSOIndex(uint32_t oso_idx); + + // If closure returns "false", iteration continues. If it returns + // "true", iteration terminates. + void ForEachSymbolFile(std::function<bool(SymbolFileDWARF *)> closure) { + for (uint32_t oso_idx = 0, num_oso_idxs = m_compile_unit_infos.size(); + oso_idx < num_oso_idxs; ++oso_idx) { + if (SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx)) { + if (closure(oso_dwarf)) + return; + } } + } + + CompileUnitInfo *GetCompileUnitInfoForSymbolWithIndex(uint32_t symbol_idx, + uint32_t *oso_idx_ptr); - CompileUnitInfo * - GetCompileUnitInfoForSymbolWithIndex (uint32_t symbol_idx, uint32_t *oso_idx_ptr); - - CompileUnitInfo * - GetCompileUnitInfoForSymbolWithID (lldb::user_id_t symbol_id, uint32_t *oso_idx_ptr); + CompileUnitInfo *GetCompileUnitInfoForSymbolWithID(lldb::user_id_t symbol_id, + uint32_t *oso_idx_ptr); - static int - SymbolContainsSymbolWithIndex (uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info); + static int + SymbolContainsSymbolWithIndex(uint32_t *symbol_idx_ptr, + const CompileUnitInfo *comp_unit_info); - static int - SymbolContainsSymbolWithID (lldb::user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info); + static int SymbolContainsSymbolWithID(lldb::user_id_t *symbol_idx_ptr, + const CompileUnitInfo *comp_unit_info); - uint32_t - PrivateFindGlobalVariables (const lldb_private::ConstString &name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, - const std::vector<uint32_t> &name_symbol_indexes, - uint32_t max_matches, - lldb_private::VariableList& variables); + uint32_t PrivateFindGlobalVariables( + const lldb_private::ConstString &name, + const lldb_private::CompilerDeclContext *parent_decl_ctx, + const std::vector<uint32_t> &name_symbol_indexes, uint32_t max_matches, + lldb_private::VariableList &variables); + void SetCompileUnit(SymbolFileDWARF *oso_dwarf, + const lldb::CompUnitSP &cu_sp); - void - SetCompileUnit (SymbolFileDWARF *oso_dwarf, const lldb::CompUnitSP &cu_sp); + lldb::CompUnitSP GetCompileUnit(SymbolFileDWARF *oso_dwarf); - lldb::CompUnitSP - GetCompileUnit (SymbolFileDWARF *oso_dwarf); - - CompileUnitInfo * - GetCompileUnitInfo (SymbolFileDWARF *oso_dwarf); + CompileUnitInfo *GetCompileUnitInfo(SymbolFileDWARF *oso_dwarf); - lldb::TypeSP - FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx); + lldb::TypeSP + FindDefinitionTypeForDWARFDeclContext(const DWARFDeclContext &die_decl_ctx); - bool - Supports_DW_AT_APPLE_objc_complete_type (SymbolFileDWARF *skip_dwarf_oso); + bool Supports_DW_AT_APPLE_objc_complete_type(SymbolFileDWARF *skip_dwarf_oso); - lldb::TypeSP - FindCompleteObjCDefinitionTypeForDIE (const DWARFDIE &die, - const lldb_private::ConstString &type_name, - bool must_be_implementation); - + lldb::TypeSP FindCompleteObjCDefinitionTypeForDIE( + const DWARFDIE &die, const lldb_private::ConstString &type_name, + bool must_be_implementation); - UniqueDWARFASTTypeMap & - GetUniqueDWARFASTTypeMap () - { - return m_unique_ast_type_map; + UniqueDWARFASTTypeMap &GetUniqueDWARFASTTypeMap() { + return m_unique_ast_type_map; + } + + //------------------------------------------------------------------ + // OSOEntry + //------------------------------------------------------------------ + class OSOEntry { + public: + OSOEntry() + : m_exe_sym_idx(UINT32_MAX), m_oso_file_addr(LLDB_INVALID_ADDRESS) {} + + OSOEntry(uint32_t exe_sym_idx, lldb::addr_t oso_file_addr) + : m_exe_sym_idx(exe_sym_idx), m_oso_file_addr(oso_file_addr) {} + + uint32_t GetExeSymbolIndex() const { return m_exe_sym_idx; } + + bool operator<(const OSOEntry &rhs) const { + return m_exe_sym_idx < rhs.m_exe_sym_idx; } - - - //------------------------------------------------------------------ - // OSOEntry - //------------------------------------------------------------------ - class OSOEntry - { - public: - - OSOEntry () : - m_exe_sym_idx (UINT32_MAX), - m_oso_file_addr (LLDB_INVALID_ADDRESS) - { - } - - OSOEntry (uint32_t exe_sym_idx, - lldb::addr_t oso_file_addr) : - m_exe_sym_idx (exe_sym_idx), - m_oso_file_addr (oso_file_addr) - { - } - - uint32_t - GetExeSymbolIndex () const - { - return m_exe_sym_idx; - } - - bool - operator < (const OSOEntry &rhs) const - { - return m_exe_sym_idx < rhs.m_exe_sym_idx; - } - - lldb::addr_t - GetOSOFileAddress () const - { - return m_oso_file_addr; - } - - void - SetOSOFileAddress (lldb::addr_t oso_file_addr) - { - m_oso_file_addr = oso_file_addr; - } - protected: - uint32_t m_exe_sym_idx; - lldb::addr_t m_oso_file_addr; - }; - - typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, OSOEntry> DebugMap; - - //------------------------------------------------------------------ - // Member Variables - //------------------------------------------------------------------ - std::bitset<kNumFlags> m_flags; - std::vector<CompileUnitInfo> m_compile_unit_infos; - std::vector<uint32_t> m_func_indexes; // Sorted by address - std::vector<uint32_t> m_glob_indexes; - std::map<lldb_private::ConstString, OSOInfoSP> m_oso_map; - UniqueDWARFASTTypeMap m_unique_ast_type_map; - lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type; - DebugMap m_debug_map; - - //------------------------------------------------------------------ - // When an object file from the debug map gets parsed in - // SymbolFileDWARF, it needs to tell the debug map about the object - // files addresses by calling this function once for each N_FUN, - // N_GSYM and N_STSYM and after all entries in the debug map have - // been matched up, FinalizeOSOFileRanges() should be called. - //------------------------------------------------------------------ - bool - AddOSOFileRange (CompileUnitInfo *cu_info, - lldb::addr_t exe_file_addr, - lldb::addr_t exe_byte_size, - lldb::addr_t oso_file_addr, - lldb::addr_t oso_byte_size); - - //------------------------------------------------------------------ - // Called after calling AddOSOFileRange() for each object file debug - // map entry to finalize the info for the unlinked compile unit. - //------------------------------------------------------------------ - void - FinalizeOSOFileRanges (CompileUnitInfo *cu_info); - - //------------------------------------------------------------------ - /// Convert \a addr from a .o file address, to an executable address. - /// - /// @param[in] addr - /// A section offset address from a .o file - /// - /// @return - /// Returns true if \a addr was converted to be an executable - /// section/offset address, false otherwise. - //------------------------------------------------------------------ - bool - LinkOSOAddress (lldb_private::Address &addr); - - //------------------------------------------------------------------ - /// Convert a .o file "file address" to an executable "file address". - /// - /// @param[in] oso_symfile - /// The DWARF symbol file that contains \a oso_file_addr - /// - /// @param[in] oso_file_addr - /// A .o file "file address" to convert. - /// - /// @return - /// LLDB_INVALID_ADDRESS if \a oso_file_addr is not in the - /// linked executable, otherwise a valid "file address" from the - /// linked executable that contains the debug map. - //------------------------------------------------------------------ - lldb::addr_t - LinkOSOFileAddress (SymbolFileDWARF *oso_symfile, lldb::addr_t oso_file_addr); - - //------------------------------------------------------------------ - /// Given a line table full of lines with "file addresses" that are - /// for a .o file represented by \a oso_symfile, link a new line table - /// and return it. - /// - /// @param[in] oso_symfile - /// The DWARF symbol file that produced the \a line_table - /// - /// @param[in] addr - /// A section offset address from a .o file - /// - /// @return - /// Returns a valid line table full of linked addresses, or NULL - /// if none of the line table addresses exist in the main - /// executable. - //------------------------------------------------------------------ - lldb_private::LineTable * - LinkOSOLineTable (SymbolFileDWARF *oso_symfile, - lldb_private::LineTable *line_table); - - size_t - AddOSOARanges (SymbolFileDWARF* dwarf2Data, - DWARFDebugAranges* debug_aranges); + + lldb::addr_t GetOSOFileAddress() const { return m_oso_file_addr; } + + void SetOSOFileAddress(lldb::addr_t oso_file_addr) { + m_oso_file_addr = oso_file_addr; + } + + protected: + uint32_t m_exe_sym_idx; + lldb::addr_t m_oso_file_addr; + }; + + typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, OSOEntry> + DebugMap; + + //------------------------------------------------------------------ + // Member Variables + //------------------------------------------------------------------ + std::bitset<kNumFlags> m_flags; + std::vector<CompileUnitInfo> m_compile_unit_infos; + std::vector<uint32_t> m_func_indexes; // Sorted by address + std::vector<uint32_t> m_glob_indexes; + std::map<lldb_private::ConstString, OSOInfoSP> m_oso_map; + UniqueDWARFASTTypeMap m_unique_ast_type_map; + lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type; + DebugMap m_debug_map; + + //------------------------------------------------------------------ + // When an object file from the debug map gets parsed in + // SymbolFileDWARF, it needs to tell the debug map about the object + // files addresses by calling this function once for each N_FUN, + // N_GSYM and N_STSYM and after all entries in the debug map have + // been matched up, FinalizeOSOFileRanges() should be called. + //------------------------------------------------------------------ + bool AddOSOFileRange(CompileUnitInfo *cu_info, lldb::addr_t exe_file_addr, + lldb::addr_t exe_byte_size, lldb::addr_t oso_file_addr, + lldb::addr_t oso_byte_size); + + //------------------------------------------------------------------ + // Called after calling AddOSOFileRange() for each object file debug + // map entry to finalize the info for the unlinked compile unit. + //------------------------------------------------------------------ + void FinalizeOSOFileRanges(CompileUnitInfo *cu_info); + + //------------------------------------------------------------------ + /// Convert \a addr from a .o file address, to an executable address. + /// + /// @param[in] addr + /// A section offset address from a .o file + /// + /// @return + /// Returns true if \a addr was converted to be an executable + /// section/offset address, false otherwise. + //------------------------------------------------------------------ + bool LinkOSOAddress(lldb_private::Address &addr); + + //------------------------------------------------------------------ + /// Convert a .o file "file address" to an executable "file address". + /// + /// @param[in] oso_symfile + /// The DWARF symbol file that contains \a oso_file_addr + /// + /// @param[in] oso_file_addr + /// A .o file "file address" to convert. + /// + /// @return + /// LLDB_INVALID_ADDRESS if \a oso_file_addr is not in the + /// linked executable, otherwise a valid "file address" from the + /// linked executable that contains the debug map. + //------------------------------------------------------------------ + lldb::addr_t LinkOSOFileAddress(SymbolFileDWARF *oso_symfile, + lldb::addr_t oso_file_addr); + + //------------------------------------------------------------------ + /// Given a line table full of lines with "file addresses" that are + /// for a .o file represented by \a oso_symfile, link a new line table + /// and return it. + /// + /// @param[in] oso_symfile + /// The DWARF symbol file that produced the \a line_table + /// + /// @param[in] addr + /// A section offset address from a .o file + /// + /// @return + /// Returns a valid line table full of linked addresses, or NULL + /// if none of the line table addresses exist in the main + /// executable. + //------------------------------------------------------------------ + lldb_private::LineTable * + LinkOSOLineTable(SymbolFileDWARF *oso_symfile, + lldb_private::LineTable *line_table); + + size_t AddOSOARanges(SymbolFileDWARF *dwarf2Data, + DWARFDebugAranges *debug_aranges); }; #endif // #ifndef SymbolFileDWARF_SymbolFileDWARFDebugMap_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp index 14603aa460c9..c14ebd1628be 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp @@ -20,120 +20,103 @@ using namespace lldb; using namespace lldb_private; -SymbolFileDWARFDwo::SymbolFileDWARFDwo(ObjectFileSP objfile, DWARFCompileUnit* dwarf_cu) : - SymbolFileDWARF(objfile.get()), - m_obj_file_sp(objfile), - m_base_dwarf_cu(dwarf_cu) -{ - SetID(((lldb::user_id_t)dwarf_cu->GetOffset())<<32); +SymbolFileDWARFDwo::SymbolFileDWARFDwo(ObjectFileSP objfile, + DWARFCompileUnit *dwarf_cu) + : SymbolFileDWARF(objfile.get()), m_obj_file_sp(objfile), + m_base_dwarf_cu(dwarf_cu) { + SetID(((lldb::user_id_t)dwarf_cu->GetOffset()) << 32); } -void -SymbolFileDWARFDwo::LoadSectionData (lldb::SectionType sect_type, DWARFDataExtractor& data) -{ - const SectionList* section_list = m_obj_file->GetSectionList(false /* update_module_section_list */); - if (section_list) - { - SectionSP section_sp (section_list->FindSectionByType(sect_type, true)); - if (section_sp) - { - // See if we memory mapped the DWARF segment? - if (m_dwarf_data.GetByteSize()) - { - data.SetData(m_dwarf_data, section_sp->GetOffset(), section_sp->GetFileSize()); - return; - } - - if (m_obj_file->ReadSectionData(section_sp.get(), data) != 0) - return; - - data.Clear(); - } +void SymbolFileDWARFDwo::LoadSectionData(lldb::SectionType sect_type, + DWARFDataExtractor &data) { + const SectionList *section_list = + m_obj_file->GetSectionList(false /* update_module_section_list */); + if (section_list) { + SectionSP section_sp(section_list->FindSectionByType(sect_type, true)); + if (section_sp) { + // See if we memory mapped the DWARF segment? + if (m_dwarf_data.GetByteSize()) { + data.SetData(m_dwarf_data, section_sp->GetOffset(), + section_sp->GetFileSize()); + return; + } + + if (m_obj_file->ReadSectionData(section_sp.get(), data) != 0) + return; + + data.Clear(); } + } - SymbolFileDWARF::LoadSectionData(sect_type, data); + SymbolFileDWARF::LoadSectionData(sect_type, data); } lldb::CompUnitSP -SymbolFileDWARFDwo::ParseCompileUnit(DWARFCompileUnit* dwarf_cu, uint32_t cu_idx) -{ - assert(GetCompileUnit() == dwarf_cu && "SymbolFileDWARFDwo::ParseCompileUnit called with incompatible compile unit"); - return GetBaseSymbolFile()->ParseCompileUnit(m_base_dwarf_cu, UINT32_MAX); +SymbolFileDWARFDwo::ParseCompileUnit(DWARFCompileUnit *dwarf_cu, + uint32_t cu_idx) { + assert(GetCompileUnit() == dwarf_cu && "SymbolFileDWARFDwo::ParseCompileUnit " + "called with incompatible compile " + "unit"); + return GetBaseSymbolFile()->ParseCompileUnit(m_base_dwarf_cu, UINT32_MAX); } -DWARFCompileUnit* -SymbolFileDWARFDwo::GetCompileUnit() -{ - // Only dwo files with 1 compile unit is supported - if (GetNumCompileUnits() == 1) - return DebugInfo()->GetCompileUnitAtIndex(0); - else - return nullptr; +DWARFCompileUnit *SymbolFileDWARFDwo::GetCompileUnit() { + // Only dwo files with 1 compile unit is supported + if (GetNumCompileUnits() == 1) + return DebugInfo()->GetCompileUnitAtIndex(0); + else + return nullptr; } -DWARFCompileUnit* -SymbolFileDWARFDwo::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) -{ - return GetCompileUnit(); +DWARFCompileUnit * +SymbolFileDWARFDwo::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) { + return GetCompileUnit(); } -SymbolFileDWARF::DIEToTypePtr& -SymbolFileDWARFDwo::GetDIEToType() -{ - return GetBaseSymbolFile()->GetDIEToType(); +SymbolFileDWARF::DIEToTypePtr &SymbolFileDWARFDwo::GetDIEToType() { + return GetBaseSymbolFile()->GetDIEToType(); } -SymbolFileDWARF::DIEToVariableSP& -SymbolFileDWARFDwo::GetDIEToVariable() -{ - return GetBaseSymbolFile()->GetDIEToVariable(); +SymbolFileDWARF::DIEToVariableSP &SymbolFileDWARFDwo::GetDIEToVariable() { + return GetBaseSymbolFile()->GetDIEToVariable(); } -SymbolFileDWARF::DIEToClangType& -SymbolFileDWARFDwo::GetForwardDeclDieToClangType() -{ - return GetBaseSymbolFile()->GetForwardDeclDieToClangType(); +SymbolFileDWARF::DIEToClangType & +SymbolFileDWARFDwo::GetForwardDeclDieToClangType() { + return GetBaseSymbolFile()->GetForwardDeclDieToClangType(); } -SymbolFileDWARF::ClangTypeToDIE& -SymbolFileDWARFDwo::GetForwardDeclClangTypeToDie() -{ - return GetBaseSymbolFile()->GetForwardDeclClangTypeToDie(); +SymbolFileDWARF::ClangTypeToDIE & +SymbolFileDWARFDwo::GetForwardDeclClangTypeToDie() { + return GetBaseSymbolFile()->GetForwardDeclClangTypeToDie(); } -UniqueDWARFASTTypeMap& -SymbolFileDWARFDwo::GetUniqueDWARFASTTypeMap() -{ - return GetBaseSymbolFile()->GetUniqueDWARFASTTypeMap(); +UniqueDWARFASTTypeMap &SymbolFileDWARFDwo::GetUniqueDWARFASTTypeMap() { + return GetBaseSymbolFile()->GetUniqueDWARFASTTypeMap(); } -lldb::TypeSP -SymbolFileDWARFDwo::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx) -{ - return GetBaseSymbolFile()->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx); +lldb::TypeSP SymbolFileDWARFDwo::FindDefinitionTypeForDWARFDeclContext( + const DWARFDeclContext &die_decl_ctx) { + return GetBaseSymbolFile()->FindDefinitionTypeForDWARFDeclContext( + die_decl_ctx); } -SymbolFileDWARF* -SymbolFileDWARFDwo::GetBaseSymbolFile() -{ - return m_base_dwarf_cu->GetSymbolFileDWARF(); +SymbolFileDWARF *SymbolFileDWARFDwo::GetBaseSymbolFile() { + return m_base_dwarf_cu->GetSymbolFileDWARF(); } DWARFExpression::LocationListFormat -SymbolFileDWARFDwo::GetLocationListFormat() const -{ - return DWARFExpression::SplitDwarfLocationList; +SymbolFileDWARFDwo::GetLocationListFormat() const { + return DWARFExpression::SplitDwarfLocationList; } -TypeSystem* -SymbolFileDWARFDwo::GetTypeSystemForLanguage(LanguageType language) -{ - return GetBaseSymbolFile()->GetTypeSystemForLanguage(language); +TypeSystem * +SymbolFileDWARFDwo::GetTypeSystemForLanguage(LanguageType language) { + return GetBaseSymbolFile()->GetTypeSystemForLanguage(language); } DWARFDIE -SymbolFileDWARFDwo::GetDIE(const DIERef &die_ref) -{ - lldbassert(m_base_dwarf_cu->GetOffset() == die_ref.cu_offset); - return DebugInfo()->GetDIEForDIEOffset(die_ref.die_offset); +SymbolFileDWARFDwo::GetDIE(const DIERef &die_ref) { + lldbassert(m_base_dwarf_cu->GetOffset() == die_ref.cu_offset); + return DebugInfo()->GetDIEForDIEOffset(die_ref.die_offset); } diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h index 9391a2824948..8cd67a2b2424 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h @@ -16,64 +16,56 @@ // Project includes #include "SymbolFileDWARF.h" -class SymbolFileDWARFDwo : public SymbolFileDWARF -{ +class SymbolFileDWARFDwo : public SymbolFileDWARF { public: - SymbolFileDWARFDwo(lldb::ObjectFileSP objfile, DWARFCompileUnit* dwarf_cu); + SymbolFileDWARFDwo(lldb::ObjectFileSP objfile, DWARFCompileUnit *dwarf_cu); - ~SymbolFileDWARFDwo() override = default; - - lldb::CompUnitSP - ParseCompileUnit(DWARFCompileUnit* dwarf_cu, uint32_t cu_idx) override; + ~SymbolFileDWARFDwo() override = default; - DWARFCompileUnit* - GetCompileUnit(); + lldb::CompUnitSP ParseCompileUnit(DWARFCompileUnit *dwarf_cu, + uint32_t cu_idx) override; - DWARFCompileUnit* - GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) override; + DWARFCompileUnit *GetCompileUnit(); - lldb_private::DWARFExpression::LocationListFormat - GetLocationListFormat() const override; + DWARFCompileUnit * + GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) override; - lldb_private::TypeSystem* - GetTypeSystemForLanguage(lldb::LanguageType language) override; + lldb_private::DWARFExpression::LocationListFormat + GetLocationListFormat() const override; - DWARFDIE - GetDIE(const DIERef &die_ref) override; + lldb_private::TypeSystem * + GetTypeSystemForLanguage(lldb::LanguageType language) override; - std::unique_ptr<SymbolFileDWARFDwo> - GetDwoSymbolFileForCompileUnit(DWARFCompileUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die) override - { - return nullptr; - } + DWARFDIE + GetDIE(const DIERef &die_ref) override; + + std::unique_ptr<SymbolFileDWARFDwo> + GetDwoSymbolFileForCompileUnit(DWARFCompileUnit &dwarf_cu, + const DWARFDebugInfoEntry &cu_die) override { + return nullptr; + } protected: - void - LoadSectionData (lldb::SectionType sect_type, lldb_private::DWARFDataExtractor& data) override; + void LoadSectionData(lldb::SectionType sect_type, + lldb_private::DWARFDataExtractor &data) override; + + DIEToTypePtr &GetDIEToType() override; - DIEToTypePtr& - GetDIEToType() override; + DIEToVariableSP &GetDIEToVariable() override; - DIEToVariableSP& - GetDIEToVariable() override; - - DIEToClangType& - GetForwardDeclDieToClangType() override; + DIEToClangType &GetForwardDeclDieToClangType() override; - ClangTypeToDIE& - GetForwardDeclClangTypeToDie() override; + ClangTypeToDIE &GetForwardDeclClangTypeToDie() override; - UniqueDWARFASTTypeMap& - GetUniqueDWARFASTTypeMap() override; + UniqueDWARFASTTypeMap &GetUniqueDWARFASTTypeMap() override; - lldb::TypeSP - FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx) override; + lldb::TypeSP FindDefinitionTypeForDWARFDeclContext( + const DWARFDeclContext &die_decl_ctx) override; - SymbolFileDWARF* - GetBaseSymbolFile(); + SymbolFileDWARF *GetBaseSymbolFile(); - lldb::ObjectFileSP m_obj_file_sp; - DWARFCompileUnit* m_base_dwarf_cu; + lldb::ObjectFileSP m_obj_file_sp; + DWARFCompileUnit *m_base_dwarf_cu; }; #endif // SymbolFileDWARFDwo_SymbolFileDWARFDwo_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp index 2ca407b9e48a..8697e08dbf86 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp @@ -15,73 +15,63 @@ // Project includes #include "lldb/Symbol/Declaration.h" -bool -UniqueDWARFASTTypeList::Find (const DWARFDIE &die, - const lldb_private::Declaration &decl, - const int32_t byte_size, - UniqueDWARFASTType &entry) const -{ - for (const UniqueDWARFASTType &udt : m_collection) - { - // Make sure the tags match - if (udt.m_die.Tag() == die.Tag()) - { - // Validate byte sizes of both types only if both are valid. - if (udt.m_byte_size < 0 || byte_size < 0 || udt.m_byte_size == byte_size) - { - // Make sure the file and line match - if (udt.m_declaration == decl) +bool UniqueDWARFASTTypeList::Find(const DWARFDIE &die, + const lldb_private::Declaration &decl, + const int32_t byte_size, + UniqueDWARFASTType &entry) const { + for (const UniqueDWARFASTType &udt : m_collection) { + // Make sure the tags match + if (udt.m_die.Tag() == die.Tag()) { + // Validate byte sizes of both types only if both are valid. + if (udt.m_byte_size < 0 || byte_size < 0 || + udt.m_byte_size == byte_size) { + // Make sure the file and line match + if (udt.m_declaration == decl) { + // The type has the same name, and was defined on the same + // file and line. Now verify all of the parent DIEs match. + DWARFDIE parent_arg_die = die.GetParent(); + DWARFDIE parent_pos_die = udt.m_die.GetParent(); + bool match = true; + bool done = false; + while (!done && match && parent_arg_die && parent_pos_die) { + const dw_tag_t parent_arg_tag = parent_arg_die.Tag(); + const dw_tag_t parent_pos_tag = parent_pos_die.Tag(); + if (parent_arg_tag == parent_pos_tag) { + switch (parent_arg_tag) { + case DW_TAG_class_type: + case DW_TAG_structure_type: + case DW_TAG_union_type: + case DW_TAG_namespace: { + const char *parent_arg_die_name = parent_arg_die.GetName(); + if (parent_arg_die_name == + NULL) // Anonymous (i.e. no-name) struct { - // The type has the same name, and was defined on the same - // file and line. Now verify all of the parent DIEs match. - DWARFDIE parent_arg_die = die.GetParent(); - DWARFDIE parent_pos_die = udt.m_die.GetParent(); - bool match = true; - bool done = false; - while (!done && match && parent_arg_die && parent_pos_die) - { - const dw_tag_t parent_arg_tag = parent_arg_die.Tag(); - const dw_tag_t parent_pos_tag = parent_pos_die.Tag(); - if (parent_arg_tag == parent_pos_tag) - { - switch (parent_arg_tag) - { - case DW_TAG_class_type: - case DW_TAG_structure_type: - case DW_TAG_union_type: - case DW_TAG_namespace: - { - const char *parent_arg_die_name = parent_arg_die.GetName(); - if (parent_arg_die_name == NULL) // Anonymous (i.e. no-name) struct - { - match = false; - } - else - { - const char *parent_pos_die_name = parent_pos_die.GetName(); - if (parent_pos_die_name == NULL || ((parent_arg_die_name != parent_pos_die_name) && strcmp (parent_arg_die_name, parent_pos_die_name))) - match = false; - } - } - break; - - case DW_TAG_compile_unit: - done = true; - break; - } - } - parent_arg_die = parent_arg_die.GetParent(); - parent_pos_die = parent_pos_die.GetParent(); - } - - if (match) - { - entry = udt; - return true; - } + match = false; + } else { + const char *parent_pos_die_name = parent_pos_die.GetName(); + if (parent_pos_die_name == NULL || + ((parent_arg_die_name != parent_pos_die_name) && + strcmp(parent_arg_die_name, parent_pos_die_name))) + match = false; } + } break; + + case DW_TAG_compile_unit: + done = true; + break; + } } + parent_arg_die = parent_arg_die.GetParent(); + parent_pos_die = parent_pos_die.GetParent(); + } + + if (match) { + entry = udt; + return true; + } } + } } - return false; + } + return false; } diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h index b7b18efd8769..5d51044cbe1a 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h @@ -18,139 +18,93 @@ #include "llvm/ADT/DenseMap.h" // Project includes -#include "lldb/Symbol/Declaration.h" #include "DWARFDIE.h" +#include "lldb/Symbol/Declaration.h" -class UniqueDWARFASTType -{ +class UniqueDWARFASTType { public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - UniqueDWARFASTType () : - m_type_sp (), - m_die (), - m_declaration (), - m_byte_size (-1) // Set to negative value to make sure we have a valid value - { - } + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + UniqueDWARFASTType() + : m_type_sp(), m_die(), m_declaration(), + m_byte_size( + -1) // Set to negative value to make sure we have a valid value + {} - UniqueDWARFASTType (lldb::TypeSP &type_sp, - const DWARFDIE &die, - const lldb_private::Declaration &decl, - int32_t byte_size) : - m_type_sp (type_sp), - m_die (die), - m_declaration (decl), - m_byte_size (byte_size) - { - } - - UniqueDWARFASTType (const UniqueDWARFASTType &rhs) : - m_type_sp (rhs.m_type_sp), - m_die (rhs.m_die), - m_declaration (rhs.m_declaration), - m_byte_size (rhs.m_byte_size) - { - } + UniqueDWARFASTType(lldb::TypeSP &type_sp, const DWARFDIE &die, + const lldb_private::Declaration &decl, int32_t byte_size) + : m_type_sp(type_sp), m_die(die), m_declaration(decl), + m_byte_size(byte_size) {} - ~UniqueDWARFASTType() - { - } + UniqueDWARFASTType(const UniqueDWARFASTType &rhs) + : m_type_sp(rhs.m_type_sp), m_die(rhs.m_die), + m_declaration(rhs.m_declaration), m_byte_size(rhs.m_byte_size) {} + + ~UniqueDWARFASTType() {} - UniqueDWARFASTType & - operator= (const UniqueDWARFASTType &rhs) - { - if (this != &rhs) - { - m_type_sp = rhs.m_type_sp; - m_die = rhs.m_die; - m_declaration = rhs.m_declaration; - m_byte_size = rhs.m_byte_size; - } - return *this; + UniqueDWARFASTType &operator=(const UniqueDWARFASTType &rhs) { + if (this != &rhs) { + m_type_sp = rhs.m_type_sp; + m_die = rhs.m_die; + m_declaration = rhs.m_declaration; + m_byte_size = rhs.m_byte_size; } + return *this; + } - lldb::TypeSP m_type_sp; - DWARFDIE m_die; - lldb_private::Declaration m_declaration; - int32_t m_byte_size; + lldb::TypeSP m_type_sp; + DWARFDIE m_die; + lldb_private::Declaration m_declaration; + int32_t m_byte_size; }; -class UniqueDWARFASTTypeList -{ +class UniqueDWARFASTTypeList { public: - UniqueDWARFASTTypeList () : - m_collection() - { - } - - ~UniqueDWARFASTTypeList () - { - } - - uint32_t - GetSize() - { - return (uint32_t)m_collection.size(); - } - - void - Append (const UniqueDWARFASTType &entry) - { - m_collection.push_back (entry); - } - - bool - Find (const DWARFDIE &die, - const lldb_private::Declaration &decl, - const int32_t byte_size, - UniqueDWARFASTType &entry) const; - + UniqueDWARFASTTypeList() : m_collection() {} + + ~UniqueDWARFASTTypeList() {} + + uint32_t GetSize() { return (uint32_t)m_collection.size(); } + + void Append(const UniqueDWARFASTType &entry) { + m_collection.push_back(entry); + } + + bool Find(const DWARFDIE &die, const lldb_private::Declaration &decl, + const int32_t byte_size, UniqueDWARFASTType &entry) const; + protected: - typedef std::vector<UniqueDWARFASTType> collection; - collection m_collection; + typedef std::vector<UniqueDWARFASTType> collection; + collection m_collection; }; -class UniqueDWARFASTTypeMap -{ +class UniqueDWARFASTTypeMap { public: - UniqueDWARFASTTypeMap () : - m_collection () - { - } - - ~UniqueDWARFASTTypeMap () - { - } + UniqueDWARFASTTypeMap() : m_collection() {} - void - Insert (const lldb_private::ConstString &name, - const UniqueDWARFASTType &entry) - { - m_collection[name.GetCString()].Append (entry); - } + ~UniqueDWARFASTTypeMap() {} + + void Insert(const lldb_private::ConstString &name, + const UniqueDWARFASTType &entry) { + m_collection[name.GetCString()].Append(entry); + } - bool - Find (const lldb_private::ConstString &name, - const DWARFDIE &die, - const lldb_private::Declaration &decl, - const int32_t byte_size, - UniqueDWARFASTType &entry) const - { - const char *unique_name_cstr = name.GetCString(); - collection::const_iterator pos = m_collection.find (unique_name_cstr); - if (pos != m_collection.end()) - { - return pos->second.Find (die, decl, byte_size, entry); - } - return false; + bool Find(const lldb_private::ConstString &name, const DWARFDIE &die, + const lldb_private::Declaration &decl, const int32_t byte_size, + UniqueDWARFASTType &entry) const { + const char *unique_name_cstr = name.GetCString(); + collection::const_iterator pos = m_collection.find(unique_name_cstr); + if (pos != m_collection.end()) { + return pos->second.Find(die, decl, byte_size, entry); } + return false; + } protected: - // A unique name string should be used - typedef llvm::DenseMap<const char *, UniqueDWARFASTTypeList> collection; - collection m_collection; + // A unique name string should be used + typedef llvm::DenseMap<const char *, UniqueDWARFASTTypeList> collection; + collection m_collection; }; -#endif // lldb_UniqueDWARFASTType_h_ +#endif // lldb_UniqueDWARFASTType_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp index 1e8e040fd47c..b48de2e591e3 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp @@ -34,204 +34,199 @@ using namespace lldb_private; using namespace llvm; using namespace llvm::pdb; -namespace -{ -int -TranslateUdtKind(PDB_UdtType pdb_kind) -{ - switch (pdb_kind) - { - case PDB_UdtType::Class: - return clang::TTK_Class; - case PDB_UdtType::Struct: - return clang::TTK_Struct; - case PDB_UdtType::Union: - return clang::TTK_Union; - case PDB_UdtType::Interface: - return clang::TTK_Interface; - } +namespace { +int TranslateUdtKind(PDB_UdtType pdb_kind) { + switch (pdb_kind) { + case PDB_UdtType::Class: return clang::TTK_Class; + case PDB_UdtType::Struct: + return clang::TTK_Struct; + case PDB_UdtType::Union: + return clang::TTK_Union; + case PDB_UdtType::Interface: + return clang::TTK_Interface; + } + return clang::TTK_Class; } -lldb::Encoding -TranslateBuiltinEncoding(PDB_BuiltinType type) -{ - switch (type) - { - case PDB_BuiltinType::Float: - return lldb::eEncodingIEEE754; - case PDB_BuiltinType::Int: - case PDB_BuiltinType::Long: - case PDB_BuiltinType::Char: - return lldb::eEncodingSint; - case PDB_BuiltinType::Bool: - case PDB_BuiltinType::UInt: - case PDB_BuiltinType::ULong: - case PDB_BuiltinType::HResult: - return lldb::eEncodingUint; - default: - return lldb::eEncodingInvalid; - } +lldb::Encoding TranslateBuiltinEncoding(PDB_BuiltinType type) { + switch (type) { + case PDB_BuiltinType::Float: + return lldb::eEncodingIEEE754; + case PDB_BuiltinType::Int: + case PDB_BuiltinType::Long: + case PDB_BuiltinType::Char: + return lldb::eEncodingSint; + case PDB_BuiltinType::Bool: + case PDB_BuiltinType::UInt: + case PDB_BuiltinType::ULong: + case PDB_BuiltinType::HResult: + return lldb::eEncodingUint; + default: + return lldb::eEncodingInvalid; + } } } -PDBASTParser::PDBASTParser(lldb_private::ClangASTContext &ast) : m_ast(ast) -{ -} +PDBASTParser::PDBASTParser(lldb_private::ClangASTContext &ast) : m_ast(ast) {} -PDBASTParser::~PDBASTParser() -{ -} +PDBASTParser::~PDBASTParser() {} // DebugInfoASTParser interface -lldb::TypeSP -PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) -{ - // PDB doesn't maintain enough information to robustly rebuild the entire - // tree, and this is most problematic when it comes to figure out the - // right DeclContext to put a type in. So for now, everything goes in - // the translation unit decl as a fully qualified type. - clang::DeclContext *tu_decl_ctx = m_ast.GetTranslationUnitDecl(); - Declaration decl; - - if (auto udt = llvm::dyn_cast<PDBSymbolTypeUDT>(&type)) - { - AccessType access = lldb::eAccessPublic; - PDB_UdtType udt_kind = udt->getUdtKind(); - - if (udt_kind == PDB_UdtType::Class) - access = lldb::eAccessPrivate; - - CompilerType clang_type = - m_ast.CreateRecordType(tu_decl_ctx, access, udt->getName().c_str(), TranslateUdtKind(udt_kind), - lldb::eLanguageTypeC_plus_plus, nullptr); - - m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true); - - return std::make_shared<Type>(type.getSymIndexId(), m_ast.GetSymbolFile(), ConstString(udt->getName()), - udt->getLength(), nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, decl, - clang_type, Type::eResolveStateForward); - } - else if (auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(&type)) - { - std::string name = enum_type->getName(); - lldb::Encoding encoding = TranslateBuiltinEncoding(enum_type->getBuiltinType()); - uint64_t bytes = enum_type->getLength(); - CompilerType builtin_type = m_ast.GetBuiltinTypeForEncodingAndBitSize(encoding, bytes * 8); - - CompilerType ast_enum = m_ast.CreateEnumerationType(name.c_str(), tu_decl_ctx, decl, builtin_type); - auto enum_values = enum_type->findAllChildren<PDBSymbolData>(); - while (auto enum_value = enum_values->getNext()) - { - if (enum_value->getDataKind() != PDB_DataKind::Constant) - continue; - AddEnumValue(ast_enum, *enum_value); - } - - return std::make_shared<Type>(type.getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name), bytes, nullptr, - LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ast_enum, Type::eResolveStateFull); +lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { + // PDB doesn't maintain enough information to robustly rebuild the entire + // tree, and this is most problematic when it comes to figure out the + // right DeclContext to put a type in. So for now, everything goes in + // the translation unit decl as a fully qualified type. + clang::DeclContext *tu_decl_ctx = m_ast.GetTranslationUnitDecl(); + Declaration decl; + + if (auto udt = llvm::dyn_cast<PDBSymbolTypeUDT>(&type)) { + AccessType access = lldb::eAccessPublic; + PDB_UdtType udt_kind = udt->getUdtKind(); + + if (udt_kind == PDB_UdtType::Class) + access = lldb::eAccessPrivate; + + CompilerType clang_type = m_ast.CreateRecordType( + tu_decl_ctx, access, udt->getName().c_str(), TranslateUdtKind(udt_kind), + lldb::eLanguageTypeC_plus_plus, nullptr); + + m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true); + + return std::make_shared<Type>(type.getSymIndexId(), m_ast.GetSymbolFile(), + ConstString(udt->getName()), udt->getLength(), + nullptr, LLDB_INVALID_UID, + Type::eEncodingIsUID, decl, clang_type, + Type::eResolveStateForward); + } else if (auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(&type)) { + std::string name = enum_type->getName(); + lldb::Encoding encoding = + TranslateBuiltinEncoding(enum_type->getBuiltinType()); + uint64_t bytes = enum_type->getLength(); + CompilerType builtin_type = + m_ast.GetBuiltinTypeForEncodingAndBitSize(encoding, bytes * 8); + + CompilerType ast_enum = m_ast.CreateEnumerationType( + name.c_str(), tu_decl_ctx, decl, builtin_type); + auto enum_values = enum_type->findAllChildren<PDBSymbolData>(); + while (auto enum_value = enum_values->getNext()) { + if (enum_value->getDataKind() != PDB_DataKind::Constant) + continue; + AddEnumValue(ast_enum, *enum_value); } - else if (auto type_def = llvm::dyn_cast<PDBSymbolTypeTypedef>(&type)) - { - Type *target_type = m_ast.GetSymbolFile()->ResolveTypeUID(type_def->getTypeId()); - std::string name = type_def->getName(); - uint64_t bytes = type_def->getLength(); - if (!target_type) - return nullptr; - CompilerType target_ast_type = target_type->GetFullCompilerType(); - CompilerDeclContext target_decl_ctx = m_ast.GetSymbolFile()->GetDeclContextForUID(target_type->GetID()); - CompilerType ast_typedef = m_ast.CreateTypedefType(target_ast_type, name.c_str(), target_decl_ctx); - return std::make_shared<Type>(type_def->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name), bytes, - nullptr, target_type->GetID(), Type::eEncodingIsTypedefUID, decl, ast_typedef, - Type::eResolveStateFull); - } - else if (auto func_sig = llvm::dyn_cast<PDBSymbolTypeFunctionSig>(&type)) - { - auto arg_enum = func_sig->getArguments(); - uint32_t num_args = arg_enum->getChildCount(); - std::vector<CompilerType> arg_list(num_args); - while (auto arg = arg_enum->getNext()) - { - Type *arg_type = m_ast.GetSymbolFile()->ResolveTypeUID(arg->getSymIndexId()); - // If there's some error looking up one of the dependent types of this function signature, bail. - if (!arg_type) - return nullptr; - CompilerType arg_ast_type = arg_type->GetFullCompilerType(); - arg_list.push_back(arg_ast_type); - } - auto pdb_return_type = func_sig->getReturnType(); - Type *return_type = m_ast.GetSymbolFile()->ResolveTypeUID(pdb_return_type->getSymIndexId()); - // If there's some error looking up one of the dependent types of this function signature, bail. - if (!return_type) - return nullptr; - CompilerType return_ast_type = return_type->GetFullCompilerType(); - uint32_t type_quals = 0; - if (func_sig->isConstType()) - type_quals |= clang::Qualifiers::Const; - if (func_sig->isVolatileType()) - type_quals |= clang::Qualifiers::Volatile; - CompilerType func_sig_ast_type = - m_ast.CreateFunctionType(return_ast_type, &arg_list[0], num_args, false, type_quals); - - return std::make_shared<Type>(func_sig->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(), 0, nullptr, - LLDB_INVALID_UID, Type::eEncodingIsUID, decl, func_sig_ast_type, - Type::eResolveStateFull); - } - else if (auto array_type = llvm::dyn_cast<PDBSymbolTypeArray>(&type)) - { - uint32_t num_elements = array_type->getCount(); - uint32_t element_uid = array_type->getElementType()->getSymIndexId(); - uint32_t bytes = array_type->getLength(); - - Type *element_type = m_ast.GetSymbolFile()->ResolveTypeUID(element_uid); - CompilerType element_ast_type = element_type->GetFullCompilerType(); - CompilerType array_ast_type = m_ast.CreateArrayType(element_ast_type, num_elements, false); - return std::make_shared<Type>(array_type->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(), bytes, nullptr, - LLDB_INVALID_UID, Type::eEncodingIsUID, decl, array_ast_type, - Type::eResolveStateFull); + + return std::make_shared<Type>(type.getSymIndexId(), m_ast.GetSymbolFile(), + ConstString(name), bytes, nullptr, + LLDB_INVALID_UID, Type::eEncodingIsUID, decl, + ast_enum, Type::eResolveStateFull); + } else if (auto type_def = llvm::dyn_cast<PDBSymbolTypeTypedef>(&type)) { + Type *target_type = + m_ast.GetSymbolFile()->ResolveTypeUID(type_def->getTypeId()); + std::string name = type_def->getName(); + uint64_t bytes = type_def->getLength(); + if (!target_type) + return nullptr; + CompilerType target_ast_type = target_type->GetFullCompilerType(); + CompilerDeclContext target_decl_ctx = + m_ast.GetSymbolFile()->GetDeclContextForUID(target_type->GetID()); + CompilerType ast_typedef = + m_ast.CreateTypedefType(target_ast_type, name.c_str(), target_decl_ctx); + return std::make_shared<Type>( + type_def->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name), + bytes, nullptr, target_type->GetID(), Type::eEncodingIsTypedefUID, decl, + ast_typedef, Type::eResolveStateFull); + } else if (auto func_sig = llvm::dyn_cast<PDBSymbolTypeFunctionSig>(&type)) { + auto arg_enum = func_sig->getArguments(); + uint32_t num_args = arg_enum->getChildCount(); + std::vector<CompilerType> arg_list(num_args); + while (auto arg = arg_enum->getNext()) { + Type *arg_type = + m_ast.GetSymbolFile()->ResolveTypeUID(arg->getSymIndexId()); + // If there's some error looking up one of the dependent types of this + // function signature, bail. + if (!arg_type) + return nullptr; + CompilerType arg_ast_type = arg_type->GetFullCompilerType(); + arg_list.push_back(arg_ast_type); } - return nullptr; + auto pdb_return_type = func_sig->getReturnType(); + Type *return_type = + m_ast.GetSymbolFile()->ResolveTypeUID(pdb_return_type->getSymIndexId()); + // If there's some error looking up one of the dependent types of this + // function signature, bail. + if (!return_type) + return nullptr; + CompilerType return_ast_type = return_type->GetFullCompilerType(); + uint32_t type_quals = 0; + if (func_sig->isConstType()) + type_quals |= clang::Qualifiers::Const; + if (func_sig->isVolatileType()) + type_quals |= clang::Qualifiers::Volatile; + CompilerType func_sig_ast_type = m_ast.CreateFunctionType( + return_ast_type, &arg_list[0], num_args, false, type_quals); + + return std::make_shared<Type>( + func_sig->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(), 0, + nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, decl, + func_sig_ast_type, Type::eResolveStateFull); + } else if (auto array_type = llvm::dyn_cast<PDBSymbolTypeArray>(&type)) { + uint32_t num_elements = array_type->getCount(); + uint32_t element_uid = array_type->getElementType()->getSymIndexId(); + uint32_t bytes = array_type->getLength(); + + Type *element_type = m_ast.GetSymbolFile()->ResolveTypeUID(element_uid); + CompilerType element_ast_type = element_type->GetFullCompilerType(); + CompilerType array_ast_type = + m_ast.CreateArrayType(element_ast_type, num_elements, false); + return std::make_shared<Type>( + array_type->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(), + bytes, nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, decl, + array_ast_type, Type::eResolveStateFull); + } + return nullptr; } -bool -PDBASTParser::AddEnumValue(CompilerType enum_type, const PDBSymbolData &enum_value) const -{ - Declaration decl; - Variant v = enum_value.getValue(); - std::string name = enum_value.getName(); - int64_t raw_value; - switch (v.Type) - { - case PDB_VariantType::Int8: - raw_value = v.Value.Int8; - break; - case PDB_VariantType::Int16: - raw_value = v.Value.Int16; - break; - case PDB_VariantType::Int32: - raw_value = v.Value.Int32; - break; - case PDB_VariantType::Int64: - raw_value = v.Value.Int64; - break; - case PDB_VariantType::UInt8: - raw_value = v.Value.UInt8; - break; - case PDB_VariantType::UInt16: - raw_value = v.Value.UInt16; - break; - case PDB_VariantType::UInt32: - raw_value = v.Value.UInt32; - break; - case PDB_VariantType::UInt64: - raw_value = v.Value.UInt64; - break; - default: - return false; - } - CompilerType underlying_type = m_ast.GetEnumerationIntegerType(enum_type.GetOpaqueQualType()); - uint32_t byte_size = m_ast.getASTContext()->getTypeSize(ClangUtil::GetQualType(underlying_type)); - return m_ast.AddEnumerationValueToEnumerationType(enum_type.GetOpaqueQualType(), underlying_type, decl, - name.c_str(), raw_value, byte_size * 8); +bool PDBASTParser::AddEnumValue(CompilerType enum_type, + const PDBSymbolData &enum_value) const { + Declaration decl; + Variant v = enum_value.getValue(); + std::string name = enum_value.getName(); + int64_t raw_value; + switch (v.Type) { + case PDB_VariantType::Int8: + raw_value = v.Value.Int8; + break; + case PDB_VariantType::Int16: + raw_value = v.Value.Int16; + break; + case PDB_VariantType::Int32: + raw_value = v.Value.Int32; + break; + case PDB_VariantType::Int64: + raw_value = v.Value.Int64; + break; + case PDB_VariantType::UInt8: + raw_value = v.Value.UInt8; + break; + case PDB_VariantType::UInt16: + raw_value = v.Value.UInt16; + break; + case PDB_VariantType::UInt32: + raw_value = v.Value.UInt32; + break; + case PDB_VariantType::UInt64: + raw_value = v.Value.UInt64; + break; + default: + return false; + } + CompilerType underlying_type = + m_ast.GetEnumerationIntegerType(enum_type.GetOpaqueQualType()); + uint32_t byte_size = m_ast.getASTContext()->getTypeSize( + ClangUtil::GetQualType(underlying_type)); + return m_ast.AddEnumerationValueToEnumerationType( + enum_type.GetOpaqueQualType(), underlying_type, decl, name.c_str(), + raw_value, byte_size * 8); } diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.h index ca425c17c451..e9ff02c0a77e 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.h @@ -14,45 +14,39 @@ #include "lldb/Symbol/ClangASTImporter.h" -namespace clang -{ +namespace clang { class CharUnits; class CXXRecordDecl; class FieldDecl; class RecordDecl; } -namespace lldb_private -{ +namespace lldb_private { class ClangASTContext; class CompilerType; } -namespace llvm -{ -namespace pdb -{ +namespace llvm { +namespace pdb { class PDBSymbol; class PDBSymbolData; class PDBSymbolTypeBuiltin; } } -class PDBASTParser -{ +class PDBASTParser { public: - PDBASTParser(lldb_private::ClangASTContext &ast); - ~PDBASTParser(); + PDBASTParser(lldb_private::ClangASTContext &ast); + ~PDBASTParser(); - lldb::TypeSP - CreateLLDBTypeFromPDBType(const llvm::pdb::PDBSymbol &type); + lldb::TypeSP CreateLLDBTypeFromPDBType(const llvm::pdb::PDBSymbol &type); private: - bool - AddEnumValue(lldb_private::CompilerType enum_type, const llvm::pdb::PDBSymbolData &data) const; + bool AddEnumValue(lldb_private::CompilerType enum_type, + const llvm::pdb::PDBSymbolData &data) const; - lldb_private::ClangASTContext &m_ast; - lldb_private::ClangASTImporter m_ast_importer; + lldb_private::ClangASTContext &m_ast; + lldb_private::ClangASTImporter m_ast_importer; }; #endif // SymbolFileDWARF_DWARFASTParserClang_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp index d8092c011acb..cd99493c239a 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -42,692 +42,661 @@ using namespace lldb_private; using namespace llvm::pdb; -namespace -{ -lldb::LanguageType -TranslateLanguage(PDB_Lang lang) -{ - switch (lang) - { - case PDB_Lang::Cpp: - return lldb::LanguageType::eLanguageTypeC_plus_plus; - case PDB_Lang::C: - return lldb::LanguageType::eLanguageTypeC; - default: - return lldb::LanguageType::eLanguageTypeUnknown; - } - } - - bool - ShouldAddLine(uint32_t requested_line, uint32_t actual_line, uint32_t addr_length) - { - return ((requested_line == 0 || actual_line == requested_line) && addr_length > 0); - } +namespace { +lldb::LanguageType TranslateLanguage(PDB_Lang lang) { + switch (lang) { + case PDB_Lang::Cpp: + return lldb::LanguageType::eLanguageTypeC_plus_plus; + case PDB_Lang::C: + return lldb::LanguageType::eLanguageTypeC; + default: + return lldb::LanguageType::eLanguageTypeUnknown; + } } -void -SymbolFilePDB::Initialize() -{ - PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance, - DebuggerInitialize); +bool ShouldAddLine(uint32_t requested_line, uint32_t actual_line, + uint32_t addr_length) { + return ((requested_line == 0 || actual_line == requested_line) && + addr_length > 0); } - -void -SymbolFilePDB::Terminate() -{ - PluginManager::UnregisterPlugin(CreateInstance); } -void -SymbolFilePDB::DebuggerInitialize(lldb_private::Debugger &debugger) -{ +void SymbolFilePDB::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + GetPluginDescriptionStatic(), CreateInstance, + DebuggerInitialize); } -lldb_private::ConstString -SymbolFilePDB::GetPluginNameStatic() -{ - static ConstString g_name("pdb"); - return g_name; +void SymbolFilePDB::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); } -const char * -SymbolFilePDB::GetPluginDescriptionStatic() -{ - return "Microsoft PDB debug symbol file reader."; -} +void SymbolFilePDB::DebuggerInitialize(lldb_private::Debugger &debugger) {} -lldb_private::SymbolFile * -SymbolFilePDB::CreateInstance(lldb_private::ObjectFile *obj_file) -{ - return new SymbolFilePDB(obj_file); +lldb_private::ConstString SymbolFilePDB::GetPluginNameStatic() { + static ConstString g_name("pdb"); + return g_name; } -SymbolFilePDB::SymbolFilePDB(lldb_private::ObjectFile *object_file) - : SymbolFile(object_file), m_cached_compile_unit_count(0) -{ +const char *SymbolFilePDB::GetPluginDescriptionStatic() { + return "Microsoft PDB debug symbol file reader."; } -SymbolFilePDB::~SymbolFilePDB() -{ +lldb_private::SymbolFile * +SymbolFilePDB::CreateInstance(lldb_private::ObjectFile *obj_file) { + return new SymbolFilePDB(obj_file); } -uint32_t -SymbolFilePDB::CalculateAbilities() -{ - if (!m_session_up) - { - // Lazily load and match the PDB file, but only do this once. - std::string exePath = m_obj_file->GetFileSpec().GetPath(); - auto error = loadDataForEXE(PDB_ReaderType::DIA, llvm::StringRef(exePath), m_session_up); - if (error) - { - llvm::consumeError(std::move(error)); - return 0; - } +SymbolFilePDB::SymbolFilePDB(lldb_private::ObjectFile *object_file) + : SymbolFile(object_file), m_cached_compile_unit_count(0) {} + +SymbolFilePDB::~SymbolFilePDB() {} + +uint32_t SymbolFilePDB::CalculateAbilities() { + if (!m_session_up) { + // Lazily load and match the PDB file, but only do this once. + std::string exePath = m_obj_file->GetFileSpec().GetPath(); + auto error = loadDataForEXE(PDB_ReaderType::DIA, llvm::StringRef(exePath), + m_session_up); + if (error) { + llvm::consumeError(std::move(error)); + return 0; } - return CompileUnits | LineTables; + } + return CompileUnits | LineTables; } -void -SymbolFilePDB::InitializeObject() -{ - lldb::addr_t obj_load_address = m_obj_file->GetFileOffset(); - m_session_up->setLoadAddress(obj_load_address); +void SymbolFilePDB::InitializeObject() { + lldb::addr_t obj_load_address = m_obj_file->GetFileOffset(); + m_session_up->setLoadAddress(obj_load_address); - TypeSystem *type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); - ClangASTContext *clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(type_system); - m_tu_decl_ctx_up = llvm::make_unique<CompilerDeclContext>(type_system, clang_type_system->GetTranslationUnitDecl()); + TypeSystem *type_system = + GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); + ClangASTContext *clang_type_system = + llvm::dyn_cast_or_null<ClangASTContext>(type_system); + m_tu_decl_ctx_up = llvm::make_unique<CompilerDeclContext>( + type_system, clang_type_system->GetTranslationUnitDecl()); } -uint32_t -SymbolFilePDB::GetNumCompileUnits() -{ - if (m_cached_compile_unit_count == 0) - { - auto global = m_session_up->getGlobalScope(); - auto compilands = global->findAllChildren<PDBSymbolCompiland>(); - m_cached_compile_unit_count = compilands->getChildCount(); - - // The linker can inject an additional "dummy" compilation unit into the PDB. - // Ignore this special compile unit for our purposes, if it is there. It is - // always the last one. - auto last_cu = compilands->getChildAtIndex(m_cached_compile_unit_count - 1); - std::string name = last_cu->getName(); - if (name == "* Linker *") - --m_cached_compile_unit_count; - } - return m_cached_compile_unit_count; -} - -lldb::CompUnitSP -SymbolFilePDB::ParseCompileUnitAtIndex(uint32_t index) -{ +uint32_t SymbolFilePDB::GetNumCompileUnits() { + if (m_cached_compile_unit_count == 0) { auto global = m_session_up->getGlobalScope(); auto compilands = global->findAllChildren<PDBSymbolCompiland>(); - auto cu = compilands->getChildAtIndex(index); + m_cached_compile_unit_count = compilands->getChildCount(); + + // The linker can inject an additional "dummy" compilation unit into the + // PDB. + // Ignore this special compile unit for our purposes, if it is there. It is + // always the last one. + auto last_cu = compilands->getChildAtIndex(m_cached_compile_unit_count - 1); + std::string name = last_cu->getName(); + if (name == "* Linker *") + --m_cached_compile_unit_count; + } + return m_cached_compile_unit_count; +} - uint32_t id = cu->getSymIndexId(); +lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitAtIndex(uint32_t index) { + auto global = m_session_up->getGlobalScope(); + auto compilands = global->findAllChildren<PDBSymbolCompiland>(); + auto cu = compilands->getChildAtIndex(index); - return ParseCompileUnitForSymIndex(id); + uint32_t id = cu->getSymIndexId(); + + return ParseCompileUnitForSymIndex(id); } lldb::LanguageType -SymbolFilePDB::ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) -{ - // What fields should I expect to be filled out on the SymbolContext? Is it - // safe to assume that `sc.comp_unit` is valid? - if (!sc.comp_unit) - return lldb::eLanguageTypeUnknown; - - auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(sc.comp_unit->GetID()); - if (!cu) - return lldb::eLanguageTypeUnknown; - auto details = cu->findOneChild<PDBSymbolCompilandDetails>(); - if (!details) - return lldb::eLanguageTypeUnknown; - return TranslateLanguage(details->getLanguage()); -} +SymbolFilePDB::ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) { + // What fields should I expect to be filled out on the SymbolContext? Is it + // safe to assume that `sc.comp_unit` is valid? + if (!sc.comp_unit) + return lldb::eLanguageTypeUnknown; -size_t -SymbolFilePDB::ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc) -{ - // TODO: Implement this - return size_t(); + auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>( + sc.comp_unit->GetID()); + if (!cu) + return lldb::eLanguageTypeUnknown; + auto details = cu->findOneChild<PDBSymbolCompilandDetails>(); + if (!details) + return lldb::eLanguageTypeUnknown; + return TranslateLanguage(details->getLanguage()); } -bool -SymbolFilePDB::ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc) -{ - return ParseCompileUnitLineTable(sc, 0); +size_t SymbolFilePDB::ParseCompileUnitFunctions( + const lldb_private::SymbolContext &sc) { + // TODO: Implement this + return size_t(); } -bool -SymbolFilePDB::ParseCompileUnitDebugMacros(const lldb_private::SymbolContext &sc) -{ - // PDB doesn't contain information about macros - return false; +bool SymbolFilePDB::ParseCompileUnitLineTable( + const lldb_private::SymbolContext &sc) { + return ParseCompileUnitLineTable(sc, 0); } -bool -SymbolFilePDB::ParseCompileUnitSupportFiles(const lldb_private::SymbolContext &sc, - lldb_private::FileSpecList &support_files) -{ - if (!sc.comp_unit) - return false; - - // In theory this is unnecessary work for us, because all of this information is easily - // (and quickly) accessible from DebugInfoPDB, so caching it a second time seems like a waste. - // Unfortunately, there's no good way around this short of a moderate refactor, since SymbolVendor - // depends on being able to cache this list. - auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(sc.comp_unit->GetID()); - if (!cu) - return false; - auto files = m_session_up->getSourceFilesForCompiland(*cu); - if (!files || files->getChildCount() == 0) - return false; - - while (auto file = files->getNext()) - { - FileSpec spec(file->getFileName(), false); - support_files.Append(spec); - } - return true; +bool SymbolFilePDB::ParseCompileUnitDebugMacros( + const lldb_private::SymbolContext &sc) { + // PDB doesn't contain information about macros + return false; } -bool -SymbolFilePDB::ParseImportedModules(const lldb_private::SymbolContext &sc, - std::vector<lldb_private::ConstString> &imported_modules) -{ - // PDB does not yet support module debug info +bool SymbolFilePDB::ParseCompileUnitSupportFiles( + const lldb_private::SymbolContext &sc, + lldb_private::FileSpecList &support_files) { + if (!sc.comp_unit) return false; -} -size_t -SymbolFilePDB::ParseFunctionBlocks(const lldb_private::SymbolContext &sc) -{ - // TODO: Implement this - return size_t(); + // In theory this is unnecessary work for us, because all of this information + // is easily + // (and quickly) accessible from DebugInfoPDB, so caching it a second time + // seems like a waste. + // Unfortunately, there's no good way around this short of a moderate + // refactor, since SymbolVendor + // depends on being able to cache this list. + auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>( + sc.comp_unit->GetID()); + if (!cu) + return false; + auto files = m_session_up->getSourceFilesForCompiland(*cu); + if (!files || files->getChildCount() == 0) + return false; + + while (auto file = files->getNext()) { + FileSpec spec(file->getFileName(), false); + support_files.Append(spec); + } + return true; } -size_t -SymbolFilePDB::ParseTypes(const lldb_private::SymbolContext &sc) -{ - // TODO: Implement this - return size_t(); +bool SymbolFilePDB::ParseImportedModules( + const lldb_private::SymbolContext &sc, + std::vector<lldb_private::ConstString> &imported_modules) { + // PDB does not yet support module debug info + return false; } size_t -SymbolFilePDB::ParseVariablesForContext(const lldb_private::SymbolContext &sc) -{ - // TODO: Implement this - return size_t(); -} - -lldb_private::Type * -SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) -{ - auto find_result = m_types.find(type_uid); - if (find_result != m_types.end()) - return find_result->second.get(); - - TypeSystem *type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); - ClangASTContext *clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(type_system); - if (!clang_type_system) - return nullptr; - PDBASTParser *pdb = llvm::dyn_cast<PDBASTParser>(clang_type_system->GetPDBParser()); - if (!pdb) - return nullptr; - - auto pdb_type = m_session_up->getSymbolById(type_uid); - if (pdb_type == nullptr) - return nullptr; - - lldb::TypeSP result = pdb->CreateLLDBTypeFromPDBType(*pdb_type); - m_types.insert(std::make_pair(type_uid, result)); - return result.get(); -} - -bool -SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) -{ - // TODO: Implement this - return false; +SymbolFilePDB::ParseFunctionBlocks(const lldb_private::SymbolContext &sc) { + // TODO: Implement this + return size_t(); } -lldb_private::CompilerDecl -SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) -{ - return lldb_private::CompilerDecl(); +size_t SymbolFilePDB::ParseTypes(const lldb_private::SymbolContext &sc) { + // TODO: Implement this + return size_t(); } -lldb_private::CompilerDeclContext -SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid) -{ - // PDB always uses the translation unit decl context for everything. We can improve this later - // but it's not easy because PDB doesn't provide a high enough level of type fidelity in this area. - return *m_tu_decl_ctx_up; +size_t +SymbolFilePDB::ParseVariablesForContext(const lldb_private::SymbolContext &sc) { + // TODO: Implement this + return size_t(); } -lldb_private::CompilerDeclContext -SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid) -{ - return *m_tu_decl_ctx_up; -} +lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) { + auto find_result = m_types.find(type_uid); + if (find_result != m_types.end()) + return find_result->second.get(); -void -SymbolFilePDB::ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) -{ -} + TypeSystem *type_system = + GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); + ClangASTContext *clang_type_system = + llvm::dyn_cast_or_null<ClangASTContext>(type_system); + if (!clang_type_system) + return nullptr; + PDBASTParser *pdb = + llvm::dyn_cast<PDBASTParser>(clang_type_system->GetPDBParser()); + if (!pdb) + return nullptr; -uint32_t -SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr, uint32_t resolve_scope, - lldb_private::SymbolContext &sc) -{ - return uint32_t(); -} + auto pdb_type = m_session_up->getSymbolById(type_uid); + if (pdb_type == nullptr) + return nullptr; -uint32_t -SymbolFilePDB::ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines, - uint32_t resolve_scope, lldb_private::SymbolContextList &sc_list) -{ - if (resolve_scope & lldb::eSymbolContextCompUnit) - { - // Locate all compilation units with line numbers referencing the specified file. For example, if - // `file_spec` is <vector>, then this should return all source files and header files that reference - // <vector>, either directly or indirectly. - auto compilands = - m_session_up->findCompilandsForSourceFile(file_spec.GetPath(), PDB_NameSearchFlags::NS_CaseInsensitive); - - // For each one, either find get its previously parsed data, or parse it afresh and add it to - // the symbol context list. - while (auto compiland = compilands->getNext()) - { - // If we're not checking inlines, then don't add line information for this file unless the FileSpec - // matches. - if (!check_inlines) - { - // `getSourceFileName` returns the basename of the original source file used to generate this compiland. - // It does not return the full path. Currently the only way to get that is to do a basename lookup to - // get the IPDBSourceFile, but this is ambiguous in the case of two source files with the same name - // contributing to the same compiland. This is a moderately extreme edge case, so we consider this ok - // for now, although we need to find a long term solution. - std::string source_file = compiland->getSourceFileName(); - auto pdb_file = m_session_up->findOneSourceFile(compiland.get(), source_file, - PDB_NameSearchFlags::NS_CaseInsensitive); - source_file = pdb_file->getFileName(); - FileSpec this_spec(source_file, false, FileSpec::ePathSyntaxWindows); - if (!file_spec.FileEquals(this_spec)) - continue; - } - - SymbolContext sc; - auto cu = ParseCompileUnitForSymIndex(compiland->getSymIndexId()); - sc.comp_unit = cu.get(); - sc.module_sp = cu->GetModule(); - sc_list.Append(sc); - - // If we were asked to resolve line entries, add all entries to the line table that match the requested - // line (or all lines if `line` == 0) - if (resolve_scope & lldb::eSymbolContextLineEntry) - ParseCompileUnitLineTable(sc, line); - } - } - return sc_list.GetSize(); + lldb::TypeSP result = pdb->CreateLLDBTypeFromPDBType(*pdb_type); + m_types.insert(std::make_pair(type_uid, result)); + return result.get(); } -uint32_t -SymbolFilePDB::FindGlobalVariables(const lldb_private::ConstString &name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, - uint32_t max_matches, lldb_private::VariableList &variables) -{ - return uint32_t(); +bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) { + // TODO: Implement this + return false; } -uint32_t -SymbolFilePDB::FindGlobalVariables(const lldb_private::RegularExpression ®ex, bool append, uint32_t max_matches, - lldb_private::VariableList &variables) -{ - return uint32_t(); +lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) { + return lldb_private::CompilerDecl(); } -uint32_t -SymbolFilePDB::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) -{ - return uint32_t(); +lldb_private::CompilerDeclContext +SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid) { + // PDB always uses the translation unit decl context for everything. We can + // improve this later + // but it's not easy because PDB doesn't provide a high enough level of type + // fidelity in this area. + return *m_tu_decl_ctx_up; } -uint32_t -SymbolFilePDB::FindFunctions(const lldb_private::RegularExpression ®ex, bool include_inlines, bool append, - lldb_private::SymbolContextList &sc_list) -{ - return uint32_t(); +lldb_private::CompilerDeclContext +SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid) { + return *m_tu_decl_ctx_up; } -void -SymbolFilePDB::GetMangledNamesForFunction(const std::string &scope_qualified_name, - std::vector<lldb_private::ConstString> &mangled_names) -{ -} +void SymbolFilePDB::ParseDeclsForContext( + lldb_private::CompilerDeclContext decl_ctx) {} uint32_t -SymbolFilePDB::FindTypes(const lldb_private::SymbolContext &sc, 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) -{ - if (!append) - types.Clear(); - if (!name) - return 0; - - searched_symbol_files.clear(); - searched_symbol_files.insert(this); - - std::string name_str = name.AsCString(); - - // If this might be a regex, we have to return EVERY symbol and process them one by one, which is going - // to destroy performance on large PDB files. So try really hard not to use a regex match. - if (name_str.find_first_of("[]?*.-+\\") != std::string::npos) - FindTypesByRegex(name_str, max_matches, types); - else - FindTypesByName(name_str, max_matches, types); - return types.GetSize(); -} - -void -SymbolFilePDB::FindTypesByRegex(const std::string ®ex, uint32_t max_matches, lldb_private::TypeMap &types) -{ - // When searching by regex, we need to go out of our way to limit the search space as much as possible, since - // the way this is implemented is by searching EVERYTHING in the PDB and manually doing a regex compare. PDB - // library isn't optimized for regex searches or searches across multiple symbol types at the same time, so the - // best we can do is to search enums, then typedefs, then classes one by one, and do a regex compare against all - // of them. - PDB_SymType tags_to_search[] = {PDB_SymType::Enum, PDB_SymType::Typedef, PDB_SymType::UDT}; - auto global = m_session_up->getGlobalScope(); - std::unique_ptr<IPDBEnumSymbols> results; - - std::regex re(regex); - - uint32_t matches = 0; - - for (auto tag : tags_to_search) - { - results = global->findAllChildren(tag); - while (auto result = results->getNext()) - { - if (max_matches > 0 && matches >= max_matches) - break; - - std::string type_name; - if (auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(result.get())) - type_name = enum_type->getName(); - else if (auto typedef_type = llvm::dyn_cast<PDBSymbolTypeTypedef>(result.get())) - type_name = typedef_type->getName(); - else if (auto class_type = llvm::dyn_cast<PDBSymbolTypeUDT>(result.get())) - type_name = class_type->getName(); - else - { - // We're only looking for types that have names. Skip symbols, as well as - // unnamed types such as arrays, pointers, etc. - continue; - } - - if (!std::regex_match(type_name, re)) - continue; - - // This should cause the type to get cached and stored in the `m_types` lookup. - if (!ResolveTypeUID(result->getSymIndexId())) - continue; - - auto iter = m_types.find(result->getSymIndexId()); - if (iter == m_types.end()) - continue; - types.Insert(iter->second); - ++matches; - } +SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr, + uint32_t resolve_scope, + lldb_private::SymbolContext &sc) { + return uint32_t(); +} + +uint32_t SymbolFilePDB::ResolveSymbolContext( + const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines, + uint32_t resolve_scope, lldb_private::SymbolContextList &sc_list) { + if (resolve_scope & lldb::eSymbolContextCompUnit) { + // Locate all compilation units with line numbers referencing the specified + // file. For example, if + // `file_spec` is <vector>, then this should return all source files and + // header files that reference + // <vector>, either directly or indirectly. + auto compilands = m_session_up->findCompilandsForSourceFile( + file_spec.GetPath(), PDB_NameSearchFlags::NS_CaseInsensitive); + + // For each one, either find get its previously parsed data, or parse it + // afresh and add it to + // the symbol context list. + while (auto compiland = compilands->getNext()) { + // If we're not checking inlines, then don't add line information for this + // file unless the FileSpec + // matches. + if (!check_inlines) { + // `getSourceFileName` returns the basename of the original source file + // used to generate this compiland. + // It does not return the full path. Currently the only way to get that + // is to do a basename lookup to + // get the IPDBSourceFile, but this is ambiguous in the case of two + // source files with the same name + // contributing to the same compiland. This is a moderately extreme + // edge case, so we consider this ok + // for now, although we need to find a long term solution. + std::string source_file = compiland->getSourceFileName(); + auto pdb_file = m_session_up->findOneSourceFile( + compiland.get(), source_file, + PDB_NameSearchFlags::NS_CaseInsensitive); + source_file = pdb_file->getFileName(); + FileSpec this_spec(source_file, false, FileSpec::ePathSyntaxWindows); + if (!file_spec.FileEquals(this_spec)) + continue; + } + + SymbolContext sc; + auto cu = ParseCompileUnitForSymIndex(compiland->getSymIndexId()); + sc.comp_unit = cu.get(); + sc.module_sp = cu->GetModule(); + sc_list.Append(sc); + + // If we were asked to resolve line entries, add all entries to the line + // table that match the requested + // line (or all lines if `line` == 0) + if (resolve_scope & lldb::eSymbolContextLineEntry) + ParseCompileUnitLineTable(sc, line); } + } + return sc_list.GetSize(); } -void -SymbolFilePDB::FindTypesByName(const std::string &name, uint32_t max_matches, lldb_private::TypeMap &types) -{ - auto global = m_session_up->getGlobalScope(); - std::unique_ptr<IPDBEnumSymbols> results; - results = global->findChildren(PDB_SymType::None, name.c_str(), PDB_NameSearchFlags::NS_Default); - - uint32_t matches = 0; - - while (auto result = results->getNext()) - { - if (max_matches > 0 && matches >= max_matches) - break; - switch (result->getSymTag()) - { - case PDB_SymType::Enum: - case PDB_SymType::UDT: - case PDB_SymType::Typedef: - break; - default: - // We're only looking for types that have names. Skip symbols, as well as - // unnamed types such as arrays, pointers, etc. - continue; - } +uint32_t SymbolFilePDB::FindGlobalVariables( + const lldb_private::ConstString &name, + const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, + uint32_t max_matches, lldb_private::VariableList &variables) { + return uint32_t(); +} - // This should cause the type to get cached and stored in the `m_types` lookup. - if (!ResolveTypeUID(result->getSymIndexId())) - continue; +uint32_t +SymbolFilePDB::FindGlobalVariables(const lldb_private::RegularExpression ®ex, + bool append, uint32_t max_matches, + lldb_private::VariableList &variables) { + return uint32_t(); +} - auto iter = m_types.find(result->getSymIndexId()); - if (iter == m_types.end()) - continue; - types.Insert(iter->second); - ++matches; - } +uint32_t SymbolFilePDB::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) { + return uint32_t(); } -size_t -SymbolFilePDB::FindTypes(const std::vector<lldb_private::CompilerContext> &contexts, bool append, - lldb_private::TypeMap &types) -{ +uint32_t +SymbolFilePDB::FindFunctions(const lldb_private::RegularExpression ®ex, + bool include_inlines, bool append, + lldb_private::SymbolContextList &sc_list) { + return uint32_t(); +} + +void SymbolFilePDB::GetMangledNamesForFunction( + const std::string &scope_qualified_name, + std::vector<lldb_private::ConstString> &mangled_names) {} + +uint32_t SymbolFilePDB::FindTypes( + const lldb_private::SymbolContext &sc, + 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) { + if (!append) + types.Clear(); + if (!name) return 0; -} -lldb_private::TypeList * -SymbolFilePDB::GetTypeList() -{ - return nullptr; -} + searched_symbol_files.clear(); + searched_symbol_files.insert(this); + + std::string name_str = name.AsCString(); + + // If this might be a regex, we have to return EVERY symbol and process them + // one by one, which is going + // to destroy performance on large PDB files. So try really hard not to use a + // regex match. + if (name_str.find_first_of("[]?*.-+\\") != std::string::npos) + FindTypesByRegex(name_str, max_matches, types); + else + FindTypesByName(name_str, max_matches, types); + return types.GetSize(); +} + +void SymbolFilePDB::FindTypesByRegex(const std::string ®ex, + uint32_t max_matches, + lldb_private::TypeMap &types) { + // When searching by regex, we need to go out of our way to limit the search + // space as much as possible, since + // the way this is implemented is by searching EVERYTHING in the PDB and + // manually doing a regex compare. PDB + // library isn't optimized for regex searches or searches across multiple + // symbol types at the same time, so the + // best we can do is to search enums, then typedefs, then classes one by one, + // and do a regex compare against all + // of them. + PDB_SymType tags_to_search[] = {PDB_SymType::Enum, PDB_SymType::Typedef, + PDB_SymType::UDT}; + auto global = m_session_up->getGlobalScope(); + std::unique_ptr<IPDBEnumSymbols> results; + + std::regex re(regex); + + uint32_t matches = 0; + + for (auto tag : tags_to_search) { + results = global->findAllChildren(tag); + while (auto result = results->getNext()) { + if (max_matches > 0 && matches >= max_matches) + break; + + std::string type_name; + if (auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(result.get())) + type_name = enum_type->getName(); + else if (auto typedef_type = + llvm::dyn_cast<PDBSymbolTypeTypedef>(result.get())) + type_name = typedef_type->getName(); + else if (auto class_type = llvm::dyn_cast<PDBSymbolTypeUDT>(result.get())) + type_name = class_type->getName(); + else { + // We're only looking for types that have names. Skip symbols, as well + // as + // unnamed types such as arrays, pointers, etc. + continue; + } + + if (!std::regex_match(type_name, re)) + continue; + + // This should cause the type to get cached and stored in the `m_types` + // lookup. + if (!ResolveTypeUID(result->getSymIndexId())) + continue; + + auto iter = m_types.find(result->getSymIndexId()); + if (iter == m_types.end()) + continue; + types.Insert(iter->second); + ++matches; + } + } +} + +void SymbolFilePDB::FindTypesByName(const std::string &name, + uint32_t max_matches, + lldb_private::TypeMap &types) { + auto global = m_session_up->getGlobalScope(); + std::unique_ptr<IPDBEnumSymbols> results; + results = global->findChildren(PDB_SymType::None, name, + PDB_NameSearchFlags::NS_Default); + + uint32_t matches = 0; + + while (auto result = results->getNext()) { + if (max_matches > 0 && matches >= max_matches) + break; + switch (result->getSymTag()) { + case PDB_SymType::Enum: + case PDB_SymType::UDT: + case PDB_SymType::Typedef: + break; + default: + // We're only looking for types that have names. Skip symbols, as well as + // unnamed types such as arrays, pointers, etc. + continue; + } -size_t -SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope, uint32_t type_mask, - lldb_private::TypeList &type_list) -{ - return size_t(); -} + // This should cause the type to get cached and stored in the `m_types` + // lookup. + if (!ResolveTypeUID(result->getSymIndexId())) + continue; -lldb_private::TypeSystem * -SymbolFilePDB::GetTypeSystemForLanguage(lldb::LanguageType language) -{ - auto type_system = m_obj_file->GetModule()->GetTypeSystemForLanguage(language); - if (type_system) - type_system->SetSymbolFile(this); - return type_system; + auto iter = m_types.find(result->getSymIndexId()); + if (iter == m_types.end()) + continue; + types.Insert(iter->second); + ++matches; + } } -lldb_private::CompilerDeclContext -SymbolFilePDB::FindNamespace(const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name, - const lldb_private::CompilerDeclContext *parent_decl_ctx) -{ - return lldb_private::CompilerDeclContext(); +size_t SymbolFilePDB::FindTypes( + const std::vector<lldb_private::CompilerContext> &contexts, bool append, + lldb_private::TypeMap &types) { + return 0; } -lldb_private::ConstString -SymbolFilePDB::GetPluginName() -{ - static ConstString g_name("pdb"); - return g_name; +lldb_private::TypeList *SymbolFilePDB::GetTypeList() { return nullptr; } + +size_t SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope, + uint32_t type_mask, + lldb_private::TypeList &type_list) { + return size_t(); } -uint32_t -SymbolFilePDB::GetPluginVersion() -{ - return 1; -} - -IPDBSession & -SymbolFilePDB::GetPDBSession() -{ - return *m_session_up; -} - -const IPDBSession & -SymbolFilePDB::GetPDBSession() const -{ - return *m_session_up; -} - -lldb::CompUnitSP -SymbolFilePDB::ParseCompileUnitForSymIndex(uint32_t id) -{ - auto found_cu = m_comp_units.find(id); - if (found_cu != m_comp_units.end()) - return found_cu->second; - - auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(id); - - // `getSourceFileName` returns the basename of the original source file used to generate this compiland. It does - // not return the full path. Currently the only way to get that is to do a basename lookup to get the - // IPDBSourceFile, but this is ambiguous in the case of two source files with the same name contributing to the - // same compiland. This is a moderately extreme edge case, so we consider this ok for now, although we need to find - // a long term solution. - auto file = - m_session_up->findOneSourceFile(cu.get(), cu->getSourceFileName(), PDB_NameSearchFlags::NS_CaseInsensitive); - std::string path = file->getFileName(); - - lldb::LanguageType lang; - auto details = cu->findOneChild<PDBSymbolCompilandDetails>(); - if (!details) - lang = lldb::eLanguageTypeC_plus_plus; - else - lang = TranslateLanguage(details->getLanguage()); - - // Don't support optimized code for now, DebugInfoPDB does not return this information. - LazyBool optimized = eLazyBoolNo; - auto result = std::make_shared<CompileUnit>(m_obj_file->GetModule(), nullptr, path.c_str(), id, lang, optimized); - m_comp_units.insert(std::make_pair(id, result)); - return result; -} - -bool -SymbolFilePDB::ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc, uint32_t match_line) -{ - auto global = m_session_up->getGlobalScope(); - auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(sc.comp_unit->GetID()); - - // LineEntry needs the *index* of the file into the list of support files returned by - // ParseCompileUnitSupportFiles. But the underlying SDK gives us a globally unique - // idenfitifier in the namespace of the PDB. So, we have to do a mapping so that we - // can hand out indices. - llvm::DenseMap<uint32_t, uint32_t> index_map; - BuildSupportFileIdToSupportFileIndexMap(*cu, index_map); - auto line_table = llvm::make_unique<LineTable>(sc.comp_unit); - - // Find contributions to `cu` from all source and header files. - std::string path = sc.comp_unit->GetPath(); - auto files = m_session_up->getSourceFilesForCompiland(*cu); - - // For each source and header file, create a LineSequence for contributions to the cu - // from that file, and add the sequence. - while (auto file = files->getNext()) - { - std::unique_ptr<LineSequence> sequence(line_table->CreateLineSequenceContainer()); - auto lines = m_session_up->findLineNumbers(*cu, *file); - int entry_count = lines->getChildCount(); - - uint64_t prev_addr; - uint32_t prev_length; - uint32_t prev_line; - uint32_t prev_source_idx; - - for (int i = 0; i < entry_count; ++i) - { - auto line = lines->getChildAtIndex(i); - - uint64_t lno = line->getLineNumber(); - uint64_t addr = line->getVirtualAddress(); - uint32_t length = line->getLength(); - uint32_t source_id = line->getSourceFileId(); - uint32_t col = line->getColumnNumber(); - uint32_t source_idx = index_map[source_id]; - - // There was a gap between the current entry and the previous entry if the addresses don't perfectly line - // up. - bool is_gap = (i > 0) && (prev_addr + prev_length < addr); - - // Before inserting the current entry, insert a terminal entry at the end of the previous entry's address - // range if the current entry resulted in a gap from the previous entry. - if (is_gap && ShouldAddLine(match_line, prev_line, prev_length)) - { - line_table->AppendLineEntryToSequence(sequence.get(), prev_addr + prev_length, prev_line, 0, - prev_source_idx, false, false, false, false, true); - } - - if (ShouldAddLine(match_line, lno, length)) - { - bool is_statement = line->isStatement(); - bool is_prologue = false; - bool is_epilogue = false; - auto func = m_session_up->findSymbolByAddress(addr, PDB_SymType::Function); - if (func) - { - auto prologue = func->findOneChild<PDBSymbolFuncDebugStart>(); - is_prologue = (addr == prologue->getVirtualAddress()); - - auto epilogue = func->findOneChild<PDBSymbolFuncDebugEnd>(); - is_epilogue = (addr == epilogue->getVirtualAddress()); - } - - line_table->AppendLineEntryToSequence(sequence.get(), addr, lno, col, source_idx, is_statement, false, - is_prologue, is_epilogue, false); - } - - prev_addr = addr; - prev_length = length; - prev_line = lno; - prev_source_idx = source_idx; +lldb_private::TypeSystem * +SymbolFilePDB::GetTypeSystemForLanguage(lldb::LanguageType language) { + auto type_system = + m_obj_file->GetModule()->GetTypeSystemForLanguage(language); + if (type_system) + type_system->SetSymbolFile(this); + return type_system; +} + +lldb_private::CompilerDeclContext SymbolFilePDB::FindNamespace( + const lldb_private::SymbolContext &sc, + const lldb_private::ConstString &name, + const lldb_private::CompilerDeclContext *parent_decl_ctx) { + return lldb_private::CompilerDeclContext(); +} + +lldb_private::ConstString SymbolFilePDB::GetPluginName() { + static ConstString g_name("pdb"); + return g_name; +} + +uint32_t SymbolFilePDB::GetPluginVersion() { return 1; } + +IPDBSession &SymbolFilePDB::GetPDBSession() { return *m_session_up; } + +const IPDBSession &SymbolFilePDB::GetPDBSession() const { + return *m_session_up; +} + +lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitForSymIndex(uint32_t id) { + auto found_cu = m_comp_units.find(id); + if (found_cu != m_comp_units.end()) + return found_cu->second; + + auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(id); + + // `getSourceFileName` returns the basename of the original source file used + // to generate this compiland. It does + // not return the full path. Currently the only way to get that is to do a + // basename lookup to get the + // IPDBSourceFile, but this is ambiguous in the case of two source files with + // the same name contributing to the + // same compiland. This is a moderately extreme edge case, so we consider this + // ok for now, although we need to find + // a long term solution. + auto file = + m_session_up->findOneSourceFile(cu.get(), cu->getSourceFileName(), + PDB_NameSearchFlags::NS_CaseInsensitive); + std::string path = file->getFileName(); + + lldb::LanguageType lang; + auto details = cu->findOneChild<PDBSymbolCompilandDetails>(); + if (!details) + lang = lldb::eLanguageTypeC_plus_plus; + else + lang = TranslateLanguage(details->getLanguage()); + + // Don't support optimized code for now, DebugInfoPDB does not return this + // information. + LazyBool optimized = eLazyBoolNo; + auto result = std::make_shared<CompileUnit>( + m_obj_file->GetModule(), nullptr, path.c_str(), id, lang, optimized); + m_comp_units.insert(std::make_pair(id, result)); + return result; +} + +bool SymbolFilePDB::ParseCompileUnitLineTable( + const lldb_private::SymbolContext &sc, uint32_t match_line) { + auto global = m_session_up->getGlobalScope(); + auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>( + sc.comp_unit->GetID()); + + // LineEntry needs the *index* of the file into the list of support files + // returned by + // ParseCompileUnitSupportFiles. But the underlying SDK gives us a globally + // unique + // idenfitifier in the namespace of the PDB. So, we have to do a mapping so + // that we + // can hand out indices. + llvm::DenseMap<uint32_t, uint32_t> index_map; + BuildSupportFileIdToSupportFileIndexMap(*cu, index_map); + auto line_table = llvm::make_unique<LineTable>(sc.comp_unit); + + // Find contributions to `cu` from all source and header files. + std::string path = sc.comp_unit->GetPath(); + auto files = m_session_up->getSourceFilesForCompiland(*cu); + + // For each source and header file, create a LineSequence for contributions to + // the cu + // from that file, and add the sequence. + while (auto file = files->getNext()) { + std::unique_ptr<LineSequence> sequence( + line_table->CreateLineSequenceContainer()); + auto lines = m_session_up->findLineNumbers(*cu, *file); + int entry_count = lines->getChildCount(); + + uint64_t prev_addr; + uint32_t prev_length; + uint32_t prev_line; + uint32_t prev_source_idx; + + for (int i = 0; i < entry_count; ++i) { + auto line = lines->getChildAtIndex(i); + + uint64_t lno = line->getLineNumber(); + uint64_t addr = line->getVirtualAddress(); + uint32_t length = line->getLength(); + uint32_t source_id = line->getSourceFileId(); + uint32_t col = line->getColumnNumber(); + uint32_t source_idx = index_map[source_id]; + + // There was a gap between the current entry and the previous entry if the + // addresses don't perfectly line + // up. + bool is_gap = (i > 0) && (prev_addr + prev_length < addr); + + // Before inserting the current entry, insert a terminal entry at the end + // of the previous entry's address + // range if the current entry resulted in a gap from the previous entry. + if (is_gap && ShouldAddLine(match_line, prev_line, prev_length)) { + line_table->AppendLineEntryToSequence( + sequence.get(), prev_addr + prev_length, prev_line, 0, + prev_source_idx, false, false, false, false, true); + } + + if (ShouldAddLine(match_line, lno, length)) { + bool is_statement = line->isStatement(); + bool is_prologue = false; + bool is_epilogue = false; + auto func = + m_session_up->findSymbolByAddress(addr, PDB_SymType::Function); + if (func) { + auto prologue = func->findOneChild<PDBSymbolFuncDebugStart>(); + is_prologue = (addr == prologue->getVirtualAddress()); + + auto epilogue = func->findOneChild<PDBSymbolFuncDebugEnd>(); + is_epilogue = (addr == epilogue->getVirtualAddress()); } - if (entry_count > 0 && ShouldAddLine(match_line, prev_line, prev_length)) - { - // The end is always a terminal entry, so insert it regardless. - line_table->AppendLineEntryToSequence(sequence.get(), prev_addr + prev_length, prev_line, 0, - prev_source_idx, false, false, false, false, true); - } + line_table->AppendLineEntryToSequence(sequence.get(), addr, lno, col, + source_idx, is_statement, false, + is_prologue, is_epilogue, false); + } - line_table->InsertSequence(sequence.release()); + prev_addr = addr; + prev_length = length; + prev_line = lno; + prev_source_idx = source_idx; } - sc.comp_unit->SetLineTable(line_table.release()); - return true; -} - -void -SymbolFilePDB::BuildSupportFileIdToSupportFileIndexMap(const PDBSymbolCompiland &cu, - llvm::DenseMap<uint32_t, uint32_t> &index_map) const -{ - // This is a hack, but we need to convert the source id into an index into the support - // files array. We don't want to do path comparisons to avoid basename / full path - // issues that may or may not even be a problem, so we use the globally unique source - // file identifiers. Ideally we could use the global identifiers everywhere, but LineEntry - // currently assumes indices. - auto source_files = m_session_up->getSourceFilesForCompiland(cu); - int index = 0; - - while (auto file = source_files->getNext()) - { - uint32_t source_id = file->getUniqueId(); - index_map[source_id] = index++; + if (entry_count > 0 && ShouldAddLine(match_line, prev_line, prev_length)) { + // The end is always a terminal entry, so insert it regardless. + line_table->AppendLineEntryToSequence( + sequence.get(), prev_addr + prev_length, prev_line, 0, + prev_source_idx, false, false, false, false, true); } + + line_table->InsertSequence(sequence.release()); + } + + sc.comp_unit->SetLineTable(line_table.release()); + return true; +} + +void SymbolFilePDB::BuildSupportFileIdToSupportFileIndexMap( + const PDBSymbolCompiland &cu, + llvm::DenseMap<uint32_t, uint32_t> &index_map) const { + // This is a hack, but we need to convert the source id into an index into the + // support + // files array. We don't want to do path comparisons to avoid basename / full + // path + // issues that may or may not even be a problem, so we use the globally unique + // source + // file identifiers. Ideally we could use the global identifiers everywhere, + // but LineEntry + // currently assumes indices. + auto source_files = m_session_up->getSourceFilesForCompiland(cu); + int index = 0; + + while (auto file = source_files->getNext()) { + uint32_t source_id = file->getUniqueId(); + index_map[source_id] = index++; + } } diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h index cf75de8ac78e..2e5918328ff0 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -17,188 +17,174 @@ #include "llvm/DebugInfo/PDB/IPDBSession.h" #include "llvm/DebugInfo/PDB/PDB.h" -class SymbolFilePDB : public lldb_private::SymbolFile -{ +class SymbolFilePDB : public lldb_private::SymbolFile { public: - //------------------------------------------------------------------ - // Static Functions - //------------------------------------------------------------------ - static void - Initialize(); + //------------------------------------------------------------------ + // Static Functions + //------------------------------------------------------------------ + static void Initialize(); - static void - Terminate(); + static void Terminate(); - static void - DebuggerInitialize(lldb_private::Debugger &debugger); + static void DebuggerInitialize(lldb_private::Debugger &debugger); - static lldb_private::ConstString - GetPluginNameStatic(); + static lldb_private::ConstString GetPluginNameStatic(); - static const char * - GetPluginDescriptionStatic(); + static const char *GetPluginDescriptionStatic(); - static lldb_private::SymbolFile * - CreateInstance(lldb_private::ObjectFile *obj_file); + static lldb_private::SymbolFile * + CreateInstance(lldb_private::ObjectFile *obj_file); - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - SymbolFilePDB(lldb_private::ObjectFile *ofile); + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + SymbolFilePDB(lldb_private::ObjectFile *ofile); - ~SymbolFilePDB() override; + ~SymbolFilePDB() override; - uint32_t - CalculateAbilities() override; + uint32_t CalculateAbilities() override; - void - InitializeObject() override; + void InitializeObject() override; - //------------------------------------------------------------------ - // Compile Unit function calls - //------------------------------------------------------------------ + //------------------------------------------------------------------ + // Compile Unit function calls + //------------------------------------------------------------------ - uint32_t - GetNumCompileUnits() override; + uint32_t GetNumCompileUnits() override; - lldb::CompUnitSP - ParseCompileUnitAtIndex(uint32_t index) override; + lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override; - lldb::LanguageType - ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) override; + lldb::LanguageType + ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) override; - size_t - ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc) override; + size_t + ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc) override; - bool - ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc) override; + bool + ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc) override; - bool - ParseCompileUnitDebugMacros(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 ParseCompileUnitSupportFiles( + const lldb_private::SymbolContext &sc, + lldb_private::FileSpecList &support_files) override; - bool - ParseImportedModules(const lldb_private::SymbolContext &sc, - std::vector<lldb_private::ConstString> &imported_modules) 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 ParseFunctionBlocks(const lldb_private::SymbolContext &sc) override; - size_t - ParseTypes(const lldb_private::SymbolContext &sc) override; + size_t ParseTypes(const lldb_private::SymbolContext &sc) override; - size_t - ParseVariablesForContext(const lldb_private::SymbolContext &sc) override; + size_t + ParseVariablesForContext(const lldb_private::SymbolContext &sc) override; - lldb_private::Type * - ResolveTypeUID(lldb::user_id_t type_uid) override; + lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override; - bool - CompleteType(lldb_private::CompilerType &compiler_type) override; + bool CompleteType(lldb_private::CompilerType &compiler_type) override; - lldb_private::CompilerDecl - GetDeclForUID(lldb::user_id_t uid) override; + lldb_private::CompilerDecl GetDeclForUID(lldb::user_id_t uid) override; - lldb_private::CompilerDeclContext - GetDeclContextForUID(lldb::user_id_t uid) override; + lldb_private::CompilerDeclContext + GetDeclContextForUID(lldb::user_id_t uid) override; - lldb_private::CompilerDeclContext - GetDeclContextContainingUID(lldb::user_id_t uid) override; + lldb_private::CompilerDeclContext + GetDeclContextContainingUID(lldb::user_id_t uid) override; - void - ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override; + void + ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override; - uint32_t - ResolveSymbolContext(const lldb_private::Address &so_addr, uint32_t resolve_scope, - lldb_private::SymbolContext &sc) override; + uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr, + uint32_t 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, lldb_private::SymbolContextList &sc_list) override; + uint32_t + ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line, + bool check_inlines, uint32_t resolve_scope, + lldb_private::SymbolContextList &sc_list) override; - uint32_t - FindGlobalVariables(const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, - bool append, uint32_t max_matches, lldb_private::VariableList &variables) override; + uint32_t + FindGlobalVariables(const lldb_private::ConstString &name, + const lldb_private::CompilerDeclContext *parent_decl_ctx, + bool append, uint32_t max_matches, + lldb_private::VariableList &variables) override; - uint32_t - FindGlobalVariables(const lldb_private::RegularExpression ®ex, bool append, uint32_t max_matches, - lldb_private::VariableList &variables) override; + uint32_t FindGlobalVariables(const lldb_private::RegularExpression ®ex, + bool append, uint32_t max_matches, + lldb_private::VariableList &variables) override; - 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; + 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; - uint32_t - FindFunctions(const lldb_private::RegularExpression ®ex, 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; - void - GetMangledNamesForFunction(const std::string &scope_qualified_name, - std::vector<lldb_private::ConstString> &mangled_names) override; + void GetMangledNamesForFunction( + const std::string &scope_qualified_name, + std::vector<lldb_private::ConstString> &mangled_names) override; - uint32_t - FindTypes(const lldb_private::SymbolContext &sc, 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; + uint32_t + FindTypes(const lldb_private::SymbolContext &sc, + 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; - size_t - FindTypes(const std::vector<lldb_private::CompilerContext> &context, bool append, - lldb_private::TypeMap &types) override; + size_t FindTypes(const std::vector<lldb_private::CompilerContext> &context, + bool append, lldb_private::TypeMap &types) override; - lldb_private::TypeList * - GetTypeList() override; + lldb_private::TypeList *GetTypeList() override; - size_t - GetTypes(lldb_private::SymbolContextScope *sc_scope, uint32_t type_mask, - lldb_private::TypeList &type_list) override; + size_t GetTypes(lldb_private::SymbolContextScope *sc_scope, + uint32_t type_mask, + lldb_private::TypeList &type_list) override; - lldb_private::TypeSystem * - GetTypeSystemForLanguage(lldb::LanguageType language) 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; + lldb_private::CompilerDeclContext FindNamespace( + const lldb_private::SymbolContext &sc, + const lldb_private::ConstString &name, + const lldb_private::CompilerDeclContext *parent_decl_ctx) override; - lldb_private::ConstString - GetPluginName() override; + lldb_private::ConstString GetPluginName() override; - uint32_t - GetPluginVersion() override; + uint32_t GetPluginVersion() override; - llvm::pdb::IPDBSession & - GetPDBSession(); + llvm::pdb::IPDBSession &GetPDBSession(); - const llvm::pdb::IPDBSession & - GetPDBSession() const; + const llvm::pdb::IPDBSession &GetPDBSession() const; private: - lldb::CompUnitSP - ParseCompileUnitForSymIndex(uint32_t id); + lldb::CompUnitSP ParseCompileUnitForSymIndex(uint32_t id); - bool - ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc, uint32_t match_line); + bool ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc, + uint32_t match_line); - void - BuildSupportFileIdToSupportFileIndexMap(const llvm::pdb::PDBSymbolCompiland &cu, - llvm::DenseMap<uint32_t, uint32_t> &index_map) const; + void BuildSupportFileIdToSupportFileIndexMap( + const llvm::pdb::PDBSymbolCompiland &cu, + llvm::DenseMap<uint32_t, uint32_t> &index_map) const; - void - FindTypesByRegex(const std::string ®ex, uint32_t max_matches, lldb_private::TypeMap &types); + void FindTypesByRegex(const std::string ®ex, uint32_t max_matches, + lldb_private::TypeMap &types); - void - FindTypesByName(const std::string &name, uint32_t max_matches, lldb_private::TypeMap &types); + void FindTypesByName(const std::string &name, uint32_t max_matches, + lldb_private::TypeMap &types); - llvm::DenseMap<uint32_t, lldb::CompUnitSP> m_comp_units; - llvm::DenseMap<uint32_t, lldb::TypeSP> m_types; + llvm::DenseMap<uint32_t, lldb::CompUnitSP> m_comp_units; + llvm::DenseMap<uint32_t, lldb::TypeSP> m_types; - std::vector<lldb::TypeSP> m_builtin_types; - std::unique_ptr<llvm::pdb::IPDBSession> m_session_up; - uint32_t m_cached_compile_unit_count; - std::unique_ptr<lldb_private::CompilerDeclContext> m_tu_decl_ctx_up; + std::vector<lldb::TypeSP> m_builtin_types; + std::unique_ptr<llvm::pdb::IPDBSession> m_session_up; + uint32_t m_cached_compile_unit_count; + std::unique_ptr<lldb_private::CompilerDeclContext> m_tu_decl_ctx_up; }; #endif // lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp index 24175079c95f..39073991c32c 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp @@ -24,312 +24,251 @@ using namespace lldb; using namespace lldb_private; -void -SymbolFileSymtab::Initialize() -{ - PluginManager::RegisterPlugin (GetPluginNameStatic(), - GetPluginDescriptionStatic(), - CreateInstance); +void SymbolFileSymtab::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + GetPluginDescriptionStatic(), CreateInstance); } -void -SymbolFileSymtab::Terminate() -{ - PluginManager::UnregisterPlugin (CreateInstance); +void SymbolFileSymtab::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); } - -lldb_private::ConstString -SymbolFileSymtab::GetPluginNameStatic() -{ - static ConstString g_name("symtab"); - return g_name; +lldb_private::ConstString SymbolFileSymtab::GetPluginNameStatic() { + static ConstString g_name("symtab"); + return g_name; } -const char * -SymbolFileSymtab::GetPluginDescriptionStatic() -{ - return "Reads debug symbols from an object file's symbol table."; +const char *SymbolFileSymtab::GetPluginDescriptionStatic() { + return "Reads debug symbols from an object file's symbol table."; } - -SymbolFile* -SymbolFileSymtab::CreateInstance (ObjectFile* obj_file) -{ - return new SymbolFileSymtab(obj_file); +SymbolFile *SymbolFileSymtab::CreateInstance(ObjectFile *obj_file) { + return new SymbolFileSymtab(obj_file); } -size_t -SymbolFileSymtab::GetTypes (SymbolContextScope *sc_scope, uint32_t type_mask, lldb_private::TypeList &type_list) -{ - return 0; +size_t SymbolFileSymtab::GetTypes(SymbolContextScope *sc_scope, + uint32_t type_mask, + lldb_private::TypeList &type_list) { + return 0; } -SymbolFileSymtab::SymbolFileSymtab(ObjectFile* obj_file) : - SymbolFile(obj_file), - m_source_indexes(), - m_func_indexes(), - m_code_indexes(), - m_objc_class_name_to_index () -{ -} +SymbolFileSymtab::SymbolFileSymtab(ObjectFile *obj_file) + : SymbolFile(obj_file), m_source_indexes(), m_func_indexes(), + m_code_indexes(), m_objc_class_name_to_index() {} -SymbolFileSymtab::~SymbolFileSymtab() -{ -} - -uint32_t -SymbolFileSymtab::CalculateAbilities () -{ - uint32_t abilities = 0; - if (m_obj_file) - { - const Symtab *symtab = m_obj_file->GetSymtab(); - if (symtab) - { - //---------------------------------------------------------------------- - // The snippet of code below will get the indexes the module symbol - // table entries that are code, data, or function related (debug info), - // sort them by value (address) and dump the sorted symbols. - //---------------------------------------------------------------------- - if (symtab->AppendSymbolIndexesWithType(eSymbolTypeSourceFile, m_source_indexes)) - { - abilities |= CompileUnits; - } - - if (symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, m_func_indexes)) - { - symtab->SortSymbolIndexesByValue(m_func_indexes, true); - abilities |= Functions; - } +SymbolFileSymtab::~SymbolFileSymtab() {} - if (symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny, m_code_indexes)) - { - symtab->SortSymbolIndexesByValue(m_code_indexes, true); - abilities |= Functions; - } - - if (symtab->AppendSymbolIndexesWithType(eSymbolTypeData, m_data_indexes)) - { - symtab->SortSymbolIndexesByValue(m_data_indexes, true); - abilities |= GlobalVariables; - } - - lldb_private::Symtab::IndexCollection objc_class_indexes; - if (symtab->AppendSymbolIndexesWithType (eSymbolTypeObjCClass, objc_class_indexes)) - { - symtab->AppendSymbolNamesToMap (objc_class_indexes, - true, - true, - m_objc_class_name_to_index); - m_objc_class_name_to_index.Sort(); - } - } +uint32_t SymbolFileSymtab::CalculateAbilities() { + uint32_t abilities = 0; + if (m_obj_file) { + const Symtab *symtab = m_obj_file->GetSymtab(); + if (symtab) { + //---------------------------------------------------------------------- + // The snippet of code below will get the indexes the module symbol + // table entries that are code, data, or function related (debug info), + // sort them by value (address) and dump the sorted symbols. + //---------------------------------------------------------------------- + if (symtab->AppendSymbolIndexesWithType(eSymbolTypeSourceFile, + m_source_indexes)) { + abilities |= CompileUnits; + } + + if (symtab->AppendSymbolIndexesWithType( + eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, + m_func_indexes)) { + symtab->SortSymbolIndexesByValue(m_func_indexes, true); + abilities |= Functions; + } + + if (symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugNo, + Symtab::eVisibilityAny, + m_code_indexes)) { + symtab->SortSymbolIndexesByValue(m_code_indexes, true); + abilities |= Functions; + } + + if (symtab->AppendSymbolIndexesWithType(eSymbolTypeData, + m_data_indexes)) { + symtab->SortSymbolIndexesByValue(m_data_indexes, true); + abilities |= GlobalVariables; + } + + lldb_private::Symtab::IndexCollection objc_class_indexes; + if (symtab->AppendSymbolIndexesWithType(eSymbolTypeObjCClass, + objc_class_indexes)) { + symtab->AppendSymbolNamesToMap(objc_class_indexes, true, true, + m_objc_class_name_to_index); + m_objc_class_name_to_index.Sort(); + } } - return abilities; + } + return abilities; } -uint32_t -SymbolFileSymtab::GetNumCompileUnits() -{ - // If we don't have any source file symbols we will just have one compile unit for - // the entire object file - if (m_source_indexes.empty()) - return 0; - - // If we have any source file symbols we will logically organize the object symbols - // using these. - return m_source_indexes.size(); +uint32_t SymbolFileSymtab::GetNumCompileUnits() { + // If we don't have any source file symbols we will just have one compile unit + // for + // the entire object file + if (m_source_indexes.empty()) + return 0; + + // If we have any source file symbols we will logically organize the object + // symbols + // using these. + return m_source_indexes.size(); } -CompUnitSP -SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx) -{ - CompUnitSP cu_sp; - - // If we don't have any source file symbols we will just have one compile unit for - // the entire object file - if (idx < m_source_indexes.size()) - { - const Symbol *cu_symbol = m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]); - if (cu_symbol) - cu_sp.reset(new CompileUnit(m_obj_file->GetModule(), NULL, cu_symbol->GetName().AsCString(), 0, - eLanguageTypeUnknown, eLazyBoolNo)); - } - return cu_sp; +CompUnitSP SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx) { + CompUnitSP cu_sp; + + // If we don't have any source file symbols we will just have one compile unit + // for + // the entire object file + if (idx < m_source_indexes.size()) { + const Symbol *cu_symbol = + m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]); + if (cu_symbol) + cu_sp.reset(new CompileUnit(m_obj_file->GetModule(), NULL, + cu_symbol->GetName().AsCString(), 0, + eLanguageTypeUnknown, eLazyBoolNo)); + } + return cu_sp; } lldb::LanguageType -SymbolFileSymtab::ParseCompileUnitLanguage (const SymbolContext& sc) -{ - return eLanguageTypeUnknown; +SymbolFileSymtab::ParseCompileUnitLanguage(const SymbolContext &sc) { + return eLanguageTypeUnknown; } +size_t SymbolFileSymtab::ParseCompileUnitFunctions(const SymbolContext &sc) { + size_t num_added = 0; + // We must at least have a valid compile unit + assert(sc.comp_unit != NULL); + const Symtab *symtab = m_obj_file->GetSymtab(); + const Symbol *curr_symbol = NULL; + const Symbol *next_symbol = NULL; + // const char *prefix = m_obj_file->SymbolPrefix(); + // if (prefix == NULL) + // prefix == ""; + // + // const uint32_t prefix_len = strlen(prefix); + + // If we don't have any source file symbols we will just have one compile unit + // for + // the entire object file + if (m_source_indexes.empty()) { + // The only time we will have a user ID of zero is when we don't have + // and source file symbols and we declare one compile unit for the + // entire object file + if (!m_func_indexes.empty()) { + } -size_t -SymbolFileSymtab::ParseCompileUnitFunctions (const SymbolContext &sc) -{ - size_t num_added = 0; - // We must at least have a valid compile unit - assert (sc.comp_unit != NULL); - const Symtab *symtab = m_obj_file->GetSymtab(); - const Symbol *curr_symbol = NULL; - const Symbol *next_symbol = NULL; -// const char *prefix = m_obj_file->SymbolPrefix(); -// if (prefix == NULL) -// prefix == ""; -// -// const uint32_t prefix_len = strlen(prefix); - - // If we don't have any source file symbols we will just have one compile unit for - // the entire object file - if (m_source_indexes.empty()) - { - // The only time we will have a user ID of zero is when we don't have - // and source file symbols and we declare one compile unit for the - // entire object file - if (!m_func_indexes.empty()) - { - - } - - if (!m_code_indexes.empty()) - { -// StreamFile s(stdout); -// symtab->Dump(&s, m_code_indexes); - - uint32_t idx = 0; // Index into the indexes - const uint32_t num_indexes = m_code_indexes.size(); - for (idx = 0; idx < num_indexes; ++idx) - { - uint32_t symbol_idx = m_code_indexes[idx]; - curr_symbol = symtab->SymbolAtIndex(symbol_idx); - if (curr_symbol) - { - // Union of all ranges in the function DIE (if the function is discontiguous) - AddressRange func_range(curr_symbol->GetAddress(), 0); - if (func_range.GetBaseAddress().IsSectionOffset()) - { - uint32_t symbol_size = curr_symbol->GetByteSize(); - if (symbol_size != 0 && !curr_symbol->GetSizeIsSibling()) - func_range.SetByteSize(symbol_size); - else if (idx + 1 < num_indexes) - { - next_symbol = symtab->SymbolAtIndex(m_code_indexes[idx + 1]); - if (next_symbol) - { - func_range.SetByteSize(next_symbol->GetAddressRef().GetOffset() - curr_symbol->GetAddressRef().GetOffset()); - } - } - - FunctionSP func_sp(new Function(sc.comp_unit, - symbol_idx, // UserID is the DIE offset - LLDB_INVALID_UID, // We don't have any type info for this function - curr_symbol->GetMangled(), // Linker/mangled name - NULL, // no return type for a code symbol... - func_range)); // first address range - - if (func_sp.get() != NULL) - { - sc.comp_unit->AddFunction(func_sp); - ++num_added; - } - } - } + if (!m_code_indexes.empty()) { + // StreamFile s(stdout); + // symtab->Dump(&s, m_code_indexes); + + uint32_t idx = 0; // Index into the indexes + const uint32_t num_indexes = m_code_indexes.size(); + for (idx = 0; idx < num_indexes; ++idx) { + uint32_t symbol_idx = m_code_indexes[idx]; + curr_symbol = symtab->SymbolAtIndex(symbol_idx); + if (curr_symbol) { + // Union of all ranges in the function DIE (if the function is + // discontiguous) + AddressRange func_range(curr_symbol->GetAddress(), 0); + if (func_range.GetBaseAddress().IsSectionOffset()) { + uint32_t symbol_size = curr_symbol->GetByteSize(); + if (symbol_size != 0 && !curr_symbol->GetSizeIsSibling()) + func_range.SetByteSize(symbol_size); + else if (idx + 1 < num_indexes) { + next_symbol = symtab->SymbolAtIndex(m_code_indexes[idx + 1]); + if (next_symbol) { + func_range.SetByteSize( + next_symbol->GetAddressRef().GetOffset() - + curr_symbol->GetAddressRef().GetOffset()); + } } + FunctionSP func_sp( + new Function(sc.comp_unit, + symbol_idx, // UserID is the DIE offset + LLDB_INVALID_UID, // We don't have any type info + // for this function + curr_symbol->GetMangled(), // Linker/mangled name + NULL, // no return type for a code symbol... + func_range)); // first address range + + if (func_sp.get() != NULL) { + sc.comp_unit->AddFunction(func_sp); + ++num_added; + } + } } + } } - else - { - // We assume we - } - return num_added; + } else { + // We assume we + } + return num_added; } -bool -SymbolFileSymtab::ParseCompileUnitLineTable (const SymbolContext &sc) -{ - return false; +bool SymbolFileSymtab::ParseCompileUnitLineTable(const SymbolContext &sc) { + return false; } -bool -SymbolFileSymtab::ParseCompileUnitDebugMacros (const SymbolContext &sc) -{ - return false; +bool SymbolFileSymtab::ParseCompileUnitDebugMacros(const SymbolContext &sc) { + return false; } -bool -SymbolFileSymtab::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files) -{ - return false; +bool SymbolFileSymtab::ParseCompileUnitSupportFiles( + const SymbolContext &sc, FileSpecList &support_files) { + return false; } -bool -SymbolFileSymtab::ParseImportedModules (const SymbolContext &sc, std::vector<ConstString> &imported_modules) -{ - return false; +bool SymbolFileSymtab::ParseImportedModules( + const SymbolContext &sc, std::vector<ConstString> &imported_modules) { + return false; } -size_t -SymbolFileSymtab::ParseFunctionBlocks (const SymbolContext &sc) -{ - return 0; +size_t SymbolFileSymtab::ParseFunctionBlocks(const SymbolContext &sc) { + return 0; } +size_t SymbolFileSymtab::ParseTypes(const SymbolContext &sc) { return 0; } -size_t -SymbolFileSymtab::ParseTypes (const SymbolContext &sc) -{ - return 0; +size_t SymbolFileSymtab::ParseVariablesForContext(const SymbolContext &sc) { + return 0; } - -size_t -SymbolFileSymtab::ParseVariablesForContext (const SymbolContext& sc) -{ - return 0; +Type *SymbolFileSymtab::ResolveTypeUID(lldb::user_id_t type_uid) { + return NULL; } -Type* -SymbolFileSymtab::ResolveTypeUID(lldb::user_id_t type_uid) -{ - return NULL; +bool SymbolFileSymtab::CompleteType(lldb_private::CompilerType &compiler_type) { + return false; } -bool -SymbolFileSymtab::CompleteType (lldb_private::CompilerType& compiler_type) -{ - return false; -} +uint32_t SymbolFileSymtab::ResolveSymbolContext(const Address &so_addr, + uint32_t resolve_scope, + SymbolContext &sc) { + if (m_obj_file->GetSymtab() == NULL) + return 0; -uint32_t -SymbolFileSymtab::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) -{ - if (m_obj_file->GetSymtab() == NULL) - return 0; - - uint32_t resolved_flags = 0; - if (resolve_scope & eSymbolContextSymbol) - { - sc.symbol = m_obj_file->GetSymtab()->FindSymbolContainingFileAddress(so_addr.GetFileAddress()); - if (sc.symbol) - resolved_flags |= eSymbolContextSymbol; - } - return resolved_flags; + uint32_t resolved_flags = 0; + if (resolve_scope & eSymbolContextSymbol) { + sc.symbol = m_obj_file->GetSymtab()->FindSymbolContainingFileAddress( + so_addr.GetFileAddress()); + if (sc.symbol) + resolved_flags |= eSymbolContextSymbol; + } + return resolved_flags; } //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ -lldb_private::ConstString -SymbolFileSymtab::GetPluginName() -{ - return GetPluginNameStatic(); +lldb_private::ConstString SymbolFileSymtab::GetPluginName() { + return GetPluginNameStatic(); } -uint32_t -SymbolFileSymtab::GetPluginVersion() -{ - return 1; -} +uint32_t SymbolFileSymtab::GetPluginVersion() { return 1; } diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h index 4648da49cb9f..1945af9a337e 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h @@ -19,112 +19,96 @@ #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/Symtab.h" -class SymbolFileSymtab : public lldb_private::SymbolFile -{ +class SymbolFileSymtab : public lldb_private::SymbolFile { public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - SymbolFileSymtab(lldb_private::ObjectFile* obj_file); + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + SymbolFileSymtab(lldb_private::ObjectFile *obj_file); - ~SymbolFileSymtab() override; + ~SymbolFileSymtab() override; - //------------------------------------------------------------------ - // Static Functions - //------------------------------------------------------------------ - static void - Initialize(); + //------------------------------------------------------------------ + // Static Functions + //------------------------------------------------------------------ + static void Initialize(); - static void - Terminate(); + static void Terminate(); - static lldb_private::ConstString - GetPluginNameStatic(); + static lldb_private::ConstString GetPluginNameStatic(); - static const char * - GetPluginDescriptionStatic(); + static const char *GetPluginDescriptionStatic(); - static lldb_private::SymbolFile* - CreateInstance (lldb_private::ObjectFile* obj_file); + static lldb_private::SymbolFile * + CreateInstance(lldb_private::ObjectFile *obj_file); - uint32_t - CalculateAbilities() override; + uint32_t CalculateAbilities() override; - //------------------------------------------------------------------ - // Compile Unit function calls - //------------------------------------------------------------------ - uint32_t - GetNumCompileUnits() override; + //------------------------------------------------------------------ + // Compile Unit function calls + //------------------------------------------------------------------ + uint32_t GetNumCompileUnits() override; - lldb::CompUnitSP - ParseCompileUnitAtIndex(uint32_t index) override; + lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override; - lldb::LanguageType - ParseCompileUnitLanguage(const lldb_private::SymbolContext& sc) override; + lldb::LanguageType + ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) override; - size_t - ParseCompileUnitFunctions(const lldb_private::SymbolContext& sc) override; + size_t + ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc) override; - bool - ParseCompileUnitLineTable(const lldb_private::SymbolContext& sc) override; + bool + ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc) override; - bool - ParseCompileUnitDebugMacros(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 - ParseImportedModules(const lldb_private::SymbolContext &sc, - std::vector<lldb_private::ConstString> &imported_modules) override; + bool ParseCompileUnitSupportFiles( + const lldb_private::SymbolContext &sc, + lldb_private::FileSpecList &support_files) override; - size_t - ParseFunctionBlocks(const lldb_private::SymbolContext& sc) override; + bool ParseImportedModules( + const lldb_private::SymbolContext &sc, + std::vector<lldb_private::ConstString> &imported_modules) override; - size_t - ParseTypes(const lldb_private::SymbolContext& sc) override; + size_t ParseFunctionBlocks(const lldb_private::SymbolContext &sc) override; - size_t - ParseVariablesForContext(const lldb_private::SymbolContext& sc) override; + size_t ParseTypes(const lldb_private::SymbolContext &sc) override; - lldb_private::Type* - ResolveTypeUID(lldb::user_id_t type_uid) override; + size_t + ParseVariablesForContext(const lldb_private::SymbolContext &sc) override; - bool - CompleteType(lldb_private::CompilerType& compiler_type) override; + lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override; - uint32_t - ResolveSymbolContext(const lldb_private::Address& so_addr, - uint32_t resolve_scope, - lldb_private::SymbolContext& sc) override; + bool CompleteType(lldb_private::CompilerType &compiler_type) override; - size_t - GetTypes(lldb_private::SymbolContextScope *sc_scope, - uint32_t type_mask, - lldb_private::TypeList &type_list) override; + uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr, + uint32_t resolve_scope, + lldb_private::SymbolContext &sc) override; - //------------------------------------------------------------------ - // PluginInterface protocol - //------------------------------------------------------------------ - lldb_private::ConstString - GetPluginName() override; + size_t GetTypes(lldb_private::SymbolContextScope *sc_scope, + uint32_t type_mask, + lldb_private::TypeList &type_list) override; - uint32_t - GetPluginVersion() override; + //------------------------------------------------------------------ + // PluginInterface protocol + //------------------------------------------------------------------ + lldb_private::ConstString GetPluginName() override; + + uint32_t GetPluginVersion() override; protected: - typedef std::map<lldb_private::ConstString, lldb::TypeSP> TypeMap; - - lldb_private::Symtab::IndexCollection m_source_indexes; - lldb_private::Symtab::IndexCollection m_func_indexes; - lldb_private::Symtab::IndexCollection m_code_indexes; - lldb_private::Symtab::IndexCollection m_data_indexes; - lldb_private::Symtab::NameToIndexMap m_objc_class_name_to_index; - TypeMap m_objc_class_types; - + typedef std::map<lldb_private::ConstString, lldb::TypeSP> TypeMap; + + lldb_private::Symtab::IndexCollection m_source_indexes; + lldb_private::Symtab::IndexCollection m_func_indexes; + lldb_private::Symtab::IndexCollection m_code_indexes; + lldb_private::Symtab::IndexCollection m_data_indexes; + lldb_private::Symtab::NameToIndexMap m_objc_class_name_to_index; + TypeMap m_objc_class_types; + private: - DISALLOW_COPY_AND_ASSIGN (SymbolFileSymtab); + DISALLOW_COPY_AND_ASSIGN(SymbolFileSymtab); }; #endif // liblldb_SymbolFileSymtab_h_ |