forked from OSchip/llvm-project
Added the ability for clients to grab a set of symbol table indexes and then
add them to a fast lookup map. lldb_private::Symtab now export the following public typedefs: namespace lldb_private { class Symtab { typedef std::vector<uint32_t> IndexCollection; typedef UniqueCStringMap<uint32_t> NameToIndexMap; }; } Clients can then find symbols by name and or type and end up with a Symtab::IndexCollection that is filled with indexes. These indexes can then be put into a name to index lookup map and control if the mangled and demangled names get added to the map: bool add_demangled = true; bool add_mangled = true; Symtab::NameToIndexMap name_to_index; symtab->AppendSymbolNamesToMap (indexes, add_demangled, add_mangled, name_to_index). This can be repeated as many times as needed to get a lookup table that you are happy with, and then this can be sorted: name_to_index.Sort(); Now name lookups can be done using a subset of the symbols you extracted from the symbol table. This is currently being used to extract objective C types from object files when there is no debug info in SymbolFileSymtab. Cleaned up how the objective C types were being vended to be more efficient and fixed some errors in the regular expression that was being used. llvm-svn: 145777
This commit is contained in:
parent
fb9968d6f1
commit
1075acafeb
|
@ -23,17 +23,20 @@ namespace lldb_private {
|
|||
class Symtab
|
||||
{
|
||||
public:
|
||||
typedef enum Debug {
|
||||
eDebugNo, // Not a debug symbol
|
||||
eDebugYes, // A debug symbol
|
||||
eDebugAny
|
||||
} Debug;
|
||||
typedef std::vector<uint32_t> IndexCollection;
|
||||
typedef UniqueCStringMap<uint32_t> NameToIndexMap;
|
||||
|
||||
typedef enum Visibility {
|
||||
eVisibilityAny,
|
||||
eVisibilityExtern,
|
||||
eVisibilityPrivate
|
||||
} Visibility;
|
||||
typedef enum Debug {
|
||||
eDebugNo, // Not a debug symbol
|
||||
eDebugYes, // A debug symbol
|
||||
eDebugAny
|
||||
} Debug;
|
||||
|
||||
typedef enum Visibility {
|
||||
eVisibilityAny,
|
||||
eVisibilityExtern,
|
||||
eVisibilityPrivate
|
||||
} Visibility;
|
||||
|
||||
Symtab(ObjectFile *objfile);
|
||||
~Symtab();
|
||||
|
@ -88,6 +91,12 @@ public:
|
|||
m_symbols.swap (new_symbols);
|
||||
}
|
||||
}
|
||||
|
||||
void AppendSymbolNamesToMap (const IndexCollection &indexes,
|
||||
bool add_demangled,
|
||||
bool add_mangled,
|
||||
NameToIndexMap &name_to_index_map) const;
|
||||
|
||||
protected:
|
||||
typedef std::vector<Symbol> collection;
|
||||
typedef collection::iterator iterator;
|
||||
|
|
|
@ -1748,7 +1748,7 @@ IRForTarget::HandleObjCClass(Value *classlist_reference)
|
|||
|
||||
StringRef name(initializer->getName());
|
||||
lldb_private::ConstString name_cstr(name.str().c_str());
|
||||
lldb::addr_t class_ptr = m_decl_map->GetSymbolAddress(name_cstr, lldb::eSymbolTypeRuntime);
|
||||
lldb::addr_t class_ptr = m_decl_map->GetSymbolAddress(name_cstr, lldb::eSymbolTypeObjCClass);
|
||||
|
||||
if (log)
|
||||
log->Printf("Found reference to Objective-C class %s (0x%llx)", name_cstr.AsCString(), (unsigned long long)class_ptr);
|
||||
|
|
|
@ -62,9 +62,7 @@ SymbolFileSymtab::SymbolFileSymtab(ObjectFile* obj_file) :
|
|||
m_source_indexes(),
|
||||
m_func_indexes(),
|
||||
m_code_indexes(),
|
||||
m_data_indexes(),
|
||||
m_addr_indexes(),
|
||||
m_has_objc_symbols(eLazyBoolCalculate)
|
||||
m_objc_class_name_to_index ()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -80,12 +78,6 @@ SymbolFileSymtab::GetClangASTContext ()
|
|||
return ast;
|
||||
}
|
||||
|
||||
bool
|
||||
SymbolFileSymtab::HasObjCSymbols ()
|
||||
{
|
||||
return (m_abilities & RuntimeTypes) != 0;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
SymbolFileSymtab::CalculateAbilities ()
|
||||
{
|
||||
|
@ -95,45 +87,43 @@ SymbolFileSymtab::CalculateAbilities ()
|
|||
const Symtab *symtab = m_obj_file->GetSymtab();
|
||||
if (symtab)
|
||||
{
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// The snippet of code below will get the indexes the module symbol
|
||||
// table entries that are code, data, or function related (debug info),
|
||||
// sort them by value (address) and dump the sorted symbols.
|
||||
//----------------------------------------------------------------------
|
||||
symtab->AppendSymbolIndexesWithType(eSymbolTypeSourceFile, m_source_indexes);
|
||||
if (!m_source_indexes.empty())
|
||||
if (symtab->AppendSymbolIndexesWithType(eSymbolTypeSourceFile, m_source_indexes))
|
||||
{
|
||||
abilities |= CompileUnits;
|
||||
}
|
||||
symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, m_func_indexes);
|
||||
if (!m_func_indexes.empty())
|
||||
|
||||
if (symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, m_func_indexes))
|
||||
{
|
||||
symtab->SortSymbolIndexesByValue(m_func_indexes, true);
|
||||
abilities |= Functions;
|
||||
}
|
||||
|
||||
symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny, m_code_indexes);
|
||||
if (!m_code_indexes.empty())
|
||||
if (symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny, m_code_indexes))
|
||||
{
|
||||
symtab->SortSymbolIndexesByValue(m_code_indexes, true);
|
||||
abilities |= Labels;
|
||||
}
|
||||
|
||||
symtab->AppendSymbolIndexesWithType(eSymbolTypeData, m_data_indexes);
|
||||
|
||||
if (!m_data_indexes.empty())
|
||||
if (symtab->AppendSymbolIndexesWithType(eSymbolTypeData, m_data_indexes))
|
||||
{
|
||||
symtab->SortSymbolIndexesByValue(m_data_indexes, true);
|
||||
abilities |= GlobalVariables;
|
||||
}
|
||||
|
||||
symtab->AppendSymbolIndexesWithType(eSymbolTypeObjCClass, m_objc_class_indexes);
|
||||
|
||||
if (!m_objc_class_indexes.empty())
|
||||
lldb_private::Symtab::IndexCollection objc_class_indexes;
|
||||
if (symtab->AppendSymbolIndexesWithType (eSymbolTypeObjCClass, objc_class_indexes))
|
||||
{
|
||||
symtab->SortSymbolIndexesByValue(m_objc_class_indexes, true);
|
||||
abilities |= RuntimeTypes;
|
||||
symtab->AppendSymbolNamesToMap (objc_class_indexes,
|
||||
true,
|
||||
true,
|
||||
m_objc_class_name_to_index);
|
||||
m_objc_class_name_to_index.Sort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -384,12 +374,17 @@ static int CountMethodArgs(const char *method_signature)
|
|||
}
|
||||
|
||||
uint32_t
|
||||
SymbolFileSymtab::FindTypes (const lldb_private::SymbolContext& sc, const lldb_private::ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, lldb_private::TypeList& types)
|
||||
SymbolFileSymtab::FindTypes (const lldb_private::SymbolContext& sc,
|
||||
const lldb_private::ConstString &name,
|
||||
const ClangNamespaceDecl *namespace_decl,
|
||||
bool append,
|
||||
uint32_t max_matches,
|
||||
lldb_private::TypeList& types)
|
||||
{
|
||||
if (!append)
|
||||
types.Clear();
|
||||
|
||||
if (HasObjCSymbols())
|
||||
if (!m_objc_class_name_to_index.IsEmpty())
|
||||
{
|
||||
TypeMap::iterator iter = m_objc_class_types.find(name);
|
||||
|
||||
|
@ -398,47 +393,48 @@ SymbolFileSymtab::FindTypes (const lldb_private::SymbolContext& sc, const lldb_p
|
|||
types.Insert(iter->second);
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::vector<uint32_t> indices;
|
||||
/*const ConstString &name, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& symbol_indexes*/
|
||||
if (m_obj_file->GetSymtab()->FindAllSymbolsWithNameAndType(name, lldb::eSymbolTypeAny, Symtab::eDebugNo, Symtab::eVisibilityAny, m_objc_class_indexes) == 0)
|
||||
return 0;
|
||||
|
||||
const Symtab::NameToIndexMap::Entry *match = m_objc_class_name_to_index.FindFirstValueForName(name.GetCString());
|
||||
|
||||
if (match == NULL)
|
||||
return 0;
|
||||
|
||||
const bool isForwardDecl = false;
|
||||
const bool isInternal = true;
|
||||
|
||||
ClangASTContext &clang_ast_ctx = GetClangASTContext();
|
||||
ClangASTContext &ast = GetClangASTContext();
|
||||
|
||||
lldb::clang_type_t objc_object_type = clang_ast_ctx.CreateObjCClass(name.AsCString(), clang_ast_ctx.GetTranslationUnitDecl(), isForwardDecl, isInternal);
|
||||
|
||||
const char *class_method_prefix = "^\\+\\[";
|
||||
const char *instance_method_prefix = "^\\-\\[";
|
||||
const char *method_suffix = " [a-zA-Z0-9:]+\\]$";
|
||||
lldb::clang_type_t objc_object_type = ast.CreateObjCClass (name.AsCString(),
|
||||
ast.GetTranslationUnitDecl(),
|
||||
isForwardDecl,
|
||||
isInternal);
|
||||
|
||||
ast.StartTagDeclarationDefinition (objc_object_type);
|
||||
|
||||
std::string regex_str("^[-+]\\["); // Make sure it starts with "+[" or "-["
|
||||
regex_str.append(name.AsCString()); // Followed by the class name
|
||||
regex_str.append("[ \\(]"); // Followed by a space or '(' (for a category)
|
||||
RegularExpression regex(regex_str.c_str());
|
||||
|
||||
std::string class_method_regexp_str(class_method_prefix);
|
||||
class_method_regexp_str.append(name.AsCString());
|
||||
class_method_regexp_str.append(method_suffix);
|
||||
Symtab::IndexCollection indices;
|
||||
|
||||
RegularExpression class_method_regexp(class_method_regexp_str.c_str());
|
||||
|
||||
indices.clear();
|
||||
|
||||
lldb::clang_type_t unknown_type = clang_ast_ctx.GetUnknownAnyType();
|
||||
lldb::clang_type_t unknown_type = ast.GetUnknownAnyType();
|
||||
std::vector<lldb::clang_type_t> arg_types;
|
||||
|
||||
if (m_obj_file->GetSymtab()->FindAllSymbolsMatchingRexExAndType(class_method_regexp, eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny, indices) != 0)
|
||||
if (m_obj_file->GetSymtab()->FindAllSymbolsMatchingRexExAndType (regex, eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny, indices) != 0)
|
||||
{
|
||||
for (std::vector<uint32_t>::iterator ii = indices.begin(), ie = indices.end();
|
||||
ii != ie;
|
||||
++ii)
|
||||
for (Symtab::IndexCollection::iterator pos = indices.begin(), end = indices.end();
|
||||
pos != end;
|
||||
++pos)
|
||||
{
|
||||
Symbol *symbol = m_obj_file->GetSymtab()->SymbolAtIndex(*ii);
|
||||
Symbol *symbol = m_obj_file->GetSymtab()->SymbolAtIndex(*pos);
|
||||
|
||||
if (!symbol)
|
||||
continue;
|
||||
|
||||
const char *signature = symbol->GetName().AsCString();
|
||||
|
||||
//printf ("%s: adding '%s'\n", name.GetCString(), signature);
|
||||
int num_args = CountMethodArgs(signature);
|
||||
|
||||
while (arg_types.size() < num_args)
|
||||
|
@ -447,55 +443,29 @@ SymbolFileSymtab::FindTypes (const lldb_private::SymbolContext& sc, const lldb_p
|
|||
bool is_variadic = false;
|
||||
unsigned type_quals = 0;
|
||||
|
||||
lldb::clang_type_t method_type = clang_ast_ctx.CreateFunctionType(unknown_type, arg_types.data(), num_args, is_variadic, type_quals);
|
||||
lldb::clang_type_t method_type = ast.CreateFunctionType (unknown_type,
|
||||
arg_types.data(),
|
||||
num_args,
|
||||
is_variadic,
|
||||
type_quals);
|
||||
|
||||
clang_ast_ctx.AddMethodToObjCObjectType(objc_object_type, signature, method_type, eAccessPublic);
|
||||
}
|
||||
}
|
||||
|
||||
std::string instance_method_regexp_str(instance_method_prefix);
|
||||
instance_method_regexp_str.append(name.AsCString());
|
||||
instance_method_regexp_str.append(method_suffix);
|
||||
|
||||
RegularExpression instance_method_regexp(instance_method_regexp_str.c_str());
|
||||
|
||||
indices.clear();
|
||||
|
||||
if (m_obj_file->GetSymtab()->FindAllSymbolsMatchingRexExAndType(instance_method_regexp, eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny, indices) != 0)
|
||||
{
|
||||
for (std::vector<uint32_t>::iterator ii = indices.begin(), ie = indices.end();
|
||||
ii != ie;
|
||||
++ii)
|
||||
{
|
||||
Symbol *symbol = m_obj_file->GetSymtab()->SymbolAtIndex(*ii);
|
||||
|
||||
if (!symbol)
|
||||
continue;
|
||||
|
||||
const char *signature = symbol->GetName().AsCString();
|
||||
|
||||
int num_args = CountMethodArgs(signature);
|
||||
|
||||
while (arg_types.size() < num_args)
|
||||
arg_types.push_back(unknown_type);
|
||||
|
||||
bool is_variadic = false;
|
||||
unsigned type_quals = 0;
|
||||
|
||||
lldb::clang_type_t method_type = clang_ast_ctx.CreateFunctionType(unknown_type, arg_types.data(), num_args, is_variadic, type_quals);
|
||||
|
||||
clang_ast_ctx.AddMethodToObjCObjectType(objc_object_type, signature, method_type, eAccessPublic);
|
||||
ast.AddMethodToObjCObjectType (objc_object_type,
|
||||
signature,
|
||||
method_type,
|
||||
eAccessPublic);
|
||||
}
|
||||
}
|
||||
|
||||
ast.CompleteTagDeclarationDefinition (objc_object_type);
|
||||
|
||||
Declaration decl;
|
||||
|
||||
lldb::TypeSP type(new Type (indices[0],
|
||||
this,
|
||||
name,
|
||||
0 /*byte_size*/,
|
||||
NULL /*SymbolContextScope*/,
|
||||
0 /*encoding_uid*/,
|
||||
0, // byte_size
|
||||
NULL, // SymbolContextScope*
|
||||
0, // encoding_uid
|
||||
Type::eEncodingInvalid,
|
||||
decl,
|
||||
objc_object_type,
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#define liblldb_SymbolFileSymtab_h_
|
||||
|
||||
#include "lldb/Symbol/SymbolFile.h"
|
||||
#include "lldb/Symbol/Symtab.h"
|
||||
#include <vector>
|
||||
|
||||
class SymbolFileSymtab : public lldb_private::SymbolFile
|
||||
|
@ -119,22 +120,15 @@ public:
|
|||
GetPluginVersion();
|
||||
|
||||
protected:
|
||||
std::vector<uint32_t> m_source_indexes;
|
||||
std::vector<uint32_t> m_func_indexes;
|
||||
std::vector<uint32_t> m_code_indexes;
|
||||
std::vector<uint32_t> m_data_indexes;
|
||||
std::vector<uint32_t> m_addr_indexes; // Anything that needs to go into an search by address
|
||||
std::vector<uint32_t> m_objc_class_indexes;
|
||||
|
||||
lldb_private::LazyBool m_has_objc_symbols;
|
||||
|
||||
typedef std::map<lldb_private::ConstString, lldb::TypeSP> TypeMap;
|
||||
|
||||
TypeMap m_objc_class_types;
|
||||
|
||||
bool
|
||||
HasObjCSymbols ();
|
||||
|
||||
lldb_private::Symtab::IndexCollection m_source_indexes;
|
||||
lldb_private::Symtab::IndexCollection m_func_indexes;
|
||||
lldb_private::Symtab::IndexCollection m_code_indexes;
|
||||
lldb_private::Symtab::IndexCollection m_data_indexes;
|
||||
lldb_private::Symtab::NameToIndexMap m_objc_class_name_to_index;
|
||||
TypeMap m_objc_class_types;
|
||||
|
||||
lldb_private::ClangASTContext &
|
||||
GetClangASTContext ();
|
||||
|
||||
|
|
|
@ -37,4 +37,4 @@ bool ClangExternalASTSourceCommon::HasMetadata (uintptr_t object)
|
|||
assert (m_magic == ClangExternalASTSourceCommon_MAGIC);
|
||||
|
||||
return m_metadata.find(object) != m_metadata.end();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -262,9 +262,6 @@ Symtab::InitNameIndexes()
|
|||
Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__);
|
||||
// Create the name index vector to be able to quickly search by name
|
||||
const size_t count = m_symbols.size();
|
||||
assert(m_objfile != NULL);
|
||||
assert(m_objfile->GetModule() != NULL);
|
||||
|
||||
#if 1
|
||||
m_name_to_index.Reserve (count);
|
||||
#else
|
||||
|
@ -287,7 +284,7 @@ Symtab::InitNameIndexes()
|
|||
m_name_to_index.Reserve (actual_count);
|
||||
#endif
|
||||
|
||||
UniqueCStringMap<uint32_t>::Entry entry;
|
||||
NameToIndexMap::Entry entry;
|
||||
|
||||
for (entry.value = 0; entry.value < count; ++entry.value)
|
||||
{
|
||||
|
@ -328,6 +325,44 @@ Symtab::InitNameIndexes()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
Symtab::AppendSymbolNamesToMap (const IndexCollection &indexes,
|
||||
bool add_demangled,
|
||||
bool add_mangled,
|
||||
NameToIndexMap &name_to_index_map) const
|
||||
{
|
||||
if (add_demangled || add_mangled)
|
||||
{
|
||||
Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__);
|
||||
Mutex::Locker locker (m_mutex);
|
||||
|
||||
// Create the name index vector to be able to quickly search by name
|
||||
NameToIndexMap::Entry entry;
|
||||
const size_t num_indexes = indexes.size();
|
||||
for (size_t i=0; i<num_indexes; ++i)
|
||||
{
|
||||
entry.value = indexes[i];
|
||||
assert (i < m_symbols.size());
|
||||
const Symbol *symbol = &m_symbols[entry.value];
|
||||
|
||||
const Mangled &mangled = symbol->GetMangled();
|
||||
if (add_demangled)
|
||||
{
|
||||
entry.cstring = mangled.GetDemangledName().GetCString();
|
||||
if (entry.cstring && entry.cstring[0])
|
||||
name_to_index_map.Append (entry);
|
||||
}
|
||||
|
||||
if (add_mangled)
|
||||
{
|
||||
entry.cstring = mangled.GetMangledName().GetCString();
|
||||
if (entry.cstring && entry.cstring[0])
|
||||
name_to_index_map.Append (entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Symtab::AppendSymbolIndexesWithType (SymbolType symbol_type, std::vector<uint32_t>& indexes, uint32_t start_idx, uint32_t end_index) const
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue