diff options
| -rw-r--r-- | lldb/include/lldb/Core/MappedHash.h | 14 | ||||
| -rw-r--r-- | lldb/lldb.xcodeproj/project.pbxproj | 4 | ||||
| -rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp | 298 | ||||
| -rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h | 311 | ||||
| -rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 223 | ||||
| -rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h | 3 |
6 files changed, 164 insertions, 689 deletions
diff --git a/lldb/include/lldb/Core/MappedHash.h b/lldb/include/lldb/Core/MappedHash.h index 6c4249ca2ec..72158e010f3 100644 --- a/lldb/include/lldb/Core/MappedHash.h +++ b/lldb/include/lldb/Core/MappedHash.h @@ -61,8 +61,7 @@ public: uint32_t magic; // HASH_MAGIC or HASH_CIGAM 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 + uint16_t hash_function; // The hash function enumeration that was used 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 header_data_len; // The size in bytes of the "header_data" template member below @@ -71,7 +70,6 @@ public: Header () : magic (HASH_MAGIC), version (1), - addr_bytesize (4), hash_function (eHashFunctionDJB), bucket_count (0), hashes_count (0), @@ -90,7 +88,6 @@ public: { return sizeof(magic) + sizeof(version) + - sizeof(addr_bytesize) + sizeof(hash_function) + sizeof(bucket_count) + sizeof(hashes_count) + @@ -112,8 +109,7 @@ public: { s.Printf ("header.magic = 0x%8.8x\n", magic); s.Printf ("header.version = 0x%4.4x\n", version); - s.Printf ("header.addr_bytesize = 0x%2.2x\n", addr_bytesize); - s.Printf ("header.hash_function = 0x%2.2x\n", hash_function); + s.Printf ("header.hash_function = 0x%4.4x\n", hash_function); s.Printf ("header.bucket_count = 0x%8.8x %u\n", bucket_count, bucket_count); s.Printf ("header.hashes_count = 0x%8.8x %u\n", hashes_count, hashes_count); s.Printf ("header.header_data_len = 0x%8.8x %u\n", header_data_len, header_data_len); @@ -125,7 +121,6 @@ public: if (data.ValidOffsetForDataOfSize (offset, sizeof (magic) + sizeof (version) + - sizeof (addr_bytesize) + sizeof (hash_function) + sizeof (bucket_count) + sizeof (hashes_count) + @@ -162,8 +157,9 @@ public: // Unsupported version return UINT32_MAX; } - addr_bytesize = data.GetU8 (&offset); - hash_function = data.GetU8 (&offset); + hash_function = data.GetU16 (&offset); + if (hash_function == 4) + hash_function = 0; // Deal with pre-release version of this table... bucket_count = data.GetU32 (&offset); hashes_count = data.GetU32 (&offset); header_data_len = data.GetU32 (&offset); diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index 91291942308..1259a7d57ec 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -340,7 +340,6 @@ 26957D9A13D381C900670048 /* RegisterContextDarwin_i386.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26957D9413D381C900670048 /* RegisterContextDarwin_i386.cpp */; }; 26957D9C13D381C900670048 /* RegisterContextDarwin_x86_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26957D9613D381C900670048 /* RegisterContextDarwin_x86_64.cpp */; }; 2697A54D133A6305004E4240 /* PlatformDarwin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2697A54B133A6305004E4240 /* PlatformDarwin.cpp */; }; - 26A0DA4E140F7226006DA411 /* HashedNameToDIE.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A0DA4C140F721D006DA411 /* HashedNameToDIE.cpp */; }; 26A69C5F137A17A500262477 /* RegisterValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C6886E137880C400407EDF /* RegisterValue.cpp */; }; 26A7A035135E6E4200FB369E /* NamedOptionValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A7A034135E6E4200FB369E /* NamedOptionValue.cpp */; }; 26B1FA1413380E61002886E2 /* LLDBWrapPython.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A4EEB511682AAC007A372A /* LLDBWrapPython.cpp */; }; @@ -790,7 +789,6 @@ 269FF08112494FC200225026 /* UnwindTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UnwindTable.h; path = include/lldb/Symbol/UnwindTable.h; sourceTree = "<group>"; }; 26A0604711A5BC7A00F75969 /* Baton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Baton.h; path = include/lldb/Core/Baton.h; sourceTree = "<group>"; }; 26A0604811A5D03C00F75969 /* Baton.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Baton.cpp; path = source/Core/Baton.cpp; sourceTree = "<group>"; }; - 26A0DA4C140F721D006DA411 /* HashedNameToDIE.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = HashedNameToDIE.cpp; sourceTree = "<group>"; }; 26A0DA4D140F721D006DA411 /* HashedNameToDIE.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HashedNameToDIE.h; sourceTree = "<group>"; }; 26A3B4AC1181454800381BC2 /* ObjectContainerBSDArchive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ObjectContainerBSDArchive.cpp; sourceTree = "<group>"; }; 26A3B4AD1181454800381BC2 /* ObjectContainerBSDArchive.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjectContainerBSDArchive.h; sourceTree = "<group>"; }; @@ -1652,7 +1650,6 @@ 260C89D610F57C5600BB2B04 /* DWARFLocationDescription.h */, 260C89D710F57C5600BB2B04 /* DWARFLocationList.cpp */, 260C89D810F57C5600BB2B04 /* DWARFLocationList.h */, - 26A0DA4C140F721D006DA411 /* HashedNameToDIE.cpp */, 26A0DA4D140F721D006DA411 /* HashedNameToDIE.h */, 2618D9EA12406FE600F2B8FE /* NameToDIE.cpp */, 2618D957124056C700F2B8FE /* NameToDIE.h */, @@ -3501,7 +3498,6 @@ 26274FA714030F79006BA130 /* DynamicLoaderDarwinKernel.cpp in Sources */, 94FA3DE01405D50400833217 /* ValueObjectConstResultChild.cpp in Sources */, 949ADF031406F648004833E1 /* ValueObjectConstResultImpl.cpp in Sources */, - 26A0DA4E140F7226006DA411 /* HashedNameToDIE.cpp in Sources */, B27318421416AC12006039C8 /* WatchpointList.cpp in Sources */, 26E152261419CAD4007967D0 /* ObjectFilePECOFF.cpp in Sources */, B2462247141AD37D00F3D409 /* OptionGroupWatchpoint.cpp in Sources */, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp deleted file mode 100644 index bc258e100d7..00000000000 --- a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp +++ /dev/null @@ -1,298 +0,0 @@ -//===-- HashedNameToDIE.cpp -------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "HashedNameToDIE.h" -#include "lldb/Core/ConstString.h" -#include "lldb/Core/DataExtractor.h" -#include "lldb/Core/Stream.h" -#include "lldb/Core/StreamString.h" -#include "lldb/Core/RegularExpression.h" -#include "lldb/Symbol/ObjectFile.h" - -#include "DWARFCompileUnit.h" -#include "DWARFDebugInfo.h" -#include "DWARFDebugInfoEntry.h" -#include "DWARFDefines.h" -#include "SymbolFileDWARF.h" -using namespace lldb; -using namespace lldb_private; - -static uint32_t -dl_new_hash (const char *s) -{ - uint32_t h = 5381; - - for (unsigned char c = *s; c; c = *++s) - h = ((h << 5) + h) + c; - - return h; -} - - -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.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); - bucket_count = data.GetU32 (&offset); - hashes_count = data.GetU32 (&offset); - prologue_length = data.GetU32 (&offset); - return offset; -} - -void -HashedNameToDIE::DWARF::Header::Dump (Stream &s) -{ - 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) - { - s.Printf ("dwarf_prologue.atom[%zi] = %17s %s\n", - i, - GetAtomTypeName (atoms[i].type), - DW_FORM_value_to_name(atoms[i].form)); - } -} - -uint32_t -HashedNameToDIE::DWARF::Prologue::Read (const DataExtractor &data, uint32_t offset) -{ - Clear(); - die_base_offset = data.GetU32 (&offset); - Atom atom; - while (offset != UINT32_MAX) - { - 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 () -{ -} - -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) - { - if (name_cstr && name_cstr[0]) - { - // Hash the C string - const uint32_t name_hash = dl_new_hash (name_cstr); - - const uint32_t bucket_count = m_header.bucket_count; - const uint32_t hashes_count = m_header.bucket_count; - // Find the correct bucket for the using the hash value - const uint32_t bucket_idx = name_hash % bucket_count; - - // Calculate the offset for the bucket entry for the bucket index - uint32_t offset = GetOffsetOfBucketEntry (bucket_idx); - - // Extract the bucket entry which is a hash index. If the hash index - // is UINT32_MAX, then the bucket is empty. If it isn't, it is the - // index of the hash in the hashes array. We will then iterate through - // all hashes as long as they match "bucket_idx" which was calculated - // above - uint32_t hash_idx = m_data.GetU32 (&offset); - if (hash_idx != UINT32_MAX) - { - uint32_t hash_offset = GetOffsetOfHashValue (hash_idx); - - const size_t initial_size = die_ofsets.size(); - uint32_t hash; - while (((hash = m_data.GetU32 (&hash_offset)) % bucket_count) == bucket_idx) - { - if (hash_idx >= hashes_count) - break; - - if (hash == name_hash) - { - // 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 (hash_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) - { - // 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)); - } - } - } - } - ++hash_idx; - } - - return die_ofsets.size() - initial_size; - } - } - } - return 0; -} - -void -HashedNameToDIE::MemoryTable::Dump (Stream &s) -{ - if (m_header.version == 1) - { - if (m_is_apple_names) - s.PutCString (".apple_names contents:\n"); - else - s.PutCString (".apple_types contents:\n"); - - m_header.Dump (s); - uint32_t empty_bucket_count = 0; - uint32_t hash_collisions = 0; - uint32_t hash_idx_offset = GetOffsetOfBucketEntry (0); - const uint32_t bucket_count = m_header.bucket_count; - const uint32_t hashes_count = m_header.hashes_count; - for (uint32_t bucket_idx=0; bucket_idx<bucket_count; ++bucket_idx) - { - uint32_t hash_idx = m_data.GetU32 (&hash_idx_offset); - s.Printf("bucket[%u] ", bucket_idx); - - if (hash_idx != UINT32_MAX) - { - s.Printf(" => hash[%u]\n", hash_idx); - - uint32_t hash_offset = GetOffsetOfHashValue (hash_idx); - uint32_t data_offset = GetOffsetOfHashDataOffset (hash_idx); - - uint32_t hash; - while (((hash = m_data.GetU32 (&hash_offset)) % bucket_count) == bucket_idx) - { - if (hash_idx >= hashes_count) - break; - - uint32_t hash_data_offset = m_data.GetU32 (&data_offset); - s.Printf(" hash[%u] = 0x%8.8x\n", hash_idx, hash); - - uint32_t string_count = 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(" str[%u] = 0x%8.8x \"%s\", dies[%u] = {", - string_count, - strp_offset, - m_string_table.PeekCStr(strp_offset), - num_die_offsets); - ++string_count; - - for (uint32_t die_idx=0; die_idx<num_die_offsets; ++die_idx) - { - const uint32_t die_offset = m_data.GetU32 (&hash_data_offset); - s.Printf(" 0x%8.8x", die_offset); - } - s.PutCString (" }\n"); - } - if (string_count > 1) - ++hash_collisions; - } - } - else - { - s.PutCString(" EMPTY\n"); - ++empty_bucket_count; - } - s.EOL(); - } - s.EOL(); - s.Printf ("%u of %u buckets empty (%2.1f%%)\n", empty_bucket_count, 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/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h index 81da55a13b2..d3b83e0bcfa 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h @@ -14,262 +14,10 @@ #include "lldb/lldb-defines.h" #include "lldb/Core/dwarf.h" #include "lldb/Core/RegularExpression.h" +#include "lldb/Core/MappedHash.h" class SymbolFileDWARF; -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 - { - 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 - 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_function (eHashFunctionDJB), - 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(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); - }; - - struct DWARF - { - 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)); - } - - 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) - { - } - - virtual - ~Header () - { - } - - Prologue dwarf_prologue; - - virtual void - Dump (lldb_private::Stream &s); - - virtual uint32_t - Read (const lldb_private::DataExtractor &data, uint32_t offset); - }; - - }; - - - class MemoryTable - { - public: - - MemoryTable (SymbolFileDWARF *dwarf, - const lldb_private::DataExtractor &data, - bool is_apple_names); - - ~MemoryTable () - { - } - - bool - Initialize (); - - bool - IsValid () const - { - return m_header.version > 0; - } - - 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; - }; -}; - -#include "lldb/Core/MappedHash.h" - struct DWARFMappedHash { typedef std::vector<uint32_t> DIEArray; @@ -277,23 +25,21 @@ struct DWARFMappedHash 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 + eAtomTypeDIEOffset = 1u, // DIE offset, check form for encoding + eAtomTypeCUOffset = 2u, // DIE offset of the compiler unit header that contains the item in question + eAtomTypeTag = 3u, // DW_TAG_xxx value, should be encoded as DW_FORM_data1 (if no tags exceed 255) or DW_FORM_data2 + eAtomTypeNameFlags = 4u, // Flags from enum NameFlags + eAtomTypeTypeFlags = 5u, // Flags from enum TypeFlags }; - + struct Atom { uint16_t type; dw_form_t form; Atom (uint16_t t = eAtomTypeNULL, dw_form_t f = 0) : - type (t), - form (f) + type (t), + form (f) { } }; @@ -307,10 +53,8 @@ struct DWARFMappedHash 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 eAtomTypeCUOffset: return "cu-offset"; case eAtomTypeTag: return "die-tag"; case eAtomTypeNameFlags: return "name-flags"; case eAtomTypeTypeFlags: return "type-flags"; @@ -329,7 +73,6 @@ struct DWARFMappedHash // 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)); } @@ -351,14 +94,26 @@ struct DWARFMappedHash Read (const lldb_private::DataExtractor &data, uint32_t offset) { die_base_offset = data.GetU32 (&offset); - Atom atom; - while (offset != UINT32_MAX) + + const uint32_t atom_count = data.GetU32 (&offset); + if (atom_count == 0x00060003u) { - atom.type = data.GetU16 (&offset); - atom.form = data.GetU16 (&offset); - if (atom.type == eAtomTypeNULL) - break; - atoms.push_back(atom); + // Old format, deal with contents of old pre-release format + while (data.GetU32(&offset)) + /* do nothing */; + + // Hardcode to the only know value for now. + atoms.push_back (Atom(eAtomTypeDIEOffset, DW_FORM_data4)); + } + else + { + Atom atom; + for (uint32_t i=0; i<atom_count; ++i) + { + atom.type = data.GetU16 (&offset); + atom.form = data.GetU16 (&offset); + atoms.push_back(atom); + } } return offset; } @@ -371,7 +126,7 @@ struct DWARFMappedHash { // 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)); + return sizeof(die_base_offset) + sizeof(uint32_t) + atoms.size() * sizeof(Atom); } }; @@ -477,11 +232,11 @@ struct DWARFMappedHash MemoryTable (lldb_private::DataExtractor &table_data, const lldb_private::DataExtractor &string_table, - bool is_apple_names) : + const char *name) : MappedHash::MemoryTable<uint32_t, Header, DIEArray> (table_data), m_data (table_data), m_string_table (string_table), - m_is_apple_names (is_apple_names) + m_name (name) { } @@ -668,7 +423,7 @@ struct DWARFMappedHash 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 + std::string m_name; }; }; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 0bbb27fa0b8..89af5bcb580 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -194,6 +194,7 @@ SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) : m_namespace_index(), m_indexed (false), m_is_external_ast_source (false), + m_using_apple_tables (false), m_ranges(), m_unique_ast_type_map () { @@ -260,23 +261,29 @@ SymbolFileDWARF::InitializeObject() get_apple_names_data(); if (m_data_apple_names.GetByteSize() > 0) { - m_apple_names_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_names, get_debug_str_data(), true)); - if (!m_apple_names_ap->IsValid()) + m_apple_names_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_names, 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.GetByteSize() > 0) { - m_apple_types_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_types, get_debug_str_data(), false)); - if (!m_apple_types_ap->IsValid()) + m_apple_types_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_types, 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.GetByteSize() > 0) { - m_apple_namespaces_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_namespaces, get_debug_str_data(), false)); - if (!m_apple_namespaces_ap->IsValid()) + m_apple_namespaces_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_namespaces, get_debug_str_data(), ".apple_namespaces")); + if (m_apple_namespaces_ap->IsValid()) + m_using_apple_tables = true; + else m_apple_namespaces_ap.reset(); } @@ -2068,16 +2075,19 @@ SymbolFileDWARF::FindGlobalVariables (const ConstString &name, const lldb_privat DIEArray die_offsets; - if (m_apple_names_ap.get()) + if (m_using_apple_tables) { - const char *name_cstr = name.GetCString(); - const char *base_name_start; - const char *base_name_end = NULL; - - if (!CPPLanguageRuntime::StripNamespacesFromVariableName(name_cstr, base_name_start, base_name_end)) - base_name_start = name_cstr; + if (m_apple_names_ap.get()) + { + const char *name_cstr = name.GetCString(); + const char *base_name_start; + const char *base_name_end = NULL; - m_apple_names_ap->FindByName (base_name_start, die_offsets); + if (!CPPLanguageRuntime::StripNamespacesFromVariableName(name_cstr, base_name_start, base_name_end)) + base_name_start = name_cstr; + + m_apple_names_ap->FindByName (base_name_start, die_offsets); + } } else { @@ -2147,9 +2157,10 @@ SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append DIEArray die_offsets; - if (m_apple_names_ap.get()) + if (m_using_apple_tables) { - m_apple_names_ap->AppendAllDIEsThatMatchingRegex (regex, die_offsets); + if (m_apple_names_ap.get()) + m_apple_names_ap->AppendAllDIEsThatMatchingRegex (regex, die_offsets); } else { @@ -2467,90 +2478,94 @@ SymbolFileDWARF::FindFunctions (const ConstString &name, return 0; DWARFCompileUnit *dwarf_cu = NULL; - if (m_apple_names_ap.get()) + if (m_using_apple_tables) { - DIEArray die_offsets; - - uint32_t num_matches = 0; - - if (effective_name_type_mask & eFunctionNameTypeFull) + if (m_apple_names_ap.get()) { - // 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 DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu); - if (die) - { - if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die)) - continue; - - ResolveFunction (dwarf_cu, die, sc_list); - } - } - } - else - { - if (effective_name_type_mask & eFunctionNameTypeSelector) + + DIEArray die_offsets; + + uint32_t num_matches = 0; + + if (effective_name_type_mask & eFunctionNameTypeFull) { - if (namespace_decl && *namespace_decl) - return 0; // no selectors in namespaces - + // 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); - // 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 DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu); + const DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu); if (die) { - const char *die_name = die->GetName(this, dwarf_cu); - if (ObjCLanguageRuntime::IsPossibleObjCMethodName(die_name)) - ResolveFunction (dwarf_cu, die, sc_list); + if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die)) + continue; + + ResolveFunction (dwarf_cu, die, sc_list); } } - die_offsets.clear(); } - - if (effective_name_type_mask & eFunctionNameTypeMethod - || effective_name_type_mask & eFunctionNameTypeBase) - { - if ((effective_name_type_mask & eFunctionNameTypeMethod) && - (namespace_decl && *namespace_decl)) - return 0; // no methods in namespaces - - // 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: - std::string base_name(base_name_start, base_name_end - base_name_start); - num_matches = m_apple_names_ap->FindByName (base_name.c_str(), die_offsets); + else + { + if (effective_name_type_mask & eFunctionNameTypeSelector) + { + if (namespace_decl && *namespace_decl) + 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 DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu); + if (die) + { + const char *die_name = die->GetName(this, dwarf_cu); + if (ObjCLanguageRuntime::IsPossibleObjCMethodName(die_name)) + ResolveFunction (dwarf_cu, die, sc_list); + } + } + die_offsets.clear(); + } - for (uint32_t i = 0; i < num_matches; i++) + if (effective_name_type_mask & eFunctionNameTypeMethod + || effective_name_type_mask & eFunctionNameTypeBase) { - const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu); - if (die) + if ((effective_name_type_mask & eFunctionNameTypeMethod) && + (namespace_decl && *namespace_decl)) + return 0; // no methods in namespaces + + // 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: + std::string base_name(base_name_start, base_name_end - base_name_start); + num_matches = m_apple_names_ap->FindByName (base_name.c_str(), die_offsets); + + for (uint32_t i = 0; i < num_matches; i++) { - if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die)) - continue; - - if (!FunctionDieMatchesPartialName(die, - dwarf_cu, - effective_name_type_mask, - name_cstr, - base_name_start, - base_name_end)) - continue; + const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu); + if (die) + { + if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die)) + continue; - // If we get to here, the die is good, and we should add it: - ResolveFunction (dwarf_cu, die, sc_list); + if (!FunctionDieMatchesPartialName(die, + dwarf_cu, + effective_name_type_mask, + name_cstr, + base_name_start, + base_name_end)) + continue; + + // If we get to here, the die is good, and we should add it: + ResolveFunction (dwarf_cu, die, sc_list); + } } + die_offsets.clear(); } - die_offsets.clear(); } } } @@ -2660,9 +2675,10 @@ SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, Symb // we are appending the results to a variable list. uint32_t original_size = sc_list.GetSize(); - if (m_apple_names_ap.get()) + if (m_using_apple_tables) { - FindFunctions (regex, *m_apple_names_ap, sc_list); + if (m_apple_names_ap.get()) + FindFunctions (regex, *m_apple_names_ap, sc_list); } else { @@ -2739,10 +2755,13 @@ SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, con DIEArray die_offsets; - if (m_apple_types_ap.get()) + if (m_using_apple_tables) { - const char *name_cstr = name.GetCString(); - m_apple_types_ap->FindByName (name_cstr, die_offsets); + if (m_apple_types_ap.get()) + { + const char *name_cstr = name.GetCString(); + m_apple_types_ap->FindByName (name_cstr, die_offsets); + } } else { @@ -2810,10 +2829,13 @@ SymbolFileDWARF::FindNamespace (const SymbolContext& sc, // Index if we already haven't to make sure the compile units // get indexed and make their global DIE index list - if (m_apple_namespaces_ap.get()) + if (m_using_apple_tables) { - const char *name_cstr = name.GetCString(); - m_apple_namespaces_ap->FindByName (name_cstr, die_offsets); + if (m_apple_namespaces_ap.get()) + { + const char *name_cstr = name.GetCString(); + m_apple_namespaces_ap->FindByName (name_cstr, die_offsets); + } } else { @@ -3500,10 +3522,13 @@ SymbolFileDWARF::FindDefinitionTypeForDIE (DWARFCompileUnit* cu, DIEArray die_offsets; - if (m_apple_types_ap.get()) + if (m_using_apple_tables) { - const char *name_cstr = type_name.GetCString(); - m_apple_types_ap->FindByName (name_cstr, die_offsets); + if (m_apple_types_ap.get()) + { + const char *name_cstr = type_name.GetCString(); + m_apple_types_ap->FindByName (name_cstr, die_offsets); + } } else { @@ -4702,12 +4727,12 @@ SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc) DWARFCompileUnit* match_dwarf_cu = NULL; const DWARFDebugInfoEntry* die = NULL; DIEArray die_offsets; - if (m_apple_names_ap.get()) + if (m_using_apple_tables) { - // TODO: implement finding all items in - m_apple_names_ap->AppendAllDIEsInRange (dwarf_cu->GetOffset(), - dwarf_cu->GetNextCompileUnitOffset(), - die_offsets); + if (m_apple_names_ap.get()) + m_apple_names_ap->AppendAllDIEsInRange (dwarf_cu->GetOffset(), + dwarf_cu->GetNextCompileUnitOffset(), + die_offsets); } else { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index 89db5f5700a..c3fb5d1145b 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -464,7 +464,8 @@ protected: NameToDIE m_type_index; // All type DIE offsets NameToDIE m_namespace_index; // All type DIE offsets bool m_indexed:1, - m_is_external_ast_source:1; + m_is_external_ast_source:1, + m_using_apple_tables:1; std::auto_ptr<DWARFDebugRanges> m_ranges; UniqueDWARFASTTypeMap m_unique_ast_type_map; |

