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