summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Core/MappedHash.h14
-rw-r--r--lldb/lldb.xcodeproj/project.pbxproj4
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp298
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h311
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp223
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h3
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;
OpenPOWER on IntegriCloud