diff options
| author | Greg Clayton <gclayton@apple.com> | 2013-10-21 18:40:51 +0000 |
|---|---|---|
| committer | Greg Clayton <gclayton@apple.com> | 2013-10-21 18:40:51 +0000 |
| commit | 9191db47dad0032653b024330c1f496f6cdee918 (patch) | |
| tree | a8bc588a9d615ffc209dba07c4fc843d0ac3b7a8 | |
| parent | f46e5f1c9a75fa22d13c50e51c6b2e6158f9e825 (diff) | |
| download | bcm5719-llvm-9191db47dad0032653b024330c1f496f6cdee918.tar.gz bcm5719-llvm-9191db47dad0032653b024330c1f496f6cdee918.zip | |
<rdar://problem/14496092>
Fixed an issue with reexported symbols on MacOSX by adding support for symbols re-exporting symbols. There is now a new symbol type eSymbolTypeReExported which contains a new name for the re-exported symbol and the new shared library. These symbols are only used when a symbol is re-exported as a symbol under a different name.
Modified the expression parser to be able to deal with finding the re-exported symbols and track down the actual symbol it refers to.
llvm-svn: 193101
| -rw-r--r-- | lldb/include/lldb/Expression/ClangExpressionDeclMap.h | 14 | ||||
| -rw-r--r-- | lldb/include/lldb/Symbol/Symbol.h | 33 | ||||
| -rw-r--r-- | lldb/include/lldb/lldb-enumerations.h | 3 | ||||
| -rw-r--r-- | lldb/source/Expression/ClangExpressionDeclMap.cpp | 82 | ||||
| -rw-r--r-- | lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp | 275 | ||||
| -rw-r--r-- | lldb/source/Symbol/ObjectFile.cpp | 1 | ||||
| -rw-r--r-- | lldb/source/Symbol/Symbol.cpp | 120 | ||||
| -rw-r--r-- | lldb/source/Symbol/Symtab.cpp | 1 |
8 files changed, 456 insertions, 73 deletions
diff --git a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h index b2a43e0ac75..b04e1bd6f11 100644 --- a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h +++ b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h @@ -291,6 +291,9 @@ public: /// @param[in] name /// The name of the symbol. /// + /// @param[in] module + /// The module to limit the search to. This can be NULL + /// /// @return /// Valid load address for the symbol //------------------------------------------------------------------ @@ -298,7 +301,8 @@ public: GetSymbolAddress (Target &target, Process *process, const ConstString &name, - lldb::SymbolType symbol_type); + lldb::SymbolType symbol_type, + Module *module = NULL); lldb::addr_t GetSymbolAddress (const ConstString &name, @@ -504,12 +508,16 @@ private: /// @param[in] name /// The name as a plain C string. /// + /// @param[in] module + /// The module to limit the search to. This can be NULL + /// /// @return /// The LLDB Symbol found, or NULL if none was found. - //--------------------------------------------------------- + //------------------------------------------------------------------ const Symbol * FindGlobalDataSymbol (Target &target, - const ConstString &name); + const ConstString &name, + Module *module = NULL); //------------------------------------------------------------------ /// Given a target, find a variable that matches the given name and diff --git a/lldb/include/lldb/Symbol/Symbol.h b/lldb/include/lldb/Symbol/Symbol.h index 11c1cc7af9a..75e0900ab64 100644 --- a/lldb/include/lldb/Symbol/Symbol.h +++ b/lldb/include/lldb/Symbol/Symbol.h @@ -122,6 +122,21 @@ public: return m_mangled; } + ConstString + GetReExportedSymbolName() const; + + FileSpec + GetReExportedSymbolSharedLibrary () const; + + bool + SetReExportedSymbolName(const ConstString &name); + + bool + SetReExportedSymbolSharedLibrary (const FileSpec &fspec); + + Symbol * + ResolveReExportedSymbol (Target &target); + uint32_t GetSiblingIndex () const; @@ -238,24 +253,6 @@ public: m_size_is_sibling = b; } -// void -// SetValue (Address &value) -// { -// m_addr_range.GetBaseAddress() = value; -// } -// -// void -// SetValue (const AddressRange &range) -// { -// m_addr_range = range; -// } -// -// void -// SetValue (lldb::addr_t value); -// { -// m_addr_range.GetBaseAddress().SetRawAddress(value); -// } - // If m_type is "Code" or "Function" then this will return the prologue size // in bytes, else it will return zero. uint32_t diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index 40b77ed4b91..ae8c92be900 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -484,7 +484,8 @@ namespace lldb { eSymbolTypeUndefined, eSymbolTypeObjCClass, eSymbolTypeObjCMetaClass, - eSymbolTypeObjCIVar + eSymbolTypeObjCIVar, + eSymbolTypeReExported } SymbolType; typedef enum SectionType diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp index cdc32532361..5a0b646e004 100644 --- a/lldb/source/Expression/ClangExpressionDeclMap.cpp +++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp @@ -21,6 +21,7 @@ #include "lldb/Core/Error.h" #include "lldb/Core/Log.h" #include "lldb/Core/Module.h" +#include "lldb/Core/ModuleSpec.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectVariable.h" @@ -591,11 +592,18 @@ ClangExpressionDeclMap::GetFunctionAddress } addr_t -ClangExpressionDeclMap::GetSymbolAddress (Target &target, Process *process, const ConstString &name, lldb::SymbolType symbol_type) +ClangExpressionDeclMap::GetSymbolAddress (Target &target, + Process *process, + const ConstString &name, + lldb::SymbolType symbol_type, + Module *module) { SymbolContextList sc_list; - target.GetImages().FindSymbolsWithNameAndType(name, symbol_type, sc_list); + if (module) + module->FindSymbolsWithNameAndType(name, symbol_type, sc_list); + else + target.GetImages().FindSymbolsWithNameAndType(name, symbol_type, sc_list); const uint32_t num_matches = sc_list.GetSize(); addr_t symbol_load_addr = LLDB_INVALID_ADDRESS; @@ -623,6 +631,28 @@ ClangExpressionDeclMap::GetSymbolAddress (Target &target, Process *process, cons symbol_load_addr = sym_address->GetCallableLoadAddress (&target, true); break; + case eSymbolTypeReExported: + { + ConstString reexport_name = sym_ctx.symbol->GetReExportedSymbolName(); + if (reexport_name) + { + ModuleSP reexport_module_sp; + ModuleSpec reexport_module_spec; + reexport_module_spec.GetPlatformFileSpec() = sym_ctx.symbol->GetReExportedSymbolSharedLibrary(); + if (reexport_module_spec.GetPlatformFileSpec()) + { + reexport_module_sp = target.GetImages().FindFirstModule(reexport_module_spec); + if (!reexport_module_sp) + { + reexport_module_spec.GetPlatformFileSpec().GetDirectory().Clear(); + reexport_module_sp = target.GetImages().FindFirstModule(reexport_module_spec); + } + } + symbol_load_addr = GetSymbolAddress(target, process, sym_ctx.symbol->GetReExportedSymbolName(), symbol_type, reexport_module_sp.get()); + } + } + break; + case eSymbolTypeData: case eSymbolTypeRuntime: case eSymbolTypeVariable: @@ -680,11 +710,15 @@ ClangExpressionDeclMap::GetSymbolAddress (const ConstString &name, lldb::SymbolT const Symbol * ClangExpressionDeclMap::FindGlobalDataSymbol (Target &target, - const ConstString &name) + const ConstString &name, + Module *module) { SymbolContextList sc_list; - target.GetImages().FindSymbolsWithNameAndType(name, eSymbolTypeAny, sc_list); + if (module) + module->FindSymbolsWithNameAndType(name, eSymbolTypeAny, sc_list); + else + target.GetImages().FindSymbolsWithNameAndType(name, eSymbolTypeAny, sc_list); const uint32_t matches = sc_list.GetSize(); for (uint32_t i=0; i<matches; ++i) @@ -716,6 +750,28 @@ ClangExpressionDeclMap::FindGlobalDataSymbol (Target &target, } return symbol; + case eSymbolTypeReExported: + { + ConstString reexport_name = symbol->GetReExportedSymbolName(); + if (reexport_name) + { + ModuleSP reexport_module_sp; + ModuleSpec reexport_module_spec; + reexport_module_spec.GetPlatformFileSpec() = symbol->GetReExportedSymbolSharedLibrary(); + if (reexport_module_spec.GetPlatformFileSpec()) + { + reexport_module_sp = target.GetImages().FindFirstModule(reexport_module_spec); + if (!reexport_module_sp) + { + reexport_module_spec.GetPlatformFileSpec().GetDirectory().Clear(); + reexport_module_sp = target.GetImages().FindFirstModule(reexport_module_spec); + } + } + return FindGlobalDataSymbol(target, symbol->GetReExportedSymbolName(), reexport_module_sp.get()); + } + } + break; + case eSymbolTypeCode: // We already lookup functions elsewhere case eSymbolTypeVariable: case eSymbolTypeLocal: @@ -1286,8 +1342,7 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context, if (sc_list.GetSize()) { - Symbol *generic_symbol = NULL; - Symbol *non_extern_symbol = NULL; + Symbol *symbol = NULL; for (uint32_t index = 0, num_indices = sc_list.GetSize(); index < num_indices; @@ -1315,23 +1370,18 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context, } else if (sym_ctx.symbol) { - if (sym_ctx.symbol->IsExternal()) - generic_symbol = sym_ctx.symbol; + if (sym_ctx.symbol->GetType() == eSymbolTypeReExported) + symbol = sym_ctx.symbol->ResolveReExportedSymbol(*target); else - non_extern_symbol = sym_ctx.symbol; + symbol = sym_ctx.symbol; } } if (!context.m_found.function_with_type_info) { - if (generic_symbol) - { - AddOneFunction (context, NULL, generic_symbol, current_id); - context.m_found.function = true; - } - else if (non_extern_symbol) + if (symbol) { - AddOneFunction (context, NULL, non_extern_symbol, current_id); + AddOneFunction (context, NULL, symbol, current_id); context.m_found.function = true; } } diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index 36652310470..a11ca26a9ad 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -894,6 +894,7 @@ ObjectFileMachO::GetAddressClass (lldb::addr_t file_addr) case eSymbolTypeObjCClass: return eAddressClassRuntime; case eSymbolTypeObjCMetaClass: return eAddressClassRuntime; case eSymbolTypeObjCIVar: return eAddressClassRuntime; + case eSymbolTypeReExported: return eAddressClassRuntime; } } } @@ -1481,6 +1482,138 @@ protected: std::vector<SectionInfo> m_section_infos; }; +struct TrieEntry +{ + TrieEntry () : + name(), + address(LLDB_INVALID_ADDRESS), + flags (0), + other(0), + import_name() + { + } + + void + Clear () + { + name.Clear(); + address = LLDB_INVALID_ADDRESS; + flags = 0; + other = 0; + import_name.Clear(); + } + + void + Dump () const + { + printf ("0x%16.16llx 0x%16.16llx 0x%16.16llx \"%s\"", address, flags, other, name.GetCString()); + if (import_name) + printf (" -> \"%s\"\n", import_name.GetCString()); + else + printf ("\n"); + } + ConstString name; + uint64_t address; + uint64_t flags; + uint64_t other; + ConstString import_name; +}; + +struct TrieEntryWithOffset +{ + lldb::offset_t nodeOffset; + TrieEntry entry; + + TrieEntryWithOffset (lldb::offset_t offset) : + nodeOffset (offset), + entry() + { + } + + void + Dump (uint32_t idx) const + { + printf ("[%3u] 0x%16.16llx: ", idx, nodeOffset); + entry.Dump(); + } + + bool + operator<(const TrieEntryWithOffset& other) const + { + return ( nodeOffset < other.nodeOffset ); + } +}; + +static void +ParseTrieEntries (DataExtractor &data, + lldb::offset_t offset, + std::vector<llvm::StringRef> &nameSlices, + std::set<lldb::addr_t> &resolver_addresses, + std::vector<TrieEntryWithOffset>& output) +{ + if (!data.ValidOffset(offset)) + return; + + const uint64_t terminalSize = data.GetULEB128(&offset); + lldb::offset_t children_offset = offset + terminalSize; + if ( terminalSize != 0 ) { + TrieEntryWithOffset e (offset); + e.entry.flags = data.GetULEB128(&offset); + const char *import_name = NULL; + if ( e.entry.flags & EXPORT_SYMBOL_FLAGS_REEXPORT ) { + e.entry.address = 0; + e.entry.other = data.GetULEB128(&offset); // dylib ordinal + import_name = data.GetCStr(&offset); + } + else { + e.entry.address = data.GetULEB128(&offset); + if ( e.entry.flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER ) + { + resolver_addresses.insert(e.entry.address); + e.entry.other = data.GetULEB128(&offset); + } + else + e.entry.other = 0; + } + // Only add symbols that are reexport symbols with a valid import name + if (EXPORT_SYMBOL_FLAGS_REEXPORT & e.entry.flags && import_name && import_name[0]) + { + std::string name; + if (!nameSlices.empty()) + { + for (auto name_slice: nameSlices) + name.append(name_slice.data(), name_slice.size()); + } + if (name.size() > 1) + { + // Skip the leading '_' + e.entry.name.SetCStringWithLength(name.c_str() + 1,name.size() - 1); + } + if (import_name) + { + // Skip the leading '_' + e.entry.import_name.SetCString(import_name+1); + } + output.push_back(e); + } + } + + const uint8_t childrenCount = data.GetU8(&children_offset); + for (uint8_t i=0; i < childrenCount; ++i) { + nameSlices.push_back(data.GetCStr(&children_offset)); + lldb::offset_t childNodeOffset = data.GetULEB128(&children_offset); + if (childNodeOffset) + { + ParseTrieEntries(data, + childNodeOffset, + nameSlices, + resolver_addresses, + output); + } + nameSlices.pop_back(); + } +} + size_t ObjectFileMachO::ParseSymtab () { @@ -1493,11 +1626,12 @@ ObjectFileMachO::ParseSymtab () struct symtab_command symtab_load_command = { 0, 0, 0, 0, 0, 0 }; struct linkedit_data_command function_starts_load_command = { 0, 0, 0, 0 }; + struct dyld_info_command dyld_info = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; typedef AddressDataArray<lldb::addr_t, bool, 100> FunctionStarts; FunctionStarts function_starts; lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); uint32_t i; - + FileSpecList dylib_files; Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS)); for (i=0; i<m_header.ncmds; ++i) @@ -1545,6 +1679,39 @@ ObjectFileMachO::ParseSymtab () } break; + case LC_DYLD_INFO: + case LC_DYLD_INFO_ONLY: + if (m_data.GetU32(&offset, &dyld_info.rebase_off, 10)) + { + dyld_info.cmd = lc.cmd; + dyld_info.cmdsize = lc.cmdsize; + } + else + { + memset (&dyld_info, 0, sizeof(dyld_info)); + } + break; + + case LC_LOAD_DYLIB: + case LC_LOAD_WEAK_DYLIB: + case LC_REEXPORT_DYLIB: + case LC_LOADFVMLIB: + case LC_LOAD_UPWARD_DYLIB: + { + uint32_t name_offset = cmd_offset + m_data.GetU32(&offset); + const char *path = m_data.PeekCStr(name_offset); + if (path) + { + FileSpec file_spec(path, false); + // Strip the path if there is @rpath, @executanble, etc so we just use the basename + if (path[0] == '@') + file_spec.GetDirectory().Clear(); + + dylib_files.Append(file_spec); + } + } + break; + case LC_FUNCTION_STARTS: function_starts_load_command.cmd = lc.cmd; function_starts_load_command.cmdsize = lc.cmdsize; @@ -1574,6 +1741,7 @@ ObjectFileMachO::ParseSymtab () DataExtractor strtab_data (NULL, 0, byte_order, addr_byte_size); DataExtractor function_starts_data (NULL, 0, byte_order, addr_byte_size); DataExtractor indirect_symbol_index_data (NULL, 0, byte_order, addr_byte_size); + DataExtractor dyld_trie_data (NULL, 0, byte_order, addr_byte_size); const addr_t nlist_data_byte_size = symtab_load_command.nsyms * nlist_byte_size; const addr_t strtab_data_byte_size = symtab_load_command.strsize; @@ -1689,6 +1857,14 @@ ObjectFileMachO::ParseSymtab () strtab_data.SetData (m_data, symtab_load_command.stroff, strtab_data_byte_size); + + if (dyld_info.export_size > 0) + { + dyld_trie_data.SetData (m_data, + dyld_info.export_off, + dyld_info.export_size); + } + if (m_dysymtab.nindirectsyms != 0) { indirect_symbol_index_data.SetData (m_data, @@ -2661,6 +2837,7 @@ ObjectFileMachO::ParseSymtab () m_nlist_idx_to_sym_idx[nlist_idx] = pos->second; // We just need the flags from the linker symbol, so put these flags // into the N_FUN flags to avoid duplicate symbols in the symbol table + sym[pos->second].SetExternal(sym[sym_idx].IsExternal()); sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc); sym[sym_idx].Clear(); continue; @@ -2681,6 +2858,7 @@ ObjectFileMachO::ParseSymtab () m_nlist_idx_to_sym_idx[nlist_idx] = pos->second; // We just need the flags from the linker symbol, so put these flags // into the N_STSYM flags to avoid duplicate symbols in the symbol table + sym[pos->second].SetExternal(sym[sym_idx].IsExternal()); sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc); sym[sym_idx].Clear(); continue; @@ -3404,6 +3582,7 @@ ObjectFileMachO::ParseSymtab () m_nlist_idx_to_sym_idx[nlist_idx] = pos->second; // We just need the flags from the linker symbol, so put these flags // into the N_FUN flags to avoid duplicate symbols in the symbol table + sym[pos->second].SetExternal(sym[sym_idx].IsExternal()); sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc); sym[sym_idx].Clear(); continue; @@ -3424,6 +3603,7 @@ ObjectFileMachO::ParseSymtab () m_nlist_idx_to_sym_idx[nlist_idx] = pos->second; // We just need the flags from the linker symbol, so put these flags // into the N_STSYM flags to avoid duplicate symbols in the symbol table + sym[pos->second].SetExternal(sym[sym_idx].IsExternal()); sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc); sym[sym_idx].Clear(); continue; @@ -3469,38 +3649,6 @@ ObjectFileMachO::ParseSymtab () { sym[sym_idx].Clear(); } - - } - - // STAB N_GSYM entries end up having a symbol type eSymbolTypeGlobal and when the symbol value - // is zero, the address of the global ends up being in a non-STAB entry. Try and fix up all - // such entries by figuring out what the address for the global is by looking up this non-STAB - // entry and copying the value into the debug symbol's value to save us the hassle in the - // debug symbol parser. - - Symbol *global_symbol = NULL; - for (nlist_idx = 0; - nlist_idx < symtab_load_command.nsyms && (global_symbol = symtab->FindSymbolWithType (eSymbolTypeData, Symtab::eDebugYes, Symtab::eVisibilityAny, nlist_idx)) != NULL; - nlist_idx++) - { - if (global_symbol->GetAddress().GetFileAddress() == 0) - { - std::vector<uint32_t> indexes; - if (symtab->AppendSymbolIndexesWithName (global_symbol->GetMangled().GetName(), indexes) > 0) - { - std::vector<uint32_t>::const_iterator pos; - std::vector<uint32_t>::const_iterator end = indexes.end(); - for (pos = indexes.begin(); pos != end; ++pos) - { - symbol_ptr = symtab->SymbolAtIndex(*pos); - if (symbol_ptr != global_symbol && symbol_ptr->IsDebug() == false) - { - global_symbol->GetAddress() = symbol_ptr->GetAddress(); - break; - } - } - } - } } } @@ -3588,6 +3736,31 @@ ObjectFileMachO::ParseSymtab () sym = symtab->Resize (num_syms); } + std::vector<TrieEntryWithOffset> trie_entries; + std::set<lldb::addr_t> resolver_addresses; + + if (dyld_trie_data.GetByteSize() > 0) + { + std::vector<llvm::StringRef> nameSlices; + ParseTrieEntries (dyld_trie_data, + 0, + nameSlices, + resolver_addresses, + trie_entries); + + ConstString text_segment_name ("__TEXT"); + SectionSP text_segment_sp = GetSectionList()->FindSectionByName(text_segment_name); + if (text_segment_sp) + { + const lldb::addr_t text_segment_file_addr = text_segment_sp->GetFileAddress(); + if (text_segment_file_addr != LLDB_INVALID_ADDRESS) + { + for (auto &e : trie_entries) + e.entry.address += text_segment_file_addr; + } + } + } + // Now synthesize indirect symbols if (m_dysymtab.nindirectsyms != 0) { @@ -3646,7 +3819,10 @@ ObjectFileMachO::ParseSymtab () // These symbols were N_UNDF N_EXT, and are useless to us, so we // can re-use them so we don't have to make up a synthetic symbol // for no good reason. - stub_symbol->SetType (eSymbolTypeTrampoline); + if (resolver_addresses.find(symbol_stub_addr) == resolver_addresses.end()) + stub_symbol->SetType (eSymbolTypeTrampoline); + else + stub_symbol->SetType (eSymbolTypeResolver); stub_symbol->SetExternal (false); stub_symbol->GetAddress() = so_addr; stub_symbol->SetByteSize (symbol_stub_byte_size); @@ -3662,7 +3838,10 @@ ObjectFileMachO::ParseSymtab () } sym[sym_idx].SetID (synthetic_sym_id++); sym[sym_idx].GetMangled() = stub_symbol_mangled_name; - sym[sym_idx].SetType (eSymbolTypeTrampoline); + if (resolver_addresses.find(symbol_stub_addr) == resolver_addresses.end()) + sym[sym_idx].SetType (eSymbolTypeTrampoline); + else + sym[sym_idx].SetType (eSymbolTypeResolver); sym[sym_idx].SetIsSynthetic (true); sym[sym_idx].GetAddress() = so_addr; sym[sym_idx].SetByteSize (symbol_stub_byte_size); @@ -3680,6 +3859,32 @@ ObjectFileMachO::ParseSymtab () } } } + + + if (!trie_entries.empty()) + { + for (const auto &e : trie_entries) + { + if (e.entry.import_name) + { + // Make a synthetic symbol to describe re-exported symbol. + if (sym_idx >= num_syms) + sym = symtab->Resize (++num_syms); + sym[sym_idx].SetID (synthetic_sym_id++); + sym[sym_idx].GetMangled() = Mangled(e.entry.name); + sym[sym_idx].SetType (eSymbolTypeReExported); + sym[sym_idx].SetIsSynthetic (true); + sym[sym_idx].SetReExportedSymbolName(e.entry.import_name); + if (e.entry.other > 0 && e.entry.other <= dylib_files.GetSize()) + { + sym[sym_idx].SetReExportedSymbolSharedLibrary(dylib_files.GetFileSpecAtIndex(e.entry.other-1)); + } + ++sym_idx; + } + } + } + + // StreamFile s(stdout, false); // s.Printf ("Symbol table before CalculateSymbolSizes():\n"); diff --git a/lldb/source/Symbol/ObjectFile.cpp b/lldb/source/Symbol/ObjectFile.cpp index 8eb4ea91b2d..ec69c9dd1e1 100644 --- a/lldb/source/Symbol/ObjectFile.cpp +++ b/lldb/source/Symbol/ObjectFile.cpp @@ -423,6 +423,7 @@ ObjectFile::GetAddressClass (addr_t file_addr) case eSymbolTypeObjCClass: return eAddressClassRuntime; case eSymbolTypeObjCMetaClass: return eAddressClassRuntime; case eSymbolTypeObjCIVar: return eAddressClassRuntime; + case eSymbolTypeReExported: return eAddressClassRuntime; } } } diff --git a/lldb/source/Symbol/Symbol.cpp b/lldb/source/Symbol/Symbol.cpp index 7f3543c3b23..a881b6f3101 100644 --- a/lldb/source/Symbol/Symbol.cpp +++ b/lldb/source/Symbol/Symbol.cpp @@ -10,6 +10,7 @@ #include "lldb/Symbol/Symbol.h" #include "lldb/Core/Module.h" +#include "lldb/Core/ModuleSpec.h" #include "lldb/Core/Section.h" #include "lldb/Core/Stream.h" #include "lldb/Symbol/ObjectFile.h" @@ -176,6 +177,66 @@ Symbol::ValueIsAddress() const return m_addr_range.GetBaseAddress().GetSection().get() != NULL; } +ConstString +Symbol::GetReExportedSymbolName() const +{ + if (m_type == eSymbolTypeReExported) + { + // For eSymbolTypeReExported, the "const char *" from a ConstString + // is used as the offset in the address range base address. We can + // then make this back into a string that is the re-exported name. + intptr_t str_ptr = m_addr_range.GetBaseAddress().GetOffset(); + if (str_ptr != 0) + return ConstString((const char *)str_ptr); + else + return GetName(); + } + return ConstString(); +} + +FileSpec +Symbol::GetReExportedSymbolSharedLibrary() const +{ + if (m_type == eSymbolTypeReExported) + { + // For eSymbolTypeReExported, the "const char *" from a ConstString + // is used as the offset in the address range base address. We can + // then make this back into a string that is the re-exported name. + intptr_t str_ptr = m_addr_range.GetByteSize(); + if (str_ptr != 0) + return FileSpec((const char *)str_ptr, false); + } + return FileSpec(); +} + +bool +Symbol::SetReExportedSymbolName(const ConstString &name) +{ + if (m_type == eSymbolTypeReExported) + { + // For eSymbolTypeReExported, the "const char *" from a ConstString + // is used as the offset in the address range base address. + m_addr_range.GetBaseAddress().SetOffset((intptr_t)name.GetCString()); + return true; + } + return false; + +} + +bool +Symbol::SetReExportedSymbolSharedLibrary(const FileSpec &fspec) +{ + if (m_type == eSymbolTypeReExported) + { + // For eSymbolTypeReExported, the "const char *" from a ConstString + // is used as the offset in the address range base address. + m_addr_range.SetByteSize((intptr_t)ConstString(fspec.GetPath().c_str()).GetCString()); + return true; + } + return false; + +} + uint32_t Symbol::GetSiblingIndex() const { @@ -267,6 +328,19 @@ Symbol::Dump(Stream *s, Target *target, uint32_t index) const m_flags, m_mangled.GetName().AsCString("")); } + else if (m_type == eSymbolTypeReExported) + { + s->Printf (" 0x%8.8x %s", + m_flags, + m_mangled.GetName().AsCString("")); + + ConstString reexport_name = GetReExportedSymbolName(); + intptr_t shlib = m_addr_range.GetByteSize(); + if (shlib) + s->Printf(" -> %s`%s\n", (const char *)shlib, reexport_name.GetCString()); + else + s->Printf(" -> %s\n", reexport_name.GetCString()); + } else { const char *format = m_size_is_sibling ? @@ -380,6 +454,7 @@ Symbol::GetTypeAsString() const ENUM_TO_CSTRING(Invalid); ENUM_TO_CSTRING(Absolute); ENUM_TO_CSTRING(Code); + ENUM_TO_CSTRING(Resolver); ENUM_TO_CSTRING(Data); ENUM_TO_CSTRING(Trampoline); ENUM_TO_CSTRING(Runtime); @@ -404,6 +479,7 @@ Symbol::GetTypeAsString() const ENUM_TO_CSTRING(ObjCClass); ENUM_TO_CSTRING(ObjCMetaClass); ENUM_TO_CSTRING(ObjCIVar); + ENUM_TO_CSTRING(ReExported); default: break; } @@ -460,3 +536,47 @@ Symbol::GetByteSize () const return m_addr_range.GetByteSize(); } +Symbol * +Symbol::ResolveReExportedSymbol (Target &target) +{ + ConstString reexport_name (GetReExportedSymbolName()); + if (reexport_name) + { + ModuleSpec module_spec; + ModuleSP module_sp; + module_spec.GetFileSpec() = GetReExportedSymbolSharedLibrary(); + if (module_spec.GetFileSpec()) + { + // Try searching for the module file spec first using the full path + module_sp = target.GetImages().FindFirstModule(module_spec); + if (!module_sp) + { + // Next try and find the module by basename in case environment + // variables or other runtime trickery causes shared libraries + // to be loaded from alternate paths + module_spec.GetFileSpec().GetDirectory().Clear(); + module_sp = target.GetImages().FindFirstModule(module_spec); + } + } + + if (module_sp) + { + lldb_private::SymbolContextList sc_list; + module_sp->FindSymbolsWithNameAndType(reexport_name, eSymbolTypeAny, sc_list); + const size_t num_scs = sc_list.GetSize(); + if (num_scs > 0) + { + for (size_t i=0; i<num_scs; ++i) + { + lldb_private::SymbolContext sc; + if (sc_list.GetContextAtIndex(i, sc)) + { + if (sc.symbol->IsExternal()) + return sc.symbol; + } + } + } + } + } + return NULL; +} diff --git a/lldb/source/Symbol/Symtab.cpp b/lldb/source/Symbol/Symtab.cpp index d3ea9d68e25..4d258855dfb 100644 --- a/lldb/source/Symbol/Symtab.cpp +++ b/lldb/source/Symbol/Symtab.cpp @@ -1135,6 +1135,7 @@ Symtab::FindFunctionSymbols (const ConstString &name, { case eSymbolTypeCode: case eSymbolTypeResolver: + case eSymbolTypeReExported: symbol_indexes.push_back(temp_symbol_indexes[i]); break; default: |

