Symtab.cpp revision 7e5fa7fc1f8efd24c078e063b2c4b5e13ba5be20
1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)//===-- Symtab.cpp ----------------------------------------------*- C++ -*-===// 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The LLVM Compiler Infrastructure 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)//===----------------------------------------------------------------------===// 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "lldb/Core/Module.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "lldb/Core/RegularExpression.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "lldb/Core/Timer.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "lldb/Symbol/ObjectFile.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "lldb/Symbol/Symtab.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "lldb/Target/ObjCLanguageRuntime.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using namespace lldb; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using namespace lldb_private; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Symtab::Symtab(ObjectFile *objfile) : 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_objfile (objfile), 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_symbols (), 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_addr_indexes (), 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_name_to_index (), 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_mutex (Mutex::eMutexTypeRecursive), 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_addr_indexes_computed (false), 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) m_name_indexes_computed (false) 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles){ 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Symtab::~Symtab() 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Symtab::Reserve(uint32_t count) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clients should grab the mutex from this symbol table and lock it manually 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // when calling this function to avoid performance issues. 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_symbols.reserve (count); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Symbol * 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Symtab::Resize(uint32_t count) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clients should grab the mutex from this symbol table and lock it manually 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // when calling this function to avoid performance issues. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_symbols.resize (count); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &m_symbols[0]; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32_t 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Symtab::AddSymbol(const Symbol& symbol) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clients should grab the mutex from this symbol table and lock it manually 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // when calling this function to avoid performance issues. 6158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) uint32_t symbol_idx = m_symbols.size(); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_name_to_index.Clear(); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_addr_indexes.clear(); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_symbols.push_back(symbol); 6558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) m_addr_indexes_computed = false; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_name_indexes_computed = false; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return symbol_idx; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Symtab::GetNumSymbols() const 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Mutex::Locker locker (m_mutex); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return m_symbols.size(); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Symtab::Dump (Stream *s, Target *target, SortOrder sort_order) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Mutex::Locker locker (m_mutex); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s->Indent(); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileSpec &file_spec = m_objfile->GetFileSpec(); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char * object_name = NULL; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (m_objfile->GetModule()) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) object_name = m_objfile->GetModule()->GetObjectName().GetCString(); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (file_spec) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s->Printf("Symtab, file = %s/%s%s%s%s, num_symbols = %lu", 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_spec.GetDirectory().AsCString(), 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_spec.GetFilename().AsCString(), 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) object_name ? "(" : "", 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) object_name ? object_name : "", 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) object_name ? ")" : "", 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_symbols.size()); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s->Printf("Symtab, num_symbols = %lu", m_symbols.size()); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!m_symbols.empty()) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (sort_order) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case eSortOrderNone: 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s->PutCString (":\n"); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DumpSymbolHeader (s); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const_iterator begin = m_symbols.begin(); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const_iterator end = m_symbols.end(); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (const_iterator pos = m_symbols.begin(); pos != end; ++pos) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s->Indent(); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos->Dump(s, target, std::distance(begin, pos)); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case eSortOrderByName: 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Although we maintain a lookup by exact name map, the table 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // isn't sorted by name. So we must make the ordered symbol list 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // up ourselves. 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s->PutCString (" (sorted by name):\n"); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DumpSymbolHeader (s); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::multimap<const char*, const Symbol *, CStringCompareFunctionObject> CStringToSymbol; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CStringToSymbol name_map; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (const_iterator pos = m_symbols.begin(), end = m_symbols.end(); pos != end; ++pos) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *name = pos->GetMangled().GetName(Mangled::ePreferDemangled).AsCString(); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (name && name[0]) 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) name_map.insert (std::make_pair(name, &(*pos))); 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (CStringToSymbol::const_iterator pos = name_map.begin(), end = name_map.end(); pos != end; ++pos) 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) { 13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) s->Indent(); 13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) pos->second->Dump (s, target, pos->second - &m_symbols[0]); 1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case eSortOrderByAddress: 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s->PutCString (" (sorted by address):\n"); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DumpSymbolHeader (s); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!m_addr_indexes_computed) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitAddressIndexes(); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t num_symbols = GetNumSymbols(); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<uint32_t>::const_iterator pos; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<uint32_t>::const_iterator end = m_addr_indexes.end(); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (pos = m_addr_indexes.begin(); pos != end; ++pos) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t idx = *pos; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (idx < num_symbols) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s->Indent(); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_symbols[idx].Dump(s, target, idx); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Symtab::Dump(Stream *s, Target *target, std::vector<uint32_t>& indexes) const 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Mutex::Locker locker (m_mutex); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t num_symbols = GetNumSymbols(); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) //s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s->Indent(); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s->Printf("Symtab %lu symbol indexes (%lu symbols total):\n", indexes.size(), m_symbols.size()); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s->IndentMore(); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!indexes.empty()) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<uint32_t>::const_iterator pos; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<uint32_t>::const_iterator end = indexes.end(); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DumpSymbolHeader (s); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (pos = indexes.begin(); pos != end; ++pos) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t idx = *pos; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (idx < num_symbols) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s->Indent(); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_symbols[idx].Dump(s, target, idx); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s->IndentLess (); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Symtab::DumpSymbolHeader (Stream *s) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s->Indent(" Debug symbol\n"); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s->Indent(" |Synthetic symbol\n"); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s->Indent(" ||Externally Visible\n"); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s->Indent(" |||\n"); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s->Indent("Index UserID DSX Type File Address/Value Load Address Size Flags Name\n"); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s->Indent("------- ------ --- ------------ ------------------ ------------------ ------------------ ---------- ----------------------------------\n"); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CompareSymbolID (const void *key, const void *p) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const user_id_t match_uid = *(user_id_t*) key; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const user_id_t symbol_uid = ((Symbol *)p)->GetID(); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (match_uid < symbol_uid) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (match_uid > symbol_uid) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Symbol * 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Symtab::FindSymbolByID (lldb::user_id_t symbol_uid) const 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Mutex::Locker locker (m_mutex); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol *symbol = (Symbol*)::bsearch (&symbol_uid, 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &m_symbols[0], 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_symbols.size(), 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (uint8_t *)&m_symbols[1] - (uint8_t *)&m_symbols[0], 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompareSymbolID); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return symbol; 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Symbol * 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Symtab::SymbolAtIndex(uint32_t idx) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clients should grab the mutex from this symbol table and lock it manually 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // when calling this function to avoid performance issues. 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (idx < m_symbols.size()) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &m_symbols[idx]; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Symbol * 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Symtab::SymbolAtIndex(uint32_t idx) const 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clients should grab the mutex from this symbol table and lock it manually 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // when calling this function to avoid performance issues. 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (idx < m_symbols.size()) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &m_symbols[idx]; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//---------------------------------------------------------------------- 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// InitNameIndexes 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//---------------------------------------------------------------------- 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Symtab::InitNameIndexes() 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Protected function, no need to lock mutex... 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!m_name_indexes_computed) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_name_indexes_computed = true; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create the name index vector to be able to quickly search by name 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t count = m_symbols.size(); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(m_objfile != NULL); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(m_objfile->GetModule() != NULL); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 1 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_name_to_index.Reserve (count); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO: benchmark this to see if we save any memory. Otherwise we 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will always keep the memory reserved in the vector unless we pull 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // some STL swap magic and then recopy... 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t actual_count = 0; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (const_iterator pos = m_symbols.begin(), end = m_symbols.end(); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos != end; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++pos) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Mangled &mangled = pos->GetMangled(); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mangled.GetMangledName()) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++actual_count; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mangled.GetDemangledName()) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++actual_count; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_name_to_index.Reserve (actual_count); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UniqueCStringMap<uint32_t>::Entry entry; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (entry.value = 0; entry.value < count; ++entry.value) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Symbol *symbol = &m_symbols[entry.value]; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't let trampolines get into the lookup by name map 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we ever need the trampoline symbols to be searchable by name 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we can remove this and then possibly add a new bool to any of the 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Symtab functions that lookup symbols by name to indicate if they 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // want trampolines. 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (symbol->IsTrampoline()) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Mangled &mangled = symbol->GetMangled(); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry.cstring = mangled.GetMangledName().GetCString(); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (entry.cstring && entry.cstring[0]) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_name_to_index.Append (entry); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry.cstring = mangled.GetDemangledName().GetCString(); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (entry.cstring && entry.cstring[0]) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_name_to_index.Append (entry); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the demangled name turns out to be an ObjC name, and 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is a category name, add the version without categories to the index too. 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConstString objc_base_name; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ObjCLanguageRuntime::ParseMethodName (entry.cstring, 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &objc_base_name) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && !objc_base_name.IsEmpty()) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry.cstring = objc_base_name.GetCString(); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_name_to_index.Append (entry); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_name_to_index.Sort(); 3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32_t 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Symtab::AppendSymbolIndexesWithType (SymbolType symbol_type, std::vector<uint32_t>& indexes, uint32_t start_idx, uint32_t end_index) const 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Mutex::Locker locker (m_mutex); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t prev_size = indexes.size(); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint32_t count = std::min<uint32_t> (m_symbols.size(), end_index); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (uint32_t i = start_idx; i < count; ++i) 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (symbol_type == eSymbolTypeAny || m_symbols[i].GetType() == symbol_type) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) indexes.push_back(i); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return indexes.size() - prev_size; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32_t 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Symtab::AppendSymbolIndexesWithTypeAndFlagsValue (SymbolType symbol_type, uint32_t flags_value, std::vector<uint32_t>& indexes, uint32_t start_idx, uint32_t end_index) const 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Mutex::Locker locker (m_mutex); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t prev_size = indexes.size(); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint32_t count = std::min<uint32_t> (m_symbols.size(), end_index); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (uint32_t i = start_idx; i < count; ++i) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((symbol_type == eSymbolTypeAny || m_symbols[i].GetType() == symbol_type) && m_symbols[i].GetFlags() == flags_value) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) indexes.push_back(i); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return indexes.size() - prev_size; 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32_t 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Symtab::AppendSymbolIndexesWithType (SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& indexes, uint32_t start_idx, uint32_t end_index) const 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Mutex::Locker locker (m_mutex); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t prev_size = indexes.size(); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint32_t count = std::min<uint32_t> (m_symbols.size(), end_index); 3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (uint32_t i = start_idx; i < count; ++i) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (symbol_type == eSymbolTypeAny || m_symbols[i].GetType() == symbol_type) 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CheckSymbolAtIndex(i, symbol_debug_type, symbol_visibility)) 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) indexes.push_back(i); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return indexes.size() - prev_size; 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32_t 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Symtab::GetIndexForSymbol (const Symbol *symbol) const 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Symbol *first_symbol = &m_symbols[0]; 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (symbol >= first_symbol && symbol < first_symbol + m_symbols.size()) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return symbol - first_symbol; 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return UINT32_MAX; 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct SymbolSortInfo 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool sort_by_load_addr; 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Symbol *symbols; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct SymbolIndexComparator { 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<Symbol>& symbols; 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SymbolIndexComparator(const std::vector<Symbol>& s) : symbols(s) { } 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool operator()(uint32_t index_a, uint32_t index_b) { 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr_t value_a; 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr_t value_b; 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (symbols[index_a].GetValue().GetSection() == symbols[index_b].GetValue().GetSection()) { 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value_a = symbols[index_a].GetValue ().GetOffset(); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value_b = symbols[index_b].GetValue ().GetOffset(); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value_a = symbols[index_a].GetValue ().GetFileAddress(); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value_b = symbols[index_b].GetValue ().GetFileAddress(); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (value_a == value_b) { 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The if the values are equal, use the original symbol user ID 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lldb::user_id_t uid_a = symbols[index_a].GetID(); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lldb::user_id_t uid_b = symbols[index_b].GetID(); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uid_a < uid_b) 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uid_a > uid_b) 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (value_a < value_b) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Symtab::SortSymbolIndexesByValue (std::vector<uint32_t>& indexes, bool remove_duplicates) const 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Mutex::Locker locker (m_mutex); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Timer scoped_timer (__PRETTY_FUNCTION__,__PRETTY_FUNCTION__); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No need to sort if we have zero or one items... 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (indexes.size() <= 1) 4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sort the indexes in place using std::stable_sort. 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: The use of std::stable_sort instead of std::sort here is strictly for performance, 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // not correctness. The indexes vector tends to be "close" to sorted, which the 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // stable sort handles better. 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::stable_sort(indexes.begin(), indexes.end(), SymbolIndexComparator(m_symbols)); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remove any duplicates if requested 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (remove_duplicates) 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::unique(indexes.begin(), indexes.end()); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32_t 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Symtab::AppendSymbolIndexesWithName (const ConstString& symbol_name, std::vector<uint32_t>& indexes) 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Mutex::Locker locker (m_mutex); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__); 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (symbol_name) 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *symbol_cstr = symbol_name.GetCString(); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!m_name_indexes_computed) 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitNameIndexes(); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return m_name_to_index.GetValues (symbol_cstr, indexes); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32_t 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Symtab::AppendSymbolIndexesWithName (const ConstString& symbol_name, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& indexes) 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Mutex::Locker locker (m_mutex); 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (symbol_name) 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 482 const size_t old_size = indexes.size(); 483 if (!m_name_indexes_computed) 484 InitNameIndexes(); 485 486 const char *symbol_cstr = symbol_name.GetCString(); 487 488 std::vector<uint32_t> all_name_indexes; 489 const size_t name_match_count = m_name_to_index.GetValues (symbol_cstr, all_name_indexes); 490 for (size_t i=0; i<name_match_count; ++i) 491 { 492 if (CheckSymbolAtIndex(all_name_indexes[i], symbol_debug_type, symbol_visibility)) 493 indexes.push_back (all_name_indexes[i]); 494 } 495 return indexes.size() - old_size; 496 } 497 return 0; 498} 499 500uint32_t 501Symtab::AppendSymbolIndexesWithNameAndType (const ConstString& symbol_name, SymbolType symbol_type, std::vector<uint32_t>& indexes) 502{ 503 Mutex::Locker locker (m_mutex); 504 505 if (AppendSymbolIndexesWithName(symbol_name, indexes) > 0) 506 { 507 std::vector<uint32_t>::iterator pos = indexes.begin(); 508 while (pos != indexes.end()) 509 { 510 if (symbol_type == eSymbolTypeAny || m_symbols[*pos].GetType() == symbol_type) 511 ++pos; 512 else 513 indexes.erase(pos); 514 } 515 } 516 return indexes.size(); 517} 518 519uint32_t 520Symtab::AppendSymbolIndexesWithNameAndType (const ConstString& symbol_name, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& indexes) 521{ 522 Mutex::Locker locker (m_mutex); 523 524 if (AppendSymbolIndexesWithName(symbol_name, symbol_debug_type, symbol_visibility, indexes) > 0) 525 { 526 std::vector<uint32_t>::iterator pos = indexes.begin(); 527 while (pos != indexes.end()) 528 { 529 if (symbol_type == eSymbolTypeAny || m_symbols[*pos].GetType() == symbol_type) 530 ++pos; 531 else 532 indexes.erase(pos); 533 } 534 } 535 return indexes.size(); 536} 537 538 539uint32_t 540Symtab::AppendSymbolIndexesMatchingRegExAndType (const RegularExpression ®exp, SymbolType symbol_type, std::vector<uint32_t>& indexes) 541{ 542 Mutex::Locker locker (m_mutex); 543 544 uint32_t prev_size = indexes.size(); 545 uint32_t sym_end = m_symbols.size(); 546 547 for (int i = 0; i < sym_end; i++) 548 { 549 if (symbol_type == eSymbolTypeAny || m_symbols[i].GetType() == symbol_type) 550 { 551 const char *name = m_symbols[i].GetMangled().GetName().AsCString(); 552 if (name) 553 { 554 if (regexp.Execute (name)) 555 indexes.push_back(i); 556 } 557 } 558 } 559 return indexes.size() - prev_size; 560 561} 562 563uint32_t 564Symtab::AppendSymbolIndexesMatchingRegExAndType (const RegularExpression ®exp, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& indexes) 565{ 566 Mutex::Locker locker (m_mutex); 567 568 uint32_t prev_size = indexes.size(); 569 uint32_t sym_end = m_symbols.size(); 570 571 for (int i = 0; i < sym_end; i++) 572 { 573 if (symbol_type == eSymbolTypeAny || m_symbols[i].GetType() == symbol_type) 574 { 575 if (CheckSymbolAtIndex(i, symbol_debug_type, symbol_visibility) == false) 576 continue; 577 578 const char *name = m_symbols[i].GetMangled().GetName().AsCString(); 579 if (name) 580 { 581 if (regexp.Execute (name)) 582 indexes.push_back(i); 583 } 584 } 585 } 586 return indexes.size() - prev_size; 587 588} 589 590Symbol * 591Symtab::FindSymbolWithType (SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, uint32_t& start_idx) 592{ 593 Mutex::Locker locker (m_mutex); 594 595 const size_t count = m_symbols.size(); 596 for (uint32_t idx = start_idx; idx < count; ++idx) 597 { 598 if (symbol_type == eSymbolTypeAny || m_symbols[idx].GetType() == symbol_type) 599 { 600 if (CheckSymbolAtIndex(idx, symbol_debug_type, symbol_visibility)) 601 { 602 start_idx = idx; 603 return &m_symbols[idx]; 604 } 605 } 606 } 607 return NULL; 608} 609 610size_t 611Symtab::FindAllSymbolsWithNameAndType (const ConstString &name, SymbolType symbol_type, std::vector<uint32_t>& symbol_indexes) 612{ 613 Mutex::Locker locker (m_mutex); 614 615 Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__); 616 // Initialize all of the lookup by name indexes before converting NAME 617 // to a uniqued string NAME_STR below. 618 if (!m_name_indexes_computed) 619 InitNameIndexes(); 620 621 if (name) 622 { 623 // The string table did have a string that matched, but we need 624 // to check the symbols and match the symbol_type if any was given. 625 AppendSymbolIndexesWithNameAndType (name, symbol_type, symbol_indexes); 626 } 627 return symbol_indexes.size(); 628} 629 630size_t 631Symtab::FindAllSymbolsWithNameAndType (const ConstString &name, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& symbol_indexes) 632{ 633 Mutex::Locker locker (m_mutex); 634 635 Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__); 636 // Initialize all of the lookup by name indexes before converting NAME 637 // to a uniqued string NAME_STR below. 638 if (!m_name_indexes_computed) 639 InitNameIndexes(); 640 641 if (name) 642 { 643 // The string table did have a string that matched, but we need 644 // to check the symbols and match the symbol_type if any was given. 645 AppendSymbolIndexesWithNameAndType (name, symbol_type, symbol_debug_type, symbol_visibility, symbol_indexes); 646 } 647 return symbol_indexes.size(); 648} 649 650size_t 651Symtab::FindAllSymbolsMatchingRexExAndType (const RegularExpression ®ex, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& symbol_indexes) 652{ 653 Mutex::Locker locker (m_mutex); 654 655 AppendSymbolIndexesMatchingRegExAndType(regex, symbol_type, symbol_debug_type, symbol_visibility, symbol_indexes); 656 return symbol_indexes.size(); 657} 658 659Symbol * 660Symtab::FindFirstSymbolWithNameAndType (const ConstString &name, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility) 661{ 662 Mutex::Locker locker (m_mutex); 663 664 Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__); 665 if (!m_name_indexes_computed) 666 InitNameIndexes(); 667 668 if (name) 669 { 670 std::vector<uint32_t> matching_indexes; 671 // The string table did have a string that matched, but we need 672 // to check the symbols and match the symbol_type if any was given. 673 if (AppendSymbolIndexesWithNameAndType (name, symbol_type, symbol_debug_type, symbol_visibility, matching_indexes)) 674 { 675 std::vector<uint32_t>::const_iterator pos, end = matching_indexes.end(); 676 for (pos = matching_indexes.begin(); pos != end; ++pos) 677 { 678 Symbol *symbol = SymbolAtIndex(*pos); 679 680 if (symbol->Compare(name, symbol_type)) 681 return symbol; 682 } 683 } 684 } 685 return NULL; 686} 687 688typedef struct 689{ 690 const Symtab *symtab; 691 const addr_t file_addr; 692 Symbol *match_symbol; 693 const uint32_t *match_index_ptr; 694 addr_t match_offset; 695} SymbolSearchInfo; 696 697static int 698SymbolWithFileAddress (SymbolSearchInfo *info, const uint32_t *index_ptr) 699{ 700 const Symbol *curr_symbol = info->symtab->SymbolAtIndex (index_ptr[0]); 701 if (curr_symbol == NULL) 702 return -1; 703 704 const addr_t info_file_addr = info->file_addr; 705 706 // lldb::Symbol::GetAddressRangePtr() will only return a non NULL address 707 // range if the symbol has a section! 708 const AddressRange *curr_range = curr_symbol->GetAddressRangePtr(); 709 if (curr_range) 710 { 711 const addr_t curr_file_addr = curr_range->GetBaseAddress().GetFileAddress(); 712 if (info_file_addr < curr_file_addr) 713 return -1; 714 if (info_file_addr > curr_file_addr) 715 return +1; 716 info->match_symbol = const_cast<Symbol *>(curr_symbol); 717 info->match_index_ptr = index_ptr; 718 return 0; 719 } 720 721 return -1; 722} 723 724static int 725SymbolWithClosestFileAddress (SymbolSearchInfo *info, const uint32_t *index_ptr) 726{ 727 const Symbol *symbol = info->symtab->SymbolAtIndex (index_ptr[0]); 728 if (symbol == NULL) 729 return -1; 730 731 const addr_t info_file_addr = info->file_addr; 732 const AddressRange *curr_range = symbol->GetAddressRangePtr(); 733 if (curr_range) 734 { 735 const addr_t curr_file_addr = curr_range->GetBaseAddress().GetFileAddress(); 736 if (info_file_addr < curr_file_addr) 737 return -1; 738 739 // Since we are finding the closest symbol that is greater than or equal 740 // to 'info->file_addr' we set the symbol here. This will get set 741 // multiple times, but after the search is done it will contain the best 742 // symbol match 743 info->match_symbol = const_cast<Symbol *>(symbol); 744 info->match_index_ptr = index_ptr; 745 info->match_offset = info_file_addr - curr_file_addr; 746 747 if (info_file_addr > curr_file_addr) 748 return +1; 749 return 0; 750 } 751 return -1; 752} 753 754static SymbolSearchInfo 755FindIndexPtrForSymbolContainingAddress(Symtab* symtab, addr_t file_addr, const uint32_t* indexes, uint32_t num_indexes) 756{ 757 SymbolSearchInfo info = { symtab, file_addr, NULL, NULL, 0 }; 758 ::bsearch (&info, 759 indexes, 760 num_indexes, 761 sizeof(uint32_t), 762 (ComparisonFunction)SymbolWithClosestFileAddress); 763 return info; 764} 765 766 767void 768Symtab::InitAddressIndexes() 769{ 770 // Protected function, no need to lock mutex... 771 if (!m_addr_indexes_computed && !m_symbols.empty()) 772 { 773 m_addr_indexes_computed = true; 774#if 0 775 // The old was to add only code, trampoline or data symbols... 776 AppendSymbolIndexesWithType (eSymbolTypeCode, m_addr_indexes); 777 AppendSymbolIndexesWithType (eSymbolTypeTrampoline, m_addr_indexes); 778 AppendSymbolIndexesWithType (eSymbolTypeData, m_addr_indexes); 779#else 780 // The new way adds all symbols with valid addresses that are section 781 // offset. 782 const_iterator begin = m_symbols.begin(); 783 const_iterator end = m_symbols.end(); 784 for (const_iterator pos = m_symbols.begin(); pos != end; ++pos) 785 { 786 if (pos->GetAddressRangePtr()) 787 m_addr_indexes.push_back (std::distance(begin, pos)); 788 } 789#endif 790 SortSymbolIndexesByValue (m_addr_indexes, false); 791 m_addr_indexes.push_back (UINT32_MAX); // Terminator for bsearch since we might need to look at the next symbol 792 } 793} 794 795size_t 796Symtab::CalculateSymbolSize (Symbol *symbol) 797{ 798 Mutex::Locker locker (m_mutex); 799 800 if (m_symbols.empty()) 801 return 0; 802 803 // Make sure this symbol is from this symbol table... 804 if (symbol < &m_symbols.front() || symbol > &m_symbols.back()) 805 return 0; 806 807 // See if this symbol already has a byte size? 808 size_t byte_size = symbol->GetByteSize(); 809 810 if (byte_size) 811 { 812 // It does, just return it 813 return byte_size; 814 } 815 816 // Else if this is an address based symbol, figure out the delta between 817 // it and the next address based symbol 818 if (symbol->GetAddressRangePtr()) 819 { 820 if (!m_addr_indexes_computed) 821 InitAddressIndexes(); 822 const size_t num_addr_indexes = m_addr_indexes.size(); 823 SymbolSearchInfo info = FindIndexPtrForSymbolContainingAddress(this, symbol->GetAddressRangePtr()->GetBaseAddress().GetFileAddress(), &m_addr_indexes.front(), num_addr_indexes); 824 if (info.match_index_ptr != NULL) 825 { 826 const lldb::addr_t curr_file_addr = symbol->GetAddressRangePtr()->GetBaseAddress().GetFileAddress(); 827 // We can figure out the address range of all symbols except the 828 // last one by taking the delta between the current symbol and 829 // the next symbol 830 831 for (uint32_t addr_index = info.match_index_ptr - &m_addr_indexes.front() + 1; 832 addr_index < num_addr_indexes; 833 ++addr_index) 834 { 835 Symbol *next_symbol = SymbolAtIndex(m_addr_indexes[addr_index]); 836 if (next_symbol == NULL) 837 break; 838 839 assert (next_symbol->GetAddressRangePtr()); 840 const lldb::addr_t next_file_addr = next_symbol->GetAddressRangePtr()->GetBaseAddress().GetFileAddress(); 841 if (next_file_addr > curr_file_addr) 842 { 843 byte_size = next_file_addr - curr_file_addr; 844 symbol->GetAddressRangePtr()->SetByteSize(byte_size); 845 symbol->SetSizeIsSynthesized(true); 846 break; 847 } 848 } 849 } 850 } 851 return byte_size; 852} 853 854Symbol * 855Symtab::FindSymbolWithFileAddress (addr_t file_addr) 856{ 857 Mutex::Locker locker (m_mutex); 858 859 if (!m_addr_indexes_computed) 860 InitAddressIndexes(); 861 862 SymbolSearchInfo info = { this, file_addr, NULL, NULL, 0 }; 863 864 uint32_t* match = (uint32_t*)::bsearch (&info, 865 &m_addr_indexes[0], 866 m_addr_indexes.size(), 867 sizeof(uint32_t), 868 (ComparisonFunction)SymbolWithFileAddress); 869 if (match) 870 return SymbolAtIndex (*match); 871 return NULL; 872} 873 874 875Symbol * 876Symtab::FindSymbolContainingFileAddress (addr_t file_addr, const uint32_t* indexes, uint32_t num_indexes) 877{ 878 Mutex::Locker locker (m_mutex); 879 880 SymbolSearchInfo info = { this, file_addr, NULL, NULL, 0 }; 881 882 ::bsearch (&info, 883 indexes, 884 num_indexes, 885 sizeof(uint32_t), 886 (ComparisonFunction)SymbolWithClosestFileAddress); 887 888 if (info.match_symbol) 889 { 890 if (info.match_offset == 0) 891 { 892 // We found an exact match! 893 return info.match_symbol; 894 } 895 896 const size_t symbol_byte_size = CalculateSymbolSize(info.match_symbol); 897 898 if (symbol_byte_size == 0) 899 { 900 // We weren't able to find the size of the symbol so lets just go 901 // with that match we found in our search... 902 return info.match_symbol; 903 } 904 905 // We were able to figure out a symbol size so lets make sure our 906 // offset puts "file_addr" in the symbol's address range. 907 if (info.match_offset < symbol_byte_size) 908 return info.match_symbol; 909 } 910 return NULL; 911} 912 913Symbol * 914Symtab::FindSymbolContainingFileAddress (addr_t file_addr) 915{ 916 Mutex::Locker locker (m_mutex); 917 918 if (!m_addr_indexes_computed) 919 InitAddressIndexes(); 920 921 return FindSymbolContainingFileAddress (file_addr, &m_addr_indexes[0], m_addr_indexes.size()); 922} 923 924