diff options
Diffstat (limited to 'source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp')
-rw-r--r-- | source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 150 |
1 files changed, 83 insertions, 67 deletions
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index f265af837eef..09b50531b8a9 100644 --- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -70,7 +70,7 @@ #ifdef ENABLE_DEBUG_PRINTF #include <stdio.h> -#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__) +#define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__) #else #define DEBUG_PRINTF(fmt, ...) #endif @@ -699,8 +699,8 @@ SymbolFileDWARF::CalculateAbilities () return abilities; } -const DataExtractor& -SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DataExtractor &data) +const DWARFDataExtractor& +SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DWARFDataExtractor &data) { if (m_flags.IsClear (got_flag)) { @@ -728,73 +728,73 @@ SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, return data; } -const DataExtractor& +const DWARFDataExtractor& SymbolFileDWARF::get_debug_abbrev_data() { return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev); } -const DataExtractor& +const DWARFDataExtractor& SymbolFileDWARF::get_debug_aranges_data() { return GetCachedSectionData (flagsGotDebugArangesData, eSectionTypeDWARFDebugAranges, m_data_debug_aranges); } -const DataExtractor& +const DWARFDataExtractor& SymbolFileDWARF::get_debug_frame_data() { return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame); } -const DataExtractor& +const DWARFDataExtractor& SymbolFileDWARF::get_debug_info_data() { return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info); } -const DataExtractor& +const DWARFDataExtractor& SymbolFileDWARF::get_debug_line_data() { return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line); } -const DataExtractor& +const DWARFDataExtractor& SymbolFileDWARF::get_debug_loc_data() { return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc); } -const DataExtractor& +const DWARFDataExtractor& SymbolFileDWARF::get_debug_ranges_data() { return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges); } -const DataExtractor& +const DWARFDataExtractor& SymbolFileDWARF::get_debug_str_data() { return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str); } -const DataExtractor& +const DWARFDataExtractor& SymbolFileDWARF::get_apple_names_data() { return GetCachedSectionData (flagsGotAppleNamesData, eSectionTypeDWARFAppleNames, m_data_apple_names); } -const DataExtractor& +const DWARFDataExtractor& SymbolFileDWARF::get_apple_types_data() { return GetCachedSectionData (flagsGotAppleTypesData, eSectionTypeDWARFAppleTypes, m_data_apple_types); } -const DataExtractor& +const DWARFDataExtractor& SymbolFileDWARF::get_apple_namespaces_data() { return GetCachedSectionData (flagsGotAppleNamespacesData, eSectionTypeDWARFAppleNamespaces, m_data_apple_namespaces); } -const DataExtractor& +const DWARFDataExtractor& SymbolFileDWARF::get_apple_objc_data() { return GetCachedSectionData (flagsGotAppleObjCData, eSectionTypeDWARFAppleObjC, m_data_apple_objc); @@ -806,7 +806,7 @@ SymbolFileDWARF::DebugAbbrev() { if (m_abbr.get() == NULL) { - const DataExtractor &debug_abbrev_data = get_debug_abbrev_data(); + const DWARFDataExtractor &debug_abbrev_data = get_debug_abbrev_data(); if (debug_abbrev_data.GetByteSize() > 0) { m_abbr.reset(new DWARFDebugAbbrev()); @@ -1706,6 +1706,7 @@ SymbolFileDWARF::ParseChildMembers const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize()); uint32_t member_idx = 0; BitfieldInfo last_field_info; + ModuleSP module = GetObjectFile()->GetModule(); for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling()) { @@ -1762,13 +1763,14 @@ SymbolFileDWARF::ParseChildMembers { Value initialValue(0); Value memberOffset(0); - const DataExtractor& debug_info_data = get_debug_info_data(); + const DWARFDataExtractor& debug_info_data = 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, debug_info_data, block_offset, block_length, @@ -2153,13 +2155,14 @@ SymbolFileDWARF::ParseChildMembers { Value initialValue(0); Value memberOffset(0); - const DataExtractor& debug_info_data = get_debug_info_data(); + const DWARFDataExtractor& debug_info_data = 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, NULL, NULL, NULL, + module, debug_info_data, block_offset, block_length, @@ -2214,12 +2217,17 @@ SymbolFileDWARF::ParseChildMembers if (is_virtual) { - layout_info.vbase_offsets.insert(std::make_pair(class_clang_type.GetAsCXXRecordDecl(), - clang::CharUnits::fromQuantity(member_byte_offset))); + // 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(class_clang_type.GetAsCXXRecordDecl(), + layout_info.base_offsets.insert(std::make_pair(base_class_clang_type.GetAsCXXRecordDecl(), clang::CharUnits::fromQuantity(member_byte_offset))); } } @@ -2460,22 +2468,21 @@ SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (ClangASTType &clang_type) if (class_language == eLanguageTypeObjC) { - std::string class_str (clang_type.GetTypeName()); - if (!class_str.empty()) + ConstString class_name (clang_type.GetTypeName()); + if (class_name) { DIEArray method_die_offsets; if (m_using_apple_tables) { if (m_apple_objc_ap.get()) - m_apple_objc_ap->FindByName(class_str.c_str(), method_die_offsets); + m_apple_objc_ap->FindByName(class_name.GetCString(), method_die_offsets); } else { if (!m_indexed) Index (); - ConstString class_name (class_str.c_str()); m_objc_class_selectors_index.Find (class_name, method_die_offsets); } @@ -2497,7 +2504,7 @@ SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (ClangASTType &clang_type) if (m_using_apple_tables) { GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_objc accelerator table had bad die 0x%8.8x for '%s')\n", - die_offset, class_str.c_str()); + die_offset, class_name.GetCString()); } } } @@ -2621,7 +2628,7 @@ SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (ClangASTType &clang_type) } } - return clang_type; + return (bool)clang_type; case DW_TAG_enumeration_type: clang_type.StartTagDeclarationDefinition (); @@ -2633,7 +2640,7 @@ SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (ClangASTType &clang_type) ParseChildEnumerators(sc, clang_type, is_signed, type->GetByteSize(), dwarf_cu, die); } clang_type.CompleteTagDeclarationDefinition (); - return clang_type; + return (bool)clang_type; default: assert(false && "not a forward clang type decl!"); @@ -2845,7 +2852,7 @@ SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, 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 = file_spec.GetDirectory(); + 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) { @@ -3096,7 +3103,7 @@ SymbolFileDWARF::FindGlobalVariables (const ConstString &name, const lldb_privat } if (!NamespaceDeclMatchesThisSymbolFile(namespace_decl)) - return 0; + return 0; DWARFDebugInfo* info = DebugInfo(); if (info == NULL) @@ -3553,7 +3560,7 @@ SymbolFileDWARF::FindFunctions (const ConstString &name, sc_list.Clear(); if (!NamespaceDeclMatchesThisSymbolFile(namespace_decl)) - return 0; + return 0; // If name is empty then we won't find anything. if (name.IsEmpty()) @@ -3691,22 +3698,30 @@ SymbolFileDWARF::FindFunctions (const ConstString &name, { Type *type = sc.function->GetType(); - clang::DeclContext* decl_ctx = GetClangDeclContextContainingTypeUID (type->GetID()); - if (decl_ctx->isRecord()) + if (type) { - if (name_type_mask & eFunctionNameTypeBase) + clang::DeclContext* decl_ctx = GetClangDeclContextContainingTypeUID (type->GetID()); + if (decl_ctx->isRecord()) { - sc_list.RemoveContextAtIndex(sc_list.GetSize()-1); - keep_die = false; + 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 { - if (name_type_mask & eFunctionNameTypeMethod) - { - sc_list.RemoveContextAtIndex(sc_list.GetSize()-1); - keep_die = false; - } + GetObjectFile()->GetModule()->ReportWarning ("function at die offset 0x%8.8x had no function type", + die_offset); } } } @@ -3736,8 +3751,9 @@ SymbolFileDWARF::FindFunctions (const ConstString &name, { FindFunctions (name, m_function_fullname_index, sc_list); - // Temporary workaround for global/anonymous namespace functions on linux -#if defined (__linux__) + // FIXME Temporary workaround for global/anonymous namespace + // functions on FreeBSD and Linux +#if defined (__FreeBSD__) || defined (__linux__) // 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 (ie. mangled names starting with @@ -3930,7 +3946,7 @@ SymbolFileDWARF::FindTypes (const SymbolContext& sc, types.Clear(); if (!NamespaceDeclMatchesThisSymbolFile(namespace_decl)) - return 0; + return 0; DIEArray die_offsets; @@ -4032,7 +4048,7 @@ SymbolFileDWARF::FindNamespace (const SymbolContext& sc, } if (!NamespaceDeclMatchesThisSymbolFile(parent_namespace_decl)) - return ClangNamespaceDecl(); + return ClangNamespaceDecl(); ClangNamespaceDecl namespace_decl; DWARFDebugInfo* info = DebugInfo(); @@ -4191,9 +4207,9 @@ SymbolFileDWARF::ParseChildParameters (const SymbolContext& sc, case DW_AT_location: // if (form_value.BlockData()) // { - // const DataExtractor& debug_info_data = debug_info(); + // const DWARFDataExtractor& debug_info_data = debug_info(); // uint32_t block_length = form_value.Unsigned(); - // DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length); + // DWARFDataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length); // } // else // { @@ -4831,17 +4847,16 @@ SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE (const DWARFDebugInfoEntry if (try_resolving_type) { - if (must_be_implementation && type_cu->Supports_DW_AT_APPLE_objc_complete_type()) - try_resolving_type = type_die->GetAttributeValueAsUnsigned (this, type_cu, DW_AT_APPLE_objc_complete_type, 0); + if (must_be_implementation && type_cu->Supports_DW_AT_APPLE_objc_complete_type()) + try_resolving_type = type_die->GetAttributeValueAsUnsigned (this, type_cu, DW_AT_APPLE_objc_complete_type, 0); if (try_resolving_type) { Type *resolved_type = ResolveType (type_cu, type_die, false); if (resolved_type && resolved_type != DIE_IS_BEING_PARSED) { - DEBUG_PRINTF ("resolved 0x%8.8" PRIx64 " (cu 0x%8.8" PRIx64 ") from %s to 0x%8.8" PRIx64 " (cu 0x%8.8" PRIx64 ")\n", + DEBUG_PRINTF ("resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64 " (cu 0x%8.8" PRIx64 ")\n", MakeUserID(die->GetOffset()), - MakeUserID(dwarf_cu->GetOffset()), m_obj_file->GetFileSpec().GetFilename().AsCString(), MakeUserID(type_die->GetOffset()), MakeUserID(type_cu->GetOffset())); @@ -5117,7 +5132,7 @@ SymbolFileDWARF::FindDefinitionTypeForDIE (DWARFCompileUnit* cu, { DEBUG_PRINTF ("resolved 0x%8.8" PRIx64 " (cu 0x%8.8" PRIx64 ") from %s to 0x%8.8" PRIx64 " (cu 0x%8.8" PRIx64 ")\n", MakeUserID(die->GetOffset()), - MakeUserID(dwarf_cu->GetOffset()), + MakeUserID(cu->GetOffset()), m_obj_file->GetFileSpec().GetFilename().AsCString(), MakeUserID(type_die->GetOffset()), MakeUserID(type_cu->GetOffset())); @@ -5732,7 +5747,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, } } - DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8x\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid); + DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8lx\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid); switch (tag) { @@ -5892,12 +5907,12 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, { case DW_AT_decl_file: if (dwarf_cu->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. + { + // 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; @@ -7255,6 +7270,7 @@ SymbolFileDWARF::ParseVariableDIE 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) || @@ -7298,13 +7314,13 @@ SymbolFileDWARF::ParseVariableDIE { location_is_const_value_data = true; // The constant value will be either a block, a data value or a string. - const DataExtractor& debug_info_data = get_debug_info_data(); + 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(debug_info_data, block_offset, block_length); + location.CopyOpcodeData(module, debug_info_data, block_offset, block_length); } else if (DWARFFormValue::IsDataForm(form_value.Form())) { @@ -7312,7 +7328,7 @@ SymbolFileDWARF::ParseVariableDIE const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize()); uint32_t data_offset = attributes.DIEOffsetAtIndex(i); uint32_t data_length = fixed_form_sizes[form_value.Form()]; - location.CopyOpcodeData(debug_info_data, data_offset, data_length); + location.CopyOpcodeData(module, debug_info_data, data_offset, data_length); } else { @@ -7322,14 +7338,14 @@ SymbolFileDWARF::ParseVariableDIE const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize()); uint32_t data_offset = attributes.DIEOffsetAtIndex(i); uint32_t data_length = fixed_form_sizes[form_value.Form()]; - location.CopyOpcodeData(debug_info_data, data_offset, data_length); + location.CopyOpcodeData(module, debug_info_data, data_offset, data_length); } else { const char *str = form_value.AsCString(&debug_info_data); uint32_t string_offset = str - (const char *)debug_info_data.GetDataStart(); uint32_t string_length = strlen(str) + 1; - location.CopyOpcodeData(debug_info_data, string_offset, string_length); + location.CopyOpcodeData(module, debug_info_data, string_offset, string_length); } } } @@ -7340,21 +7356,21 @@ SymbolFileDWARF::ParseVariableDIE has_explicit_location = true; if (form_value.BlockData()) { - const DataExtractor& debug_info_data = get_debug_info_data(); + 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(get_debug_info_data(), block_offset, block_length); + location.CopyOpcodeData(module, get_debug_info_data(), block_offset, block_length); } else { - const DataExtractor& debug_loc_data = get_debug_loc_data(); + const DWARFDataExtractor& debug_loc_data = get_debug_loc_data(); const dw_offset_t debug_loc_offset = form_value.Unsigned(); size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset); if (loc_list_length > 0) { - location.CopyOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length); + location.CopyOpcodeData(module, debug_loc_data, debug_loc_offset, loc_list_length); assert (func_low_pc != LLDB_INVALID_ADDRESS); location.SetLocationListSlide (func_low_pc - dwarf_cu->GetBaseAddress()); } |