Enable all the new accelerator tables if they are present and don't manually
index the DWARF. Also fixed an issue with memory accelerator tables with a size of 1 where we would loop infinitely. Added support for parsing the new .apple_namespaces section which gives us a memory hash table for looking up namespaces. llvm-svn: 141128
This commit is contained in:
parent
6c98dfd0f4
commit
7f99513e8f
|
@ -477,6 +477,7 @@ namespace lldb {
|
||||||
eSectionTypeDWARFDebugStr,
|
eSectionTypeDWARFDebugStr,
|
||||||
eSectionTypeDWARFAppleNames,
|
eSectionTypeDWARFAppleNames,
|
||||||
eSectionTypeDWARFAppleTypes,
|
eSectionTypeDWARFAppleTypes,
|
||||||
|
eSectionTypeDWARFAppleNamespaces,
|
||||||
eSectionTypeEHFrame,
|
eSectionTypeEHFrame,
|
||||||
eSectionTypeOther
|
eSectionTypeOther
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,7 @@
|
||||||
26744EF31338317700EF765A /* GDBRemoteCommunicationServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26744EEF1338317700EF765A /* GDBRemoteCommunicationServer.cpp */; };
|
26744EF31338317700EF765A /* GDBRemoteCommunicationServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26744EEF1338317700EF765A /* GDBRemoteCommunicationServer.cpp */; };
|
||||||
267C012B136880DF006E963E /* OptionGroupValueObjectDisplay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 267C012A136880DF006E963E /* OptionGroupValueObjectDisplay.cpp */; };
|
267C012B136880DF006E963E /* OptionGroupValueObjectDisplay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 267C012A136880DF006E963E /* OptionGroupValueObjectDisplay.cpp */; };
|
||||||
267C01371368C49C006E963E /* OptionGroupOutputFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BCFC531368B3E4006DC050 /* OptionGroupOutputFile.cpp */; };
|
267C01371368C49C006E963E /* OptionGroupOutputFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BCFC531368B3E4006DC050 /* OptionGroupOutputFile.cpp */; };
|
||||||
|
2682100D143A59AE004BCF2D /* MappedHash.h in Headers */ = {isa = PBXBuildFile; fileRef = 2682100C143A59AE004BCF2D /* MappedHash.h */; };
|
||||||
2686536C1370ACB200D186A3 /* OptionGroupBoolean.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2686536B1370ACB200D186A3 /* OptionGroupBoolean.cpp */; };
|
2686536C1370ACB200D186A3 /* OptionGroupBoolean.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2686536B1370ACB200D186A3 /* OptionGroupBoolean.cpp */; };
|
||||||
268653701370AE7200D186A3 /* OptionGroupUInt64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2686536F1370AE7200D186A3 /* OptionGroupUInt64.cpp */; };
|
268653701370AE7200D186A3 /* OptionGroupUInt64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2686536F1370AE7200D186A3 /* OptionGroupUInt64.cpp */; };
|
||||||
2689000113353DB600698AC0 /* BreakpointResolverAddress.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26D0DD5310FE555900271C65 /* BreakpointResolverAddress.cpp */; };
|
2689000113353DB600698AC0 /* BreakpointResolverAddress.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26D0DD5310FE555900271C65 /* BreakpointResolverAddress.cpp */; };
|
||||||
|
@ -742,6 +743,7 @@
|
||||||
2676A094119C93C8008A98EF /* StringExtractorGDBRemote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StringExtractorGDBRemote.h; path = source/Utility/StringExtractorGDBRemote.h; sourceTree = "<group>"; };
|
2676A094119C93C8008A98EF /* StringExtractorGDBRemote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StringExtractorGDBRemote.h; path = source/Utility/StringExtractorGDBRemote.h; sourceTree = "<group>"; };
|
||||||
267C0128136880C7006E963E /* OptionGroupValueObjectDisplay.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OptionGroupValueObjectDisplay.h; path = include/lldb/Interpreter/OptionGroupValueObjectDisplay.h; sourceTree = "<group>"; };
|
267C0128136880C7006E963E /* OptionGroupValueObjectDisplay.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OptionGroupValueObjectDisplay.h; path = include/lldb/Interpreter/OptionGroupValueObjectDisplay.h; sourceTree = "<group>"; };
|
||||||
267C012A136880DF006E963E /* OptionGroupValueObjectDisplay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OptionGroupValueObjectDisplay.cpp; path = source/Interpreter/OptionGroupValueObjectDisplay.cpp; sourceTree = "<group>"; };
|
267C012A136880DF006E963E /* OptionGroupValueObjectDisplay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OptionGroupValueObjectDisplay.cpp; path = source/Interpreter/OptionGroupValueObjectDisplay.cpp; sourceTree = "<group>"; };
|
||||||
|
2682100C143A59AE004BCF2D /* MappedHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MappedHash.h; path = include/lldb/Core/MappedHash.h; sourceTree = "<group>"; };
|
||||||
2682F16A115EDA0D00CCFF99 /* PseudoTerminal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PseudoTerminal.cpp; path = source/Utility/PseudoTerminal.cpp; sourceTree = "<group>"; };
|
2682F16A115EDA0D00CCFF99 /* PseudoTerminal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PseudoTerminal.cpp; path = source/Utility/PseudoTerminal.cpp; sourceTree = "<group>"; };
|
||||||
2682F16B115EDA0D00CCFF99 /* PseudoTerminal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PseudoTerminal.h; path = include/lldb/Utility/PseudoTerminal.h; sourceTree = "<group>"; };
|
2682F16B115EDA0D00CCFF99 /* PseudoTerminal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PseudoTerminal.h; path = include/lldb/Utility/PseudoTerminal.h; sourceTree = "<group>"; };
|
||||||
2682F284115EF3A700CCFF99 /* SBError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBError.cpp; path = source/API/SBError.cpp; sourceTree = "<group>"; };
|
2682F284115EF3A700CCFF99 /* SBError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBError.cpp; path = source/API/SBError.cpp; sourceTree = "<group>"; };
|
||||||
|
@ -2121,6 +2123,7 @@
|
||||||
26BC7E7F10F1B85900F91463 /* Log.cpp */,
|
26BC7E7F10F1B85900F91463 /* Log.cpp */,
|
||||||
26BC7D6910F1B77400F91463 /* Mangled.h */,
|
26BC7D6910F1B77400F91463 /* Mangled.h */,
|
||||||
26BC7E8010F1B85900F91463 /* Mangled.cpp */,
|
26BC7E8010F1B85900F91463 /* Mangled.cpp */,
|
||||||
|
2682100C143A59AE004BCF2D /* MappedHash.h */,
|
||||||
26BC7D6A10F1B77400F91463 /* Module.h */,
|
26BC7D6A10F1B77400F91463 /* Module.h */,
|
||||||
26BC7E8110F1B85900F91463 /* Module.cpp */,
|
26BC7E8110F1B85900F91463 /* Module.cpp */,
|
||||||
26BC7D6B10F1B77400F91463 /* ModuleChild.h */,
|
26BC7D6B10F1B77400F91463 /* ModuleChild.h */,
|
||||||
|
@ -2885,6 +2888,7 @@
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
496B015B1406DEB100F830D5 /* IRInterpreter.h in Headers */,
|
496B015B1406DEB100F830D5 /* IRInterpreter.h in Headers */,
|
||||||
|
2682100D143A59AE004BCF2D /* MappedHash.h in Headers */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -257,6 +257,7 @@ ObjectFileMachO::GetAddressClass (lldb::addr_t file_addr)
|
||||||
case eSectionTypeDWARFDebugStr: return eAddressClassDebug;
|
case eSectionTypeDWARFDebugStr: return eAddressClassDebug;
|
||||||
case eSectionTypeDWARFAppleNames: return eAddressClassDebug;
|
case eSectionTypeDWARFAppleNames: return eAddressClassDebug;
|
||||||
case eSectionTypeDWARFAppleTypes: return eAddressClassDebug;
|
case eSectionTypeDWARFAppleTypes: return eAddressClassDebug;
|
||||||
|
case eSectionTypeDWARFAppleNamespaces: return eAddressClassDebug;
|
||||||
case eSectionTypeEHFrame: return eAddressClassRuntime;
|
case eSectionTypeEHFrame: return eAddressClassRuntime;
|
||||||
case eSectionTypeOther: return eAddressClassUnknown;
|
case eSectionTypeOther: return eAddressClassUnknown;
|
||||||
}
|
}
|
||||||
|
@ -509,6 +510,7 @@ ObjectFileMachO::ParseSections ()
|
||||||
static ConstString g_sect_name_dwarf_debug_str ("__debug_str");
|
static ConstString g_sect_name_dwarf_debug_str ("__debug_str");
|
||||||
static ConstString g_sect_name_dwarf_apple_names ("__apple_names");
|
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_dwarf_apple_types ("__apple_types");
|
||||||
|
static ConstString g_sect_name_dwarf_apple_namespaces ("__apple_namespac");
|
||||||
static ConstString g_sect_name_eh_frame ("__eh_frame");
|
static ConstString g_sect_name_eh_frame ("__eh_frame");
|
||||||
static ConstString g_sect_name_DATA ("__DATA");
|
static ConstString g_sect_name_DATA ("__DATA");
|
||||||
static ConstString g_sect_name_TEXT ("__TEXT");
|
static ConstString g_sect_name_TEXT ("__TEXT");
|
||||||
|
@ -541,6 +543,8 @@ ObjectFileMachO::ParseSections ()
|
||||||
sect_type = eSectionTypeDWARFAppleNames;
|
sect_type = eSectionTypeDWARFAppleNames;
|
||||||
else if (section_name == g_sect_name_dwarf_apple_types)
|
else if (section_name == g_sect_name_dwarf_apple_types)
|
||||||
sect_type = eSectionTypeDWARFAppleTypes;
|
sect_type = eSectionTypeDWARFAppleTypes;
|
||||||
|
else if (section_name == g_sect_name_dwarf_apple_namespaces)
|
||||||
|
sect_type = eSectionTypeDWARFAppleNamespaces;
|
||||||
else if (section_name == g_sect_name_objc_selrefs)
|
else if (section_name == g_sect_name_objc_selrefs)
|
||||||
sect_type = eSectionTypeDataCStringPointers;
|
sect_type = eSectionTypeDataCStringPointers;
|
||||||
else if (section_name == g_sect_name_objc_msgrefs)
|
else if (section_name == g_sect_name_objc_msgrefs)
|
||||||
|
|
|
@ -786,21 +786,20 @@ DWARFCompileUnit::Index (const uint32_t cu_idx,
|
||||||
if (ObjCLanguageRuntime::IsPossibleObjCMethodName(name))
|
if (ObjCLanguageRuntime::IsPossibleObjCMethodName(name))
|
||||||
{
|
{
|
||||||
ConstString objc_class_name;
|
ConstString objc_class_name;
|
||||||
ConstString objc_method_name;
|
ConstString objc_selector_name;
|
||||||
ConstString objc_base_name;
|
ConstString objc_fullname_no_category_name;
|
||||||
if (ObjCLanguageRuntime::ParseMethodName (name,
|
if (ObjCLanguageRuntime::ParseMethodName (name,
|
||||||
&objc_class_name,
|
&objc_class_name,
|
||||||
&objc_method_name,
|
&objc_selector_name,
|
||||||
&objc_base_name))
|
&objc_fullname_no_category_name))
|
||||||
{
|
{
|
||||||
objc_class_selectors.Insert(objc_class_name, die.GetOffset());
|
objc_class_selectors.Insert(objc_class_name, die.GetOffset());
|
||||||
|
|
||||||
func_selectors.Insert (objc_method_name, die.GetOffset());
|
func_selectors.Insert (objc_selector_name, die.GetOffset());
|
||||||
|
func_fullnames.Insert (ConstString(name), die.GetOffset());
|
||||||
if (!objc_base_name.IsEmpty())
|
if (objc_fullname_no_category_name)
|
||||||
{
|
{
|
||||||
func_basenames.Insert (objc_base_name, die.GetOffset());
|
func_fullnames.Insert (objc_fullname_no_category_name, die.GetOffset());
|
||||||
func_fullnames.Insert (objc_base_name, die.GetOffset());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,6 +152,7 @@ HashedNameToDIE::MemoryTable::Find (const char *name_cstr, DIEArray &die_ofsets)
|
||||||
const uint32_t name_hash = dl_new_hash (name_cstr);
|
const uint32_t name_hash = dl_new_hash (name_cstr);
|
||||||
|
|
||||||
const uint32_t bucket_count = m_header.bucket_count;
|
const uint32_t bucket_count = m_header.bucket_count;
|
||||||
|
const uint32_t hashes_count = m_header.bucket_count;
|
||||||
// Find the correct bucket for the using the hash value
|
// Find the correct bucket for the using the hash value
|
||||||
const uint32_t bucket_idx = name_hash % bucket_count;
|
const uint32_t bucket_idx = name_hash % bucket_count;
|
||||||
|
|
||||||
|
@ -172,6 +173,9 @@ HashedNameToDIE::MemoryTable::Find (const char *name_cstr, DIEArray &die_ofsets)
|
||||||
uint32_t hash;
|
uint32_t hash;
|
||||||
while (((hash = m_data.GetU32 (&hash_offset)) % bucket_count) == bucket_idx)
|
while (((hash = m_data.GetU32 (&hash_offset)) % bucket_count) == bucket_idx)
|
||||||
{
|
{
|
||||||
|
if (hash_idx >= hashes_count)
|
||||||
|
break;
|
||||||
|
|
||||||
if (hash == name_hash)
|
if (hash == name_hash)
|
||||||
{
|
{
|
||||||
// The hash matches, but we still need to verify that the
|
// The hash matches, but we still need to verify that the
|
||||||
|
@ -232,6 +236,7 @@ HashedNameToDIE::MemoryTable::Dump (Stream &s)
|
||||||
uint32_t hash_collisions = 0;
|
uint32_t hash_collisions = 0;
|
||||||
uint32_t hash_idx_offset = GetOffsetOfBucketEntry (0);
|
uint32_t hash_idx_offset = GetOffsetOfBucketEntry (0);
|
||||||
const uint32_t bucket_count = m_header.bucket_count;
|
const uint32_t bucket_count = m_header.bucket_count;
|
||||||
|
const uint32_t hashes_count = m_header.hashes_count;
|
||||||
for (uint32_t bucket_idx=0; bucket_idx<bucket_count; ++bucket_idx)
|
for (uint32_t bucket_idx=0; bucket_idx<bucket_count; ++bucket_idx)
|
||||||
{
|
{
|
||||||
uint32_t hash_idx = m_data.GetU32 (&hash_idx_offset);
|
uint32_t hash_idx = m_data.GetU32 (&hash_idx_offset);
|
||||||
|
@ -247,6 +252,9 @@ HashedNameToDIE::MemoryTable::Dump (Stream &s)
|
||||||
uint32_t hash;
|
uint32_t hash;
|
||||||
while (((hash = m_data.GetU32 (&hash_offset)) % bucket_count) == bucket_idx)
|
while (((hash = m_data.GetU32 (&hash_offset)) % bucket_count) == bucket_idx)
|
||||||
{
|
{
|
||||||
|
if (hash_idx >= hashes_count)
|
||||||
|
break;
|
||||||
|
|
||||||
uint32_t hash_data_offset = m_data.GetU32 (&data_offset);
|
uint32_t hash_data_offset = m_data.GetU32 (&data_offset);
|
||||||
s.Printf(" hash[%u] = 0x%8.8x\n", hash_idx, hash);
|
s.Printf(" hash[%u] = 0x%8.8x\n", hash_idx, hash);
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "lldb/lldb-defines.h"
|
#include "lldb/lldb-defines.h"
|
||||||
#include "lldb/Core/dwarf.h"
|
#include "lldb/Core/dwarf.h"
|
||||||
|
#include "lldb/Core/RegularExpression.h"
|
||||||
|
|
||||||
class SymbolFileDWARF;
|
class SymbolFileDWARF;
|
||||||
|
|
||||||
|
@ -267,4 +268,396 @@ public:
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#include "lldb/Core/MappedHash.h"
|
||||||
|
|
||||||
|
struct DWARFMappedHash
|
||||||
|
{
|
||||||
|
typedef std::vector<uint32_t> DIEArray;
|
||||||
|
|
||||||
|
enum AtomType
|
||||||
|
{
|
||||||
|
eAtomTypeNULL = 0u,
|
||||||
|
eAtomTypeHashString = 1u, // String value for hash, use DW_FORM_strp (preferred) or DW_FORM_string
|
||||||
|
eAtomTypeHashLength = 2u, // Length of data for the previous string refered by the last eAtomTypeHashString atom
|
||||||
|
eAtomTypeArraySize = 3u, // A count that specifies a number of atoms that follow this entry, the next atom defines what the atom type for the array is
|
||||||
|
eAtomTypeDIEOffset = 4u, // DIE offset, check form for encoding. If DW_FORM_ref1,2,4,8 or DW_FORM_ref_udata, then this value is added to the prologue
|
||||||
|
eAtomTypeTag = 5u, // DW_TAG_xxx value, should be encoded as DW_FORM_data1 (if no tags exceed 255) or DW_FORM_data2
|
||||||
|
eAtomTypeNameFlags = 6u, // Flags from enum NameFlags
|
||||||
|
eAtomTypeTypeFlags = 7u, // Flags from enum TypeFlags
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Atom
|
||||||
|
{
|
||||||
|
uint16_t type;
|
||||||
|
dw_form_t form;
|
||||||
|
|
||||||
|
Atom (uint16_t t = eAtomTypeNULL, dw_form_t f = 0) :
|
||||||
|
type (t),
|
||||||
|
form (f)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::vector<Atom> AtomArray;
|
||||||
|
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
GetAtomTypeName (uint16_t atom)
|
||||||
|
{
|
||||||
|
switch (atom)
|
||||||
|
{
|
||||||
|
case eAtomTypeNULL: return "NULL";
|
||||||
|
case eAtomTypeHashString: return "hash-string";
|
||||||
|
case eAtomTypeHashLength: return "hash-data-length";
|
||||||
|
case eAtomTypeArraySize: return "array-size";
|
||||||
|
case eAtomTypeDIEOffset: return "die-offset";
|
||||||
|
case eAtomTypeTag: return "die-tag";
|
||||||
|
case eAtomTypeNameFlags: return "name-flags";
|
||||||
|
case eAtomTypeTypeFlags: return "type-flags";
|
||||||
|
}
|
||||||
|
return "<invalid>";
|
||||||
|
}
|
||||||
|
struct Prologue
|
||||||
|
{
|
||||||
|
// DIE offset base so die offsets in hash_data can be CU relative
|
||||||
|
dw_offset_t die_base_offset;
|
||||||
|
AtomArray atoms;
|
||||||
|
|
||||||
|
Prologue (dw_offset_t _die_base_offset = 0) :
|
||||||
|
die_base_offset (_die_base_offset)
|
||||||
|
{
|
||||||
|
// Define an array of DIE offsets by first defining an array,
|
||||||
|
// and then define the atom type for the array, in this case
|
||||||
|
// we have an array of DIE offsets
|
||||||
|
atoms.push_back (Atom(eAtomTypeArraySize, DW_FORM_data4));
|
||||||
|
atoms.push_back (Atom(eAtomTypeDIEOffset, DW_FORM_data4));
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~Prologue()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void
|
||||||
|
Clear ()
|
||||||
|
{
|
||||||
|
die_base_offset = 0;
|
||||||
|
atoms.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// void
|
||||||
|
// Dump (std::ostream* ostrm_ptr);
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
Read (const lldb_private::DataExtractor &data, uint32_t offset)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// virtual void
|
||||||
|
// Write (BinaryStreamBuf &s);
|
||||||
|
|
||||||
|
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 MappedHash::Header<Prologue>
|
||||||
|
{
|
||||||
|
Header (dw_offset_t _die_base_offset = 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual
|
||||||
|
~Header()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual size_t
|
||||||
|
GetByteSize (const HeaderData &header_data)
|
||||||
|
{
|
||||||
|
return header_data.GetByteSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// virtual void
|
||||||
|
// Dump (std::ostream* ostrm_ptr);
|
||||||
|
//
|
||||||
|
virtual uint32_t
|
||||||
|
Read (lldb_private::DataExtractor &data, uint32_t offset)
|
||||||
|
{
|
||||||
|
offset = MappedHash::Header<Prologue>::Read (data, offset);
|
||||||
|
if (offset != UINT32_MAX)
|
||||||
|
{
|
||||||
|
offset = header_data.Read (data, offset);
|
||||||
|
}
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// virtual void
|
||||||
|
// Write (BinaryStreamBuf &s);
|
||||||
|
};
|
||||||
|
|
||||||
|
// class ExportTable
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// ExportTable ();
|
||||||
|
//
|
||||||
|
// void
|
||||||
|
// AppendNames (DWARFDebugPubnamesSet &pubnames_set,
|
||||||
|
// StringTable &string_table);
|
||||||
|
//
|
||||||
|
// void
|
||||||
|
// AppendNamesEntry (SymbolFileDWARF *dwarf2Data,
|
||||||
|
// const DWARFCompileUnit* cu,
|
||||||
|
// const DWARFDebugInfoEntry* die,
|
||||||
|
// StringTable &string_table);
|
||||||
|
//
|
||||||
|
// void
|
||||||
|
// AppendTypesEntry (DWARFData *dwarf2Data,
|
||||||
|
// const DWARFCompileUnit* cu,
|
||||||
|
// const DWARFDebugInfoEntry* die,
|
||||||
|
// StringTable &string_table);
|
||||||
|
//
|
||||||
|
// size_t
|
||||||
|
// Save (BinaryStreamBuf &names_data, const StringTable &string_table);
|
||||||
|
//
|
||||||
|
// void
|
||||||
|
// AppendName (const char *name,
|
||||||
|
// uint32_t die_offset,
|
||||||
|
// StringTable &string_table,
|
||||||
|
// dw_offset_t name_debug_str_offset = DW_INVALID_OFFSET); // If "name" has already been looked up, then it can be supplied
|
||||||
|
// void
|
||||||
|
// AppendType (const char *name,
|
||||||
|
// uint32_t die_offset,
|
||||||
|
// StringTable &string_table);
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// protected:
|
||||||
|
// struct Entry
|
||||||
|
// {
|
||||||
|
// uint32_t hash;
|
||||||
|
// uint32_t str_offset;
|
||||||
|
// uint32_t die_offset;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// // Map uniqued .debug_str offset to the corresponding DIE offsets
|
||||||
|
// typedef std::map<uint32_t, DIEArray> NameInfo;
|
||||||
|
// // Map a name hash to one or more name infos
|
||||||
|
// typedef std::map<uint32_t, NameInfo> BucketEntry;
|
||||||
|
//
|
||||||
|
// static uint32_t
|
||||||
|
// GetByteSize (const NameInfo &name_info);
|
||||||
|
//
|
||||||
|
// typedef std::vector<BucketEntry> BucketEntryColl;
|
||||||
|
// typedef std::vector<Entry> EntryColl;
|
||||||
|
// EntryColl m_entries;
|
||||||
|
//
|
||||||
|
// };
|
||||||
|
|
||||||
|
|
||||||
|
// A class for reading and using a saved hash table from a block of data
|
||||||
|
// in memory
|
||||||
|
class MemoryTable : public MappedHash::MemoryTable<uint32_t, DWARFMappedHash::Header, DIEArray>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
MemoryTable (lldb_private::DataExtractor &table_data,
|
||||||
|
const lldb_private::DataExtractor &string_table,
|
||||||
|
bool is_apple_names) :
|
||||||
|
MappedHash::MemoryTable<uint32_t, Header, DIEArray> (table_data),
|
||||||
|
m_data (table_data),
|
||||||
|
m_string_table (string_table),
|
||||||
|
m_is_apple_names (is_apple_names)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual
|
||||||
|
~MemoryTable ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const char *
|
||||||
|
GetStringForKeyType (KeyType key) const
|
||||||
|
{
|
||||||
|
// The key in the DWARF table is the .debug_str offset for the string
|
||||||
|
return m_string_table.PeekCStr (key);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Result
|
||||||
|
GetHashDataForName (const char *name,
|
||||||
|
uint32_t* hash_data_offset_ptr,
|
||||||
|
Pair &pair) const
|
||||||
|
{
|
||||||
|
pair.key = m_data.GetU32 (hash_data_offset_ptr);
|
||||||
|
// If the key is zero, this terminates our chain of HashData objects
|
||||||
|
// for this hash value.
|
||||||
|
if (pair.key == 0)
|
||||||
|
return eResultEndOfHashData;
|
||||||
|
|
||||||
|
// There definitely should be a string for this string offset, if
|
||||||
|
// there isn't, there is something wrong, return and error
|
||||||
|
const char *strp_cstr = m_string_table.PeekCStr (pair.key);
|
||||||
|
if (strp_cstr == NULL)
|
||||||
|
return eResultError;
|
||||||
|
|
||||||
|
const uint32_t count = m_data.GetU32 (hash_data_offset_ptr);
|
||||||
|
const uint32_t data_size = count * sizeof(uint32_t);
|
||||||
|
if (count > 0 && m_data.ValidOffsetForDataOfSize (*hash_data_offset_ptr, data_size))
|
||||||
|
{
|
||||||
|
if (strcmp (name, strp_cstr) == 0)
|
||||||
|
{
|
||||||
|
pair.value.clear();
|
||||||
|
for (uint32_t i=0; i<count; ++i)
|
||||||
|
pair.value.push_back (m_data.GetU32 (hash_data_offset_ptr));
|
||||||
|
return eResultKeyMatch;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Skip the data so we are ready to parse another HashData
|
||||||
|
// for this hash value
|
||||||
|
*hash_data_offset_ptr += data_size;
|
||||||
|
// The key doesn't match
|
||||||
|
return eResultKeyMismatch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*hash_data_offset_ptr = UINT32_MAX;
|
||||||
|
return eResultError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Result
|
||||||
|
AppendHashDataForRegularExpression (const lldb_private::RegularExpression& regex,
|
||||||
|
uint32_t* hash_data_offset_ptr,
|
||||||
|
Pair &pair) const
|
||||||
|
{
|
||||||
|
pair.key = m_data.GetU32 (hash_data_offset_ptr);
|
||||||
|
// If the key is zero, this terminates our chain of HashData objects
|
||||||
|
// for this hash value.
|
||||||
|
if (pair.key == 0)
|
||||||
|
return eResultEndOfHashData;
|
||||||
|
|
||||||
|
// There definitely should be a string for this string offset, if
|
||||||
|
// there isn't, there is something wrong, return and error
|
||||||
|
const char *strp_cstr = m_string_table.PeekCStr (pair.key);
|
||||||
|
if (strp_cstr == NULL)
|
||||||
|
return eResultError;
|
||||||
|
|
||||||
|
const uint32_t count = m_data.GetU32 (hash_data_offset_ptr);
|
||||||
|
const uint32_t data_size = count * sizeof(uint32_t);
|
||||||
|
if (count > 0 && m_data.ValidOffsetForDataOfSize (*hash_data_offset_ptr, data_size))
|
||||||
|
{
|
||||||
|
if (regex.Execute(strp_cstr))
|
||||||
|
{
|
||||||
|
for (uint32_t i=0; i<count; ++i)
|
||||||
|
pair.value.push_back (m_data.GetU32 (hash_data_offset_ptr));
|
||||||
|
return eResultKeyMatch;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Skip the data so we are ready to parse another HashData
|
||||||
|
// for this hash value
|
||||||
|
*hash_data_offset_ptr += data_size;
|
||||||
|
// The key doesn't match
|
||||||
|
return eResultKeyMismatch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*hash_data_offset_ptr = UINT32_MAX;
|
||||||
|
return eResultError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
AppendAllDIEsThatMatchingRegex (const lldb_private::RegularExpression& regex,
|
||||||
|
DIEArray &die_offsets) const
|
||||||
|
{
|
||||||
|
const uint32_t hash_count = m_header.hashes_count;
|
||||||
|
Pair pair;
|
||||||
|
for (uint32_t offset_idx=0; offset_idx<hash_count; ++offset_idx)
|
||||||
|
{
|
||||||
|
uint32_t hash_data_offset = GetHashDataOffset (offset_idx);
|
||||||
|
while (hash_data_offset != UINT32_MAX)
|
||||||
|
{
|
||||||
|
const uint32_t prev_hash_data_offset = hash_data_offset;
|
||||||
|
Result hash_result = AppendHashDataForRegularExpression (regex, &hash_data_offset, pair);
|
||||||
|
if (prev_hash_data_offset == hash_data_offset)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Check the result of getting our hash data
|
||||||
|
switch (hash_result)
|
||||||
|
{
|
||||||
|
case eResultKeyMatch:
|
||||||
|
case eResultKeyMismatch:
|
||||||
|
// Whether we matches or not, it doesn't matter, we
|
||||||
|
// keep looking.
|
||||||
|
break;
|
||||||
|
|
||||||
|
case eResultEndOfHashData:
|
||||||
|
case eResultError:
|
||||||
|
hash_data_offset = UINT32_MAX;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
die_offsets.swap (pair.value);
|
||||||
|
return die_offsets.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
AppendAllDIEsInRange (const uint32_t die_offset_start,
|
||||||
|
const uint32_t die_offset_end,
|
||||||
|
DIEArray &die_offsets) const
|
||||||
|
{
|
||||||
|
const uint32_t hash_count = m_header.hashes_count;
|
||||||
|
for (uint32_t offset_idx=0; offset_idx<hash_count; ++offset_idx)
|
||||||
|
{
|
||||||
|
bool done = false;
|
||||||
|
uint32_t hash_data_offset = GetHashDataOffset (offset_idx);
|
||||||
|
while (!done && hash_data_offset != UINT32_MAX)
|
||||||
|
{
|
||||||
|
KeyType key = m_data.GetU32 (&hash_data_offset);
|
||||||
|
// If the key is zero, this terminates our chain of HashData objects
|
||||||
|
// for this hash value.
|
||||||
|
if (key == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
const uint32_t count = m_data.GetU32 (&hash_data_offset);
|
||||||
|
for (uint32_t i=0; i<count; ++i)
|
||||||
|
{
|
||||||
|
uint32_t die_offset = m_data.GetU32 (&hash_data_offset);
|
||||||
|
if (die_offset == 0)
|
||||||
|
done = true;
|
||||||
|
if (die_offset_start <= die_offset && die_offset < die_offset_end)
|
||||||
|
die_offsets.push_back(die_offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return die_offsets.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // SymbolFileDWARF_HashedNameToDIE_h_
|
#endif // SymbolFileDWARF_HashedNameToDIE_h_
|
||||||
|
|
|
@ -173,11 +173,13 @@ SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
|
||||||
m_data_debug_str (),
|
m_data_debug_str (),
|
||||||
m_data_apple_names (),
|
m_data_apple_names (),
|
||||||
m_data_apple_types (),
|
m_data_apple_types (),
|
||||||
|
m_data_apple_namespaces (),
|
||||||
m_abbr(),
|
m_abbr(),
|
||||||
m_info(),
|
m_info(),
|
||||||
m_line(),
|
m_line(),
|
||||||
m_apple_names (this, m_data_apple_names, true),
|
m_apple_names_ap (),
|
||||||
m_apple_types (this, m_data_apple_types, true),
|
m_apple_types_ap (),
|
||||||
|
m_apple_namespaces_ap (),
|
||||||
m_function_basename_index(),
|
m_function_basename_index(),
|
||||||
m_function_fullname_index(),
|
m_function_fullname_index(),
|
||||||
m_function_method_index(),
|
m_function_method_index(),
|
||||||
|
@ -252,9 +254,27 @@ SymbolFileDWARF::InitializeObject()
|
||||||
section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data);
|
section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data);
|
||||||
}
|
}
|
||||||
get_apple_names_data();
|
get_apple_names_data();
|
||||||
|
if (m_data_apple_names.GetByteSize() > 0)
|
||||||
|
{
|
||||||
|
m_apple_names_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_names, get_debug_str_data(), true));
|
||||||
|
if (!m_apple_names_ap->IsValid())
|
||||||
|
m_apple_names_ap.reset();
|
||||||
|
}
|
||||||
get_apple_types_data();
|
get_apple_types_data();
|
||||||
m_apple_names.Initialize();
|
if (m_data_apple_types.GetByteSize() > 0)
|
||||||
m_apple_types.Initialize();
|
{
|
||||||
|
m_apple_types_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_types, get_debug_str_data(), false));
|
||||||
|
if (!m_apple_types_ap->IsValid())
|
||||||
|
m_apple_types_ap.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
get_apple_namespaces_data();
|
||||||
|
if (m_data_apple_namespaces.GetByteSize() > 0)
|
||||||
|
{
|
||||||
|
m_apple_namespaces_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_namespaces, get_debug_str_data(), false));
|
||||||
|
if (!m_apple_namespaces_ap->IsValid())
|
||||||
|
m_apple_namespaces_ap.reset();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -470,6 +490,12 @@ SymbolFileDWARF::get_apple_types_data()
|
||||||
return GetCachedSectionData (flagsGotDebugTypesData, eSectionTypeDWARFAppleTypes, m_data_apple_types);
|
return GetCachedSectionData (flagsGotDebugTypesData, eSectionTypeDWARFAppleTypes, m_data_apple_types);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DataExtractor&
|
||||||
|
SymbolFileDWARF::get_apple_namespaces_data()
|
||||||
|
{
|
||||||
|
return GetCachedSectionData (flagsGotDebugTypesData, eSectionTypeDWARFAppleNamespaces, m_data_apple_namespaces);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DWARFDebugAbbrev*
|
DWARFDebugAbbrev*
|
||||||
SymbolFileDWARF::DebugAbbrev()
|
SymbolFileDWARF::DebugAbbrev()
|
||||||
|
@ -1937,21 +1963,36 @@ SymbolFileDWARF::FindGlobalVariables (const ConstString &name, bool append, uint
|
||||||
// we are appending the results to a variable list.
|
// we are appending the results to a variable list.
|
||||||
const uint32_t original_size = variables.GetSize();
|
const uint32_t original_size = variables.GetSize();
|
||||||
|
|
||||||
|
DIEArray die_offsets;
|
||||||
|
|
||||||
|
if (m_apple_names_ap.get())
|
||||||
|
{
|
||||||
|
const char *name_cstr = name.GetCString();
|
||||||
|
DWARFMappedHash::MemoryTable::Pair kv_pair;
|
||||||
|
if (m_apple_names_ap->Find (name_cstr, kv_pair))
|
||||||
|
{
|
||||||
|
die_offsets.swap(kv_pair.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Index the DWARF if we haven't already
|
// Index the DWARF if we haven't already
|
||||||
if (!m_indexed)
|
if (!m_indexed)
|
||||||
Index ();
|
Index ();
|
||||||
|
|
||||||
|
m_global_index.Find (name, die_offsets);
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t num_matches = die_offsets.size();
|
||||||
|
if (num_matches)
|
||||||
|
{
|
||||||
SymbolContext sc;
|
SymbolContext sc;
|
||||||
sc.module_sp = m_obj_file->GetModule();
|
sc.module_sp = m_obj_file->GetModule();
|
||||||
assert (sc.module_sp);
|
assert (sc.module_sp);
|
||||||
|
|
||||||
|
DWARFDebugInfo* debug_info = DebugInfo();
|
||||||
DWARFCompileUnit* dwarf_cu = NULL;
|
DWARFCompileUnit* dwarf_cu = NULL;
|
||||||
const DWARFDebugInfoEntry* die = NULL;
|
const DWARFDebugInfoEntry* die = NULL;
|
||||||
DIEArray die_offsets;
|
|
||||||
const size_t num_matches = m_global_index.Find (name, die_offsets);
|
|
||||||
if (num_matches)
|
|
||||||
{
|
|
||||||
DWARFDebugInfo* debug_info = DebugInfo();
|
|
||||||
for (size_t i=0; i<num_matches; ++i)
|
for (size_t i=0; i<num_matches; ++i)
|
||||||
{
|
{
|
||||||
const dw_offset_t die_offset = die_offsets[i];
|
const dw_offset_t die_offset = die_offsets[i];
|
||||||
|
@ -1986,18 +2027,28 @@ SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append
|
||||||
// we are appending the results to a variable list.
|
// we are appending the results to a variable list.
|
||||||
const uint32_t original_size = variables.GetSize();
|
const uint32_t original_size = variables.GetSize();
|
||||||
|
|
||||||
|
DIEArray die_offsets;
|
||||||
|
|
||||||
|
if (m_apple_names_ap.get())
|
||||||
|
{
|
||||||
|
m_apple_names_ap->AppendAllDIEsThatMatchingRegex (regex, die_offsets);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Index the DWARF if we haven't already
|
// Index the DWARF if we haven't already
|
||||||
if (!m_indexed)
|
if (!m_indexed)
|
||||||
Index ();
|
Index ();
|
||||||
|
|
||||||
|
m_global_index.Find (regex, die_offsets);
|
||||||
|
}
|
||||||
|
|
||||||
SymbolContext sc;
|
SymbolContext sc;
|
||||||
sc.module_sp = m_obj_file->GetModule();
|
sc.module_sp = m_obj_file->GetModule();
|
||||||
assert (sc.module_sp);
|
assert (sc.module_sp);
|
||||||
|
|
||||||
DWARFCompileUnit* dwarf_cu = NULL;
|
DWARFCompileUnit* dwarf_cu = NULL;
|
||||||
const DWARFDebugInfoEntry* die = NULL;
|
const DWARFDebugInfoEntry* die = NULL;
|
||||||
DIEArray die_offsets;
|
const size_t num_matches = die_offsets.size();
|
||||||
const size_t num_matches = m_global_index.Find (regex, die_offsets);
|
|
||||||
if (num_matches)
|
if (num_matches)
|
||||||
{
|
{
|
||||||
DWARFDebugInfo* debug_info = DebugInfo();
|
DWARFDebugInfo* debug_info = DebugInfo();
|
||||||
|
@ -2006,7 +2057,6 @@ SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append
|
||||||
const dw_offset_t die_offset = die_offsets[i];
|
const dw_offset_t die_offset = die_offsets[i];
|
||||||
die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
|
die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
|
||||||
sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
|
sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
|
||||||
assert(sc.comp_unit != NULL);
|
|
||||||
|
|
||||||
ParseVariables(sc, dwarf_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
|
ParseVariables(sc, dwarf_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
|
||||||
|
|
||||||
|
@ -2066,7 +2116,8 @@ SymbolFileDWARF::ResolveFunctions (const DIEArray &die_offsets,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert (die->Tag() == DW_TAG_subprogram);
|
if (die->Tag() == DW_TAG_subprogram)
|
||||||
|
{
|
||||||
if (GetFunction (dwarf_cu, die, sc))
|
if (GetFunction (dwarf_cu, die, sc))
|
||||||
{
|
{
|
||||||
Address addr;
|
Address addr;
|
||||||
|
@ -2102,31 +2153,62 @@ SymbolFileDWARF::ResolveFunctions (const DIEArray &die_offsets,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return sc_list.GetSize() - sc_list_initial_size;
|
return sc_list.GetSize() - sc_list_initial_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
SymbolFileDWARF::FindFunctions
|
|
||||||
(
|
|
||||||
const ConstString &name,
|
|
||||||
const NameToDIE &name_to_die,
|
|
||||||
SymbolContextList& sc_list
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DWARFDebugInfo* info = DebugInfo();
|
|
||||||
if (info == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SymbolFileDWARF::FindFunctions (const ConstString &name,
|
||||||
|
const NameToDIE &name_to_die,
|
||||||
|
SymbolContextList& sc_list)
|
||||||
|
{
|
||||||
|
DIEArray die_offsets;
|
||||||
|
if (name_to_die.Find (name, die_offsets))
|
||||||
|
{
|
||||||
|
ParseFunctions (die_offsets, sc_list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SymbolFileDWARF::FindFunctions (const RegularExpression ®ex,
|
||||||
|
const NameToDIE &name_to_die,
|
||||||
|
SymbolContextList& sc_list)
|
||||||
|
{
|
||||||
|
DIEArray die_offsets;
|
||||||
|
if (name_to_die.Find (regex, die_offsets))
|
||||||
|
{
|
||||||
|
ParseFunctions (die_offsets, sc_list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SymbolFileDWARF::FindFunctions (const RegularExpression ®ex,
|
||||||
|
const DWARFMappedHash::MemoryTable &memory_table,
|
||||||
|
SymbolContextList& sc_list)
|
||||||
|
{
|
||||||
|
DIEArray die_offsets;
|
||||||
|
if (memory_table.AppendAllDIEsThatMatchingRegex (regex, die_offsets))
|
||||||
|
{
|
||||||
|
ParseFunctions (die_offsets, sc_list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SymbolFileDWARF::ParseFunctions (const DIEArray &die_offsets,
|
||||||
|
SymbolContextList& sc_list)
|
||||||
|
{
|
||||||
|
const size_t num_matches = die_offsets.size();
|
||||||
|
if (num_matches)
|
||||||
|
{
|
||||||
SymbolContext sc;
|
SymbolContext sc;
|
||||||
sc.module_sp = m_obj_file->GetModule();
|
sc.module_sp = m_obj_file->GetModule();
|
||||||
assert (sc.module_sp);
|
|
||||||
|
|
||||||
DWARFCompileUnit* dwarf_cu = NULL;
|
DWARFCompileUnit* dwarf_cu = NULL;
|
||||||
const DWARFDebugInfoEntry* die = NULL;
|
const DWARFDebugInfoEntry* die = NULL;
|
||||||
DIEArray die_offsets;
|
|
||||||
const size_t num_matches = name_to_die.Find (name, die_offsets);
|
|
||||||
if (num_matches)
|
|
||||||
{
|
|
||||||
DWARFDebugInfo* debug_info = DebugInfo();
|
DWARFDebugInfo* debug_info = DebugInfo();
|
||||||
for (size_t i=0; i<num_matches; ++i)
|
for (size_t i=0; i<num_matches; ++i)
|
||||||
{
|
{
|
||||||
|
@ -2183,84 +2265,6 @@ SymbolFileDWARF::FindFunctions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
SymbolFileDWARF::FindFunctions
|
|
||||||
(
|
|
||||||
const RegularExpression ®ex,
|
|
||||||
const NameToDIE &name_to_die,
|
|
||||||
SymbolContextList& sc_list
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DWARFDebugInfo* info = DebugInfo();
|
|
||||||
if (info == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
SymbolContext sc;
|
|
||||||
sc.module_sp = m_obj_file->GetModule();
|
|
||||||
assert (sc.module_sp);
|
|
||||||
|
|
||||||
DWARFCompileUnit* dwarf_cu = NULL;
|
|
||||||
const DWARFDebugInfoEntry* die = NULL;
|
|
||||||
DIEArray die_offsets;
|
|
||||||
const size_t num_matches = name_to_die.Find (regex, die_offsets);
|
|
||||||
if (num_matches)
|
|
||||||
{
|
|
||||||
DWARFDebugInfo* debug_info = DebugInfo();
|
|
||||||
for (size_t i=0; i<num_matches; ++i)
|
|
||||||
{
|
|
||||||
const dw_offset_t die_offset = die_offsets[i];
|
|
||||||
die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
|
|
||||||
|
|
||||||
const DWARFDebugInfoEntry* inlined_die = NULL;
|
|
||||||
if (die->Tag() == DW_TAG_inlined_subroutine)
|
|
||||||
{
|
|
||||||
inlined_die = die;
|
|
||||||
|
|
||||||
while ((die = die->GetParent()) != NULL)
|
|
||||||
{
|
|
||||||
if (die->Tag() == DW_TAG_subprogram)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert (die->Tag() == DW_TAG_subprogram);
|
|
||||||
if (GetFunction (dwarf_cu, die, sc))
|
|
||||||
{
|
|
||||||
Address addr;
|
|
||||||
// Parse all blocks if needed
|
|
||||||
if (inlined_die)
|
|
||||||
{
|
|
||||||
sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset());
|
|
||||||
assert (sc.block != NULL);
|
|
||||||
if (sc.block->GetStartAddress (addr) == false)
|
|
||||||
addr.Clear();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sc.block = NULL;
|
|
||||||
addr = sc.function->GetAddressRange().GetBaseAddress();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addr.IsValid())
|
|
||||||
{
|
|
||||||
|
|
||||||
// We found the function, so we should find the line table
|
|
||||||
// and line table entry as well
|
|
||||||
LineTable *line_table = sc.comp_unit->GetLineTable();
|
|
||||||
if (line_table == NULL)
|
|
||||||
{
|
|
||||||
if (ParseCompileUnitLineTable(sc))
|
|
||||||
line_table = sc.comp_unit->GetLineTable();
|
|
||||||
}
|
|
||||||
if (line_table != NULL)
|
|
||||||
line_table->FindLineEntryByAddress (addr, sc.line_entry);
|
|
||||||
|
|
||||||
sc_list.Append(sc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
SymbolFileDWARF::FindFunctions (const ConstString &name,
|
SymbolFileDWARF::FindFunctions (const ConstString &name,
|
||||||
uint32_t name_type_mask,
|
uint32_t name_type_mask,
|
||||||
|
@ -2280,6 +2284,16 @@ SymbolFileDWARF::FindFunctions (const ConstString &name,
|
||||||
|
|
||||||
const uint32_t original_size = sc_list.GetSize();
|
const uint32_t original_size = sc_list.GetSize();
|
||||||
|
|
||||||
|
if (m_apple_names_ap.get())
|
||||||
|
{
|
||||||
|
const char *name_cstr = name.GetCString();
|
||||||
|
DWARFMappedHash::MemoryTable::Pair kv_pair;
|
||||||
|
if (m_apple_names_ap->Find (name_cstr, kv_pair))
|
||||||
|
ResolveFunctions (kv_pair.value, sc_list, name, name_type_mask);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
// Index the DWARF if we haven't already
|
// Index the DWARF if we haven't already
|
||||||
if (!m_indexed)
|
if (!m_indexed)
|
||||||
Index ();
|
Index ();
|
||||||
|
@ -2295,16 +2309,6 @@ SymbolFileDWARF::FindFunctions (const ConstString &name,
|
||||||
|
|
||||||
if (name_type_mask & eFunctionNameTypeSelector)
|
if (name_type_mask & eFunctionNameTypeSelector)
|
||||||
FindFunctions (name, m_function_selector_index, sc_list);
|
FindFunctions (name, m_function_selector_index, sc_list);
|
||||||
|
|
||||||
if (m_apple_names.IsValid())
|
|
||||||
{
|
|
||||||
SymbolContextList sc_list_apple;
|
|
||||||
DIEArray die_offsets;
|
|
||||||
const uint32_t num_matches = m_apple_names.Find(name.GetCString(), die_offsets);
|
|
||||||
if (num_matches > 0)
|
|
||||||
ResolveFunctions (die_offsets, sc_list_apple, name, name_type_mask);
|
|
||||||
if (sc_list != sc_list_apple)
|
|
||||||
assert (!"__apple_names results differ from DWARF index results");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the number of variable that were appended to the list
|
// Return the number of variable that were appended to the list
|
||||||
|
@ -2328,12 +2332,19 @@ SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, Symb
|
||||||
uint32_t original_size = sc_list.GetSize();
|
uint32_t original_size = sc_list.GetSize();
|
||||||
|
|
||||||
// Index the DWARF if we haven't already
|
// Index the DWARF if we haven't already
|
||||||
|
if (m_apple_names_ap.get())
|
||||||
|
{
|
||||||
|
FindFunctions (regex, *m_apple_names_ap, sc_list);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (!m_indexed)
|
if (!m_indexed)
|
||||||
Index ();
|
Index ();
|
||||||
|
|
||||||
FindFunctions (regex, m_function_basename_index, sc_list);
|
FindFunctions (regex, m_function_basename_index, sc_list);
|
||||||
|
|
||||||
FindFunctions (regex, m_function_fullname_index, sc_list);
|
FindFunctions (regex, m_function_fullname_index, sc_list);
|
||||||
|
}
|
||||||
|
|
||||||
// Return the number of variable that were appended to the list
|
// Return the number of variable that were appended to the list
|
||||||
return sc_list.GetSize() - original_size;
|
return sc_list.GetSize() - original_size;
|
||||||
|
@ -2384,18 +2395,33 @@ SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, boo
|
||||||
if (!append)
|
if (!append)
|
||||||
types.Clear();
|
types.Clear();
|
||||||
|
|
||||||
// Index if we already haven't to make sure the compile units
|
DIEArray die_offsets;
|
||||||
// get indexed and make their global DIE index list
|
|
||||||
|
if (m_apple_types_ap.get())
|
||||||
|
{
|
||||||
|
const char *name_cstr = name.GetCString();
|
||||||
|
DWARFMappedHash::MemoryTable::Pair kv_pair;
|
||||||
|
if (m_apple_types_ap->Find (name_cstr, kv_pair))
|
||||||
|
{
|
||||||
|
die_offsets.swap(kv_pair.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (!m_indexed)
|
if (!m_indexed)
|
||||||
Index ();
|
Index ();
|
||||||
|
|
||||||
|
m_type_index.Find (name, die_offsets);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const size_t num_matches = die_offsets.size();
|
||||||
|
|
||||||
|
if (num_matches)
|
||||||
|
{
|
||||||
const uint32_t initial_types_size = types.GetSize();
|
const uint32_t initial_types_size = types.GetSize();
|
||||||
DWARFCompileUnit* dwarf_cu = NULL;
|
DWARFCompileUnit* dwarf_cu = NULL;
|
||||||
const DWARFDebugInfoEntry* die = NULL;
|
const DWARFDebugInfoEntry* die = NULL;
|
||||||
DIEArray die_offsets;
|
|
||||||
const size_t num_matches = m_type_index.Find (name, die_offsets);
|
|
||||||
if (num_matches)
|
|
||||||
{
|
|
||||||
DWARFDebugInfo* debug_info = DebugInfo();
|
DWARFDebugInfo* debug_info = DebugInfo();
|
||||||
for (size_t i=0; i<num_matches; ++i)
|
for (size_t i=0; i<num_matches; ++i)
|
||||||
{
|
{
|
||||||
|
@ -2419,9 +2445,10 @@ SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, boo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return types.GetSize() - initial_types_size;
|
return types.GetSize() - initial_types_size;
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ClangNamespaceDecl
|
ClangNamespaceDecl
|
||||||
|
@ -2432,16 +2459,30 @@ SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
|
||||||
DWARFDebugInfo* info = DebugInfo();
|
DWARFDebugInfo* info = DebugInfo();
|
||||||
if (info)
|
if (info)
|
||||||
{
|
{
|
||||||
|
DIEArray die_offsets;
|
||||||
|
|
||||||
// Index if we already haven't to make sure the compile units
|
// Index if we already haven't to make sure the compile units
|
||||||
// get indexed and make their global DIE index list
|
// get indexed and make their global DIE index list
|
||||||
|
if (m_apple_namespaces_ap.get())
|
||||||
|
{
|
||||||
|
const char *name_cstr = name.GetCString();
|
||||||
|
DWARFMappedHash::MemoryTable::Pair kv_pair;
|
||||||
|
if (m_apple_namespaces_ap->Find (name_cstr, kv_pair))
|
||||||
|
{
|
||||||
|
die_offsets.swap(kv_pair.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (!m_indexed)
|
if (!m_indexed)
|
||||||
Index ();
|
Index ();
|
||||||
|
|
||||||
|
m_namespace_index.Find (name, die_offsets);
|
||||||
|
}
|
||||||
|
|
||||||
DWARFCompileUnit* dwarf_cu = NULL;
|
DWARFCompileUnit* dwarf_cu = NULL;
|
||||||
const DWARFDebugInfoEntry* die = NULL;
|
const DWARFDebugInfoEntry* die = NULL;
|
||||||
DIEArray die_offsets;
|
const size_t num_matches = die_offsets.size();
|
||||||
const size_t num_matches = m_namespace_index.Find (name, die_offsets);
|
|
||||||
if (num_matches)
|
if (num_matches)
|
||||||
{
|
{
|
||||||
DWARFDebugInfo* debug_info = DebugInfo();
|
DWARFDebugInfo* debug_info = DebugInfo();
|
||||||
|
@ -3079,26 +3120,41 @@ SymbolFileDWARF::GetDeclContextDIEContainingDIE (DWARFCompileUnit *cu, const DWA
|
||||||
// This function can be used when a DIE is found that is a forward declaration
|
// This function can be used when a DIE is found that is a forward declaration
|
||||||
// DIE and we want to try and find a type that has the complete definition.
|
// DIE and we want to try and find a type that has the complete definition.
|
||||||
TypeSP
|
TypeSP
|
||||||
SymbolFileDWARF::FindDefinitionTypeForDIE (
|
SymbolFileDWARF::FindDefinitionTypeForDIE (DWARFCompileUnit* cu,
|
||||||
DWARFCompileUnit* cu,
|
|
||||||
const DWARFDebugInfoEntry *die,
|
const DWARFDebugInfoEntry *die,
|
||||||
const ConstString &type_name
|
const ConstString &type_name)
|
||||||
)
|
|
||||||
{
|
{
|
||||||
TypeSP type_sp;
|
TypeSP type_sp;
|
||||||
|
|
||||||
if (cu == NULL || die == NULL || !type_name)
|
if (cu == NULL || die == NULL || !type_name)
|
||||||
return type_sp;
|
return type_sp;
|
||||||
|
|
||||||
|
DIEArray die_offsets;
|
||||||
|
|
||||||
|
if (m_apple_types_ap.get())
|
||||||
|
{
|
||||||
|
const char *name_cstr = type_name.GetCString();
|
||||||
|
DWARFMappedHash::MemoryTable::Pair kv_pair;
|
||||||
|
if (m_apple_types_ap->Find (name_cstr, kv_pair))
|
||||||
|
{
|
||||||
|
die_offsets.swap(kv_pair.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (!m_indexed)
|
if (!m_indexed)
|
||||||
Index ();
|
Index ();
|
||||||
|
|
||||||
|
m_type_index.Find (type_name, die_offsets);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const size_t num_matches = die_offsets.size();
|
||||||
|
|
||||||
const dw_tag_t type_tag = die->Tag();
|
const dw_tag_t type_tag = die->Tag();
|
||||||
|
|
||||||
DWARFCompileUnit* type_cu = NULL;
|
DWARFCompileUnit* type_cu = NULL;
|
||||||
const DWARFDebugInfoEntry* type_die = NULL;
|
const DWARFDebugInfoEntry* type_die = NULL;
|
||||||
DIEArray die_offsets;
|
|
||||||
const size_t num_matches = m_type_index.Find (type_name, die_offsets);
|
|
||||||
if (num_matches)
|
if (num_matches)
|
||||||
{
|
{
|
||||||
DWARFDebugInfo* debug_info = DebugInfo();
|
DWARFDebugInfo* debug_info = DebugInfo();
|
||||||
|
@ -4235,17 +4291,29 @@ SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
|
||||||
variables.reset(new VariableList());
|
variables.reset(new VariableList());
|
||||||
sc.comp_unit->SetVariableList(variables);
|
sc.comp_unit->SetVariableList(variables);
|
||||||
|
|
||||||
|
DWARFCompileUnit* match_dwarf_cu = NULL;
|
||||||
|
const DWARFDebugInfoEntry* die = NULL;
|
||||||
|
DIEArray die_offsets;
|
||||||
|
if (m_apple_names_ap.get())
|
||||||
|
{
|
||||||
|
// TODO: implement finding all items in
|
||||||
|
m_apple_names_ap->AppendAllDIEsInRange (dwarf_cu->GetOffset(),
|
||||||
|
dwarf_cu->GetNextCompileUnitOffset(),
|
||||||
|
die_offsets);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Index if we already haven't to make sure the compile units
|
// Index if we already haven't to make sure the compile units
|
||||||
// get indexed and make their global DIE index list
|
// get indexed and make their global DIE index list
|
||||||
if (!m_indexed)
|
if (!m_indexed)
|
||||||
Index ();
|
Index ();
|
||||||
|
|
||||||
DWARFCompileUnit* match_dwarf_cu = NULL;
|
m_global_index.FindAllEntriesForCompileUnit (dwarf_cu->GetOffset(),
|
||||||
const DWARFDebugInfoEntry* die = NULL;
|
|
||||||
DIEArray die_offsets;
|
|
||||||
const size_t num_matches = m_global_index.FindAllEntriesForCompileUnit (dwarf_cu->GetOffset(),
|
|
||||||
dwarf_cu->GetNextCompileUnitOffset(),
|
dwarf_cu->GetNextCompileUnitOffset(),
|
||||||
die_offsets);
|
die_offsets);
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t num_matches = die_offsets.size();
|
||||||
if (num_matches)
|
if (num_matches)
|
||||||
{
|
{
|
||||||
DWARFDebugInfo* debug_info = DebugInfo();
|
DWARFDebugInfo* debug_info = DebugInfo();
|
||||||
|
@ -4284,6 +4352,11 @@ SymbolFileDWARF::ParseVariableDIE
|
||||||
return var_sp; // Already been parsed!
|
return var_sp; // Already been parsed!
|
||||||
|
|
||||||
const dw_tag_t tag = die->Tag();
|
const dw_tag_t tag = die->Tag();
|
||||||
|
|
||||||
|
if ((tag == DW_TAG_variable) ||
|
||||||
|
(tag == DW_TAG_constant) ||
|
||||||
|
(tag == DW_TAG_formal_parameter && sc.function))
|
||||||
|
{
|
||||||
DWARFDebugInfoEntry::Attributes attributes;
|
DWARFDebugInfoEntry::Attributes attributes;
|
||||||
const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
|
const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
|
||||||
if (num_attributes > 0)
|
if (num_attributes > 0)
|
||||||
|
@ -4408,6 +4481,7 @@ SymbolFileDWARF::ParseVariableDIE
|
||||||
// (missing location due to optimization, etc)) so we don't re-parse
|
// (missing location due to optimization, etc)) so we don't re-parse
|
||||||
// this DIE over and over later...
|
// this DIE over and over later...
|
||||||
m_die_to_variable_sp[die] = var_sp;
|
m_die_to_variable_sp[die] = var_sp;
|
||||||
|
}
|
||||||
return var_sp;
|
return var_sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -166,6 +166,8 @@ public:
|
||||||
const lldb_private::DataExtractor& get_debug_str_data ();
|
const lldb_private::DataExtractor& get_debug_str_data ();
|
||||||
const lldb_private::DataExtractor& get_apple_names_data ();
|
const lldb_private::DataExtractor& get_apple_names_data ();
|
||||||
const lldb_private::DataExtractor& get_apple_types_data ();
|
const lldb_private::DataExtractor& get_apple_types_data ();
|
||||||
|
const lldb_private::DataExtractor& get_apple_namespaces_data ();
|
||||||
|
|
||||||
|
|
||||||
DWARFDebugAbbrev* DebugAbbrev();
|
DWARFDebugAbbrev* DebugAbbrev();
|
||||||
const DWARFDebugAbbrev* DebugAbbrev() const;
|
const DWARFDebugAbbrev* DebugAbbrev() const;
|
||||||
|
@ -326,11 +328,18 @@ protected:
|
||||||
const NameToDIE &name_to_die,
|
const NameToDIE &name_to_die,
|
||||||
lldb_private::SymbolContextList& sc_list);
|
lldb_private::SymbolContextList& sc_list);
|
||||||
|
|
||||||
|
void FindFunctions (
|
||||||
|
const lldb_private::RegularExpression ®ex,
|
||||||
|
const DWARFMappedHash::MemoryTable &memory_table,
|
||||||
|
lldb_private::SymbolContextList& sc_list);
|
||||||
|
|
||||||
lldb::TypeSP FindDefinitionTypeForDIE (
|
lldb::TypeSP FindDefinitionTypeForDIE (
|
||||||
DWARFCompileUnit* cu,
|
DWARFCompileUnit* cu,
|
||||||
const DWARFDebugInfoEntry *die,
|
const DWARFDebugInfoEntry *die,
|
||||||
const lldb_private::ConstString &type_name);
|
const lldb_private::ConstString &type_name);
|
||||||
|
|
||||||
|
void ParseFunctions (const DIEArray &die_offsets,
|
||||||
|
lldb_private::SymbolContextList& sc_list);
|
||||||
lldb::TypeSP GetTypeForDIE (DWARFCompileUnit *cu,
|
lldb::TypeSP GetTypeForDIE (DWARFCompileUnit *cu,
|
||||||
const DWARFDebugInfoEntry* die);
|
const DWARFDebugInfoEntry* die);
|
||||||
|
|
||||||
|
@ -388,14 +397,16 @@ protected:
|
||||||
lldb_private::DataExtractor m_data_debug_str;
|
lldb_private::DataExtractor m_data_debug_str;
|
||||||
lldb_private::DataExtractor m_data_apple_names;
|
lldb_private::DataExtractor m_data_apple_names;
|
||||||
lldb_private::DataExtractor m_data_apple_types;
|
lldb_private::DataExtractor m_data_apple_types;
|
||||||
|
lldb_private::DataExtractor m_data_apple_namespaces;
|
||||||
|
|
||||||
// The auto_ptr items below are generated on demand if and when someone accesses
|
// The auto_ptr items below are generated on demand if and when someone accesses
|
||||||
// them through a non const version of this class.
|
// them through a non const version of this class.
|
||||||
std::auto_ptr<DWARFDebugAbbrev> m_abbr;
|
std::auto_ptr<DWARFDebugAbbrev> m_abbr;
|
||||||
std::auto_ptr<DWARFDebugInfo> m_info;
|
std::auto_ptr<DWARFDebugInfo> m_info;
|
||||||
std::auto_ptr<DWARFDebugLine> m_line;
|
std::auto_ptr<DWARFDebugLine> m_line;
|
||||||
HashedNameToDIE::MemoryTable m_apple_names;
|
std::auto_ptr<DWARFMappedHash::MemoryTable> m_apple_names_ap;
|
||||||
HashedNameToDIE::MemoryTable m_apple_types;
|
std::auto_ptr<DWARFMappedHash::MemoryTable> m_apple_types_ap;
|
||||||
|
std::auto_ptr<DWARFMappedHash::MemoryTable> m_apple_namespaces_ap;
|
||||||
NameToDIE m_function_basename_index; // All concrete functions
|
NameToDIE m_function_basename_index; // All concrete functions
|
||||||
NameToDIE m_function_fullname_index; // All concrete functions
|
NameToDIE m_function_fullname_index; // All concrete functions
|
||||||
NameToDIE m_function_method_index; // All inlined functions
|
NameToDIE m_function_method_index; // All inlined functions
|
||||||
|
|
|
@ -223,6 +223,7 @@ ObjectFile::GetAddressClass (addr_t file_addr)
|
||||||
case eSectionTypeDWARFDebugStr: return eAddressClassDebug;
|
case eSectionTypeDWARFDebugStr: return eAddressClassDebug;
|
||||||
case eSectionTypeDWARFAppleNames: return eAddressClassDebug;
|
case eSectionTypeDWARFAppleNames: return eAddressClassDebug;
|
||||||
case eSectionTypeDWARFAppleTypes: return eAddressClassDebug;
|
case eSectionTypeDWARFAppleTypes: return eAddressClassDebug;
|
||||||
|
case eSectionTypeDWARFAppleNamespaces: return eAddressClassDebug;
|
||||||
case eSectionTypeEHFrame: return eAddressClassRuntime;
|
case eSectionTypeEHFrame: return eAddressClassRuntime;
|
||||||
case eSectionTypeOther: return eAddressClassUnknown;
|
case eSectionTypeOther: return eAddressClassUnknown;
|
||||||
}
|
}
|
||||||
|
|
|
@ -981,7 +981,8 @@ SymbolContextList::Dump(Stream *s, Target *target) const
|
||||||
collection::const_iterator pos, end = m_symbol_contexts.end();
|
collection::const_iterator pos, end = m_symbol_contexts.end();
|
||||||
for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
|
for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
|
||||||
{
|
{
|
||||||
pos->Dump(s, target);
|
//pos->Dump(s, target);
|
||||||
|
pos->GetDescription(s, eDescriptionLevelVerbose, target);
|
||||||
}
|
}
|
||||||
s->IndentLess();
|
s->IndentLess();
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,12 +104,12 @@ ObjCLanguageRuntime::GetByteOffsetForIvar (ClangASTType &parent_qual_type, const
|
||||||
bool
|
bool
|
||||||
ObjCLanguageRuntime::ParseMethodName (const char *name,
|
ObjCLanguageRuntime::ParseMethodName (const char *name,
|
||||||
ConstString *class_name,
|
ConstString *class_name,
|
||||||
ConstString *method_name,
|
ConstString *selector_name,
|
||||||
ConstString *base_name)
|
ConstString *name_sans_category)
|
||||||
{
|
{
|
||||||
if (class_name) { class_name->Clear(); }
|
if (class_name) { class_name->Clear(); }
|
||||||
if (method_name) { method_name->Clear(); }
|
if (selector_name) { selector_name->Clear(); }
|
||||||
if (base_name) { base_name->Clear(); }
|
if (name_sans_category) { name_sans_category->Clear(); }
|
||||||
|
|
||||||
if (IsPossibleObjCMethodName (name))
|
if (IsPossibleObjCMethodName (name))
|
||||||
{
|
{
|
||||||
|
@ -122,35 +122,35 @@ ObjCLanguageRuntime::ParseMethodName (const char *name,
|
||||||
// "]" suffix
|
// "]" suffix
|
||||||
if (name_len >= 6 && name[name_len - 1] == ']')
|
if (name_len >= 6 && name[name_len - 1] == ']')
|
||||||
{
|
{
|
||||||
const char *method_name_ptr;
|
const char *selector_name_ptr;
|
||||||
method_name_ptr = strchr (name, ' ');
|
selector_name_ptr = strchr (name, ' ');
|
||||||
if (method_name_ptr)
|
if (selector_name_ptr)
|
||||||
{
|
{
|
||||||
if (class_name)
|
if (class_name)
|
||||||
class_name->SetCStringWithLength (name + 2, method_name_ptr - name - 2);
|
class_name->SetCStringWithLength (name + 2, selector_name_ptr - name - 2);
|
||||||
|
|
||||||
// Skip the space
|
// Skip the space
|
||||||
++method_name_ptr;
|
++selector_name_ptr;
|
||||||
// Extract the objective C basename and add it to the
|
// Extract the objective C basename and add it to the
|
||||||
// accelerator tables
|
// accelerator tables
|
||||||
size_t method_name_len = name_len - (method_name_ptr - name) - 1;
|
size_t selector_name_len = name_len - (selector_name_ptr - name) - 1;
|
||||||
if (method_name)
|
if (selector_name)
|
||||||
method_name->SetCStringWithLength (method_name_ptr, method_name_len);
|
selector_name->SetCStringWithLength (selector_name_ptr, selector_name_len);
|
||||||
|
|
||||||
// Also see if this is a "category" on our class. If so strip off the category name,
|
// Also see if this is a "category" on our class. If so strip off the category name,
|
||||||
// and add the class name without it to the basename table.
|
// and add the class name without it to the basename table.
|
||||||
|
|
||||||
if (base_name)
|
if (name_sans_category)
|
||||||
{
|
{
|
||||||
const char *first_paren = (char *) memchr (name, '(', method_name_ptr - name);
|
const char *first_paren = (char *) memchr (name, '(', selector_name_ptr - name);
|
||||||
if (first_paren)
|
if (first_paren)
|
||||||
{
|
{
|
||||||
const char *second_paren = (char *) memchr (first_paren, ')', method_name_ptr - first_paren);
|
const char *second_paren = (char *) memchr (first_paren, ')', selector_name_ptr - first_paren);
|
||||||
if (second_paren)
|
if (second_paren)
|
||||||
{
|
{
|
||||||
std::string buffer (name, first_paren - name);
|
std::string buffer (name, first_paren - name);
|
||||||
buffer.append (second_paren + 1);
|
buffer.append (second_paren + 1);
|
||||||
base_name->SetCString (buffer.c_str());
|
name_sans_category->SetCString (buffer.c_str());
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -261,6 +261,7 @@ lldb_private::GetSectionTypeAsCString (SectionType sect_type)
|
||||||
case eSectionTypeDWARFDebugStr: return "dwarf-str";
|
case eSectionTypeDWARFDebugStr: return "dwarf-str";
|
||||||
case eSectionTypeDWARFAppleNames: return "apple-names";
|
case eSectionTypeDWARFAppleNames: return "apple-names";
|
||||||
case eSectionTypeDWARFAppleTypes: return "apple-types";
|
case eSectionTypeDWARFAppleTypes: return "apple-types";
|
||||||
|
case eSectionTypeDWARFAppleNamespaces: return "apple-namespaces";
|
||||||
case eSectionTypeEHFrame: return "eh-frame";
|
case eSectionTypeEHFrame: return "eh-frame";
|
||||||
case eSectionTypeOther: return "regular";
|
case eSectionTypeOther: return "regular";
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue