diff options
-rw-r--r-- | include/lldb/lldb-enumerations.h | 4 | ||||
-rw-r--r-- | lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme | 6 | ||||
-rw-r--r-- | source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp | 16 | ||||
-rw-r--r-- | source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp | 323 | ||||
-rw-r--r-- | source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h | 322 | ||||
-rw-r--r-- | source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 22 | ||||
-rw-r--r-- | source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h | 10 | ||||
-rw-r--r-- | source/Symbol/ObjectFile.cpp | 4 | ||||
-rw-r--r-- | source/lldb.cpp | 4 |
9 files changed, 526 insertions, 185 deletions
diff --git a/include/lldb/lldb-enumerations.h b/include/lldb/lldb-enumerations.h index 154cb4447..4ac43c1a9 100644 --- a/include/lldb/lldb-enumerations.h +++ b/include/lldb/lldb-enumerations.h @@ -475,8 +475,8 @@ namespace lldb { eSectionTypeDWARFDebugPubTypes, eSectionTypeDWARFDebugRanges, eSectionTypeDWARFDebugStr, - eSectionTypeDWARFDebugNames, - eSectionTypeDWARFDebugTypes, + eSectionTypeDWARFAppleNames, + eSectionTypeDWARFAppleTypes, eSectionTypeEHFrame, eSectionTypeOther diff --git a/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme b/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme index 6e12c06c9..007ad4eb4 100644 --- a/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme +++ b/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme @@ -99,6 +99,12 @@ ReferencedContainer = "container:lldb.xcodeproj"> </BuildableReference> </BuildableProductRunnable> + <CommandLineArguments> + <CommandLineArgument + argument = "/Volumes/work/gclayton/Documents/src/WebCore-6530.1/build/Production/WebCore.framework/Versions/A/WebCore" + isEnabled = "YES"> + </CommandLineArgument> + </CommandLineArguments> <EnvironmentVariables> <EnvironmentVariable key = "LLDB_LAUNCH_FLAG_DISABLE_ASLR" diff --git a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index 9ad3d252d..a833a670e 100644 --- a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -255,8 +255,8 @@ ObjectFileMachO::GetAddressClass (lldb::addr_t file_addr) case eSectionTypeDWARFDebugPubTypes: return eAddressClassDebug; case eSectionTypeDWARFDebugRanges: return eAddressClassDebug; case eSectionTypeDWARFDebugStr: return eAddressClassDebug; - case eSectionTypeDWARFDebugNames: return eAddressClassDebug; - case eSectionTypeDWARFDebugTypes: return eAddressClassDebug; + case eSectionTypeDWARFAppleNames: return eAddressClassDebug; + case eSectionTypeDWARFAppleTypes: return eAddressClassDebug; case eSectionTypeEHFrame: return eAddressClassRuntime; case eSectionTypeOther: return eAddressClassUnknown; } @@ -507,8 +507,8 @@ ObjectFileMachO::ParseSections () static ConstString g_sect_name_dwarf_debug_pubtypes ("__debug_pubtypes"); static ConstString g_sect_name_dwarf_debug_ranges ("__debug_ranges"); static ConstString g_sect_name_dwarf_debug_str ("__debug_str"); - static ConstString g_sect_name_dwarf_debug_names ("__debug_names"); - static ConstString g_sect_name_dwarf_debug_types ("__debug_types"); + static ConstString g_sect_name_dwarf_apple_names ("__apple_names"); + static ConstString g_sect_name_dwarf_apple_types ("__apple_types"); static ConstString g_sect_name_eh_frame ("__eh_frame"); static ConstString g_sect_name_DATA ("__DATA"); static ConstString g_sect_name_TEXT ("__TEXT"); @@ -537,10 +537,10 @@ ObjectFileMachO::ParseSections () sect_type = eSectionTypeDWARFDebugRanges; else if (section_name == g_sect_name_dwarf_debug_str) sect_type = eSectionTypeDWARFDebugStr; - else if (section_name == g_sect_name_dwarf_debug_names) - sect_type = eSectionTypeDWARFDebugNames; - else if (section_name == g_sect_name_dwarf_debug_types) - sect_type = eSectionTypeDWARFDebugTypes; + else if (section_name == g_sect_name_dwarf_apple_names) + sect_type = eSectionTypeDWARFAppleNames; + else if (section_name == g_sect_name_dwarf_apple_types) + sect_type = eSectionTypeDWARFAppleTypes; else if (section_name == g_sect_name_objc_selrefs) sect_type = eSectionTypeDataCStringPointers; else if (section_name == g_sect_name_objc_msgrefs) diff --git a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp index 3ee478ebc..1a764913a 100644 --- a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp +++ b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp @@ -18,6 +18,7 @@ #include "DWARFCompileUnit.h" #include "DWARFDebugInfo.h" #include "DWARFDebugInfoEntry.h" +#include "DWARFDefines.h" #include "SymbolFileDWARF.h" using namespace lldb; using namespace lldb_private; @@ -33,115 +34,275 @@ dl_new_hash (const char *s) return h; } -HashedNameToDIE::HashedNameToDIE (SymbolFileDWARF *dwarf, const DataExtractor &data) : - m_dwarf (dwarf), - m_data (data), - m_header () + +void +HashedNameToDIE::Header::Dump (Stream &s) { + s.Printf ("header.magic = 0x%8.8x", magic); + s.Printf ("header.version = 0x%4.4x", version); + s.Printf ("header.addr_bytesize = 0x%2.2x", addr_bytesize); + s.Printf ("header.hash_function = 0x%2.2x", hash_function); + s.Printf ("header.hash_count_bitsize = 0x%2.2x", hash_count_bitsize); + s.Printf ("header.hash_index_bitsize = 0x%2.2x", hash_index_bitsize); + s.Printf ("header.hash_bytesize = 0x%2.2x", hash_bytesize); + s.Printf ("header.offset_bytesize = 0x%2.2x", offset_bytesize); + s.Printf ("header.bucket_count = 0x%8.8x %u", bucket_count, bucket_count); + s.Printf ("header.hashes_count = 0x%8.8x %u", hashes_count, hashes_count); + s.Printf ("header.prologue_length = 0x%8.8x %u", prologue_length, prologue_length); +} + +uint32_t +HashedNameToDIE::Header::Read (const DataExtractor &data, uint32_t offset) +{ + magic = data.GetU32 (&offset); + if (magic != HASH_MAGIC) + { + // Magic bytes didn't match + version = 0; + return UINT32_MAX; + } + + version = data.GetU16 (&offset); + if (version != 1) + { + // Unsupported version + return UINT32_MAX; + } + addr_bytesize = data.GetU8 (&offset); + hash_function = data.GetU8 (&offset); + hash_count_bitsize = data.GetU8 (&offset); + hash_index_bitsize = data.GetU8 (&offset); + hash_bytesize = data.GetU8 (&offset); + offset_bytesize = data.GetU8 (&offset); + bucket_count = data.GetU32 (&offset); + hashes_count = data.GetU32 (&offset); + prologue_length = data.GetU32 (&offset); + return offset; } void -HashedNameToDIE::Initialize() +HashedNameToDIE::DWARF::Header::Dump (Stream &s) { - uint32_t offset = 0; - m_header.version = m_data.GetU16(&offset); - if (m_header.version) + HashedNameToDIE::Header::Dump (s); + dwarf_prologue.Dump (s); +} + +uint32_t +HashedNameToDIE::DWARF::Header::Read (const DataExtractor &data, uint32_t offset) +{ + offset = HashedNameToDIE::Header::Read (data, offset); + if (offset != UINT32_MAX) + offset = dwarf_prologue.Read (data, offset); + else + dwarf_prologue.Clear(); + return offset; +} + +void +HashedNameToDIE::DWARF::Prologue::Dump (Stream &s) +{ + s.Printf ("dwarf_prologue.die_base_offset = 0x%8.8x\n", die_base_offset); + const size_t num_atoms = atoms.size(); + for (size_t i = 0; i < num_atoms; ++i) { - m_header.hash_type = m_data.GetU8(&offset); - m_header.hash_index_bitsize = m_data.GetU8(&offset); - m_header.num_buckets = m_data.GetU32(&offset); - m_header.num_hashes = m_data.GetU32(&offset); - m_header.die_offset_base = m_data.GetU32(&offset); + s.Printf ("dwarf_prologue.atom[%zi] = %17s %s\n", + i, + GetAtomTypeName (atoms[i].type), + DW_FORM_value_to_name(atoms[i].form)); } } -size_t -HashedNameToDIE::Find (const ConstString &name, DIEArray &die_ofsets) const +uint32_t +HashedNameToDIE::DWARF::Prologue::Read (const DataExtractor &data, uint32_t offset) { - const size_t initial_size = die_ofsets.size(); - const char *name_cstr = name.GetCString(); - if (name_cstr && name_cstr[0]) + Clear(); + die_base_offset = data.GetU32 (&offset); + Atom atom; + while (offset != UINT32_MAX) { - // Hash the C string - const uint32_t name_hash = dl_new_hash (name_cstr); - - // Find the correct bucket for the using the hash value - const uint32_t bucket_idx = name_hash % m_header.num_buckets; - - // Calculate the offset for the bucket entry for the bucket index - uint32_t offset = GetOffsetOfBucketEntry (bucket_idx); + atom.type = data.GetU16 (&offset); + atom.form = data.GetU16 (&offset); + if (atom.type == eAtomTypeNULL) + break; + atoms.push_back(atom); + } + return offset; +} + + +HashedNameToDIE::MemoryTable::MemoryTable (SymbolFileDWARF *dwarf, + const lldb_private::DataExtractor &data, + bool is_apple_names) : + m_data (data), + m_string_table (dwarf->get_debug_str_data ()), + m_is_apple_names (is_apple_names), + m_header () +{ +} - // Extract the bucket entry. - const uint32_t bucket_entry = m_data.GetU32 (&offset); - if (bucket_entry) +bool +HashedNameToDIE::MemoryTable::Initialize () +{ + uint32_t offset = 0; + offset = m_header.Read (m_data, offset); + return m_header.version == 1; +} + + +size_t +HashedNameToDIE::MemoryTable::Find (const char *name_cstr, DIEArray &die_ofsets) const +{ + if (m_header.version == 1) + { + const size_t initial_size = die_ofsets.size(); + if (name_cstr && name_cstr[0]) { - // The bucket entry is non-zero which means it isn't empty. - // The bucket entry is made up of a hash index whose bit width - // is m_header.hash_index_bitsize, and a hash count whose value - // is the remaining bits in the 32 bit value. Below we extract - // the hash index and the hash count - const uint32_t hash_idx = bucket_entry & GetHashIndexMask(); - const uint32_t hash_count = bucket_entry >> m_header.hash_index_bitsize; - const uint32_t hash_end_idx = hash_idx + hash_count; - // Figure out the offset to the hash value by index - uint32_t hash_offset = GetOffsetOfHashValue (hash_idx); - for (uint32_t idx = hash_idx; idx < hash_end_idx; ++idx) + // Hash the C string + const uint32_t name_hash = dl_new_hash (name_cstr); + + // Find the correct bucket for the using the hash value + const uint32_t bucket_idx = name_hash % m_header.bucket_count; + + // Calculate the offset for the bucket entry for the bucket index + uint32_t offset = GetOffsetOfBucketEntry (bucket_idx); + + // Extract the bucket entry. + const uint32_t bucket_entry = m_data.GetU32 (&offset); + if (bucket_entry) { - // Extract the hash value and see if it matches our string - const uint32_t hash = m_data.GetU32 (&hash_offset); - if (hash == name_hash) + // The bucket entry is non-zero which means it isn't empty. + // The bucket entry is made up of a hash index whose bit width + // is m_header.hash_index_bitsize, and a hash count whose value + // is the remaining bits in the 32 bit value. Below we extract + // the hash index and the hash count + const uint32_t hash_idx = bucket_entry & GetHashIndexMask(); + const uint32_t hash_count = bucket_entry >> m_header.hash_index_bitsize; + const uint32_t hash_end_idx = hash_idx + hash_count; + // Figure out the offset to the hash value by index + uint32_t hash_offset = GetOffsetOfHashValue (hash_idx); + for (uint32_t idx = hash_idx; idx < hash_end_idx; ++idx) { - // The hash matches, but we still need to verify that the - // C string matches in case we have a hash collision. Figure - // out the offset for the data associated with this hash entry - offset = GetOffsetOfHashDataOffset (idx); - // Extract the first 32 bit value which is the .debug_str offset - // of the string we need - uint32_t hash_data_offset = m_data.GetU32 (&offset); - const uint32_t str_offset = m_data.GetU32 (&hash_data_offset); - // Extract the C string and comapare it - const char *cstr_name = m_dwarf->get_debug_str_data().PeekCStr(str_offset); - if (cstr_name) + // Extract the hash value and see if it matches our string + const uint32_t hash = m_data.GetU32 (&hash_offset); + if (hash == name_hash) { - if (strcmp(name_cstr, cstr_name) == 0) + // The hash matches, but we still need to verify that the + // C string matches in case we have a hash collision. Figure + // out the offset for the data associated with this hash entry + offset = GetOffsetOfHashDataOffset (idx); + uint32_t hash_data_offset = m_data.GetU32 (&offset); + uint32_t str_offset; + // Now we have the offset to the data for all strings that match + // our 32 bit hash. The format of the hash bucket is: + // + // uint32_t stroff; // string offset in .debug_str table + // uint32_t num_dies; // Number of DIEs in debug info that match the string that follow this + // uint32_t die_offsets[num_dies]; // An array of DIE offsets + // + // When a "stroff" is read and it is zero, then the data for this + // hash is terminated. + while ((str_offset = m_data.GetU32 (&hash_data_offset)) != 0) { - // We have a match, now extract the DIE count - const uint32_t die_count = m_data.GetU32 (&hash_data_offset); - // Now extract "die_count" DIE offsets and put them into the - // results - for (uint32_t die_idx = 0; die_idx < die_count; ++die_idx) - die_ofsets.push_back(m_data.GetU32 (&hash_data_offset)); + // Extract the C string and comapare it + const char *cstr_name = m_string_table.PeekCStr(str_offset); + if (cstr_name) + { + if (strcmp(name_cstr, cstr_name) == 0) + { + // We have a match, now extract the DIE count + const uint32_t die_count = m_data.GetU32 (&hash_data_offset); + // Now extract "die_count" DIE offsets and put them into the + // results + for (uint32_t die_idx = 0; die_idx < die_count; ++die_idx) + die_ofsets.push_back(m_data.GetU32 (&hash_data_offset)); + } + } } } } } } + return die_ofsets.size() - initial_size; } - return die_ofsets.size() - initial_size; -} - -size_t -HashedNameToDIE::Find (const RegularExpression& regex, DIEArray &die_ofsets) const -{ -// const size_t initial_info_array_size = info_array.size(); -// collection::const_iterator pos, end = m_collection.end(); -// for (pos = m_collection.begin(); pos != end; ++pos) -// { -// if (regex.Execute(pos->first)) -// info_array.push_back (pos->second); -// } -// return info_array.size() - initial_info_array_size; return 0; } void -HashedNameToDIE::Dump (Stream *s) +HashedNameToDIE::MemoryTable::Dump (Stream &s) { -// collection::const_iterator pos, end = m_collection.end(); -// for (pos = m_collection.begin(); pos != end; ++pos) -// { -// s->Printf("%p: 0x%8.8x 0x%8.8x \"%s\"\n", pos->first, pos->second.cu_idx, pos->second.die_idx, pos->first); -// } + if (m_header.version == 1) + { + + bool verbose = s.GetVerbose(); + + if (m_is_apple_names) + s.PutCString (".apple_names contents:\n"); + else + s.PutCString (".apple_types contents:\n"); + + m_header.Dump (s); + uint32_t i,j,k; + uint32_t empty_bucket_count = 0; + uint32_t hash_collisions = 0; + uint32_t bucket_entry_offset = GetOffsetOfBucketEntry (0); + for (i=0; i<m_header.bucket_count; ++i) + { + const uint32_t bucket_entry = m_data.GetU32 (&bucket_entry_offset); + s.Printf("bucket[%u] 0x%8.8x", i, bucket_entry); + if (bucket_entry) + { + const uint32_t hash_idx = bucket_entry & GetHashIndexMask(); + const uint32_t hash_count = bucket_entry >> m_header.hash_index_bitsize; + + s.Printf(" (hash_idx = %u, hash_count = %u)\n", hash_idx, hash_count); + + const uint32_t hash_end_idx = hash_idx + hash_count; + uint32_t hash_offset = GetOffsetOfHashValue (hash_idx); + uint32_t data_offset = GetOffsetOfHashDataOffset (hash_idx); + + for (j=hash_idx; j<hash_end_idx; ++j) + { + const uint32_t hash = m_data.GetU32 (&hash_offset); + uint32_t hash_data_offset = m_data.GetU32 (&data_offset); + if (verbose) + s.Printf(" hash[%u] = 0x%8.8x, offset[%u] = 0x%8.8x\n", j, hash, j, hash_data_offset); + else + s.Printf(" hash[%u] = 0x%8.8x\n", j, hash); + + uint32_t string_idx = 0; + uint32_t strp_offset; + while ((strp_offset = m_data.GetU32 (&hash_data_offset)) != 0) + { + const uint32_t num_die_offsets = m_data.GetU32 (&hash_data_offset); + s.Printf(" string[%u] = 0x%8.8x \"%s\", dies[%u] = {", + string_idx, + strp_offset, + m_string_table.PeekCStr(strp_offset), + num_die_offsets); + ++string_idx; + + for (k=0; k<num_die_offsets; ++k) + { + const uint32_t die_offset = m_data.GetU32 (&hash_data_offset); + s.Printf(" 0x%8.8x", die_offset); + } + s.PutCString (" }\n"); + } + if (string_idx > 1) + ++hash_collisions; + } + } + else + { + s.PutCString(" (empty)\n"); + ++empty_bucket_count; + } + } + + s.Printf ("%u of %u buckets empty (%2.1f%%)\n", empty_bucket_count, m_header.bucket_count, (((float)empty_bucket_count/(float)m_header.bucket_count)*100.0f)); + s.Printf ("Average hashes/non-empty bucket = %2.1f%%\n", ((float)m_header.hashes_count/(float)(m_header.bucket_count - empty_bucket_count))); + s.Printf ("Hash collisions = %u\n", hash_collisions); + } } diff --git a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h index 96b4426ff..5f2363bef 100644 --- a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h +++ b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h @@ -21,95 +21,269 @@ typedef std::vector<dw_offset_t> DIEArray; class HashedNameToDIE { public: + enum NameFlags + { + eNameFlagIsExternal = (1u << 0), + eNameFlagIsClassCXX = (1u << 1), + eNameFlagIsClassObjC = (1u << 2), + eNameFlagIsClassObjCMaster = (1u << 3) + }; + + enum TypeFlags + { + eTypeFlagIsExternal = (1u << 0) + }; + + enum HashFunctionType + { + eHashFunctionDJB = 0u, // Daniel J Bernstein hash function that is also used by the ELF GNU_HASH sections + }; + + static const uint32_t HASH_MAGIC = 0x48415348u; + struct Header { - uint16_t version; - uint8_t hash_type; - uint8_t hash_index_bitsize; - uint32_t num_buckets; - uint32_t num_hashes; - uint32_t die_offset_base; - - Header() : - version(0), - hash_type (0), - hash_index_bitsize (0), - num_buckets(0), - num_hashes (0), - die_offset_base(0) + uint32_t magic; // 'HASH' magic value to allow endian detection + uint16_t version; // Version number + uint8_t addr_bytesize; // Size in bytes of an address + uint8_t hash_function; // The hash function enumeration that was used + uint8_t hash_count_bitsize; // Size in bits of the hash count in each bucket entry + uint8_t hash_index_bitsize; // Size in bits of the hash index in each bucket entry + uint8_t hash_bytesize; // Size in bytes of the hash that is stored in the hashes which must be <= 4 + uint8_t offset_bytesize; // Size in bytes of the hash data offsets + + uint32_t bucket_count; // The number of buckets in this hash table + uint32_t hashes_count; // The total number of unique hash values and hash data offsets in this table + uint32_t prologue_length; // The length of the prologue + + Header (uint32_t _prologue_length) : + magic (HASH_MAGIC), + version (1), + addr_bytesize (4), + hash_count_bitsize (8), + hash_index_bitsize (24), + hash_function (eHashFunctionDJB), + hash_bytesize (4), // Store the entire 32 bit hash by default + offset_bytesize (4), // Store a 4 byte offset for every hash value + bucket_count (0), + hashes_count (0), + prologue_length (_prologue_length) { } + + virtual + ~Header () + { + } + + virtual size_t + GetByteSize() const + { + return sizeof(magic) + + sizeof(version) + + sizeof(addr_bytesize) + + sizeof(hash_function) + + sizeof(hash_count_bitsize) + + sizeof(hash_index_bitsize) + + sizeof(hash_bytesize) + + sizeof(offset_bytesize) + + sizeof(bucket_count) + + sizeof(hashes_count) + + sizeof(prologue_length) + + prologue_length; + } + + virtual void + Dump (lldb_private::Stream &s); + + virtual uint32_t + Read (const lldb_private::DataExtractor &data, uint32_t offset); }; - - HashedNameToDIE (SymbolFileDWARF *dwarf, - const lldb_private::DataExtractor &data); - - ~HashedNameToDIE () - { - } - - bool - IsValid () const + struct DWARF { - return m_header.version > 0; - } + enum AtomType + { + eAtomTypeNULL = 0u, + eAtomTypeHashString = 1u, // String value for hash, use DW_FORM_strp (preferred) or DW_FORM_string + eAtomTypeHashLength = 2u, // Length of data for the previous string refered by the last eAtomTypeHashString atom + eAtomTypeArraySize = 3u, // A count that specifies a number of atoms that follow this entry, the next atom defines what the atom type for the array is + eAtomTypeDIEOffset = 4u, // DIE offset, check form for encoding. If DW_FORM_ref1,2,4,8 or DW_FORM_ref_udata, then this value is added to the prologue + eAtomTypeTag = 5u, // DW_TAG_xxx value, should be encoded as DW_FORM_data1 (if no tags exceed 255) or DW_FORM_data2 + eAtomTypeNameFlags = 6u, // Flags from enum NameFlags + eAtomTypeTypeFlags = 7u, // Flags from enum TypeFlags + }; + + struct Atom + { + uint16_t type; + dw_form_t form; + + Atom (uint16_t t = eAtomTypeNULL, dw_form_t f = 0) : + type (t), + form (f) + { + } + }; + + typedef std::vector<Atom> AtomArray; + + + static const char * + GetAtomTypeName (uint16_t atom) + { + switch (atom) + { + case eAtomTypeNULL: return "NULL"; + case eAtomTypeHashString: return "hash-string"; + case eAtomTypeHashLength: return "hash-data-length"; + case eAtomTypeArraySize: return "array-size"; + case eAtomTypeDIEOffset: return "die-offset"; + case eAtomTypeTag: return "die-tag"; + case eAtomTypeNameFlags: return "name-flags"; + case eAtomTypeTypeFlags: return "type-flags"; + } + return "<invalid>"; + } + struct Prologue + { + // DIE offset base so die offsets in hash_data can be CU relative + dw_offset_t die_base_offset; + AtomArray atoms; + + Prologue (dw_offset_t _die_base_offset = 0) : + die_base_offset (_die_base_offset) + { + // Define an array of DIE offsets by first defining an array, + // and then define the atom type for the array, in this case + // we have an array of DIE offsets + atoms.push_back (Atom(eAtomTypeArraySize, DW_FORM_data4)); + atoms.push_back (Atom(eAtomTypeDIEOffset, DW_FORM_data4)); + } - uint32_t - GetHashIndexMask () const - { - return (1u << m_header.hash_index_bitsize) - 1u; - } - - uint32_t - GetOffsetOfBucketEntry (uint32_t idx) const - { - if (idx < m_header.num_buckets) - return sizeof(Header) + 4 * idx; - return UINT32_MAX; - } + virtual + ~Prologue () + { + } + + + virtual void + Clear () + { + die_base_offset = 0; + atoms.clear(); + } + + virtual void + Dump (lldb_private::Stream &s); + + virtual uint32_t + Read (const lldb_private::DataExtractor &data, uint32_t offset); + + size_t + GetByteSize () const + { + // Add an extra count to the atoms size for the zero termination Atom that gets + // written to disk + return sizeof(die_base_offset) + ((atoms.size() + 1) * sizeof(Atom)); + } + }; + + struct Header : public HashedNameToDIE::Header + { + Header (dw_offset_t _die_base_offset = 0) : + HashedNameToDIE::Header (sizeof(Prologue)), + dwarf_prologue (_die_base_offset) + { + } - uint32_t - GetOffsetOfHashValue (uint32_t idx) const - { - if (idx < m_header.num_hashes) - return sizeof(Header) + - 4 * m_header.num_buckets + - 4 * idx; - return UINT32_MAX; - } + virtual + ~Header () + { + } - uint32_t - GetOffsetOfHashDataOffset (uint32_t idx) const + Prologue dwarf_prologue; + + virtual void + Dump (lldb_private::Stream &s); + + virtual uint32_t + Read (const lldb_private::DataExtractor &data, uint32_t offset); + }; + + }; + + + class MemoryTable { - if (idx < m_header.num_hashes) + public: + + MemoryTable (SymbolFileDWARF *dwarf, + const lldb_private::DataExtractor &data, + bool is_apple_names); + + ~MemoryTable () { - return sizeof(Header) + - 4 * m_header.num_buckets + - 4 * m_header.num_hashes + - 4 * idx; } - return UINT32_MAX; - } - void - Dump (lldb_private::Stream *s); + bool + Initialize (); - size_t - Find (const lldb_private::ConstString &name, - DIEArray &die_ofsets) const; - - size_t - Find (const lldb_private::RegularExpression& regex, - DIEArray &die_ofsets) const; - - void - Initialize(); - -protected: - SymbolFileDWARF *m_dwarf; - const lldb_private::DataExtractor &m_data; - Header m_header; + bool + IsValid () const + { + return m_header.version > 0; + } + + uint32_t + GetHashIndexMask () const + { + return (1u << m_header.hash_index_bitsize) - 1u; + } + + uint32_t + GetOffsetOfBucketEntry (uint32_t idx) const + { + if (idx < m_header.bucket_count) + return m_header.GetByteSize() + 4 * idx; + return UINT32_MAX; + } + + uint32_t + GetOffsetOfHashValue (uint32_t idx) const + { + if (idx < m_header.hashes_count) + return m_header.GetByteSize() + + 4 * m_header.bucket_count + + 4 * idx; + return UINT32_MAX; + } + + uint32_t + GetOffsetOfHashDataOffset (uint32_t idx) const + { + if (idx < m_header.hashes_count) + { + return m_header.GetByteSize() + + 4 * m_header.bucket_count + + 4 * m_header.hashes_count + + 4 * idx; + } + return UINT32_MAX; + } + + void + Dump (lldb_private::Stream &s); + + size_t + Find (const char *name, DIEArray &die_ofsets) const; + + protected: + const lldb_private::DataExtractor &m_data; + const lldb_private::DataExtractor &m_string_table; + bool m_is_apple_names; // true => .apple_names, false => .apple_types + DWARF::Header m_header; + }; }; #endif // SymbolFileDWARF_HashedNameToDIE_h_ diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index c10ffaad1..535c9103c 100644 --- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -171,12 +171,12 @@ SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) : m_data_debug_loc (), m_data_debug_ranges (), m_data_debug_str (), - m_data_debug_names (), - m_data_debug_types (), + m_data_apple_names (), + m_data_apple_types (), m_abbr(), m_info(), m_line(), - m_debug_names (this, m_data_debug_names), + m_apple_names (this, m_data_apple_names, true), m_function_basename_index(), m_function_fullname_index(), m_function_method_index(), @@ -190,8 +190,8 @@ SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) : m_ranges(), m_unique_ast_type_map () { - get_debug_names_data(); - m_debug_names.Initialize(); + get_apple_names_data(); + m_apple_names.Initialize(); } SymbolFileDWARF::~SymbolFileDWARF() @@ -455,15 +455,15 @@ SymbolFileDWARF::get_debug_str_data() } const DataExtractor& -SymbolFileDWARF::get_debug_names_data() +SymbolFileDWARF::get_apple_names_data() { - return GetCachedSectionData (flagsGotDebugNamesData, eSectionTypeDWARFDebugNames, m_data_debug_names); + return GetCachedSectionData (flagsGotDebugNamesData, eSectionTypeDWARFAppleNames, m_data_apple_names); } const DataExtractor& -SymbolFileDWARF::get_debug_types_data() +SymbolFileDWARF::get_apple_types_data() { - return GetCachedSectionData (flagsGotDebugTypesData, eSectionTypeDWARFDebugTypes, m_data_debug_types); + return GetCachedSectionData (flagsGotDebugTypesData, eSectionTypeDWARFAppleTypes, m_data_apple_types); } @@ -2293,10 +2293,10 @@ SymbolFileDWARF::FindFunctions // Remember how many sc_list are in the list before we search in case // we are appending the results to a variable list. - if (m_debug_names.IsValid()) + if (m_apple_names.IsValid()) { DIEArray die_offsets; - const uint32_t num_matches = m_debug_names.Find(name, die_offsets); + const uint32_t num_matches = m_apple_names.Find(name.GetCString(), die_offsets); if (num_matches > 0) { return ResolveFunctions (die_offsets, sc_list); diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index 3a0026a89..6a77d17a2 100644 --- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -164,8 +164,8 @@ public: const lldb_private::DataExtractor& get_debug_loc_data (); const lldb_private::DataExtractor& get_debug_ranges_data (); const lldb_private::DataExtractor& get_debug_str_data (); - const lldb_private::DataExtractor& get_debug_names_data (); - const lldb_private::DataExtractor& get_debug_types_data (); + const lldb_private::DataExtractor& get_apple_names_data (); + const lldb_private::DataExtractor& get_apple_types_data (); DWARFDebugAbbrev* DebugAbbrev(); const DWARFDebugAbbrev* DebugAbbrev() const; @@ -379,15 +379,15 @@ protected: lldb_private::DataExtractor m_data_debug_loc; lldb_private::DataExtractor m_data_debug_ranges; lldb_private::DataExtractor m_data_debug_str; - lldb_private::DataExtractor m_data_debug_names; - lldb_private::DataExtractor m_data_debug_types; + lldb_private::DataExtractor m_data_apple_names; + lldb_private::DataExtractor m_data_apple_types; // The auto_ptr items below are generated on demand if and when someone accesses // them through a non const version of this class. std::auto_ptr<DWARFDebugAbbrev> m_abbr; std::auto_ptr<DWARFDebugInfo> m_info; std::auto_ptr<DWARFDebugLine> m_line; - HashedNameToDIE m_debug_names; + HashedNameToDIE::MemoryTable m_apple_names; NameToDIE m_function_basename_index; // All concrete functions NameToDIE m_function_fullname_index; // All concrete functions NameToDIE m_function_method_index; // All inlined functions diff --git a/source/Symbol/ObjectFile.cpp b/source/Symbol/ObjectFile.cpp index 7411c0cdf..9aa1daf57 100644 --- a/source/Symbol/ObjectFile.cpp +++ b/source/Symbol/ObjectFile.cpp @@ -221,8 +221,8 @@ ObjectFile::GetAddressClass (addr_t file_addr) case eSectionTypeDWARFDebugPubTypes: return eAddressClassDebug; case eSectionTypeDWARFDebugRanges: return eAddressClassDebug; case eSectionTypeDWARFDebugStr: return eAddressClassDebug; - case eSectionTypeDWARFDebugNames: return eAddressClassDebug; - case eSectionTypeDWARFDebugTypes: return eAddressClassDebug; + case eSectionTypeDWARFAppleNames: return eAddressClassDebug; + case eSectionTypeDWARFAppleTypes: return eAddressClassDebug; case eSectionTypeEHFrame: return eAddressClassRuntime; case eSectionTypeOther: return eAddressClassUnknown; } diff --git a/source/lldb.cpp b/source/lldb.cpp index 94c640028..f640457f6 100644 --- a/source/lldb.cpp +++ b/source/lldb.cpp @@ -259,8 +259,8 @@ lldb_private::GetSectionTypeAsCString (SectionType sect_type) case eSectionTypeDWARFDebugPubTypes: return "dwarf-pubtypes"; case eSectionTypeDWARFDebugRanges: return "dwarf-ranges"; case eSectionTypeDWARFDebugStr: return "dwarf-str"; - case eSectionTypeDWARFDebugNames: return "dwarf-names"; - case eSectionTypeDWARFDebugTypes: return "dwarf-types"; + case eSectionTypeDWARFAppleNames: return "apple-names"; + case eSectionTypeDWARFAppleTypes: return "apple-types"; case eSectionTypeEHFrame: return "eh-frame"; case eSectionTypeOther: return "regular"; } |