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 "lldb/Core/Module.h"
13 #include "lldb/Core/ModuleList.h"
14 #include "lldb/Core/PluginManager.h"
15 #include "lldb/Core/RegularExpression.h"
16 #include "lldb/Core/StreamFile.h"
17 #include "lldb/Core/Timer.h"
18 
19 #include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
20 #include "lldb/Symbol/ObjectFile.h"
21 #include "lldb/Symbol/SymbolVendor.h"
22 #include "lldb/Symbol/VariableList.h"
23 
24 #include "LogChannelDWARF.h"
25 #include "SymbolFileDWARF.h"
26 
27 using namespace lldb;
28 using namespace lldb_private;
29 
30 void
31 SymbolFileDWARFDebugMap::Initialize()
32 {
33     PluginManager::RegisterPlugin (GetPluginNameStatic(),
34                                    GetPluginDescriptionStatic(),
35                                    CreateInstance);
36 }
37 
38 void
39 SymbolFileDWARFDebugMap::Terminate()
40 {
41     PluginManager::UnregisterPlugin (CreateInstance);
42 }
43 
44 
45 const char *
46 SymbolFileDWARFDebugMap::GetPluginNameStatic()
47 {
48     return "dwarf-debugmap";
49 }
50 
51 const char *
52 SymbolFileDWARFDebugMap::GetPluginDescriptionStatic()
53 {
54     return "DWARF and DWARF3 debug symbol file reader (debug map).";
55 }
56 
57 SymbolFile*
58 SymbolFileDWARFDebugMap::CreateInstance (ObjectFile* obj_file)
59 {
60     return new SymbolFileDWARFDebugMap (obj_file);
61 }
62 
63 
64 SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap (ObjectFile* ofile) :
65     SymbolFile(ofile),
66     m_flags(),
67     m_compile_unit_infos(),
68     m_func_indexes(),
69     m_glob_indexes(),
70     m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate)
71 {
72 }
73 
74 
75 SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap()
76 {
77 }
78 
79 void
80 SymbolFileDWARFDebugMap::InitializeObject()
81 {
82     // Install our external AST source callbacks so we can complete Clang types.
83     llvm::OwningPtr<clang::ExternalASTSource> ast_source_ap (
84         new ClangExternalASTSourceCallbacks (SymbolFileDWARFDebugMap::CompleteTagDecl,
85                                              SymbolFileDWARFDebugMap::CompleteObjCInterfaceDecl,
86                                              NULL,
87                                              SymbolFileDWARFDebugMap::LayoutRecordType,
88                                              this));
89 
90     GetClangASTContext().SetExternalSource (ast_source_ap);
91 }
92 
93 
94 
95 void
96 SymbolFileDWARFDebugMap::InitOSO ()
97 {
98     if (m_flags.test(kHaveInitializedOSOs))
99         return;
100 
101     m_flags.set(kHaveInitializedOSOs);
102     // In order to get the abilities of this plug-in, we look at the list of
103     // N_OSO entries (object files) from the symbol table and make sure that
104     // these files exist and also contain valid DWARF. If we get any of that
105     // then we return the abilities of the first N_OSO's DWARF.
106 
107     Symtab* symtab = m_obj_file->GetSymtab();
108     if (symtab)
109     {
110         LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
111 
112         std::vector<uint32_t> oso_indexes;
113 //      StreamFile s(stdout);
114 //      symtab->Dump(&s, NULL, eSortOrderNone);
115 
116         // When a mach-o symbol is encoded, the n_type field is encoded in bits
117         // 23:16, and the n_desc field is encoded in bits 15:0.
118         //
119         // To find all N_OSO entries that are part of the DWARF + debug map
120         // we find only object file symbols with the flags value as follows:
121         // bits 23:16 == 0x66 (N_OSO)
122         // bits 15: 0 == 0x0001 (specifies this is a debug map object file)
123         const uint32_t k_oso_symbol_flags_value = 0x660001u;
124 
125         const uint32_t oso_index_count = symtab->AppendSymbolIndexesWithTypeAndFlagsValue(eSymbolTypeObjectFile, k_oso_symbol_flags_value, oso_indexes);
126 
127         if (oso_index_count > 0)
128         {
129             symtab->AppendSymbolIndexesWithType (eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, m_func_indexes);
130             symtab->AppendSymbolIndexesWithType (eSymbolTypeData, Symtab::eDebugYes, Symtab::eVisibilityAny, m_glob_indexes);
131 
132             symtab->SortSymbolIndexesByValue(m_func_indexes, true);
133             symtab->SortSymbolIndexesByValue(m_glob_indexes, true);
134 
135             m_compile_unit_infos.resize(oso_index_count);
136 //          s.Printf("%s N_OSO symbols:\n", __PRETTY_FUNCTION__);
137 //          symtab->Dump(&s, oso_indexes);
138 
139             for (uint32_t i=0; i<oso_index_count; ++i)
140             {
141                 m_compile_unit_infos[i].so_symbol = symtab->SymbolAtIndex(oso_indexes[i] - 1);
142                 if (m_compile_unit_infos[i].so_symbol->GetSiblingIndex() == 0)
143                     m_compile_unit_infos[i].so_symbol = symtab->SymbolAtIndex(oso_indexes[i] - 2);
144                 m_compile_unit_infos[i].oso_symbol = symtab->SymbolAtIndex(oso_indexes[i]);
145                 uint32_t sibling_idx = m_compile_unit_infos[i].so_symbol->GetSiblingIndex();
146                 // The sibling index can't be less that or equal to the current index "i"
147                 if (sibling_idx <= i)
148                 {
149                     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", m_compile_unit_infos[i].so_symbol->GetID());
150                 }
151                 else
152                 {
153                     m_compile_unit_infos[i].last_symbol = symtab->SymbolAtIndex (sibling_idx - 1);
154                     m_compile_unit_infos[i].first_symbol_index = symtab->GetIndexForSymbol(m_compile_unit_infos[i].so_symbol);
155                     m_compile_unit_infos[i].last_symbol_index = symtab->GetIndexForSymbol(m_compile_unit_infos[i].last_symbol);
156 
157                     if (log)
158                         log->Printf("Initialized OSO 0x%8.8x: file=%s", i, m_compile_unit_infos[i].oso_symbol->GetName().GetCString());
159                 }
160             }
161         }
162     }
163 }
164 
165 Module *
166 SymbolFileDWARFDebugMap::GetModuleByOSOIndex (uint32_t oso_idx)
167 {
168     const uint32_t cu_count = GetNumCompileUnits();
169     if (oso_idx < cu_count)
170         return GetModuleByCompUnitInfo (&m_compile_unit_infos[oso_idx]);
171     return NULL;
172 }
173 
174 Module *
175 SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo (CompileUnitInfo *comp_unit_info)
176 {
177     if (comp_unit_info->oso_module_sp.get() == NULL && comp_unit_info->symbol_file_supported)
178     {
179         Symbol *oso_symbol = comp_unit_info->oso_symbol;
180         if (oso_symbol)
181         {
182             FileSpec oso_file_spec(oso_symbol->GetMangled().GetName().AsCString(), true);
183             // Always create a new module for .o files. Why? Because we
184             // use the debug map, to add new sections to each .o file and
185             // even though a .o file might not have changed, the sections
186             // that get added to the .o file can change.
187             comp_unit_info->oso_module_sp.reset (new Module (oso_file_spec,
188                                                              m_obj_file->GetModule()->GetArchitecture(),
189                                                              NULL,
190                                                              0));
191         }
192     }
193     return comp_unit_info->oso_module_sp.get();
194 }
195 
196 
197 bool
198 SymbolFileDWARFDebugMap::GetFileSpecForSO (uint32_t oso_idx, FileSpec &file_spec)
199 {
200     if (oso_idx < m_compile_unit_infos.size())
201     {
202         if (!m_compile_unit_infos[oso_idx].so_file)
203         {
204 
205             if (m_compile_unit_infos[oso_idx].so_symbol == NULL)
206                 return false;
207 
208             std::string so_path (m_compile_unit_infos[oso_idx].so_symbol->GetMangled().GetName().AsCString());
209             if (m_compile_unit_infos[oso_idx].so_symbol[1].GetType() == eSymbolTypeSourceFile)
210                 so_path += m_compile_unit_infos[oso_idx].so_symbol[1].GetMangled().GetName().AsCString();
211             m_compile_unit_infos[oso_idx].so_file.SetFile(so_path.c_str(), true);
212         }
213         file_spec = m_compile_unit_infos[oso_idx].so_file;
214         return true;
215     }
216     return false;
217 }
218 
219 
220 
221 ObjectFile *
222 SymbolFileDWARFDebugMap::GetObjectFileByOSOIndex (uint32_t oso_idx)
223 {
224     Module *oso_module = GetModuleByOSOIndex (oso_idx);
225     if (oso_module)
226         return oso_module->GetObjectFile();
227     return NULL;
228 }
229 
230 SymbolFileDWARF *
231 SymbolFileDWARFDebugMap::GetSymbolFile (const SymbolContext& sc)
232 {
233     CompileUnitInfo *comp_unit_info = GetCompUnitInfo (sc);
234     if (comp_unit_info)
235         return GetSymbolFileByCompUnitInfo (comp_unit_info);
236     return NULL;
237 }
238 
239 ObjectFile *
240 SymbolFileDWARFDebugMap::GetObjectFileByCompUnitInfo (CompileUnitInfo *comp_unit_info)
241 {
242     Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
243     if (oso_module)
244         return oso_module->GetObjectFile();
245     return NULL;
246 }
247 
248 
249 uint32_t
250 SymbolFileDWARFDebugMap::GetCompUnitInfoIndex (const CompileUnitInfo *comp_unit_info)
251 {
252     if (!m_compile_unit_infos.empty())
253     {
254         const CompileUnitInfo *first_comp_unit_info = &m_compile_unit_infos.front();
255         const CompileUnitInfo *last_comp_unit_info = &m_compile_unit_infos.back();
256         if (first_comp_unit_info <= comp_unit_info && comp_unit_info <= last_comp_unit_info)
257             return comp_unit_info - first_comp_unit_info;
258     }
259     return UINT32_MAX;
260 }
261 
262 SymbolFileDWARF *
263 SymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex (uint32_t oso_idx)
264 {
265     if (oso_idx < m_compile_unit_infos.size())
266         return GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[oso_idx]);
267     return NULL;
268 }
269 
270 SymbolFileDWARF *
271 SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo (CompileUnitInfo *comp_unit_info)
272 {
273     if (comp_unit_info->oso_symbol_vendor == NULL && comp_unit_info->symbol_file_supported)
274     {
275         ObjectFile *oso_objfile = GetObjectFileByCompUnitInfo (comp_unit_info);
276 
277         if (oso_objfile)
278         {
279             comp_unit_info->oso_symbol_vendor = oso_objfile->GetModule()->GetSymbolVendor();
280 //          SymbolFileDWARF *oso_dwarf = new SymbolFileDWARF(oso_objfile);
281 //          comp_unit_info->oso_dwarf_sp.reset (oso_dwarf);
282             if (comp_unit_info->oso_symbol_vendor)
283             {
284                 // Set a a pointer to this class to set our OSO DWARF file know
285                 // that the DWARF is being used along with a debug map and that
286                 // it will have the remapped sections that we do below.
287                 SymbolFileDWARF *oso_symfile = (SymbolFileDWARF *)comp_unit_info->oso_symbol_vendor->GetSymbolFile();
288 
289                 if (!oso_symfile)
290                     return NULL;
291 
292                 if (oso_symfile->GetNumCompileUnits() != 1)
293                 {
294                     oso_symfile->GetObjectFile()->GetModule()->ReportError ("DWARF for object file '%s' contains multiple translation units!",
295                                                                             oso_symfile->GetObjectFile()->GetFileSpec().GetFilename().AsCString());
296                     comp_unit_info->symbol_file_supported = false;
297                     comp_unit_info->oso_module_sp.reset();
298                     comp_unit_info->oso_compile_unit_sp.reset();
299                     comp_unit_info->oso_symbol_vendor = NULL;
300                     return NULL;
301                 }
302 
303                 oso_symfile->SetDebugMapSymfile(this);
304                 // Set the ID of the symbol file DWARF to the index of the OSO
305                 // shifted left by 32 bits to provide a unique prefix for any
306                 // UserID's that get created in the symbol file.
307                 oso_symfile->SetID (((uint64_t)GetCompUnitInfoIndex(comp_unit_info) + 1ull) << 32ull);
308                 comp_unit_info->debug_map_sections_sp.reset(new SectionList);
309 
310                 Symtab *exe_symtab = m_obj_file->GetSymtab();
311                 ModuleSP oso_module_sp (oso_objfile->GetModule());
312                 Symtab *oso_symtab = oso_objfile->GetSymtab();
313 //#define DEBUG_OSO_DMAP    // Do not check in with this defined...
314 #if defined(DEBUG_OSO_DMAP)
315                 StreamFile s(stdout);
316                 s << "OSO symtab:\n";
317                 oso_symtab->Dump(&s, NULL);
318                 s << "OSO sections before:\n";
319                 oso_objfile->GetSectionList()->Dump(&s, NULL, true);
320 #endif
321 
322                 ///const uint32_t fun_resolve_flags = SymbolContext::Module | eSymbolContextCompUnit | eSymbolContextFunction;
323                 //SectionList *oso_sections = oso_objfile->Sections();
324                 // Now we need to make sections that map from zero based object
325                 // file addresses to where things eneded up in the main executable.
326                 uint32_t oso_start_idx = exe_symtab->GetIndexForSymbol (comp_unit_info->oso_symbol);
327                 assert (oso_start_idx != UINT32_MAX);
328                 oso_start_idx += 1;
329                 const uint32_t oso_end_idx = comp_unit_info->so_symbol->GetSiblingIndex();
330                 uint32_t sect_id = 0x10000;
331                 for (uint32_t idx = oso_start_idx; idx < oso_end_idx; ++idx)
332                 {
333                     Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx);
334                     if (exe_symbol)
335                     {
336                         if (exe_symbol->IsDebug() == false)
337                             continue;
338 
339                         switch (exe_symbol->GetType())
340                         {
341                         default:
342                             break;
343 
344                         case eSymbolTypeCode:
345                             {
346                                 // For each N_FUN, or function that we run into in the debug map
347                                 // we make a new section that we add to the sections found in the
348                                 // .o file. This new section has the file address set to what the
349                                 // addresses are in the .o file, and the load address is adjusted
350                                 // to match where it ended up in the final executable! We do this
351                                 // before we parse any dwarf info so that when it goes get parsed
352                                 // all section/offset addresses that get registered will resolve
353                                 // correctly to the new addresses in the main executable.
354 
355                                 // First we find the original symbol in the .o file's symbol table
356                                 Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType(exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny);
357                                 if (oso_fun_symbol)
358                                 {
359                                     // If we found the symbol, then we
360                                     SectionSP exe_fun_section (exe_symbol->GetAddress().GetSection());
361                                     SectionSP oso_fun_section (oso_fun_symbol->GetAddress().GetSection());
362                                     if (oso_fun_section)
363                                     {
364                                         // Now we create a section that we will add as a child of the
365                                         // section in which the .o symbol (the N_FUN) exists.
366 
367                                         // We use the exe_symbol size because the one in the .o file
368                                         // will just be a symbol with no size, and the exe_symbol
369                                         // size will reflect any size changes (ppc has been known to
370                                         // shrink function sizes when it gets rid of jump islands that
371                                         // aren't needed anymore).
372                                         SectionSP oso_fun_section_sp (new Section (oso_fun_symbol->GetAddress().GetSection(),
373                                                                                         oso_module_sp,                         // Module (the .o file)
374                                                                                         sect_id++,                          // Section ID starts at 0x10000 and increments so the section IDs don't overlap with the standard mach IDs
375                                                                                         exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), // Name the section the same as the symbol for which is was generated!
376                                                                                         eSectionTypeDebug,
377                                                                                         oso_fun_symbol->GetAddress().GetOffset(),  // File VM address offset in the current section
378                                                                                         exe_symbol->GetByteSize(),          // File size (we need the size from the executable)
379                                                                                         0, 0, 0));
380 
381                                         oso_fun_section_sp->SetLinkedLocation (exe_fun_section,
382                                                                                exe_symbol->GetAddress().GetFileAddress() - exe_fun_section->GetFileAddress());
383                                         oso_fun_section->GetChildren().AddSection(oso_fun_section_sp);
384                                         comp_unit_info->debug_map_sections_sp->AddSection(oso_fun_section_sp);
385                                     }
386                                 }
387                             }
388                             break;
389 
390                         case eSymbolTypeData:
391                             {
392                                 // For each N_GSYM we remap the address for the global by making
393                                 // a new section that we add to the sections found in the .o file.
394                                 // This new section has the file address set to what the
395                                 // addresses are in the .o file, and the load address is adjusted
396                                 // to match where it ended up in the final executable! We do this
397                                 // before we parse any dwarf info so that when it goes get parsed
398                                 // all section/offset addresses that get registered will resolve
399                                 // correctly to the new addresses in the main executable. We
400                                 // initially set the section size to be 1 byte, but will need to
401                                 // fix up these addresses further after all globals have been
402                                 // parsed to span the gaps, or we can find the global variable
403                                 // sizes from the DWARF info as we are parsing.
404 
405                                 // Next we find the non-stab entry that corresponds to the N_GSYM in the .o file
406                                 Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(),
407                                                                                                       eSymbolTypeData,
408                                                                                                       Symtab::eDebugNo,
409                                                                                                       Symtab::eVisibilityAny);
410 
411                                 if (exe_symbol && oso_gsym_symbol && exe_symbol->ValueIsAddress() && oso_gsym_symbol->ValueIsAddress())
412                                 {
413                                     // If we found the symbol, then we
414                                     SectionSP exe_gsym_section (exe_symbol->GetAddress().GetSection());
415                                     SectionSP oso_gsym_section (oso_gsym_symbol->GetAddress().GetSection());
416                                     if (oso_gsym_section)
417                                     {
418                                         SectionSP oso_gsym_section_sp (new Section (oso_gsym_symbol->GetAddress().GetSection(),
419                                                                                     oso_module_sp,                         // Module (the .o file)
420                                                                                     sect_id++,                          // Section ID starts at 0x10000 and increments so the section IDs don't overlap with the standard mach IDs
421                                                                                     exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), // Name the section the same as the symbol for which is was generated!
422                                                                                     eSectionTypeDebug,
423                                                                                     oso_gsym_symbol->GetAddress().GetOffset(),  // File VM address offset in the current section
424                                                                                     1,                                   // We don't know the size of the global, just do the main address for now.
425                                                                                     0, 0, 0));
426 
427                                         oso_gsym_section_sp->SetLinkedLocation (exe_gsym_section,
428                                                                                 exe_symbol->GetAddress().GetFileAddress() - exe_gsym_section->GetFileAddress());
429                                         oso_gsym_section->GetChildren().AddSection(oso_gsym_section_sp);
430                                         comp_unit_info->debug_map_sections_sp->AddSection(oso_gsym_section_sp);
431                                     }
432                                 }
433                             }
434                             break;
435                         }
436                     }
437                 }
438                 oso_objfile->GetSectionList()->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches
439                 comp_unit_info->debug_map_sections_sp->Finalize();
440 #if defined(DEBUG_OSO_DMAP)
441                 s << "OSO sections after:\n";
442                 oso_objfile->GetSectionList()->Dump(&s, NULL, true);
443 #endif
444             }
445         }
446     }
447     if (comp_unit_info->oso_symbol_vendor)
448         return (SymbolFileDWARF *)comp_unit_info->oso_symbol_vendor->GetSymbolFile();
449     return NULL;
450 }
451 
452 uint32_t
453 SymbolFileDWARFDebugMap::CalculateAbilities ()
454 {
455     // In order to get the abilities of this plug-in, we look at the list of
456     // N_OSO entries (object files) from the symbol table and make sure that
457     // these files exist and also contain valid DWARF. If we get any of that
458     // then we return the abilities of the first N_OSO's DWARF.
459 
460     const uint32_t oso_index_count = GetNumCompileUnits();
461     if (oso_index_count > 0)
462     {
463         const uint32_t dwarf_abilities = SymbolFile::CompileUnits |
464                                          SymbolFile::Functions |
465                                          SymbolFile::Blocks |
466                                          SymbolFile::GlobalVariables |
467                                          SymbolFile::LocalVariables |
468                                          SymbolFile::VariableTypes |
469                                          SymbolFile::LineTables;
470 
471         for (uint32_t oso_idx=0; oso_idx<oso_index_count; ++oso_idx)
472         {
473             SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
474             if (oso_dwarf)
475             {
476                 uint32_t oso_abilities = oso_dwarf->GetAbilities();
477                 if ((oso_abilities & dwarf_abilities) == dwarf_abilities)
478                     return oso_abilities;
479             }
480         }
481     }
482     return 0;
483 }
484 
485 uint32_t
486 SymbolFileDWARFDebugMap::GetNumCompileUnits()
487 {
488     InitOSO ();
489     return m_compile_unit_infos.size();
490 }
491 
492 
493 CompUnitSP
494 SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx)
495 {
496     CompUnitSP comp_unit_sp;
497     const uint32_t cu_count = GetNumCompileUnits();
498 
499     if (cu_idx < cu_count)
500     {
501         if (m_compile_unit_infos[cu_idx].oso_compile_unit_sp.get() == NULL &&
502             m_compile_unit_infos[cu_idx].symbol_file_supported)
503         {
504             SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (cu_idx);
505             if (oso_dwarf)
506             {
507                 // There is only one compile unit for N_OSO entry right now, so
508                 // it will always exist at index zero.
509                 m_compile_unit_infos[cu_idx].oso_compile_unit_sp = m_compile_unit_infos[cu_idx].oso_symbol_vendor->GetCompileUnitAtIndex (0);
510             }
511 
512             if (m_compile_unit_infos[cu_idx].oso_compile_unit_sp.get() == NULL)
513             {
514                 // We weren't able to get the DWARF for this N_OSO entry (the
515                 // .o file may be missing or not at the specified path), make
516                 // one up as best we can from the debug map. We set the uid
517                 // of the compile unit to the symbol index with the MSBit set
518                 // so that it doesn't collide with any uid values from the DWARF
519                 Symbol *so_symbol = m_compile_unit_infos[cu_idx].so_symbol;
520                 if (so_symbol)
521                 {
522                     m_compile_unit_infos[cu_idx].oso_compile_unit_sp.reset(new CompileUnit (m_obj_file->GetModule(),
523                                                                                             NULL,
524                                                                                             so_symbol->GetMangled().GetName().AsCString(),
525                                                                                             cu_idx,
526                                                                                             eLanguageTypeUnknown));
527 
528                     // Let our symbol vendor know about this compile unit
529                     m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex (cu_idx,
530                                                                                        m_compile_unit_infos[cu_idx].oso_compile_unit_sp);
531                 }
532             }
533         }
534         comp_unit_sp = m_compile_unit_infos[cu_idx].oso_compile_unit_sp;
535     }
536 
537     return comp_unit_sp;
538 }
539 
540 SymbolFileDWARFDebugMap::CompileUnitInfo *
541 SymbolFileDWARFDebugMap::GetCompUnitInfo (const SymbolContext& sc)
542 {
543     const uint32_t cu_count = GetNumCompileUnits();
544     for (uint32_t i=0; i<cu_count; ++i)
545     {
546         if (sc.comp_unit == m_compile_unit_infos[i].oso_compile_unit_sp.get())
547             return &m_compile_unit_infos[i];
548     }
549     return NULL;
550 }
551 
552 size_t
553 SymbolFileDWARFDebugMap::ParseCompileUnitFunctions (const SymbolContext& sc)
554 {
555     SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
556     if (oso_dwarf)
557         return oso_dwarf->ParseCompileUnitFunctions (sc);
558     return 0;
559 }
560 
561 bool
562 SymbolFileDWARFDebugMap::ParseCompileUnitLineTable (const SymbolContext& sc)
563 {
564     SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
565     if (oso_dwarf)
566         return oso_dwarf->ParseCompileUnitLineTable (sc);
567     return false;
568 }
569 
570 bool
571 SymbolFileDWARFDebugMap::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files)
572 {
573     SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
574     if (oso_dwarf)
575         return oso_dwarf->ParseCompileUnitSupportFiles (sc, support_files);
576     return false;
577 }
578 
579 
580 size_t
581 SymbolFileDWARFDebugMap::ParseFunctionBlocks (const SymbolContext& sc)
582 {
583     SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
584     if (oso_dwarf)
585         return oso_dwarf->ParseFunctionBlocks (sc);
586     return 0;
587 }
588 
589 
590 size_t
591 SymbolFileDWARFDebugMap::ParseTypes (const SymbolContext& sc)
592 {
593     SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
594     if (oso_dwarf)
595         return oso_dwarf->ParseTypes (sc);
596     return 0;
597 }
598 
599 
600 size_t
601 SymbolFileDWARFDebugMap::ParseVariablesForContext (const SymbolContext& sc)
602 {
603     SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
604     if (oso_dwarf)
605         return oso_dwarf->ParseTypes (sc);
606     return 0;
607 }
608 
609 
610 
611 Type*
612 SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid)
613 {
614     const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
615     SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
616     if (oso_dwarf)
617         oso_dwarf->ResolveTypeUID (type_uid);
618     return NULL;
619 }
620 
621 lldb::clang_type_t
622 SymbolFileDWARFDebugMap::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type)
623 {
624     // We have a struct/union/class/enum that needs to be fully resolved.
625     return NULL;
626 }
627 
628 uint32_t
629 SymbolFileDWARFDebugMap::ResolveSymbolContext (const Address& exe_so_addr, uint32_t resolve_scope, SymbolContext& sc)
630 {
631     uint32_t resolved_flags = 0;
632     Symtab* symtab = m_obj_file->GetSymtab();
633     if (symtab)
634     {
635         const addr_t exe_file_addr = exe_so_addr.GetFileAddress();
636         sc.symbol = symtab->FindSymbolContainingFileAddress (exe_file_addr, &m_func_indexes[0], m_func_indexes.size());
637 
638         if (sc.symbol != NULL)
639         {
640             resolved_flags |= eSymbolContextSymbol;
641 
642             uint32_t oso_idx = 0;
643             CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithID (sc.symbol->GetID(), &oso_idx);
644             if (comp_unit_info)
645             {
646                 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
647                 ObjectFile *oso_objfile = GetObjectFileByOSOIndex (oso_idx);
648                 if (oso_dwarf && oso_objfile)
649                 {
650                     SectionList *oso_section_list = oso_objfile->GetSectionList();
651 
652                     SectionSP oso_symbol_section_sp (oso_section_list->FindSectionContainingLinkedFileAddress (exe_file_addr, UINT32_MAX));
653 
654                     if (oso_symbol_section_sp)
655                     {
656                         const addr_t linked_file_addr = oso_symbol_section_sp->GetLinkedFileAddress();
657                         Address oso_so_addr (oso_symbol_section_sp, exe_file_addr - linked_file_addr);
658                         if (oso_so_addr.IsSectionOffset())
659                             resolved_flags |= oso_dwarf->ResolveSymbolContext (oso_so_addr, resolve_scope, sc);
660                     }
661                 }
662             }
663         }
664     }
665     return resolved_flags;
666 }
667 
668 
669 uint32_t
670 SymbolFileDWARFDebugMap::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
671 {
672     uint32_t initial = sc_list.GetSize();
673     const uint32_t cu_count = GetNumCompileUnits();
674 
675     FileSpec so_file_spec;
676     for (uint32_t i=0; i<cu_count; ++i)
677     {
678         if (GetFileSpecForSO (i, so_file_spec))
679         {
680             // By passing false to the comparison we will be able to match
681             // and files given a filename only. If both file_spec and
682             // so_file_spec have directories, we will still do a full match.
683             if (FileSpec::Compare (file_spec, so_file_spec, false) == 0)
684             {
685                 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (i);
686                 if (oso_dwarf)
687                     oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope, sc_list);
688             }
689         }
690     }
691     return sc_list.GetSize() - initial;
692 }
693 
694 uint32_t
695 SymbolFileDWARFDebugMap::PrivateFindGlobalVariables
696 (
697     const ConstString &name,
698     const ClangNamespaceDecl *namespace_decl,
699     const std::vector<uint32_t> &indexes,   // Indexes into the symbol table that match "name"
700     uint32_t max_matches,
701     VariableList& variables
702 )
703 {
704     const uint32_t original_size = variables.GetSize();
705     const size_t match_count = indexes.size();
706     for (size_t i=0; i<match_count; ++i)
707     {
708         uint32_t oso_idx;
709         CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithIndex (indexes[i], &oso_idx);
710         if (comp_unit_info)
711         {
712             SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
713             if (oso_dwarf)
714             {
715                 if (oso_dwarf->FindGlobalVariables(name, namespace_decl, true, max_matches, variables))
716                     if (variables.GetSize() > max_matches)
717                         break;
718             }
719         }
720     }
721     return variables.GetSize() - original_size;
722 }
723 
724 uint32_t
725 SymbolFileDWARFDebugMap::FindGlobalVariables (const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables)
726 {
727 
728     // If we aren't appending the results to this list, then clear the list
729     if (!append)
730         variables.Clear();
731 
732     // Remember how many variables are in the list before we search in case
733     // we are appending the results to a variable list.
734     const uint32_t original_size = variables.GetSize();
735 
736     uint32_t total_matches = 0;
737     SymbolFileDWARF *oso_dwarf;
738     for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
739     {
740         const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (name,
741                                                                      namespace_decl,
742                                                                      true,
743                                                                      max_matches,
744                                                                      variables);
745         if (oso_matches > 0)
746         {
747             total_matches += oso_matches;
748 
749             // Are we getting all matches?
750             if (max_matches == UINT32_MAX)
751                 continue;   // Yep, continue getting everything
752 
753             // If we have found enough matches, lets get out
754             if (max_matches >= total_matches)
755                 break;
756 
757             // Update the max matches for any subsequent calls to find globals
758             // in any other object files with DWARF
759             max_matches -= oso_matches;
760         }
761     }
762     // Return the number of variable that were appended to the list
763     return variables.GetSize() - original_size;
764 }
765 
766 
767 uint32_t
768 SymbolFileDWARFDebugMap::FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
769 {
770     // If we aren't appending the results to this list, then clear the list
771     if (!append)
772         variables.Clear();
773 
774     // Remember how many variables are in the list before we search in case
775     // we are appending the results to a variable list.
776     const uint32_t original_size = variables.GetSize();
777 
778     uint32_t total_matches = 0;
779     SymbolFileDWARF *oso_dwarf;
780     for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
781     {
782         const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (regex,
783                                                                      true,
784                                                                      max_matches,
785                                                                      variables);
786         if (oso_matches > 0)
787         {
788             total_matches += oso_matches;
789 
790             // Are we getting all matches?
791             if (max_matches == UINT32_MAX)
792                 continue;   // Yep, continue getting everything
793 
794             // If we have found enough matches, lets get out
795             if (max_matches >= total_matches)
796                 break;
797 
798             // Update the max matches for any subsequent calls to find globals
799             // in any other object files with DWARF
800             max_matches -= oso_matches;
801         }
802     }
803     // Return the number of variable that were appended to the list
804     return variables.GetSize() - original_size;
805 }
806 
807 
808 int
809 SymbolFileDWARFDebugMap::SymbolContainsSymbolWithIndex (uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info)
810 {
811     const uint32_t symbol_idx = *symbol_idx_ptr;
812 
813     if (symbol_idx < comp_unit_info->first_symbol_index)
814         return -1;
815 
816     if (symbol_idx <= comp_unit_info->last_symbol_index)
817         return 0;
818 
819     return 1;
820 }
821 
822 
823 int
824 SymbolFileDWARFDebugMap::SymbolContainsSymbolWithID (user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info)
825 {
826     const user_id_t symbol_id = *symbol_idx_ptr;
827 
828     if (symbol_id < comp_unit_info->so_symbol->GetID())
829         return -1;
830 
831     if (symbol_id <= comp_unit_info->last_symbol->GetID())
832         return 0;
833 
834     return 1;
835 }
836 
837 
838 SymbolFileDWARFDebugMap::CompileUnitInfo*
839 SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithIndex (uint32_t symbol_idx, uint32_t *oso_idx_ptr)
840 {
841     const uint32_t oso_index_count = m_compile_unit_infos.size();
842     CompileUnitInfo *comp_unit_info = NULL;
843     if (oso_index_count)
844     {
845         comp_unit_info = (CompileUnitInfo*)bsearch(&symbol_idx,
846                                                    &m_compile_unit_infos[0],
847                                                    m_compile_unit_infos.size(),
848                                                    sizeof(CompileUnitInfo),
849                                                    (ComparisonFunction)SymbolContainsSymbolWithIndex);
850     }
851 
852     if (oso_idx_ptr)
853     {
854         if (comp_unit_info != NULL)
855             *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
856         else
857             *oso_idx_ptr = UINT32_MAX;
858     }
859     return comp_unit_info;
860 }
861 
862 SymbolFileDWARFDebugMap::CompileUnitInfo*
863 SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithID (user_id_t symbol_id, uint32_t *oso_idx_ptr)
864 {
865     const uint32_t oso_index_count = m_compile_unit_infos.size();
866     CompileUnitInfo *comp_unit_info = NULL;
867     if (oso_index_count)
868     {
869         comp_unit_info = (CompileUnitInfo*)::bsearch (&symbol_id,
870                                                       &m_compile_unit_infos[0],
871                                                       m_compile_unit_infos.size(),
872                                                       sizeof(CompileUnitInfo),
873                                                       (ComparisonFunction)SymbolContainsSymbolWithID);
874     }
875 
876     if (oso_idx_ptr)
877     {
878         if (comp_unit_info != NULL)
879             *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
880         else
881             *oso_idx_ptr = UINT32_MAX;
882     }
883     return comp_unit_info;
884 }
885 
886 
887 static void
888 RemoveFunctionsWithModuleNotEqualTo (const ModuleSP &module_sp, SymbolContextList &sc_list, uint32_t start_idx)
889 {
890     // We found functions in .o files. Not all functions in the .o files
891     // will have made it into the final output file. The ones that did
892     // make it into the final output file will have a section whose module
893     // matches the module from the ObjectFile for this SymbolFile. When
894     // the modules don't match, then we have something that was in a
895     // .o file, but doesn't map to anything in the final executable.
896     uint32_t i=start_idx;
897     while (i < sc_list.GetSize())
898     {
899         SymbolContext sc;
900         sc_list.GetContextAtIndex(i, sc);
901         if (sc.function)
902         {
903             const SectionSP section_sp (sc.function->GetAddressRange().GetBaseAddress().GetSection());
904             if (section_sp->GetModule() != module_sp)
905             {
906                 sc_list.RemoveContextAtIndex(i);
907                 continue;
908             }
909         }
910         ++i;
911     }
912 }
913 
914 uint32_t
915 SymbolFileDWARFDebugMap::FindFunctions(const ConstString &name, const ClangNamespaceDecl *namespace_decl, uint32_t name_type_mask, bool include_inlines, bool append, SymbolContextList& sc_list)
916 {
917     Timer scoped_timer (__PRETTY_FUNCTION__,
918                         "SymbolFileDWARFDebugMap::FindFunctions (name = %s)",
919                         name.GetCString());
920 
921     uint32_t initial_size = 0;
922     if (append)
923         initial_size = sc_list.GetSize();
924     else
925         sc_list.Clear();
926 
927     uint32_t oso_idx = 0;
928     SymbolFileDWARF *oso_dwarf;
929     while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL)
930     {
931         uint32_t sc_idx = sc_list.GetSize();
932         if (oso_dwarf->FindFunctions(name, namespace_decl, name_type_mask, include_inlines, true, sc_list))
933         {
934             RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx);
935         }
936     }
937 
938     return sc_list.GetSize() - initial_size;
939 }
940 
941 
942 uint32_t
943 SymbolFileDWARFDebugMap::FindFunctions (const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list)
944 {
945     Timer scoped_timer (__PRETTY_FUNCTION__,
946                         "SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')",
947                         regex.GetText());
948 
949     uint32_t initial_size = 0;
950     if (append)
951         initial_size = sc_list.GetSize();
952     else
953         sc_list.Clear();
954 
955     uint32_t oso_idx = 0;
956     SymbolFileDWARF *oso_dwarf;
957     while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL)
958     {
959         uint32_t sc_idx = sc_list.GetSize();
960 
961         if (oso_dwarf->FindFunctions(regex, include_inlines, true, sc_list))
962         {
963             RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx);
964         }
965     }
966 
967     return sc_list.GetSize() - initial_size;
968 }
969 
970 TypeSP
971 SymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx)
972 {
973     TypeSP type_sp;
974     SymbolFileDWARF *oso_dwarf;
975     for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
976     {
977         type_sp = oso_dwarf->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);
978         if (type_sp)
979             break;
980     }
981     return type_sp;
982 }
983 
984 
985 
986 bool
987 SymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type (SymbolFileDWARF *skip_dwarf_oso)
988 {
989     if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate)
990     {
991         m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
992         SymbolFileDWARF *oso_dwarf;
993         for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
994         {
995             if (skip_dwarf_oso != oso_dwarf && oso_dwarf->Supports_DW_AT_APPLE_objc_complete_type(NULL))
996             {
997                 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
998                 break;
999             }
1000         }
1001     }
1002     return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
1003 }
1004 
1005 TypeSP
1006 SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE (const DWARFDebugInfoEntry *die,
1007                                                                const ConstString &type_name,
1008                                                                bool must_be_implementation)
1009 {
1010     TypeSP type_sp;
1011     SymbolFileDWARF *oso_dwarf;
1012     for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
1013     {
1014         type_sp = oso_dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name, must_be_implementation);
1015         if (type_sp)
1016             break;
1017     }
1018     return type_sp;
1019 }
1020 
1021 uint32_t
1022 SymbolFileDWARFDebugMap::FindTypes
1023 (
1024     const SymbolContext& sc,
1025     const ConstString &name,
1026     const ClangNamespaceDecl *namespace_decl,
1027     bool append,
1028     uint32_t max_matches,
1029     TypeList& types
1030 )
1031 {
1032     if (!append)
1033         types.Clear();
1034 
1035     const uint32_t initial_types_size = types.GetSize();
1036     SymbolFileDWARF *oso_dwarf;
1037 
1038     if (sc.comp_unit)
1039     {
1040         oso_dwarf = GetSymbolFile (sc);
1041         if (oso_dwarf)
1042             return oso_dwarf->FindTypes (sc, name, namespace_decl, append, max_matches, types);
1043     }
1044     else
1045     {
1046         uint32_t oso_idx = 0;
1047         while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL)
1048             oso_dwarf->FindTypes (sc, name, namespace_decl, append, max_matches, types);
1049     }
1050 
1051     return types.GetSize() - initial_types_size;
1052 }
1053 
1054 //
1055 //uint32_t
1056 //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)
1057 //{
1058 //  SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
1059 //  if (oso_dwarf)
1060 //      return oso_dwarf->FindTypes (sc, regex, append, max_matches, encoding, udt_uid, types);
1061 //  return 0;
1062 //}
1063 
1064 
1065 ClangNamespaceDecl
1066 SymbolFileDWARFDebugMap::FindNamespace (const lldb_private::SymbolContext& sc,
1067                                         const lldb_private::ConstString &name,
1068                                         const ClangNamespaceDecl *parent_namespace_decl)
1069 {
1070     ClangNamespaceDecl matching_namespace;
1071     SymbolFileDWARF *oso_dwarf;
1072 
1073     if (sc.comp_unit)
1074     {
1075         oso_dwarf = GetSymbolFile (sc);
1076         if (oso_dwarf)
1077             matching_namespace = oso_dwarf->FindNamespace (sc, name, parent_namespace_decl);
1078     }
1079     else
1080     {
1081         for (uint32_t oso_idx = 0;
1082              ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL);
1083              ++oso_idx)
1084         {
1085             matching_namespace = oso_dwarf->FindNamespace (sc, name, parent_namespace_decl);
1086 
1087             if (matching_namespace)
1088                 break;
1089         }
1090     }
1091 
1092     return matching_namespace;
1093 }
1094 
1095 //------------------------------------------------------------------
1096 // PluginInterface protocol
1097 //------------------------------------------------------------------
1098 const char *
1099 SymbolFileDWARFDebugMap::GetPluginName()
1100 {
1101     return "SymbolFileDWARFDebugMap";
1102 }
1103 
1104 const char *
1105 SymbolFileDWARFDebugMap::GetShortPluginName()
1106 {
1107     return GetPluginNameStatic();
1108 }
1109 
1110 uint32_t
1111 SymbolFileDWARFDebugMap::GetPluginVersion()
1112 {
1113     return 1;
1114 }
1115 
1116 void
1117 SymbolFileDWARFDebugMap::SetCompileUnit (SymbolFileDWARF *oso_dwarf, const CompUnitSP &cu_sp)
1118 {
1119     const uint32_t cu_count = GetNumCompileUnits();
1120     for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
1121     {
1122         if (m_compile_unit_infos[cu_idx].oso_symbol_vendor &&
1123             m_compile_unit_infos[cu_idx].oso_symbol_vendor->GetSymbolFile() == oso_dwarf)
1124         {
1125             if (m_compile_unit_infos[cu_idx].oso_compile_unit_sp)
1126             {
1127                 assert (m_compile_unit_infos[cu_idx].oso_compile_unit_sp.get() == cu_sp.get());
1128             }
1129             else
1130             {
1131                 m_compile_unit_infos[cu_idx].oso_compile_unit_sp = cu_sp;
1132                 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp);
1133             }
1134         }
1135     }
1136 }
1137 
1138 
1139 void
1140 SymbolFileDWARFDebugMap::CompleteTagDecl (void *baton, clang::TagDecl *decl)
1141 {
1142     SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton;
1143     clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
1144     if (clang_type)
1145     {
1146         SymbolFileDWARF *oso_dwarf;
1147 
1148         for (uint32_t oso_idx = 0; ((oso_dwarf = symbol_file_dwarf->GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
1149         {
1150             if (oso_dwarf->HasForwardDeclForClangType (clang_type))
1151             {
1152                 oso_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
1153                 return;
1154             }
1155         }
1156     }
1157 }
1158 
1159 void
1160 SymbolFileDWARFDebugMap::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl)
1161 {
1162     SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton;
1163     clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
1164     if (clang_type)
1165     {
1166         SymbolFileDWARF *oso_dwarf;
1167 
1168         for (uint32_t oso_idx = 0; ((oso_dwarf = symbol_file_dwarf->GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
1169         {
1170             if (oso_dwarf->HasForwardDeclForClangType (clang_type))
1171             {
1172                 oso_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
1173                 return;
1174             }
1175         }
1176     }
1177 }
1178 
1179 bool
1180 SymbolFileDWARFDebugMap::LayoutRecordType (void *baton,
1181                                            const clang::RecordDecl *record_decl,
1182                                            uint64_t &size,
1183                                            uint64_t &alignment,
1184                                            llvm::DenseMap <const clang::FieldDecl *, uint64_t> &field_offsets,
1185                                            llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
1186                                            llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets)
1187 {
1188     SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton;
1189     SymbolFileDWARF *oso_dwarf;
1190     for (uint32_t oso_idx = 0; ((oso_dwarf = symbol_file_dwarf->GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
1191     {
1192         if (oso_dwarf->LayoutRecordType (record_decl, size, alignment, field_offsets, base_offsets, vbase_offsets))
1193             return true;
1194     }
1195     return false;
1196 }
1197 
1198 
1199 
1200 clang::DeclContext*
1201 SymbolFileDWARFDebugMap::GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid)
1202 {
1203     const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
1204     SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
1205     if (oso_dwarf)
1206         return oso_dwarf->GetClangDeclContextContainingTypeUID (type_uid);
1207     return NULL;
1208 }
1209 
1210 clang::DeclContext*
1211 SymbolFileDWARFDebugMap::GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid)
1212 {
1213     const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
1214     SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
1215     if (oso_dwarf)
1216         return oso_dwarf->GetClangDeclContextForTypeUID (sc, type_uid);
1217     return NULL;
1218 }
1219 
1220 
1221