aboutsummaryrefslogtreecommitdiff
path: root/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp')
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp7823
1 files changed, 3642 insertions, 4181 deletions
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 942a5d62d9b4..5c44ee03b02c 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/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 = &section->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 = &section->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(&sect_offset));
+ sc.comp_unit->SetDebugMacros(ParseDebugMacros(&sect_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 &regex,
+ 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 &regex,
- 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 &regex,
+ 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 &regex,
- 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 &regex,
+ 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 &regex,
+ 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;
}