forked from OSchip/llvm-project
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. llvm-svn: 140702
This commit is contained in:
parent
ef8e4efff8
commit
1767440a72
|
@ -475,8 +475,8 @@ namespace lldb {
|
|||
eSectionTypeDWARFDebugPubTypes,
|
||||
eSectionTypeDWARFDebugRanges,
|
||||
eSectionTypeDWARFDebugStr,
|
||||
eSectionTypeDWARFDebugNames,
|
||||
eSectionTypeDWARFDebugTypes,
|
||||
eSectionTypeDWARFAppleNames,
|
||||
eSectionTypeDWARFAppleTypes,
|
||||
eSectionTypeEHFrame,
|
||||
eSectionTypeOther
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,40 +34,134 @@ dl_new_hash (const char *s)
|
|||
return h;
|
||||
}
|
||||
|
||||
HashedNameToDIE::HashedNameToDIE (SymbolFileDWARF *dwarf, const DataExtractor &data) :
|
||||
m_dwarf (dwarf),
|
||||
|
||||
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::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 ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
HashedNameToDIE::Initialize()
|
||||
bool
|
||||
HashedNameToDIE::MemoryTable::Initialize ()
|
||||
{
|
||||
uint32_t offset = 0;
|
||||
m_header.version = m_data.GetU16(&offset);
|
||||
if (m_header.version)
|
||||
{
|
||||
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);
|
||||
}
|
||||
offset = m_header.Read (m_data, offset);
|
||||
return m_header.version == 1;
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
HashedNameToDIE::Find (const ConstString &name, DIEArray &die_ofsets) const
|
||||
HashedNameToDIE::MemoryTable::Find (const char *name_cstr, DIEArray &die_ofsets) const
|
||||
{
|
||||
if (m_header.version == 1)
|
||||
{
|
||||
const size_t initial_size = die_ofsets.size();
|
||||
const char *name_cstr = name.GetCString();
|
||||
if (name_cstr && name_cstr[0])
|
||||
{
|
||||
// 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;
|
||||
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);
|
||||
|
@ -95,12 +190,21 @@ HashedNameToDIE::Find (const ConstString &name, DIEArray &die_ofsets) const
|
|||
// 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);
|
||||
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_dwarf->get_debug_str_data().PeekCStr(str_offset);
|
||||
const char *cstr_name = m_string_table.PeekCStr(str_offset);
|
||||
if (cstr_name)
|
||||
{
|
||||
if (strcmp(name_cstr, cstr_name) == 0)
|
||||
|
@ -117,31 +221,88 @@ HashedNameToDIE::Find (const ConstString &name, DIEArray &die_ofsets) const
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -21,34 +21,214 @@ 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;
|
||||
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
|
||||
|
||||
Header() :
|
||||
version(0),
|
||||
hash_type (0),
|
||||
hash_index_bitsize (0),
|
||||
num_buckets(0),
|
||||
num_hashes (0),
|
||||
die_offset_base(0)
|
||||
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);
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
HashedNameToDIE (SymbolFileDWARF *dwarf,
|
||||
const lldb_private::DataExtractor &data);
|
||||
|
||||
~HashedNameToDIE ()
|
||||
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
|
||||
{
|
||||
|
@ -64,17 +244,17 @@ public:
|
|||
uint32_t
|
||||
GetOffsetOfBucketEntry (uint32_t idx) const
|
||||
{
|
||||
if (idx < m_header.num_buckets)
|
||||
return sizeof(Header) + 4 * idx;
|
||||
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.num_hashes)
|
||||
return sizeof(Header) +
|
||||
4 * m_header.num_buckets +
|
||||
if (idx < m_header.hashes_count)
|
||||
return m_header.GetByteSize() +
|
||||
4 * m_header.bucket_count +
|
||||
4 * idx;
|
||||
return UINT32_MAX;
|
||||
}
|
||||
|
@ -82,34 +262,28 @@ public:
|
|||
uint32_t
|
||||
GetOffsetOfHashDataOffset (uint32_t idx) const
|
||||
{
|
||||
if (idx < m_header.num_hashes)
|
||||
if (idx < m_header.hashes_count)
|
||||
{
|
||||
return sizeof(Header) +
|
||||
4 * m_header.num_buckets +
|
||||
4 * m_header.num_hashes +
|
||||
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);
|
||||
Dump (lldb_private::Stream &s);
|
||||
|
||||
size_t
|
||||
Find (const lldb_private::ConstString &name,
|
||||
DIEArray &die_ofsets) const;
|
||||
Find (const char *name, DIEArray &die_ofsets) const;
|
||||
|
||||
size_t
|
||||
Find (const lldb_private::RegularExpression& regex,
|
||||
DIEArray &die_ofsets) const;
|
||||
|
||||
void
|
||||
Initialize();
|
||||
|
||||
protected:
|
||||
SymbolFileDWARF *m_dwarf;
|
||||
protected:
|
||||
const lldb_private::DataExtractor &m_data;
|
||||
Header m_header;
|
||||
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_
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue