aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/lldb/lldb-enumerations.h4
-rw-r--r--lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme6
-rw-r--r--source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp16
-rw-r--r--source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp323
-rw-r--r--source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h322
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp22
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h10
-rw-r--r--source/Symbol/ObjectFile.cpp4
-rw-r--r--source/lldb.cpp4
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";
}