Home | History | Annotate | Download | only in DWARF
      1 //===-- SymbolFileDWARFDebugMap.cpp ----------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "SymbolFileDWARFDebugMap.h"
     11 
     12 #include "DWARFDebugAranges.h"
     13 
     14 #include "lldb/Core/RangeMap.h"
     15 #include "lldb/Core/Module.h"
     16 #include "lldb/Core/ModuleList.h"
     17 #include "lldb/Core/PluginManager.h"
     18 #include "lldb/Core/RegularExpression.h"
     19 #include "lldb/Core/Section.h"
     20 
     21 //#define DEBUG_OSO_DMAP // DO NOT CHECKIN WITH THIS NOT COMMENTED OUT
     22 #if defined(DEBUG_OSO_DMAP)
     23 #include "lldb/Core/StreamFile.h"
     24 #endif
     25 #include "lldb/Core/Timer.h"
     26 
     27 #include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
     28 #include "lldb/Symbol/CompileUnit.h"
     29 #include "lldb/Symbol/LineTable.h"
     30 #include "lldb/Symbol/ObjectFile.h"
     31 #include "lldb/Symbol/SymbolVendor.h"
     32 #include "lldb/Symbol/VariableList.h"
     33 
     34 #include "LogChannelDWARF.h"
     35 #include "SymbolFileDWARF.h"
     36 
     37 using namespace lldb;
     38 using namespace lldb_private;
     39 
     40 // Subclass lldb_private::Module so we can intercept the "Module::GetObjectFile()"
     41 // (so we can fixup the object file sections) and also for "Module::GetSymbolVendor()"
     42 // (so we can fixup the symbol file id.
     43 
     44 
     45 
     46 
     47 const SymbolFileDWARFDebugMap::FileRangeMap &
     48 SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile)
     49 {
     50     if (file_range_map_valid)
     51         return file_range_map;
     52 
     53     file_range_map_valid = true;
     54 
     55     Module *oso_module = exe_symfile->GetModuleByCompUnitInfo (this);
     56     if (!oso_module)
     57         return file_range_map;
     58 
     59     ObjectFile *oso_objfile = oso_module->GetObjectFile();
     60     if (!oso_objfile)
     61         return file_range_map;
     62 
     63     Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
     64     if (log)
     65     {
     66         ConstString object_name (oso_module->GetObjectName());
     67         log->Printf("%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s')",
     68                     this,
     69                     oso_module->GetSpecificationDescription().c_str());
     70     }
     71 
     72 
     73     std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos;
     74     if (exe_symfile->GetCompUnitInfosForModule(oso_module, cu_infos))
     75     {
     76         for (auto comp_unit_info : cu_infos)
     77         {
     78             Symtab *exe_symtab = exe_symfile->GetObjectFile()->GetSymtab();
     79             ModuleSP oso_module_sp (oso_objfile->GetModule());
     80             Symtab *oso_symtab = oso_objfile->GetSymtab();
     81 
     82             ///const uint32_t fun_resolve_flags = SymbolContext::Module | eSymbolContextCompUnit | eSymbolContextFunction;
     83             //SectionList *oso_sections = oso_objfile->Sections();
     84             // Now we need to make sections that map from zero based object
     85             // file addresses to where things eneded up in the main executable.
     86 
     87             assert (comp_unit_info->first_symbol_index != UINT32_MAX);
     88             // End index is one past the last valid symbol index
     89             const uint32_t oso_end_idx = comp_unit_info->last_symbol_index + 1;
     90             for (uint32_t idx = comp_unit_info->first_symbol_index + 2; // Skip the N_SO and N_OSO
     91                  idx < oso_end_idx;
     92                  ++idx)
     93             {
     94                 Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx);
     95                 if (exe_symbol)
     96                 {
     97                     if (exe_symbol->IsDebug() == false)
     98                         continue;
     99 
    100                     switch (exe_symbol->GetType())
    101                     {
    102                     default:
    103                         break;
    104 
    105                     case eSymbolTypeCode:
    106                         {
    107                             // For each N_FUN, or function that we run into in the debug map
    108                             // we make a new section that we add to the sections found in the
    109                             // .o file. This new section has the file address set to what the
    110                             // addresses are in the .o file, and the load address is adjusted
    111                             // to match where it ended up in the final executable! We do this
    112                             // before we parse any dwarf info so that when it goes get parsed
    113                             // all section/offset addresses that get registered will resolve
    114                             // correctly to the new addresses in the main executable.
    115 
    116                             // First we find the original symbol in the .o file's symbol table
    117                             Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(Mangled::ePreferMangled),
    118                                                                                                  eSymbolTypeCode,
    119                                                                                                  Symtab::eDebugNo,
    120                                                                                                  Symtab::eVisibilityAny);
    121                             if (oso_fun_symbol)
    122                             {
    123                                 // Add the inverse OSO file address to debug map entry mapping
    124                                 exe_symfile->AddOSOFileRange (this,
    125                                                               exe_symbol->GetAddress().GetFileAddress(),
    126                                                               oso_fun_symbol->GetAddress().GetFileAddress(),
    127                                                               std::min<addr_t>(exe_symbol->GetByteSize(), oso_fun_symbol->GetByteSize()));
    128 
    129                             }
    130                         }
    131                         break;
    132 
    133                     case eSymbolTypeData:
    134                         {
    135                             // For each N_GSYM we remap the address for the global by making
    136                             // a new section that we add to the sections found in the .o file.
    137                             // This new section has the file address set to what the
    138                             // addresses are in the .o file, and the load address is adjusted
    139                             // to match where it ended up in the final executable! We do this
    140                             // before we parse any dwarf info so that when it goes get parsed
    141                             // all section/offset addresses that get registered will resolve
    142                             // correctly to the new addresses in the main executable. We
    143                             // initially set the section size to be 1 byte, but will need to
    144                             // fix up these addresses further after all globals have been
    145                             // parsed to span the gaps, or we can find the global variable
    146                             // sizes from the DWARF info as we are parsing.
    147 
    148                             // Next we find the non-stab entry that corresponds to the N_GSYM in the .o file
    149                             Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(Mangled::ePreferMangled),
    150                                                                                                   eSymbolTypeData,
    151                                                                                                   Symtab::eDebugNo,
    152                                                                                                   Symtab::eVisibilityAny);
    153 
    154                             if (exe_symbol && oso_gsym_symbol &&
    155                                 exe_symbol->ValueIsAddress() &&
    156                                 oso_gsym_symbol->ValueIsAddress())
    157                             {
    158                                 // Add the inverse OSO file address to debug map entry mapping
    159                                 exe_symfile->AddOSOFileRange (this,
    160                                                               exe_symbol->GetAddress().GetFileAddress(),
    161                                                               oso_gsym_symbol->GetAddress().GetFileAddress(),
    162                                                               std::min<addr_t>(exe_symbol->GetByteSize(), oso_gsym_symbol->GetByteSize()));
    163                             }
    164                         }
    165                         break;
    166                     }
    167                 }
    168             }
    169 
    170             exe_symfile->FinalizeOSOFileRanges (this);
    171             // We don't need the symbols anymore for the .o files
    172             oso_objfile->ClearSymtab();
    173         }
    174     }
    175     return file_range_map;
    176 }
    177 
    178 
    179 class DebugMapModule : public Module
    180 {
    181 public:
    182     DebugMapModule (const ModuleSP &exe_module_sp,
    183                     uint32_t cu_idx,
    184                     const FileSpec& file_spec,
    185                     const ArchSpec& arch,
    186                     const ConstString *object_name,
    187                     off_t object_offset,
    188                     const TimeValue *object_mod_time_ptr) :
    189         Module (file_spec, arch, object_name, object_offset, object_mod_time_ptr),
    190         m_exe_module_wp (exe_module_sp),
    191         m_cu_idx (cu_idx)
    192     {
    193     }
    194 
    195     virtual
    196     ~DebugMapModule ()
    197     {
    198     }
    199 
    200 
    201     virtual SymbolVendor*
    202     GetSymbolVendor(bool can_create = true, lldb_private::Stream *feedback_strm = NULL)
    203     {
    204         // Scope for locker
    205         if (m_symfile_ap.get() || can_create == false)
    206             return m_symfile_ap.get();
    207 
    208         ModuleSP exe_module_sp (m_exe_module_wp.lock());
    209         if (exe_module_sp)
    210         {
    211             // Now get the object file outside of a locking scope
    212             ObjectFile *oso_objfile = GetObjectFile ();
    213             if (oso_objfile)
    214             {
    215                 Mutex::Locker locker (m_mutex);
    216                 SymbolVendor* symbol_vendor = Module::GetSymbolVendor(can_create, feedback_strm);
    217                 if (symbol_vendor)
    218                 {
    219                     // Set a a pointer to this class to set our OSO DWARF file know
    220                     // that the DWARF is being used along with a debug map and that
    221                     // it will have the remapped sections that we do below.
    222                     SymbolFileDWARF *oso_symfile = SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(symbol_vendor->GetSymbolFile());
    223 
    224                     if (!oso_symfile)
    225                         return NULL;
    226 
    227                     ObjectFile *exe_objfile = exe_module_sp->GetObjectFile();
    228                     SymbolVendor *exe_sym_vendor = exe_module_sp->GetSymbolVendor();
    229 
    230                     if (exe_objfile && exe_sym_vendor)
    231                     {
    232                         if (oso_symfile->GetNumCompileUnits() == 1)
    233                         {
    234                             oso_symfile->SetDebugMapModule(exe_module_sp);
    235                             // Set the ID of the symbol file DWARF to the index of the OSO
    236                             // shifted left by 32 bits to provide a unique prefix for any
    237                             // UserID's that get created in the symbol file.
    238                             oso_symfile->SetID (((uint64_t)m_cu_idx + 1ull) << 32ull);
    239                         }
    240                         else
    241                         {
    242                             oso_symfile->SetID (UINT64_MAX);
    243                         }
    244                     }
    245                     return symbol_vendor;
    246                 }
    247             }
    248         }
    249         return NULL;
    250     }
    251 
    252 protected:
    253     ModuleWP m_exe_module_wp;
    254     const uint32_t m_cu_idx;
    255 };
    256 
    257 void
    258 SymbolFileDWARFDebugMap::Initialize()
    259 {
    260     PluginManager::RegisterPlugin (GetPluginNameStatic(),
    261                                    GetPluginDescriptionStatic(),
    262                                    CreateInstance);
    263 }
    264 
    265 void
    266 SymbolFileDWARFDebugMap::Terminate()
    267 {
    268     PluginManager::UnregisterPlugin (CreateInstance);
    269 }
    270 
    271 
    272 lldb_private::ConstString
    273 SymbolFileDWARFDebugMap::GetPluginNameStatic()
    274 {
    275     static ConstString g_name("dwarf-debugmap");
    276     return g_name;
    277 }
    278 
    279 const char *
    280 SymbolFileDWARFDebugMap::GetPluginDescriptionStatic()
    281 {
    282     return "DWARF and DWARF3 debug symbol file reader (debug map).";
    283 }
    284 
    285 SymbolFile*
    286 SymbolFileDWARFDebugMap::CreateInstance (ObjectFile* obj_file)
    287 {
    288     return new SymbolFileDWARFDebugMap (obj_file);
    289 }
    290 
    291 
    292 SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap (ObjectFile* ofile) :
    293     SymbolFile(ofile),
    294     m_flags(),
    295     m_compile_unit_infos(),
    296     m_func_indexes(),
    297     m_glob_indexes(),
    298     m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate)
    299 {
    300 }
    301 
    302 
    303 SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap()
    304 {
    305 }
    306 
    307 void
    308 SymbolFileDWARFDebugMap::InitializeObject()
    309 {
    310     // Install our external AST source callbacks so we can complete Clang types.
    311     llvm::OwningPtr<clang::ExternalASTSource> ast_source_ap (
    312         new ClangExternalASTSourceCallbacks (SymbolFileDWARFDebugMap::CompleteTagDecl,
    313                                              SymbolFileDWARFDebugMap::CompleteObjCInterfaceDecl,
    314                                              NULL,
    315                                              SymbolFileDWARFDebugMap::LayoutRecordType,
    316                                              this));
    317 
    318     GetClangASTContext().SetExternalSource (ast_source_ap);
    319 }
    320 
    321 void
    322 SymbolFileDWARFDebugMap::InitOSO()
    323 {
    324     if (m_flags.test(kHaveInitializedOSOs))
    325         return;
    326 
    327     m_flags.set(kHaveInitializedOSOs);
    328 
    329     // If the object file has been stripped, there is no sense in looking further
    330     // as all of the debug symbols for the debug map will not be available
    331     if (m_obj_file->IsStripped())
    332         return;
    333 
    334     // Also make sure the file type is some sort of executable. Core files, debug
    335     // info files (dSYM), object files (.o files), and stub libraries all can
    336     switch (m_obj_file->GetType())
    337     {
    338         case ObjectFile::eTypeInvalid:
    339         case ObjectFile::eTypeCoreFile:
    340         case ObjectFile::eTypeDebugInfo:
    341         case ObjectFile::eTypeObjectFile:
    342         case ObjectFile::eTypeStubLibrary:
    343         case ObjectFile::eTypeUnknown:
    344             return;
    345 
    346         case ObjectFile::eTypeExecutable:
    347         case ObjectFile::eTypeDynamicLinker:
    348         case ObjectFile::eTypeSharedLibrary:
    349             break;
    350     }
    351 
    352     // In order to get the abilities of this plug-in, we look at the list of
    353     // N_OSO entries (object files) from the symbol table and make sure that
    354     // these files exist and also contain valid DWARF. If we get any of that
    355     // then we return the abilities of the first N_OSO's DWARF.
    356 
    357     Symtab* symtab = m_obj_file->GetSymtab();
    358     if (symtab)
    359     {
    360         Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
    361 
    362         std::vector<uint32_t> oso_indexes;
    363         // When a mach-o symbol is encoded, the n_type field is encoded in bits
    364         // 23:16, and the n_desc field is encoded in bits 15:0.
    365         //
    366         // To find all N_OSO entries that are part of the DWARF + debug map
    367         // we find only object file symbols with the flags value as follows:
    368         // bits 23:16 == 0x66 (N_OSO)
    369         // bits 15: 0 == 0x0001 (specifies this is a debug map object file)
    370         const uint32_t k_oso_symbol_flags_value = 0x660001u;
    371 
    372         const uint32_t oso_index_count = symtab->AppendSymbolIndexesWithTypeAndFlagsValue(eSymbolTypeObjectFile, k_oso_symbol_flags_value, oso_indexes);
    373 
    374         if (oso_index_count > 0)
    375         {
    376             symtab->AppendSymbolIndexesWithType (eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, m_func_indexes);
    377             symtab->AppendSymbolIndexesWithType (eSymbolTypeData, Symtab::eDebugYes, Symtab::eVisibilityAny, m_glob_indexes);
    378 
    379             symtab->SortSymbolIndexesByValue(m_func_indexes, true);
    380             symtab->SortSymbolIndexesByValue(m_glob_indexes, true);
    381 
    382             for (uint32_t sym_idx : m_func_indexes)
    383             {
    384                 const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
    385                 lldb::addr_t file_addr = symbol->GetAddress().GetFileAddress();
    386                 lldb::addr_t byte_size = symbol->GetByteSize();
    387                 DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
    388                 m_debug_map.Append(debug_map_entry);
    389             }
    390             for (uint32_t sym_idx : m_glob_indexes)
    391             {
    392                 const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
    393                 lldb::addr_t file_addr = symbol->GetAddress().GetFileAddress();
    394                 lldb::addr_t byte_size = symbol->GetByteSize();
    395                 DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
    396                 m_debug_map.Append(debug_map_entry);
    397             }
    398             m_debug_map.Sort();
    399 
    400             m_compile_unit_infos.resize(oso_index_count);
    401 
    402             for (uint32_t i=0; i<oso_index_count; ++i)
    403             {
    404                 const uint32_t so_idx = oso_indexes[i] - 1;
    405                 const uint32_t oso_idx = oso_indexes[i];
    406                 const Symbol *so_symbol = symtab->SymbolAtIndex(so_idx);
    407                 const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_idx);
    408                 if (so_symbol &&
    409                     oso_symbol &&
    410                     so_symbol->GetType() == eSymbolTypeSourceFile &&
    411                     oso_symbol->GetType() == eSymbolTypeObjectFile)
    412                 {
    413                     m_compile_unit_infos[i].so_file.SetFile(so_symbol->GetName().AsCString(), false);
    414                     m_compile_unit_infos[i].oso_path = oso_symbol->GetName();
    415                     TimeValue oso_mod_time;
    416                     oso_mod_time.OffsetWithSeconds(oso_symbol->GetAddress().GetOffset());
    417                     m_compile_unit_infos[i].oso_mod_time = oso_mod_time;
    418                     uint32_t sibling_idx = so_symbol->GetSiblingIndex();
    419                     // The sibling index can't be less that or equal to the current index "i"
    420                     if (sibling_idx <= i)
    421                     {
    422                         m_obj_file->GetModule()->ReportError ("N_SO in symbol with UID %u has invalid sibling in debug map, please file a bug and attach the binary listed in this error", so_symbol->GetID());
    423                     }
    424                     else
    425                     {
    426                         const Symbol* last_symbol = symtab->SymbolAtIndex (sibling_idx - 1);
    427                         m_compile_unit_infos[i].first_symbol_index = so_idx;
    428                         m_compile_unit_infos[i].last_symbol_index = sibling_idx - 1;
    429                         m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID();
    430                         m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID();
    431 
    432                         if (log)
    433                             log->Printf("Initialized OSO 0x%8.8x: file=%s", i, oso_symbol->GetName().GetCString());
    434                     }
    435                 }
    436                 else
    437                 {
    438                     if (oso_symbol == NULL)
    439                         m_obj_file->GetModule()->ReportError ("N_OSO symbol[%u] can't be found, please file a bug and attach the binary listed in this error", oso_idx);
    440                     else if (so_symbol == NULL)
    441                         m_obj_file->GetModule()->ReportError ("N_SO not found for N_OSO symbol[%u], please file a bug and attach the binary listed in this error", oso_idx);
    442                     else if (so_symbol->GetType() != eSymbolTypeSourceFile)
    443                         m_obj_file->GetModule()->ReportError ("N_SO has incorrect symbol type (%u) for N_OSO symbol[%u], please file a bug and attach the binary listed in this error", so_symbol->GetType(), oso_idx);
    444                     else if (oso_symbol->GetType() != eSymbolTypeSourceFile)
    445                         m_obj_file->GetModule()->ReportError ("N_OSO has incorrect symbol type (%u) for N_OSO symbol[%u], please file a bug and attach the binary listed in this error", oso_symbol->GetType(), oso_idx);
    446                 }
    447             }
    448         }
    449     }
    450 }
    451 
    452 Module *
    453 SymbolFileDWARFDebugMap::GetModuleByOSOIndex (uint32_t oso_idx)
    454 {
    455     const uint32_t cu_count = GetNumCompileUnits();
    456     if (oso_idx < cu_count)
    457         return GetModuleByCompUnitInfo (&m_compile_unit_infos[oso_idx]);
    458     return NULL;
    459 }
    460 
    461 Module *
    462 SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo (CompileUnitInfo *comp_unit_info)
    463 {
    464     if (!comp_unit_info->oso_sp)
    465     {
    466         auto pos = m_oso_map.find (comp_unit_info->oso_path);
    467         if (pos != m_oso_map.end())
    468         {
    469             comp_unit_info->oso_sp = pos->second;
    470         }
    471         else
    472         {
    473             ObjectFile *obj_file = GetObjectFile();
    474             comp_unit_info->oso_sp.reset (new OSOInfo());
    475             m_oso_map[comp_unit_info->oso_path] = comp_unit_info->oso_sp;
    476             const char *oso_path = comp_unit_info->oso_path.GetCString();
    477             FileSpec oso_file (oso_path, false);
    478             ConstString oso_object;
    479             if (oso_file.Exists())
    480             {
    481                 TimeValue oso_mod_time (oso_file.GetModificationTime());
    482                 if (oso_mod_time != comp_unit_info->oso_mod_time)
    483                 {
    484                     obj_file->GetModule()->ReportError ("debug map object file '%s' has changed (actual time is 0x%" PRIx64 ", debug map time is 0x%" PRIx64 ") since this executable was linked, file will be ignored",
    485                                                         oso_file.GetPath().c_str(),
    486                                                         oso_mod_time.GetAsSecondsSinceJan1_1970(),
    487                                                         comp_unit_info->oso_mod_time.GetAsSecondsSinceJan1_1970());
    488                     return NULL;
    489                 }
    490 
    491             }
    492             else
    493             {
    494                 const bool must_exist = true;
    495 
    496                 if (!ObjectFile::SplitArchivePathWithObject (oso_path,
    497                                                              oso_file,
    498                                                              oso_object,
    499                                                              must_exist))
    500                 {
    501                     return NULL;
    502                 }
    503             }
    504             // Always create a new module for .o files. Why? Because we
    505             // use the debug map, to add new sections to each .o file and
    506             // even though a .o file might not have changed, the sections
    507             // that get added to the .o file can change.
    508             comp_unit_info->oso_sp->module_sp.reset (new DebugMapModule (obj_file->GetModule(),
    509                                                                          GetCompUnitInfoIndex(comp_unit_info),
    510                                                                          oso_file,
    511                                                                          m_obj_file->GetModule()->GetArchitecture(),
    512                                                                          oso_object ? &oso_object : NULL,
    513                                                                          0,
    514                                                                          oso_object ? &comp_unit_info->oso_mod_time : NULL));
    515         }
    516     }
    517     if (comp_unit_info->oso_sp)
    518         return comp_unit_info->oso_sp->module_sp.get();
    519     return NULL;
    520 }
    521 
    522 
    523 bool
    524 SymbolFileDWARFDebugMap::GetFileSpecForSO (uint32_t oso_idx, FileSpec &file_spec)
    525 {
    526     if (oso_idx < m_compile_unit_infos.size())
    527     {
    528         if (m_compile_unit_infos[oso_idx].so_file)
    529         {
    530             file_spec = m_compile_unit_infos[oso_idx].so_file;
    531             return true;
    532         }
    533     }
    534     return false;
    535 }
    536 
    537 
    538 
    539 ObjectFile *
    540 SymbolFileDWARFDebugMap::GetObjectFileByOSOIndex (uint32_t oso_idx)
    541 {
    542     Module *oso_module = GetModuleByOSOIndex (oso_idx);
    543     if (oso_module)
    544         return oso_module->GetObjectFile();
    545     return NULL;
    546 }
    547 
    548 SymbolFileDWARF *
    549 SymbolFileDWARFDebugMap::GetSymbolFile (const SymbolContext& sc)
    550 {
    551     CompileUnitInfo *comp_unit_info = GetCompUnitInfo (sc);
    552     if (comp_unit_info)
    553         return GetSymbolFileByCompUnitInfo (comp_unit_info);
    554     return NULL;
    555 }
    556 
    557 ObjectFile *
    558 SymbolFileDWARFDebugMap::GetObjectFileByCompUnitInfo (CompileUnitInfo *comp_unit_info)
    559 {
    560     Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
    561     if (oso_module)
    562         return oso_module->GetObjectFile();
    563     return NULL;
    564 }
    565 
    566 
    567 uint32_t
    568 SymbolFileDWARFDebugMap::GetCompUnitInfoIndex (const CompileUnitInfo *comp_unit_info)
    569 {
    570     if (!m_compile_unit_infos.empty())
    571     {
    572         const CompileUnitInfo *first_comp_unit_info = &m_compile_unit_infos.front();
    573         const CompileUnitInfo *last_comp_unit_info = &m_compile_unit_infos.back();
    574         if (first_comp_unit_info <= comp_unit_info && comp_unit_info <= last_comp_unit_info)
    575             return comp_unit_info - first_comp_unit_info;
    576     }
    577     return UINT32_MAX;
    578 }
    579 
    580 SymbolFileDWARF *
    581 SymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex (uint32_t oso_idx)
    582 {
    583     if (oso_idx < m_compile_unit_infos.size())
    584         return GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[oso_idx]);
    585     return NULL;
    586 }
    587 
    588 SymbolFileDWARF *
    589 SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF (SymbolFile *sym_file)
    590 {
    591     if (sym_file && sym_file->GetPluginName() == SymbolFileDWARF::GetPluginNameStatic())
    592         return (SymbolFileDWARF *)sym_file;
    593     return NULL;
    594 }
    595 
    596 SymbolFileDWARF *
    597 SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo (CompileUnitInfo *comp_unit_info)
    598 {
    599     Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
    600     if (oso_module)
    601     {
    602         SymbolVendor *sym_vendor = oso_module->GetSymbolVendor();
    603         if (sym_vendor)
    604             return GetSymbolFileAsSymbolFileDWARF (sym_vendor->GetSymbolFile());
    605     }
    606     return NULL;
    607 }
    608 
    609 uint32_t
    610 SymbolFileDWARFDebugMap::CalculateAbilities ()
    611 {
    612     // In order to get the abilities of this plug-in, we look at the list of
    613     // N_OSO entries (object files) from the symbol table and make sure that
    614     // these files exist and also contain valid DWARF. If we get any of that
    615     // then we return the abilities of the first N_OSO's DWARF.
    616 
    617     const uint32_t oso_index_count = GetNumCompileUnits();
    618     if (oso_index_count > 0)
    619     {
    620         InitOSO();
    621         if (!m_compile_unit_infos.empty())
    622         {
    623             return SymbolFile::CompileUnits    |
    624                    SymbolFile::Functions       |
    625                    SymbolFile::Blocks          |
    626                    SymbolFile::GlobalVariables |
    627                    SymbolFile::LocalVariables  |
    628                    SymbolFile::VariableTypes   |
    629                    SymbolFile::LineTables      ;
    630         }
    631     }
    632     return 0;
    633 }
    634 
    635 uint32_t
    636 SymbolFileDWARFDebugMap::GetNumCompileUnits()
    637 {
    638     InitOSO ();
    639     return m_compile_unit_infos.size();
    640 }
    641 
    642 
    643 CompUnitSP
    644 SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx)
    645 {
    646     CompUnitSP comp_unit_sp;
    647     const uint32_t cu_count = GetNumCompileUnits();
    648 
    649     if (cu_idx < cu_count)
    650     {
    651         Module *oso_module = GetModuleByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
    652         if (oso_module)
    653         {
    654             FileSpec so_file_spec;
    655             if (GetFileSpecForSO (cu_idx, so_file_spec))
    656             {
    657                 // User zero as the ID to match the compile unit at offset
    658                 // zero in each .o file since each .o file can only have
    659                 // one compile unit for now.
    660                 lldb::user_id_t cu_id = 0;
    661                 m_compile_unit_infos[cu_idx].compile_unit_sp.reset(new CompileUnit (m_obj_file->GetModule(),
    662                                                                                     NULL,
    663                                                                                     so_file_spec,
    664                                                                                     cu_id,
    665                                                                                     eLanguageTypeUnknown));
    666 
    667                 if (m_compile_unit_infos[cu_idx].compile_unit_sp)
    668                 {
    669                     // Let our symbol vendor know about this compile unit
    670                     m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex (cu_idx, m_compile_unit_infos[cu_idx].compile_unit_sp);
    671                 }
    672             }
    673         }
    674         comp_unit_sp = m_compile_unit_infos[cu_idx].compile_unit_sp;
    675     }
    676 
    677     return comp_unit_sp;
    678 }
    679 
    680 SymbolFileDWARFDebugMap::CompileUnitInfo *
    681 SymbolFileDWARFDebugMap::GetCompUnitInfo (const SymbolContext& sc)
    682 {
    683     const uint32_t cu_count = GetNumCompileUnits();
    684     for (uint32_t i=0; i<cu_count; ++i)
    685     {
    686         if (sc.comp_unit == m_compile_unit_infos[i].compile_unit_sp.get())
    687             return &m_compile_unit_infos[i];
    688     }
    689     return NULL;
    690 }
    691 
    692 
    693 size_t
    694 SymbolFileDWARFDebugMap::GetCompUnitInfosForModule (const lldb_private::Module *module, std::vector<CompileUnitInfo *>& cu_infos)
    695 {
    696     const uint32_t cu_count = GetNumCompileUnits();
    697     for (uint32_t i=0; i<cu_count; ++i)
    698     {
    699         if (module == GetModuleByCompUnitInfo (&m_compile_unit_infos[i]))
    700             cu_infos.push_back (&m_compile_unit_infos[i]);
    701     }
    702     return cu_infos.size();
    703 }
    704 
    705 lldb::LanguageType
    706 SymbolFileDWARFDebugMap::ParseCompileUnitLanguage (const SymbolContext& sc)
    707 {
    708     SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
    709     if (oso_dwarf)
    710         return oso_dwarf->ParseCompileUnitLanguage (sc);
    711     return eLanguageTypeUnknown;
    712 }
    713 
    714 size_t
    715 SymbolFileDWARFDebugMap::ParseCompileUnitFunctions (const SymbolContext& sc)
    716 {
    717     SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
    718     if (oso_dwarf)
    719         return oso_dwarf->ParseCompileUnitFunctions (sc);
    720     return 0;
    721 }
    722 
    723 bool
    724 SymbolFileDWARFDebugMap::ParseCompileUnitLineTable (const SymbolContext& sc)
    725 {
    726     SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
    727     if (oso_dwarf)
    728         return oso_dwarf->ParseCompileUnitLineTable (sc);
    729     return false;
    730 }
    731 
    732 bool
    733 SymbolFileDWARFDebugMap::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files)
    734 {
    735     SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
    736     if (oso_dwarf)
    737         return oso_dwarf->ParseCompileUnitSupportFiles (sc, support_files);
    738     return false;
    739 }
    740 
    741 
    742 size_t
    743 SymbolFileDWARFDebugMap::ParseFunctionBlocks (const SymbolContext& sc)
    744 {
    745     SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
    746     if (oso_dwarf)
    747         return oso_dwarf->ParseFunctionBlocks (sc);
    748     return 0;
    749 }
    750 
    751 
    752 size_t
    753 SymbolFileDWARFDebugMap::ParseTypes (const SymbolContext& sc)
    754 {
    755     SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
    756     if (oso_dwarf)
    757         return oso_dwarf->ParseTypes (sc);
    758     return 0;
    759 }
    760 
    761 
    762 size_t
    763 SymbolFileDWARFDebugMap::ParseVariablesForContext (const SymbolContext& sc)
    764 {
    765     SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
    766     if (oso_dwarf)
    767         return oso_dwarf->ParseVariablesForContext (sc);
    768     return 0;
    769 }
    770 
    771 
    772 
    773 Type*
    774 SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid)
    775 {
    776     const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
    777     SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
    778     if (oso_dwarf)
    779         return oso_dwarf->ResolveTypeUID (type_uid);
    780     return NULL;
    781 }
    782 
    783 bool
    784 SymbolFileDWARFDebugMap::ResolveClangOpaqueTypeDefinition (ClangASTType& clang_type)
    785 {
    786     // We have a struct/union/class/enum that needs to be fully resolved.
    787     return false;
    788 }
    789 
    790 uint32_t
    791 SymbolFileDWARFDebugMap::ResolveSymbolContext (const Address& exe_so_addr, uint32_t resolve_scope, SymbolContext& sc)
    792 {
    793     uint32_t resolved_flags = 0;
    794     Symtab* symtab = m_obj_file->GetSymtab();
    795     if (symtab)
    796     {
    797         const addr_t exe_file_addr = exe_so_addr.GetFileAddress();
    798 
    799         const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains (exe_file_addr);
    800         if (debug_map_entry)
    801         {
    802 
    803             sc.symbol = symtab->SymbolAtIndex(debug_map_entry->data.GetExeSymbolIndex());
    804 
    805             if (sc.symbol != NULL)
    806             {
    807                 resolved_flags |= eSymbolContextSymbol;
    808 
    809                 uint32_t oso_idx = 0;
    810                 CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithID (sc.symbol->GetID(), &oso_idx);
    811                 if (comp_unit_info)
    812                 {
    813                     comp_unit_info->GetFileRangeMap(this);
    814                     Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
    815                     if (oso_module)
    816                     {
    817                         lldb::addr_t oso_file_addr = exe_file_addr - debug_map_entry->GetRangeBase() + debug_map_entry->data.GetOSOFileAddress();
    818                         Address oso_so_addr;
    819                         if (oso_module->ResolveFileAddress(oso_file_addr, oso_so_addr))
    820                         {
    821                             resolved_flags |= oso_module->GetSymbolVendor()->ResolveSymbolContext (oso_so_addr, resolve_scope, sc);
    822                         }
    823                     }
    824                 }
    825             }
    826         }
    827     }
    828     return resolved_flags;
    829 }
    830 
    831 
    832 uint32_t
    833 SymbolFileDWARFDebugMap::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
    834 {
    835     const uint32_t initial = sc_list.GetSize();
    836     const uint32_t cu_count = GetNumCompileUnits();
    837 
    838     for (uint32_t i=0; i<cu_count; ++i)
    839     {
    840         // If we are checking for inlines, then we need to look through all
    841         // compile units no matter if "file_spec" matches.
    842         bool resolve = check_inlines;
    843 
    844         if (!resolve)
    845         {
    846             FileSpec so_file_spec;
    847             if (GetFileSpecForSO (i, so_file_spec))
    848             {
    849                 // Match the full path if the incoming file_spec has a directory (not just a basename)
    850                 const bool full_match = file_spec.GetDirectory();
    851                 resolve = FileSpec::Equal (file_spec, so_file_spec, full_match);
    852             }
    853         }
    854         if (resolve)
    855         {
    856             SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (i);
    857             if (oso_dwarf)
    858                 oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope, sc_list);
    859         }
    860     }
    861     return sc_list.GetSize() - initial;
    862 }
    863 
    864 uint32_t
    865 SymbolFileDWARFDebugMap::PrivateFindGlobalVariables
    866 (
    867     const ConstString &name,
    868     const ClangNamespaceDecl *namespace_decl,
    869     const std::vector<uint32_t> &indexes,   // Indexes into the symbol table that match "name"
    870     uint32_t max_matches,
    871     VariableList& variables
    872 )
    873 {
    874     const uint32_t original_size = variables.GetSize();
    875     const size_t match_count = indexes.size();
    876     for (size_t i=0; i<match_count; ++i)
    877     {
    878         uint32_t oso_idx;
    879         CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithIndex (indexes[i], &oso_idx);
    880         if (comp_unit_info)
    881         {
    882             SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
    883             if (oso_dwarf)
    884             {
    885                 if (oso_dwarf->FindGlobalVariables(name, namespace_decl, true, max_matches, variables))
    886                     if (variables.GetSize() > max_matches)
    887                         break;
    888             }
    889         }
    890     }
    891     return variables.GetSize() - original_size;
    892 }
    893 
    894 uint32_t
    895 SymbolFileDWARFDebugMap::FindGlobalVariables (const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables)
    896 {
    897 
    898     // If we aren't appending the results to this list, then clear the list
    899     if (!append)
    900         variables.Clear();
    901 
    902     // Remember how many variables are in the list before we search in case
    903     // we are appending the results to a variable list.
    904     const uint32_t original_size = variables.GetSize();
    905 
    906     uint32_t total_matches = 0;
    907     SymbolFileDWARF *oso_dwarf;
    908     for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
    909     {
    910         const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (name,
    911                                                                      namespace_decl,
    912                                                                      true,
    913                                                                      max_matches,
    914                                                                      variables);
    915         if (oso_matches > 0)
    916         {
    917             total_matches += oso_matches;
    918 
    919             // Are we getting all matches?
    920             if (max_matches == UINT32_MAX)
    921                 continue;   // Yep, continue getting everything
    922 
    923             // If we have found enough matches, lets get out
    924             if (max_matches >= total_matches)
    925                 break;
    926 
    927             // Update the max matches for any subsequent calls to find globals
    928             // in any other object files with DWARF
    929             max_matches -= oso_matches;
    930         }
    931     }
    932     // Return the number of variable that were appended to the list
    933     return variables.GetSize() - original_size;
    934 }
    935 
    936 
    937 uint32_t
    938 SymbolFileDWARFDebugMap::FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
    939 {
    940     // If we aren't appending the results to this list, then clear the list
    941     if (!append)
    942         variables.Clear();
    943 
    944     // Remember how many variables are in the list before we search in case
    945     // we are appending the results to a variable list.
    946     const uint32_t original_size = variables.GetSize();
    947 
    948     uint32_t total_matches = 0;
    949     SymbolFileDWARF *oso_dwarf;
    950     for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
    951     {
    952         const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (regex,
    953                                                                      true,
    954                                                                      max_matches,
    955                                                                      variables);
    956         if (oso_matches > 0)
    957         {
    958             total_matches += oso_matches;
    959 
    960             // Are we getting all matches?
    961             if (max_matches == UINT32_MAX)
    962                 continue;   // Yep, continue getting everything
    963 
    964             // If we have found enough matches, lets get out
    965             if (max_matches >= total_matches)
    966                 break;
    967 
    968             // Update the max matches for any subsequent calls to find globals
    969             // in any other object files with DWARF
    970             max_matches -= oso_matches;
    971         }
    972     }
    973     // Return the number of variable that were appended to the list
    974     return variables.GetSize() - original_size;
    975 }
    976 
    977 
    978 int
    979 SymbolFileDWARFDebugMap::SymbolContainsSymbolWithIndex (uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info)
    980 {
    981     const uint32_t symbol_idx = *symbol_idx_ptr;
    982 
    983     if (symbol_idx < comp_unit_info->first_symbol_index)
    984         return -1;
    985 
    986     if (symbol_idx <= comp_unit_info->last_symbol_index)
    987         return 0;
    988 
    989     return 1;
    990 }
    991 
    992 
    993 int
    994 SymbolFileDWARFDebugMap::SymbolContainsSymbolWithID (user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info)
    995 {
    996     const user_id_t symbol_id = *symbol_idx_ptr;
    997 
    998     if (symbol_id < comp_unit_info->first_symbol_id)
    999         return -1;
   1000 
   1001     if (symbol_id <= comp_unit_info->last_symbol_id)
   1002         return 0;
   1003 
   1004     return 1;
   1005 }
   1006 
   1007 
   1008 SymbolFileDWARFDebugMap::CompileUnitInfo*
   1009 SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithIndex (uint32_t symbol_idx, uint32_t *oso_idx_ptr)
   1010 {
   1011     const uint32_t oso_index_count = m_compile_unit_infos.size();
   1012     CompileUnitInfo *comp_unit_info = NULL;
   1013     if (oso_index_count)
   1014     {
   1015         comp_unit_info = (CompileUnitInfo*)bsearch(&symbol_idx,
   1016                                                    &m_compile_unit_infos[0],
   1017                                                    m_compile_unit_infos.size(),
   1018                                                    sizeof(CompileUnitInfo),
   1019                                                    (ComparisonFunction)SymbolContainsSymbolWithIndex);
   1020     }
   1021 
   1022     if (oso_idx_ptr)
   1023     {
   1024         if (comp_unit_info != NULL)
   1025             *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
   1026         else
   1027             *oso_idx_ptr = UINT32_MAX;
   1028     }
   1029     return comp_unit_info;
   1030 }
   1031 
   1032 SymbolFileDWARFDebugMap::CompileUnitInfo*
   1033 SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithID (user_id_t symbol_id, uint32_t *oso_idx_ptr)
   1034 {
   1035     const uint32_t oso_index_count = m_compile_unit_infos.size();
   1036     CompileUnitInfo *comp_unit_info = NULL;
   1037     if (oso_index_count)
   1038     {
   1039         comp_unit_info = (CompileUnitInfo*)::bsearch (&symbol_id,
   1040                                                       &m_compile_unit_infos[0],
   1041                                                       m_compile_unit_infos.size(),
   1042                                                       sizeof(CompileUnitInfo),
   1043                                                       (ComparisonFunction)SymbolContainsSymbolWithID);
   1044     }
   1045 
   1046     if (oso_idx_ptr)
   1047     {
   1048         if (comp_unit_info != NULL)
   1049             *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
   1050         else
   1051             *oso_idx_ptr = UINT32_MAX;
   1052     }
   1053     return comp_unit_info;
   1054 }
   1055 
   1056 
   1057 static void
   1058 RemoveFunctionsWithModuleNotEqualTo (const ModuleSP &module_sp, SymbolContextList &sc_list, uint32_t start_idx)
   1059 {
   1060     // We found functions in .o files. Not all functions in the .o files
   1061     // will have made it into the final output file. The ones that did
   1062     // make it into the final output file will have a section whose module
   1063     // matches the module from the ObjectFile for this SymbolFile. When
   1064     // the modules don't match, then we have something that was in a
   1065     // .o file, but doesn't map to anything in the final executable.
   1066     uint32_t i=start_idx;
   1067     while (i < sc_list.GetSize())
   1068     {
   1069         SymbolContext sc;
   1070         sc_list.GetContextAtIndex(i, sc);
   1071         if (sc.function)
   1072         {
   1073             const SectionSP section_sp (sc.function->GetAddressRange().GetBaseAddress().GetSection());
   1074             if (section_sp->GetModule() != module_sp)
   1075             {
   1076                 sc_list.RemoveContextAtIndex(i);
   1077                 continue;
   1078             }
   1079         }
   1080         ++i;
   1081     }
   1082 }
   1083 
   1084 uint32_t
   1085 SymbolFileDWARFDebugMap::FindFunctions(const ConstString &name, const ClangNamespaceDecl *namespace_decl, uint32_t name_type_mask, bool include_inlines, bool append, SymbolContextList& sc_list)
   1086 {
   1087     Timer scoped_timer (__PRETTY_FUNCTION__,
   1088                         "SymbolFileDWARFDebugMap::FindFunctions (name = %s)",
   1089                         name.GetCString());
   1090 
   1091     uint32_t initial_size = 0;
   1092     if (append)
   1093         initial_size = sc_list.GetSize();
   1094     else
   1095         sc_list.Clear();
   1096 
   1097     uint32_t oso_idx = 0;
   1098     SymbolFileDWARF *oso_dwarf;
   1099     while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL)
   1100     {
   1101         uint32_t sc_idx = sc_list.GetSize();
   1102         if (oso_dwarf->FindFunctions(name, namespace_decl, name_type_mask, include_inlines, true, sc_list))
   1103         {
   1104             RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx);
   1105         }
   1106     }
   1107 
   1108     return sc_list.GetSize() - initial_size;
   1109 }
   1110 
   1111 
   1112 uint32_t
   1113 SymbolFileDWARFDebugMap::FindFunctions (const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list)
   1114 {
   1115     Timer scoped_timer (__PRETTY_FUNCTION__,
   1116                         "SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')",
   1117                         regex.GetText());
   1118 
   1119     uint32_t initial_size = 0;
   1120     if (append)
   1121         initial_size = sc_list.GetSize();
   1122     else
   1123         sc_list.Clear();
   1124 
   1125     uint32_t oso_idx = 0;
   1126     SymbolFileDWARF *oso_dwarf;
   1127     while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL)
   1128     {
   1129         uint32_t sc_idx = sc_list.GetSize();
   1130 
   1131         if (oso_dwarf->FindFunctions(regex, include_inlines, true, sc_list))
   1132         {
   1133             RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx);
   1134         }
   1135     }
   1136 
   1137     return sc_list.GetSize() - initial_size;
   1138 }
   1139 
   1140 size_t
   1141 SymbolFileDWARFDebugMap::GetTypes (SymbolContextScope *sc_scope,
   1142                                    uint32_t type_mask,
   1143                                    TypeList &type_list)
   1144 {
   1145     Timer scoped_timer (__PRETTY_FUNCTION__,
   1146                         "SymbolFileDWARFDebugMap::GetTypes (type_mask = 0x%8.8x)",
   1147                         type_mask);
   1148 
   1149 
   1150     uint32_t initial_size = type_list.GetSize();
   1151     SymbolFileDWARF *oso_dwarf = NULL;
   1152     if (sc_scope)
   1153     {
   1154         SymbolContext sc;
   1155         sc_scope->CalculateSymbolContext(&sc);
   1156 
   1157         CompileUnitInfo *cu_info = GetCompUnitInfo (sc);
   1158         if (cu_info)
   1159         {
   1160             oso_dwarf = GetSymbolFileByCompUnitInfo (cu_info);
   1161             if (oso_dwarf)
   1162                 oso_dwarf->GetTypes (sc_scope, type_mask, type_list);
   1163         }
   1164     }
   1165     else
   1166     {
   1167         uint32_t oso_idx = 0;
   1168         while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL)
   1169         {
   1170             oso_dwarf->GetTypes (sc_scope, type_mask, type_list);
   1171         }
   1172     }
   1173     return type_list.GetSize() - initial_size;
   1174 }
   1175 
   1176 
   1177 TypeSP
   1178 SymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx)
   1179 {
   1180     TypeSP type_sp;
   1181     SymbolFileDWARF *oso_dwarf;
   1182     for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
   1183     {
   1184         type_sp = oso_dwarf->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);
   1185         if (type_sp)
   1186             break;
   1187     }
   1188     return type_sp;
   1189 }
   1190 
   1191 
   1192 
   1193 bool
   1194 SymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type (SymbolFileDWARF *skip_dwarf_oso)
   1195 {
   1196     if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate)
   1197     {
   1198         m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
   1199         SymbolFileDWARF *oso_dwarf;
   1200         for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
   1201         {
   1202             if (skip_dwarf_oso != oso_dwarf && oso_dwarf->Supports_DW_AT_APPLE_objc_complete_type(NULL))
   1203             {
   1204                 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
   1205                 break;
   1206             }
   1207         }
   1208     }
   1209     return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
   1210 }
   1211 
   1212 TypeSP
   1213 SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE (const DWARFDebugInfoEntry *die,
   1214                                                                const ConstString &type_name,
   1215                                                                bool must_be_implementation)
   1216 {
   1217     TypeSP type_sp;
   1218     SymbolFileDWARF *oso_dwarf;
   1219     for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
   1220     {
   1221         type_sp = oso_dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name, must_be_implementation);
   1222         if (type_sp)
   1223             break;
   1224     }
   1225     return type_sp;
   1226 }
   1227 
   1228 uint32_t
   1229 SymbolFileDWARFDebugMap::FindTypes
   1230 (
   1231     const SymbolContext& sc,
   1232     const ConstString &name,
   1233     const ClangNamespaceDecl *namespace_decl,
   1234     bool append,
   1235     uint32_t max_matches,
   1236     TypeList& types
   1237 )
   1238 {
   1239     if (!append)
   1240         types.Clear();
   1241 
   1242     const uint32_t initial_types_size = types.GetSize();
   1243     SymbolFileDWARF *oso_dwarf;
   1244 
   1245     if (sc.comp_unit)
   1246     {
   1247         oso_dwarf = GetSymbolFile (sc);
   1248         if (oso_dwarf)
   1249             return oso_dwarf->FindTypes (sc, name, namespace_decl, append, max_matches, types);
   1250     }
   1251     else
   1252     {
   1253         uint32_t oso_idx = 0;
   1254         while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL)
   1255             oso_dwarf->FindTypes (sc, name, namespace_decl, append, max_matches, types);
   1256     }
   1257 
   1258     return types.GetSize() - initial_types_size;
   1259 }
   1260 
   1261 //
   1262 //uint32_t
   1263 //SymbolFileDWARFDebugMap::FindTypes (const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types)
   1264 //{
   1265 //  SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
   1266 //  if (oso_dwarf)
   1267 //      return oso_dwarf->FindTypes (sc, regex, append, max_matches, encoding, udt_uid, types);
   1268 //  return 0;
   1269 //}
   1270 
   1271 
   1272 ClangNamespaceDecl
   1273 SymbolFileDWARFDebugMap::FindNamespace (const lldb_private::SymbolContext& sc,
   1274                                         const lldb_private::ConstString &name,
   1275                                         const ClangNamespaceDecl *parent_namespace_decl)
   1276 {
   1277     ClangNamespaceDecl matching_namespace;
   1278     SymbolFileDWARF *oso_dwarf;
   1279 
   1280     if (sc.comp_unit)
   1281     {
   1282         oso_dwarf = GetSymbolFile (sc);
   1283         if (oso_dwarf)
   1284             matching_namespace = oso_dwarf->FindNamespace (sc, name, parent_namespace_decl);
   1285     }
   1286     else
   1287     {
   1288         for (uint32_t oso_idx = 0;
   1289              ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL);
   1290              ++oso_idx)
   1291         {
   1292             matching_namespace = oso_dwarf->FindNamespace (sc, name, parent_namespace_decl);
   1293 
   1294             if (matching_namespace)
   1295                 break;
   1296         }
   1297     }
   1298 
   1299     return matching_namespace;
   1300 }
   1301 
   1302 //------------------------------------------------------------------
   1303 // PluginInterface protocol
   1304 //------------------------------------------------------------------
   1305 lldb_private::ConstString
   1306 SymbolFileDWARFDebugMap::GetPluginName()
   1307 {
   1308     return GetPluginNameStatic();
   1309 }
   1310 
   1311 uint32_t
   1312 SymbolFileDWARFDebugMap::GetPluginVersion()
   1313 {
   1314     return 1;
   1315 }
   1316 
   1317 lldb::CompUnitSP
   1318 SymbolFileDWARFDebugMap::GetCompileUnit (SymbolFileDWARF *oso_dwarf)
   1319 {
   1320     if (oso_dwarf)
   1321     {
   1322         const uint32_t cu_count = GetNumCompileUnits();
   1323         for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
   1324         {
   1325             SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
   1326             if (oso_symfile == oso_dwarf)
   1327             {
   1328                 if (!m_compile_unit_infos[cu_idx].compile_unit_sp)
   1329                     m_compile_unit_infos[cu_idx].compile_unit_sp = ParseCompileUnitAtIndex (cu_idx);
   1330 
   1331                 return m_compile_unit_infos[cu_idx].compile_unit_sp;
   1332             }
   1333         }
   1334     }
   1335     assert(!"this shouldn't happen");
   1336     return lldb::CompUnitSP();
   1337 }
   1338 
   1339 SymbolFileDWARFDebugMap::CompileUnitInfo *
   1340 SymbolFileDWARFDebugMap::GetCompileUnitInfo (SymbolFileDWARF *oso_dwarf)
   1341 {
   1342     if (oso_dwarf)
   1343     {
   1344         const uint32_t cu_count = GetNumCompileUnits();
   1345         for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
   1346         {
   1347             SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
   1348             if (oso_symfile == oso_dwarf)
   1349             {
   1350                 return &m_compile_unit_infos[cu_idx];
   1351             }
   1352         }
   1353     }
   1354     return NULL;
   1355 }
   1356 
   1357 
   1358 void
   1359 SymbolFileDWARFDebugMap::SetCompileUnit (SymbolFileDWARF *oso_dwarf, const CompUnitSP &cu_sp)
   1360 {
   1361     if (oso_dwarf)
   1362     {
   1363         const uint32_t cu_count = GetNumCompileUnits();
   1364         for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
   1365         {
   1366             SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
   1367             if (oso_symfile == oso_dwarf)
   1368             {
   1369                 if (m_compile_unit_infos[cu_idx].compile_unit_sp)
   1370                 {
   1371                     assert (m_compile_unit_infos[cu_idx].compile_unit_sp.get() == cu_sp.get());
   1372                 }
   1373                 else
   1374                 {
   1375                     m_compile_unit_infos[cu_idx].compile_unit_sp = cu_sp;
   1376                     m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp);
   1377                 }
   1378             }
   1379         }
   1380     }
   1381 }
   1382 
   1383 
   1384 void
   1385 SymbolFileDWARFDebugMap::CompleteTagDecl (void *baton, clang::TagDecl *decl)
   1386 {
   1387     SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton;
   1388     ClangASTType clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
   1389     if (clang_type)
   1390     {
   1391         SymbolFileDWARF *oso_dwarf;
   1392 
   1393         for (uint32_t oso_idx = 0; ((oso_dwarf = symbol_file_dwarf->GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
   1394         {
   1395             if (oso_dwarf->HasForwardDeclForClangType (clang_type))
   1396             {
   1397                 oso_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
   1398                 return;
   1399             }
   1400         }
   1401     }
   1402 }
   1403 
   1404 void
   1405 SymbolFileDWARFDebugMap::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl)
   1406 {
   1407     SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton;
   1408     ClangASTType clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
   1409     if (clang_type)
   1410     {
   1411         SymbolFileDWARF *oso_dwarf;
   1412 
   1413         for (uint32_t oso_idx = 0; ((oso_dwarf = symbol_file_dwarf->GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
   1414         {
   1415             if (oso_dwarf->HasForwardDeclForClangType (clang_type))
   1416             {
   1417                 oso_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
   1418                 return;
   1419             }
   1420         }
   1421     }
   1422 }
   1423 
   1424 bool
   1425 SymbolFileDWARFDebugMap::LayoutRecordType (void *baton,
   1426                                            const clang::RecordDecl *record_decl,
   1427                                            uint64_t &size,
   1428                                            uint64_t &alignment,
   1429                                            llvm::DenseMap <const clang::FieldDecl *, uint64_t> &field_offsets,
   1430                                            llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
   1431                                            llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets)
   1432 {
   1433     SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton;
   1434     SymbolFileDWARF *oso_dwarf;
   1435     for (uint32_t oso_idx = 0; ((oso_dwarf = symbol_file_dwarf->GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
   1436     {
   1437         if (oso_dwarf->LayoutRecordType (record_decl, size, alignment, field_offsets, base_offsets, vbase_offsets))
   1438             return true;
   1439     }
   1440     return false;
   1441 }
   1442 
   1443 
   1444 
   1445 clang::DeclContext*
   1446 SymbolFileDWARFDebugMap::GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid)
   1447 {
   1448     const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
   1449     SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
   1450     if (oso_dwarf)
   1451         return oso_dwarf->GetClangDeclContextContainingTypeUID (type_uid);
   1452     return NULL;
   1453 }
   1454 
   1455 clang::DeclContext*
   1456 SymbolFileDWARFDebugMap::GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid)
   1457 {
   1458     const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
   1459     SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
   1460     if (oso_dwarf)
   1461         return oso_dwarf->GetClangDeclContextForTypeUID (sc, type_uid);
   1462     return NULL;
   1463 }
   1464 
   1465 bool
   1466 SymbolFileDWARFDebugMap::AddOSOFileRange (CompileUnitInfo *cu_info,
   1467                                           lldb::addr_t exe_file_addr,
   1468                                           lldb::addr_t oso_file_addr,
   1469                                           lldb::addr_t oso_byte_size)
   1470 {
   1471     const uint32_t debug_map_idx = m_debug_map.FindEntryIndexThatContains(exe_file_addr);
   1472     if (debug_map_idx != UINT32_MAX)
   1473     {
   1474         DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(exe_file_addr);
   1475         debug_map_entry->data.SetOSOFileAddress(oso_file_addr);
   1476         cu_info->file_range_map.Append(FileRangeMap::Entry(oso_file_addr, oso_byte_size, exe_file_addr));
   1477         return true;
   1478     }
   1479     return false;
   1480 }
   1481 
   1482 void
   1483 SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (CompileUnitInfo *cu_info)
   1484 {
   1485     cu_info->file_range_map.Sort();
   1486 #if defined(DEBUG_OSO_DMAP)
   1487     const FileRangeMap &oso_file_range_map = cu_info->GetFileRangeMap(this);
   1488     const size_t n = oso_file_range_map.GetSize();
   1489     printf ("SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (cu_info = %p) %s\n",
   1490             cu_info,
   1491             cu_info->oso_sp->module_sp->GetFileSpec().GetPath().c_str());
   1492     for (size_t i=0; i<n; ++i)
   1493     {
   1494         const FileRangeMap::Entry &entry = oso_file_range_map.GetEntryRef(i);
   1495         printf ("oso [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") ==> exe [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n",
   1496                 entry.GetRangeBase(), entry.GetRangeEnd(),
   1497                 entry.data, entry.data + entry.GetByteSize());
   1498     }
   1499 #endif
   1500 }
   1501 
   1502 lldb::addr_t
   1503 SymbolFileDWARFDebugMap::LinkOSOFileAddress (SymbolFileDWARF *oso_symfile, lldb::addr_t oso_file_addr)
   1504 {
   1505     CompileUnitInfo *cu_info = GetCompileUnitInfo (oso_symfile);
   1506     if (cu_info)
   1507     {
   1508         const FileRangeMap::Entry *oso_range_entry = cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
   1509         if (oso_range_entry)
   1510         {
   1511             const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(oso_range_entry->data);
   1512             if (debug_map_entry)
   1513             {
   1514                 const lldb::addr_t offset = oso_file_addr - oso_range_entry->GetRangeBase();
   1515                 const lldb::addr_t exe_file_addr = debug_map_entry->GetRangeBase() + offset;
   1516                 return exe_file_addr;
   1517             }
   1518         }
   1519     }
   1520     return LLDB_INVALID_ADDRESS;
   1521 }
   1522 
   1523 bool
   1524 SymbolFileDWARFDebugMap::LinkOSOAddress (Address &addr)
   1525 {
   1526     // Make sure this address hasn't been fixed already
   1527     Module *exe_module = GetObjectFile()->GetModule().get();
   1528     Module *addr_module = addr.GetModule().get();
   1529     if (addr_module == exe_module)
   1530         return true; // Address is already in terms of the main executable module
   1531 
   1532     CompileUnitInfo *cu_info = GetCompileUnitInfo (GetSymbolFileAsSymbolFileDWARF(addr_module->GetSymbolVendor()->GetSymbolFile()));
   1533     if (cu_info)
   1534     {
   1535         const lldb::addr_t oso_file_addr = addr.GetFileAddress();
   1536         const FileRangeMap::Entry *oso_range_entry = cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
   1537         if (oso_range_entry)
   1538         {
   1539             const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(oso_range_entry->data);
   1540             if (debug_map_entry)
   1541             {
   1542                 const lldb::addr_t offset = oso_file_addr - oso_range_entry->GetRangeBase();
   1543                 const lldb::addr_t exe_file_addr = debug_map_entry->GetRangeBase() + offset;
   1544                 return exe_module->ResolveFileAddress(exe_file_addr, addr);
   1545             }
   1546         }
   1547     }
   1548     return true;
   1549 }
   1550 
   1551 LineTable *
   1552 SymbolFileDWARFDebugMap::LinkOSOLineTable (SymbolFileDWARF *oso_dwarf, LineTable *line_table)
   1553 {
   1554     CompileUnitInfo *cu_info = GetCompileUnitInfo (oso_dwarf);
   1555     if (cu_info)
   1556         return line_table->LinkLineTable(cu_info->GetFileRangeMap(this));
   1557     return NULL;
   1558 }
   1559 
   1560 size_t
   1561 SymbolFileDWARFDebugMap::AddOSOARanges (SymbolFileDWARF* dwarf2Data, DWARFDebugAranges* debug_aranges)
   1562 {
   1563     size_t num_line_entries_added = 0;
   1564     if (debug_aranges && dwarf2Data)
   1565     {
   1566         CompileUnitInfo *compile_unit_info = GetCompileUnitInfo(dwarf2Data);
   1567         if (compile_unit_info)
   1568         {
   1569             const FileRangeMap &file_range_map = compile_unit_info->GetFileRangeMap(this);
   1570             for (size_t idx = 0;
   1571                  idx < file_range_map.GetSize();
   1572                  idx++)
   1573             {
   1574                 const FileRangeMap::Entry* entry = file_range_map.GetEntryAtIndex(idx);
   1575                 if (entry)
   1576                 {
   1577                     printf ("[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n", entry->GetRangeBase(), entry->GetRangeEnd());
   1578                     debug_aranges->AppendRange(dwarf2Data->GetID(), entry->GetRangeBase(), entry->GetRangeEnd());
   1579                     num_line_entries_added++;
   1580                 }
   1581             }
   1582         }
   1583     }
   1584     return num_line_entries_added;
   1585 }
   1586 
   1587