diff options
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp')
-rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp | 770 |
1 files changed, 770 insertions, 0 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp new file mode 100644 index 00000000000..e7f92c6eff2 --- /dev/null +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -0,0 +1,770 @@ +//===-- DWARFCompileUnit.cpp ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "DWARFCompileUnit.h" + +#include "lldb/Core/Stream.h" +#include "lldb/Core/Timer.h" + +#include "DWARFDebugAbbrev.h" +#include "DWARFDebugAranges.h" +#include "DWARFDIECollection.h" +#include "DWARFFormValue.h" +#include "LogChannelDWARF.h" +#include "SymbolFileDWARF.h" + +using namespace lldb_private; +using namespace std; + +extern int g_verbose; + +DWARFCompileUnit::DWARFCompileUnit(SymbolFileDWARF* m_dwarf2Data) : + m_dwarf2Data ( m_dwarf2Data ), + m_offset ( DW_INVALID_OFFSET ), + m_length ( 0 ), + m_version ( 0 ), + m_abbrevs ( NULL ), + m_addr_size ( DWARFCompileUnit::GetDefaultAddressSize() ), + m_base_addr ( 0 ), + m_die_array (), + m_aranges_ap (), + m_user_data ( NULL ) +{ +} + +void +DWARFCompileUnit::Clear() +{ + m_offset = DW_INVALID_OFFSET; + m_length = 0; + m_version = 0; + m_abbrevs = NULL; + m_addr_size = DWARFCompileUnit::GetDefaultAddressSize(); + m_base_addr = 0; + m_die_array.clear(); + m_aranges_ap.reset(); + m_user_data = NULL; +} + +bool +DWARFCompileUnit::Extract(const DataExtractor &debug_info, uint32_t* offset_ptr) +{ + Clear(); + + m_offset = *offset_ptr; + + if (debug_info.ValidOffset(*offset_ptr)) + { + dw_offset_t abbr_offset; + const DWARFDebugAbbrev *abbr = m_dwarf2Data->DebugAbbrev(); + m_length = debug_info.GetU32(offset_ptr); + m_version = debug_info.GetU16(offset_ptr); + abbr_offset = debug_info.GetU32(offset_ptr); + m_addr_size = debug_info.GetU8 (offset_ptr); + + bool length_OK = debug_info.ValidOffset(GetNextCompileUnitOffset()-1); + bool version_OK = SymbolFileDWARF::SupportedVersion(m_version); + bool abbr_offset_OK = m_dwarf2Data->get_debug_abbrev_data().ValidOffset(abbr_offset); + bool addr_size_OK = ((m_addr_size == 4) || (m_addr_size == 8)); + + if (length_OK && version_OK && addr_size_OK && abbr_offset_OK && abbr != NULL) + { + m_abbrevs = abbr->GetAbbreviationDeclarationSet(abbr_offset); + return true; + } + + // reset the offset to where we tried to parse from if anything went wrong + *offset_ptr = m_offset; + } + + return false; +} + + +dw_offset_t +DWARFCompileUnit::Extract(dw_offset_t offset, const DataExtractor& debug_info_data, const DWARFAbbreviationDeclarationSet* abbrevs) +{ + Clear(); + + m_offset = offset; + + if (debug_info_data.ValidOffset(offset)) + { + m_length = debug_info_data.GetU32(&offset); + m_version = debug_info_data.GetU16(&offset); + bool abbrevs_OK = debug_info_data.GetU32(&offset) == abbrevs->GetOffset(); + m_abbrevs = abbrevs; + m_addr_size = debug_info_data.GetU8 (&offset); + + bool version_OK = SymbolFileDWARF::SupportedVersion(m_version); + bool addr_size_OK = ((m_addr_size == 4) || (m_addr_size == 8)); + + if (version_OK && addr_size_OK && abbrevs_OK && debug_info_data.ValidOffset(offset)) + return offset; + } + return DW_INVALID_OFFSET; +} + +void +DWARFCompileUnit::ClearDIEs(bool keep_compile_unit_die) +{ + if (m_die_array.size() > 1) + { + // std::vectors never get any smaller when resized to a smaller size, + // or when clear() or erase() are called, the size will report that it + // is smaller, but the memory allocated remains intact (call capacity() + // to see this). So we need to create a temporary vector and swap the + // contents which will cause just the internal pointers to be swapped + // so that when "tmp_array" goes out of scope, it will destroy the + // contents. + + // Save at least the compile unit DIE + DWARFDebugInfoEntry::collection tmp_array; + m_die_array.swap(tmp_array); + if (keep_compile_unit_die) + m_die_array.push_back(tmp_array.front()); + } +} + +//---------------------------------------------------------------------- +// ParseCompileUnitDIEsIfNeeded +// +// Parses a compile unit and indexes its DIEs if it already hasn't been +// done. +//---------------------------------------------------------------------- +size_t +DWARFCompileUnit::ExtractDIEsIfNeeded (bool cu_die_only) +{ + const size_t initial_die_array_size = m_die_array.size(); + if ((cu_die_only && initial_die_array_size > 0) || initial_die_array_size > 1) + return 0; // Already parsed + + Timer scoped_timer (__PRETTY_FUNCTION__, + "%8.8x: DWARFCompileUnit::ExtractDIEsIfNeeded( cu_die_only = %i )", + m_offset, + cu_die_only); + + // Set the offset to that of the first DIE + uint32_t offset = GetFirstDIEOffset(); + const dw_offset_t next_cu_offset = GetNextCompileUnitOffset(); + DWARFDebugInfoEntry die; + // Keep a flat array of the DIE for binary lookup by DIE offset + Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO); +// if (log) +// log->Printf("0x%8.8x: Compile Unit: length = 0x%8.8x, version = 0x%4.4x, abbr_offset = 0x%8.8x, addr_size = 0x%2.2x", +// cu->GetOffset(), +// cu->GetLength(), +// cu->GetVersion(), +// cu->GetAbbrevOffset(), +// cu->GetAddressByteSize()); + + uint32_t depth = 0; + // We are in our compile unit, parse starting at the offset + // we were told to parse + while (die.Extract(m_dwarf2Data, this, &offset)) + { + if (log) + log->Printf("0x%8.8x: %*.*s%s%s", + die.GetOffset(), + depth * 2, depth * 2, "", + DW_TAG_value_to_name (die.Tag()), + die.HasChildren() ? " *" : ""); + if (cu_die_only) + { + AddDIE(die); + return 1; + } + else if (depth == 0 && initial_die_array_size == 1) + { + // Don't append the CU die as we already did that + } + else + { + AddDIE(die); + } + + const DWARFAbbreviationDeclaration* abbrDecl = die.GetAbbreviationDeclarationPtr(); + if (abbrDecl) + { + // Normal DIE + if (abbrDecl->HasChildren()) + ++depth; + } + else + { + // NULL DIE. + if (depth > 0) + --depth; + else + break; // We are done with this compile unit! + } + + assert(offset <= next_cu_offset); + } + SetDIERelations(); + return m_die_array.size(); +} + + +dw_offset_t +DWARFCompileUnit::GetAbbrevOffset() const +{ + return m_abbrevs ? m_abbrevs->GetOffset() : DW_INVALID_OFFSET; +} + + + +bool +DWARFCompileUnit::Verify(Stream *s) const +{ + const DataExtractor& debug_info = m_dwarf2Data->get_debug_info_data(); + bool valid_offset = debug_info.ValidOffset(m_offset); + bool length_OK = debug_info.ValidOffset(GetNextCompileUnitOffset()-1); + bool version_OK = SymbolFileDWARF::SupportedVersion(m_version); + bool abbr_offset_OK = m_dwarf2Data->get_debug_abbrev_data().ValidOffset(GetAbbrevOffset()); + bool addr_size_OK = ((m_addr_size == 4) || (m_addr_size == 8)); + bool verbose = s->GetVerbose(); + if (valid_offset && length_OK && version_OK && addr_size_OK && abbr_offset_OK) + { + if (verbose) + s->Printf(" 0x%8.8x: OK\n", m_offset); + return true; + } + else + { + s->Printf(" 0x%8.8x: ", m_offset); + + m_dwarf2Data->get_debug_info_data().Dump (s, m_offset, lldb::eFormatHex, 1, Size(), 32, LLDB_INVALID_ADDRESS, 0, 0); + s->EOL(); + if (valid_offset) + { + if (!length_OK) + s->Printf(" The length (0x%8.8x) for this compile unit is too large for the .debug_info provided.\n", m_length); + if (!version_OK) + s->Printf(" The 16 bit compile unit header version is not supported.\n"); + if (!abbr_offset_OK) + s->Printf(" The offset into the .debug_abbrev section (0x%8.8x) is not valid.\n", GetAbbrevOffset()); + if (!addr_size_OK) + s->Printf(" The address size is unsupported: 0x%2.2x\n", m_addr_size); + } + else + s->Printf(" The start offset of the compile unit header in the .debug_info is invalid.\n"); + } + return false; +} + + +void +DWARFCompileUnit::Dump(Stream *s) const +{ + s->Printf("0x%8.8x: Compile Unit: length = 0x%8.8x, version = 0x%4.4x, abbr_offset = 0x%8.8x, addr_size = 0x%2.2x (next CU at {0x%8.8x})\n", + m_offset, m_length, m_version, GetAbbrevOffset(), m_addr_size, GetNextCompileUnitOffset()); +} + + +static uint8_t g_default_addr_size = 4; + +uint8_t +DWARFCompileUnit::GetAddressByteSize(const DWARFCompileUnit* cu) +{ + if (cu) + return cu->GetAddressByteSize(); + return DWARFCompileUnit::GetDefaultAddressSize(); +} + +uint8_t +DWARFCompileUnit::GetDefaultAddressSize() +{ + return g_default_addr_size; +} + +void +DWARFCompileUnit::SetDefaultAddressSize(uint8_t addr_size) +{ + g_default_addr_size = addr_size; +} + +bool +DWARFCompileUnit::LookupAddress +( + const dw_addr_t address, + DWARFDebugInfoEntry** function_die_handle, + DWARFDebugInfoEntry** block_die_handle +) +{ + bool success = false; + + if (function_die_handle != NULL && DIE()) + { + if (m_aranges_ap.get() == NULL) + { + m_aranges_ap.reset(new DWARFDebugAranges()); + m_die_array.front().BuildFunctionAddressRangeTable(m_dwarf2Data, this, m_aranges_ap.get()); + } + + // Re-check the aranges auto pointer contents in case it was created above + if (m_aranges_ap.get() != NULL) + { + *function_die_handle = GetDIEPtr(m_aranges_ap->FindAddress(address)); + if (*function_die_handle != NULL) + { + success = true; + if (block_die_handle != NULL) + { + DWARFDebugInfoEntry* child = (*function_die_handle)->GetFirstChild(); + while (child) + { + if (child->LookupAddress(address, m_dwarf2Data, this, NULL, block_die_handle)) + break; + child = child->GetSibling(); + } + } + } + } + } + return success; +} + +//---------------------------------------------------------------------- +// SetDIERelations() +// +// We read in all of the DIE entries into our flat list of DIE entries +// and now we need to go back through all of them and set the parent, +// sibling and child pointers for quick DIE navigation. +//---------------------------------------------------------------------- +void +DWARFCompileUnit::SetDIERelations() +{ +#if 0 + // Compute average bytes per DIE + // + // We can figure out what the average number of bytes per DIE is + // to help us pre-allocate the correct number of m_die_array + // entries so we don't end up doing a lot of memory copies as we + // are creating our DIE array when parsing + // + // Enable this code by changing "#if 0" above to "#if 1" and running + // the dsymutil or dwarfdump with a bunch of dwarf files and see what + // the running average ends up being in the stdout log. + static size_t g_total_cu_debug_info_size = 0; + static size_t g_total_num_dies = 0; + static size_t g_min_bytes_per_die = UINT_MAX; + static size_t g_max_bytes_per_die = 0; + const size_t num_dies = m_die_array.size(); + const size_t cu_debug_info_size = GetDebugInfoSize(); + const size_t bytes_per_die = cu_debug_info_size / num_dies; + if (g_min_bytes_per_die > bytes_per_die) + g_min_bytes_per_die = bytes_per_die; + if (g_max_bytes_per_die < bytes_per_die) + g_max_bytes_per_die = bytes_per_die; + if (g_total_cu_debug_info_size == 0) + { + cout << " min max avg" << endl + << "n dies cu size bpd bpd bpd bpd" << endl + << "------ -------- --- === === ===" << endl; + } + g_total_cu_debug_info_size += cu_debug_info_size; + g_total_num_dies += num_dies; + const size_t avg_bytes_per_die = g_total_cu_debug_info_size / g_total_num_dies; + cout + << DECIMAL_WIDTH(6) << num_dies << ' ' + << DECIMAL_WIDTH(8) << cu_debug_info_size << ' ' + << DECIMAL_WIDTH(3) << bytes_per_die << ' ' + << DECIMAL_WIDTH(3) << g_min_bytes_per_die << ' ' + << DECIMAL_WIDTH(3) << g_max_bytes_per_die << ' ' + << DECIMAL_WIDTH(3) << avg_bytes_per_die + << endl; +#endif + if (m_die_array.empty()) + return; + DWARFDebugInfoEntry* die_array_begin = &m_die_array.front(); + DWARFDebugInfoEntry* die_array_end = &m_die_array.back(); + DWARFDebugInfoEntry* curr_die; + // We purposely are skipping the last element in the array in the loop below + // so that we can always have a valid next item + for (curr_die = die_array_begin; curr_die < die_array_end; ++curr_die) + { + // Since our loop doesn't include the last element, we can always + // safely access the next die in the array. + DWARFDebugInfoEntry* next_die = curr_die + 1; + + const DWARFAbbreviationDeclaration* curr_die_abbrev = curr_die->GetAbbreviationDeclarationPtr(); + + if (curr_die_abbrev) + { + // Normal DIE + if (curr_die_abbrev->HasChildren()) + next_die->SetParent(curr_die); + else + curr_die->SetSibling(next_die); + } + else + { + // NULL DIE that terminates a sibling chain + DWARFDebugInfoEntry* parent = curr_die->GetParent(); + if (parent) + parent->SetSibling(next_die); + } + } + + // Since we skipped the last element, we need to fix it up! + if (die_array_begin < die_array_end) + curr_die->SetParent(die_array_begin); + +#if 0 + // The code below will dump the DIE relations in case any modification + // is done to the above code. This dump can be used in a diff to make + // sure that no functionality is lost. + { + DWARFDebugInfoEntry::const_iterator pos; + DWARFDebugInfoEntry::const_iterator end = m_die_array.end(); + puts("offset parent sibling child"); + puts("-------- -------- -------- --------"); + for (pos = m_die_array.begin(); pos != end; ++pos) + { + const DWARFDebugInfoEntry& die_ref = *pos; + const DWARFDebugInfoEntry* p = die_ref.GetParent(); + const DWARFDebugInfoEntry* s = die_ref.GetSibling(); + const DWARFDebugInfoEntry* c = die_ref.GetFirstChild(); + printf("%.8x: %.8x %.8x %.8x\n", die_ref.GetOffset(), + p ? p->GetOffset() : 0, + s ? s->GetOffset() : 0, + c ? c->GetOffset() : 0); + } + } +#endif + +} +//---------------------------------------------------------------------- +// Compare function DWARFDebugAranges::Range structures +//---------------------------------------------------------------------- +static bool CompareDIEOffset (const DWARFDebugInfoEntry& die1, const DWARFDebugInfoEntry& die2) +{ + return die1.GetOffset() < die2.GetOffset(); +} + +//---------------------------------------------------------------------- +// GetDIEPtr() +// +// Get the DIE (Debug Information Entry) with the specified offset. +//---------------------------------------------------------------------- +DWARFDebugInfoEntry* +DWARFCompileUnit::GetDIEPtr(dw_offset_t die_offset) +{ + if (die_offset != DW_INVALID_OFFSET) + { + ExtractDIEsIfNeeded (false); + DWARFDebugInfoEntry compare_die; + compare_die.SetOffset(die_offset); + DWARFDebugInfoEntry::iterator end = m_die_array.end(); + DWARFDebugInfoEntry::iterator pos = lower_bound(m_die_array.begin(), end, compare_die, CompareDIEOffset); + if (pos != end) + { + if (die_offset == (*pos).GetOffset()) + return &(*pos); + } + } + return NULL; // Not found in any compile units +} + +//---------------------------------------------------------------------- +// GetDIEPtrContainingOffset() +// +// Get the DIE (Debug Information Entry) that contains the specified +// .debug_info offset. +//---------------------------------------------------------------------- +const DWARFDebugInfoEntry* +DWARFCompileUnit::GetDIEPtrContainingOffset(dw_offset_t die_offset) +{ + if (die_offset != DW_INVALID_OFFSET) + { + ExtractDIEsIfNeeded (false); + DWARFDebugInfoEntry compare_die; + compare_die.SetOffset(die_offset); + DWARFDebugInfoEntry::iterator end = m_die_array.end(); + DWARFDebugInfoEntry::iterator pos = lower_bound(m_die_array.begin(), end, compare_die, CompareDIEOffset); + if (pos != end) + { + if (die_offset >= (*pos).GetOffset()) + { + DWARFDebugInfoEntry::iterator next = pos + 1; + if (next != end) + { + if (die_offset < (*next).GetOffset()) + return &(*pos); + } + } + } + } + return NULL; // Not found in any compile units +} + + + +size_t +DWARFCompileUnit::AppendDIEsWithTag (const dw_tag_t tag, DWARFDIECollection& dies, uint32_t depth) const +{ + size_t old_size = dies.Size(); + DWARFDebugInfoEntry::const_iterator pos; + DWARFDebugInfoEntry::const_iterator end = m_die_array.end(); + for (pos = m_die_array.begin(); pos != end; ++pos) + { + if (pos->Tag() == tag) + dies.Insert(&(*pos)); + } + + // Return the number of DIEs added to the collection + return dies.Size() - old_size; +} + +void +DWARFCompileUnit::AddGlobalDIEByIndex (uint32_t die_idx) +{ + m_global_die_indexes.push_back (die_idx); +} + + +void +DWARFCompileUnit::AddGlobal (const DWARFDebugInfoEntry* die) +{ + // Indexes to all file level global and static variables + m_global_die_indexes; + + if (m_die_array.empty()) + return; + + const DWARFDebugInfoEntry* first_die = &m_die_array[0]; + const DWARFDebugInfoEntry* end = first_die + m_die_array.size(); + if (first_die <= die && die < end) + m_global_die_indexes.push_back (die - first_die); +} + + +void +DWARFCompileUnit::Index +( + lldb_private::UniqueCStringMap<dw_offset_t>& name_to_function_die, + lldb_private::UniqueCStringMap<dw_offset_t>& name_to_inlined_die, + lldb_private::UniqueCStringMap<dw_offset_t>& name_to_global_die, + lldb_private::UniqueCStringMap<dw_offset_t>& name_to_type_die +) +{ + + const DataExtractor* debug_str = &m_dwarf2Data->get_debug_str_data(); + + DWARFDebugInfoEntry::const_iterator pos; + DWARFDebugInfoEntry::const_iterator begin = m_die_array.begin(); + DWARFDebugInfoEntry::const_iterator end = m_die_array.end(); + for (pos = begin; pos != end; ++pos) + { + const DWARFDebugInfoEntry &die = *pos; + + const dw_tag_t tag = die.Tag(); + + switch (tag) + { + case DW_TAG_subprogram: + case DW_TAG_inlined_subroutine: + case DW_TAG_base_type: + case DW_TAG_class_type: + case DW_TAG_constant: + case DW_TAG_enumeration_type: + case DW_TAG_string_type: + case DW_TAG_subroutine_type: + case DW_TAG_structure_type: + case DW_TAG_union_type: + case DW_TAG_typedef: + case DW_TAG_namespace: + case DW_TAG_variable: + break; + + default: + continue; + } + + DWARFDebugInfoEntry::Attributes attributes; + const char *name = NULL; + const char *mangled = NULL; + bool is_variable = false; + bool is_declaration = false; + bool is_artificial = false; + bool has_address = false; + bool has_location = false; + bool is_global_or_static_variable = false; + const size_t num_attributes = die.GetAttributes(m_dwarf2Data, this, attributes); + if (num_attributes > 0) + { + uint32_t i; + + dw_tag_t tag = die.Tag(); + + is_variable = tag == DW_TAG_variable; + + for (i=0; i<num_attributes; ++i) + { + dw_attr_t attr = attributes.AttributeAtIndex(i); + DWARFFormValue form_value; + switch (attr) + { + case DW_AT_name: + if (attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value)) + name = form_value.AsCString(debug_str); + break; + + case DW_AT_declaration: + if (attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value)) + is_declaration = form_value.Unsigned() != 0; + break; + + case DW_AT_artificial: + if (attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value)) + is_artificial = form_value.Unsigned() != 0; + break; + + case DW_AT_MIPS_linkage_name: + if (attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value)) + mangled = form_value.AsCString(debug_str); + break; + + case DW_AT_low_pc: + case DW_AT_ranges: + case DW_AT_entry_pc: + has_address = true; + break; + + case DW_AT_location: + has_location = true; + if (tag == DW_TAG_variable) + { + const DWARFDebugInfoEntry* parent_die = die.GetParent(); + while ( parent_die != NULL ) + { + switch (parent_die->Tag()) + { + case DW_TAG_subprogram: + case DW_TAG_lexical_block: + case DW_TAG_inlined_subroutine: + // Even if this is a function level static, we don't add it. We could theoretically + // add these if we wanted to by introspecting into the DW_AT_location and seeing + // if the location describes a hard coded address, but we dont want the performance + // penalty of that right now. + is_global_or_static_variable = false; +// if (attributes.ExtractFormValueAtIndex(dwarf2Data, i, form_value)) +// { +// // If we have valid block data, then we have location expression bytes +// // that are fixed (not a location list). +// const uint8_t *block_data = form_value.BlockData(); +// if (block_data) +// { +// uint32_t block_length = form_value.Unsigned(); +// if (block_length == 1 + attributes.CompileUnitAtIndex(i)->GetAddressByteSize()) +// { +// if (block_data[0] == DW_OP_addr) +// add_die = true; +// } +// } +// } + parent_die = NULL; // Terminate the while loop. + break; + + case DW_TAG_compile_unit: + is_global_or_static_variable = true; + parent_die = NULL; // Terminate the while loop. + break; + + default: + parent_die = parent_die->GetParent(); // Keep going in the while loop. + break; + } + } + } + break; + } + } + } + + switch (tag) + { + case DW_TAG_subprogram: + if (has_address) + { + if (name && name[0]) + { + if ((name[0] == '-' || name[0] == '+') && name[1] == '[') + { + int name_len = strlen (name); + // Objective C methods must have at least: + // "-[" or "+[" prefix + // One character for a class name + // One character for the space between the class name + // One character for the method name + // "]" suffix + if (name_len >= 6 && name[name_len - 1] == ']') + { + const char *method_name = strchr (name, ' '); + if (method_name) + { + // Skip the space + ++method_name; + // Extract the objective C basename and add it to the + // accelerator tables + size_t method_name_len = name_len - (method_name - name) - 1; + ConstString method_const_str (method_name, method_name_len); + name_to_function_die.Append(method_const_str.AsCString(), die.GetOffset()); + } + } + } + name_to_function_die.Append(ConstString(name).AsCString(), die.GetOffset()); + } + if (mangled && mangled[0]) + name_to_function_die.Append(ConstString(mangled).AsCString(), die.GetOffset()); + } + break; + + case DW_TAG_inlined_subroutine: + if (has_address) + { + if (name && name[0]) + name_to_inlined_die.Append(ConstString(name).AsCString(), die.GetOffset()); + if (mangled && mangled[0]) + name_to_inlined_die.Append(ConstString(mangled).AsCString(), die.GetOffset()); + } + break; + + case DW_TAG_base_type: + case DW_TAG_class_type: + case DW_TAG_constant: + case DW_TAG_enumeration_type: + case DW_TAG_string_type: + case DW_TAG_subroutine_type: + case DW_TAG_structure_type: + case DW_TAG_union_type: + case DW_TAG_typedef: + case DW_TAG_namespace: + if (name && is_declaration == false) + { + name_to_type_die.Append(ConstString(name).AsCString(), die.GetOffset()); + } + break; + + case DW_TAG_variable: + if (name && has_location && is_global_or_static_variable) + { + AddGlobalDIEByIndex (std::distance (begin, pos)); + name_to_global_die.Append(ConstString(name).AsCString(), die.GetOffset()); + } + break; + + default: + continue; + } + } +} + + |