124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- Symtab.cpp ----------------------------------------------*- C++ -*-===//
224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//                     The LLVM Compiler Infrastructure
424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source
624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details.
724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===//
924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <map>
1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Module.h"
1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/RegularExpression.h"
14464a5063bc59755cb6ec063d0b2491097302d2abGreg Clayton#include "lldb/Core/Section.h"
1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Timer.h"
1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Symbol/ObjectFile.h"
172fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton#include "lldb/Symbol/SymbolContext.h"
1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Symbol/Symtab.h"
19296b06d325413723f5aac5988eed977b278a7807Greg Clayton#include "lldb/Target/CPPLanguageRuntime.h"
203ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham#include "lldb/Target/ObjCLanguageRuntime.h"
2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb;
2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private;
2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerSymtab::Symtab(ObjectFile *objfile) :
288d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    m_objfile (objfile),
298d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    m_symbols (),
307940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton    m_file_addr_to_index (),
318d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    m_name_to_index (),
328d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    m_mutex (Mutex::eMutexTypeRecursive),
337940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton    m_file_addr_to_index_computed (false),
348d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    m_name_indexes_computed (false)
3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerSymtab::~Symtab()
3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
4336da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg ClaytonSymtab::Reserve(size_t count)
4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
458d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    // Clients should grab the mutex from this symbol table and lock it manually
468d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    // when calling this function to avoid performance issues.
4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_symbols.reserve (count);
4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerSymbol *
5136da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg ClaytonSymtab::Resize(size_t count)
5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
538d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    // Clients should grab the mutex from this symbol table and lock it manually
548d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    // when calling this function to avoid performance issues.
5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_symbols.resize (count);
5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return &m_symbols[0];
5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint32_t
6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerSymtab::AddSymbol(const Symbol& symbol)
6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
628d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    // Clients should grab the mutex from this symbol table and lock it manually
638d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    // when calling this function to avoid performance issues.
6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t symbol_idx = m_symbols.size();
6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_name_to_index.Clear();
667940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton    m_file_addr_to_index.Clear();
6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_symbols.push_back(symbol);
687940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton    m_file_addr_to_index_computed = false;
698d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    m_name_indexes_computed = false;
7024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return symbol_idx;
7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnersize_t
7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerSymtab::GetNumSymbols() const
7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
768d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    Mutex::Locker locker (m_mutex);
7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return m_symbols.size();
7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
81b344843f75ef893762c93fd0a22d2d45712ce74dGreg ClaytonSymtab::Dump (Stream *s, Target *target, SortOrder sort_order)
8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
838d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    Mutex::Locker locker (m_mutex);
848d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton
853fed8b9b2696fc2ea78005c8f9b1c621d5748042Greg Clayton//    s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    s->Indent();
8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const FileSpec &file_spec = m_objfile->GetFileSpec();
8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const char * object_name = NULL;
8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (m_objfile->GetModule())
9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        object_name = m_objfile->GetModule()->GetObjectName().GetCString();
9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (file_spec)
9397a19b21dacd9063bb5475812df7781777262198Greg Clayton        s->Printf("Symtab, file = %s%s%s%s, num_symbols = %lu",
9497a19b21dacd9063bb5475812df7781777262198Greg Clayton        file_spec.GetPath().c_str(),
9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        object_name ? "(" : "",
9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        object_name ? object_name : "",
9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        object_name ? ")" : "",
9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_symbols.size());
9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
1007e5fa7fc1f8efd24c078e063b2c4b5e13ba5be20Jason Molenda        s->Printf("Symtab, num_symbols = %lu", m_symbols.size());
10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
10224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (!m_symbols.empty())
10324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
1048d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton        switch (sort_order)
10524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
1068d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton        case eSortOrderNone:
1078d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton            {
1088d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                s->PutCString (":\n");
1098d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                DumpSymbolHeader (s);
1108d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                const_iterator begin = m_symbols.begin();
1118d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                const_iterator end = m_symbols.end();
1128d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                for (const_iterator pos = m_symbols.begin(); pos != end; ++pos)
1138d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                {
1148d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                    s->Indent();
1158d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                    pos->Dump(s, target, std::distance(begin, pos));
1168d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                }
1178d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton            }
1188d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton            break;
1198d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton
1208d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton        case eSortOrderByName:
1218d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton            {
1228d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                // Although we maintain a lookup by exact name map, the table
1238d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                // isn't sorted by name. So we must make the ordered symbol list
1248d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                // up ourselves.
1258d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                s->PutCString (" (sorted by name):\n");
1268d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                DumpSymbolHeader (s);
1278d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                typedef std::multimap<const char*, const Symbol *, CStringCompareFunctionObject> CStringToSymbol;
1288d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                CStringToSymbol name_map;
1298d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                for (const_iterator pos = m_symbols.begin(), end = m_symbols.end(); pos != end; ++pos)
1308d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                {
1318d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                    const char *name = pos->GetMangled().GetName(Mangled::ePreferDemangled).AsCString();
1328d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                    if (name && name[0])
1338d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                        name_map.insert (std::make_pair(name, &(*pos)));
1348d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                }
1358d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton
1368d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                for (CStringToSymbol::const_iterator pos = name_map.begin(), end = name_map.end(); pos != end; ++pos)
1378d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                {
1388d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                    s->Indent();
1398d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                    pos->second->Dump (s, target, pos->second - &m_symbols[0]);
1408d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                }
1418d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton            }
1428d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton            break;
1438d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton
1448d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton        case eSortOrderByAddress:
1458d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton            s->PutCString (" (sorted by address):\n");
1468d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton            DumpSymbolHeader (s);
1477940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton            if (!m_file_addr_to_index_computed)
1488d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                InitAddressIndexes();
1497940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton            const size_t num_entries = m_file_addr_to_index.GetSize();
1507940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton            for (size_t i=0; i<num_entries; ++i)
1518d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton            {
1527940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton                s->Indent();
1537940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton                const uint32_t symbol_idx = m_file_addr_to_index.GetEntryRef(i).data;
1547940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton                m_symbols[symbol_idx].Dump(s, target, symbol_idx);
1558d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton            }
1568d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton            break;
15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
162eea264007bc5fb42c8f3239726a9d28ae42e1b7bGreg ClaytonSymtab::Dump(Stream *s, Target *target, std::vector<uint32_t>& indexes) const
16324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
1648d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    Mutex::Locker locker (m_mutex);
1658d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton
16624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const size_t num_symbols = GetNumSymbols();
1678d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    //s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
16824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    s->Indent();
1697e5fa7fc1f8efd24c078e063b2c4b5e13ba5be20Jason Molenda    s->Printf("Symtab %lu symbol indexes (%lu symbols total):\n", indexes.size(), m_symbols.size());
17024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    s->IndentMore();
17124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (!indexes.empty())
17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
17424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        std::vector<uint32_t>::const_iterator pos;
17524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        std::vector<uint32_t>::const_iterator end = indexes.end();
17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        DumpSymbolHeader (s);
17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        for (pos = indexes.begin(); pos != end; ++pos)
17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
17936da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton            size_t idx = *pos;
18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (idx < num_symbols)
18124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
18224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                s->Indent();
183eea264007bc5fb42c8f3239726a9d28ae42e1b7bGreg Clayton                m_symbols[idx].Dump(s, target, idx);
18424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
18624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
18724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    s->IndentLess ();
18824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
18924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
19024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerSymtab::DumpSymbolHeader (Stream *s)
19224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
19324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    s->Indent("               Debug symbol\n");
19424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    s->Indent("               |Synthetic symbol\n");
19524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    s->Indent("               ||Externally Visible\n");
19624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    s->Indent("               |||\n");
19724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    s->Indent("Index   UserID DSX Type         File Address/Value Load Address       Size               Flags      Name\n");
19824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    s->Indent("------- ------ --- ------------ ------------------ ------------------ ------------------ ---------- ----------------------------------\n");
19924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
20024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2010ad086f3ab18d6927b9df2f79169607d3a5d90e4Greg Clayton
2020ad086f3ab18d6927b9df2f79169607d3a5d90e4Greg Claytonstatic int
2030ad086f3ab18d6927b9df2f79169607d3a5d90e4Greg ClaytonCompareSymbolID (const void *key, const void *p)
2040ad086f3ab18d6927b9df2f79169607d3a5d90e4Greg Clayton{
2050ad086f3ab18d6927b9df2f79169607d3a5d90e4Greg Clayton    const user_id_t match_uid = *(user_id_t*) key;
2060ad086f3ab18d6927b9df2f79169607d3a5d90e4Greg Clayton    const user_id_t symbol_uid = ((Symbol *)p)->GetID();
2070ad086f3ab18d6927b9df2f79169607d3a5d90e4Greg Clayton    if (match_uid < symbol_uid)
2080ad086f3ab18d6927b9df2f79169607d3a5d90e4Greg Clayton        return -1;
2090ad086f3ab18d6927b9df2f79169607d3a5d90e4Greg Clayton    if (match_uid > symbol_uid)
2100ad086f3ab18d6927b9df2f79169607d3a5d90e4Greg Clayton        return 1;
2110ad086f3ab18d6927b9df2f79169607d3a5d90e4Greg Clayton    return 0;
2120ad086f3ab18d6927b9df2f79169607d3a5d90e4Greg Clayton}
2130ad086f3ab18d6927b9df2f79169607d3a5d90e4Greg Clayton
2140ad086f3ab18d6927b9df2f79169607d3a5d90e4Greg ClaytonSymbol *
2150ad086f3ab18d6927b9df2f79169607d3a5d90e4Greg ClaytonSymtab::FindSymbolByID (lldb::user_id_t symbol_uid) const
2160ad086f3ab18d6927b9df2f79169607d3a5d90e4Greg Clayton{
2178d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    Mutex::Locker locker (m_mutex);
2188d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton
2190ad086f3ab18d6927b9df2f79169607d3a5d90e4Greg Clayton    Symbol *symbol = (Symbol*)::bsearch (&symbol_uid,
2200ad086f3ab18d6927b9df2f79169607d3a5d90e4Greg Clayton                                         &m_symbols[0],
2210ad086f3ab18d6927b9df2f79169607d3a5d90e4Greg Clayton                                         m_symbols.size(),
222637029b85196806ce0f39271764efae43c888e85Greg Clayton                                         (uint8_t *)&m_symbols[1] - (uint8_t *)&m_symbols[0],
2230ad086f3ab18d6927b9df2f79169607d3a5d90e4Greg Clayton                                         CompareSymbolID);
2240ad086f3ab18d6927b9df2f79169607d3a5d90e4Greg Clayton    return symbol;
2250ad086f3ab18d6927b9df2f79169607d3a5d90e4Greg Clayton}
2260ad086f3ab18d6927b9df2f79169607d3a5d90e4Greg Clayton
2270ad086f3ab18d6927b9df2f79169607d3a5d90e4Greg Clayton
22824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerSymbol *
22936da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg ClaytonSymtab::SymbolAtIndex(size_t idx)
23024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
2318d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    // Clients should grab the mutex from this symbol table and lock it manually
2328d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    // when calling this function to avoid performance issues.
23324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (idx < m_symbols.size())
23424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return &m_symbols[idx];
23524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return NULL;
23624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
23724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
23824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
23924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerconst Symbol *
24036da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg ClaytonSymtab::SymbolAtIndex(size_t idx) const
24124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
2428d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    // Clients should grab the mutex from this symbol table and lock it manually
2438d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    // when calling this function to avoid performance issues.
24424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (idx < m_symbols.size())
24524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return &m_symbols[idx];
24624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return NULL;
24724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
24824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
24924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
25024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// InitNameIndexes
25124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
25224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
25324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerSymtab::InitNameIndexes()
25424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
2558d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    // Protected function, no need to lock mutex...
2568d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    if (!m_name_indexes_computed)
2578d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    {
2588d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton        m_name_indexes_computed = true;
2598d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton        Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__);
2608d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton        // Create the name index vector to be able to quickly search by name
261296b06d325413723f5aac5988eed977b278a7807Greg Clayton        const size_t num_symbols = m_symbols.size();
2628d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton#if 1
263296b06d325413723f5aac5988eed977b278a7807Greg Clayton        m_name_to_index.Reserve (num_symbols);
2648d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton#else
2658d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton        // TODO: benchmark this to see if we save any memory. Otherwise we
2668d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton        // will always keep the memory reserved in the vector unless we pull
2678d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton        // some STL swap magic and then recopy...
2688d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton        uint32_t actual_count = 0;
2698d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton        for (const_iterator pos = m_symbols.begin(), end = m_symbols.end();
2708d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton             pos != end;
2718d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton             ++pos)
2728d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton        {
2738d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton            const Mangled &mangled = pos->GetMangled();
2748d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton            if (mangled.GetMangledName())
2758d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                ++actual_count;
2768d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton
2778d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton            if (mangled.GetDemangledName())
2788d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                ++actual_count;
2798d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton        }
28024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2818d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton        m_name_to_index.Reserve (actual_count);
2828d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton#endif
28324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
28416d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton        NameToIndexMap::Entry entry;
2858d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton
286296b06d325413723f5aac5988eed977b278a7807Greg Clayton        // The "const char *" in "class_contexts" must come from a ConstString::GetCString()
287296b06d325413723f5aac5988eed977b278a7807Greg Clayton        std::set<const char *> class_contexts;
288296b06d325413723f5aac5988eed977b278a7807Greg Clayton        UniqueCStringMap<uint32_t> mangled_name_to_index;
289296b06d325413723f5aac5988eed977b278a7807Greg Clayton        std::vector<const char *> symbol_contexts(num_symbols, NULL);
290296b06d325413723f5aac5988eed977b278a7807Greg Clayton
291296b06d325413723f5aac5988eed977b278a7807Greg Clayton        for (entry.value = 0; entry.value<num_symbols; ++entry.value)
2928d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton        {
2938d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton            const Symbol *symbol = &m_symbols[entry.value];
2948d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton
2958d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton            // Don't let trampolines get into the lookup by name map
2968d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton            // If we ever need the trampoline symbols to be searchable by name
2978d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton            // we can remove this and then possibly add a new bool to any of the
2988d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton            // Symtab functions that lookup symbols by name to indicate if they
2998d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton            // want trampolines.
3008d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton            if (symbol->IsTrampoline())
3018d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                continue;
3028d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton
3038d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton            const Mangled &mangled = symbol->GetMangled();
3048d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton            entry.cstring = mangled.GetMangledName().GetCString();
3058d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton            if (entry.cstring && entry.cstring[0])
306296b06d325413723f5aac5988eed977b278a7807Greg Clayton            {
3078d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                m_name_to_index.Append (entry);
308296b06d325413723f5aac5988eed977b278a7807Greg Clayton
309296b06d325413723f5aac5988eed977b278a7807Greg Clayton                const SymbolType symbol_type = symbol->GetType();
310296b06d325413723f5aac5988eed977b278a7807Greg Clayton                if (symbol_type == eSymbolTypeCode || symbol_type == eSymbolTypeResolver)
311296b06d325413723f5aac5988eed977b278a7807Greg Clayton                {
312296b06d325413723f5aac5988eed977b278a7807Greg Clayton                    if (entry.cstring[0] == '_' && entry.cstring[1] == 'Z' &&
313296b06d325413723f5aac5988eed977b278a7807Greg Clayton                        (entry.cstring[2] != 'T' && // avoid virtual table, VTT structure, typeinfo structure, and typeinfo name
314296b06d325413723f5aac5988eed977b278a7807Greg Clayton                         entry.cstring[2] != 'G' && // avoid guard variables
315296b06d325413723f5aac5988eed977b278a7807Greg Clayton                         entry.cstring[2] != 'Z'))  // named local entities (if we eventually handle eSymbolTypeData, we will want this back)
316296b06d325413723f5aac5988eed977b278a7807Greg Clayton                    {
317296b06d325413723f5aac5988eed977b278a7807Greg Clayton                        CPPLanguageRuntime::MethodName cxx_method (mangled.GetDemangledName());
31883d90c5e68f4a977150c6791a49ade7a23c92177Greg Clayton                        entry.cstring = ConstString(cxx_method.GetBasename()).GetCString();
319296b06d325413723f5aac5988eed977b278a7807Greg Clayton                        if (entry.cstring && entry.cstring[0])
320296b06d325413723f5aac5988eed977b278a7807Greg Clayton                        {
321296b06d325413723f5aac5988eed977b278a7807Greg Clayton                            // ConstString objects permanently store the string in the pool so calling
322296b06d325413723f5aac5988eed977b278a7807Greg Clayton                            // GetCString() on the value gets us a const char * that will never go away
323296b06d325413723f5aac5988eed977b278a7807Greg Clayton                            const char *const_context = ConstString(cxx_method.GetContext()).GetCString();
324296b06d325413723f5aac5988eed977b278a7807Greg Clayton
325296b06d325413723f5aac5988eed977b278a7807Greg Clayton                            if (entry.cstring[0] == '~' || !cxx_method.GetQualifiers().empty())
326296b06d325413723f5aac5988eed977b278a7807Greg Clayton                            {
327296b06d325413723f5aac5988eed977b278a7807Greg Clayton                                // The first character of the demangled basename is '~' which
328296b06d325413723f5aac5988eed977b278a7807Greg Clayton                                // means we have a class destructor. We can use this information
329296b06d325413723f5aac5988eed977b278a7807Greg Clayton                                // to help us know what is a class and what isn't.
330296b06d325413723f5aac5988eed977b278a7807Greg Clayton                                if (class_contexts.find(const_context) == class_contexts.end())
331296b06d325413723f5aac5988eed977b278a7807Greg Clayton                                    class_contexts.insert(const_context);
332296b06d325413723f5aac5988eed977b278a7807Greg Clayton                                m_method_to_index.Append (entry);
333296b06d325413723f5aac5988eed977b278a7807Greg Clayton                            }
334296b06d325413723f5aac5988eed977b278a7807Greg Clayton                            else
335296b06d325413723f5aac5988eed977b278a7807Greg Clayton                            {
336296b06d325413723f5aac5988eed977b278a7807Greg Clayton                                if (const_context && const_context[0])
337296b06d325413723f5aac5988eed977b278a7807Greg Clayton                                {
338296b06d325413723f5aac5988eed977b278a7807Greg Clayton                                    if (class_contexts.find(const_context) != class_contexts.end())
339296b06d325413723f5aac5988eed977b278a7807Greg Clayton                                    {
340296b06d325413723f5aac5988eed977b278a7807Greg Clayton                                        // The current decl context is in our "class_contexts" which means
341296b06d325413723f5aac5988eed977b278a7807Greg Clayton                                        // this is a method on a class
342296b06d325413723f5aac5988eed977b278a7807Greg Clayton                                        m_method_to_index.Append (entry);
343296b06d325413723f5aac5988eed977b278a7807Greg Clayton                                    }
344296b06d325413723f5aac5988eed977b278a7807Greg Clayton                                    else
345296b06d325413723f5aac5988eed977b278a7807Greg Clayton                                    {
346296b06d325413723f5aac5988eed977b278a7807Greg Clayton                                        // We don't know if this is a function basename or a method,
347296b06d325413723f5aac5988eed977b278a7807Greg Clayton                                        // so put it into a temporary collection so once we are done
348296b06d325413723f5aac5988eed977b278a7807Greg Clayton                                        // we can look in class_contexts to see if each entry is a class
349296b06d325413723f5aac5988eed977b278a7807Greg Clayton                                        // or just a function and will put any remaining items into
350296b06d325413723f5aac5988eed977b278a7807Greg Clayton                                        // m_method_to_index or m_basename_to_index as needed
351296b06d325413723f5aac5988eed977b278a7807Greg Clayton                                        mangled_name_to_index.Append (entry);
352296b06d325413723f5aac5988eed977b278a7807Greg Clayton                                        symbol_contexts[entry.value] = const_context;
353296b06d325413723f5aac5988eed977b278a7807Greg Clayton                                    }
354296b06d325413723f5aac5988eed977b278a7807Greg Clayton                                }
355296b06d325413723f5aac5988eed977b278a7807Greg Clayton                                else
356296b06d325413723f5aac5988eed977b278a7807Greg Clayton                                {
357296b06d325413723f5aac5988eed977b278a7807Greg Clayton                                    // No context for this function so this has to be a basename
358296b06d325413723f5aac5988eed977b278a7807Greg Clayton                                    m_basename_to_index.Append(entry);
359296b06d325413723f5aac5988eed977b278a7807Greg Clayton                                }
360296b06d325413723f5aac5988eed977b278a7807Greg Clayton                            }
361296b06d325413723f5aac5988eed977b278a7807Greg Clayton                        }
362296b06d325413723f5aac5988eed977b278a7807Greg Clayton                    }
363296b06d325413723f5aac5988eed977b278a7807Greg Clayton                }
364296b06d325413723f5aac5988eed977b278a7807Greg Clayton            }
365296b06d325413723f5aac5988eed977b278a7807Greg Clayton
3668d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton            entry.cstring = mangled.GetDemangledName().GetCString();
3678d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton            if (entry.cstring && entry.cstring[0])
3688d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton                m_name_to_index.Append (entry);
3693ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham
3703ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham            // If the demangled name turns out to be an ObjC name, and
3713ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham            // is a category name, add the version without categories to the index too.
372f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            ObjCLanguageRuntime::MethodName objc_method (entry.cstring, true);
373f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            if (objc_method.IsValid(true))
3743ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham            {
375f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                entry.cstring = objc_method.GetSelector().GetCString();
3762fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton                m_selector_to_index.Append (entry);
377f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton
378f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                ConstString objc_method_no_category (objc_method.GetFullNameWithoutCategory(true));
379f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                if (objc_method_no_category)
380f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                {
381f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                    entry.cstring = objc_method_no_category.GetCString();
382f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                    m_name_to_index.Append (entry);
383f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                }
3843ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham            }
3853ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham
3868d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton        }
387296b06d325413723f5aac5988eed977b278a7807Greg Clayton
388296b06d325413723f5aac5988eed977b278a7807Greg Clayton        size_t count;
389296b06d325413723f5aac5988eed977b278a7807Greg Clayton        if (!mangled_name_to_index.IsEmpty())
390296b06d325413723f5aac5988eed977b278a7807Greg Clayton        {
391296b06d325413723f5aac5988eed977b278a7807Greg Clayton            count = mangled_name_to_index.GetSize();
392296b06d325413723f5aac5988eed977b278a7807Greg Clayton            for (size_t i=0; i<count; ++i)
393296b06d325413723f5aac5988eed977b278a7807Greg Clayton            {
394296b06d325413723f5aac5988eed977b278a7807Greg Clayton                if (mangled_name_to_index.GetValueAtIndex(i, entry.value))
395296b06d325413723f5aac5988eed977b278a7807Greg Clayton                {
396296b06d325413723f5aac5988eed977b278a7807Greg Clayton                    entry.cstring = mangled_name_to_index.GetCStringAtIndex(i);
397296b06d325413723f5aac5988eed977b278a7807Greg Clayton                    if (symbol_contexts[entry.value] && class_contexts.find(symbol_contexts[entry.value]) != class_contexts.end())
398296b06d325413723f5aac5988eed977b278a7807Greg Clayton                    {
399296b06d325413723f5aac5988eed977b278a7807Greg Clayton                        m_method_to_index.Append (entry);
400296b06d325413723f5aac5988eed977b278a7807Greg Clayton                    }
401296b06d325413723f5aac5988eed977b278a7807Greg Clayton                    else
402296b06d325413723f5aac5988eed977b278a7807Greg Clayton                    {
403296b06d325413723f5aac5988eed977b278a7807Greg Clayton                        // If we got here, we have something that had a context (was inside a namespace or class)
404296b06d325413723f5aac5988eed977b278a7807Greg Clayton                        // yet we don't know if the entry
405296b06d325413723f5aac5988eed977b278a7807Greg Clayton                        m_method_to_index.Append (entry);
406296b06d325413723f5aac5988eed977b278a7807Greg Clayton                        m_basename_to_index.Append (entry);
407296b06d325413723f5aac5988eed977b278a7807Greg Clayton                    }
408296b06d325413723f5aac5988eed977b278a7807Greg Clayton                }
409296b06d325413723f5aac5988eed977b278a7807Greg Clayton            }
410296b06d325413723f5aac5988eed977b278a7807Greg Clayton        }
4118d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton        m_name_to_index.Sort();
412d3850ab15ed119ae36136656df0bae4feb0c9fc1Greg Clayton        m_name_to_index.SizeToFit();
4132fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton        m_selector_to_index.Sort();
4142fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton        m_selector_to_index.SizeToFit();
415296b06d325413723f5aac5988eed977b278a7807Greg Clayton        m_basename_to_index.Sort();
416296b06d325413723f5aac5988eed977b278a7807Greg Clayton        m_basename_to_index.SizeToFit();
417296b06d325413723f5aac5988eed977b278a7807Greg Clayton        m_method_to_index.Sort();
418296b06d325413723f5aac5988eed977b278a7807Greg Clayton        m_method_to_index.SizeToFit();
419296b06d325413723f5aac5988eed977b278a7807Greg Clayton
420296b06d325413723f5aac5988eed977b278a7807Greg Clayton//        static StreamFile a ("/tmp/a.txt");
421296b06d325413723f5aac5988eed977b278a7807Greg Clayton//
422296b06d325413723f5aac5988eed977b278a7807Greg Clayton//        count = m_basename_to_index.GetSize();
423296b06d325413723f5aac5988eed977b278a7807Greg Clayton//        if (count)
424296b06d325413723f5aac5988eed977b278a7807Greg Clayton//        {
425296b06d325413723f5aac5988eed977b278a7807Greg Clayton//            for (size_t i=0; i<count; ++i)
426296b06d325413723f5aac5988eed977b278a7807Greg Clayton//            {
427296b06d325413723f5aac5988eed977b278a7807Greg Clayton//                if (m_basename_to_index.GetValueAtIndex(i, entry.value))
428296b06d325413723f5aac5988eed977b278a7807Greg Clayton//                    a.Printf ("%s BASENAME\n", m_symbols[entry.value].GetMangled().GetName().GetCString());
429296b06d325413723f5aac5988eed977b278a7807Greg Clayton//            }
430296b06d325413723f5aac5988eed977b278a7807Greg Clayton//        }
431296b06d325413723f5aac5988eed977b278a7807Greg Clayton//        count = m_method_to_index.GetSize();
432296b06d325413723f5aac5988eed977b278a7807Greg Clayton//        if (count)
433296b06d325413723f5aac5988eed977b278a7807Greg Clayton//        {
434296b06d325413723f5aac5988eed977b278a7807Greg Clayton//            for (size_t i=0; i<count; ++i)
435296b06d325413723f5aac5988eed977b278a7807Greg Clayton//            {
436296b06d325413723f5aac5988eed977b278a7807Greg Clayton//                if (m_method_to_index.GetValueAtIndex(i, entry.value))
437296b06d325413723f5aac5988eed977b278a7807Greg Clayton//                    a.Printf ("%s METHOD\n", m_symbols[entry.value].GetMangled().GetName().GetCString());
438296b06d325413723f5aac5988eed977b278a7807Greg Clayton//            }
439296b06d325413723f5aac5988eed977b278a7807Greg Clayton//        }
44024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
44124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
44224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
44316d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Claytonvoid
444296b06d325413723f5aac5988eed977b278a7807Greg ClaytonSymtab::AppendSymbolNamesToMap (const IndexCollection &indexes,
44516d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton                                bool add_demangled,
44616d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton                                bool add_mangled,
44716d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton                                NameToIndexMap &name_to_index_map) const
44816d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton{
44916d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton    if (add_demangled || add_mangled)
45016d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton    {
45116d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton        Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__);
45216d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton        Mutex::Locker locker (m_mutex);
45316d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton
45416d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton        // Create the name index vector to be able to quickly search by name
45516d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton        NameToIndexMap::Entry entry;
45616d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton        const size_t num_indexes = indexes.size();
45716d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton        for (size_t i=0; i<num_indexes; ++i)
45816d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton        {
45916d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton            entry.value = indexes[i];
46016d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton            assert (i < m_symbols.size());
46116d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton            const Symbol *symbol = &m_symbols[entry.value];
46216d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton
46316d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton            const Mangled &mangled = symbol->GetMangled();
46416d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton            if (add_demangled)
46516d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton            {
46616d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton                entry.cstring = mangled.GetDemangledName().GetCString();
46716d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton                if (entry.cstring && entry.cstring[0])
46816d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton                    name_to_index_map.Append (entry);
46916d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton            }
47016d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton
47116d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton            if (add_mangled)
47216d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton            {
47316d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton                entry.cstring = mangled.GetMangledName().GetCString();
47416d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton                if (entry.cstring && entry.cstring[0])
47516d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton                    name_to_index_map.Append (entry);
47616d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton            }
47716d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton        }
47816d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton    }
47916d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton}
48016d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton
48124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint32_t
4827c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg ClaytonSymtab::AppendSymbolIndexesWithType (SymbolType symbol_type, std::vector<uint32_t>& indexes, uint32_t start_idx, uint32_t end_index) const
48324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
4848d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    Mutex::Locker locker (m_mutex);
4858d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton
48624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t prev_size = indexes.size();
48724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
48824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const uint32_t count = std::min<uint32_t> (m_symbols.size(), end_index);
48924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
49024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    for (uint32_t i = start_idx; i < count; ++i)
49124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
49224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (symbol_type == eSymbolTypeAny || m_symbols[i].GetType() == symbol_type)
49324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            indexes.push_back(i);
49424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
49524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
49624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return indexes.size() - prev_size;
49724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
49824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
4997c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Claytonuint32_t
500cd151697a4b4d32d8818488b793ea44712945448Greg ClaytonSymtab::AppendSymbolIndexesWithTypeAndFlagsValue (SymbolType symbol_type, uint32_t flags_value, std::vector<uint32_t>& indexes, uint32_t start_idx, uint32_t end_index) const
501cd151697a4b4d32d8818488b793ea44712945448Greg Clayton{
502cd151697a4b4d32d8818488b793ea44712945448Greg Clayton    Mutex::Locker locker (m_mutex);
503cd151697a4b4d32d8818488b793ea44712945448Greg Clayton
504cd151697a4b4d32d8818488b793ea44712945448Greg Clayton    uint32_t prev_size = indexes.size();
505cd151697a4b4d32d8818488b793ea44712945448Greg Clayton
506cd151697a4b4d32d8818488b793ea44712945448Greg Clayton    const uint32_t count = std::min<uint32_t> (m_symbols.size(), end_index);
507cd151697a4b4d32d8818488b793ea44712945448Greg Clayton
508cd151697a4b4d32d8818488b793ea44712945448Greg Clayton    for (uint32_t i = start_idx; i < count; ++i)
509cd151697a4b4d32d8818488b793ea44712945448Greg Clayton    {
510cd151697a4b4d32d8818488b793ea44712945448Greg Clayton        if ((symbol_type == eSymbolTypeAny || m_symbols[i].GetType() == symbol_type) && m_symbols[i].GetFlags() == flags_value)
511cd151697a4b4d32d8818488b793ea44712945448Greg Clayton            indexes.push_back(i);
512cd151697a4b4d32d8818488b793ea44712945448Greg Clayton    }
513cd151697a4b4d32d8818488b793ea44712945448Greg Clayton
514cd151697a4b4d32d8818488b793ea44712945448Greg Clayton    return indexes.size() - prev_size;
515cd151697a4b4d32d8818488b793ea44712945448Greg Clayton}
516cd151697a4b4d32d8818488b793ea44712945448Greg Clayton
517cd151697a4b4d32d8818488b793ea44712945448Greg Claytonuint32_t
5187c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg ClaytonSymtab::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
5197c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton{
5208d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    Mutex::Locker locker (m_mutex);
5218d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton
5227c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton    uint32_t prev_size = indexes.size();
5237c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton
5247c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton    const uint32_t count = std::min<uint32_t> (m_symbols.size(), end_index);
5257c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton
5267c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton    for (uint32_t i = start_idx; i < count; ++i)
5277c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton    {
5287c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton        if (symbol_type == eSymbolTypeAny || m_symbols[i].GetType() == symbol_type)
5297c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton        {
5307c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton            if (CheckSymbolAtIndex(i, symbol_debug_type, symbol_visibility))
5317c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton                indexes.push_back(i);
5327c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton        }
5337c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton    }
5347c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton
5357c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton    return indexes.size() - prev_size;
5367c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton}
5377c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton
5387c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton
5397c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Claytonuint32_t
5407c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg ClaytonSymtab::GetIndexForSymbol (const Symbol *symbol) const
5417c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton{
5427c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton    const Symbol *first_symbol = &m_symbols[0];
5437c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton    if (symbol >= first_symbol && symbol < first_symbol + m_symbols.size())
5447c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton        return symbol - first_symbol;
5457c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton    return UINT32_MAX;
5467c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton}
5477c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton
54824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstruct SymbolSortInfo
54924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
55024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const bool sort_by_load_addr;
55124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const Symbol *symbols;
55224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner};
55324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
554c3d68556a5ae14219eb7638dade1799ab94b69feOwen Andersonnamespace {
555c3d68556a5ae14219eb7638dade1799ab94b69feOwen Anderson    struct SymbolIndexComparator {
556c3d68556a5ae14219eb7638dade1799ab94b69feOwen Anderson        const std::vector<Symbol>& symbols;
55799c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham        std::vector<lldb::addr_t>  &addr_cache;
55899c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham
55999c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham        // Getting from the symbol to the Address to the File Address involves some work.
56099c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham        // Since there are potentially many symbols here, and we're using this for sorting so
56199c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham        // we're going to be computing the address many times, cache that in addr_cache.
56299c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham        // The array passed in has to be the same size as the symbols array passed into the
56399c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham        // member variable symbols, and should be initialized with LLDB_INVALID_ADDRESS.
56499c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham        // NOTE: You have to make addr_cache externally and pass it in because std::stable_sort
56599c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham        // makes copies of the comparator it is initially passed in, and you end up spending
56699c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham        // huge amounts of time copying this array...
56799c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham
56899c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham        SymbolIndexComparator(const std::vector<Symbol>& s, std::vector<lldb::addr_t> &a) : symbols(s), addr_cache(a)  {
56999c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham            assert (symbols.size() == addr_cache.size());
57099c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham        }
571c3d68556a5ae14219eb7638dade1799ab94b69feOwen Anderson        bool operator()(uint32_t index_a, uint32_t index_b) {
57299c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham            addr_t value_a = addr_cache[index_a];
57399c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham            if (value_a == LLDB_INVALID_ADDRESS)
57499c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham            {
57599c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham                value_a = symbols[index_a].GetAddress().GetFileAddress();
57699c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham                addr_cache[index_a] = value_a;
57799c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham            }
57899c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham
57999c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham            addr_t value_b = addr_cache[index_b];
58099c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham            if (value_b == LLDB_INVALID_ADDRESS)
58199c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham            {
58299c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham                value_b = symbols[index_b].GetAddress().GetFileAddress();
58399c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham                addr_cache[index_b] = value_b;
58499c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham            }
58599c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham
5867dbd6da9a222b6bcef35f1cb8ab838a30b7f75e5Owen Anderson
587c3d68556a5ae14219eb7638dade1799ab94b69feOwen Anderson            if (value_a == value_b) {
588c3d68556a5ae14219eb7638dade1799ab94b69feOwen Anderson                // The if the values are equal, use the original symbol user ID
589c3d68556a5ae14219eb7638dade1799ab94b69feOwen Anderson                lldb::user_id_t uid_a = symbols[index_a].GetID();
590c3d68556a5ae14219eb7638dade1799ab94b69feOwen Anderson                lldb::user_id_t uid_b = symbols[index_b].GetID();
591c3d68556a5ae14219eb7638dade1799ab94b69feOwen Anderson                if (uid_a < uid_b)
592c3d68556a5ae14219eb7638dade1799ab94b69feOwen Anderson                    return true;
593c3d68556a5ae14219eb7638dade1799ab94b69feOwen Anderson                if (uid_a > uid_b)
594c3d68556a5ae14219eb7638dade1799ab94b69feOwen Anderson                    return false;
595c3d68556a5ae14219eb7638dade1799ab94b69feOwen Anderson                return false;
596c3d68556a5ae14219eb7638dade1799ab94b69feOwen Anderson            } else if (value_a < value_b)
597c3d68556a5ae14219eb7638dade1799ab94b69feOwen Anderson                return true;
598c3d68556a5ae14219eb7638dade1799ab94b69feOwen Anderson
599c3d68556a5ae14219eb7638dade1799ab94b69feOwen Anderson            return false;
600c3d68556a5ae14219eb7638dade1799ab94b69feOwen Anderson        }
601c3d68556a5ae14219eb7638dade1799ab94b69feOwen Anderson    };
602020f353bf792f1028e4037ea92d03acc90594c40Eli Friedman}
603020f353bf792f1028e4037ea92d03acc90594c40Eli Friedman
60424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
60524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerSymtab::SortSymbolIndexesByValue (std::vector<uint32_t>& indexes, bool remove_duplicates) const
60624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
6078d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    Mutex::Locker locker (m_mutex);
6088d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton
609c3d68556a5ae14219eb7638dade1799ab94b69feOwen Anderson    Timer scoped_timer (__PRETTY_FUNCTION__,__PRETTY_FUNCTION__);
61024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // No need to sort if we have zero or one items...
61124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (indexes.size() <= 1)
61224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return;
61324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
614a1e14750737ce399beb491973e8f9a349c3e3a1cOwen Anderson    // Sort the indexes in place using std::stable_sort.
615a1e14750737ce399beb491973e8f9a349c3e3a1cOwen Anderson    // NOTE: The use of std::stable_sort instead of std::sort here is strictly for performance,
616a1e14750737ce399beb491973e8f9a349c3e3a1cOwen Anderson    // not correctness.  The indexes vector tends to be "close" to sorted, which the
617a1e14750737ce399beb491973e8f9a349c3e3a1cOwen Anderson    // stable sort handles better.
61899c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham
61999c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham    std::vector<lldb::addr_t> addr_cache(m_symbols.size(), LLDB_INVALID_ADDRESS);
62099c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham
62199c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham    SymbolIndexComparator comparator(m_symbols, addr_cache);
62299c63be2c47f5f01d3b0885c4405a4488456417fJim Ingham    std::stable_sort(indexes.begin(), indexes.end(), comparator);
62324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
62424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Remove any duplicates if requested
62524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (remove_duplicates)
62624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        std::unique(indexes.begin(), indexes.end());
62724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
62824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
62924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint32_t
6307c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg ClaytonSymtab::AppendSymbolIndexesWithName (const ConstString& symbol_name, std::vector<uint32_t>& indexes)
63124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
6328d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    Mutex::Locker locker (m_mutex);
6338d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton
63424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__);
63524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (symbol_name)
63624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
637448bd2fe5693c3ef591743d460b8b830607cfa09Greg Clayton        const char *symbol_cstr = symbol_name.GetCString();
6388d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton        if (!m_name_indexes_computed)
63924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            InitNameIndexes();
64024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
641448bd2fe5693c3ef591743d460b8b830607cfa09Greg Clayton        return m_name_to_index.GetValues (symbol_cstr, indexes);
64224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
64324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return 0;
64424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
64524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
64624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint32_t
6477c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg ClaytonSymtab::AppendSymbolIndexesWithName (const ConstString& symbol_name, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& indexes)
6487c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton{
6498d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    Mutex::Locker locker (m_mutex);
6508d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton
6517c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton    Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__);
6527c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton    if (symbol_name)
6537c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton    {
6547c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton        const size_t old_size = indexes.size();
6558d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton        if (!m_name_indexes_computed)
6567c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton            InitNameIndexes();
6577c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton
6587c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton        const char *symbol_cstr = symbol_name.GetCString();
659448bd2fe5693c3ef591743d460b8b830607cfa09Greg Clayton
660448bd2fe5693c3ef591743d460b8b830607cfa09Greg Clayton        std::vector<uint32_t> all_name_indexes;
661448bd2fe5693c3ef591743d460b8b830607cfa09Greg Clayton        const size_t name_match_count = m_name_to_index.GetValues (symbol_cstr, all_name_indexes);
662448bd2fe5693c3ef591743d460b8b830607cfa09Greg Clayton        for (size_t i=0; i<name_match_count; ++i)
6637c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton        {
664448bd2fe5693c3ef591743d460b8b830607cfa09Greg Clayton            if (CheckSymbolAtIndex(all_name_indexes[i], symbol_debug_type, symbol_visibility))
665448bd2fe5693c3ef591743d460b8b830607cfa09Greg Clayton                indexes.push_back (all_name_indexes[i]);
6667c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton        }
6677c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton        return indexes.size() - old_size;
6687c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton    }
6697c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton    return 0;
6707c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton}
6717c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton
6727c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Claytonuint32_t
6737c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg ClaytonSymtab::AppendSymbolIndexesWithNameAndType (const ConstString& symbol_name, SymbolType symbol_type, std::vector<uint32_t>& indexes)
67424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
6758d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    Mutex::Locker locker (m_mutex);
6768d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton
67724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (AppendSymbolIndexesWithName(symbol_name, indexes) > 0)
67824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
67924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        std::vector<uint32_t>::iterator pos = indexes.begin();
68024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        while (pos != indexes.end())
68124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
68224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (symbol_type == eSymbolTypeAny || m_symbols[*pos].GetType() == symbol_type)
68324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                ++pos;
68424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            else
68524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                indexes.erase(pos);
68624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
68724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
68824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return indexes.size();
68924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
69024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
69124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint32_t
6927c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg ClaytonSymtab::AppendSymbolIndexesWithNameAndType (const ConstString& symbol_name, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& indexes)
6937c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton{
6948d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    Mutex::Locker locker (m_mutex);
6958d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton
6967c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton    if (AppendSymbolIndexesWithName(symbol_name, symbol_debug_type, symbol_visibility, indexes) > 0)
6977c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton    {
6987c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton        std::vector<uint32_t>::iterator pos = indexes.begin();
6997c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton        while (pos != indexes.end())
7007c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton        {
7017c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton            if (symbol_type == eSymbolTypeAny || m_symbols[*pos].GetType() == symbol_type)
7027c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton                ++pos;
7037c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton            else
7047c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton                indexes.erase(pos);
7057c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton        }
7067c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton    }
7077c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton    return indexes.size();
7087c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton}
7097c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton
7107c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton
7117c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Claytonuint32_t
71224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerSymtab::AppendSymbolIndexesMatchingRegExAndType (const RegularExpression &regexp, SymbolType symbol_type, std::vector<uint32_t>& indexes)
71324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
7148d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    Mutex::Locker locker (m_mutex);
7158d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton
71624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t prev_size = indexes.size();
71724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t sym_end = m_symbols.size();
71824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7193e11c7ec050648ba865f1d451f8cb46fd39072a8Andy Gibbs    for (uint32_t i = 0; i < sym_end; i++)
72024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
72124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (symbol_type == eSymbolTypeAny || m_symbols[i].GetType() == symbol_type)
72224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
72324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            const char *name = m_symbols[i].GetMangled().GetName().AsCString();
72424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (name)
72524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
72624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (regexp.Execute (name))
72724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    indexes.push_back(i);
72824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
72924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
73024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
73124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return indexes.size() - prev_size;
73224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
73324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
73424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7357c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Claytonuint32_t
7367c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg ClaytonSymtab::AppendSymbolIndexesMatchingRegExAndType (const RegularExpression &regexp, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& indexes)
73724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
7388d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    Mutex::Locker locker (m_mutex);
7398d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton
7407c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton    uint32_t prev_size = indexes.size();
7417c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton    uint32_t sym_end = m_symbols.size();
7427c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton
7433e11c7ec050648ba865f1d451f8cb46fd39072a8Andy Gibbs    for (uint32_t i = 0; i < sym_end; i++)
74424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
7457c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton        if (symbol_type == eSymbolTypeAny || m_symbols[i].GetType() == symbol_type)
74624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
7477c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton            if (CheckSymbolAtIndex(i, symbol_debug_type, symbol_visibility) == false)
7487c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton                continue;
7497c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton
7507c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton            const char *name = m_symbols[i].GetMangled().GetName().AsCString();
7517c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton            if (name)
7527c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton            {
7537c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton                if (regexp.Execute (name))
7547c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton                    indexes.push_back(i);
7557c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton            }
75624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
75724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
7587c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton    return indexes.size() - prev_size;
7597c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton
76024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
76124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7627c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg ClaytonSymbol *
7637c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg ClaytonSymtab::FindSymbolWithType (SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, uint32_t& start_idx)
76424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
7658d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    Mutex::Locker locker (m_mutex);
7668d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton
76724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const size_t count = m_symbols.size();
76836da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton    for (size_t idx = start_idx; idx < count; ++idx)
76924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
77024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (symbol_type == eSymbolTypeAny || m_symbols[idx].GetType() == symbol_type)
77124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
7727c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton            if (CheckSymbolAtIndex(idx, symbol_debug_type, symbol_visibility))
7737c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton            {
7747c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton                start_idx = idx;
7757c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton                return &m_symbols[idx];
7767c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton            }
77724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
77824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
77924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return NULL;
78024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
78124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
78224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnersize_t
78324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerSymtab::FindAllSymbolsWithNameAndType (const ConstString &name, SymbolType symbol_type, std::vector<uint32_t>& symbol_indexes)
78424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
7858d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    Mutex::Locker locker (m_mutex);
7868d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton
78724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__);
78824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Initialize all of the lookup by name indexes before converting NAME
78924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // to a uniqued string NAME_STR below.
7908d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    if (!m_name_indexes_computed)
79124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        InitNameIndexes();
79224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
79324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (name)
79424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
79524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // The string table did have a string that matched, but we need
79624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // to check the symbols and match the symbol_type if any was given.
7977c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton        AppendSymbolIndexesWithNameAndType (name, symbol_type, symbol_indexes);
7987c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton    }
7997c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton    return symbol_indexes.size();
8007c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton}
8017c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton
8027c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Claytonsize_t
8037c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg ClaytonSymtab::FindAllSymbolsWithNameAndType (const ConstString &name, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& symbol_indexes)
8047c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton{
8058d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    Mutex::Locker locker (m_mutex);
8068d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton
8077c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton    Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__);
8087c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton    // Initialize all of the lookup by name indexes before converting NAME
8097c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton    // to a uniqued string NAME_STR below.
8108d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    if (!m_name_indexes_computed)
8117c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton        InitNameIndexes();
8127c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton
8137c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton    if (name)
8147c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton    {
8157c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton        // The string table did have a string that matched, but we need
8167c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton        // to check the symbols and match the symbol_type if any was given.
8177c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton        AppendSymbolIndexesWithNameAndType (name, symbol_type, symbol_debug_type, symbol_visibility, symbol_indexes);
81824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
81924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return symbol_indexes.size();
82024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
82124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
82224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnersize_t
8237c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg ClaytonSymtab::FindAllSymbolsMatchingRexExAndType (const RegularExpression &regex, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& symbol_indexes)
82424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
8258d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    Mutex::Locker locker (m_mutex);
8268d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton
8277c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton    AppendSymbolIndexesMatchingRegExAndType(regex, symbol_type, symbol_debug_type, symbol_visibility, symbol_indexes);
82824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return symbol_indexes.size();
82924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
83024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
83124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerSymbol *
8327c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg ClaytonSymtab::FindFirstSymbolWithNameAndType (const ConstString &name, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility)
83324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
8348d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    Mutex::Locker locker (m_mutex);
8358d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton
83624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__);
8378d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    if (!m_name_indexes_computed)
83824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        InitNameIndexes();
83924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
84024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (name)
84124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
84224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        std::vector<uint32_t> matching_indexes;
84324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // The string table did have a string that matched, but we need
84424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // to check the symbols and match the symbol_type if any was given.
8457c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton        if (AppendSymbolIndexesWithNameAndType (name, symbol_type, symbol_debug_type, symbol_visibility, matching_indexes))
84624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
84724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            std::vector<uint32_t>::const_iterator pos, end = matching_indexes.end();
84824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            for (pos = matching_indexes.begin(); pos != end; ++pos)
84924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
85024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                Symbol *symbol = SymbolAtIndex(*pos);
85124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
85224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (symbol->Compare(name, symbol_type))
85324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    return symbol;
85424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
85524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
85624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
85724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return NULL;
85824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
85924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
86024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnertypedef struct
86124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
86224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const Symtab *symtab;
86324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const addr_t file_addr;
86424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Symbol *match_symbol;
86524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const uint32_t *match_index_ptr;
86624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    addr_t match_offset;
86724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} SymbolSearchInfo;
86824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
86924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic int
87024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerSymbolWithFileAddress (SymbolSearchInfo *info, const uint32_t *index_ptr)
87124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
87224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const Symbol *curr_symbol = info->symtab->SymbolAtIndex (index_ptr[0]);
87324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (curr_symbol == NULL)
87424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return -1;
87524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
87624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const addr_t info_file_addr = info->file_addr;
87724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
87824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // lldb::Symbol::GetAddressRangePtr() will only return a non NULL address
87924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // range if the symbol has a section!
8800c31d3d3a4a1d00d53346d8a23b0519f47e55d1fGreg Clayton    if (curr_symbol->ValueIsAddress())
88124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
8820c31d3d3a4a1d00d53346d8a23b0519f47e55d1fGreg Clayton        const addr_t curr_file_addr = curr_symbol->GetAddress().GetFileAddress();
88324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (info_file_addr < curr_file_addr)
88424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return -1;
88524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (info_file_addr > curr_file_addr)
88624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return +1;
88724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        info->match_symbol = const_cast<Symbol *>(curr_symbol);
88824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        info->match_index_ptr = index_ptr;
88924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return 0;
89024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
89124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
89224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return -1;
89324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
89424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
89524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic int
89624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerSymbolWithClosestFileAddress (SymbolSearchInfo *info, const uint32_t *index_ptr)
89724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
89824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const Symbol *symbol = info->symtab->SymbolAtIndex (index_ptr[0]);
89924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (symbol == NULL)
90024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return -1;
90124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
90224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const addr_t info_file_addr = info->file_addr;
9030c31d3d3a4a1d00d53346d8a23b0519f47e55d1fGreg Clayton    if (symbol->ValueIsAddress())
90424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
9050c31d3d3a4a1d00d53346d8a23b0519f47e55d1fGreg Clayton        const addr_t curr_file_addr = symbol->GetAddress().GetFileAddress();
90624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (info_file_addr < curr_file_addr)
90724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return -1;
90824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
90924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Since we are finding the closest symbol that is greater than or equal
91024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // to 'info->file_addr' we set the symbol here. This will get set
91124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // multiple times, but after the search is done it will contain the best
91224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // symbol match
91324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        info->match_symbol = const_cast<Symbol *>(symbol);
91424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        info->match_index_ptr = index_ptr;
91524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        info->match_offset = info_file_addr - curr_file_addr;
91624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
91724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (info_file_addr > curr_file_addr)
91824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return +1;
91924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return 0;
92024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
92124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return -1;
92224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
92324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
92424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic SymbolSearchInfo
92524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFindIndexPtrForSymbolContainingAddress(Symtab* symtab, addr_t file_addr, const uint32_t* indexes, uint32_t num_indexes)
92624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
92724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    SymbolSearchInfo info = { symtab, file_addr, NULL, NULL, 0 };
928b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton    ::bsearch (&info,
929b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton               indexes,
930b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton               num_indexes,
931b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton               sizeof(uint32_t),
932b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton               (ComparisonFunction)SymbolWithClosestFileAddress);
93324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return info;
93424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
93524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
93624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
93724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
93824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerSymtab::InitAddressIndexes()
93924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
9408d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    // Protected function, no need to lock mutex...
9417940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton    if (!m_file_addr_to_index_computed && !m_symbols.empty())
94224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
9437940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton        m_file_addr_to_index_computed = true;
944f58438fa7751274b6f4e4b1805940127dce13b00Greg Clayton
9457940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton        FileRangeToIndexMap::Entry entry;
9468d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton        const_iterator begin = m_symbols.begin();
9478d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton        const_iterator end = m_symbols.end();
9488d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton        for (const_iterator pos = m_symbols.begin(); pos != end; ++pos)
9498d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton        {
9500c31d3d3a4a1d00d53346d8a23b0519f47e55d1fGreg Clayton            if (pos->ValueIsAddress())
9517940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton            {
9527940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton                entry.SetRangeBase(pos->GetAddress().GetFileAddress());
9537940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton                entry.SetByteSize(pos->GetByteSize());
9547940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton                entry.data = std::distance(begin, pos);
9557940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton                m_file_addr_to_index.Append(entry);
9567940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton            }
9578d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton        }
9587940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton        const size_t num_entries = m_file_addr_to_index.GetSize();
9597940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton        if (num_entries > 0)
9607940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton        {
9617940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton            m_file_addr_to_index.Sort();
9627940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton            m_file_addr_to_index.CalculateSizesOfZeroByteSizeRanges();
9637940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton
9647940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton            // Now our last symbols might not have had sizes because there
9657940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton            // was no subsequent symbol to calculate the size from. If this is
9667940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton            // the case, then calculate the size by capping it at the end of the
9677940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton            // section in which the symbol resides
9687940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton            for (int i = num_entries - 1; i >= 0; --i)
9697940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton            {
9707940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton                const FileRangeToIndexMap::Entry &entry = m_file_addr_to_index.GetEntryRef(i);
9717940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton                // As we iterate backwards, as soon as we find a symbol with a valid
9727940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton                // byte size, we are done
9737940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton                if (entry.GetByteSize() > 0)
9747940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton                    break;
9757940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton
9767940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton                // Cap the size to the end of the section in which the symbol resides
9777940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton                SectionSP section_sp (m_objfile->GetSectionList()->FindSectionContainingFileAddress (entry.GetRangeBase()));
9787940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton                if (section_sp)
9797940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton                {
9807940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton                    const lldb::addr_t end_section_file_addr = section_sp->GetFileAddress() + section_sp->GetByteSize();
9817940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton                    const lldb::addr_t symbol_file_addr = entry.GetRangeBase();
9827940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton                    if (end_section_file_addr > symbol_file_addr)
9837940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton                    {
9847940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton                        Symbol &symbol = m_symbols[entry.data];
985f58438fa7751274b6f4e4b1805940127dce13b00Greg Clayton
9867940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton                        symbol.SetByteSize(end_section_file_addr - symbol_file_addr);
9877940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton                        symbol.SetSizeIsSynthesized(true);
9887940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton                    }
9897940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton                }
9907940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton            }
9917940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton            // Sort again in case the range size changes the ordering
9927940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton            m_file_addr_to_index.Sort();
9937940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton        }
99424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
99524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
99624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9977940069905bee0b2e5f0661bf37c9f906ddf8603Greg Claytonvoid
9987940069905bee0b2e5f0661bf37c9f906ddf8603Greg ClaytonSymtab::CalculateSymbolSizes ()
99924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
10008d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    Mutex::Locker locker (m_mutex);
10018d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton
10027940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton    if (!m_symbols.empty())
100324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
10047940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton        if (!m_file_addr_to_index_computed)
100524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            InitAddressIndexes();
10067940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton
10077940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton        const size_t num_entries = m_file_addr_to_index.GetSize();
10087940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton
10097940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton        for (size_t i = 0; i < num_entries; ++i)
101024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
10117940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton            // The entries in the m_file_addr_to_index have calculated the sizes already
10127940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton            // so we will use this size if we need to.
10137940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton            const FileRangeToIndexMap::Entry &entry = m_file_addr_to_index.GetEntryRef(i);
10147940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton
10157940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton            Symbol &symbol = m_symbols[entry.data];
101624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
10177940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton            // If the symbol size is already valid, no need to do anything
10187940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton            if (symbol.GetByteSizeIsValid())
10197940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton                continue;
10207940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton
10217940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton            const addr_t range_size = entry.GetByteSize();
10227940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton            if (range_size > 0)
102324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
10247940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton                symbol.SetByteSize(range_size);
10257940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton                symbol.SetSizeIsSynthesized(true);
102624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
102724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
102824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
102924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
103024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
103124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerSymbol *
103224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerSymtab::FindSymbolContainingFileAddress (addr_t file_addr, const uint32_t* indexes, uint32_t num_indexes)
103324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
10348d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    Mutex::Locker locker (m_mutex);
10358d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton
10367940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton
103724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    SymbolSearchInfo info = { this, file_addr, NULL, NULL, 0 };
103824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1039b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton    ::bsearch (&info,
1040b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton               indexes,
1041b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton               num_indexes,
1042b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton               sizeof(uint32_t),
1043b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton               (ComparisonFunction)SymbolWithClosestFileAddress);
104424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
104524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (info.match_symbol)
104624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
10473fed8b9b2696fc2ea78005c8f9b1c621d5748042Greg Clayton        if (info.match_offset == 0)
10483fed8b9b2696fc2ea78005c8f9b1c621d5748042Greg Clayton        {
10493fed8b9b2696fc2ea78005c8f9b1c621d5748042Greg Clayton            // We found an exact match!
10503fed8b9b2696fc2ea78005c8f9b1c621d5748042Greg Clayton            return info.match_symbol;
10513fed8b9b2696fc2ea78005c8f9b1c621d5748042Greg Clayton        }
10523fed8b9b2696fc2ea78005c8f9b1c621d5748042Greg Clayton
10539f69f982142c1c6d4dbece98879eaf746e66728bGreg Clayton        const size_t symbol_byte_size = info.match_symbol->GetByteSize();
10543fed8b9b2696fc2ea78005c8f9b1c621d5748042Greg Clayton
10553fed8b9b2696fc2ea78005c8f9b1c621d5748042Greg Clayton        if (symbol_byte_size == 0)
10563fed8b9b2696fc2ea78005c8f9b1c621d5748042Greg Clayton        {
10573fed8b9b2696fc2ea78005c8f9b1c621d5748042Greg Clayton            // We weren't able to find the size of the symbol so lets just go
10583fed8b9b2696fc2ea78005c8f9b1c621d5748042Greg Clayton            // with that match we found in our search...
10593fed8b9b2696fc2ea78005c8f9b1c621d5748042Greg Clayton            return info.match_symbol;
10603fed8b9b2696fc2ea78005c8f9b1c621d5748042Greg Clayton        }
10613fed8b9b2696fc2ea78005c8f9b1c621d5748042Greg Clayton
10623fed8b9b2696fc2ea78005c8f9b1c621d5748042Greg Clayton        // We were able to figure out a symbol size so lets make sure our
10633fed8b9b2696fc2ea78005c8f9b1c621d5748042Greg Clayton        // offset puts "file_addr" in the symbol's address range.
10643fed8b9b2696fc2ea78005c8f9b1c621d5748042Greg Clayton        if (info.match_offset < symbol_byte_size)
106524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return info.match_symbol;
106624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
106724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return NULL;
106824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
106924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
107024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerSymbol *
107124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerSymtab::FindSymbolContainingFileAddress (addr_t file_addr)
107224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
10738d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton    Mutex::Locker locker (m_mutex);
10748d3802d9d6c1be4c0d37c4d269b18bcb865823e6Greg Clayton
10757940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton    if (!m_file_addr_to_index_computed)
107624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        InitAddressIndexes();
107724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
10787940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton    const FileRangeToIndexMap::Entry *entry = m_file_addr_to_index.FindEntryThatContains(file_addr);
10797940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton    if (entry)
10807940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton        return SymbolAtIndex(entry->data);
10817940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton    return NULL;
108224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
108324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
10842fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Claytonvoid
10852fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg ClaytonSymtab::SymbolIndicesToSymbolContextList (std::vector<uint32_t> &symbol_indexes, SymbolContextList &sc_list)
10862fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton{
10872fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton    // No need to protect this call using m_mutex all other method calls are
10882fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton    // already thread safe.
10892fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton
1090296b06d325413723f5aac5988eed977b278a7807Greg Clayton    const bool merge_symbol_into_function = true;
10912fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton    size_t num_indices = symbol_indexes.size();
10922fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton    if (num_indices > 0)
10932fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton    {
10942fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton        SymbolContext sc;
10952fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton        sc.module_sp = m_objfile->GetModule();
10962fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton        for (size_t i = 0; i < num_indices; i++)
10972fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton        {
10982fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton            sc.symbol = SymbolAtIndex (symbol_indexes[i]);
10992fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton            if (sc.symbol)
1100296b06d325413723f5aac5988eed977b278a7807Greg Clayton                sc_list.AppendIfUnique(sc, merge_symbol_into_function);
11012fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton        }
11022fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton    }
11032fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton}
11042fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton
11052fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton
11062fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Claytonsize_t
11072fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg ClaytonSymtab::FindFunctionSymbols (const ConstString &name,
11082fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton                             uint32_t name_type_mask,
11092fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton                             SymbolContextList& sc_list)
11102fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton{
11112fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton    size_t count = 0;
11122fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton    std::vector<uint32_t> symbol_indexes;
1113296b06d325413723f5aac5988eed977b278a7807Greg Clayton
1114296b06d325413723f5aac5988eed977b278a7807Greg Clayton    const char *name_cstr = name.GetCString();
1115296b06d325413723f5aac5988eed977b278a7807Greg Clayton
1116296b06d325413723f5aac5988eed977b278a7807Greg Clayton    // eFunctionNameTypeAuto should be pre-resolved by a call to Module::PrepareForFunctionNameLookup()
1117296b06d325413723f5aac5988eed977b278a7807Greg Clayton    assert ((name_type_mask & eFunctionNameTypeAuto) == 0);
1118296b06d325413723f5aac5988eed977b278a7807Greg Clayton
1119296b06d325413723f5aac5988eed977b278a7807Greg Clayton    if (name_type_mask & (eFunctionNameTypeBase | eFunctionNameTypeFull))
11202fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton    {
1121977260cc6e57003ed02940a81f9b1af0aa5c89baMatt Kopec        std::vector<uint32_t> temp_symbol_indexes;
1122977260cc6e57003ed02940a81f9b1af0aa5c89baMatt Kopec        FindAllSymbolsWithNameAndType (name, eSymbolTypeAny, temp_symbol_indexes);
1123977260cc6e57003ed02940a81f9b1af0aa5c89baMatt Kopec
1124977260cc6e57003ed02940a81f9b1af0aa5c89baMatt Kopec        unsigned temp_symbol_indexes_size = temp_symbol_indexes.size();
1125977260cc6e57003ed02940a81f9b1af0aa5c89baMatt Kopec        if (temp_symbol_indexes_size > 0)
1126977260cc6e57003ed02940a81f9b1af0aa5c89baMatt Kopec        {
1127977260cc6e57003ed02940a81f9b1af0aa5c89baMatt Kopec            Mutex::Locker locker (m_mutex);
1128977260cc6e57003ed02940a81f9b1af0aa5c89baMatt Kopec            for (unsigned i = 0; i < temp_symbol_indexes_size; i++)
1129977260cc6e57003ed02940a81f9b1af0aa5c89baMatt Kopec            {
1130977260cc6e57003ed02940a81f9b1af0aa5c89baMatt Kopec                SymbolContext sym_ctx;
1131977260cc6e57003ed02940a81f9b1af0aa5c89baMatt Kopec                sym_ctx.symbol = SymbolAtIndex (temp_symbol_indexes[i]);
1132977260cc6e57003ed02940a81f9b1af0aa5c89baMatt Kopec                if (sym_ctx.symbol)
1133977260cc6e57003ed02940a81f9b1af0aa5c89baMatt Kopec                {
1134977260cc6e57003ed02940a81f9b1af0aa5c89baMatt Kopec                    switch (sym_ctx.symbol->GetType())
1135977260cc6e57003ed02940a81f9b1af0aa5c89baMatt Kopec                    {
1136977260cc6e57003ed02940a81f9b1af0aa5c89baMatt Kopec                    case eSymbolTypeCode:
1137977260cc6e57003ed02940a81f9b1af0aa5c89baMatt Kopec                    case eSymbolTypeResolver:
1138977260cc6e57003ed02940a81f9b1af0aa5c89baMatt Kopec                        symbol_indexes.push_back(temp_symbol_indexes[i]);
1139977260cc6e57003ed02940a81f9b1af0aa5c89baMatt Kopec                        break;
1140977260cc6e57003ed02940a81f9b1af0aa5c89baMatt Kopec                    default:
1141977260cc6e57003ed02940a81f9b1af0aa5c89baMatt Kopec                        break;
1142977260cc6e57003ed02940a81f9b1af0aa5c89baMatt Kopec                    }
1143977260cc6e57003ed02940a81f9b1af0aa5c89baMatt Kopec                }
1144977260cc6e57003ed02940a81f9b1af0aa5c89baMatt Kopec            }
1145977260cc6e57003ed02940a81f9b1af0aa5c89baMatt Kopec        }
11462fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton    }
11472fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton
1148296b06d325413723f5aac5988eed977b278a7807Greg Clayton    if (name_type_mask & eFunctionNameTypeBase)
1149296b06d325413723f5aac5988eed977b278a7807Greg Clayton    {
1150296b06d325413723f5aac5988eed977b278a7807Greg Clayton        // From mangled names we can't tell what is a basename and what
1151296b06d325413723f5aac5988eed977b278a7807Greg Clayton        // is a method name, so we just treat them the same
1152296b06d325413723f5aac5988eed977b278a7807Greg Clayton        if (!m_name_indexes_computed)
1153296b06d325413723f5aac5988eed977b278a7807Greg Clayton            InitNameIndexes();
1154296b06d325413723f5aac5988eed977b278a7807Greg Clayton
1155296b06d325413723f5aac5988eed977b278a7807Greg Clayton        if (!m_basename_to_index.IsEmpty())
1156296b06d325413723f5aac5988eed977b278a7807Greg Clayton        {
1157296b06d325413723f5aac5988eed977b278a7807Greg Clayton            const UniqueCStringMap<uint32_t>::Entry *match;
1158296b06d325413723f5aac5988eed977b278a7807Greg Clayton            for (match = m_basename_to_index.FindFirstValueForName(name_cstr);
1159296b06d325413723f5aac5988eed977b278a7807Greg Clayton                 match != NULL;
1160296b06d325413723f5aac5988eed977b278a7807Greg Clayton                 match = m_basename_to_index.FindNextValueForName(match))
1161296b06d325413723f5aac5988eed977b278a7807Greg Clayton            {
1162296b06d325413723f5aac5988eed977b278a7807Greg Clayton                symbol_indexes.push_back(match->value);
1163296b06d325413723f5aac5988eed977b278a7807Greg Clayton            }
1164296b06d325413723f5aac5988eed977b278a7807Greg Clayton        }
1165296b06d325413723f5aac5988eed977b278a7807Greg Clayton    }
1166296b06d325413723f5aac5988eed977b278a7807Greg Clayton
1167296b06d325413723f5aac5988eed977b278a7807Greg Clayton    if (name_type_mask & eFunctionNameTypeMethod)
1168296b06d325413723f5aac5988eed977b278a7807Greg Clayton    {
1169296b06d325413723f5aac5988eed977b278a7807Greg Clayton        if (!m_name_indexes_computed)
1170296b06d325413723f5aac5988eed977b278a7807Greg Clayton            InitNameIndexes();
1171296b06d325413723f5aac5988eed977b278a7807Greg Clayton
1172296b06d325413723f5aac5988eed977b278a7807Greg Clayton        if (!m_method_to_index.IsEmpty())
1173296b06d325413723f5aac5988eed977b278a7807Greg Clayton        {
1174296b06d325413723f5aac5988eed977b278a7807Greg Clayton            const UniqueCStringMap<uint32_t>::Entry *match;
1175296b06d325413723f5aac5988eed977b278a7807Greg Clayton            for (match = m_method_to_index.FindFirstValueForName(name_cstr);
1176296b06d325413723f5aac5988eed977b278a7807Greg Clayton                 match != NULL;
1177296b06d325413723f5aac5988eed977b278a7807Greg Clayton                 match = m_method_to_index.FindNextValueForName(match))
1178296b06d325413723f5aac5988eed977b278a7807Greg Clayton            {
1179296b06d325413723f5aac5988eed977b278a7807Greg Clayton                symbol_indexes.push_back(match->value);
1180296b06d325413723f5aac5988eed977b278a7807Greg Clayton            }
1181296b06d325413723f5aac5988eed977b278a7807Greg Clayton        }
1182296b06d325413723f5aac5988eed977b278a7807Greg Clayton    }
1183296b06d325413723f5aac5988eed977b278a7807Greg Clayton
11842fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton    if (name_type_mask & eFunctionNameTypeSelector)
11852fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton    {
11862fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton        if (!m_name_indexes_computed)
11872fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton            InitNameIndexes();
11882fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton
11892fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton        if (!m_selector_to_index.IsEmpty())
11902fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton        {
11912fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton            const UniqueCStringMap<uint32_t>::Entry *match;
1192296b06d325413723f5aac5988eed977b278a7807Greg Clayton            for (match = m_selector_to_index.FindFirstValueForName(name_cstr);
11932fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton                 match != NULL;
11942fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton                 match = m_selector_to_index.FindNextValueForName(match))
11952fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton            {
11962fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton                symbol_indexes.push_back(match->value);
11972fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton            }
11982fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton        }
11992fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton    }
12002fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton
12012fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton    if (!symbol_indexes.empty())
12022fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton    {
12032fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton        std::sort(symbol_indexes.begin(), symbol_indexes.end());
12042fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton        symbol_indexes.erase(std::unique(symbol_indexes.begin(), symbol_indexes.end()), symbol_indexes.end());
12052fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton        count = symbol_indexes.size();
12062fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton        SymbolIndicesToSymbolContextList (symbol_indexes, sc_list);
12072fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton    }
12082fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton
12092fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton    return count;
12102fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton}
12112fcbf6e3d86ac0e6a95e11e5e232a9f72bd612d2Greg Clayton
1212