[Lldb-commits] [lldb] r140702 - in /lldb/trunk: include/lldb/lldb-enumerations.h lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h source/Symbol/ObjectFile.cpp source/lldb.cpp

Greg Clayton gclayton at apple.com
Wed Sep 28 10:06:41 PDT 2011


Author: gclayton
Date: Wed Sep 28 12:06:40 2011
New Revision: 140702

URL: http://llvm.org/viewvc/llvm-project?rev=140702&view=rev
Log:
Convert over to the latest and greatest on disc accelerator
hash tables. Renamed the DWARF sections to ".apple_names" and
".apple_types" until we get more buy in from other vendors.


Modified:
    lldb/trunk/include/lldb/lldb-enumerations.h
    lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme
    lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
    lldb/trunk/source/Symbol/ObjectFile.cpp
    lldb/trunk/source/lldb.cpp

Modified: lldb/trunk/include/lldb/lldb-enumerations.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=140702&r1=140701&r2=140702&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-enumerations.h (original)
+++ lldb/trunk/include/lldb/lldb-enumerations.h Wed Sep 28 12:06:40 2011
@@ -475,8 +475,8 @@
         eSectionTypeDWARFDebugPubTypes,
         eSectionTypeDWARFDebugRanges,
         eSectionTypeDWARFDebugStr,
-        eSectionTypeDWARFDebugNames,
-        eSectionTypeDWARFDebugTypes,
+        eSectionTypeDWARFAppleNames,
+        eSectionTypeDWARFAppleTypes,
         eSectionTypeEHFrame,
         eSectionTypeOther
         

Modified: lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme?rev=140702&r1=140701&r2=140702&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme (original)
+++ lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme Wed Sep 28 12:06:40 2011
@@ -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"

Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp?rev=140702&r1=140701&r2=140702&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp Wed Sep 28 12:06:40 2011
@@ -255,8 +255,8 @@
                     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 @@
                         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 @@
                             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)

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp?rev=140702&r1=140701&r2=140702&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp Wed Sep 28 12:06:40 2011
@@ -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 @@
     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);
+    }
 }
 
 

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h?rev=140702&r1=140701&r2=140702&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h Wed Sep 28 12:06:40 2011
@@ -21,95 +21,269 @@
 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 ()
+    struct DWARF
     {
-    }
-    
-    bool
-    IsValid () const
-    {
-        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 ()
+            {            
+            }
+
+            Prologue dwarf_prologue;
+            
+            virtual void
+            Dump (lldb_private::Stream &s);        
+            
+            virtual uint32_t
+            Read (const lldb_private::DataExtractor &data, uint32_t offset);
+        };
+        
+    };
+    
 
-    uint32_t
-    GetOffsetOfHashDataOffset (uint32_t idx) const
+    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);
-
-    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
+        Initialize ();
+
+        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_

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=140702&r1=140701&r2=140702&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Wed Sep 28 12:06:40 2011
@@ -171,12 +171,12 @@
     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 @@
     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 @@
 }
 
 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 @@
     // 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);

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h?rev=140702&r1=140701&r2=140702&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h Wed Sep 28 12:06:40 2011
@@ -164,8 +164,8 @@
     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 @@
     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

Modified: lldb/trunk/source/Symbol/ObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ObjectFile.cpp?rev=140702&r1=140701&r2=140702&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ObjectFile.cpp (original)
+++ lldb/trunk/source/Symbol/ObjectFile.cpp Wed Sep 28 12:06:40 2011
@@ -221,8 +221,8 @@
                     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;
                     }

Modified: lldb/trunk/source/lldb.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/lldb.cpp?rev=140702&r1=140701&r2=140702&view=diff
==============================================================================
--- lldb/trunk/source/lldb.cpp (original)
+++ lldb/trunk/source/lldb.cpp Wed Sep 28 12:06:40 2011
@@ -259,8 +259,8 @@
     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";
     }





More information about the lldb-commits mailing list