1 //===-- SymbolFileDWARF.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 "SymbolFileDWARF.h"
11 
12 // Other libraries and framework includes
13 #include "llvm/Support/Casting.h"
14 
15 #include "lldb/Core/ArchSpec.h"
16 #include "lldb/Core/Module.h"
17 #include "lldb/Core/ModuleList.h"
18 #include "lldb/Core/ModuleSpec.h"
19 #include "lldb/Core/PluginManager.h"
20 #include "lldb/Core/RegularExpression.h"
21 #include "lldb/Core/Scalar.h"
22 #include "lldb/Core/Section.h"
23 #include "lldb/Core/StreamFile.h"
24 #include "lldb/Core/StreamString.h"
25 #include "lldb/Core/Timer.h"
26 #include "lldb/Core/Value.h"
27 
28 #include "lldb/Expression/ClangModulesDeclVendor.h"
29 
30 #include "lldb/Host/FileSystem.h"
31 #include "lldb/Host/Host.h"
32 
33 #include "lldb/Interpreter/OptionValueFileSpecList.h"
34 #include "lldb/Interpreter/OptionValueProperties.h"
35 
36 #include "lldb/Symbol/Block.h"
37 #include "lldb/Symbol/ClangASTContext.h"
38 #include "lldb/Symbol/CompilerDecl.h"
39 #include "lldb/Symbol/CompilerDeclContext.h"
40 #include "lldb/Symbol/CompileUnit.h"
41 #include "lldb/Symbol/LineTable.h"
42 #include "lldb/Symbol/ObjectFile.h"
43 #include "lldb/Symbol/SymbolVendor.h"
44 #include "lldb/Symbol/TypeSystem.h"
45 #include "lldb/Symbol/VariableList.h"
46 
47 #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
48 #include "Plugins/Language/ObjC/ObjCLanguage.h"
49 
50 #include "lldb/Target/Language.h"
51 
52 #include "DWARFASTParser.h"
53 #include "DWARFCompileUnit.h"
54 #include "DWARFDebugAbbrev.h"
55 #include "DWARFDebugAranges.h"
56 #include "DWARFDebugInfo.h"
57 #include "DWARFDebugLine.h"
58 #include "DWARFDebugPubnames.h"
59 #include "DWARFDebugRanges.h"
60 #include "DWARFDeclContext.h"
61 #include "DWARFDIECollection.h"
62 #include "DWARFFormValue.h"
63 #include "LogChannelDWARF.h"
64 #include "SymbolFileDWARFDwo.h"
65 #include "SymbolFileDWARFDebugMap.h"
66 
67 #include <map>
68 
69 #include <ctype.h>
70 #include <string.h>
71 
72 //#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
73 
74 #ifdef ENABLE_DEBUG_PRINTF
75 #include <stdio.h>
76 #define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
77 #else
78 #define DEBUG_PRINTF(fmt, ...)
79 #endif
80 
81 using namespace lldb;
82 using namespace lldb_private;
83 
84 //static inline bool
85 //child_requires_parent_class_union_or_struct_to_be_completed (dw_tag_t tag)
86 //{
87 //    switch (tag)
88 //    {
89 //    default:
90 //        break;
91 //    case DW_TAG_subprogram:
92 //    case DW_TAG_inlined_subroutine:
93 //    case DW_TAG_class_type:
94 //    case DW_TAG_structure_type:
95 //    case DW_TAG_union_type:
96 //        return true;
97 //    }
98 //    return false;
99 //}
100 //
101 
102 namespace {
103 
104     PropertyDefinition
105     g_properties[] =
106     {
107         { "comp-dir-symlink-paths" , OptionValue::eTypeFileSpecList, true,  0 ,   nullptr, nullptr, "If the DW_AT_comp_dir matches any of these paths the symbolic links will be resolved at DWARF parse time." },
108         {  nullptr                 , OptionValue::eTypeInvalid     , false, 0,    nullptr, nullptr, nullptr }
109     };
110 
111     enum
112     {
113         ePropertySymLinkPaths
114     };
115 
116 
117     class PluginProperties : public Properties
118     {
119     public:
120         static ConstString
121         GetSettingName()
122         {
123             return SymbolFileDWARF::GetPluginNameStatic();
124         }
125 
126         PluginProperties()
127         {
128             m_collection_sp.reset (new OptionValueProperties(GetSettingName()));
129             m_collection_sp->Initialize(g_properties);
130         }
131 
132         FileSpecList&
133         GetSymLinkPaths()
134         {
135             OptionValueFileSpecList *option_value = m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr, true, ePropertySymLinkPaths);
136             assert(option_value);
137             return option_value->GetCurrentValue();
138         }
139 
140     };
141 
142     typedef std::shared_ptr<PluginProperties> SymbolFileDWARFPropertiesSP;
143 
144     static const SymbolFileDWARFPropertiesSP&
145     GetGlobalPluginProperties()
146     {
147         static const auto g_settings_sp(std::make_shared<PluginProperties>());
148         return g_settings_sp;
149     }
150 
151 }  // anonymous namespace end
152 
153 
154 static const char*
155 removeHostnameFromPathname(const char* path_from_dwarf)
156 {
157     if (!path_from_dwarf || !path_from_dwarf[0])
158     {
159         return path_from_dwarf;
160     }
161 
162     const char *colon_pos = strchr(path_from_dwarf, ':');
163     if (nullptr == colon_pos)
164     {
165         return path_from_dwarf;
166     }
167 
168     const char *slash_pos = strchr(path_from_dwarf, '/');
169     if (slash_pos && (slash_pos < colon_pos))
170     {
171         return path_from_dwarf;
172     }
173 
174     // check whether we have a windows path, and so the first character
175     // is a drive-letter not a hostname.
176     if (
177         colon_pos == path_from_dwarf + 1 &&
178         isalpha(*path_from_dwarf) &&
179         strlen(path_from_dwarf) > 2 &&
180         '\\' == path_from_dwarf[2])
181     {
182         return path_from_dwarf;
183     }
184 
185     return colon_pos + 1;
186 }
187 
188 static const char*
189 resolveCompDir(const char* path_from_dwarf)
190 {
191     if (!path_from_dwarf)
192         return nullptr;
193 
194     // DWARF2/3 suggests the form hostname:pathname for compilation directory.
195     // Remove the host part if present.
196     const char* local_path = removeHostnameFromPathname(path_from_dwarf);
197     if (!local_path)
198         return nullptr;
199 
200     bool is_symlink = false;
201     FileSpec local_path_spec(local_path, false);
202     const auto& file_specs = GetGlobalPluginProperties()->GetSymLinkPaths();
203     for (size_t i = 0; i < file_specs.GetSize() && !is_symlink; ++i)
204         is_symlink = FileSpec::Equal(file_specs.GetFileSpecAtIndex(i), local_path_spec, true);
205 
206     if (!is_symlink)
207         return local_path;
208 
209     if (!local_path_spec.IsSymbolicLink())
210         return local_path;
211 
212     FileSpec resolved_local_path_spec;
213     const auto error = FileSystem::Readlink(local_path_spec, resolved_local_path_spec);
214     if (error.Success())
215         return resolved_local_path_spec.GetCString();
216 
217     return nullptr;
218 }
219 
220 
221 void
222 SymbolFileDWARF::Initialize()
223 {
224     LogChannelDWARF::Initialize();
225     PluginManager::RegisterPlugin (GetPluginNameStatic(),
226                                    GetPluginDescriptionStatic(),
227                                    CreateInstance,
228                                    DebuggerInitialize);
229 }
230 
231 void
232 SymbolFileDWARF::DebuggerInitialize(Debugger &debugger)
233 {
234     if (!PluginManager::GetSettingForSymbolFilePlugin(debugger, PluginProperties::GetSettingName()))
235     {
236         const bool is_global_setting = true;
237         PluginManager::CreateSettingForSymbolFilePlugin(debugger,
238                                                         GetGlobalPluginProperties()->GetValueProperties(),
239                                                         ConstString ("Properties for the dwarf symbol-file plug-in."),
240                                                         is_global_setting);
241     }
242 }
243 
244 void
245 SymbolFileDWARF::Terminate()
246 {
247     PluginManager::UnregisterPlugin (CreateInstance);
248     LogChannelDWARF::Initialize();
249 }
250 
251 
252 lldb_private::ConstString
253 SymbolFileDWARF::GetPluginNameStatic()
254 {
255     static ConstString g_name("dwarf");
256     return g_name;
257 }
258 
259 const char *
260 SymbolFileDWARF::GetPluginDescriptionStatic()
261 {
262     return "DWARF and DWARF3 debug symbol file reader.";
263 }
264 
265 
266 SymbolFile*
267 SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
268 {
269     return new SymbolFileDWARF(obj_file);
270 }
271 
272 TypeList *
273 SymbolFileDWARF::GetTypeList ()
274 {
275     if (GetDebugMapSymfile ())
276         return m_debug_map_symfile->GetTypeList();
277     return m_obj_file->GetModule()->GetTypeList();
278 
279 }
280 void
281 SymbolFileDWARF::GetTypes (const DWARFDIE &die,
282                            dw_offset_t min_die_offset,
283                            dw_offset_t max_die_offset,
284                            uint32_t type_mask,
285                            TypeSet &type_set)
286 {
287     if (die)
288     {
289         const dw_offset_t die_offset = die.GetOffset();
290 
291         if (die_offset >= max_die_offset)
292             return;
293 
294         if (die_offset >= min_die_offset)
295         {
296             const dw_tag_t tag = die.Tag();
297 
298             bool add_type = false;
299 
300             switch (tag)
301             {
302                 case DW_TAG_array_type:         add_type = (type_mask & eTypeClassArray         ) != 0; break;
303                 case DW_TAG_unspecified_type:
304                 case DW_TAG_base_type:          add_type = (type_mask & eTypeClassBuiltin       ) != 0; break;
305                 case DW_TAG_class_type:         add_type = (type_mask & eTypeClassClass         ) != 0; break;
306                 case DW_TAG_structure_type:     add_type = (type_mask & eTypeClassStruct        ) != 0; break;
307                 case DW_TAG_union_type:         add_type = (type_mask & eTypeClassUnion         ) != 0; break;
308                 case DW_TAG_enumeration_type:   add_type = (type_mask & eTypeClassEnumeration   ) != 0; break;
309                 case DW_TAG_subroutine_type:
310                 case DW_TAG_subprogram:
311                 case DW_TAG_inlined_subroutine: add_type = (type_mask & eTypeClassFunction      ) != 0; break;
312                 case DW_TAG_pointer_type:       add_type = (type_mask & eTypeClassPointer       ) != 0; break;
313                 case DW_TAG_rvalue_reference_type:
314                 case DW_TAG_reference_type:     add_type = (type_mask & eTypeClassReference     ) != 0; break;
315                 case DW_TAG_typedef:            add_type = (type_mask & eTypeClassTypedef       ) != 0; break;
316                 case DW_TAG_ptr_to_member_type: add_type = (type_mask & eTypeClassMemberPointer ) != 0; break;
317             }
318 
319             if (add_type)
320             {
321                 const bool assert_not_being_parsed = true;
322                 Type *type = ResolveTypeUID (die, assert_not_being_parsed);
323                 if (type)
324                 {
325                     if (type_set.find(type) == type_set.end())
326                         type_set.insert(type);
327                 }
328             }
329         }
330 
331         for (DWARFDIE child_die = die.GetFirstChild();
332              child_die.IsValid();
333              child_die = child_die.GetSibling())
334         {
335             GetTypes (child_die, min_die_offset, max_die_offset, type_mask, type_set);
336         }
337     }
338 }
339 
340 size_t
341 SymbolFileDWARF::GetTypes (SymbolContextScope *sc_scope,
342                            uint32_t type_mask,
343                            TypeList &type_list)
344 
345 {
346     TypeSet type_set;
347 
348     CompileUnit *comp_unit = NULL;
349     DWARFCompileUnit* dwarf_cu = NULL;
350     if (sc_scope)
351         comp_unit = sc_scope->CalculateSymbolContextCompileUnit();
352 
353     if (comp_unit)
354     {
355         dwarf_cu = GetDWARFCompileUnit(comp_unit);
356         if (dwarf_cu == 0)
357             return 0;
358         GetTypes (dwarf_cu->DIE(),
359                   dwarf_cu->GetOffset(),
360                   dwarf_cu->GetNextCompileUnitOffset(),
361                   type_mask,
362                   type_set);
363     }
364     else
365     {
366         DWARFDebugInfo* info = DebugInfo();
367         if (info)
368         {
369             const size_t num_cus = info->GetNumCompileUnits();
370             for (size_t cu_idx=0; cu_idx<num_cus; ++cu_idx)
371             {
372                 dwarf_cu = info->GetCompileUnitAtIndex(cu_idx);
373                 if (dwarf_cu)
374                 {
375                     GetTypes (dwarf_cu->DIE(),
376                               0,
377                               UINT32_MAX,
378                               type_mask,
379                               type_set);
380                 }
381             }
382         }
383     }
384 
385     std::set<CompilerType> clang_type_set;
386     size_t num_types_added = 0;
387     for (Type *type : type_set)
388     {
389         CompilerType clang_type = type->GetForwardCompilerType ();
390         if (clang_type_set.find(clang_type) == clang_type_set.end())
391         {
392             clang_type_set.insert(clang_type);
393             type_list.Insert (type->shared_from_this());
394             ++num_types_added;
395         }
396     }
397     return num_types_added;
398 }
399 
400 
401 //----------------------------------------------------------------------
402 // Gets the first parent that is a lexical block, function or inlined
403 // subroutine, or compile unit.
404 //----------------------------------------------------------------------
405 DWARFDIE
406 SymbolFileDWARF::GetParentSymbolContextDIE(const DWARFDIE &child_die)
407 {
408     DWARFDIE die;
409     for (die = child_die.GetParent(); die; die = die.GetParent())
410     {
411         dw_tag_t tag = die.Tag();
412 
413         switch (tag)
414         {
415         case DW_TAG_compile_unit:
416         case DW_TAG_subprogram:
417         case DW_TAG_inlined_subroutine:
418         case DW_TAG_lexical_block:
419             return die;
420         }
421     }
422     return DWARFDIE();
423 }
424 
425 
426 SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
427     SymbolFile (objfile),
428     UserID (0),  // Used by SymbolFileDWARFDebugMap to when this class parses .o files to contain the .o file index/ID
429     m_debug_map_module_wp (),
430     m_debug_map_symfile (NULL),
431     m_flags(),
432     m_data_debug_abbrev (),
433     m_data_debug_aranges (),
434     m_data_debug_frame (),
435     m_data_debug_info (),
436     m_data_debug_line (),
437     m_data_debug_loc (),
438     m_data_debug_ranges (),
439     m_data_debug_str (),
440     m_data_apple_names (),
441     m_data_apple_types (),
442     m_data_apple_namespaces (),
443     m_abbr(),
444     m_info(),
445     m_line(),
446     m_apple_names_ap (),
447     m_apple_types_ap (),
448     m_apple_namespaces_ap (),
449     m_apple_objc_ap (),
450     m_function_basename_index(),
451     m_function_fullname_index(),
452     m_function_method_index(),
453     m_function_selector_index(),
454     m_objc_class_selectors_index(),
455     m_global_index(),
456     m_type_index(),
457     m_namespace_index(),
458     m_indexed (false),
459     m_using_apple_tables (false),
460     m_fetched_external_modules (false),
461     m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate),
462     m_ranges(),
463     m_unique_ast_type_map ()
464 {
465 }
466 
467 SymbolFileDWARF::~SymbolFileDWARF()
468 {
469 }
470 
471 static const ConstString &
472 GetDWARFMachOSegmentName ()
473 {
474     static ConstString g_dwarf_section_name ("__DWARF");
475     return g_dwarf_section_name;
476 }
477 
478 UniqueDWARFASTTypeMap &
479 SymbolFileDWARF::GetUniqueDWARFASTTypeMap ()
480 {
481     if (GetDebugMapSymfile ())
482         return m_debug_map_symfile->GetUniqueDWARFASTTypeMap ();
483     return m_unique_ast_type_map;
484 }
485 
486 TypeSystem *
487 SymbolFileDWARF::GetTypeSystemForLanguage (LanguageType language)
488 {
489     SymbolFileDWARFDebugMap * debug_map_symfile = GetDebugMapSymfile ();
490     TypeSystem *type_system;
491     if (debug_map_symfile)
492     {
493         type_system = debug_map_symfile->GetTypeSystemForLanguage(language);
494     }
495     else
496     {
497         type_system = m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
498         if (type_system)
499             type_system->SetSymbolFile(this);
500     }
501     return type_system;
502 }
503 
504 void
505 SymbolFileDWARF::InitializeObject()
506 {
507     ModuleSP module_sp (m_obj_file->GetModule());
508     if (module_sp)
509     {
510         const SectionList *section_list = module_sp->GetSectionList();
511 
512         const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
513 
514         // Memory map the DWARF mach-o segment so we have everything mmap'ed
515         // to keep our heap memory usage down.
516         if (section)
517             m_obj_file->MemoryMapSectionData(section, m_dwarf_data);
518     }
519     get_apple_names_data();
520     if (m_data_apple_names.GetByteSize() > 0)
521     {
522         m_apple_names_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_names, get_debug_str_data(), ".apple_names"));
523         if (m_apple_names_ap->IsValid())
524             m_using_apple_tables = true;
525         else
526             m_apple_names_ap.reset();
527     }
528     get_apple_types_data();
529     if (m_data_apple_types.GetByteSize() > 0)
530     {
531         m_apple_types_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_types, get_debug_str_data(), ".apple_types"));
532         if (m_apple_types_ap->IsValid())
533             m_using_apple_tables = true;
534         else
535             m_apple_types_ap.reset();
536     }
537 
538     get_apple_namespaces_data();
539     if (m_data_apple_namespaces.GetByteSize() > 0)
540     {
541         m_apple_namespaces_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_namespaces, get_debug_str_data(), ".apple_namespaces"));
542         if (m_apple_namespaces_ap->IsValid())
543             m_using_apple_tables = true;
544         else
545             m_apple_namespaces_ap.reset();
546     }
547 
548     get_apple_objc_data();
549     if (m_data_apple_objc.GetByteSize() > 0)
550     {
551         m_apple_objc_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_objc, get_debug_str_data(), ".apple_objc"));
552         if (m_apple_objc_ap->IsValid())
553             m_using_apple_tables = true;
554         else
555             m_apple_objc_ap.reset();
556     }
557 }
558 
559 bool
560 SymbolFileDWARF::SupportedVersion(uint16_t version)
561 {
562     return version == 2 || version == 3 || version == 4;
563 }
564 
565 uint32_t
566 SymbolFileDWARF::CalculateAbilities ()
567 {
568     uint32_t abilities = 0;
569     if (m_obj_file != NULL)
570     {
571         const Section* section = NULL;
572         const SectionList *section_list = m_obj_file->GetSectionList();
573         if (section_list == NULL)
574             return 0;
575 
576         uint64_t debug_abbrev_file_size = 0;
577         uint64_t debug_info_file_size = 0;
578         uint64_t debug_line_file_size = 0;
579 
580         section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
581 
582         if (section)
583             section_list = &section->GetChildren ();
584 
585         section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
586         if (section != NULL)
587         {
588             debug_info_file_size = section->GetFileSize();
589 
590             section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
591             if (section)
592                 debug_abbrev_file_size = section->GetFileSize();
593             else
594                 m_flags.Set (flagsGotDebugAbbrevData);
595 
596             section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get();
597             if (!section)
598                 m_flags.Set (flagsGotDebugArangesData);
599 
600             section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get();
601             if (!section)
602                 m_flags.Set (flagsGotDebugFrameData);
603 
604             section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
605             if (section)
606                 debug_line_file_size = section->GetFileSize();
607             else
608                 m_flags.Set (flagsGotDebugLineData);
609 
610             section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get();
611             if (!section)
612                 m_flags.Set (flagsGotDebugLocData);
613 
614             section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get();
615             if (!section)
616                 m_flags.Set (flagsGotDebugMacInfoData);
617 
618             section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get();
619             if (!section)
620                 m_flags.Set (flagsGotDebugPubNamesData);
621 
622             section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get();
623             if (!section)
624                 m_flags.Set (flagsGotDebugPubTypesData);
625 
626             section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get();
627             if (!section)
628                 m_flags.Set (flagsGotDebugRangesData);
629 
630             section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
631             if (!section)
632                 m_flags.Set (flagsGotDebugStrData);
633         }
634         else
635         {
636             const char *symfile_dir_cstr = m_obj_file->GetFileSpec().GetDirectory().GetCString();
637             if (symfile_dir_cstr)
638             {
639                 if (strcasestr(symfile_dir_cstr, ".dsym"))
640                 {
641                     if (m_obj_file->GetType() == ObjectFile::eTypeDebugInfo)
642                     {
643                         // We have a dSYM file that didn't have a any debug info.
644                         // If the string table has a size of 1, then it was made from
645                         // an executable with no debug info, or from an executable that
646                         // was stripped.
647                         section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
648                         if (section && section->GetFileSize() == 1)
649                         {
650                             m_obj_file->GetModule()->ReportWarning ("empty dSYM file detected, dSYM was created with an executable with no debug info.");
651                         }
652                     }
653                 }
654             }
655         }
656 
657         if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
658             abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
659 
660         if (debug_line_file_size > 0)
661             abilities |= LineTables;
662     }
663     return abilities;
664 }
665 
666 const DWARFDataExtractor&
667 SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DWARFDataExtractor &data)
668 {
669     if (m_flags.IsClear (got_flag))
670     {
671         ModuleSP module_sp (m_obj_file->GetModule());
672         m_flags.Set (got_flag);
673         const SectionList *section_list = module_sp->GetSectionList();
674         if (section_list)
675         {
676             SectionSP section_sp (section_list->FindSectionByType(sect_type, true));
677             if (section_sp)
678             {
679                 // See if we memory mapped the DWARF segment?
680                 if (m_dwarf_data.GetByteSize())
681                 {
682                     data.SetData(m_dwarf_data, section_sp->GetOffset (), section_sp->GetFileSize());
683                 }
684                 else
685                 {
686                     if (m_obj_file->ReadSectionData (section_sp.get(), data) == 0)
687                         data.Clear();
688                 }
689             }
690         }
691     }
692     return data;
693 }
694 
695 const DWARFDataExtractor&
696 SymbolFileDWARF::get_debug_abbrev_data()
697 {
698     return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
699 }
700 
701 const DWARFDataExtractor&
702 SymbolFileDWARF::get_debug_addr_data()
703 {
704     return GetCachedSectionData (flagsGotDebugAddrData, eSectionTypeDWARFDebugAddr, m_data_debug_addr);
705 }
706 
707 const DWARFDataExtractor&
708 SymbolFileDWARF::get_debug_aranges_data()
709 {
710     return GetCachedSectionData (flagsGotDebugArangesData, eSectionTypeDWARFDebugAranges, m_data_debug_aranges);
711 }
712 
713 const DWARFDataExtractor&
714 SymbolFileDWARF::get_debug_frame_data()
715 {
716     return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame);
717 }
718 
719 const DWARFDataExtractor&
720 SymbolFileDWARF::get_debug_info_data()
721 {
722     return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info);
723 }
724 
725 const DWARFDataExtractor&
726 SymbolFileDWARF::get_debug_line_data()
727 {
728     return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line);
729 }
730 
731 const DWARFDataExtractor&
732 SymbolFileDWARF::get_debug_loc_data()
733 {
734     return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc);
735 }
736 
737 const DWARFDataExtractor&
738 SymbolFileDWARF::get_debug_ranges_data()
739 {
740     return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
741 }
742 
743 const DWARFDataExtractor&
744 SymbolFileDWARF::get_debug_str_data()
745 {
746     return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str);
747 }
748 
749 const DWARFDataExtractor&
750 SymbolFileDWARF::get_debug_str_offsets_data()
751 {
752     return GetCachedSectionData (flagsGotDebugStrOffsetsData, eSectionTypeDWARFDebugStrOffsets, m_data_debug_str_offsets);
753 }
754 
755 const DWARFDataExtractor&
756 SymbolFileDWARF::get_apple_names_data()
757 {
758     return GetCachedSectionData (flagsGotAppleNamesData, eSectionTypeDWARFAppleNames, m_data_apple_names);
759 }
760 
761 const DWARFDataExtractor&
762 SymbolFileDWARF::get_apple_types_data()
763 {
764     return GetCachedSectionData (flagsGotAppleTypesData, eSectionTypeDWARFAppleTypes, m_data_apple_types);
765 }
766 
767 const DWARFDataExtractor&
768 SymbolFileDWARF::get_apple_namespaces_data()
769 {
770     return GetCachedSectionData (flagsGotAppleNamespacesData, eSectionTypeDWARFAppleNamespaces, m_data_apple_namespaces);
771 }
772 
773 const DWARFDataExtractor&
774 SymbolFileDWARF::get_apple_objc_data()
775 {
776     return GetCachedSectionData (flagsGotAppleObjCData, eSectionTypeDWARFAppleObjC, m_data_apple_objc);
777 }
778 
779 
780 DWARFDebugAbbrev*
781 SymbolFileDWARF::DebugAbbrev()
782 {
783     if (m_abbr.get() == NULL)
784     {
785         const DWARFDataExtractor &debug_abbrev_data = get_debug_abbrev_data();
786         if (debug_abbrev_data.GetByteSize() > 0)
787         {
788             m_abbr.reset(new DWARFDebugAbbrev());
789             if (m_abbr.get())
790                 m_abbr->Parse(debug_abbrev_data);
791         }
792     }
793     return m_abbr.get();
794 }
795 
796 const DWARFDebugAbbrev*
797 SymbolFileDWARF::DebugAbbrev() const
798 {
799     return m_abbr.get();
800 }
801 
802 
803 DWARFDebugInfo*
804 SymbolFileDWARF::DebugInfo()
805 {
806     if (m_info.get() == NULL)
807     {
808         Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p",
809                            __PRETTY_FUNCTION__, static_cast<void*>(this));
810         if (get_debug_info_data().GetByteSize() > 0)
811         {
812             m_info.reset(new DWARFDebugInfo());
813             if (m_info.get())
814             {
815                 m_info->SetDwarfData(this);
816             }
817         }
818     }
819     return m_info.get();
820 }
821 
822 const DWARFDebugInfo*
823 SymbolFileDWARF::DebugInfo() const
824 {
825     return m_info.get();
826 }
827 
828 DWARFCompileUnit*
829 SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit)
830 {
831     if (!comp_unit)
832         return nullptr;
833 
834     DWARFDebugInfo* info = DebugInfo();
835     if (info)
836     {
837         if (GetDebugMapSymfile ())
838         {
839             // The debug map symbol file made the compile units for this DWARF
840             // file which is .o file with DWARF in it, and we should have
841             // only 1 compile unit which is at offset zero in the DWARF.
842             // TODO: modify to support LTO .o files where each .o file might
843             // have multiple DW_TAG_compile_unit tags.
844 
845             DWARFCompileUnit *dwarf_cu = info->GetCompileUnit(0);
846             if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
847                 dwarf_cu->SetUserData(comp_unit);
848             return dwarf_cu;
849         }
850         else
851         {
852             // Just a normal DWARF file whose user ID for the compile unit is
853             // the DWARF offset itself
854 
855             DWARFCompileUnit *dwarf_cu = info->GetCompileUnit((dw_offset_t)comp_unit->GetID());
856             if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
857                 dwarf_cu->SetUserData(comp_unit);
858             return dwarf_cu;
859 
860         }
861     }
862     return NULL;
863 }
864 
865 
866 DWARFDebugRanges*
867 SymbolFileDWARF::DebugRanges()
868 {
869     if (m_ranges.get() == NULL)
870     {
871         Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p",
872                            __PRETTY_FUNCTION__, static_cast<void*>(this));
873         if (get_debug_ranges_data().GetByteSize() > 0)
874         {
875             m_ranges.reset(new DWARFDebugRanges());
876             if (m_ranges.get())
877                 m_ranges->Extract(this);
878         }
879     }
880     return m_ranges.get();
881 }
882 
883 const DWARFDebugRanges*
884 SymbolFileDWARF::DebugRanges() const
885 {
886     return m_ranges.get();
887 }
888 
889 lldb::CompUnitSP
890 SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
891 {
892     CompUnitSP cu_sp;
893     if (dwarf_cu)
894     {
895         CompileUnit *comp_unit = (CompileUnit*)dwarf_cu->GetUserData();
896         if (comp_unit)
897         {
898             // We already parsed this compile unit, had out a shared pointer to it
899             cu_sp = comp_unit->shared_from_this();
900         }
901         else
902         {
903             if (dwarf_cu->GetSymbolFileDWARF() != this)
904             {
905                 return dwarf_cu->GetSymbolFileDWARF()->ParseCompileUnit(dwarf_cu, cu_idx);
906             }
907             else if (GetDebugMapSymfile ())
908             {
909                 // Let the debug map create the compile unit
910                 cu_sp = m_debug_map_symfile->GetCompileUnit(this);
911                 dwarf_cu->SetUserData(cu_sp.get());
912             }
913             else
914             {
915                 ModuleSP module_sp (m_obj_file->GetModule());
916                 if (module_sp)
917                 {
918                     const DWARFDIE cu_die = dwarf_cu->GetCompileUnitDIEOnly ();
919                     if (cu_die)
920                     {
921                         FileSpec cu_file_spec{cu_die.GetName(), false};
922                         if (cu_file_spec)
923                         {
924                             // If we have a full path to the compile unit, we don't need to resolve
925                             // the file.  This can be expensive e.g. when the source files are NFS mounted.
926                             if (cu_file_spec.IsRelative())
927                             {
928                                 const char *cu_comp_dir{cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr)};
929                                 cu_file_spec.PrependPathComponent(resolveCompDir(cu_comp_dir));
930                             }
931 
932                             std::string remapped_file;
933                             if (module_sp->RemapSourceFile(cu_file_spec.GetCString(), remapped_file))
934                                 cu_file_spec.SetFile(remapped_file, false);
935                         }
936 
937                         LanguageType cu_language = DWARFCompileUnit::LanguageTypeFromDWARF(cu_die.GetAttributeValueAsUnsigned(DW_AT_language, 0));
938 
939                         bool is_optimized = dwarf_cu->GetIsOptimized ();
940                         cu_sp.reset(new CompileUnit (module_sp,
941                                                      dwarf_cu,
942                                                      cu_file_spec,
943                                                      dwarf_cu->GetID(),
944                                                      cu_language,
945                                                      is_optimized));
946                         if (cu_sp)
947                         {
948                             // If we just created a compile unit with an invalid file spec, try and get the
949                             // first entry in the supports files from the line table as that should be the
950                             // compile unit.
951                             if (!cu_file_spec)
952                             {
953                                 cu_file_spec = cu_sp->GetSupportFiles().GetFileSpecAtIndex(1);
954                                 if (cu_file_spec)
955                                 {
956                                     (FileSpec &)(*cu_sp) = cu_file_spec;
957                                     // Also fix the invalid file spec which was copied from the compile unit.
958                                     cu_sp->GetSupportFiles().Replace(0, cu_file_spec);
959                                 }
960                             }
961 
962                             dwarf_cu->SetUserData(cu_sp.get());
963 
964                             // Figure out the compile unit index if we weren't given one
965                             if (cu_idx == UINT32_MAX)
966                                 DebugInfo()->GetCompileUnit(dwarf_cu->GetOffset(), &cu_idx);
967 
968                             m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp);
969                         }
970                     }
971                 }
972             }
973         }
974     }
975     return cu_sp;
976 }
977 
978 uint32_t
979 SymbolFileDWARF::GetNumCompileUnits()
980 {
981     DWARFDebugInfo* info = DebugInfo();
982     if (info)
983         return info->GetNumCompileUnits();
984     return 0;
985 }
986 
987 CompUnitSP
988 SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
989 {
990     CompUnitSP cu_sp;
991     DWARFDebugInfo* info = DebugInfo();
992     if (info)
993     {
994         DWARFCompileUnit* dwarf_cu = info->GetCompileUnitAtIndex(cu_idx);
995         if (dwarf_cu)
996             cu_sp = ParseCompileUnit(dwarf_cu, cu_idx);
997     }
998     return cu_sp;
999 }
1000 
1001 Function *
1002 SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, const DWARFDIE &die)
1003 {
1004     if (die.IsValid())
1005     {
1006         TypeSystem *type_system = GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
1007 
1008         if (type_system)
1009         {
1010             DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
1011             if (dwarf_ast)
1012                 return dwarf_ast->ParseFunctionFromDWARF(sc, die);
1013         }
1014     }
1015     return nullptr;
1016 }
1017 
1018 bool
1019 SymbolFileDWARF::FixupAddress (Address &addr)
1020 {
1021     SymbolFileDWARFDebugMap * debug_map_symfile = GetDebugMapSymfile ();
1022     if (debug_map_symfile)
1023     {
1024         return debug_map_symfile->LinkOSOAddress(addr);
1025     }
1026     // This is a normal DWARF file, no address fixups need to happen
1027     return true;
1028 }
1029 lldb::LanguageType
1030 SymbolFileDWARF::ParseCompileUnitLanguage (const SymbolContext& sc)
1031 {
1032     assert (sc.comp_unit);
1033     DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
1034     if (dwarf_cu)
1035         return dwarf_cu->GetLanguageType();
1036     else
1037         return eLanguageTypeUnknown;
1038 }
1039 
1040 size_t
1041 SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
1042 {
1043     assert (sc.comp_unit);
1044     size_t functions_added = 0;
1045     DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
1046     if (dwarf_cu)
1047     {
1048         DWARFDIECollection function_dies;
1049         const size_t num_functions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
1050         size_t func_idx;
1051         for (func_idx = 0; func_idx < num_functions; ++func_idx)
1052         {
1053             DWARFDIE die = function_dies.GetDIEAtIndex(func_idx);
1054             if (sc.comp_unit->FindFunctionByUID (die.GetID()).get() == NULL)
1055             {
1056                 if (ParseCompileUnitFunction(sc, die))
1057                     ++functions_added;
1058             }
1059         }
1060         //FixupTypes();
1061     }
1062     return functions_added;
1063 }
1064 
1065 bool
1066 SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
1067 {
1068     assert (sc.comp_unit);
1069     DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
1070     if (dwarf_cu)
1071     {
1072         const DWARFDIE cu_die = dwarf_cu->GetCompileUnitDIEOnly();
1073 
1074         if (cu_die)
1075         {
1076             const char * cu_comp_dir = resolveCompDir(cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr));
1077 
1078             const dw_offset_t stmt_list = cu_die.GetAttributeValueAsUnsigned(DW_AT_stmt_list, DW_INVALID_OFFSET);
1079 
1080             // All file indexes in DWARF are one based and a file of index zero is
1081             // supposed to be the compile unit itself.
1082             support_files.Append (*sc.comp_unit);
1083 
1084             return DWARFDebugLine::ParseSupportFiles(sc.comp_unit->GetModule(), get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
1085         }
1086     }
1087     return false;
1088 }
1089 
1090 bool
1091 SymbolFileDWARF::ParseImportedModules (const lldb_private::SymbolContext &sc, std::vector<lldb_private::ConstString> &imported_modules)
1092 {
1093     assert (sc.comp_unit);
1094     DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
1095     if (dwarf_cu)
1096     {
1097         if (ClangModulesDeclVendor::LanguageSupportsClangModules(sc.comp_unit->GetLanguage()))
1098         {
1099             UpdateExternalModuleListIfNeeded();
1100             for (const std::pair<uint64_t, const ClangModuleInfo> &external_type_module : m_external_type_modules)
1101             {
1102                 imported_modules.push_back(external_type_module.second.m_name);
1103             }
1104         }
1105     }
1106     return false;
1107 }
1108 
1109 struct ParseDWARFLineTableCallbackInfo
1110 {
1111     LineTable* line_table;
1112     std::unique_ptr<LineSequence> sequence_ap;
1113 };
1114 
1115 //----------------------------------------------------------------------
1116 // ParseStatementTableCallback
1117 //----------------------------------------------------------------------
1118 static void
1119 ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
1120 {
1121     if (state.row == DWARFDebugLine::State::StartParsingLineTable)
1122     {
1123         // Just started parsing the line table
1124     }
1125     else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
1126     {
1127         // Done parsing line table, nothing to do for the cleanup
1128     }
1129     else
1130     {
1131         ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
1132         LineTable* line_table = info->line_table;
1133 
1134         // If this is our first time here, we need to create a
1135         // sequence container.
1136         if (!info->sequence_ap.get())
1137         {
1138             info->sequence_ap.reset(line_table->CreateLineSequenceContainer());
1139             assert(info->sequence_ap.get());
1140         }
1141         line_table->AppendLineEntryToSequence (info->sequence_ap.get(),
1142                                                state.address,
1143                                                state.line,
1144                                                state.column,
1145                                                state.file,
1146                                                state.is_stmt,
1147                                                state.basic_block,
1148                                                state.prologue_end,
1149                                                state.epilogue_begin,
1150                                                state.end_sequence);
1151         if (state.end_sequence)
1152         {
1153             // First, put the current sequence into the line table.
1154             line_table->InsertSequence(info->sequence_ap.get());
1155             // Then, empty it to prepare for the next sequence.
1156             info->sequence_ap->Clear();
1157         }
1158     }
1159 }
1160 
1161 bool
1162 SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
1163 {
1164     assert (sc.comp_unit);
1165     if (sc.comp_unit->GetLineTable() != NULL)
1166         return true;
1167 
1168     DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
1169     if (dwarf_cu)
1170     {
1171         const DWARFDIE dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
1172         if (dwarf_cu_die)
1173         {
1174             const dw_offset_t cu_line_offset = dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_stmt_list, DW_INVALID_OFFSET);
1175             if (cu_line_offset != DW_INVALID_OFFSET)
1176             {
1177                 std::unique_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
1178                 if (line_table_ap.get())
1179                 {
1180                     ParseDWARFLineTableCallbackInfo info;
1181                     info.line_table = line_table_ap.get();
1182                     lldb::offset_t offset = cu_line_offset;
1183                     DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
1184                     if (m_debug_map_symfile)
1185                     {
1186                         // We have an object file that has a line table with addresses
1187                         // that are not linked. We need to link the line table and convert
1188                         // the addresses that are relative to the .o file into addresses
1189                         // for the main executable.
1190                         sc.comp_unit->SetLineTable (m_debug_map_symfile->LinkOSOLineTable (this, line_table_ap.get()));
1191                     }
1192                     else
1193                     {
1194                         sc.comp_unit->SetLineTable(line_table_ap.release());
1195                         return true;
1196                     }
1197                 }
1198             }
1199         }
1200     }
1201     return false;
1202 }
1203 
1204 size_t
1205 SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext& sc,
1206                                       Block *parent_block,
1207                                       const DWARFDIE &orig_die,
1208                                       addr_t subprogram_low_pc,
1209                                       uint32_t depth)
1210 {
1211     size_t blocks_added = 0;
1212     DWARFDIE die = orig_die;
1213     while (die)
1214     {
1215         dw_tag_t tag = die.Tag();
1216 
1217         switch (tag)
1218         {
1219         case DW_TAG_inlined_subroutine:
1220         case DW_TAG_subprogram:
1221         case DW_TAG_lexical_block:
1222             {
1223                 Block *block = NULL;
1224                 if (tag == DW_TAG_subprogram)
1225                 {
1226                     // Skip any DW_TAG_subprogram DIEs that are inside
1227                     // of a normal or inlined functions. These will be
1228                     // parsed on their own as separate entities.
1229 
1230                     if (depth > 0)
1231                         break;
1232 
1233                     block = parent_block;
1234                 }
1235                 else
1236                 {
1237                     BlockSP block_sp(new Block (die.GetID()));
1238                     parent_block->AddChild(block_sp);
1239                     block = block_sp.get();
1240                 }
1241                 DWARFRangeList ranges;
1242                 const char *name = NULL;
1243                 const char *mangled_name = NULL;
1244 
1245                 int decl_file = 0;
1246                 int decl_line = 0;
1247                 int decl_column = 0;
1248                 int call_file = 0;
1249                 int call_line = 0;
1250                 int call_column = 0;
1251                 if (die.GetDIENamesAndRanges (name,
1252                                               mangled_name,
1253                                               ranges,
1254                                               decl_file, decl_line, decl_column,
1255                                               call_file, call_line, call_column, nullptr))
1256                 {
1257                     if (tag == DW_TAG_subprogram)
1258                     {
1259                         assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
1260                         subprogram_low_pc = ranges.GetMinRangeBase(0);
1261                     }
1262                     else if (tag == DW_TAG_inlined_subroutine)
1263                     {
1264                         // We get called here for inlined subroutines in two ways.
1265                         // The first time is when we are making the Function object
1266                         // for this inlined concrete instance.  Since we're creating a top level block at
1267                         // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS.  So we need to
1268                         // adjust the containing address.
1269                         // The second time is when we are parsing the blocks inside the function that contains
1270                         // the inlined concrete instance.  Since these will be blocks inside the containing "real"
1271                         // function the offset will be for that function.
1272                         if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
1273                         {
1274                             subprogram_low_pc = ranges.GetMinRangeBase(0);
1275                         }
1276                     }
1277 
1278                     const size_t num_ranges = ranges.GetSize();
1279                     for (size_t i = 0; i<num_ranges; ++i)
1280                     {
1281                         const DWARFRangeList::Entry &range = ranges.GetEntryRef (i);
1282                         const addr_t range_base = range.GetRangeBase();
1283                         if (range_base >= subprogram_low_pc)
1284                             block->AddRange(Block::Range (range_base - subprogram_low_pc, range.GetByteSize()));
1285                         else
1286                         {
1287                             GetObjectFile()->GetModule()->ReportError ("0x%8.8" PRIx64 ": adding range [0x%" PRIx64 "-0x%" PRIx64 ") which has a base that is less than the function's low PC 0x%" PRIx64 ". Please file a bug and attach the file at the start of this error message",
1288                                                                        block->GetID(),
1289                                                                        range_base,
1290                                                                        range.GetRangeEnd(),
1291                                                                        subprogram_low_pc);
1292                         }
1293                     }
1294                     block->FinalizeRanges ();
1295 
1296                     if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
1297                     {
1298                         std::unique_ptr<Declaration> decl_ap;
1299                         if (decl_file != 0 || decl_line != 0 || decl_column != 0)
1300                             decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
1301                                                           decl_line, decl_column));
1302 
1303                         std::unique_ptr<Declaration> call_ap;
1304                         if (call_file != 0 || call_line != 0 || call_column != 0)
1305                             call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file),
1306                                                           call_line, call_column));
1307 
1308                         block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get());
1309                     }
1310 
1311                     ++blocks_added;
1312 
1313                     if (die.HasChildren())
1314                     {
1315                         blocks_added += ParseFunctionBlocks (sc,
1316                                                              block,
1317                                                              die.GetFirstChild(),
1318                                                              subprogram_low_pc,
1319                                                              depth + 1);
1320                     }
1321                 }
1322             }
1323             break;
1324         default:
1325             break;
1326         }
1327 
1328         // Only parse siblings of the block if we are not at depth zero. A depth
1329         // of zero indicates we are currently parsing the top level
1330         // DW_TAG_subprogram DIE
1331 
1332         if (depth == 0)
1333             die.Clear();
1334         else
1335             die = die.GetSibling();
1336     }
1337     return blocks_added;
1338 }
1339 
1340 bool
1341 SymbolFileDWARF::ClassOrStructIsVirtual (const DWARFDIE &parent_die)
1342 {
1343     if (parent_die)
1344     {
1345         for (DWARFDIE die = parent_die.GetFirstChild(); die; die = die.GetSibling())
1346         {
1347             dw_tag_t tag = die.Tag();
1348             bool check_virtuality = false;
1349             switch (tag)
1350             {
1351                 case DW_TAG_inheritance:
1352                 case DW_TAG_subprogram:
1353                     check_virtuality = true;
1354                     break;
1355                 default:
1356                     break;
1357             }
1358             if (check_virtuality)
1359             {
1360                 if (die.GetAttributeValueAsUnsigned(DW_AT_virtuality, 0) != 0)
1361                     return true;
1362             }
1363         }
1364     }
1365     return false;
1366 }
1367 
1368 void
1369 SymbolFileDWARF::ParseDeclsForContext (CompilerDeclContext decl_ctx)
1370 {
1371     TypeSystem *type_system = decl_ctx.GetTypeSystem();
1372     DWARFASTParser *ast_parser = type_system->GetDWARFParser();
1373     std::vector<DWARFDIE> decl_ctx_die_list = ast_parser->GetDIEForDeclContext(decl_ctx);
1374 
1375     for (DWARFDIE decl_ctx_die : decl_ctx_die_list)
1376         for (DWARFDIE decl = decl_ctx_die.GetFirstChild(); decl; decl = decl.GetSibling())
1377             ast_parser->GetDeclForUIDFromDWARF(decl);
1378 }
1379 
1380 CompilerDecl
1381 SymbolFileDWARF::GetDeclForUID (lldb::user_id_t type_uid)
1382 {
1383     if (UserIDMatches(type_uid))
1384     {
1385         DWARFDebugInfo* debug_info = DebugInfo();
1386         if (debug_info)
1387         {
1388             DWARFDIE die = debug_info->GetDIE(DIERef(type_uid));
1389             if (die)
1390             {
1391                 DWARFASTParser *dwarf_ast = die.GetDWARFParser();
1392                 if (dwarf_ast)
1393                     return dwarf_ast->GetDeclForUIDFromDWARF(die);
1394             }
1395         }
1396     }
1397     return CompilerDecl();
1398 }
1399 
1400 CompilerDeclContext
1401 SymbolFileDWARF::GetDeclContextForUID (lldb::user_id_t type_uid)
1402 {
1403     if (UserIDMatches(type_uid))
1404     {
1405         DWARFDebugInfo* debug_info = DebugInfo();
1406         if (debug_info)
1407         {
1408             DWARFDIE die = debug_info->GetDIE(DIERef(type_uid));
1409             if (die)
1410             {
1411                 DWARFASTParser *dwarf_ast = die.GetDWARFParser();
1412                 if (dwarf_ast)
1413                     return dwarf_ast->GetDeclContextForUIDFromDWARF(die);
1414             }
1415         }
1416     }
1417     return CompilerDeclContext();
1418 }
1419 
1420 CompilerDeclContext
1421 SymbolFileDWARF::GetDeclContextContainingUID (lldb::user_id_t type_uid)
1422 {
1423     if (UserIDMatches(type_uid))
1424     {
1425         DWARFDebugInfo* debug_info = DebugInfo();
1426         if (debug_info)
1427         {
1428             DWARFDIE die = debug_info->GetDIE(DIERef(type_uid));
1429             if (die)
1430             {
1431                 DWARFASTParser *dwarf_ast = die.GetDWARFParser();
1432                 if (dwarf_ast)
1433                     return dwarf_ast->GetDeclContextContainingUIDFromDWARF(die);
1434             }
1435         }
1436     }
1437     return CompilerDeclContext();
1438 }
1439 
1440 
1441 Type*
1442 SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
1443 {
1444     if (UserIDMatches(type_uid))
1445     {
1446         DWARFDebugInfo* debug_info = DebugInfo();
1447         if (debug_info)
1448         {
1449             DWARFDIE type_die = debug_info->GetDIE (DIERef(type_uid));
1450             if (type_die)
1451             {
1452                 const bool assert_not_being_parsed = true;
1453                 return ResolveTypeUID (type_die, assert_not_being_parsed);
1454             }
1455         }
1456     }
1457     return NULL;
1458 }
1459 
1460 Type*
1461 SymbolFileDWARF::ResolveTypeUID (const DWARFDIE &die, bool assert_not_being_parsed)
1462 {
1463     if (die)
1464     {
1465         Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
1466         if (log)
1467             GetObjectFile()->GetModule()->LogMessage (log,
1468                                                       "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s'",
1469                                                       die.GetOffset(),
1470                                                       die.GetTagAsCString(),
1471                                                       die.GetName());
1472 
1473         // We might be coming in in the middle of a type tree (a class
1474         // withing a class, an enum within a class), so parse any needed
1475         // parent DIEs before we get to this one...
1476         DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE (die);
1477         if (decl_ctx_die)
1478         {
1479             if (log)
1480             {
1481                 switch (decl_ctx_die.Tag())
1482                 {
1483                     case DW_TAG_structure_type:
1484                     case DW_TAG_union_type:
1485                     case DW_TAG_class_type:
1486                     {
1487                         // Get the type, which could be a forward declaration
1488                         if (log)
1489                             GetObjectFile()->GetModule()->LogMessage (log,
1490                                                                       "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' resolve parent forward type for 0x%8.8x",
1491                                                                       die.GetOffset(),
1492                                                                       die.GetTagAsCString(),
1493                                                                       die.GetName(),
1494                                                                       decl_ctx_die.GetOffset());
1495                     }
1496                     break;
1497 
1498                     default:
1499                         break;
1500                 }
1501             }
1502         }
1503         return ResolveType (die);
1504     }
1505     return NULL;
1506 }
1507 
1508 // This function is used when SymbolFileDWARFDebugMap owns a bunch of
1509 // SymbolFileDWARF objects to detect if this DWARF file is the one that
1510 // can resolve a clang_type.
1511 bool
1512 SymbolFileDWARF::HasForwardDeclForClangType (const CompilerType &clang_type)
1513 {
1514     CompilerType clang_type_no_qualifiers = ClangASTContext::RemoveFastQualifiers(clang_type);
1515     return GetForwardDeclClangTypeToDie().count (clang_type_no_qualifiers.GetOpaqueQualType());
1516 }
1517 
1518 
1519 bool
1520 SymbolFileDWARF::CompleteType (CompilerType &clang_type)
1521 {
1522     // We have a struct/union/class/enum that needs to be fully resolved.
1523     CompilerType clang_type_no_qualifiers = ClangASTContext::RemoveFastQualifiers(clang_type);
1524     auto die_it = GetForwardDeclClangTypeToDie().find (clang_type_no_qualifiers.GetOpaqueQualType());
1525     if (die_it == GetForwardDeclClangTypeToDie().end())
1526     {
1527         // We have already resolved this type...
1528         return true;
1529     }
1530 
1531     DWARFDebugInfo* debug_info = DebugInfo();
1532     DWARFDIE dwarf_die = debug_info->GetDIE(die_it->getSecond());
1533 
1534     // Once we start resolving this type, remove it from the forward declaration
1535     // map in case anyone child members or other types require this type to get resolved.
1536     // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
1537     // are done.
1538     GetForwardDeclClangTypeToDie().erase (die_it);
1539 
1540     Type *type = GetDIEToType().lookup (dwarf_die.GetDIE());
1541 
1542     Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
1543     if (log)
1544         GetObjectFile()->GetModule()->LogMessageVerboseBacktrace (log,
1545                                                                   "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...",
1546                                                                   dwarf_die.GetID(),
1547                                                                   dwarf_die.GetTagAsCString(),
1548                                                                   type->GetName().AsCString());
1549     assert (clang_type);
1550     DWARFASTParser *dwarf_ast = dwarf_die.GetDWARFParser();
1551     if (dwarf_ast)
1552         return dwarf_ast->CompleteTypeFromDWARF (dwarf_die, type, clang_type);
1553     return false;
1554 }
1555 
1556 Type*
1557 SymbolFileDWARF::ResolveType (const DWARFDIE &die, bool assert_not_being_parsed)
1558 {
1559     if (die)
1560     {
1561         Type *type = GetDIEToType().lookup (die.GetDIE());
1562 
1563         if (type == NULL)
1564             type = GetTypeForDIE (die).get();
1565 
1566         if (assert_not_being_parsed)
1567         {
1568             if (type != DIE_IS_BEING_PARSED)
1569                 return type;
1570 
1571             GetObjectFile()->GetModule()->ReportError ("Parsing a die that is being parsed die: 0x%8.8x: %s %s",
1572                                                        die.GetOffset(),
1573                                                        die.GetTagAsCString(),
1574                                                        die.GetName());
1575 
1576         }
1577         else
1578             return type;
1579     }
1580     return nullptr;
1581 }
1582 
1583 CompileUnit*
1584 SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
1585 {
1586     // Check if the symbol vendor already knows about this compile unit?
1587     if (dwarf_cu->GetUserData() == NULL)
1588     {
1589         // The symbol vendor doesn't know about this compile unit, we
1590         // need to parse and add it to the symbol vendor object.
1591         return ParseCompileUnit(dwarf_cu, cu_idx).get();
1592     }
1593     return (CompileUnit*)dwarf_cu->GetUserData();
1594 }
1595 
1596 size_t
1597 SymbolFileDWARF::GetObjCMethodDIEOffsets (ConstString class_name, DIEArray &method_die_offsets)
1598 {
1599     method_die_offsets.clear();
1600     if (m_using_apple_tables)
1601     {
1602         if (m_apple_objc_ap.get())
1603             m_apple_objc_ap->FindByName(class_name.GetCString(), method_die_offsets);
1604     }
1605     else
1606     {
1607         if (!m_indexed)
1608             Index ();
1609 
1610         m_objc_class_selectors_index.Find (class_name, method_die_offsets);
1611     }
1612     return method_die_offsets.size();
1613 }
1614 
1615 bool
1616 SymbolFileDWARF::GetFunction (const DWARFDIE &die, SymbolContext& sc)
1617 {
1618     sc.Clear(false);
1619 
1620     if (die)
1621     {
1622         // Check if the symbol vendor already knows about this compile unit?
1623         sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
1624 
1625         sc.function = sc.comp_unit->FindFunctionByUID (die.GetID()).get();
1626         if (sc.function == NULL)
1627             sc.function = ParseCompileUnitFunction(sc, die);
1628 
1629         if (sc.function)
1630         {
1631             sc.module_sp = sc.function->CalculateSymbolContextModule();
1632             return true;
1633         }
1634     }
1635 
1636     return false;
1637 }
1638 
1639 void
1640 SymbolFileDWARF::UpdateExternalModuleListIfNeeded()
1641 {
1642     if (m_fetched_external_modules)
1643         return;
1644     m_fetched_external_modules = true;
1645 
1646     DWARFDebugInfo * debug_info = DebugInfo();
1647 
1648     const uint32_t num_compile_units = GetNumCompileUnits();
1649     for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
1650     {
1651         DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
1652 
1653         const DWARFDIE die = dwarf_cu->GetCompileUnitDIEOnly();
1654         if (die && die.HasChildren() == false)
1655         {
1656             const uint64_t name_strp = die.GetAttributeValueAsUnsigned (DW_AT_name, UINT64_MAX);
1657             const uint64_t dwo_path_strp = die.GetAttributeValueAsUnsigned (DW_AT_GNU_dwo_name, UINT64_MAX);
1658 
1659             if (name_strp != UINT64_MAX)
1660             {
1661                 if (m_external_type_modules.find(dwo_path_strp) == m_external_type_modules.end())
1662                 {
1663                     const char *name = get_debug_str_data().PeekCStr(name_strp);
1664                     const char *dwo_path = get_debug_str_data().PeekCStr(dwo_path_strp);
1665                     if (name || dwo_path)
1666                     {
1667                         ModuleSP module_sp;
1668                         if (dwo_path)
1669                         {
1670                             ModuleSpec dwo_module_spec;
1671                             dwo_module_spec.GetFileSpec().SetFile(dwo_path, false);
1672                             dwo_module_spec.GetArchitecture() = m_obj_file->GetModule()->GetArchitecture();
1673                             //printf ("Loading dwo = '%s'\n", dwo_path);
1674                             Error error = ModuleList::GetSharedModule (dwo_module_spec, module_sp, NULL, NULL, NULL);
1675                         }
1676 
1677                         if (dwo_path_strp != LLDB_INVALID_UID)
1678                         {
1679                             m_external_type_modules[dwo_path_strp] = ClangModuleInfo { ConstString(name), module_sp };
1680                         }
1681                         else
1682                         {
1683                             // This hack should be removed promptly once clang emits both.
1684                             m_external_type_modules[name_strp] = ClangModuleInfo { ConstString(name), module_sp };
1685                         }
1686                     }
1687                 }
1688             }
1689         }
1690     }
1691 }
1692 
1693 SymbolFileDWARF::GlobalVariableMap &
1694 SymbolFileDWARF::GetGlobalAranges()
1695 {
1696     if (!m_global_aranges_ap)
1697     {
1698         m_global_aranges_ap.reset (new GlobalVariableMap());
1699 
1700         ModuleSP module_sp = GetObjectFile()->GetModule();
1701         if (module_sp)
1702         {
1703             const size_t num_cus = module_sp->GetNumCompileUnits();
1704             for (size_t i = 0; i < num_cus; ++i)
1705             {
1706                 CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(i);
1707                 if (cu_sp)
1708                 {
1709                     VariableListSP globals_sp = cu_sp->GetVariableList(true);
1710                     if (globals_sp)
1711                     {
1712                         const size_t num_globals = globals_sp->GetSize();
1713                         for (size_t g = 0; g < num_globals; ++g)
1714                         {
1715                             VariableSP var_sp = globals_sp->GetVariableAtIndex(g);
1716                             if (var_sp && !var_sp->GetLocationIsConstantValueData())
1717                             {
1718                                 const DWARFExpression &location = var_sp->LocationExpression();
1719                                 Value location_result;
1720                                 Error error;
1721                                 if (location.Evaluate(NULL, NULL, NULL, LLDB_INVALID_ADDRESS, NULL, location_result, &error))
1722                                 {
1723                                     if (location_result.GetValueType() == Value::eValueTypeFileAddress)
1724                                     {
1725                                         lldb::addr_t file_addr = location_result.GetScalar().ULongLong();
1726                                         lldb::addr_t byte_size = 1;
1727                                         if (var_sp->GetType())
1728                                             byte_size = var_sp->GetType()->GetByteSize();
1729                                         m_global_aranges_ap->Append(GlobalVariableMap::Entry(file_addr, byte_size, var_sp.get()));
1730                                     }
1731                                 }
1732                             }
1733                         }
1734                     }
1735                 }
1736             }
1737         }
1738         m_global_aranges_ap->Sort();
1739     }
1740     return *m_global_aranges_ap;
1741 }
1742 
1743 
1744 uint32_t
1745 SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
1746 {
1747     Timer scoped_timer(__PRETTY_FUNCTION__,
1748                        "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%" PRIx64 " }, resolve_scope = 0x%8.8x)",
1749                        static_cast<void*>(so_addr.GetSection().get()),
1750                        so_addr.GetOffset(), resolve_scope);
1751     uint32_t resolved = 0;
1752     if (resolve_scope & (   eSymbolContextCompUnit  |
1753                             eSymbolContextFunction  |
1754                             eSymbolContextBlock     |
1755                             eSymbolContextLineEntry |
1756                             eSymbolContextVariable  ))
1757     {
1758         lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
1759 
1760         DWARFDebugInfo* debug_info = DebugInfo();
1761         if (debug_info)
1762         {
1763             const dw_offset_t cu_offset = debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr);
1764             if (cu_offset == DW_INVALID_OFFSET)
1765             {
1766                 // Global variables are not in the compile unit address ranges. The only way to
1767                 // currently find global variables is to iterate over the .debug_pubnames or the
1768                 // __apple_names table and find all items in there that point to DW_TAG_variable
1769                 // DIEs and then find the address that matches.
1770                 if (resolve_scope & eSymbolContextVariable)
1771                 {
1772                     GlobalVariableMap &map = GetGlobalAranges();
1773                     const GlobalVariableMap::Entry *entry = map.FindEntryThatContains(file_vm_addr);
1774                     if (entry && entry->data)
1775                     {
1776                         Variable *variable = entry->data;
1777                         SymbolContextScope *scc = variable->GetSymbolContextScope();
1778                         if (scc)
1779                         {
1780                             scc->CalculateSymbolContext(&sc);
1781                             sc.variable = variable;
1782                         }
1783                         return sc.GetResolvedMask();
1784                     }
1785                 }
1786             }
1787             else
1788             {
1789                 uint32_t cu_idx = DW_INVALID_INDEX;
1790                 DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx);
1791                 if (dwarf_cu)
1792                 {
1793                     sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
1794                     if (sc.comp_unit)
1795                     {
1796                         resolved |= eSymbolContextCompUnit;
1797 
1798                         bool force_check_line_table = false;
1799                         if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1800                         {
1801                             DWARFDIE function_die = dwarf_cu->LookupAddress(file_vm_addr);
1802                             DWARFDIE block_die;
1803                             if (function_die)
1804                             {
1805                                 sc.function = sc.comp_unit->FindFunctionByUID (function_die.GetID()).get();
1806                                 if (sc.function == NULL)
1807                                     sc.function = ParseCompileUnitFunction(sc, function_die);
1808 
1809                                 if (sc.function && (resolve_scope & eSymbolContextBlock))
1810                                     block_die = function_die.LookupDeepestBlock(file_vm_addr);
1811                             }
1812                             else
1813                             {
1814                                 // We might have had a compile unit that had discontiguous
1815                                 // address ranges where the gaps are symbols that don't have
1816                                 // any debug info. Discontiguous compile unit address ranges
1817                                 // should only happen when there aren't other functions from
1818                                 // other compile units in these gaps. This helps keep the size
1819                                 // of the aranges down.
1820                                 force_check_line_table = true;
1821                             }
1822 
1823                             if (sc.function != NULL)
1824                             {
1825                                 resolved |= eSymbolContextFunction;
1826 
1827                                 if (resolve_scope & eSymbolContextBlock)
1828                                 {
1829                                     Block& block = sc.function->GetBlock (true);
1830 
1831                                     if (block_die)
1832                                         sc.block = block.FindBlockByID (block_die.GetID());
1833                                     else
1834                                         sc.block = block.FindBlockByID (function_die.GetID());
1835                                     if (sc.block)
1836                                         resolved |= eSymbolContextBlock;
1837                                 }
1838                             }
1839                         }
1840 
1841                         if ((resolve_scope & eSymbolContextLineEntry) || force_check_line_table)
1842                         {
1843                             LineTable *line_table = sc.comp_unit->GetLineTable();
1844                             if (line_table != NULL)
1845                             {
1846                                 // And address that makes it into this function should be in terms
1847                                 // of this debug file if there is no debug map, or it will be an
1848                                 // address in the .o file which needs to be fixed up to be in terms
1849                                 // of the debug map executable. Either way, calling FixupAddress()
1850                                 // will work for us.
1851                                 Address exe_so_addr (so_addr);
1852                                 if (FixupAddress(exe_so_addr))
1853                                 {
1854                                     if (line_table->FindLineEntryByAddress (exe_so_addr, sc.line_entry))
1855                                     {
1856                                         resolved |= eSymbolContextLineEntry;
1857                                     }
1858                                 }
1859                             }
1860                         }
1861 
1862                         if (force_check_line_table && !(resolved & eSymbolContextLineEntry))
1863                         {
1864                             // We might have had a compile unit that had discontiguous
1865                             // address ranges where the gaps are symbols that don't have
1866                             // any debug info. Discontiguous compile unit address ranges
1867                             // should only happen when there aren't other functions from
1868                             // other compile units in these gaps. This helps keep the size
1869                             // of the aranges down.
1870                             sc.comp_unit = NULL;
1871                             resolved &= ~eSymbolContextCompUnit;
1872                         }
1873                     }
1874                     else
1875                     {
1876                         GetObjectFile()->GetModule()->ReportWarning ("0x%8.8x: compile unit %u failed to create a valid lldb_private::CompileUnit class.",
1877                                                                      cu_offset,
1878                                                                      cu_idx);
1879                     }
1880                 }
1881             }
1882         }
1883     }
1884     return resolved;
1885 }
1886 
1887 
1888 
1889 uint32_t
1890 SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
1891 {
1892     const uint32_t prev_size = sc_list.GetSize();
1893     if (resolve_scope & eSymbolContextCompUnit)
1894     {
1895         DWARFDebugInfo* debug_info = DebugInfo();
1896         if (debug_info)
1897         {
1898             uint32_t cu_idx;
1899             DWARFCompileUnit* dwarf_cu = NULL;
1900 
1901             for (cu_idx = 0; (dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
1902             {
1903                 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
1904                 const bool full_match = (bool)file_spec.GetDirectory();
1905                 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Equal(file_spec, *dc_cu, full_match);
1906                 if (check_inlines || file_spec_matches_cu_file_spec)
1907                 {
1908                     SymbolContext sc (m_obj_file->GetModule());
1909                     sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
1910                     if (sc.comp_unit)
1911                     {
1912                         uint32_t file_idx = UINT32_MAX;
1913 
1914                         // If we are looking for inline functions only and we don't
1915                         // find it in the support files, we are done.
1916                         if (check_inlines)
1917                         {
1918                             file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
1919                             if (file_idx == UINT32_MAX)
1920                                 continue;
1921                         }
1922 
1923                         if (line != 0)
1924                         {
1925                             LineTable *line_table = sc.comp_unit->GetLineTable();
1926 
1927                             if (line_table != NULL && line != 0)
1928                             {
1929                                 // We will have already looked up the file index if
1930                                 // we are searching for inline entries.
1931                                 if (!check_inlines)
1932                                     file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
1933 
1934                                 if (file_idx != UINT32_MAX)
1935                                 {
1936                                     uint32_t found_line;
1937                                     uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
1938                                     found_line = sc.line_entry.line;
1939 
1940                                     while (line_idx != UINT32_MAX)
1941                                     {
1942                                         sc.function = NULL;
1943                                         sc.block = NULL;
1944                                         if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1945                                         {
1946                                             const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
1947                                             if (file_vm_addr != LLDB_INVALID_ADDRESS)
1948                                             {
1949                                                 DWARFDIE function_die = dwarf_cu->LookupAddress(file_vm_addr);
1950                                                 DWARFDIE block_die;
1951                                                 if (function_die)
1952                                                 {
1953                                                     sc.function = sc.comp_unit->FindFunctionByUID (function_die.GetID()).get();
1954                                                     if (sc.function == NULL)
1955                                                         sc.function = ParseCompileUnitFunction(sc, function_die);
1956 
1957                                                     if (sc.function && (resolve_scope & eSymbolContextBlock))
1958                                                         block_die = function_die.LookupDeepestBlock(file_vm_addr);
1959                                                 }
1960 
1961                                                 if (sc.function != NULL)
1962                                                 {
1963                                                     Block& block = sc.function->GetBlock (true);
1964 
1965                                                     if (block_die)
1966                                                         sc.block = block.FindBlockByID (block_die.GetID());
1967                                                     else if (function_die)
1968                                                         sc.block = block.FindBlockByID (function_die.GetID());
1969                                                 }
1970                                             }
1971                                         }
1972 
1973                                         sc_list.Append(sc);
1974                                         line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
1975                                     }
1976                                 }
1977                             }
1978                             else if (file_spec_matches_cu_file_spec && !check_inlines)
1979                             {
1980                                 // only append the context if we aren't looking for inline call sites
1981                                 // by file and line and if the file spec matches that of the compile unit
1982                                 sc_list.Append(sc);
1983                             }
1984                         }
1985                         else if (file_spec_matches_cu_file_spec && !check_inlines)
1986                         {
1987                             // only append the context if we aren't looking for inline call sites
1988                             // by file and line and if the file spec matches that of the compile unit
1989                             sc_list.Append(sc);
1990                         }
1991 
1992                         if (!check_inlines)
1993                             break;
1994                     }
1995                 }
1996             }
1997         }
1998     }
1999     return sc_list.GetSize() - prev_size;
2000 }
2001 
2002 void
2003 SymbolFileDWARF::Index ()
2004 {
2005     if (m_indexed)
2006         return;
2007     m_indexed = true;
2008     Timer scoped_timer (__PRETTY_FUNCTION__,
2009                         "SymbolFileDWARF::Index (%s)",
2010                         GetObjectFile()->GetFileSpec().GetFilename().AsCString("<Unknown>"));
2011 
2012     DWARFDebugInfo* debug_info = DebugInfo();
2013     if (debug_info)
2014     {
2015         uint32_t cu_idx = 0;
2016         const uint32_t num_compile_units = GetNumCompileUnits();
2017         for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
2018         {
2019             DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
2020 
2021             bool clear_dies = dwarf_cu->ExtractDIEsIfNeeded (false) > 1;
2022 
2023             dwarf_cu->Index (m_function_basename_index,
2024                              m_function_fullname_index,
2025                              m_function_method_index,
2026                              m_function_selector_index,
2027                              m_objc_class_selectors_index,
2028                              m_global_index,
2029                              m_type_index,
2030                              m_namespace_index);
2031 
2032             // Keep memory down by clearing DIEs if this generate function
2033             // caused them to be parsed
2034             if (clear_dies)
2035                 dwarf_cu->ClearDIEs (true);
2036         }
2037 
2038         m_function_basename_index.Finalize();
2039         m_function_fullname_index.Finalize();
2040         m_function_method_index.Finalize();
2041         m_function_selector_index.Finalize();
2042         m_objc_class_selectors_index.Finalize();
2043         m_global_index.Finalize();
2044         m_type_index.Finalize();
2045         m_namespace_index.Finalize();
2046 
2047 #if defined (ENABLE_DEBUG_PRINTF)
2048         StreamFile s(stdout, false);
2049         s.Printf ("DWARF index for '%s':",
2050                   GetObjectFile()->GetFileSpec().GetPath().c_str());
2051         s.Printf("\nFunction basenames:\n");    m_function_basename_index.Dump (&s);
2052         s.Printf("\nFunction fullnames:\n");    m_function_fullname_index.Dump (&s);
2053         s.Printf("\nFunction methods:\n");      m_function_method_index.Dump (&s);
2054         s.Printf("\nFunction selectors:\n");    m_function_selector_index.Dump (&s);
2055         s.Printf("\nObjective C class selectors:\n");    m_objc_class_selectors_index.Dump (&s);
2056         s.Printf("\nGlobals and statics:\n");   m_global_index.Dump (&s);
2057         s.Printf("\nTypes:\n");                 m_type_index.Dump (&s);
2058         s.Printf("\nNamespaces:\n")             m_namespace_index.Dump (&s);
2059 #endif
2060     }
2061 }
2062 
2063 bool
2064 SymbolFileDWARF::DeclContextMatchesThisSymbolFile (const lldb_private::CompilerDeclContext *decl_ctx)
2065 {
2066     if (decl_ctx == nullptr || !decl_ctx->IsValid())
2067     {
2068         // Invalid namespace decl which means we aren't matching only things
2069         // in this symbol file, so return true to indicate it matches this
2070         // symbol file.
2071         return true;
2072     }
2073 
2074     TypeSystem *decl_ctx_type_system = decl_ctx->GetTypeSystem();
2075     TypeSystem *type_system = GetTypeSystemForLanguage(decl_ctx_type_system->GetMinimumLanguage(nullptr));
2076     if (decl_ctx_type_system == type_system)
2077         return true;    // The type systems match, return true
2078 
2079     // The namespace AST was valid, and it does not match...
2080     Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2081 
2082     if (log)
2083         GetObjectFile()->GetModule()->LogMessage(log, "Valid namespace does not match symbol file");
2084 
2085     return false;
2086 }
2087 
2088 uint32_t
2089 SymbolFileDWARF::FindGlobalVariables (const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, VariableList& variables)
2090 {
2091     Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2092 
2093     if (log)
2094         GetObjectFile()->GetModule()->LogMessage (log,
2095                                                   "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", parent_decl_ctx=%p, append=%u, max_matches=%u, variables)",
2096                                                   name.GetCString(),
2097                                                   static_cast<const void*>(parent_decl_ctx),
2098                                                   append, max_matches);
2099 
2100     if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
2101         return 0;
2102 
2103     DWARFDebugInfo* info = DebugInfo();
2104     if (info == NULL)
2105         return 0;
2106 
2107     // If we aren't appending the results to this list, then clear the list
2108     if (!append)
2109         variables.Clear();
2110 
2111     // Remember how many variables are in the list before we search in case
2112     // we are appending the results to a variable list.
2113     const uint32_t original_size = variables.GetSize();
2114 
2115     DIEArray die_offsets;
2116 
2117     if (m_using_apple_tables)
2118     {
2119         if (m_apple_names_ap.get())
2120         {
2121             const char *name_cstr = name.GetCString();
2122             llvm::StringRef basename;
2123             llvm::StringRef context;
2124 
2125             if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context, basename))
2126                 basename = name_cstr;
2127 
2128             m_apple_names_ap->FindByName (basename.data(), die_offsets);
2129         }
2130     }
2131     else
2132     {
2133         // Index the DWARF if we haven't already
2134         if (!m_indexed)
2135             Index ();
2136 
2137         m_global_index.Find (name, die_offsets);
2138     }
2139 
2140     const size_t num_die_matches = die_offsets.size();
2141     if (num_die_matches)
2142     {
2143         SymbolContext sc;
2144         sc.module_sp = m_obj_file->GetModule();
2145         assert (sc.module_sp);
2146 
2147         DWARFDebugInfo* debug_info = DebugInfo();
2148         bool done = false;
2149         for (size_t i=0; i<num_die_matches && !done; ++i)
2150         {
2151             const DIERef& die_ref = die_offsets[i];
2152             DWARFDIE die = debug_info->GetDIE (die_ref);
2153 
2154             if (die)
2155             {
2156                 switch (die.Tag())
2157                 {
2158                     default:
2159                     case DW_TAG_subprogram:
2160                     case DW_TAG_inlined_subroutine:
2161                     case DW_TAG_try_block:
2162                     case DW_TAG_catch_block:
2163                         break;
2164 
2165                     case DW_TAG_variable:
2166                         {
2167                             sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
2168 
2169                             if (parent_decl_ctx)
2170                             {
2171                                 DWARFASTParser *dwarf_ast = die.GetDWARFParser();
2172                                 if (dwarf_ast)
2173                                 {
2174                                     CompilerDeclContext actual_parent_decl_ctx = dwarf_ast->GetDeclContextContainingUIDFromDWARF (die);
2175                                     if (!actual_parent_decl_ctx || actual_parent_decl_ctx != *parent_decl_ctx)
2176                                         continue;
2177                                 }
2178                             }
2179 
2180                             ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables);
2181 
2182                             if (variables.GetSize() - original_size >= max_matches)
2183                                 done = true;
2184                         }
2185                         break;
2186                 }
2187             }
2188             else
2189             {
2190                 if (m_using_apple_tables)
2191                 {
2192                     GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')\n",
2193                                                                                die_ref.die_offset, name.GetCString());
2194                 }
2195             }
2196         }
2197     }
2198 
2199     // Return the number of variable that were appended to the list
2200     const uint32_t num_matches = variables.GetSize() - original_size;
2201     if (log && num_matches > 0)
2202     {
2203         GetObjectFile()->GetModule()->LogMessage (log,
2204                                                   "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", parent_decl_ctx=%p, append=%u, max_matches=%u, variables) => %u",
2205                                                   name.GetCString(),
2206                                                   static_cast<const void*>(parent_decl_ctx),
2207                                                   append, max_matches,
2208                                                   num_matches);
2209     }
2210     return num_matches;
2211 }
2212 
2213 uint32_t
2214 SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
2215 {
2216     Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2217 
2218     if (log)
2219     {
2220         GetObjectFile()->GetModule()->LogMessage (log,
2221                                                   "SymbolFileDWARF::FindGlobalVariables (regex=\"%s\", append=%u, max_matches=%u, variables)",
2222                                                   regex.GetText(), append,
2223                                                   max_matches);
2224     }
2225 
2226     DWARFDebugInfo* info = DebugInfo();
2227     if (info == NULL)
2228         return 0;
2229 
2230     // If we aren't appending the results to this list, then clear the list
2231     if (!append)
2232         variables.Clear();
2233 
2234     // Remember how many variables are in the list before we search in case
2235     // we are appending the results to a variable list.
2236     const uint32_t original_size = variables.GetSize();
2237 
2238     DIEArray die_offsets;
2239 
2240     if (m_using_apple_tables)
2241     {
2242         if (m_apple_names_ap.get())
2243         {
2244             DWARFMappedHash::DIEInfoArray hash_data_array;
2245             if (m_apple_names_ap->AppendAllDIEsThatMatchingRegex (regex, hash_data_array))
2246                 DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
2247         }
2248     }
2249     else
2250     {
2251         // Index the DWARF if we haven't already
2252         if (!m_indexed)
2253             Index ();
2254 
2255         m_global_index.Find (regex, die_offsets);
2256     }
2257 
2258     SymbolContext sc;
2259     sc.module_sp = m_obj_file->GetModule();
2260     assert (sc.module_sp);
2261 
2262     const size_t num_matches = die_offsets.size();
2263     if (num_matches)
2264     {
2265         DWARFDebugInfo* debug_info = DebugInfo();
2266         for (size_t i=0; i<num_matches; ++i)
2267         {
2268             const DIERef& die_ref = die_offsets[i];
2269             DWARFDIE die = debug_info->GetDIE (die_ref);
2270 
2271             if (die)
2272             {
2273                 sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
2274 
2275                 ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables);
2276 
2277                 if (variables.GetSize() - original_size >= max_matches)
2278                     break;
2279             }
2280             else
2281             {
2282                 if (m_using_apple_tables)
2283                 {
2284                     GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for regex '%s')\n",
2285                                                                                die_ref.die_offset, regex.GetText());
2286                 }
2287             }
2288         }
2289     }
2290 
2291     // Return the number of variable that were appended to the list
2292     return variables.GetSize() - original_size;
2293 }
2294 
2295 
2296 bool
2297 SymbolFileDWARF::ResolveFunction (const DIERef& die_ref,
2298                                   bool include_inlines,
2299                                   SymbolContextList& sc_list)
2300 {
2301     DWARFDIE die = DebugInfo()->GetDIE (die_ref);
2302     return ResolveFunction (die, include_inlines, sc_list);
2303 }
2304 
2305 
2306 bool
2307 SymbolFileDWARF::ResolveFunction (const DWARFDIE &orig_die,
2308                                   bool include_inlines,
2309                                   SymbolContextList& sc_list)
2310 {
2311     SymbolContext sc;
2312 
2313     if (!orig_die)
2314         return false;
2315 
2316     // If we were passed a die that is not a function, just return false...
2317     if (!(orig_die.Tag() == DW_TAG_subprogram || (include_inlines && orig_die.Tag() == DW_TAG_inlined_subroutine)))
2318         return false;
2319 
2320     DWARFDIE die = orig_die;
2321     DWARFDIE inlined_die;
2322     if (die.Tag() == DW_TAG_inlined_subroutine)
2323     {
2324         inlined_die = die;
2325 
2326         while (1)
2327         {
2328             die = die.GetParent();
2329 
2330             if (die)
2331             {
2332                 if (die.Tag() == DW_TAG_subprogram)
2333                     break;
2334             }
2335             else
2336                 break;
2337         }
2338     }
2339     assert (die && die.Tag() == DW_TAG_subprogram);
2340     if (GetFunction (die, sc))
2341     {
2342         Address addr;
2343         // Parse all blocks if needed
2344         if (inlined_die)
2345         {
2346             Block &function_block = sc.function->GetBlock (true);
2347             sc.block = function_block.FindBlockByID (inlined_die.GetID());
2348             if (sc.block == NULL)
2349                 sc.block = function_block.FindBlockByID (inlined_die.GetOffset());
2350             if (sc.block == NULL || sc.block->GetStartAddress (addr) == false)
2351                 addr.Clear();
2352         }
2353         else
2354         {
2355             sc.block = NULL;
2356             addr = sc.function->GetAddressRange().GetBaseAddress();
2357         }
2358 
2359         if (addr.IsValid())
2360         {
2361             sc_list.Append(sc);
2362             return true;
2363         }
2364     }
2365 
2366     return false;
2367 }
2368 
2369 void
2370 SymbolFileDWARF::FindFunctions (const ConstString &name,
2371                                 const NameToDIE &name_to_die,
2372                                 bool include_inlines,
2373                                 SymbolContextList& sc_list)
2374 {
2375     DIEArray die_offsets;
2376     if (name_to_die.Find (name, die_offsets))
2377     {
2378         ParseFunctions (die_offsets, include_inlines, sc_list);
2379     }
2380 }
2381 
2382 
2383 void
2384 SymbolFileDWARF::FindFunctions (const RegularExpression &regex,
2385                                 const NameToDIE &name_to_die,
2386                                 bool include_inlines,
2387                                 SymbolContextList& sc_list)
2388 {
2389     DIEArray die_offsets;
2390     if (name_to_die.Find (regex, die_offsets))
2391     {
2392         ParseFunctions (die_offsets, include_inlines, sc_list);
2393     }
2394 }
2395 
2396 
2397 void
2398 SymbolFileDWARF::FindFunctions (const RegularExpression &regex,
2399                                 const DWARFMappedHash::MemoryTable &memory_table,
2400                                 bool include_inlines,
2401                                 SymbolContextList& sc_list)
2402 {
2403     DIEArray die_offsets;
2404     DWARFMappedHash::DIEInfoArray hash_data_array;
2405     if (memory_table.AppendAllDIEsThatMatchingRegex (regex, hash_data_array))
2406     {
2407         DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
2408         ParseFunctions (die_offsets, include_inlines, sc_list);
2409     }
2410 }
2411 
2412 void
2413 SymbolFileDWARF::ParseFunctions (const DIEArray &die_offsets,
2414                                  bool include_inlines,
2415                                  SymbolContextList& sc_list)
2416 {
2417     const size_t num_matches = die_offsets.size();
2418     if (num_matches)
2419     {
2420         for (size_t i=0; i<num_matches; ++i)
2421             ResolveFunction (die_offsets[i], include_inlines, sc_list);
2422     }
2423 }
2424 
2425 bool
2426 SymbolFileDWARF::DIEInDeclContext (const CompilerDeclContext *decl_ctx,
2427                                    const DWARFDIE &die)
2428 {
2429     // If we have no parent decl context to match this DIE matches, and if the parent
2430     // decl context isn't valid, we aren't trying to look for any particular decl
2431     // context so any die matches.
2432     if (decl_ctx == nullptr || !decl_ctx->IsValid())
2433         return true;
2434 
2435     if (die)
2436     {
2437         DWARFASTParser *dwarf_ast = die.GetDWARFParser();
2438         if (dwarf_ast)
2439         {
2440             CompilerDeclContext actual_decl_ctx = dwarf_ast->GetDeclContextContainingUIDFromDWARF (die);
2441             if (actual_decl_ctx)
2442                 return actual_decl_ctx == *decl_ctx;
2443         }
2444     }
2445     return false;
2446 }
2447 
2448 uint32_t
2449 SymbolFileDWARF::FindFunctions (const ConstString &name,
2450                                 const CompilerDeclContext *parent_decl_ctx,
2451                                 uint32_t name_type_mask,
2452                                 bool include_inlines,
2453                                 bool append,
2454                                 SymbolContextList& sc_list)
2455 {
2456     Timer scoped_timer (__PRETTY_FUNCTION__,
2457                         "SymbolFileDWARF::FindFunctions (name = '%s')",
2458                         name.AsCString());
2459 
2460     // eFunctionNameTypeAuto should be pre-resolved by a call to Module::PrepareForFunctionNameLookup()
2461     assert ((name_type_mask & eFunctionNameTypeAuto) == 0);
2462 
2463     Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2464 
2465     if (log)
2466     {
2467         GetObjectFile()->GetModule()->LogMessage (log,
2468                                                   "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, append=%u, sc_list)",
2469                                                   name.GetCString(),
2470                                                   name_type_mask,
2471                                                   append);
2472     }
2473 
2474     // If we aren't appending the results to this list, then clear the list
2475     if (!append)
2476         sc_list.Clear();
2477 
2478     if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
2479         return 0;
2480 
2481     // If name is empty then we won't find anything.
2482     if (name.IsEmpty())
2483         return 0;
2484 
2485     // Remember how many sc_list are in the list before we search in case
2486     // we are appending the results to a variable list.
2487 
2488     const char *name_cstr = name.GetCString();
2489 
2490     const uint32_t original_size = sc_list.GetSize();
2491 
2492     DWARFDebugInfo* info = DebugInfo();
2493     if (info == NULL)
2494         return 0;
2495 
2496     std::set<const DWARFDebugInfoEntry *> resolved_dies;
2497     if (m_using_apple_tables)
2498     {
2499         if (m_apple_names_ap.get())
2500         {
2501 
2502             DIEArray die_offsets;
2503 
2504             uint32_t num_matches = 0;
2505 
2506             if (name_type_mask & eFunctionNameTypeFull)
2507             {
2508                 // If they asked for the full name, match what they typed.  At some point we may
2509                 // want to canonicalize this (strip double spaces, etc.  For now, we just add all the
2510                 // dies that we find by exact match.
2511                 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
2512                 for (uint32_t i = 0; i < num_matches; i++)
2513                 {
2514                     const DIERef& die_ref = die_offsets[i];
2515                     DWARFDIE die = info->GetDIE (die_ref);
2516                     if (die)
2517                     {
2518                         if (!DIEInDeclContext(parent_decl_ctx, die))
2519                             continue; // The containing decl contexts don't match
2520 
2521                         if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
2522                         {
2523                             if (ResolveFunction (die, include_inlines, sc_list))
2524                                 resolved_dies.insert(die.GetDIE());
2525                         }
2526                     }
2527                     else
2528                     {
2529                         GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
2530                                                                                    die_ref.die_offset, name_cstr);
2531                     }
2532                 }
2533             }
2534 
2535             if (name_type_mask & eFunctionNameTypeSelector)
2536             {
2537                 if (parent_decl_ctx && parent_decl_ctx->IsValid())
2538                     return 0; // no selectors in namespaces
2539 
2540                 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
2541                 // Now make sure these are actually ObjC methods.  In this case we can simply look up the name,
2542                 // and if it is an ObjC method name, we're good.
2543 
2544                 for (uint32_t i = 0; i < num_matches; i++)
2545                 {
2546                     const DIERef& die_ref = die_offsets[i];
2547                     DWARFDIE die = info->GetDIE (die_ref);
2548                     if (die)
2549                     {
2550                         const char *die_name = die.GetName();
2551                         if (ObjCLanguage::IsPossibleObjCMethodName(die_name))
2552                         {
2553                             if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
2554                             {
2555                                 if (ResolveFunction (die, include_inlines, sc_list))
2556                                     resolved_dies.insert(die.GetDIE());
2557                             }
2558                         }
2559                     }
2560                     else
2561                     {
2562                         GetObjectFile()->GetModule()->ReportError ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
2563                                                                    die_ref.die_offset, name_cstr);
2564                     }
2565                 }
2566                 die_offsets.clear();
2567             }
2568 
2569             if (((name_type_mask & eFunctionNameTypeMethod) && !parent_decl_ctx) || name_type_mask & eFunctionNameTypeBase)
2570             {
2571                 // The apple_names table stores just the "base name" of C++ methods in the table.  So we have to
2572                 // extract the base name, look that up, and if there is any other information in the name we were
2573                 // passed in we have to post-filter based on that.
2574 
2575                 // FIXME: Arrange the logic above so that we don't calculate the base name twice:
2576                 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
2577 
2578                 for (uint32_t i = 0; i < num_matches; i++)
2579                 {
2580                     const DIERef& die_ref = die_offsets[i];
2581                     DWARFDIE die = info->GetDIE (die_ref);
2582                     if (die)
2583                     {
2584                         if (!DIEInDeclContext(parent_decl_ctx, die))
2585                             continue; // The containing decl contexts don't match
2586 
2587 
2588                         // If we get to here, the die is good, and we should add it:
2589                         if (resolved_dies.find(die.GetDIE()) == resolved_dies.end() && ResolveFunction (die, include_inlines, sc_list))
2590                         {
2591                             bool keep_die = true;
2592                             if ((name_type_mask & (eFunctionNameTypeBase|eFunctionNameTypeMethod)) != (eFunctionNameTypeBase|eFunctionNameTypeMethod))
2593                             {
2594                                 // We are looking for either basenames or methods, so we need to
2595                                 // trim out the ones we won't want by looking at the type
2596                                 SymbolContext sc;
2597                                 if (sc_list.GetLastContext(sc))
2598                                 {
2599                                     if (sc.block)
2600                                     {
2601                                         // We have an inlined function
2602                                     }
2603                                     else if (sc.function)
2604                                     {
2605                                         Type *type = sc.function->GetType();
2606 
2607                                         if (type)
2608                                         {
2609                                             CompilerDeclContext decl_ctx = GetDeclContextContainingUID (type->GetID());
2610                                             if (decl_ctx.IsStructUnionOrClass())
2611                                             {
2612                                                 if (name_type_mask & eFunctionNameTypeBase)
2613                                                 {
2614                                                     sc_list.RemoveContextAtIndex(sc_list.GetSize()-1);
2615                                                     keep_die = false;
2616                                                 }
2617                                             }
2618                                             else
2619                                             {
2620                                                 if (name_type_mask & eFunctionNameTypeMethod)
2621                                                 {
2622                                                     sc_list.RemoveContextAtIndex(sc_list.GetSize()-1);
2623                                                     keep_die = false;
2624                                                 }
2625                                             }
2626                                         }
2627                                         else
2628                                         {
2629                                             GetObjectFile()->GetModule()->ReportWarning ("function at die offset 0x%8.8x had no function type",
2630                                                                                          die_ref.die_offset);
2631                                         }
2632                                     }
2633                                 }
2634                             }
2635                             if (keep_die)
2636                                 resolved_dies.insert(die.GetDIE());
2637                         }
2638                     }
2639                     else
2640                     {
2641                         GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
2642                                                                                    die_ref.die_offset, name_cstr);
2643                     }
2644                 }
2645                 die_offsets.clear();
2646             }
2647         }
2648     }
2649     else
2650     {
2651 
2652         // Index the DWARF if we haven't already
2653         if (!m_indexed)
2654             Index ();
2655 
2656         if (name_type_mask & eFunctionNameTypeFull)
2657         {
2658             FindFunctions (name, m_function_fullname_index, include_inlines, sc_list);
2659 
2660             // FIXME Temporary workaround for global/anonymous namespace
2661             // functions debugging FreeBSD and Linux binaries.
2662             // If we didn't find any functions in the global namespace try
2663             // looking in the basename index but ignore any returned
2664             // functions that have a namespace but keep functions which
2665             // have an anonymous namespace
2666             // TODO: The arch in the object file isn't correct for MSVC
2667             // binaries on windows, we should find a way to make it
2668             // correct and handle those symbols as well.
2669             if (sc_list.GetSize() == 0)
2670             {
2671                 ArchSpec arch;
2672                 if (!parent_decl_ctx &&
2673                     GetObjectFile()->GetArchitecture(arch) &&
2674                     (arch.GetTriple().isOSFreeBSD() || arch.GetTriple().isOSLinux() ||
2675                      arch.GetMachine() == llvm::Triple::hexagon))
2676                 {
2677                     SymbolContextList temp_sc_list;
2678                     FindFunctions (name, m_function_basename_index, include_inlines, temp_sc_list);
2679                     SymbolContext sc;
2680                     for (uint32_t i = 0; i < temp_sc_list.GetSize(); i++)
2681                     {
2682                         if (temp_sc_list.GetContextAtIndex(i, sc))
2683                         {
2684                             ConstString mangled_name = sc.GetFunctionName(Mangled::ePreferMangled);
2685                             ConstString demangled_name = sc.GetFunctionName(Mangled::ePreferDemangled);
2686                             // Mangled names on Linux and FreeBSD are of the form:
2687                             // _ZN18function_namespace13function_nameEv.
2688                             if (strncmp(mangled_name.GetCString(), "_ZN", 3) ||
2689                                 !strncmp(demangled_name.GetCString(), "(anonymous namespace)", 21))
2690                             {
2691                                 sc_list.Append(sc);
2692                             }
2693                         }
2694                     }
2695                 }
2696             }
2697         }
2698         DIEArray die_offsets;
2699         if (name_type_mask & eFunctionNameTypeBase)
2700         {
2701             uint32_t num_base = m_function_basename_index.Find(name, die_offsets);
2702             for (uint32_t i = 0; i < num_base; i++)
2703             {
2704                 DWARFDIE die = info->GetDIE (die_offsets[i]);
2705                 if (die)
2706                 {
2707                     if (!DIEInDeclContext(parent_decl_ctx, die))
2708                         continue; // The containing decl contexts don't match
2709 
2710                     // If we get to here, the die is good, and we should add it:
2711                     if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
2712                     {
2713                         if (ResolveFunction (die, include_inlines, sc_list))
2714                             resolved_dies.insert(die.GetDIE());
2715                     }
2716                 }
2717             }
2718             die_offsets.clear();
2719         }
2720 
2721         if (name_type_mask & eFunctionNameTypeMethod)
2722         {
2723             if (parent_decl_ctx && parent_decl_ctx->IsValid())
2724                 return 0; // no methods in namespaces
2725 
2726             uint32_t num_base = m_function_method_index.Find(name, die_offsets);
2727             {
2728                 for (uint32_t i = 0; i < num_base; i++)
2729                 {
2730                     DWARFDIE die = info->GetDIE (die_offsets[i]);
2731                     if (die)
2732                     {
2733                         // If we get to here, the die is good, and we should add it:
2734                         if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
2735                         {
2736                             if (ResolveFunction (die, include_inlines, sc_list))
2737                                 resolved_dies.insert(die.GetDIE());
2738                         }
2739                     }
2740                 }
2741             }
2742             die_offsets.clear();
2743         }
2744 
2745         if ((name_type_mask & eFunctionNameTypeSelector) && (!parent_decl_ctx || !parent_decl_ctx->IsValid()))
2746         {
2747             FindFunctions (name, m_function_selector_index, include_inlines, sc_list);
2748         }
2749 
2750     }
2751 
2752     // Return the number of variable that were appended to the list
2753     const uint32_t num_matches = sc_list.GetSize() - original_size;
2754 
2755     if (log && num_matches > 0)
2756     {
2757         GetObjectFile()->GetModule()->LogMessage (log,
2758                                                   "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, include_inlines=%d, append=%u, sc_list) => %u",
2759                                                   name.GetCString(),
2760                                                   name_type_mask,
2761                                                   include_inlines,
2762                                                   append,
2763                                                   num_matches);
2764     }
2765     return num_matches;
2766 }
2767 
2768 uint32_t
2769 SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list)
2770 {
2771     Timer scoped_timer (__PRETTY_FUNCTION__,
2772                         "SymbolFileDWARF::FindFunctions (regex = '%s')",
2773                         regex.GetText());
2774 
2775     Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2776 
2777     if (log)
2778     {
2779         GetObjectFile()->GetModule()->LogMessage (log,
2780                                                   "SymbolFileDWARF::FindFunctions (regex=\"%s\", append=%u, sc_list)",
2781                                                   regex.GetText(),
2782                                                   append);
2783     }
2784 
2785 
2786     // If we aren't appending the results to this list, then clear the list
2787     if (!append)
2788         sc_list.Clear();
2789 
2790     // Remember how many sc_list are in the list before we search in case
2791     // we are appending the results to a variable list.
2792     uint32_t original_size = sc_list.GetSize();
2793 
2794     if (m_using_apple_tables)
2795     {
2796         if (m_apple_names_ap.get())
2797             FindFunctions (regex, *m_apple_names_ap, include_inlines, sc_list);
2798     }
2799     else
2800     {
2801         // Index the DWARF if we haven't already
2802         if (!m_indexed)
2803             Index ();
2804 
2805         FindFunctions (regex, m_function_basename_index, include_inlines, sc_list);
2806 
2807         FindFunctions (regex, m_function_fullname_index, include_inlines, sc_list);
2808     }
2809 
2810     // Return the number of variable that were appended to the list
2811     return sc_list.GetSize() - original_size;
2812 }
2813 
2814 uint32_t
2815 SymbolFileDWARF::FindTypes (const SymbolContext& sc,
2816                             const ConstString &name,
2817                             const CompilerDeclContext *parent_decl_ctx,
2818                             bool append,
2819                             uint32_t max_matches,
2820                             TypeList& types)
2821 {
2822     DWARFDebugInfo* info = DebugInfo();
2823     if (info == NULL)
2824         return 0;
2825 
2826     Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2827 
2828     if (log)
2829     {
2830         if (parent_decl_ctx)
2831             GetObjectFile()->GetModule()->LogMessage (log,
2832                                                       "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = %p (\"%s\"), append=%u, max_matches=%u, type_list)",
2833                                                       name.GetCString(),
2834                                                       static_cast<const void*>(parent_decl_ctx),
2835                                                       parent_decl_ctx->GetName().AsCString("<NULL>"),
2836                                                       append, max_matches);
2837         else
2838             GetObjectFile()->GetModule()->LogMessage (log,
2839                                                       "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = NULL, append=%u, max_matches=%u, type_list)",
2840                                                       name.GetCString(), append,
2841                                                       max_matches);
2842     }
2843 
2844     // If we aren't appending the results to this list, then clear the list
2845     if (!append)
2846         types.Clear();
2847 
2848     if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
2849         return 0;
2850 
2851     DIEArray die_offsets;
2852 
2853     if (m_using_apple_tables)
2854     {
2855         if (m_apple_types_ap.get())
2856         {
2857             const char *name_cstr = name.GetCString();
2858             m_apple_types_ap->FindByName (name_cstr, die_offsets);
2859         }
2860     }
2861     else
2862     {
2863         if (!m_indexed)
2864             Index ();
2865 
2866         m_type_index.Find (name, die_offsets);
2867     }
2868 
2869     const size_t num_die_matches = die_offsets.size();
2870 
2871     if (num_die_matches)
2872     {
2873         const uint32_t initial_types_size = types.GetSize();
2874         DWARFDebugInfo* debug_info = DebugInfo();
2875         for (size_t i=0; i<num_die_matches; ++i)
2876         {
2877             const DIERef& die_ref = die_offsets[i];
2878             DWARFDIE die = debug_info->GetDIE (die_ref);
2879 
2880             if (die)
2881             {
2882                 if (!DIEInDeclContext(parent_decl_ctx, die))
2883                     continue; // The containing decl contexts don't match
2884 
2885                 Type *matching_type = ResolveType (die);
2886                 if (matching_type)
2887                 {
2888                     // We found a type pointer, now find the shared pointer form our type list
2889                     types.InsertUnique (matching_type->shared_from_this());
2890                     if (types.GetSize() >= max_matches)
2891                         break;
2892                 }
2893             }
2894             else
2895             {
2896                 if (m_using_apple_tables)
2897                 {
2898                     GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
2899                                                                                die_ref.die_offset, name.GetCString());
2900                 }
2901             }
2902 
2903         }
2904         const uint32_t num_matches = types.GetSize() - initial_types_size;
2905         if (log && num_matches)
2906         {
2907             if (parent_decl_ctx)
2908             {
2909                 GetObjectFile()->GetModule()->LogMessage (log,
2910                                                           "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = %p (\"%s\"), append=%u, max_matches=%u, type_list) => %u",
2911                                                           name.GetCString(),
2912                                                           static_cast<const void*>(parent_decl_ctx),
2913                                                           parent_decl_ctx->GetName().AsCString("<NULL>"),
2914                                                           append, max_matches,
2915                                                           num_matches);
2916             }
2917             else
2918             {
2919                 GetObjectFile()->GetModule()->LogMessage (log,
2920                                                           "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = NULL, append=%u, max_matches=%u, type_list) => %u",
2921                                                           name.GetCString(),
2922                                                           append, max_matches,
2923                                                           num_matches);
2924             }
2925         }
2926         return num_matches;
2927     }
2928     return 0;
2929 }
2930 
2931 
2932 CompilerDeclContext
2933 SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
2934                                 const ConstString &name,
2935                                 const CompilerDeclContext *parent_decl_ctx)
2936 {
2937     Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2938 
2939     if (log)
2940     {
2941         GetObjectFile()->GetModule()->LogMessage (log,
2942                                                   "SymbolFileDWARF::FindNamespace (sc, name=\"%s\")",
2943                                                   name.GetCString());
2944     }
2945 
2946     CompilerDeclContext namespace_decl_ctx;
2947 
2948     if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
2949         return namespace_decl_ctx;
2950 
2951 
2952     DWARFDebugInfo* info = DebugInfo();
2953     if (info)
2954     {
2955         DIEArray die_offsets;
2956 
2957         // Index if we already haven't to make sure the compile units
2958         // get indexed and make their global DIE index list
2959         if (m_using_apple_tables)
2960         {
2961             if (m_apple_namespaces_ap.get())
2962             {
2963                 const char *name_cstr = name.GetCString();
2964                 m_apple_namespaces_ap->FindByName (name_cstr, die_offsets);
2965             }
2966         }
2967         else
2968         {
2969             if (!m_indexed)
2970                 Index ();
2971 
2972             m_namespace_index.Find (name, die_offsets);
2973         }
2974 
2975         const size_t num_matches = die_offsets.size();
2976         if (num_matches)
2977         {
2978             DWARFDebugInfo* debug_info = DebugInfo();
2979             for (size_t i=0; i<num_matches; ++i)
2980             {
2981                 const DIERef& die_ref = die_offsets[i];
2982                 DWARFDIE die = debug_info->GetDIE (die_ref);
2983 
2984                 if (die)
2985                 {
2986                     if (!DIEInDeclContext (parent_decl_ctx, die))
2987                         continue; // The containing decl contexts don't match
2988 
2989                     DWARFASTParser *dwarf_ast = die.GetDWARFParser();
2990                     if (dwarf_ast)
2991                     {
2992                         namespace_decl_ctx = dwarf_ast->GetDeclContextForUIDFromDWARF (die);
2993                         if (namespace_decl_ctx)
2994                             break;
2995                     }
2996                 }
2997                 else
2998                 {
2999                     if (m_using_apple_tables)
3000                     {
3001                         GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_namespaces accelerator table had bad die 0x%8.8x for '%s')\n",
3002                                                                    die_ref.die_offset, name.GetCString());
3003                     }
3004                 }
3005 
3006             }
3007         }
3008     }
3009     if (log && namespace_decl_ctx)
3010     {
3011         GetObjectFile()->GetModule()->LogMessage (log,
3012                                                   "SymbolFileDWARF::FindNamespace (sc, name=\"%s\") => CompilerDeclContext(%p/%p) \"%s\"",
3013                                                   name.GetCString(),
3014                                                   static_cast<const void*>(namespace_decl_ctx.GetTypeSystem()),
3015                                                   static_cast<const void*>(namespace_decl_ctx.GetOpaqueDeclContext()),
3016                                                   namespace_decl_ctx.GetName().AsCString("<NULL>"));
3017     }
3018 
3019     return namespace_decl_ctx;
3020 }
3021 
3022 TypeSP
3023 SymbolFileDWARF::GetTypeForDIE (const DWARFDIE &die)
3024 {
3025     TypeSP type_sp;
3026     if (die)
3027     {
3028         Type *type_ptr = GetDIEToType().lookup (die.GetDIE());
3029         if (type_ptr == NULL)
3030         {
3031             CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(die.GetCU());
3032             assert (lldb_cu);
3033             SymbolContext sc(lldb_cu);
3034             type_sp = ParseType(sc, die, NULL);
3035         }
3036         else if (type_ptr != DIE_IS_BEING_PARSED)
3037         {
3038             // Grab the existing type from the master types lists
3039             type_sp = type_ptr->shared_from_this();
3040         }
3041 
3042     }
3043     return type_sp;
3044 }
3045 
3046 
3047 DWARFDIE
3048 SymbolFileDWARF::GetDeclContextDIEContainingDIE (const DWARFDIE &orig_die)
3049 {
3050     if (orig_die)
3051     {
3052         DWARFDIE die = orig_die;
3053 
3054         while (die)
3055         {
3056             // If this is the original DIE that we are searching for a declaration
3057             // for, then don't look in the cache as we don't want our own decl
3058             // context to be our decl context...
3059             if (orig_die != die)
3060             {
3061                 switch (die.Tag())
3062                 {
3063                     case DW_TAG_compile_unit:
3064                     case DW_TAG_namespace:
3065                     case DW_TAG_structure_type:
3066                     case DW_TAG_union_type:
3067                     case DW_TAG_class_type:
3068                     case DW_TAG_lexical_block:
3069                     case DW_TAG_subprogram:
3070                         return die;
3071 
3072                     default:
3073                         break;
3074                 }
3075             }
3076 
3077             DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification);
3078             if (spec_die)
3079             {
3080                 DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(spec_die);
3081                 if (decl_ctx_die)
3082                     return decl_ctx_die;
3083             }
3084 
3085             DWARFDIE abs_die = die.GetReferencedDIE(DW_AT_abstract_origin);
3086             if (abs_die)
3087             {
3088                 DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(abs_die);
3089                 if (decl_ctx_die)
3090                     return decl_ctx_die;
3091             }
3092 
3093             die = die.GetParent();
3094         }
3095     }
3096     return DWARFDIE();
3097 }
3098 
3099 
3100 Symbol *
3101 SymbolFileDWARF::GetObjCClassSymbol (const ConstString &objc_class_name)
3102 {
3103     Symbol *objc_class_symbol = NULL;
3104     if (m_obj_file)
3105     {
3106         Symtab *symtab = m_obj_file->GetSymtab ();
3107         if (symtab)
3108         {
3109             objc_class_symbol = symtab->FindFirstSymbolWithNameAndType (objc_class_name,
3110                                                                         eSymbolTypeObjCClass,
3111                                                                         Symtab::eDebugNo,
3112                                                                         Symtab::eVisibilityAny);
3113         }
3114     }
3115     return objc_class_symbol;
3116 }
3117 
3118 // Some compilers don't emit the DW_AT_APPLE_objc_complete_type attribute. If they don't
3119 // then we can end up looking through all class types for a complete type and never find
3120 // the full definition. We need to know if this attribute is supported, so we determine
3121 // this here and cache th result. We also need to worry about the debug map DWARF file
3122 // if we are doing darwin DWARF in .o file debugging.
3123 bool
3124 SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type (DWARFCompileUnit *cu)
3125 {
3126     if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate)
3127     {
3128         m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
3129         if (cu && cu->Supports_DW_AT_APPLE_objc_complete_type())
3130             m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
3131         else
3132         {
3133             DWARFDebugInfo* debug_info = DebugInfo();
3134             const uint32_t num_compile_units = GetNumCompileUnits();
3135             for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
3136             {
3137                 DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
3138                 if (dwarf_cu != cu && dwarf_cu->Supports_DW_AT_APPLE_objc_complete_type())
3139                 {
3140                     m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
3141                     break;
3142                 }
3143             }
3144         }
3145         if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolNo && GetDebugMapSymfile ())
3146             return m_debug_map_symfile->Supports_DW_AT_APPLE_objc_complete_type (this);
3147     }
3148     return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
3149 }
3150 
3151 // This function can be used when a DIE is found that is a forward declaration
3152 // DIE and we want to try and find a type that has the complete definition.
3153 TypeSP
3154 SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE (const DWARFDIE &die,
3155                                                        const ConstString &type_name,
3156                                                        bool must_be_implementation)
3157 {
3158 
3159     TypeSP type_sp;
3160 
3161     if (!type_name || (must_be_implementation && !GetObjCClassSymbol (type_name)))
3162         return type_sp;
3163 
3164     DIEArray die_offsets;
3165 
3166     if (m_using_apple_tables)
3167     {
3168         if (m_apple_types_ap.get())
3169         {
3170             const char *name_cstr = type_name.GetCString();
3171             m_apple_types_ap->FindCompleteObjCClassByName (name_cstr, die_offsets, must_be_implementation);
3172         }
3173     }
3174     else
3175     {
3176         if (!m_indexed)
3177             Index ();
3178 
3179         m_type_index.Find (type_name, die_offsets);
3180     }
3181 
3182     const size_t num_matches = die_offsets.size();
3183 
3184     if (num_matches)
3185     {
3186         DWARFDebugInfo* debug_info = DebugInfo();
3187         for (size_t i=0; i<num_matches; ++i)
3188         {
3189             const DIERef& die_ref = die_offsets[i];
3190             DWARFDIE type_die = debug_info->GetDIE (die_ref);
3191 
3192             if (type_die)
3193             {
3194                 bool try_resolving_type = false;
3195 
3196                 // Don't try and resolve the DIE we are looking for with the DIE itself!
3197                 if (type_die != die)
3198                 {
3199                     switch (type_die.Tag())
3200                     {
3201                         case DW_TAG_class_type:
3202                         case DW_TAG_structure_type:
3203                             try_resolving_type = true;
3204                             break;
3205                         default:
3206                             break;
3207                     }
3208                 }
3209 
3210                 if (try_resolving_type)
3211                 {
3212                     if (must_be_implementation && type_die.Supports_DW_AT_APPLE_objc_complete_type())
3213                         try_resolving_type = type_die.GetAttributeValueAsUnsigned (DW_AT_APPLE_objc_complete_type, 0);
3214 
3215                     if (try_resolving_type)
3216                     {
3217                         Type *resolved_type = ResolveType (type_die, false);
3218                         if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
3219                         {
3220                             DEBUG_PRINTF ("resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64 " (cu 0x%8.8" PRIx64 ")\n",
3221                                           die.GetID(),
3222                                           m_obj_file->GetFileSpec().GetFilename().AsCString("<Unknown>"),
3223                                           type_die.GetID(),
3224                                           type_cu->GetID());
3225 
3226                             if (die)
3227                                 GetDIEToType()[die.GetDIE()] = resolved_type;
3228                             type_sp = resolved_type->shared_from_this();
3229                             break;
3230                         }
3231                     }
3232                 }
3233             }
3234             else
3235             {
3236                 if (m_using_apple_tables)
3237                 {
3238                     GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
3239                                                                die_ref.die_offset, type_name.GetCString());
3240                 }
3241             }
3242 
3243         }
3244     }
3245     return type_sp;
3246 }
3247 
3248 
3249 //----------------------------------------------------------------------
3250 // This function helps to ensure that the declaration contexts match for
3251 // two different DIEs. Often times debug information will refer to a
3252 // forward declaration of a type (the equivalent of "struct my_struct;".
3253 // There will often be a declaration of that type elsewhere that has the
3254 // full definition. When we go looking for the full type "my_struct", we
3255 // will find one or more matches in the accelerator tables and we will
3256 // then need to make sure the type was in the same declaration context
3257 // as the original DIE. This function can efficiently compare two DIEs
3258 // and will return true when the declaration context matches, and false
3259 // when they don't.
3260 //----------------------------------------------------------------------
3261 bool
3262 SymbolFileDWARF::DIEDeclContextsMatch (const DWARFDIE &die1,
3263                                        const DWARFDIE &die2)
3264 {
3265     if (die1 == die2)
3266         return true;
3267 
3268     DWARFDIECollection decl_ctx_1;
3269     DWARFDIECollection decl_ctx_2;
3270     //The declaration DIE stack is a stack of the declaration context
3271     // DIEs all the way back to the compile unit. If a type "T" is
3272     // declared inside a class "B", and class "B" is declared inside
3273     // a class "A" and class "A" is in a namespace "lldb", and the
3274     // namespace is in a compile unit, there will be a stack of DIEs:
3275     //
3276     //   [0] DW_TAG_class_type for "B"
3277     //   [1] DW_TAG_class_type for "A"
3278     //   [2] DW_TAG_namespace  for "lldb"
3279     //   [3] DW_TAG_compile_unit for the source file.
3280     //
3281     // We grab both contexts and make sure that everything matches
3282     // all the way back to the compiler unit.
3283 
3284     // First lets grab the decl contexts for both DIEs
3285     die1.GetDeclContextDIEs (decl_ctx_1);
3286     die2.GetDeclContextDIEs (decl_ctx_2);
3287     // Make sure the context arrays have the same size, otherwise
3288     // we are done
3289     const size_t count1 = decl_ctx_1.Size();
3290     const size_t count2 = decl_ctx_2.Size();
3291     if (count1 != count2)
3292         return false;
3293 
3294     // Make sure the DW_TAG values match all the way back up the
3295     // compile unit. If they don't, then we are done.
3296     DWARFDIE decl_ctx_die1;
3297     DWARFDIE decl_ctx_die2;
3298     size_t i;
3299     for (i=0; i<count1; i++)
3300     {
3301         decl_ctx_die1 = decl_ctx_1.GetDIEAtIndex (i);
3302         decl_ctx_die2 = decl_ctx_2.GetDIEAtIndex (i);
3303         if (decl_ctx_die1.Tag() != decl_ctx_die2.Tag())
3304             return false;
3305     }
3306 #if defined LLDB_CONFIGURATION_DEBUG
3307 
3308     // Make sure the top item in the decl context die array is always
3309     // DW_TAG_compile_unit. If it isn't then something went wrong in
3310     // the DWARFDIE::GetDeclContextDIEs() function...
3311     assert (decl_ctx_1.GetDIEAtIndex (count1 - 1).Tag() == DW_TAG_compile_unit);
3312 
3313 #endif
3314     // Always skip the compile unit when comparing by only iterating up to
3315     // "count - 1". Here we compare the names as we go.
3316     for (i=0; i<count1 - 1; i++)
3317     {
3318         decl_ctx_die1 = decl_ctx_1.GetDIEAtIndex (i);
3319         decl_ctx_die2 = decl_ctx_2.GetDIEAtIndex (i);
3320         const char *name1 = decl_ctx_die1.GetName();
3321         const char *name2 = decl_ctx_die2.GetName();
3322         // If the string was from a DW_FORM_strp, then the pointer will often
3323         // be the same!
3324         if (name1 == name2)
3325             continue;
3326 
3327         // Name pointers are not equal, so only compare the strings
3328         // if both are not NULL.
3329         if (name1 && name2)
3330         {
3331             // If the strings don't compare, we are done...
3332             if (strcmp(name1, name2) != 0)
3333                 return false;
3334         }
3335         else
3336         {
3337             // One name was NULL while the other wasn't
3338             return false;
3339         }
3340     }
3341     // We made it through all of the checks and the declaration contexts
3342     // are equal.
3343     return true;
3344 }
3345 
3346 
3347 TypeSP
3348 SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &dwarf_decl_ctx)
3349 {
3350     TypeSP type_sp;
3351 
3352     const uint32_t dwarf_decl_ctx_count = dwarf_decl_ctx.GetSize();
3353     if (dwarf_decl_ctx_count > 0)
3354     {
3355         const ConstString type_name(dwarf_decl_ctx[0].name);
3356         const dw_tag_t tag = dwarf_decl_ctx[0].tag;
3357 
3358         if (type_name)
3359         {
3360             Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION|DWARF_LOG_LOOKUPS));
3361             if (log)
3362             {
3363                 GetObjectFile()->GetModule()->LogMessage (log,
3364                                                           "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s')",
3365                                                           DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
3366                                                           dwarf_decl_ctx.GetQualifiedName());
3367             }
3368 
3369             DIEArray die_offsets;
3370 
3371             if (m_using_apple_tables)
3372             {
3373                 if (m_apple_types_ap.get())
3374                 {
3375                     const bool has_tag = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeTag);
3376                     const bool has_qualified_name_hash = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeQualNameHash);
3377                     if (has_tag && has_qualified_name_hash)
3378                     {
3379                         const char *qualified_name = dwarf_decl_ctx.GetQualifiedName();
3380                         const uint32_t qualified_name_hash = MappedHash::HashStringUsingDJB (qualified_name);
3381                         if (log)
3382                             GetObjectFile()->GetModule()->LogMessage (log,"FindByNameAndTagAndQualifiedNameHash()");
3383                         m_apple_types_ap->FindByNameAndTagAndQualifiedNameHash (type_name.GetCString(), tag, qualified_name_hash, die_offsets);
3384                     }
3385                     else if (has_tag)
3386                     {
3387                         if (log)
3388                             GetObjectFile()->GetModule()->LogMessage (log,"FindByNameAndTag()");
3389                         m_apple_types_ap->FindByNameAndTag (type_name.GetCString(), tag, die_offsets);
3390                     }
3391                     else
3392                     {
3393                         m_apple_types_ap->FindByName (type_name.GetCString(), die_offsets);
3394                     }
3395                 }
3396             }
3397             else
3398             {
3399                 if (!m_indexed)
3400                     Index ();
3401 
3402                 m_type_index.Find (type_name, die_offsets);
3403             }
3404 
3405             const size_t num_matches = die_offsets.size();
3406 
3407 
3408             if (num_matches)
3409             {
3410                 DWARFDebugInfo* debug_info = DebugInfo();
3411                 for (size_t i=0; i<num_matches; ++i)
3412                 {
3413                     const DIERef& die_ref = die_offsets[i];
3414                     DWARFDIE type_die = debug_info->GetDIE (die_ref);
3415 
3416                     if (type_die)
3417                     {
3418                         bool try_resolving_type = false;
3419 
3420                         // Don't try and resolve the DIE we are looking for with the DIE itself!
3421                         const dw_tag_t type_tag = type_die.Tag();
3422                         // Make sure the tags match
3423                         if (type_tag == tag)
3424                         {
3425                             // The tags match, lets try resolving this type
3426                             try_resolving_type = true;
3427                         }
3428                         else
3429                         {
3430                             // The tags don't match, but we need to watch our for a
3431                             // forward declaration for a struct and ("struct foo")
3432                             // ends up being a class ("class foo { ... };") or
3433                             // vice versa.
3434                             switch (type_tag)
3435                             {
3436                                 case DW_TAG_class_type:
3437                                     // We had a "class foo", see if we ended up with a "struct foo { ... };"
3438                                     try_resolving_type = (tag == DW_TAG_structure_type);
3439                                     break;
3440                                 case DW_TAG_structure_type:
3441                                     // We had a "struct foo", see if we ended up with a "class foo { ... };"
3442                                     try_resolving_type = (tag == DW_TAG_class_type);
3443                                     break;
3444                                 default:
3445                                     // Tags don't match, don't event try to resolve
3446                                     // using this type whose name matches....
3447                                     break;
3448                             }
3449                         }
3450 
3451                         if (try_resolving_type)
3452                         {
3453                             DWARFDeclContext type_dwarf_decl_ctx;
3454                             type_die.GetDWARFDeclContext (type_dwarf_decl_ctx);
3455 
3456                             if (log)
3457                             {
3458                                 GetObjectFile()->GetModule()->LogMessage (log,
3459                                                                           "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') trying die=0x%8.8x (%s)",
3460                                                                           DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
3461                                                                           dwarf_decl_ctx.GetQualifiedName(),
3462                                                                           type_die.GetOffset(),
3463                                                                           type_dwarf_decl_ctx.GetQualifiedName());
3464                             }
3465 
3466                             // Make sure the decl contexts match all the way up
3467                             if (dwarf_decl_ctx == type_dwarf_decl_ctx)
3468                             {
3469                                 Type *resolved_type = ResolveType (type_die, false);
3470                                 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
3471                                 {
3472                                     type_sp = resolved_type->shared_from_this();
3473                                     break;
3474                                 }
3475                             }
3476                         }
3477                         else
3478                         {
3479                             if (log)
3480                             {
3481                                 std::string qualified_name;
3482                                 type_die.GetQualifiedName(qualified_name);
3483                                 GetObjectFile()->GetModule()->LogMessage (log,
3484                                                                           "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') ignoring die=0x%8.8x (%s)",
3485                                                                           DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
3486                                                                           dwarf_decl_ctx.GetQualifiedName(),
3487                                                                           type_die.GetOffset(),
3488                                                                           qualified_name.c_str());
3489                             }
3490                         }
3491                     }
3492                     else
3493                     {
3494                         if (m_using_apple_tables)
3495                         {
3496                             GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
3497                                                                                        die_ref.die_offset, type_name.GetCString());
3498                         }
3499                     }
3500 
3501                 }
3502             }
3503         }
3504     }
3505     return type_sp;
3506 }
3507 
3508 TypeSP
3509 SymbolFileDWARF::ParseType (const SymbolContext& sc, const DWARFDIE &die, bool *type_is_new_ptr)
3510 {
3511     TypeSP type_sp;
3512 
3513     if (die)
3514     {
3515         TypeSystem *type_system = GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
3516 
3517         if (type_system)
3518         {
3519             DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
3520             if (dwarf_ast)
3521             {
3522                 Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
3523                 type_sp = dwarf_ast->ParseTypeFromDWARF (sc, die, log, type_is_new_ptr);
3524                 if (type_sp)
3525                 {
3526                     TypeList* type_list = GetTypeList();
3527                     if (type_list)
3528                         type_list->Insert(type_sp);
3529                 }
3530             }
3531         }
3532     }
3533 
3534     return type_sp;
3535 }
3536 
3537 size_t
3538 SymbolFileDWARF::ParseTypes
3539 (
3540     const SymbolContext& sc,
3541     const DWARFDIE &orig_die,
3542     bool parse_siblings,
3543     bool parse_children
3544 )
3545 {
3546     size_t types_added = 0;
3547     DWARFDIE die = orig_die;
3548     while (die)
3549     {
3550         bool type_is_new = false;
3551         if (ParseType(sc, die, &type_is_new).get())
3552         {
3553             if (type_is_new)
3554                 ++types_added;
3555         }
3556 
3557         if (parse_children && die.HasChildren())
3558         {
3559             if (die.Tag() == DW_TAG_subprogram)
3560             {
3561                 SymbolContext child_sc(sc);
3562                 child_sc.function = sc.comp_unit->FindFunctionByUID(die.GetID()).get();
3563                 types_added += ParseTypes(child_sc, die.GetFirstChild(), true, true);
3564             }
3565             else
3566                 types_added += ParseTypes(sc, die.GetFirstChild(), true, true);
3567         }
3568 
3569         if (parse_siblings)
3570             die = die.GetSibling();
3571         else
3572             die.Clear();
3573     }
3574     return types_added;
3575 }
3576 
3577 
3578 size_t
3579 SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
3580 {
3581     assert(sc.comp_unit && sc.function);
3582     size_t functions_added = 0;
3583     DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
3584     if (dwarf_cu)
3585     {
3586         const dw_offset_t function_die_offset = sc.function->GetID();
3587         DWARFDIE function_die = dwarf_cu->GetDIE (function_die_offset);
3588         if (function_die)
3589         {
3590             ParseFunctionBlocks(sc, &sc.function->GetBlock (false), function_die, LLDB_INVALID_ADDRESS, 0);
3591         }
3592     }
3593 
3594     return functions_added;
3595 }
3596 
3597 
3598 size_t
3599 SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
3600 {
3601     // At least a compile unit must be valid
3602     assert(sc.comp_unit);
3603     size_t types_added = 0;
3604     DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
3605     if (dwarf_cu)
3606     {
3607         if (sc.function)
3608         {
3609             dw_offset_t function_die_offset = sc.function->GetID();
3610             DWARFDIE func_die = dwarf_cu->GetDIE(function_die_offset);
3611             if (func_die && func_die.HasChildren())
3612             {
3613                 types_added = ParseTypes(sc, func_die.GetFirstChild(), true, true);
3614             }
3615         }
3616         else
3617         {
3618             DWARFDIE dwarf_cu_die = dwarf_cu->DIE();
3619             if (dwarf_cu_die && dwarf_cu_die.HasChildren())
3620             {
3621                 types_added = ParseTypes(sc, dwarf_cu_die.GetFirstChild(), true, true);
3622             }
3623         }
3624     }
3625 
3626     return types_added;
3627 }
3628 
3629 size_t
3630 SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
3631 {
3632     if (sc.comp_unit != NULL)
3633     {
3634         DWARFDebugInfo* info = DebugInfo();
3635         if (info == NULL)
3636             return 0;
3637 
3638         if (sc.function)
3639         {
3640             DWARFDIE function_die = info->GetDIE(DIERef(sc.function->GetID()));
3641 
3642             const dw_addr_t func_lo_pc = function_die.GetAttributeValueAsAddress (DW_AT_low_pc, LLDB_INVALID_ADDRESS);
3643             if (func_lo_pc != LLDB_INVALID_ADDRESS)
3644             {
3645                 const size_t num_variables = ParseVariables(sc, function_die.GetFirstChild(), func_lo_pc, true, true);
3646 
3647                 // Let all blocks know they have parse all their variables
3648                 sc.function->GetBlock (false).SetDidParseVariables (true, true);
3649                 return num_variables;
3650             }
3651         }
3652         else if (sc.comp_unit)
3653         {
3654             DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID());
3655 
3656             if (dwarf_cu == NULL)
3657                 return 0;
3658 
3659             uint32_t vars_added = 0;
3660             VariableListSP variables (sc.comp_unit->GetVariableList(false));
3661 
3662             if (variables.get() == NULL)
3663             {
3664                 variables.reset(new VariableList());
3665                 sc.comp_unit->SetVariableList(variables);
3666 
3667                 DIEArray die_offsets;
3668                 if (m_using_apple_tables)
3669                 {
3670                     if (m_apple_names_ap.get())
3671                     {
3672                         DWARFMappedHash::DIEInfoArray hash_data_array;
3673                         if (m_apple_names_ap->AppendAllDIEsInRange (dwarf_cu->GetOffset(),
3674                                                                     dwarf_cu->GetNextCompileUnitOffset(),
3675                                                                     hash_data_array))
3676                         {
3677                             DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
3678                         }
3679                     }
3680                 }
3681                 else
3682                 {
3683                     // Index if we already haven't to make sure the compile units
3684                     // get indexed and make their global DIE index list
3685                     if (!m_indexed)
3686                         Index ();
3687 
3688                     m_global_index.FindAllEntriesForCompileUnit (dwarf_cu->GetOffset(),
3689                                                                  die_offsets);
3690                 }
3691 
3692                 const size_t num_matches = die_offsets.size();
3693                 if (num_matches)
3694                 {
3695                     DWARFDebugInfo* debug_info = DebugInfo();
3696                     for (size_t i=0; i<num_matches; ++i)
3697                     {
3698                         const DIERef& die_ref = die_offsets[i];
3699                         DWARFDIE die = debug_info->GetDIE (die_ref);
3700                         if (die)
3701                         {
3702                             VariableSP var_sp (ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS));
3703                             if (var_sp)
3704                             {
3705                                 variables->AddVariableIfUnique (var_sp);
3706                                 ++vars_added;
3707                             }
3708                         }
3709                         else
3710                         {
3711                             if (m_using_apple_tables)
3712                             {
3713                                 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x)\n", die_ref.die_offset);
3714                             }
3715                         }
3716 
3717                     }
3718                 }
3719             }
3720             return vars_added;
3721         }
3722     }
3723     return 0;
3724 }
3725 
3726 VariableSP
3727 SymbolFileDWARF::ParseVariableDIE
3728 (
3729     const SymbolContext& sc,
3730     const DWARFDIE &die,
3731     const lldb::addr_t func_low_pc
3732 )
3733 {
3734     if (die.GetDWARF() != this)
3735         return die.GetDWARF()->ParseVariableDIE(sc, die, func_low_pc);
3736 
3737     VariableSP var_sp;
3738     if (!die)
3739         return var_sp;
3740 
3741     var_sp = GetDIEToVariable()[die.GetDIE()];
3742     if (var_sp)
3743         return var_sp;  // Already been parsed!
3744 
3745     const dw_tag_t tag = die.Tag();
3746     ModuleSP module = GetObjectFile()->GetModule();
3747 
3748     if ((tag == DW_TAG_variable) ||
3749         (tag == DW_TAG_constant) ||
3750         (tag == DW_TAG_formal_parameter && sc.function))
3751     {
3752         DWARFAttributes attributes;
3753         const size_t num_attributes = die.GetAttributes(attributes);
3754         DWARFDIE spec_die;
3755         if (num_attributes > 0)
3756         {
3757             const char *name = NULL;
3758             const char *mangled = NULL;
3759             Declaration decl;
3760             uint32_t i;
3761             DWARFFormValue type_die_form;
3762             DWARFExpression location(die.GetCU());
3763             bool is_external = false;
3764             bool is_artificial = false;
3765             bool location_is_const_value_data = false;
3766             bool has_explicit_location = false;
3767             DWARFFormValue const_value;
3768             //AccessType accessibility = eAccessNone;
3769 
3770             for (i=0; i<num_attributes; ++i)
3771             {
3772                 dw_attr_t attr = attributes.AttributeAtIndex(i);
3773                 DWARFFormValue form_value;
3774 
3775                 if (attributes.ExtractFormValueAtIndex(i, form_value))
3776                 {
3777                     switch (attr)
3778                     {
3779                     case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3780                     case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
3781                     case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3782                     case DW_AT_name:        name = form_value.AsCString(); break;
3783                     case DW_AT_linkage_name:
3784                     case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(); break;
3785                     case DW_AT_type:        type_die_form = form_value; break;
3786                     case DW_AT_external:    is_external = form_value.Boolean(); break;
3787                     case DW_AT_const_value:
3788                         // If we have already found a DW_AT_location attribute, ignore this attribute.
3789                         if (!has_explicit_location)
3790                         {
3791                             location_is_const_value_data = true;
3792                             // The constant value will be either a block, a data value or a string.
3793                             const DWARFDataExtractor& debug_info_data = get_debug_info_data();
3794                             if (DWARFFormValue::IsBlockForm(form_value.Form()))
3795                             {
3796                                 // Retrieve the value as a block expression.
3797                                 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
3798                                 uint32_t block_length = form_value.Unsigned();
3799                                 location.CopyOpcodeData(module, debug_info_data, block_offset, block_length);
3800                             }
3801                             else if (DWARFFormValue::IsDataForm(form_value.Form()))
3802                             {
3803                                 // Retrieve the value as a data expression.
3804                                 DWARFFormValue::FixedFormSizes fixed_form_sizes =
3805                                     DWARFFormValue::GetFixedFormSizesForAddressSize (
3806                                             attributes.CompileUnitAtIndex(i)->GetAddressByteSize(),
3807                                             attributes.CompileUnitAtIndex(i)->IsDWARF64());
3808                                 uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
3809                                 uint32_t data_length = fixed_form_sizes.GetSize(form_value.Form());
3810                                 if (data_length == 0)
3811                                 {
3812                                     const uint8_t *data_pointer = form_value.BlockData();
3813                                     if (data_pointer)
3814                                     {
3815                                         form_value.Unsigned();
3816                                     }
3817                                     else if (DWARFFormValue::IsDataForm(form_value.Form()))
3818                                     {
3819                                         // we need to get the byte size of the type later after we create the variable
3820                                         const_value = form_value;
3821                                     }
3822                                 }
3823                                 else
3824                                     location.CopyOpcodeData(module, debug_info_data, data_offset, data_length);
3825                             }
3826                             else
3827                             {
3828                                 // Retrieve the value as a string expression.
3829                                 if (form_value.Form() == DW_FORM_strp)
3830                                 {
3831                                     DWARFFormValue::FixedFormSizes fixed_form_sizes =
3832                                         DWARFFormValue::GetFixedFormSizesForAddressSize (
3833                                                 attributes.CompileUnitAtIndex(i)->GetAddressByteSize(),
3834                                                 attributes.CompileUnitAtIndex(i)->IsDWARF64());
3835                                     uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
3836                                     uint32_t data_length = fixed_form_sizes.GetSize(form_value.Form());
3837                                     location.CopyOpcodeData(module, debug_info_data, data_offset, data_length);
3838                                 }
3839                                 else
3840                                 {
3841                                     const char *str = form_value.AsCString();
3842                                     uint32_t string_offset = str - (const char *)debug_info_data.GetDataStart();
3843                                     uint32_t string_length = strlen(str) + 1;
3844                                     location.CopyOpcodeData(module, debug_info_data, string_offset, string_length);
3845                                 }
3846                             }
3847                         }
3848                         break;
3849                     case DW_AT_location:
3850                         {
3851                             location_is_const_value_data = false;
3852                             has_explicit_location = true;
3853                             if (form_value.BlockData())
3854                             {
3855                                 const DWARFDataExtractor& debug_info_data = get_debug_info_data();
3856 
3857                                 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
3858                                 uint32_t block_length = form_value.Unsigned();
3859                                 location.CopyOpcodeData(module, get_debug_info_data(), block_offset, block_length);
3860                             }
3861                             else
3862                             {
3863                                 const DWARFDataExtractor& debug_loc_data = get_debug_loc_data();
3864                                 const dw_offset_t debug_loc_offset = form_value.Unsigned();
3865 
3866                                 size_t loc_list_length = DWARFExpression::LocationListSize(die.GetCU(), debug_loc_data, debug_loc_offset);
3867                                 if (loc_list_length > 0)
3868                                 {
3869                                     location.CopyOpcodeData(module, debug_loc_data, debug_loc_offset, loc_list_length);
3870                                     assert (func_low_pc != LLDB_INVALID_ADDRESS);
3871                                     location.SetLocationListSlide (func_low_pc - attributes.CompileUnitAtIndex(i)->GetBaseAddress());
3872                                 }
3873                             }
3874                         }
3875                         break;
3876                     case DW_AT_specification:
3877                     {
3878                         DWARFDebugInfo* debug_info = DebugInfo();
3879                         if (debug_info)
3880                             spec_die = debug_info->GetDIE(DIERef(form_value));
3881                         break;
3882                     }
3883                     case DW_AT_artificial:      is_artificial = form_value.Boolean(); break;
3884                     case DW_AT_accessibility:   break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
3885                     case DW_AT_declaration:
3886                     case DW_AT_description:
3887                     case DW_AT_endianity:
3888                     case DW_AT_segment:
3889                     case DW_AT_start_scope:
3890                     case DW_AT_visibility:
3891                     default:
3892                     case DW_AT_abstract_origin:
3893                     case DW_AT_sibling:
3894                         break;
3895                     }
3896                 }
3897             }
3898 
3899             const DWARFDIE parent_context_die = GetDeclContextDIEContainingDIE(die);
3900             const dw_tag_t parent_tag = die.GetParent().Tag();
3901             bool is_static_member = parent_tag == DW_TAG_compile_unit && (parent_context_die.Tag() == DW_TAG_class_type || parent_context_die.Tag() == DW_TAG_structure_type);
3902 
3903             ValueType scope = eValueTypeInvalid;
3904 
3905             const DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die);
3906             SymbolContextScope * symbol_context_scope = NULL;
3907 
3908             if (!mangled)
3909             {
3910                 // LLDB relies on the mangled name (DW_TAG_linkage_name or DW_AT_MIPS_linkage_name) to
3911                 // generate fully qualified names of global variables with commands like "frame var j".
3912                 // For example, if j were an int variable holding a value 4 and declared in a namespace
3913                 // B which in turn is contained in a namespace A, the command "frame var j" returns
3914                 // "(int) A::B::j = 4". If the compiler does not emit a linkage name, we should be able
3915                 // to generate a fully qualified name from the declaration context.
3916                 if (parent_tag == DW_TAG_compile_unit &&
3917                     Language::LanguageIsCPlusPlus(die.GetLanguage()))
3918                 {
3919                     DWARFDeclContext decl_ctx;
3920 
3921                     die.GetDWARFDeclContext(decl_ctx);
3922                     mangled = decl_ctx.GetQualifiedNameAsConstString().GetCString();
3923                 }
3924             }
3925 
3926             // DWARF doesn't specify if a DW_TAG_variable is a local, global
3927             // or static variable, so we have to do a little digging by
3928             // looking at the location of a variable to see if it contains
3929             // a DW_OP_addr opcode _somewhere_ in the definition. I say
3930             // somewhere because clang likes to combine small global variables
3931             // into the same symbol and have locations like:
3932             // DW_OP_addr(0x1000), DW_OP_constu(2), DW_OP_plus
3933             // So if we don't have a DW_TAG_formal_parameter, we can look at
3934             // the location to see if it contains a DW_OP_addr opcode, and
3935             // then we can correctly classify  our variables.
3936             if (tag == DW_TAG_formal_parameter)
3937                 scope = eValueTypeVariableArgument;
3938             else
3939             {
3940                 bool op_error = false;
3941                 // Check if the location has a DW_OP_addr with any address value...
3942                 lldb::addr_t location_DW_OP_addr = LLDB_INVALID_ADDRESS;
3943                 if (!location_is_const_value_data)
3944                 {
3945                     location_DW_OP_addr = location.GetLocation_DW_OP_addr (0, op_error);
3946                     if (op_error)
3947                     {
3948                         StreamString strm;
3949                         location.DumpLocationForAddress (&strm, eDescriptionLevelFull, 0, 0, NULL);
3950                         GetObjectFile()->GetModule()->ReportError ("0x%8.8x: %s has an invalid location: %s", die.GetOffset(), die.GetTagAsCString(), strm.GetString().c_str());
3951                     }
3952                 }
3953 
3954                 if (location_DW_OP_addr != LLDB_INVALID_ADDRESS)
3955                 {
3956                     if (is_external)
3957                         scope = eValueTypeVariableGlobal;
3958                     else
3959                         scope = eValueTypeVariableStatic;
3960 
3961 
3962                     SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile ();
3963 
3964                     if (debug_map_symfile)
3965                     {
3966                         // When leaving the DWARF in the .o files on darwin,
3967                         // when we have a global variable that wasn't initialized,
3968                         // the .o file might not have allocated a virtual
3969                         // address for the global variable. In this case it will
3970                         // have created a symbol for the global variable
3971                         // that is undefined/data and external and the value will
3972                         // be the byte size of the variable. When we do the
3973                         // address map in SymbolFileDWARFDebugMap we rely on
3974                         // having an address, we need to do some magic here
3975                         // so we can get the correct address for our global
3976                         // variable. The address for all of these entries
3977                         // will be zero, and there will be an undefined symbol
3978                         // in this object file, and the executable will have
3979                         // a matching symbol with a good address. So here we
3980                         // dig up the correct address and replace it in the
3981                         // location for the variable, and set the variable's
3982                         // symbol context scope to be that of the main executable
3983                         // so the file address will resolve correctly.
3984                         bool linked_oso_file_addr = false;
3985                         if (is_external && location_DW_OP_addr == 0)
3986                         {
3987                             // we have a possible uninitialized extern global
3988                             ConstString const_name(mangled ? mangled : name);
3989                             ObjectFile *debug_map_objfile = debug_map_symfile->GetObjectFile();
3990                             if (debug_map_objfile)
3991                             {
3992                                 Symtab *debug_map_symtab = debug_map_objfile->GetSymtab();
3993                                 if (debug_map_symtab)
3994                                 {
3995                                     Symbol *exe_symbol = debug_map_symtab->FindFirstSymbolWithNameAndType (const_name,
3996                                                                                                            eSymbolTypeData,
3997                                                                                                            Symtab::eDebugYes,
3998                                                                                                            Symtab::eVisibilityExtern);
3999                                     if (exe_symbol)
4000                                     {
4001                                         if (exe_symbol->ValueIsAddress())
4002                                         {
4003                                             const addr_t exe_file_addr = exe_symbol->GetAddressRef().GetFileAddress();
4004                                             if (exe_file_addr != LLDB_INVALID_ADDRESS)
4005                                             {
4006                                                 if (location.Update_DW_OP_addr (exe_file_addr))
4007                                                 {
4008                                                     linked_oso_file_addr = true;
4009                                                     symbol_context_scope = exe_symbol;
4010                                                 }
4011                                             }
4012                                         }
4013                                     }
4014                                 }
4015                             }
4016                         }
4017 
4018                         if (!linked_oso_file_addr)
4019                         {
4020                             // The DW_OP_addr is not zero, but it contains a .o file address which
4021                             // needs to be linked up correctly.
4022                             const lldb::addr_t exe_file_addr = debug_map_symfile->LinkOSOFileAddress(this, location_DW_OP_addr);
4023                             if (exe_file_addr != LLDB_INVALID_ADDRESS)
4024                             {
4025                                 // Update the file address for this variable
4026                                 location.Update_DW_OP_addr (exe_file_addr);
4027                             }
4028                             else
4029                             {
4030                                 // Variable didn't make it into the final executable
4031                                 return var_sp;
4032                             }
4033                         }
4034                     }
4035                 }
4036                 else
4037                 {
4038                     scope = eValueTypeVariableLocal;
4039                 }
4040             }
4041 
4042             if (symbol_context_scope == NULL)
4043             {
4044                 switch (parent_tag)
4045                 {
4046                 case DW_TAG_subprogram:
4047                 case DW_TAG_inlined_subroutine:
4048                 case DW_TAG_lexical_block:
4049                     if (sc.function)
4050                     {
4051                         symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
4052                         if (symbol_context_scope == NULL)
4053                             symbol_context_scope = sc.function;
4054                     }
4055                     break;
4056 
4057                 default:
4058                     symbol_context_scope = sc.comp_unit;
4059                     break;
4060                 }
4061             }
4062 
4063             if (symbol_context_scope)
4064             {
4065                 SymbolFileTypeSP type_sp(new SymbolFileType(*this, DIERef(type_die_form).GetUID()));
4066 
4067                 if (const_value.Form() && type_sp && type_sp->GetType())
4068                     location.CopyOpcodeData(const_value.Unsigned(), type_sp->GetType()->GetByteSize(), die.GetCU()->GetAddressByteSize());
4069 
4070                 var_sp.reset (new Variable (die.GetID(),
4071                                             name,
4072                                             mangled,
4073                                             type_sp,
4074                                             scope,
4075                                             symbol_context_scope,
4076                                             &decl,
4077                                             location,
4078                                             is_external,
4079                                             is_artificial,
4080                                             is_static_member));
4081 
4082                 var_sp->SetLocationIsConstantValueData (location_is_const_value_data);
4083             }
4084             else
4085             {
4086                 // Not ready to parse this variable yet. It might be a global
4087                 // or static variable that is in a function scope and the function
4088                 // in the symbol context wasn't filled in yet
4089                 return var_sp;
4090             }
4091         }
4092         // Cache var_sp even if NULL (the variable was just a specification or
4093         // was missing vital information to be able to be displayed in the debugger
4094         // (missing location due to optimization, etc)) so we don't re-parse
4095         // this DIE over and over later...
4096         GetDIEToVariable()[die.GetDIE()] = var_sp;
4097         if (spec_die)
4098             GetDIEToVariable()[spec_die.GetDIE()] = var_sp;
4099     }
4100     return var_sp;
4101 }
4102 
4103 
4104 DWARFDIE
4105 SymbolFileDWARF::FindBlockContainingSpecification (const DIERef& func_die_ref,
4106                                                    dw_offset_t spec_block_die_offset)
4107 {
4108     // Give the concrete function die specified by "func_die_offset", find the
4109     // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
4110     // to "spec_block_die_offset"
4111     return FindBlockContainingSpecification (DebugInfo()->GetDIE (func_die_ref), spec_block_die_offset);
4112 }
4113 
4114 
4115 DWARFDIE
4116 SymbolFileDWARF::FindBlockContainingSpecification(const DWARFDIE &die,
4117                                                   dw_offset_t spec_block_die_offset)
4118 {
4119     if (die)
4120     {
4121         switch (die.Tag())
4122         {
4123         case DW_TAG_subprogram:
4124         case DW_TAG_inlined_subroutine:
4125         case DW_TAG_lexical_block:
4126             {
4127                 if (die.GetAttributeValueAsReference (DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset)
4128                     return die;
4129 
4130                 if (die.GetAttributeValueAsReference (DW_AT_abstract_origin, DW_INVALID_OFFSET) == spec_block_die_offset)
4131                     return die;
4132             }
4133             break;
4134         }
4135 
4136         // Give the concrete function die specified by "func_die_offset", find the
4137         // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
4138         // to "spec_block_die_offset"
4139         for (DWARFDIE child_die = die.GetFirstChild(); child_die; child_die = child_die.GetSibling())
4140         {
4141             DWARFDIE result_die = FindBlockContainingSpecification (child_die, spec_block_die_offset);
4142             if (result_die)
4143                 return result_die;
4144         }
4145     }
4146 
4147     return DWARFDIE();
4148 }
4149 
4150 size_t
4151 SymbolFileDWARF::ParseVariables (const SymbolContext& sc,
4152                                  const DWARFDIE &orig_die,
4153                                  const lldb::addr_t func_low_pc,
4154                                  bool parse_siblings,
4155                                  bool parse_children,
4156                                  VariableList* cc_variable_list)
4157 {
4158     if (!orig_die)
4159         return 0;
4160 
4161     VariableListSP variable_list_sp;
4162 
4163     size_t vars_added = 0;
4164     DWARFDIE die = orig_die;
4165     while (die)
4166     {
4167         dw_tag_t tag = die.Tag();
4168 
4169         // Check to see if we have already parsed this variable or constant?
4170         VariableSP var_sp = GetDIEToVariable()[die.GetDIE()];
4171         if (var_sp)
4172         {
4173             if (cc_variable_list)
4174                 cc_variable_list->AddVariableIfUnique (var_sp);
4175         }
4176         else
4177         {
4178             // We haven't already parsed it, lets do that now.
4179             if ((tag == DW_TAG_variable) ||
4180                 (tag == DW_TAG_constant) ||
4181                 (tag == DW_TAG_formal_parameter && sc.function))
4182             {
4183                 if (variable_list_sp.get() == NULL)
4184                 {
4185                     DWARFDIE sc_parent_die = GetParentSymbolContextDIE(orig_die);
4186                     dw_tag_t parent_tag = sc_parent_die.Tag();
4187                     switch (parent_tag)
4188                     {
4189                         case DW_TAG_compile_unit:
4190                             if (sc.comp_unit != NULL)
4191                             {
4192                                 variable_list_sp = sc.comp_unit->GetVariableList(false);
4193                                 if (variable_list_sp.get() == NULL)
4194                                 {
4195                                     variable_list_sp.reset(new VariableList());
4196                                     sc.comp_unit->SetVariableList(variable_list_sp);
4197                                 }
4198                             }
4199                             else
4200                             {
4201                                 GetObjectFile()->GetModule()->ReportError ("parent 0x%8.8" PRIx64 " %s with no valid compile unit in symbol context for 0x%8.8" PRIx64 " %s.\n",
4202                                                                            sc_parent_die.GetID(),
4203                                                                            sc_parent_die.GetTagAsCString(),
4204                                                                            orig_die.GetID(),
4205                                                                            orig_die.GetTagAsCString());
4206                             }
4207                             break;
4208 
4209                         case DW_TAG_subprogram:
4210                         case DW_TAG_inlined_subroutine:
4211                         case DW_TAG_lexical_block:
4212                             if (sc.function != NULL)
4213                             {
4214                                 // Check to see if we already have parsed the variables for the given scope
4215 
4216                                 Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
4217                                 if (block == NULL)
4218                                 {
4219                                     // This must be a specification or abstract origin with
4220                                     // a concrete block counterpart in the current function. We need
4221                                     // to find the concrete block so we can correctly add the
4222                                     // variable to it
4223                                     const DWARFDIE concrete_block_die = FindBlockContainingSpecification (DIERef(sc.function->GetID()),
4224                                                                                                           sc_parent_die.GetOffset());
4225                                     if (concrete_block_die)
4226                                         block = sc.function->GetBlock(true).FindBlockByID(concrete_block_die.GetID());
4227                                 }
4228 
4229                                 if (block != NULL)
4230                                 {
4231                                     const bool can_create = false;
4232                                     variable_list_sp = block->GetBlockVariableList (can_create);
4233                                     if (variable_list_sp.get() == NULL)
4234                                     {
4235                                         variable_list_sp.reset(new VariableList());
4236                                         block->SetVariableList(variable_list_sp);
4237                                     }
4238                                 }
4239                             }
4240                             break;
4241 
4242                         default:
4243                              GetObjectFile()->GetModule()->ReportError ("didn't find appropriate parent DIE for variable list for 0x%8.8" PRIx64 " %s.\n",
4244                                                                         orig_die.GetID(),
4245                                                                         orig_die.GetTagAsCString());
4246                             break;
4247                     }
4248                 }
4249 
4250                 if (variable_list_sp)
4251                 {
4252                     VariableSP var_sp (ParseVariableDIE(sc, die, func_low_pc));
4253                     if (var_sp)
4254                     {
4255                         variable_list_sp->AddVariableIfUnique (var_sp);
4256                         if (cc_variable_list)
4257                             cc_variable_list->AddVariableIfUnique (var_sp);
4258                         ++vars_added;
4259                     }
4260                 }
4261             }
4262         }
4263 
4264         bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
4265 
4266         if (!skip_children && parse_children && die.HasChildren())
4267         {
4268             vars_added += ParseVariables(sc, die.GetFirstChild(), func_low_pc, true, true, cc_variable_list);
4269         }
4270 
4271         if (parse_siblings)
4272             die = die.GetSibling();
4273         else
4274             die.Clear();
4275     }
4276     return vars_added;
4277 }
4278 
4279 //------------------------------------------------------------------
4280 // PluginInterface protocol
4281 //------------------------------------------------------------------
4282 ConstString
4283 SymbolFileDWARF::GetPluginName()
4284 {
4285     return GetPluginNameStatic();
4286 }
4287 
4288 uint32_t
4289 SymbolFileDWARF::GetPluginVersion()
4290 {
4291     return 1;
4292 }
4293 
4294 void
4295 SymbolFileDWARF::DumpIndexes ()
4296 {
4297     StreamFile s(stdout, false);
4298 
4299     s.Printf ("DWARF index for (%s) '%s':",
4300               GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(),
4301               GetObjectFile()->GetFileSpec().GetPath().c_str());
4302     s.Printf("\nFunction basenames:\n");    m_function_basename_index.Dump (&s);
4303     s.Printf("\nFunction fullnames:\n");    m_function_fullname_index.Dump (&s);
4304     s.Printf("\nFunction methods:\n");      m_function_method_index.Dump (&s);
4305     s.Printf("\nFunction selectors:\n");    m_function_selector_index.Dump (&s);
4306     s.Printf("\nObjective C class selectors:\n");    m_objc_class_selectors_index.Dump (&s);
4307     s.Printf("\nGlobals and statics:\n");   m_global_index.Dump (&s);
4308     s.Printf("\nTypes:\n");                 m_type_index.Dump (&s);
4309     s.Printf("\nNamespaces:\n");            m_namespace_index.Dump (&s);
4310 }
4311 
4312 
4313 SymbolFileDWARFDebugMap *
4314 SymbolFileDWARF::GetDebugMapSymfile ()
4315 {
4316     if (m_debug_map_symfile == NULL && !m_debug_map_module_wp.expired())
4317     {
4318         lldb::ModuleSP module_sp (m_debug_map_module_wp.lock());
4319         if (module_sp)
4320         {
4321             SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
4322             if (sym_vendor)
4323                 m_debug_map_symfile = (SymbolFileDWARFDebugMap *)sym_vendor->GetSymbolFile();
4324         }
4325     }
4326     return m_debug_map_symfile;
4327 }
4328 
4329 DWARFExpression::LocationListFormat
4330 SymbolFileDWARF::GetLocationListFormat() const
4331 {
4332     return DWARFExpression::RegularLocationList;
4333 }
4334