blob: 7637e43658d60f55459f7c6ffaf24d3f55dc2439 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- 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 "clang/AST/ASTConsumer.h"
14#include "clang/AST/ASTContext.h"
15#include "clang/AST/Decl.h"
16#include "clang/AST/DeclGroup.h"
Jim Inghame3ae82a2011-11-12 01:36:43 +000017#include "clang/AST/DeclObjC.h"
Greg Clayton3c2e3ae2012-02-06 06:42:51 +000018#include "clang/AST/DeclTemplate.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019#include "clang/Basic/Builtins.h"
20#include "clang/Basic/IdentifierTable.h"
21#include "clang/Basic/LangOptions.h"
22#include "clang/Basic/SourceManager.h"
23#include "clang/Basic/TargetInfo.h"
24#include "clang/Basic/Specifiers.h"
Greg Clayton7fedea22010-11-16 02:10:54 +000025#include "clang/Sema/DeclSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026
Sean Callanancc427fa2011-07-30 02:42:06 +000027#include "llvm/Support/Casting.h"
28
Robert Flackeb83fab2015-05-15 18:59:59 +000029#include "lldb/Core/ArchSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000030#include "lldb/Core/Module.h"
Sean Callananf0c5aeb2015-04-20 16:31:29 +000031#include "lldb/Core/ModuleList.h"
32#include "lldb/Core/ModuleSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000033#include "lldb/Core/PluginManager.h"
34#include "lldb/Core/RegularExpression.h"
35#include "lldb/Core/Scalar.h"
36#include "lldb/Core/Section.h"
Greg Claytonc685f8e2010-09-15 04:15:46 +000037#include "lldb/Core/StreamFile.h"
Jim Ingham318c9f22011-08-26 19:44:13 +000038#include "lldb/Core/StreamString.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039#include "lldb/Core/Timer.h"
40#include "lldb/Core/Value.h"
41
Sean Callananf0c5aeb2015-04-20 16:31:29 +000042#include "lldb/Expression/ClangModulesDeclVendor.h"
43
Oleksiy Vyalov5d9c50b2015-07-21 02:09:42 +000044#include "lldb/Host/FileSystem.h"
Greg Clayton20568dd2011-10-13 23:13:20 +000045#include "lldb/Host/Host.h"
46
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +000047#include "lldb/Interpreter/OptionValueFileSpecList.h"
48#include "lldb/Interpreter/OptionValueProperties.h"
49
Chris Lattner30fdc8d2010-06-08 16:52:24 +000050#include "lldb/Symbol/Block.h"
51#include "lldb/Symbol/CompileUnit.h"
52#include "lldb/Symbol/LineTable.h"
53#include "lldb/Symbol/ObjectFile.h"
54#include "lldb/Symbol/SymbolVendor.h"
55#include "lldb/Symbol/VariableList.h"
56
Jim Inghamaa816b82015-09-02 01:59:14 +000057#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
58#include "Plugins/Language/ObjC/ObjCLanguage.h"
Jim Inghamb7f6b2f2011-09-08 22:13:49 +000059
Jim Ingham0e0984e2015-09-02 01:06:46 +000060#include "lldb/Target/Language.h"
61
Greg Clayton261ac3f2015-08-28 01:01:03 +000062#include "DWARFASTParser.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000063#include "DWARFCompileUnit.h"
64#include "DWARFDebugAbbrev.h"
65#include "DWARFDebugAranges.h"
66#include "DWARFDebugInfo.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000067#include "DWARFDebugLine.h"
68#include "DWARFDebugPubnames.h"
69#include "DWARFDebugRanges.h"
Greg Claytona8022fa2012-04-24 21:22:41 +000070#include "DWARFDeclContext.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000071#include "DWARFDIECollection.h"
72#include "DWARFFormValue.h"
73#include "DWARFLocationList.h"
74#include "LogChannelDWARF.h"
Greg Clayton450e3f32010-10-12 02:24:53 +000075#include "SymbolFileDWARFDebugMap.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000076
77#include <map>
78
Matthew Gardinere81df3b2014-08-26 06:57:23 +000079#include <ctype.h>
80#include <string.h>
81
Greg Clayton62742b12010-11-11 01:09:45 +000082//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
Greg Claytonc93237c2010-10-01 20:48:32 +000083
84#ifdef ENABLE_DEBUG_PRINTF
85#include <stdio.h>
Ed Mastea0191d12013-10-17 20:42:56 +000086#define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
Greg Claytonc93237c2010-10-01 20:48:32 +000087#else
88#define DEBUG_PRINTF(fmt, ...)
89#endif
90
Chris Lattner30fdc8d2010-06-08 16:52:24 +000091using namespace lldb;
92using namespace lldb_private;
93
Greg Clayton219cf312012-03-30 00:51:13 +000094//static inline bool
95//child_requires_parent_class_union_or_struct_to_be_completed (dw_tag_t tag)
96//{
97// switch (tag)
98// {
99// default:
100// break;
101// case DW_TAG_subprogram:
102// case DW_TAG_inlined_subroutine:
103// case DW_TAG_class_type:
104// case DW_TAG_structure_type:
105// case DW_TAG_union_type:
106// return true;
107// }
108// return false;
109//}
110//
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +0000111
112namespace {
113
114 PropertyDefinition
115 g_properties[] =
116 {
117 { "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." },
118 { nullptr , OptionValue::eTypeInvalid , false, 0, nullptr, nullptr, nullptr }
119 };
120
121 enum
122 {
123 ePropertySymLinkPaths
124 };
125
126
127 class PluginProperties : public Properties
128 {
129 public:
130 static ConstString
131 GetSettingName()
132 {
133 return SymbolFileDWARF::GetPluginNameStatic();
134 }
135
136 PluginProperties()
137 {
138 m_collection_sp.reset (new OptionValueProperties(GetSettingName()));
139 m_collection_sp->Initialize(g_properties);
140 }
141
142 FileSpecList&
143 GetSymLinkPaths()
144 {
145 OptionValueFileSpecList *option_value = m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr, true, ePropertySymLinkPaths);
146 assert(option_value);
147 return option_value->GetCurrentValue();
148 }
149
150 };
151
152 typedef std::shared_ptr<PluginProperties> SymbolFileDWARFPropertiesSP;
153
154 static const SymbolFileDWARFPropertiesSP&
155 GetGlobalPluginProperties()
156 {
157 static const auto g_settings_sp(std::make_shared<PluginProperties>());
158 return g_settings_sp;
159 }
160
161} // anonymous namespace end
162
163
Matthew Gardinere81df3b2014-08-26 06:57:23 +0000164static const char*
165removeHostnameFromPathname(const char* path_from_dwarf)
166{
167 if (!path_from_dwarf || !path_from_dwarf[0])
168 {
169 return path_from_dwarf;
170 }
Enrico Granata99e5e222015-07-27 21:27:02 +0000171
Matthew Gardinere81df3b2014-08-26 06:57:23 +0000172 const char *colon_pos = strchr(path_from_dwarf, ':');
Enrico Granata99e5e222015-07-27 21:27:02 +0000173 if (nullptr == colon_pos)
174 {
175 return path_from_dwarf;
176 }
177
178 const char *slash_pos = strchr(path_from_dwarf, '/');
179 if (slash_pos && (slash_pos < colon_pos))
Matthew Gardinere81df3b2014-08-26 06:57:23 +0000180 {
181 return path_from_dwarf;
182 }
183
184 // check whether we have a windows path, and so the first character
185 // is a drive-letter not a hostname.
186 if (
187 colon_pos == path_from_dwarf + 1 &&
188 isalpha(*path_from_dwarf) &&
189 strlen(path_from_dwarf) > 2 &&
190 '\\' == path_from_dwarf[2])
191 {
192 return path_from_dwarf;
193 }
Enrico Granata99e5e222015-07-27 21:27:02 +0000194
Matthew Gardinere81df3b2014-08-26 06:57:23 +0000195 return colon_pos + 1;
196}
197
Oleksiy Vyalov5d9c50b2015-07-21 02:09:42 +0000198static const char*
199resolveCompDir(const char* path_from_dwarf)
200{
201 if (!path_from_dwarf)
202 return nullptr;
203
204 // DWARF2/3 suggests the form hostname:pathname for compilation directory.
205 // Remove the host part if present.
206 const char* local_path = removeHostnameFromPathname(path_from_dwarf);
207 if (!local_path)
208 return nullptr;
209
210 bool is_symlink = false;
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +0000211 FileSpec local_path_spec(local_path, false);
212 const auto& file_specs = GetGlobalPluginProperties()->GetSymLinkPaths();
213 for (size_t i = 0; i < file_specs.GetSize() && !is_symlink; ++i)
214 is_symlink = FileSpec::Equal(file_specs.GetFileSpecAtIndex(i), local_path_spec, true);
Oleksiy Vyalov5d9c50b2015-07-21 02:09:42 +0000215
216 if (!is_symlink)
217 return local_path;
218
Oleksiy Vyalov5d9c50b2015-07-21 02:09:42 +0000219 if (!local_path_spec.IsSymbolicLink())
220 return local_path;
221
222 FileSpec resolved_local_path_spec;
223 const auto error = FileSystem::Readlink(local_path_spec, resolved_local_path_spec);
224 if (error.Success())
225 return resolved_local_path_spec.GetCString();
226
227 return nullptr;
228}
229
230
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000231void
232SymbolFileDWARF::Initialize()
233{
234 LogChannelDWARF::Initialize();
235 PluginManager::RegisterPlugin (GetPluginNameStatic(),
236 GetPluginDescriptionStatic(),
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +0000237 CreateInstance,
238 DebuggerInitialize);
239}
240
241void
242SymbolFileDWARF::DebuggerInitialize(Debugger &debugger)
243{
244 if (!PluginManager::GetSettingForSymbolFilePlugin(debugger, PluginProperties::GetSettingName()))
245 {
246 const bool is_global_setting = true;
247 PluginManager::CreateSettingForSymbolFilePlugin(debugger,
248 GetGlobalPluginProperties()->GetValueProperties(),
249 ConstString ("Properties for the dwarf symbol-file plug-in."),
250 is_global_setting);
251 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000252}
253
254void
255SymbolFileDWARF::Terminate()
256{
257 PluginManager::UnregisterPlugin (CreateInstance);
258 LogChannelDWARF::Initialize();
259}
260
261
Greg Clayton57abc5d2013-05-10 21:47:16 +0000262lldb_private::ConstString
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000263SymbolFileDWARF::GetPluginNameStatic()
264{
Greg Clayton57abc5d2013-05-10 21:47:16 +0000265 static ConstString g_name("dwarf");
266 return g_name;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000267}
268
269const char *
270SymbolFileDWARF::GetPluginDescriptionStatic()
271{
272 return "DWARF and DWARF3 debug symbol file reader.";
273}
274
275
276SymbolFile*
277SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
278{
279 return new SymbolFileDWARF(obj_file);
280}
281
Greg Clayton2d95dc9b2010-11-10 04:57:04 +0000282TypeList *
283SymbolFileDWARF::GetTypeList ()
284{
Greg Clayton1f746072012-08-29 21:13:06 +0000285 if (GetDebugMapSymfile ())
Greg Clayton2d95dc9b2010-11-10 04:57:04 +0000286 return m_debug_map_symfile->GetTypeList();
287 return m_obj_file->GetModule()->GetTypeList();
288
289}
Greg Claytonf02500c2013-06-18 22:51:05 +0000290void
Greg Clayton6071e6f2015-08-26 22:57:51 +0000291SymbolFileDWARF::GetTypes (const DWARFDIE &die,
Greg Claytonf02500c2013-06-18 22:51:05 +0000292 dw_offset_t min_die_offset,
293 dw_offset_t max_die_offset,
294 uint32_t type_mask,
295 TypeSet &type_set)
296{
Greg Clayton6071e6f2015-08-26 22:57:51 +0000297 if (die)
Greg Claytonf02500c2013-06-18 22:51:05 +0000298 {
Greg Clayton6071e6f2015-08-26 22:57:51 +0000299 const dw_offset_t die_offset = die.GetOffset();
300
301 if (die_offset >= max_die_offset)
302 return;
303
304 if (die_offset >= min_die_offset)
Greg Claytonf02500c2013-06-18 22:51:05 +0000305 {
Greg Clayton6071e6f2015-08-26 22:57:51 +0000306 const dw_tag_t tag = die.Tag();
Greg Claytonf02500c2013-06-18 22:51:05 +0000307
Greg Clayton6071e6f2015-08-26 22:57:51 +0000308 bool add_type = false;
309
310 switch (tag)
Greg Claytonf02500c2013-06-18 22:51:05 +0000311 {
Greg Clayton6071e6f2015-08-26 22:57:51 +0000312 case DW_TAG_array_type: add_type = (type_mask & eTypeClassArray ) != 0; break;
313 case DW_TAG_unspecified_type:
314 case DW_TAG_base_type: add_type = (type_mask & eTypeClassBuiltin ) != 0; break;
315 case DW_TAG_class_type: add_type = (type_mask & eTypeClassClass ) != 0; break;
316 case DW_TAG_structure_type: add_type = (type_mask & eTypeClassStruct ) != 0; break;
317 case DW_TAG_union_type: add_type = (type_mask & eTypeClassUnion ) != 0; break;
318 case DW_TAG_enumeration_type: add_type = (type_mask & eTypeClassEnumeration ) != 0; break;
319 case DW_TAG_subroutine_type:
320 case DW_TAG_subprogram:
321 case DW_TAG_inlined_subroutine: add_type = (type_mask & eTypeClassFunction ) != 0; break;
322 case DW_TAG_pointer_type: add_type = (type_mask & eTypeClassPointer ) != 0; break;
323 case DW_TAG_rvalue_reference_type:
324 case DW_TAG_reference_type: add_type = (type_mask & eTypeClassReference ) != 0; break;
325 case DW_TAG_typedef: add_type = (type_mask & eTypeClassTypedef ) != 0; break;
326 case DW_TAG_ptr_to_member_type: add_type = (type_mask & eTypeClassMemberPointer ) != 0; break;
327 }
Greg Claytonf02500c2013-06-18 22:51:05 +0000328
Greg Clayton6071e6f2015-08-26 22:57:51 +0000329 if (add_type)
330 {
331 const bool assert_not_being_parsed = true;
332 Type *type = ResolveTypeUID (die, assert_not_being_parsed);
333 if (type)
Greg Claytonf02500c2013-06-18 22:51:05 +0000334 {
Greg Clayton6071e6f2015-08-26 22:57:51 +0000335 if (type_set.find(type) == type_set.end())
336 type_set.insert(type);
Greg Claytonf02500c2013-06-18 22:51:05 +0000337 }
338 }
Greg Clayton6071e6f2015-08-26 22:57:51 +0000339 }
340
341 for (DWARFDIE child_die = die.GetFirstChild();
342 child_die.IsValid();
343 child_die = child_die.GetSibling())
344 {
345 GetTypes (child_die, min_die_offset, max_die_offset, type_mask, type_set);
Greg Claytonf02500c2013-06-18 22:51:05 +0000346 }
347 }
348}
349
350size_t
351SymbolFileDWARF::GetTypes (SymbolContextScope *sc_scope,
352 uint32_t type_mask,
353 TypeList &type_list)
354
355{
356 TypeSet type_set;
357
358 CompileUnit *comp_unit = NULL;
359 DWARFCompileUnit* dwarf_cu = NULL;
360 if (sc_scope)
361 comp_unit = sc_scope->CalculateSymbolContextCompileUnit();
362
363 if (comp_unit)
364 {
365 dwarf_cu = GetDWARFCompileUnit(comp_unit);
366 if (dwarf_cu == 0)
367 return 0;
Greg Clayton6071e6f2015-08-26 22:57:51 +0000368 GetTypes (dwarf_cu->DIE(),
Greg Claytonf02500c2013-06-18 22:51:05 +0000369 dwarf_cu->GetOffset(),
370 dwarf_cu->GetNextCompileUnitOffset(),
371 type_mask,
372 type_set);
373 }
374 else
375 {
376 DWARFDebugInfo* info = DebugInfo();
377 if (info)
378 {
379 const size_t num_cus = info->GetNumCompileUnits();
380 for (size_t cu_idx=0; cu_idx<num_cus; ++cu_idx)
381 {
382 dwarf_cu = info->GetCompileUnitAtIndex(cu_idx);
383 if (dwarf_cu)
384 {
Greg Clayton6071e6f2015-08-26 22:57:51 +0000385 GetTypes (dwarf_cu->DIE(),
Greg Claytonf02500c2013-06-18 22:51:05 +0000386 0,
387 UINT32_MAX,
388 type_mask,
389 type_set);
390 }
391 }
392 }
393 }
Greg Clayton6071e6f2015-08-26 22:57:51 +0000394
Greg Claytona1e5dc82015-08-11 22:53:00 +0000395 std::set<CompilerType> clang_type_set;
Greg Claytonf02500c2013-06-18 22:51:05 +0000396 size_t num_types_added = 0;
397 for (Type *type : type_set)
398 {
Greg Clayton99558cc42015-08-24 23:46:31 +0000399 CompilerType clang_type = type->GetForwardCompilerType ();
Greg Clayton0fc4f312013-06-20 01:23:18 +0000400 if (clang_type_set.find(clang_type) == clang_type_set.end())
401 {
402 clang_type_set.insert(clang_type);
403 type_list.Insert (type->shared_from_this());
404 ++num_types_added;
405 }
Greg Claytonf02500c2013-06-18 22:51:05 +0000406 }
407 return num_types_added;
408}
409
Greg Clayton2d95dc9b2010-11-10 04:57:04 +0000410
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000411//----------------------------------------------------------------------
412// Gets the first parent that is a lexical block, function or inlined
413// subroutine, or compile unit.
414//----------------------------------------------------------------------
Greg Clayton6071e6f2015-08-26 22:57:51 +0000415DWARFDIE
416SymbolFileDWARF::GetParentSymbolContextDIE(const DWARFDIE &child_die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000417{
Greg Clayton6071e6f2015-08-26 22:57:51 +0000418 DWARFDIE die;
419 for (die = child_die.GetParent(); die; die = die.GetParent())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000420 {
Greg Clayton6071e6f2015-08-26 22:57:51 +0000421 dw_tag_t tag = die.Tag();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000422
423 switch (tag)
424 {
425 case DW_TAG_compile_unit:
426 case DW_TAG_subprogram:
427 case DW_TAG_inlined_subroutine:
428 case DW_TAG_lexical_block:
429 return die;
430 }
431 }
Greg Clayton6071e6f2015-08-26 22:57:51 +0000432 return DWARFDIE();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000433}
434
435
Greg Clayton450e3f32010-10-12 02:24:53 +0000436SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
437 SymbolFile (objfile),
Greg Clayton81c22f62011-10-19 18:09:39 +0000438 UserID (0), // Used by SymbolFileDWARFDebugMap to when this class parses .o files to contain the .o file index/ID
Greg Clayton1f746072012-08-29 21:13:06 +0000439 m_debug_map_module_wp (),
Greg Clayton450e3f32010-10-12 02:24:53 +0000440 m_debug_map_symfile (NULL),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000441 m_flags(),
Greg Claytond4a2b372011-09-12 23:21:58 +0000442 m_data_debug_abbrev (),
443 m_data_debug_aranges (),
444 m_data_debug_frame (),
445 m_data_debug_info (),
446 m_data_debug_line (),
447 m_data_debug_loc (),
448 m_data_debug_ranges (),
449 m_data_debug_str (),
Greg Clayton17674402011-09-28 17:06:40 +0000450 m_data_apple_names (),
451 m_data_apple_types (),
Greg Clayton7f995132011-10-04 22:41:51 +0000452 m_data_apple_namespaces (),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000453 m_abbr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000454 m_info(),
455 m_line(),
Greg Clayton7f995132011-10-04 22:41:51 +0000456 m_apple_names_ap (),
457 m_apple_types_ap (),
458 m_apple_namespaces_ap (),
Greg Clayton5009f9d2011-10-27 17:55:14 +0000459 m_apple_objc_ap (),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000460 m_function_basename_index(),
461 m_function_fullname_index(),
462 m_function_method_index(),
463 m_function_selector_index(),
Greg Clayton450e3f32010-10-12 02:24:53 +0000464 m_objc_class_selectors_index(),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000465 m_global_index(),
Greg Clayton69b04882010-10-15 02:03:22 +0000466 m_type_index(),
467 m_namespace_index(),
Greg Clayton6beaaa62011-01-17 03:46:26 +0000468 m_indexed (false),
Greg Clayton97fbc342011-10-20 22:30:33 +0000469 m_using_apple_tables (false),
Sean Callananf0c5aeb2015-04-20 16:31:29 +0000470 m_fetched_external_modules (false),
Greg Claytonc7f03b62012-01-12 04:33:28 +0000471 m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate),
Greg Clayton1c9e5ac2011-02-09 19:06:17 +0000472 m_ranges(),
473 m_unique_ast_type_map ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000474{
475}
476
477SymbolFileDWARF::~SymbolFileDWARF()
478{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000479}
480
481static const ConstString &
482GetDWARFMachOSegmentName ()
483{
484 static ConstString g_dwarf_section_name ("__DWARF");
485 return g_dwarf_section_name;
486}
487
Greg Claytone576ab22011-02-15 00:19:15 +0000488UniqueDWARFASTTypeMap &
489SymbolFileDWARF::GetUniqueDWARFASTTypeMap ()
490{
Greg Clayton1f746072012-08-29 21:13:06 +0000491 if (GetDebugMapSymfile ())
Greg Claytone576ab22011-02-15 00:19:15 +0000492 return m_debug_map_symfile->GetUniqueDWARFASTTypeMap ();
493 return m_unique_ast_type_map;
494}
495
Greg Clayton8b4edba2015-08-14 20:02:05 +0000496ClangASTContext &
Greg Clayton6beaaa62011-01-17 03:46:26 +0000497SymbolFileDWARF::GetClangASTContext ()
498{
Greg Clayton1f746072012-08-29 21:13:06 +0000499 if (GetDebugMapSymfile ())
Greg Clayton6beaaa62011-01-17 03:46:26 +0000500 return m_debug_map_symfile->GetClangASTContext ();
Greg Clayton6dc8d582015-08-18 22:32:36 +0000501 else
502 return m_obj_file->GetModule()->GetClangASTContext();
Greg Clayton6beaaa62011-01-17 03:46:26 +0000503}
504
Greg Clayton8b4edba2015-08-14 20:02:05 +0000505TypeSystem *
506SymbolFileDWARF::GetTypeSystemForLanguage (LanguageType language)
507{
508 SymbolFileDWARFDebugMap * debug_map_symfile = GetDebugMapSymfile ();
509 if (debug_map_symfile)
510 return debug_map_symfile->GetTypeSystemForLanguage (language);
511 else
Greg Clayton6dc8d582015-08-18 22:32:36 +0000512 return m_obj_file->GetModule()->GetTypeSystemForLanguage (language);
Greg Clayton8b4edba2015-08-14 20:02:05 +0000513}
514
Greg Clayton6beaaa62011-01-17 03:46:26 +0000515void
516SymbolFileDWARF::InitializeObject()
517{
Greg Claytone72dfb32012-02-24 01:59:29 +0000518 ModuleSP module_sp (m_obj_file->GetModule());
519 if (module_sp)
Greg Clayton6beaaa62011-01-17 03:46:26 +0000520 {
Greg Clayton3046e662013-07-10 01:23:25 +0000521 const SectionList *section_list = module_sp->GetSectionList();
Greg Clayton6beaaa62011-01-17 03:46:26 +0000522
523 const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
524
525 // Memory map the DWARF mach-o segment so we have everything mmap'ed
526 // to keep our heap memory usage down.
527 if (section)
Greg Claytonc9660542012-02-05 02:38:54 +0000528 m_obj_file->MemoryMapSectionData(section, m_dwarf_data);
Greg Clayton6beaaa62011-01-17 03:46:26 +0000529 }
Greg Clayton4d01ace2011-09-29 16:58:15 +0000530 get_apple_names_data();
Greg Clayton7f995132011-10-04 22:41:51 +0000531 if (m_data_apple_names.GetByteSize() > 0)
532 {
Greg Clayton97fbc342011-10-20 22:30:33 +0000533 m_apple_names_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_names, get_debug_str_data(), ".apple_names"));
534 if (m_apple_names_ap->IsValid())
535 m_using_apple_tables = true;
536 else
Greg Clayton7f995132011-10-04 22:41:51 +0000537 m_apple_names_ap.reset();
538 }
Greg Clayton4d01ace2011-09-29 16:58:15 +0000539 get_apple_types_data();
Greg Clayton7f995132011-10-04 22:41:51 +0000540 if (m_data_apple_types.GetByteSize() > 0)
541 {
Greg Clayton97fbc342011-10-20 22:30:33 +0000542 m_apple_types_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_types, get_debug_str_data(), ".apple_types"));
543 if (m_apple_types_ap->IsValid())
544 m_using_apple_tables = true;
545 else
Greg Clayton7f995132011-10-04 22:41:51 +0000546 m_apple_types_ap.reset();
547 }
548
549 get_apple_namespaces_data();
550 if (m_data_apple_namespaces.GetByteSize() > 0)
551 {
Greg Clayton97fbc342011-10-20 22:30:33 +0000552 m_apple_namespaces_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_namespaces, get_debug_str_data(), ".apple_namespaces"));
553 if (m_apple_namespaces_ap->IsValid())
554 m_using_apple_tables = true;
555 else
Greg Clayton7f995132011-10-04 22:41:51 +0000556 m_apple_namespaces_ap.reset();
557 }
Greg Clayton4d01ace2011-09-29 16:58:15 +0000558
Greg Clayton5009f9d2011-10-27 17:55:14 +0000559 get_apple_objc_data();
560 if (m_data_apple_objc.GetByteSize() > 0)
561 {
562 m_apple_objc_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_objc, get_debug_str_data(), ".apple_objc"));
563 if (m_apple_objc_ap->IsValid())
564 m_using_apple_tables = true;
565 else
566 m_apple_objc_ap.reset();
567 }
Greg Clayton6dc8d582015-08-18 22:32:36 +0000568
569 // Set the symbol file to this file if we don't have a debug map symbol
570 // file as our main symbol file. This allows the clang ASTContext to complete
571 // types using this symbol file when it needs to complete classes and structures.
572 if (GetDebugMapSymfile () == nullptr)
573 GetClangASTContext().SetSymbolFile(this);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000574}
575
576bool
577SymbolFileDWARF::SupportedVersion(uint16_t version)
578{
Greg Claytonabcbfe52013-04-04 00:00:36 +0000579 return version == 2 || version == 3 || version == 4;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000580}
581
582uint32_t
Sean Callananbfaf54d2011-12-03 04:38:43 +0000583SymbolFileDWARF::CalculateAbilities ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000584{
585 uint32_t abilities = 0;
586 if (m_obj_file != NULL)
587 {
588 const Section* section = NULL;
589 const SectionList *section_list = m_obj_file->GetSectionList();
590 if (section_list == NULL)
591 return 0;
592
593 uint64_t debug_abbrev_file_size = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000594 uint64_t debug_info_file_size = 0;
595 uint64_t debug_line_file_size = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000596
Greg Clayton6beaaa62011-01-17 03:46:26 +0000597 section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000598
599 if (section)
Greg Clayton4ceb9982010-07-21 22:54:26 +0000600 section_list = &section->GetChildren ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000601
Greg Clayton4ceb9982010-07-21 22:54:26 +0000602 section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000603 if (section != NULL)
604 {
Greg Clayton47037bc2012-03-27 02:40:46 +0000605 debug_info_file_size = section->GetFileSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000606
Greg Clayton4ceb9982010-07-21 22:54:26 +0000607 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000608 if (section)
Greg Clayton47037bc2012-03-27 02:40:46 +0000609 debug_abbrev_file_size = section->GetFileSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000610 else
611 m_flags.Set (flagsGotDebugAbbrevData);
612
Greg Clayton4ceb9982010-07-21 22:54:26 +0000613 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get();
Greg Clayton23f59502012-07-17 03:23:13 +0000614 if (!section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000615 m_flags.Set (flagsGotDebugArangesData);
616
Greg Clayton4ceb9982010-07-21 22:54:26 +0000617 section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get();
Greg Clayton23f59502012-07-17 03:23:13 +0000618 if (!section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000619 m_flags.Set (flagsGotDebugFrameData);
620
Greg Clayton4ceb9982010-07-21 22:54:26 +0000621 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000622 if (section)
Greg Clayton47037bc2012-03-27 02:40:46 +0000623 debug_line_file_size = section->GetFileSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000624 else
625 m_flags.Set (flagsGotDebugLineData);
626
Greg Clayton4ceb9982010-07-21 22:54:26 +0000627 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get();
Greg Clayton23f59502012-07-17 03:23:13 +0000628 if (!section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000629 m_flags.Set (flagsGotDebugLocData);
630
Greg Clayton4ceb9982010-07-21 22:54:26 +0000631 section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get();
Greg Clayton23f59502012-07-17 03:23:13 +0000632 if (!section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000633 m_flags.Set (flagsGotDebugMacInfoData);
634
Greg Clayton4ceb9982010-07-21 22:54:26 +0000635 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get();
Greg Clayton23f59502012-07-17 03:23:13 +0000636 if (!section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000637 m_flags.Set (flagsGotDebugPubNamesData);
638
Greg Clayton4ceb9982010-07-21 22:54:26 +0000639 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get();
Greg Clayton23f59502012-07-17 03:23:13 +0000640 if (!section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000641 m_flags.Set (flagsGotDebugPubTypesData);
642
Greg Clayton4ceb9982010-07-21 22:54:26 +0000643 section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get();
Greg Clayton23f59502012-07-17 03:23:13 +0000644 if (!section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000645 m_flags.Set (flagsGotDebugRangesData);
646
Greg Clayton4ceb9982010-07-21 22:54:26 +0000647 section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
Greg Clayton23f59502012-07-17 03:23:13 +0000648 if (!section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000649 m_flags.Set (flagsGotDebugStrData);
650 }
Greg Clayton6c596612012-05-18 21:47:20 +0000651 else
652 {
653 const char *symfile_dir_cstr = m_obj_file->GetFileSpec().GetDirectory().GetCString();
654 if (symfile_dir_cstr)
655 {
656 if (strcasestr(symfile_dir_cstr, ".dsym"))
657 {
658 if (m_obj_file->GetType() == ObjectFile::eTypeDebugInfo)
659 {
660 // We have a dSYM file that didn't have a any debug info.
661 // If the string table has a size of 1, then it was made from
662 // an executable with no debug info, or from an executable that
663 // was stripped.
664 section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
665 if (section && section->GetFileSize() == 1)
666 {
667 m_obj_file->GetModule()->ReportWarning ("empty dSYM file detected, dSYM was created with an executable with no debug info.");
668 }
669 }
670 }
671 }
672 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000673
674 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
675 abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
676
677 if (debug_line_file_size > 0)
678 abilities |= LineTables;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000679 }
680 return abilities;
681}
682
Ed Masteeeae7212013-10-24 20:43:47 +0000683const DWARFDataExtractor&
684SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DWARFDataExtractor &data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000685{
686 if (m_flags.IsClear (got_flag))
687 {
Michael Sartaina7499c92013-07-01 19:45:50 +0000688 ModuleSP module_sp (m_obj_file->GetModule());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000689 m_flags.Set (got_flag);
Greg Clayton3046e662013-07-10 01:23:25 +0000690 const SectionList *section_list = module_sp->GetSectionList();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000691 if (section_list)
692 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000693 SectionSP section_sp (section_list->FindSectionByType(sect_type, true));
694 if (section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000695 {
696 // See if we memory mapped the DWARF segment?
697 if (m_dwarf_data.GetByteSize())
698 {
Greg Clayton47037bc2012-03-27 02:40:46 +0000699 data.SetData(m_dwarf_data, section_sp->GetOffset (), section_sp->GetFileSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000700 }
701 else
702 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000703 if (m_obj_file->ReadSectionData (section_sp.get(), data) == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000704 data.Clear();
705 }
706 }
707 }
708 }
709 return data;
710}
711
Ed Masteeeae7212013-10-24 20:43:47 +0000712const DWARFDataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000713SymbolFileDWARF::get_debug_abbrev_data()
714{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000715 return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000716}
717
Ed Masteeeae7212013-10-24 20:43:47 +0000718const DWARFDataExtractor&
Tamas Berghammerc178d4c2015-08-25 11:45:58 +0000719SymbolFileDWARF::get_debug_addr_data()
720{
721 return GetCachedSectionData (flagsGotDebugAddrData, eSectionTypeDWARFDebugAddr, m_data_debug_addr);
722}
723
724const DWARFDataExtractor&
Greg Claytond4a2b372011-09-12 23:21:58 +0000725SymbolFileDWARF::get_debug_aranges_data()
726{
727 return GetCachedSectionData (flagsGotDebugArangesData, eSectionTypeDWARFDebugAranges, m_data_debug_aranges);
728}
729
Ed Masteeeae7212013-10-24 20:43:47 +0000730const DWARFDataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000731SymbolFileDWARF::get_debug_frame_data()
732{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000733 return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000734}
735
Ed Masteeeae7212013-10-24 20:43:47 +0000736const DWARFDataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000737SymbolFileDWARF::get_debug_info_data()
738{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000739 return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000740}
741
Ed Masteeeae7212013-10-24 20:43:47 +0000742const DWARFDataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000743SymbolFileDWARF::get_debug_line_data()
744{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000745 return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000746}
747
Ed Masteeeae7212013-10-24 20:43:47 +0000748const DWARFDataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000749SymbolFileDWARF::get_debug_loc_data()
750{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000751 return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000752}
753
Ed Masteeeae7212013-10-24 20:43:47 +0000754const DWARFDataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000755SymbolFileDWARF::get_debug_ranges_data()
756{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000757 return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000758}
759
Ed Masteeeae7212013-10-24 20:43:47 +0000760const DWARFDataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000761SymbolFileDWARF::get_debug_str_data()
762{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000763 return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000764}
765
Ed Masteeeae7212013-10-24 20:43:47 +0000766const DWARFDataExtractor&
Tamas Berghammerc178d4c2015-08-25 11:45:58 +0000767SymbolFileDWARF::get_debug_str_offsets_data()
768{
769 return GetCachedSectionData (flagsGotDebugStrOffsetsData, eSectionTypeDWARFDebugStrOffsets, m_data_debug_str_offsets);
770}
771
772const DWARFDataExtractor&
Greg Clayton17674402011-09-28 17:06:40 +0000773SymbolFileDWARF::get_apple_names_data()
Greg Claytonf9eec202011-09-01 23:16:13 +0000774{
Greg Clayton5009f9d2011-10-27 17:55:14 +0000775 return GetCachedSectionData (flagsGotAppleNamesData, eSectionTypeDWARFAppleNames, m_data_apple_names);
Greg Claytonf9eec202011-09-01 23:16:13 +0000776}
777
Ed Masteeeae7212013-10-24 20:43:47 +0000778const DWARFDataExtractor&
Greg Clayton17674402011-09-28 17:06:40 +0000779SymbolFileDWARF::get_apple_types_data()
Greg Claytonf9eec202011-09-01 23:16:13 +0000780{
Greg Clayton5009f9d2011-10-27 17:55:14 +0000781 return GetCachedSectionData (flagsGotAppleTypesData, eSectionTypeDWARFAppleTypes, m_data_apple_types);
Greg Claytonf9eec202011-09-01 23:16:13 +0000782}
783
Ed Masteeeae7212013-10-24 20:43:47 +0000784const DWARFDataExtractor&
Greg Clayton7f995132011-10-04 22:41:51 +0000785SymbolFileDWARF::get_apple_namespaces_data()
786{
Greg Clayton5009f9d2011-10-27 17:55:14 +0000787 return GetCachedSectionData (flagsGotAppleNamespacesData, eSectionTypeDWARFAppleNamespaces, m_data_apple_namespaces);
788}
789
Ed Masteeeae7212013-10-24 20:43:47 +0000790const DWARFDataExtractor&
Greg Clayton5009f9d2011-10-27 17:55:14 +0000791SymbolFileDWARF::get_apple_objc_data()
792{
793 return GetCachedSectionData (flagsGotAppleObjCData, eSectionTypeDWARFAppleObjC, m_data_apple_objc);
Greg Clayton7f995132011-10-04 22:41:51 +0000794}
795
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000796
797DWARFDebugAbbrev*
798SymbolFileDWARF::DebugAbbrev()
799{
800 if (m_abbr.get() == NULL)
801 {
Ed Masteeeae7212013-10-24 20:43:47 +0000802 const DWARFDataExtractor &debug_abbrev_data = get_debug_abbrev_data();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000803 if (debug_abbrev_data.GetByteSize() > 0)
804 {
805 m_abbr.reset(new DWARFDebugAbbrev());
806 if (m_abbr.get())
807 m_abbr->Parse(debug_abbrev_data);
808 }
809 }
810 return m_abbr.get();
811}
812
813const DWARFDebugAbbrev*
814SymbolFileDWARF::DebugAbbrev() const
815{
816 return m_abbr.get();
817}
818
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000819
820DWARFDebugInfo*
821SymbolFileDWARF::DebugInfo()
822{
823 if (m_info.get() == NULL)
824 {
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000825 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p",
826 __PRETTY_FUNCTION__, static_cast<void*>(this));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000827 if (get_debug_info_data().GetByteSize() > 0)
828 {
829 m_info.reset(new DWARFDebugInfo());
830 if (m_info.get())
831 {
832 m_info->SetDwarfData(this);
833 }
834 }
835 }
836 return m_info.get();
837}
838
839const DWARFDebugInfo*
840SymbolFileDWARF::DebugInfo() const
841{
842 return m_info.get();
843}
844
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000845DWARFCompileUnit*
Greg Clayton1f746072012-08-29 21:13:06 +0000846SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000847{
848 DWARFDebugInfo* info = DebugInfo();
Greg Clayton1f746072012-08-29 21:13:06 +0000849 if (info)
850 {
851 if (GetDebugMapSymfile ())
852 {
853 // The debug map symbol file made the compile units for this DWARF
854 // file which is .o file with DWARF in it, and we should have
855 // only 1 compile unit which is at offset zero in the DWARF.
856 // TODO: modify to support LTO .o files where each .o file might
857 // have multiple DW_TAG_compile_unit tags.
Greg Clayton68c00bd2015-02-05 02:10:29 +0000858
Greg Clayton6071e6f2015-08-26 22:57:51 +0000859 DWARFCompileUnit *dwarf_cu = info->GetCompileUnit(0);
Greg Clayton68c00bd2015-02-05 02:10:29 +0000860 if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
861 dwarf_cu->SetUserData(comp_unit);
862 return dwarf_cu;
Greg Clayton1f746072012-08-29 21:13:06 +0000863 }
864 else
865 {
866 // Just a normal DWARF file whose user ID for the compile unit is
867 // the DWARF offset itself
Greg Clayton68c00bd2015-02-05 02:10:29 +0000868
Greg Clayton6071e6f2015-08-26 22:57:51 +0000869 DWARFCompileUnit *dwarf_cu = info->GetCompileUnit((dw_offset_t)comp_unit->GetID());
Greg Clayton68c00bd2015-02-05 02:10:29 +0000870 if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
871 dwarf_cu->SetUserData(comp_unit);
872 return dwarf_cu;
873
Greg Clayton1f746072012-08-29 21:13:06 +0000874 }
875 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000876 return NULL;
877}
878
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000879
880DWARFDebugRanges*
881SymbolFileDWARF::DebugRanges()
882{
883 if (m_ranges.get() == NULL)
884 {
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000885 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p",
886 __PRETTY_FUNCTION__, static_cast<void*>(this));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000887 if (get_debug_ranges_data().GetByteSize() > 0)
888 {
889 m_ranges.reset(new DWARFDebugRanges());
890 if (m_ranges.get())
891 m_ranges->Extract(this);
892 }
893 }
894 return m_ranges.get();
895}
896
897const DWARFDebugRanges*
898SymbolFileDWARF::DebugRanges() const
899{
900 return m_ranges.get();
901}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000902
Greg Clayton53eb1c22012-04-02 22:59:12 +0000903lldb::CompUnitSP
904SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000905{
Greg Clayton53eb1c22012-04-02 22:59:12 +0000906 CompUnitSP cu_sp;
907 if (dwarf_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000908 {
Greg Clayton53eb1c22012-04-02 22:59:12 +0000909 CompileUnit *comp_unit = (CompileUnit*)dwarf_cu->GetUserData();
910 if (comp_unit)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000911 {
Greg Clayton53eb1c22012-04-02 22:59:12 +0000912 // We already parsed this compile unit, had out a shared pointer to it
913 cu_sp = comp_unit->shared_from_this();
914 }
915 else
916 {
Greg Clayton1f746072012-08-29 21:13:06 +0000917 if (GetDebugMapSymfile ())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000918 {
Greg Clayton1f746072012-08-29 21:13:06 +0000919 // Let the debug map create the compile unit
920 cu_sp = m_debug_map_symfile->GetCompileUnit(this);
921 dwarf_cu->SetUserData(cu_sp.get());
922 }
923 else
924 {
925 ModuleSP module_sp (m_obj_file->GetModule());
926 if (module_sp)
Greg Clayton53eb1c22012-04-02 22:59:12 +0000927 {
Greg Clayton5ce1a842015-08-27 18:09:44 +0000928 const DWARFDIE cu_die = dwarf_cu->GetCompileUnitDIEOnly ();
Greg Clayton1f746072012-08-29 21:13:06 +0000929 if (cu_die)
Greg Clayton53eb1c22012-04-02 22:59:12 +0000930 {
Greg Clayton5ce1a842015-08-27 18:09:44 +0000931 FileSpec cu_file_spec{cu_die.GetName(), false};
Chaoren Lin0c5a9c12015-06-05 00:28:06 +0000932 if (cu_file_spec)
Greg Clayton1f746072012-08-29 21:13:06 +0000933 {
Chaoren Lin0c5a9c12015-06-05 00:28:06 +0000934 // If we have a full path to the compile unit, we don't need to resolve
935 // the file. This can be expensive e.g. when the source files are NFS mounted.
Chaoren Lin372e9062015-06-09 17:54:27 +0000936 if (cu_file_spec.IsRelative())
Greg Clayton53eb1c22012-04-02 22:59:12 +0000937 {
Greg Clayton5ce1a842015-08-27 18:09:44 +0000938 const char *cu_comp_dir{cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr)};
Oleksiy Vyalov5d9c50b2015-07-21 02:09:42 +0000939 cu_file_spec.PrependPathComponent(resolveCompDir(cu_comp_dir));
Greg Clayton1f746072012-08-29 21:13:06 +0000940 }
941
Chaoren Lin0c5a9c12015-06-05 00:28:06 +0000942 std::string remapped_file;
943 if (module_sp->RemapSourceFile(cu_file_spec.GetCString(), remapped_file))
944 cu_file_spec.SetFile(remapped_file, false);
David Srbeckyd515e942015-07-08 14:00:04 +0000945 }
Chaoren Lin0c5a9c12015-06-05 00:28:06 +0000946
Greg Clayton5ce1a842015-08-27 18:09:44 +0000947 LanguageType cu_language = DWARFCompileUnit::LanguageTypeFromDWARF(cu_die.GetAttributeValueAsUnsigned(DW_AT_language, 0));
Chaoren Lin0c5a9c12015-06-05 00:28:06 +0000948
Jason Molendac7099582015-07-31 05:47:00 +0000949 bool is_optimized = dwarf_cu->GetIsOptimized ();
David Srbeckyd515e942015-07-08 14:00:04 +0000950 cu_sp.reset(new CompileUnit (module_sp,
951 dwarf_cu,
952 cu_file_spec,
Greg Clayton6071e6f2015-08-26 22:57:51 +0000953 dwarf_cu->GetID(),
Jason Molenda6ab659a2015-07-29 00:42:47 +0000954 cu_language,
955 is_optimized));
David Srbeckyd515e942015-07-08 14:00:04 +0000956 if (cu_sp)
957 {
958 // If we just created a compile unit with an invalid file spec, try and get the
959 // first entry in the supports files from the line table as that should be the
960 // compile unit.
961 if (!cu_file_spec)
Greg Clayton1f746072012-08-29 21:13:06 +0000962 {
David Srbeckyd515e942015-07-08 14:00:04 +0000963 cu_file_spec = cu_sp->GetSupportFiles().GetFileSpecAtIndex(1);
964 if (cu_file_spec)
965 {
966 (FileSpec &)(*cu_sp) = cu_file_spec;
967 // Also fix the invalid file spec which was copied from the compile unit.
968 cu_sp->GetSupportFiles().Replace(0, cu_file_spec);
969 }
Greg Clayton53eb1c22012-04-02 22:59:12 +0000970 }
David Srbeckyd515e942015-07-08 14:00:04 +0000971
972 dwarf_cu->SetUserData(cu_sp.get());
973
974 // Figure out the compile unit index if we weren't given one
975 if (cu_idx == UINT32_MAX)
976 DebugInfo()->GetCompileUnit(dwarf_cu->GetOffset(), &cu_idx);
977
978 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp);
Greg Clayton53eb1c22012-04-02 22:59:12 +0000979 }
980 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000981 }
982 }
983 }
984 }
Greg Clayton53eb1c22012-04-02 22:59:12 +0000985 return cu_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000986}
987
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000988uint32_t
989SymbolFileDWARF::GetNumCompileUnits()
990{
991 DWARFDebugInfo* info = DebugInfo();
992 if (info)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000993 return info->GetNumCompileUnits();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000994 return 0;
995}
996
997CompUnitSP
998SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
999{
Greg Clayton53eb1c22012-04-02 22:59:12 +00001000 CompUnitSP cu_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001001 DWARFDebugInfo* info = DebugInfo();
1002 if (info)
1003 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00001004 DWARFCompileUnit* dwarf_cu = info->GetCompileUnitAtIndex(cu_idx);
1005 if (dwarf_cu)
1006 cu_sp = ParseCompileUnit(dwarf_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001007 }
Greg Clayton53eb1c22012-04-02 22:59:12 +00001008 return cu_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001009}
1010
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001011Function *
Greg Clayton6071e6f2015-08-26 22:57:51 +00001012SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, const DWARFDIE &die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001013{
Greg Clayton6071e6f2015-08-26 22:57:51 +00001014 if (die.IsValid())
1015 {
1016 TypeSystem *type_system = GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001017
Greg Clayton6071e6f2015-08-26 22:57:51 +00001018 if (type_system)
1019 {
Greg Clayton261ac3f2015-08-28 01:01:03 +00001020 DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
1021 if (dwarf_ast)
1022 return dwarf_ast->ParseFunctionFromDWARF(sc, die);
Greg Clayton6071e6f2015-08-26 22:57:51 +00001023 }
1024 }
1025 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001026}
1027
Greg Clayton9422dd62013-03-04 21:46:16 +00001028bool
1029SymbolFileDWARF::FixupAddress (Address &addr)
1030{
1031 SymbolFileDWARFDebugMap * debug_map_symfile = GetDebugMapSymfile ();
1032 if (debug_map_symfile)
1033 {
1034 return debug_map_symfile->LinkOSOAddress(addr);
1035 }
1036 // This is a normal DWARF file, no address fixups need to happen
1037 return true;
1038}
Greg Clayton1f746072012-08-29 21:13:06 +00001039lldb::LanguageType
1040SymbolFileDWARF::ParseCompileUnitLanguage (const SymbolContext& sc)
1041{
1042 assert (sc.comp_unit);
1043 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
1044 if (dwarf_cu)
Greg Clayton5ce1a842015-08-27 18:09:44 +00001045 return dwarf_cu->GetLanguageType();
1046 else
1047 return eLanguageTypeUnknown;
Greg Clayton1f746072012-08-29 21:13:06 +00001048}
1049
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001050size_t
1051SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
1052{
1053 assert (sc.comp_unit);
1054 size_t functions_added = 0;
Greg Clayton1f746072012-08-29 21:13:06 +00001055 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001056 if (dwarf_cu)
1057 {
1058 DWARFDIECollection function_dies;
Greg Clayton1f746072012-08-29 21:13:06 +00001059 const size_t num_functions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001060 size_t func_idx;
Greg Clayton1f746072012-08-29 21:13:06 +00001061 for (func_idx = 0; func_idx < num_functions; ++func_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001062 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001063 DWARFDIE die = function_dies.GetDIEAtIndex(func_idx);
1064 if (sc.comp_unit->FindFunctionByUID (die.GetID()).get() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001065 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001066 if (ParseCompileUnitFunction(sc, die))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001067 ++functions_added;
1068 }
1069 }
1070 //FixupTypes();
1071 }
1072 return functions_added;
1073}
1074
1075bool
1076SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
1077{
1078 assert (sc.comp_unit);
Greg Clayton1f746072012-08-29 21:13:06 +00001079 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
Greg Claytonda2455b2012-11-01 17:28:37 +00001080 if (dwarf_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001081 {
Greg Clayton5ce1a842015-08-27 18:09:44 +00001082 const DWARFDIE cu_die = dwarf_cu->GetCompileUnitDIEOnly();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001083
Greg Claytonda2455b2012-11-01 17:28:37 +00001084 if (cu_die)
1085 {
Greg Clayton5ce1a842015-08-27 18:09:44 +00001086 const char * cu_comp_dir = resolveCompDir(cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr));
Matthew Gardinere81df3b2014-08-26 06:57:23 +00001087
Greg Clayton5ce1a842015-08-27 18:09:44 +00001088 const dw_offset_t stmt_list = cu_die.GetAttributeValueAsUnsigned(DW_AT_stmt_list, DW_INVALID_OFFSET);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001089
Greg Claytonda2455b2012-11-01 17:28:37 +00001090 // All file indexes in DWARF are one based and a file of index zero is
1091 // supposed to be the compile unit itself.
1092 support_files.Append (*sc.comp_unit);
1093
1094 return DWARFDebugLine::ParseSupportFiles(sc.comp_unit->GetModule(), get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
1095 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001096 }
1097 return false;
1098}
1099
Sean Callananf0c5aeb2015-04-20 16:31:29 +00001100bool
1101SymbolFileDWARF::ParseImportedModules (const lldb_private::SymbolContext &sc, std::vector<lldb_private::ConstString> &imported_modules)
1102{
1103 assert (sc.comp_unit);
1104 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
1105 if (dwarf_cu)
1106 {
1107 if (ClangModulesDeclVendor::LanguageSupportsClangModules(sc.comp_unit->GetLanguage()))
1108 {
1109 UpdateExternalModuleListIfNeeded();
1110 for (const std::pair<uint64_t, const ClangModuleInfo> &external_type_module : m_external_type_modules)
1111 {
1112 imported_modules.push_back(external_type_module.second.m_name);
1113 }
1114 }
1115 }
1116 return false;
1117}
1118
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001119struct ParseDWARFLineTableCallbackInfo
1120{
1121 LineTable* line_table;
Greg Clayton7b0992d2013-04-18 22:45:39 +00001122 std::unique_ptr<LineSequence> sequence_ap;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001123};
1124
1125//----------------------------------------------------------------------
1126// ParseStatementTableCallback
1127//----------------------------------------------------------------------
1128static void
1129ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
1130{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001131 if (state.row == DWARFDebugLine::State::StartParsingLineTable)
1132 {
1133 // Just started parsing the line table
1134 }
1135 else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
1136 {
1137 // Done parsing line table, nothing to do for the cleanup
1138 }
1139 else
1140 {
1141 ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
Greg Clayton9422dd62013-03-04 21:46:16 +00001142 LineTable* line_table = info->line_table;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001143
Greg Clayton9422dd62013-03-04 21:46:16 +00001144 // If this is our first time here, we need to create a
1145 // sequence container.
1146 if (!info->sequence_ap.get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001147 {
Greg Clayton9422dd62013-03-04 21:46:16 +00001148 info->sequence_ap.reset(line_table->CreateLineSequenceContainer());
1149 assert(info->sequence_ap.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001150 }
Greg Clayton9422dd62013-03-04 21:46:16 +00001151 line_table->AppendLineEntryToSequence (info->sequence_ap.get(),
1152 state.address,
1153 state.line,
1154 state.column,
1155 state.file,
1156 state.is_stmt,
1157 state.basic_block,
1158 state.prologue_end,
1159 state.epilogue_begin,
1160 state.end_sequence);
1161 if (state.end_sequence)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001162 {
Greg Clayton9422dd62013-03-04 21:46:16 +00001163 // First, put the current sequence into the line table.
1164 line_table->InsertSequence(info->sequence_ap.get());
1165 // Then, empty it to prepare for the next sequence.
1166 info->sequence_ap->Clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001167 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001168 }
1169}
1170
1171bool
1172SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
1173{
1174 assert (sc.comp_unit);
1175 if (sc.comp_unit->GetLineTable() != NULL)
1176 return true;
1177
Greg Clayton1f746072012-08-29 21:13:06 +00001178 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001179 if (dwarf_cu)
1180 {
Greg Clayton5ce1a842015-08-27 18:09:44 +00001181 const DWARFDIE dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
Greg Clayton129d12c2011-11-28 03:29:03 +00001182 if (dwarf_cu_die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001183 {
Greg Clayton5ce1a842015-08-27 18:09:44 +00001184 const dw_offset_t cu_line_offset = dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_stmt_list, DW_INVALID_OFFSET);
Greg Clayton129d12c2011-11-28 03:29:03 +00001185 if (cu_line_offset != DW_INVALID_OFFSET)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001186 {
Greg Clayton7b0992d2013-04-18 22:45:39 +00001187 std::unique_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
Greg Clayton129d12c2011-11-28 03:29:03 +00001188 if (line_table_ap.get())
1189 {
Greg Clayton9422dd62013-03-04 21:46:16 +00001190 ParseDWARFLineTableCallbackInfo info;
1191 info.line_table = line_table_ap.get();
Greg Claytonc7bece562013-01-25 18:06:21 +00001192 lldb::offset_t offset = cu_line_offset;
Greg Clayton129d12c2011-11-28 03:29:03 +00001193 DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
Greg Clayton9422dd62013-03-04 21:46:16 +00001194 if (m_debug_map_symfile)
1195 {
1196 // We have an object file that has a line table with addresses
1197 // that are not linked. We need to link the line table and convert
1198 // the addresses that are relative to the .o file into addresses
1199 // for the main executable.
1200 sc.comp_unit->SetLineTable (m_debug_map_symfile->LinkOSOLineTable (this, line_table_ap.get()));
1201 }
1202 else
1203 {
1204 sc.comp_unit->SetLineTable(line_table_ap.release());
1205 return true;
1206 }
Greg Clayton129d12c2011-11-28 03:29:03 +00001207 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001208 }
1209 }
1210 }
1211 return false;
1212}
1213
1214size_t
Greg Clayton6071e6f2015-08-26 22:57:51 +00001215SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext& sc,
1216 Block *parent_block,
1217 const DWARFDIE &orig_die,
1218 addr_t subprogram_low_pc,
1219 uint32_t depth)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001220{
1221 size_t blocks_added = 0;
Greg Clayton6071e6f2015-08-26 22:57:51 +00001222 DWARFDIE die = orig_die;
1223 while (die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001224 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001225 dw_tag_t tag = die.Tag();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001226
1227 switch (tag)
1228 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001229 case DW_TAG_inlined_subroutine:
Greg Claytonb4d37332011-08-12 16:22:48 +00001230 case DW_TAG_subprogram:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001231 case DW_TAG_lexical_block:
1232 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001233 Block *block = NULL;
Greg Claytondd7feaf2011-08-12 17:54:33 +00001234 if (tag == DW_TAG_subprogram)
1235 {
1236 // Skip any DW_TAG_subprogram DIEs that are inside
1237 // of a normal or inlined functions. These will be
1238 // parsed on their own as separate entities.
1239
1240 if (depth > 0)
1241 break;
1242
1243 block = parent_block;
1244 }
1245 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001246 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001247 BlockSP block_sp(new Block (die.GetID()));
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001248 parent_block->AddChild(block_sp);
1249 block = block_sp.get();
1250 }
Greg Clayton6071e6f2015-08-26 22:57:51 +00001251 DWARFRangeList ranges;
Greg Claytondd7feaf2011-08-12 17:54:33 +00001252 const char *name = NULL;
1253 const char *mangled_name = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001254
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001255 int decl_file = 0;
1256 int decl_line = 0;
1257 int decl_column = 0;
1258 int call_file = 0;
1259 int call_line = 0;
1260 int call_column = 0;
Greg Clayton6071e6f2015-08-26 22:57:51 +00001261 if (die.GetDIENamesAndRanges (name,
1262 mangled_name,
1263 ranges,
1264 decl_file, decl_line, decl_column,
1265 call_file, call_line, call_column, nullptr))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001266 {
1267 if (tag == DW_TAG_subprogram)
1268 {
1269 assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
Greg Claytonea3e7d52011-10-08 00:49:15 +00001270 subprogram_low_pc = ranges.GetMinRangeBase(0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001271 }
Jim Inghamb0be4422010-08-12 01:20:14 +00001272 else if (tag == DW_TAG_inlined_subroutine)
1273 {
1274 // We get called here for inlined subroutines in two ways.
1275 // The first time is when we are making the Function object
1276 // for this inlined concrete instance. Since we're creating a top level block at
1277 // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we need to
1278 // adjust the containing address.
1279 // The second time is when we are parsing the blocks inside the function that contains
1280 // the inlined concrete instance. Since these will be blocks inside the containing "real"
1281 // function the offset will be for that function.
1282 if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
1283 {
Greg Claytonea3e7d52011-10-08 00:49:15 +00001284 subprogram_low_pc = ranges.GetMinRangeBase(0);
Jim Inghamb0be4422010-08-12 01:20:14 +00001285 }
1286 }
Greg Clayton103f3092015-01-15 03:04:37 +00001287
1288 const size_t num_ranges = ranges.GetSize();
1289 for (size_t i = 0; i<num_ranges; ++i)
1290 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001291 const DWARFRangeList::Entry &range = ranges.GetEntryRef (i);
Greg Clayton103f3092015-01-15 03:04:37 +00001292 const addr_t range_base = range.GetRangeBase();
1293 if (range_base >= subprogram_low_pc)
1294 block->AddRange(Block::Range (range_base - subprogram_low_pc, range.GetByteSize()));
1295 else
1296 {
1297 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",
1298 block->GetID(),
1299 range_base,
1300 range.GetRangeEnd(),
1301 subprogram_low_pc);
1302 }
1303 }
1304 block->FinalizeRanges ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001305
1306 if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
1307 {
Greg Clayton7b0992d2013-04-18 22:45:39 +00001308 std::unique_ptr<Declaration> decl_ap;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001309 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001310 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
1311 decl_line, decl_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001312
Greg Clayton7b0992d2013-04-18 22:45:39 +00001313 std::unique_ptr<Declaration> call_ap;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001314 if (call_file != 0 || call_line != 0 || call_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001315 call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file),
1316 call_line, call_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001317
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001318 block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001319 }
1320
1321 ++blocks_added;
1322
Greg Clayton6071e6f2015-08-26 22:57:51 +00001323 if (die.HasChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001324 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001325 blocks_added += ParseFunctionBlocks (sc,
1326 block,
Greg Clayton6071e6f2015-08-26 22:57:51 +00001327 die.GetFirstChild(),
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001328 subprogram_low_pc,
Greg Claytondd7feaf2011-08-12 17:54:33 +00001329 depth + 1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001330 }
1331 }
1332 }
1333 break;
1334 default:
1335 break;
1336 }
1337
Greg Claytondd7feaf2011-08-12 17:54:33 +00001338 // Only parse siblings of the block if we are not at depth zero. A depth
1339 // of zero indicates we are currently parsing the top level
1340 // DW_TAG_subprogram DIE
1341
1342 if (depth == 0)
Greg Clayton6071e6f2015-08-26 22:57:51 +00001343 die.Clear();
Greg Claytondd7feaf2011-08-12 17:54:33 +00001344 else
Greg Clayton6071e6f2015-08-26 22:57:51 +00001345 die = die.GetSibling();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001346 }
1347 return blocks_added;
1348}
1349
Greg Claytonf0705c82011-10-22 03:33:13 +00001350bool
Greg Clayton6071e6f2015-08-26 22:57:51 +00001351SymbolFileDWARF::ClassOrStructIsVirtual (const DWARFDIE &parent_die)
Greg Claytonc4ffd662013-03-08 01:37:30 +00001352{
1353 if (parent_die)
1354 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001355 for (DWARFDIE die = parent_die.GetFirstChild(); die; die = die.GetSibling())
Greg Claytonc4ffd662013-03-08 01:37:30 +00001356 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001357 dw_tag_t tag = die.Tag();
Greg Claytonc4ffd662013-03-08 01:37:30 +00001358 bool check_virtuality = false;
1359 switch (tag)
1360 {
1361 case DW_TAG_inheritance:
1362 case DW_TAG_subprogram:
1363 check_virtuality = true;
1364 break;
1365 default:
1366 break;
1367 }
1368 if (check_virtuality)
1369 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001370 if (die.GetAttributeValueAsUnsigned(DW_AT_virtuality, 0) != 0)
Greg Claytonc4ffd662013-03-08 01:37:30 +00001371 return true;
1372 }
1373 }
1374 }
1375 return false;
1376}
1377
Greg Clayton99558cc42015-08-24 23:46:31 +00001378CompilerDeclContext
1379SymbolFileDWARF::GetDeclContextForUID (lldb::user_id_t type_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001380{
Greg Clayton8b4edba2015-08-14 20:02:05 +00001381 if (UserIDMatches(type_uid))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001382 {
Greg Clayton8b4edba2015-08-14 20:02:05 +00001383 DWARFDebugInfo* debug_info = DebugInfo();
1384 if (debug_info)
1385 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001386 DWARFDIE die = debug_info->GetDIE(type_uid);
Greg Clayton8b4edba2015-08-14 20:02:05 +00001387 if (die)
1388 {
Greg Clayton261ac3f2015-08-28 01:01:03 +00001389 DWARFASTParser *dwarf_ast = die.GetDWARFParser();
1390 if (dwarf_ast)
1391 return dwarf_ast->GetDeclContextForUIDFromDWARF(die);
Greg Clayton8b4edba2015-08-14 20:02:05 +00001392 }
1393 }
Sean Callanan72e49402011-08-05 23:43:37 +00001394 }
Greg Clayton99558cc42015-08-24 23:46:31 +00001395 return CompilerDeclContext();
Sean Callanan72e49402011-08-05 23:43:37 +00001396}
1397
Greg Clayton99558cc42015-08-24 23:46:31 +00001398CompilerDeclContext
1399SymbolFileDWARF::GetDeclContextContainingUID (lldb::user_id_t type_uid)
Sean Callanan72e49402011-08-05 23:43:37 +00001400{
Greg Clayton81c22f62011-10-19 18:09:39 +00001401 if (UserIDMatches(type_uid))
Greg Clayton8b4edba2015-08-14 20:02:05 +00001402 {
1403 DWARFDebugInfo* debug_info = DebugInfo();
1404 if (debug_info)
1405 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001406 DWARFDIE die = debug_info->GetDIE(type_uid);
Greg Clayton8b4edba2015-08-14 20:02:05 +00001407 if (die)
1408 {
Greg Clayton261ac3f2015-08-28 01:01:03 +00001409 DWARFASTParser *dwarf_ast = die.GetDWARFParser();
1410 if (dwarf_ast)
1411 return dwarf_ast->GetDeclContextContainingUIDFromDWARF(die);
Greg Clayton8b4edba2015-08-14 20:02:05 +00001412 }
1413 }
1414 }
Greg Clayton99558cc42015-08-24 23:46:31 +00001415 return CompilerDeclContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001416}
1417
Greg Clayton99558cc42015-08-24 23:46:31 +00001418
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001419Type*
Greg Claytonc685f8e2010-09-15 04:15:46 +00001420SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001421{
Greg Clayton81c22f62011-10-19 18:09:39 +00001422 if (UserIDMatches(type_uid))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001423 {
Greg Clayton81c22f62011-10-19 18:09:39 +00001424 DWARFDebugInfo* debug_info = DebugInfo();
1425 if (debug_info)
Greg Claytonca512b32011-01-14 04:54:56 +00001426 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001427 DWARFDIE type_die = debug_info->GetDIE (type_uid);
1428 if (type_die)
1429 {
1430 const bool assert_not_being_parsed = true;
1431 return ResolveTypeUID (type_die, assert_not_being_parsed);
1432 }
Greg Claytonca512b32011-01-14 04:54:56 +00001433 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001434 }
1435 return NULL;
1436}
1437
Greg Claytoncab36a32011-12-08 05:16:30 +00001438Type*
Greg Clayton6071e6f2015-08-26 22:57:51 +00001439SymbolFileDWARF::ResolveTypeUID (const DWARFDIE &die, bool assert_not_being_parsed)
Sean Callanan5b26f272012-02-04 08:49:35 +00001440{
Greg Clayton6071e6f2015-08-26 22:57:51 +00001441 if (die)
Greg Claytoncab36a32011-12-08 05:16:30 +00001442 {
Greg Clayton5160ce52013-03-27 23:08:40 +00001443 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
Greg Clayton3bffb082011-12-10 02:15:28 +00001444 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00001445 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytone38a5ed2012-01-05 03:57:59 +00001446 "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s'",
Greg Clayton6071e6f2015-08-26 22:57:51 +00001447 die.GetOffset(),
1448 die.GetTagAsCString(),
1449 die.GetName());
Greg Clayton3bffb082011-12-10 02:15:28 +00001450
Greg Claytoncab36a32011-12-08 05:16:30 +00001451 // We might be coming in in the middle of a type tree (a class
1452 // withing a class, an enum within a class), so parse any needed
1453 // parent DIEs before we get to this one...
Greg Clayton6071e6f2015-08-26 22:57:51 +00001454 DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE (die);
1455 if (decl_ctx_die)
Greg Claytoncab36a32011-12-08 05:16:30 +00001456 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001457 if (log)
Greg Claytoncab36a32011-12-08 05:16:30 +00001458 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001459 switch (decl_ctx_die.Tag())
1460 {
1461 case DW_TAG_structure_type:
1462 case DW_TAG_union_type:
1463 case DW_TAG_class_type:
1464 {
1465 // Get the type, which could be a forward declaration
1466 if (log)
1467 GetObjectFile()->GetModule()->LogMessage (log,
1468 "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' resolve parent forward type for 0x%8.8x",
1469 die.GetOffset(),
1470 die.GetTagAsCString(),
1471 die.GetName(),
1472 decl_ctx_die.GetOffset());
1473 }
1474 break;
Greg Claytoncab36a32011-12-08 05:16:30 +00001475
Greg Clayton6071e6f2015-08-26 22:57:51 +00001476 default:
1477 break;
1478 }
1479 }
Greg Claytoncab36a32011-12-08 05:16:30 +00001480 }
Greg Clayton6071e6f2015-08-26 22:57:51 +00001481 return ResolveType (die);
Greg Claytoncab36a32011-12-08 05:16:30 +00001482 }
1483 return NULL;
1484}
1485
Greg Clayton6beaaa62011-01-17 03:46:26 +00001486// This function is used when SymbolFileDWARFDebugMap owns a bunch of
1487// SymbolFileDWARF objects to detect if this DWARF file is the one that
1488// can resolve a clang_type.
1489bool
Greg Claytona1e5dc82015-08-11 22:53:00 +00001490SymbolFileDWARF::HasForwardDeclForClangType (const CompilerType &clang_type)
Greg Clayton6beaaa62011-01-17 03:46:26 +00001491{
Greg Claytona1e5dc82015-08-11 22:53:00 +00001492 CompilerType clang_type_no_qualifiers = ClangASTContext::RemoveFastQualifiers(clang_type);
Greg Clayton5ce1a842015-08-27 18:09:44 +00001493 return m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers.GetOpaqueQualType()) != nullptr;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001494}
1495
1496
Greg Clayton57ee3062013-07-11 22:46:58 +00001497bool
Greg Clayton6dc8d582015-08-18 22:32:36 +00001498SymbolFileDWARF::CompleteType (CompilerType &clang_type)
Greg Clayton1be10fc2010-09-29 01:12:09 +00001499{
1500 // We have a struct/union/class/enum that needs to be fully resolved.
Greg Claytona1e5dc82015-08-11 22:53:00 +00001501 CompilerType clang_type_no_qualifiers = ClangASTContext::RemoveFastQualifiers(clang_type);
Greg Clayton57ee3062013-07-11 22:46:58 +00001502 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers.GetOpaqueQualType());
Greg Clayton1be10fc2010-09-29 01:12:09 +00001503 if (die == NULL)
Greg Clayton73b472d2010-10-27 03:32:59 +00001504 {
1505 // We have already resolved this type...
Greg Clayton57ee3062013-07-11 22:46:58 +00001506 return true;
Greg Clayton73b472d2010-10-27 03:32:59 +00001507 }
1508 // Once we start resolving this type, remove it from the forward declaration
1509 // map in case anyone child members or other types require this type to get resolved.
1510 // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
1511 // are done.
Greg Clayton57ee3062013-07-11 22:46:58 +00001512 m_forward_decl_clang_type_to_die.erase (clang_type_no_qualifiers.GetOpaqueQualType());
Greg Clayton1be10fc2010-09-29 01:12:09 +00001513
Greg Clayton450e3f32010-10-12 02:24:53 +00001514 DWARFDebugInfo* debug_info = DebugInfo();
Greg Clayton6071e6f2015-08-26 22:57:51 +00001515 DWARFDIE dwarf_die (debug_info->GetCompileUnitContainingDIE (die->GetOffset()), die);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001516 Type *type = m_die_to_type.lookup (die);
1517
Greg Clayton5160ce52013-03-27 23:08:40 +00001518 Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
Greg Clayton3bffb082011-12-10 02:15:28 +00001519 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00001520 GetObjectFile()->GetModule()->LogMessageVerboseBacktrace (log,
Daniel Malead01b2952012-11-29 21:49:15 +00001521 "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...",
Greg Clayton6071e6f2015-08-26 22:57:51 +00001522 dwarf_die.GetID(),
1523 dwarf_die.GetTagAsCString(),
Greg Claytond61c0fc2012-04-23 22:55:20 +00001524 type->GetName().AsCString());
Greg Clayton1be10fc2010-09-29 01:12:09 +00001525 assert (clang_type);
Greg Clayton6071e6f2015-08-26 22:57:51 +00001526 DWARFAttributes attributes;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001527
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001528
Greg Clayton261ac3f2015-08-28 01:01:03 +00001529 DWARFASTParser *dwarf_ast = dwarf_die.GetDWARFParser();
1530 if (dwarf_ast)
1531 return dwarf_ast->CompleteTypeFromDWARF (dwarf_die, type, clang_type);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001532
Ashok Thirumurthia4658a52013-07-30 14:58:39 +00001533 return false;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001534}
1535
Greg Clayton8b4edba2015-08-14 20:02:05 +00001536Type*
Greg Clayton6071e6f2015-08-26 22:57:51 +00001537SymbolFileDWARF::ResolveType (const DWARFDIE &die, bool assert_not_being_parsed)
Greg Clayton8b4edba2015-08-14 20:02:05 +00001538{
Greg Clayton6071e6f2015-08-26 22:57:51 +00001539 if (die)
Greg Clayton8b4edba2015-08-14 20:02:05 +00001540 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001541 Type *type = m_die_to_type.lookup (die.GetDIE());
Greg Claytoncab36a32011-12-08 05:16:30 +00001542
Greg Claytonc685f8e2010-09-15 04:15:46 +00001543 if (type == NULL)
Greg Clayton6071e6f2015-08-26 22:57:51 +00001544 type = GetTypeForDIE (die).get();
Greg Claytoncab36a32011-12-08 05:16:30 +00001545
Greg Clayton24739922010-10-13 03:15:28 +00001546 if (assert_not_being_parsed)
Jim Inghamc3549282012-01-11 02:21:12 +00001547 {
1548 if (type != DIE_IS_BEING_PARSED)
1549 return type;
1550
1551 GetObjectFile()->GetModule()->ReportError ("Parsing a die that is being parsed die: 0x%8.8x: %s %s",
Greg Clayton6071e6f2015-08-26 22:57:51 +00001552 die.GetOffset(),
1553 die.GetTagAsCString(),
1554 die.GetName());
Jim Inghamc3549282012-01-11 02:21:12 +00001555
1556 }
1557 else
1558 return type;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001559 }
Greg Clayton6071e6f2015-08-26 22:57:51 +00001560 return nullptr;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001561}
1562
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001563CompileUnit*
Greg Clayton53eb1c22012-04-02 22:59:12 +00001564SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001565{
1566 // Check if the symbol vendor already knows about this compile unit?
Greg Clayton53eb1c22012-04-02 22:59:12 +00001567 if (dwarf_cu->GetUserData() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001568 {
1569 // The symbol vendor doesn't know about this compile unit, we
1570 // need to parse and add it to the symbol vendor object.
Greg Clayton53eb1c22012-04-02 22:59:12 +00001571 return ParseCompileUnit(dwarf_cu, cu_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001572 }
Greg Clayton53eb1c22012-04-02 22:59:12 +00001573 return (CompileUnit*)dwarf_cu->GetUserData();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001574}
1575
Greg Clayton8b4edba2015-08-14 20:02:05 +00001576size_t
1577SymbolFileDWARF::GetObjCMethodDIEOffsets (ConstString class_name, DIEArray &method_die_offsets)
1578{
1579 method_die_offsets.clear();
1580 if (m_using_apple_tables)
1581 {
1582 if (m_apple_objc_ap.get())
1583 m_apple_objc_ap->FindByName(class_name.GetCString(), method_die_offsets);
1584 }
1585 else
1586 {
1587 if (!m_indexed)
1588 Index ();
1589
1590 m_objc_class_selectors_index.Find (class_name, method_die_offsets);
1591 }
1592 return method_die_offsets.size();
1593}
1594
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001595bool
Greg Clayton6071e6f2015-08-26 22:57:51 +00001596SymbolFileDWARF::GetFunction (const DWARFDIE &die, SymbolContext& sc)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001597{
Greg Clayton72310352013-02-23 04:12:47 +00001598 sc.Clear(false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001599
Greg Clayton6071e6f2015-08-26 22:57:51 +00001600 if (die)
1601 {
1602 // Check if the symbol vendor already knows about this compile unit?
1603 sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
1604
1605 sc.function = sc.comp_unit->FindFunctionByUID (die.GetID()).get();
1606 if (sc.function == NULL)
1607 sc.function = ParseCompileUnitFunction(sc, die);
1608
1609 if (sc.function)
1610 {
1611 sc.module_sp = sc.function->CalculateSymbolContextModule();
1612 return true;
1613 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00001614 }
1615
1616 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001617}
1618
Sean Callananf0c5aeb2015-04-20 16:31:29 +00001619void
1620SymbolFileDWARF::UpdateExternalModuleListIfNeeded()
1621{
1622 if (m_fetched_external_modules)
1623 return;
1624 m_fetched_external_modules = true;
1625
1626 DWARFDebugInfo * debug_info = DebugInfo();
1627 debug_info->GetNumCompileUnits();
1628
1629 const uint32_t num_compile_units = GetNumCompileUnits();
1630 for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
1631 {
1632 DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
1633
Greg Clayton5ce1a842015-08-27 18:09:44 +00001634 const DWARFDIE die = dwarf_cu->GetCompileUnitDIEOnly();
1635 if (die && die.HasChildren() == false)
Sean Callananf0c5aeb2015-04-20 16:31:29 +00001636 {
Greg Clayton5ce1a842015-08-27 18:09:44 +00001637 const uint64_t name_strp = die.GetAttributeValueAsUnsigned (DW_AT_name, UINT64_MAX);
1638 const uint64_t dwo_path_strp = die.GetAttributeValueAsUnsigned (DW_AT_GNU_dwo_name, UINT64_MAX);
Sean Callananf0c5aeb2015-04-20 16:31:29 +00001639
1640 if (name_strp != UINT64_MAX)
1641 {
1642 if (m_external_type_modules.find(dwo_path_strp) == m_external_type_modules.end())
1643 {
1644 const char *name = get_debug_str_data().PeekCStr(name_strp);
1645 const char *dwo_path = get_debug_str_data().PeekCStr(dwo_path_strp);
1646 if (name || dwo_path)
1647 {
1648 ModuleSP module_sp;
1649 if (dwo_path)
1650 {
1651 ModuleSpec dwo_module_spec;
1652 dwo_module_spec.GetFileSpec().SetFile(dwo_path, false);
1653 dwo_module_spec.GetArchitecture() = m_obj_file->GetModule()->GetArchitecture();
1654 //printf ("Loading dwo = '%s'\n", dwo_path);
1655 Error error = ModuleList::GetSharedModule (dwo_module_spec, module_sp, NULL, NULL, NULL);
1656 }
1657
1658 if (dwo_path_strp != LLDB_INVALID_UID)
1659 {
1660 m_external_type_modules[dwo_path_strp] = ClangModuleInfo { ConstString(name), module_sp };
1661 }
1662 else
1663 {
1664 // This hack should be removed promptly once clang emits both.
1665 m_external_type_modules[name_strp] = ClangModuleInfo { ConstString(name), module_sp };
1666 }
1667 }
1668 }
1669 }
1670 }
1671 }
1672}
Greg Clayton2501e5e2015-01-15 02:59:20 +00001673
1674SymbolFileDWARF::GlobalVariableMap &
1675SymbolFileDWARF::GetGlobalAranges()
1676{
1677 if (!m_global_aranges_ap)
1678 {
1679 m_global_aranges_ap.reset (new GlobalVariableMap());
1680
1681 ModuleSP module_sp = GetObjectFile()->GetModule();
1682 if (module_sp)
1683 {
1684 const size_t num_cus = module_sp->GetNumCompileUnits();
1685 for (size_t i = 0; i < num_cus; ++i)
1686 {
1687 CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(i);
1688 if (cu_sp)
1689 {
1690 VariableListSP globals_sp = cu_sp->GetVariableList(true);
1691 if (globals_sp)
1692 {
1693 const size_t num_globals = globals_sp->GetSize();
1694 for (size_t g = 0; g < num_globals; ++g)
1695 {
1696 VariableSP var_sp = globals_sp->GetVariableAtIndex(g);
1697 if (var_sp && !var_sp->GetLocationIsConstantValueData())
1698 {
1699 const DWARFExpression &location = var_sp->LocationExpression();
1700 Value location_result;
1701 Error error;
1702 if (location.Evaluate(NULL, NULL, NULL, LLDB_INVALID_ADDRESS, NULL, location_result, &error))
1703 {
1704 if (location_result.GetValueType() == Value::eValueTypeFileAddress)
1705 {
1706 lldb::addr_t file_addr = location_result.GetScalar().ULongLong();
1707 lldb::addr_t byte_size = 1;
1708 if (var_sp->GetType())
1709 byte_size = var_sp->GetType()->GetByteSize();
1710 m_global_aranges_ap->Append(GlobalVariableMap::Entry(file_addr, byte_size, var_sp.get()));
1711 }
1712 }
1713 }
1714 }
1715 }
1716 }
1717 }
1718 }
1719 m_global_aranges_ap->Sort();
1720 }
1721 return *m_global_aranges_ap;
1722}
1723
1724
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001725uint32_t
1726SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
1727{
1728 Timer scoped_timer(__PRETTY_FUNCTION__,
Daniel Malead01b2952012-11-29 21:49:15 +00001729 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%" PRIx64 " }, resolve_scope = 0x%8.8x)",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001730 static_cast<void*>(so_addr.GetSection().get()),
1731 so_addr.GetOffset(), resolve_scope);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001732 uint32_t resolved = 0;
Greg Clayton2501e5e2015-01-15 02:59:20 +00001733 if (resolve_scope & ( eSymbolContextCompUnit |
1734 eSymbolContextFunction |
1735 eSymbolContextBlock |
1736 eSymbolContextLineEntry |
1737 eSymbolContextVariable ))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001738 {
1739 lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
1740
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001741 DWARFDebugInfo* debug_info = DebugInfo();
Greg Claytond4a2b372011-09-12 23:21:58 +00001742 if (debug_info)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001743 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00001744 const dw_offset_t cu_offset = debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr);
Greg Clayton2501e5e2015-01-15 02:59:20 +00001745 if (cu_offset == DW_INVALID_OFFSET)
1746 {
1747 // Global variables are not in the compile unit address ranges. The only way to
1748 // currently find global variables is to iterate over the .debug_pubnames or the
1749 // __apple_names table and find all items in there that point to DW_TAG_variable
1750 // DIEs and then find the address that matches.
1751 if (resolve_scope & eSymbolContextVariable)
1752 {
1753 GlobalVariableMap &map = GetGlobalAranges();
1754 const GlobalVariableMap::Entry *entry = map.FindEntryThatContains(file_vm_addr);
1755 if (entry && entry->data)
1756 {
1757 Variable *variable = entry->data;
1758 SymbolContextScope *scc = variable->GetSymbolContextScope();
1759 if (scc)
1760 {
1761 scc->CalculateSymbolContext(&sc);
1762 sc.variable = variable;
1763 }
1764 return sc.GetResolvedMask();
1765 }
1766 }
1767 }
1768 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001769 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00001770 uint32_t cu_idx = DW_INVALID_INDEX;
Greg Clayton6071e6f2015-08-26 22:57:51 +00001771 DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx);
Greg Clayton53eb1c22012-04-02 22:59:12 +00001772 if (dwarf_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001773 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00001774 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
Greg Clayton526a4ae2012-05-16 22:09:01 +00001775 if (sc.comp_unit)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001776 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00001777 resolved |= eSymbolContextCompUnit;
1778
Greg Clayton6ab80132012-12-12 17:30:52 +00001779 bool force_check_line_table = false;
Greg Clayton526a4ae2012-05-16 22:09:01 +00001780 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1781 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001782 DWARFDIE function_die = dwarf_cu->LookupAddress(file_vm_addr);
1783 DWARFDIE block_die;
1784 if (function_die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001785 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001786 sc.function = sc.comp_unit->FindFunctionByUID (function_die.GetID()).get();
Greg Clayton526a4ae2012-05-16 22:09:01 +00001787 if (sc.function == NULL)
Greg Clayton6071e6f2015-08-26 22:57:51 +00001788 sc.function = ParseCompileUnitFunction(sc, function_die);
1789
1790 if (sc.function && (resolve_scope & eSymbolContextBlock))
1791 block_die = function_die.LookupDeepestBlock(file_vm_addr);
Greg Clayton526a4ae2012-05-16 22:09:01 +00001792 }
1793 else
1794 {
1795 // We might have had a compile unit that had discontiguous
1796 // address ranges where the gaps are symbols that don't have
1797 // any debug info. Discontiguous compile unit address ranges
1798 // should only happen when there aren't other functions from
1799 // other compile units in these gaps. This helps keep the size
1800 // of the aranges down.
Greg Clayton6ab80132012-12-12 17:30:52 +00001801 force_check_line_table = true;
Greg Clayton526a4ae2012-05-16 22:09:01 +00001802 }
1803
1804 if (sc.function != NULL)
1805 {
1806 resolved |= eSymbolContextFunction;
1807
1808 if (resolve_scope & eSymbolContextBlock)
1809 {
1810 Block& block = sc.function->GetBlock (true);
1811
Greg Clayton6071e6f2015-08-26 22:57:51 +00001812 if (block_die)
1813 sc.block = block.FindBlockByID (block_die.GetID());
Greg Clayton526a4ae2012-05-16 22:09:01 +00001814 else
Greg Clayton6071e6f2015-08-26 22:57:51 +00001815 sc.block = block.FindBlockByID (function_die.GetID());
Greg Clayton526a4ae2012-05-16 22:09:01 +00001816 if (sc.block)
1817 resolved |= eSymbolContextBlock;
1818 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001819 }
1820 }
Greg Clayton6ab80132012-12-12 17:30:52 +00001821
1822 if ((resolve_scope & eSymbolContextLineEntry) || force_check_line_table)
1823 {
1824 LineTable *line_table = sc.comp_unit->GetLineTable();
1825 if (line_table != NULL)
1826 {
Greg Clayton9422dd62013-03-04 21:46:16 +00001827 // And address that makes it into this function should be in terms
1828 // of this debug file if there is no debug map, or it will be an
1829 // address in the .o file which needs to be fixed up to be in terms
1830 // of the debug map executable. Either way, calling FixupAddress()
1831 // will work for us.
1832 Address exe_so_addr (so_addr);
1833 if (FixupAddress(exe_so_addr))
Greg Clayton6ab80132012-12-12 17:30:52 +00001834 {
Greg Clayton9422dd62013-03-04 21:46:16 +00001835 if (line_table->FindLineEntryByAddress (exe_so_addr, sc.line_entry))
Greg Clayton6ab80132012-12-12 17:30:52 +00001836 {
1837 resolved |= eSymbolContextLineEntry;
1838 }
1839 }
Greg Clayton6ab80132012-12-12 17:30:52 +00001840 }
1841 }
1842
1843 if (force_check_line_table && !(resolved & eSymbolContextLineEntry))
1844 {
1845 // We might have had a compile unit that had discontiguous
1846 // address ranges where the gaps are symbols that don't have
1847 // any debug info. Discontiguous compile unit address ranges
1848 // should only happen when there aren't other functions from
1849 // other compile units in these gaps. This helps keep the size
1850 // of the aranges down.
1851 sc.comp_unit = NULL;
1852 resolved &= ~eSymbolContextCompUnit;
1853 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001854 }
Greg Clayton526a4ae2012-05-16 22:09:01 +00001855 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001856 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00001857 GetObjectFile()->GetModule()->ReportWarning ("0x%8.8x: compile unit %u failed to create a valid lldb_private::CompileUnit class.",
1858 cu_offset,
1859 cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001860 }
1861 }
1862 }
1863 }
1864 }
1865 return resolved;
1866}
1867
1868
1869
1870uint32_t
1871SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
1872{
1873 const uint32_t prev_size = sc_list.GetSize();
1874 if (resolve_scope & eSymbolContextCompUnit)
1875 {
1876 DWARFDebugInfo* debug_info = DebugInfo();
1877 if (debug_info)
1878 {
1879 uint32_t cu_idx;
Greg Clayton53eb1c22012-04-02 22:59:12 +00001880 DWARFCompileUnit* dwarf_cu = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001881
Greg Clayton53eb1c22012-04-02 22:59:12 +00001882 for (cu_idx = 0; (dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001883 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00001884 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
Sean Callananddd7a2a2013-10-03 22:27:29 +00001885 const bool full_match = (bool)file_spec.GetDirectory();
Greg Clayton1f746072012-08-29 21:13:06 +00001886 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Equal(file_spec, *dc_cu, full_match);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001887 if (check_inlines || file_spec_matches_cu_file_spec)
1888 {
1889 SymbolContext sc (m_obj_file->GetModule());
Greg Clayton53eb1c22012-04-02 22:59:12 +00001890 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
Greg Clayton526a4ae2012-05-16 22:09:01 +00001891 if (sc.comp_unit)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001892 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00001893 uint32_t file_idx = UINT32_MAX;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001894
Greg Clayton526a4ae2012-05-16 22:09:01 +00001895 // If we are looking for inline functions only and we don't
1896 // find it in the support files, we are done.
1897 if (check_inlines)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001898 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00001899 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
1900 if (file_idx == UINT32_MAX)
1901 continue;
1902 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001903
Greg Clayton526a4ae2012-05-16 22:09:01 +00001904 if (line != 0)
1905 {
1906 LineTable *line_table = sc.comp_unit->GetLineTable();
1907
1908 if (line_table != NULL && line != 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001909 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00001910 // We will have already looked up the file index if
1911 // we are searching for inline entries.
1912 if (!check_inlines)
1913 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001914
Greg Clayton526a4ae2012-05-16 22:09:01 +00001915 if (file_idx != UINT32_MAX)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001916 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00001917 uint32_t found_line;
1918 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
1919 found_line = sc.line_entry.line;
1920
1921 while (line_idx != UINT32_MAX)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001922 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00001923 sc.function = NULL;
1924 sc.block = NULL;
1925 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001926 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00001927 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
1928 if (file_vm_addr != LLDB_INVALID_ADDRESS)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001929 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001930 DWARFDIE function_die = dwarf_cu->LookupAddress(file_vm_addr);
1931 DWARFDIE block_die;
1932 if (function_die)
Greg Clayton526a4ae2012-05-16 22:09:01 +00001933 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001934 sc.function = sc.comp_unit->FindFunctionByUID (function_die.GetID()).get();
Greg Clayton526a4ae2012-05-16 22:09:01 +00001935 if (sc.function == NULL)
Greg Clayton6071e6f2015-08-26 22:57:51 +00001936 sc.function = ParseCompileUnitFunction(sc, function_die);
1937
1938 if (sc.function && (resolve_scope & eSymbolContextBlock))
1939 block_die = function_die.LookupDeepestBlock(file_vm_addr);
Greg Clayton526a4ae2012-05-16 22:09:01 +00001940 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001941
Greg Clayton526a4ae2012-05-16 22:09:01 +00001942 if (sc.function != NULL)
1943 {
1944 Block& block = sc.function->GetBlock (true);
1945
Greg Clayton6071e6f2015-08-26 22:57:51 +00001946 if (block_die)
1947 sc.block = block.FindBlockByID (block_die.GetID());
1948 else if (function_die)
1949 sc.block = block.FindBlockByID (function_die.GetID());
Greg Clayton526a4ae2012-05-16 22:09:01 +00001950 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001951 }
1952 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001953
Greg Clayton526a4ae2012-05-16 22:09:01 +00001954 sc_list.Append(sc);
1955 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
1956 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001957 }
1958 }
Greg Clayton526a4ae2012-05-16 22:09:01 +00001959 else if (file_spec_matches_cu_file_spec && !check_inlines)
1960 {
1961 // only append the context if we aren't looking for inline call sites
1962 // by file and line and if the file spec matches that of the compile unit
1963 sc_list.Append(sc);
1964 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001965 }
1966 else if (file_spec_matches_cu_file_spec && !check_inlines)
1967 {
1968 // only append the context if we aren't looking for inline call sites
1969 // by file and line and if the file spec matches that of the compile unit
1970 sc_list.Append(sc);
1971 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001972
Greg Clayton526a4ae2012-05-16 22:09:01 +00001973 if (!check_inlines)
1974 break;
1975 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001976 }
1977 }
1978 }
1979 }
1980 return sc_list.GetSize() - prev_size;
1981}
1982
1983void
1984SymbolFileDWARF::Index ()
1985{
1986 if (m_indexed)
1987 return;
1988 m_indexed = true;
1989 Timer scoped_timer (__PRETTY_FUNCTION__,
1990 "SymbolFileDWARF::Index (%s)",
Jim Ingham4af59612014-12-19 19:20:44 +00001991 GetObjectFile()->GetFileSpec().GetFilename().AsCString("<Unknown>"));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001992
1993 DWARFDebugInfo* debug_info = DebugInfo();
1994 if (debug_info)
1995 {
1996 uint32_t cu_idx = 0;
1997 const uint32_t num_compile_units = GetNumCompileUnits();
1998 for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
1999 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00002000 DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002001
Greg Clayton53eb1c22012-04-02 22:59:12 +00002002 bool clear_dies = dwarf_cu->ExtractDIEsIfNeeded (false) > 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002003
Greg Clayton53eb1c22012-04-02 22:59:12 +00002004 dwarf_cu->Index (cu_idx,
2005 m_function_basename_index,
2006 m_function_fullname_index,
2007 m_function_method_index,
2008 m_function_selector_index,
2009 m_objc_class_selectors_index,
2010 m_global_index,
2011 m_type_index,
2012 m_namespace_index);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002013
2014 // Keep memory down by clearing DIEs if this generate function
2015 // caused them to be parsed
2016 if (clear_dies)
Greg Clayton53eb1c22012-04-02 22:59:12 +00002017 dwarf_cu->ClearDIEs (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002018 }
2019
Greg Claytond4a2b372011-09-12 23:21:58 +00002020 m_function_basename_index.Finalize();
2021 m_function_fullname_index.Finalize();
2022 m_function_method_index.Finalize();
2023 m_function_selector_index.Finalize();
2024 m_objc_class_selectors_index.Finalize();
2025 m_global_index.Finalize();
2026 m_type_index.Finalize();
2027 m_namespace_index.Finalize();
Greg Claytonc685f8e2010-09-15 04:15:46 +00002028
Greg Clayton24739922010-10-13 03:15:28 +00002029#if defined (ENABLE_DEBUG_PRINTF)
Greg Clayton7bd65b92011-02-09 23:39:34 +00002030 StreamFile s(stdout, false);
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00002031 s.Printf ("DWARF index for '%s':",
2032 GetObjectFile()->GetFileSpec().GetPath().c_str());
Greg Claytonba2d22d2010-11-13 22:57:37 +00002033 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
2034 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
2035 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
2036 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
2037 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
2038 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
Greg Clayton69b04882010-10-15 02:03:22 +00002039 s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
Bruce Mitchenere171da52015-07-22 00:16:02 +00002040 s.Printf("\nNamespaces:\n") m_namespace_index.Dump (&s);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002041#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002042 }
2043}
Greg Claytonbfe3dd42011-10-13 00:00:53 +00002044
2045bool
Greg Clayton99558cc42015-08-24 23:46:31 +00002046SymbolFileDWARF::DeclContextMatchesThisSymbolFile (const lldb_private::CompilerDeclContext *decl_ctx)
Greg Claytonbfe3dd42011-10-13 00:00:53 +00002047{
Greg Clayton99558cc42015-08-24 23:46:31 +00002048 if (decl_ctx == nullptr || !decl_ctx->IsValid())
Greg Claytonbfe3dd42011-10-13 00:00:53 +00002049 {
2050 // Invalid namespace decl which means we aren't matching only things
2051 // in this symbol file, so return true to indicate it matches this
2052 // symbol file.
2053 return true;
2054 }
Greg Claytonbfe3dd42011-10-13 00:00:53 +00002055
Greg Clayton99558cc42015-08-24 23:46:31 +00002056 if ((TypeSystem *)&GetClangASTContext() == decl_ctx->GetTypeSystem())
2057 return true; // The type systems match, return true
Greg Claytonbfe3dd42011-10-13 00:00:53 +00002058
2059 // The namespace AST was valid, and it does not match...
Greg Clayton5160ce52013-03-27 23:08:40 +00002060 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Sean Callananc41e68b2011-10-13 21:08:11 +00002061
2062 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002063 GetObjectFile()->GetModule()->LogMessage(log, "Valid namespace does not match symbol file");
Sean Callananc41e68b2011-10-13 21:08:11 +00002064
Greg Claytonbfe3dd42011-10-13 00:00:53 +00002065 return false;
2066}
2067
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002068uint32_t
Greg Clayton99558cc42015-08-24 23:46:31 +00002069SymbolFileDWARF::FindGlobalVariables (const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, VariableList& variables)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002070{
Greg Clayton5160ce52013-03-27 23:08:40 +00002071 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Greg Clayton21f2a492011-10-06 00:09:08 +00002072
2073 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002074 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton99558cc42015-08-24 23:46:31 +00002075 "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", parent_decl_ctx=%p, append=%u, max_matches=%u, variables)",
Greg Claytone38a5ed2012-01-05 03:57:59 +00002076 name.GetCString(),
Greg Clayton99558cc42015-08-24 23:46:31 +00002077 static_cast<const void*>(parent_decl_ctx),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002078 append, max_matches);
2079
Greg Clayton99558cc42015-08-24 23:46:31 +00002080 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
Ed Maste4c24b122013-10-17 20:13:14 +00002081 return 0;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002082
Greg Claytonc685f8e2010-09-15 04:15:46 +00002083 DWARFDebugInfo* info = DebugInfo();
2084 if (info == NULL)
2085 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002086
2087 // If we aren't appending the results to this list, then clear the list
2088 if (!append)
2089 variables.Clear();
2090
2091 // Remember how many variables are in the list before we search in case
2092 // we are appending the results to a variable list.
2093 const uint32_t original_size = variables.GetSize();
2094
Greg Claytond4a2b372011-09-12 23:21:58 +00002095 DIEArray die_offsets;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002096
Greg Clayton97fbc342011-10-20 22:30:33 +00002097 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00002098 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002099 if (m_apple_names_ap.get())
2100 {
2101 const char *name_cstr = name.GetCString();
Jim Inghamfa39bb42014-10-25 00:33:55 +00002102 llvm::StringRef basename;
2103 llvm::StringRef context;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002104
Jim Inghamaa816b82015-09-02 01:59:14 +00002105 if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context, basename))
Jim Inghamfa39bb42014-10-25 00:33:55 +00002106 basename = name_cstr;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002107
Jim Inghamfa39bb42014-10-25 00:33:55 +00002108 m_apple_names_ap->FindByName (basename.data(), die_offsets);
Greg Clayton97fbc342011-10-20 22:30:33 +00002109 }
Greg Clayton7f995132011-10-04 22:41:51 +00002110 }
2111 else
2112 {
2113 // Index the DWARF if we haven't already
2114 if (!m_indexed)
2115 Index ();
2116
2117 m_global_index.Find (name, die_offsets);
2118 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002119
Greg Clayton437a1352012-04-09 22:43:43 +00002120 const size_t num_die_matches = die_offsets.size();
2121 if (num_die_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002122 {
Greg Clayton7f995132011-10-04 22:41:51 +00002123 SymbolContext sc;
Greg Claytone72dfb32012-02-24 01:59:29 +00002124 sc.module_sp = m_obj_file->GetModule();
Greg Clayton7f995132011-10-04 22:41:51 +00002125 assert (sc.module_sp);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002126
Greg Claytond4a2b372011-09-12 23:21:58 +00002127 DWARFDebugInfo* debug_info = DebugInfo();
Greg Clayton437a1352012-04-09 22:43:43 +00002128 bool done = false;
2129 for (size_t i=0; i<num_die_matches && !done; ++i)
Greg Claytond4a2b372011-09-12 23:21:58 +00002130 {
2131 const dw_offset_t die_offset = die_offsets[i];
Greg Clayton6071e6f2015-08-26 22:57:51 +00002132 DWARFDIE die = debug_info->GetDIE (die_offset);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002133
Greg Clayton95d87902011-11-11 03:16:25 +00002134 if (die)
2135 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002136 switch (die.Tag())
Greg Clayton437a1352012-04-09 22:43:43 +00002137 {
2138 default:
2139 case DW_TAG_subprogram:
2140 case DW_TAG_inlined_subroutine:
2141 case DW_TAG_try_block:
2142 case DW_TAG_catch_block:
2143 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002144
Greg Clayton437a1352012-04-09 22:43:43 +00002145 case DW_TAG_variable:
2146 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002147 sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002148
Greg Clayton99558cc42015-08-24 23:46:31 +00002149 if (parent_decl_ctx)
Greg Clayton8b4edba2015-08-14 20:02:05 +00002150 {
Greg Clayton261ac3f2015-08-28 01:01:03 +00002151 DWARFASTParser *dwarf_ast = die.GetDWARFParser();
2152 if (dwarf_ast)
Greg Clayton99558cc42015-08-24 23:46:31 +00002153 {
Greg Clayton261ac3f2015-08-28 01:01:03 +00002154 CompilerDeclContext actual_parent_decl_ctx = dwarf_ast->GetDeclContextContainingUIDFromDWARF (die);
Greg Clayton99558cc42015-08-24 23:46:31 +00002155 if (!actual_parent_decl_ctx || actual_parent_decl_ctx != *parent_decl_ctx)
2156 continue;
2157 }
Greg Clayton8b4edba2015-08-14 20:02:05 +00002158 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002159
Greg Clayton6071e6f2015-08-26 22:57:51 +00002160 ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002161
Greg Clayton437a1352012-04-09 22:43:43 +00002162 if (variables.GetSize() - original_size >= max_matches)
2163 done = true;
2164 }
2165 break;
2166 }
Greg Clayton95d87902011-11-11 03:16:25 +00002167 }
2168 else
2169 {
2170 if (m_using_apple_tables)
2171 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00002172 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')\n",
2173 die_offset, name.GetCString());
Greg Clayton95d87902011-11-11 03:16:25 +00002174 }
2175 }
Greg Claytond4a2b372011-09-12 23:21:58 +00002176 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002177 }
2178
2179 // Return the number of variable that were appended to the list
Greg Clayton437a1352012-04-09 22:43:43 +00002180 const uint32_t num_matches = variables.GetSize() - original_size;
2181 if (log && num_matches > 0)
2182 {
Greg Clayton5160ce52013-03-27 23:08:40 +00002183 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton99558cc42015-08-24 23:46:31 +00002184 "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", parent_decl_ctx=%p, append=%u, max_matches=%u, variables) => %u",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002185 name.GetCString(),
Greg Clayton99558cc42015-08-24 23:46:31 +00002186 static_cast<const void*>(parent_decl_ctx),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002187 append, max_matches,
Greg Clayton437a1352012-04-09 22:43:43 +00002188 num_matches);
2189 }
2190 return num_matches;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002191}
2192
2193uint32_t
2194SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
2195{
Greg Clayton5160ce52013-03-27 23:08:40 +00002196 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002197
Greg Clayton21f2a492011-10-06 00:09:08 +00002198 if (log)
2199 {
Greg Clayton5160ce52013-03-27 23:08:40 +00002200 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytone38a5ed2012-01-05 03:57:59 +00002201 "SymbolFileDWARF::FindGlobalVariables (regex=\"%s\", append=%u, max_matches=%u, variables)",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002202 regex.GetText(), append,
Greg Claytone38a5ed2012-01-05 03:57:59 +00002203 max_matches);
Greg Clayton21f2a492011-10-06 00:09:08 +00002204 }
2205
Greg Claytonc685f8e2010-09-15 04:15:46 +00002206 DWARFDebugInfo* info = DebugInfo();
2207 if (info == NULL)
2208 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002209
2210 // If we aren't appending the results to this list, then clear the list
2211 if (!append)
2212 variables.Clear();
2213
2214 // Remember how many variables are in the list before we search in case
2215 // we are appending the results to a variable list.
2216 const uint32_t original_size = variables.GetSize();
2217
Greg Clayton7f995132011-10-04 22:41:51 +00002218 DIEArray die_offsets;
2219
Greg Clayton97fbc342011-10-20 22:30:33 +00002220 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00002221 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002222 if (m_apple_names_ap.get())
Greg Claytond1767f02011-12-08 02:13:16 +00002223 {
2224 DWARFMappedHash::DIEInfoArray hash_data_array;
2225 if (m_apple_names_ap->AppendAllDIEsThatMatchingRegex (regex, hash_data_array))
2226 DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
2227 }
Greg Clayton7f995132011-10-04 22:41:51 +00002228 }
2229 else
2230 {
2231 // Index the DWARF if we haven't already
2232 if (!m_indexed)
2233 Index ();
2234
2235 m_global_index.Find (regex, die_offsets);
2236 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002237
Greg Claytonc685f8e2010-09-15 04:15:46 +00002238 SymbolContext sc;
Greg Claytone72dfb32012-02-24 01:59:29 +00002239 sc.module_sp = m_obj_file->GetModule();
Greg Claytonc685f8e2010-09-15 04:15:46 +00002240 assert (sc.module_sp);
2241
Greg Clayton7f995132011-10-04 22:41:51 +00002242 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00002243 if (num_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002244 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002245 DWARFDebugInfo* debug_info = DebugInfo();
2246 for (size_t i=0; i<num_matches; ++i)
2247 {
2248 const dw_offset_t die_offset = die_offsets[i];
Greg Clayton6071e6f2015-08-26 22:57:51 +00002249 DWARFDIE die = debug_info->GetDIE (die_offset);
Greg Clayton95d87902011-11-11 03:16:25 +00002250
2251 if (die)
2252 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002253 sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002254
Greg Clayton6071e6f2015-08-26 22:57:51 +00002255 ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002256
Greg Clayton95d87902011-11-11 03:16:25 +00002257 if (variables.GetSize() - original_size >= max_matches)
2258 break;
2259 }
2260 else
2261 {
2262 if (m_using_apple_tables)
2263 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00002264 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for regex '%s')\n",
2265 die_offset, regex.GetText());
Greg Clayton95d87902011-11-11 03:16:25 +00002266 }
2267 }
Greg Claytond4a2b372011-09-12 23:21:58 +00002268 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002269 }
2270
2271 // Return the number of variable that were appended to the list
2272 return variables.GetSize() - original_size;
2273}
2274
Greg Claytonaa044962011-10-13 00:59:38 +00002275
Jim Ingham4cda6e02011-10-07 22:23:45 +00002276bool
2277SymbolFileDWARF::ResolveFunction (dw_offset_t die_offset,
Pavel Labatha73d6572015-03-13 10:22:00 +00002278 bool include_inlines,
Jim Ingham4cda6e02011-10-07 22:23:45 +00002279 SymbolContextList& sc_list)
Greg Clayton9e315582011-09-02 04:03:59 +00002280{
Greg Clayton6071e6f2015-08-26 22:57:51 +00002281 DWARFDIE die = DebugInfo()->GetDIE (die_offset);
2282 return ResolveFunction (die, include_inlines, sc_list);
Greg Claytonaa044962011-10-13 00:59:38 +00002283}
2284
2285
2286bool
Greg Clayton6071e6f2015-08-26 22:57:51 +00002287SymbolFileDWARF::ResolveFunction (const DWARFDIE &orig_die,
Pavel Labatha73d6572015-03-13 10:22:00 +00002288 bool include_inlines,
Greg Claytonaa044962011-10-13 00:59:38 +00002289 SymbolContextList& sc_list)
2290{
Greg Clayton9e315582011-09-02 04:03:59 +00002291 SymbolContext sc;
Greg Claytonaa044962011-10-13 00:59:38 +00002292
Greg Clayton6071e6f2015-08-26 22:57:51 +00002293 if (!orig_die)
Greg Claytonaa044962011-10-13 00:59:38 +00002294 return false;
2295
Jim Ingham4cda6e02011-10-07 22:23:45 +00002296 // If we were passed a die that is not a function, just return false...
Greg Clayton6071e6f2015-08-26 22:57:51 +00002297 if (!(orig_die.Tag() == DW_TAG_subprogram || (include_inlines && orig_die.Tag() == DW_TAG_inlined_subroutine)))
Jim Ingham4cda6e02011-10-07 22:23:45 +00002298 return false;
Greg Clayton6071e6f2015-08-26 22:57:51 +00002299
2300 DWARFDIE die = orig_die;
2301 DWARFDIE inlined_die;
2302 if (die.Tag() == DW_TAG_inlined_subroutine)
Greg Clayton9e315582011-09-02 04:03:59 +00002303 {
Jim Ingham4cda6e02011-10-07 22:23:45 +00002304 inlined_die = die;
Greg Clayton9e315582011-09-02 04:03:59 +00002305
Greg Clayton6071e6f2015-08-26 22:57:51 +00002306 while (1)
Greg Clayton2bc22f82011-09-30 03:20:47 +00002307 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002308 die = die.GetParent();
2309
2310 if (die)
2311 {
2312 if (die.Tag() == DW_TAG_subprogram)
2313 break;
2314 }
2315 else
Jim Ingham4cda6e02011-10-07 22:23:45 +00002316 break;
Greg Clayton9e315582011-09-02 04:03:59 +00002317 }
2318 }
Greg Clayton6071e6f2015-08-26 22:57:51 +00002319 assert (die && die.Tag() == DW_TAG_subprogram);
2320 if (GetFunction (die, sc))
Jim Ingham4cda6e02011-10-07 22:23:45 +00002321 {
2322 Address addr;
2323 // Parse all blocks if needed
2324 if (inlined_die)
2325 {
Greg Claytonf7bb1fb2015-01-15 03:13:44 +00002326 Block &function_block = sc.function->GetBlock (true);
Greg Clayton6071e6f2015-08-26 22:57:51 +00002327 sc.block = function_block.FindBlockByID (inlined_die.GetID());
Greg Claytonf7bb1fb2015-01-15 03:13:44 +00002328 if (sc.block == NULL)
Greg Clayton6071e6f2015-08-26 22:57:51 +00002329 sc.block = function_block.FindBlockByID (inlined_die.GetOffset());
Greg Claytonf7bb1fb2015-01-15 03:13:44 +00002330 if (sc.block == NULL || sc.block->GetStartAddress (addr) == false)
Jim Ingham4cda6e02011-10-07 22:23:45 +00002331 addr.Clear();
2332 }
2333 else
2334 {
2335 sc.block = NULL;
2336 addr = sc.function->GetAddressRange().GetBaseAddress();
2337 }
2338
2339 if (addr.IsValid())
2340 {
Jim Ingham4cda6e02011-10-07 22:23:45 +00002341 sc_list.Append(sc);
Greg Claytonaa044962011-10-13 00:59:38 +00002342 return true;
Jim Ingham4cda6e02011-10-07 22:23:45 +00002343 }
2344 }
2345
Greg Claytonaa044962011-10-13 00:59:38 +00002346 return false;
Greg Clayton9e315582011-09-02 04:03:59 +00002347}
2348
Greg Clayton7f995132011-10-04 22:41:51 +00002349void
2350SymbolFileDWARF::FindFunctions (const ConstString &name,
2351 const NameToDIE &name_to_die,
Pavel Labatha73d6572015-03-13 10:22:00 +00002352 bool include_inlines,
Greg Clayton7f995132011-10-04 22:41:51 +00002353 SymbolContextList& sc_list)
2354{
Greg Claytond4a2b372011-09-12 23:21:58 +00002355 DIEArray die_offsets;
Greg Clayton7f995132011-10-04 22:41:51 +00002356 if (name_to_die.Find (name, die_offsets))
2357 {
Pavel Labatha73d6572015-03-13 10:22:00 +00002358 ParseFunctions (die_offsets, include_inlines, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00002359 }
2360}
2361
2362
2363void
2364SymbolFileDWARF::FindFunctions (const RegularExpression &regex,
2365 const NameToDIE &name_to_die,
Pavel Labatha73d6572015-03-13 10:22:00 +00002366 bool include_inlines,
Greg Clayton7f995132011-10-04 22:41:51 +00002367 SymbolContextList& sc_list)
2368{
2369 DIEArray die_offsets;
2370 if (name_to_die.Find (regex, die_offsets))
2371 {
Pavel Labatha73d6572015-03-13 10:22:00 +00002372 ParseFunctions (die_offsets, include_inlines, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00002373 }
2374}
2375
2376
2377void
2378SymbolFileDWARF::FindFunctions (const RegularExpression &regex,
2379 const DWARFMappedHash::MemoryTable &memory_table,
Pavel Labatha73d6572015-03-13 10:22:00 +00002380 bool include_inlines,
Greg Clayton7f995132011-10-04 22:41:51 +00002381 SymbolContextList& sc_list)
2382{
2383 DIEArray die_offsets;
Greg Claytond1767f02011-12-08 02:13:16 +00002384 DWARFMappedHash::DIEInfoArray hash_data_array;
2385 if (memory_table.AppendAllDIEsThatMatchingRegex (regex, hash_data_array))
Greg Clayton7f995132011-10-04 22:41:51 +00002386 {
Greg Claytond1767f02011-12-08 02:13:16 +00002387 DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
Pavel Labatha73d6572015-03-13 10:22:00 +00002388 ParseFunctions (die_offsets, include_inlines, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00002389 }
2390}
2391
2392void
2393SymbolFileDWARF::ParseFunctions (const DIEArray &die_offsets,
Pavel Labatha73d6572015-03-13 10:22:00 +00002394 bool include_inlines,
Greg Clayton7f995132011-10-04 22:41:51 +00002395 SymbolContextList& sc_list)
2396{
2397 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00002398 if (num_matches)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002399 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002400 for (size_t i=0; i<num_matches; ++i)
Greg Claytond7e05462010-11-14 00:22:48 +00002401 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002402 const dw_offset_t die_offset = die_offsets[i];
Greg Clayton6071e6f2015-08-26 22:57:51 +00002403 ResolveFunction (die_offset, include_inlines, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002404 }
2405 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002406}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002407
Jim Ingham4cda6e02011-10-07 22:23:45 +00002408bool
Greg Clayton99558cc42015-08-24 23:46:31 +00002409SymbolFileDWARF::DIEInDeclContext (const CompilerDeclContext *decl_ctx,
Greg Clayton6071e6f2015-08-26 22:57:51 +00002410 const DWARFDIE &die)
Greg Clayton99558cc42015-08-24 23:46:31 +00002411{
2412 // If we have no parent decl context to match this DIE matches, and if the parent
2413 // decl context isn't valid, we aren't trying to look for any particular decl
2414 // context so any die matches.
2415 if (decl_ctx == nullptr || !decl_ctx->IsValid())
2416 return true;
2417
Greg Clayton6071e6f2015-08-26 22:57:51 +00002418 if (die)
Greg Clayton99558cc42015-08-24 23:46:31 +00002419 {
Greg Clayton261ac3f2015-08-28 01:01:03 +00002420 DWARFASTParser *dwarf_ast = die.GetDWARFParser();
2421 if (dwarf_ast)
Greg Clayton99558cc42015-08-24 23:46:31 +00002422 {
Greg Clayton261ac3f2015-08-28 01:01:03 +00002423 CompilerDeclContext actual_decl_ctx = dwarf_ast->GetDeclContextContainingUIDFromDWARF (die);
Greg Clayton99558cc42015-08-24 23:46:31 +00002424 if (actual_decl_ctx)
2425 return actual_decl_ctx == *decl_ctx;
2426 }
2427 }
2428 return false;
2429}
2430
Greg Clayton0c5cd902010-06-28 21:30:43 +00002431uint32_t
Greg Clayton99558cc42015-08-24 23:46:31 +00002432SymbolFileDWARF::FindFunctions (const ConstString &name,
2433 const CompilerDeclContext *parent_decl_ctx,
Sean Callanan9df05fb2012-02-10 22:52:19 +00002434 uint32_t name_type_mask,
2435 bool include_inlines,
Greg Clayton2bc22f82011-09-30 03:20:47 +00002436 bool append,
2437 SymbolContextList& sc_list)
Greg Clayton0c5cd902010-06-28 21:30:43 +00002438{
2439 Timer scoped_timer (__PRETTY_FUNCTION__,
2440 "SymbolFileDWARF::FindFunctions (name = '%s')",
2441 name.AsCString());
2442
Greg Clayton43fe2172013-04-03 02:00:15 +00002443 // eFunctionNameTypeAuto should be pre-resolved by a call to Module::PrepareForFunctionNameLookup()
2444 assert ((name_type_mask & eFunctionNameTypeAuto) == 0);
2445
Greg Clayton5160ce52013-03-27 23:08:40 +00002446 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Greg Clayton21f2a492011-10-06 00:09:08 +00002447
2448 if (log)
2449 {
Greg Clayton5160ce52013-03-27 23:08:40 +00002450 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytone38a5ed2012-01-05 03:57:59 +00002451 "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, append=%u, sc_list)",
2452 name.GetCString(),
2453 name_type_mask,
2454 append);
Greg Clayton21f2a492011-10-06 00:09:08 +00002455 }
2456
Greg Clayton0c5cd902010-06-28 21:30:43 +00002457 // If we aren't appending the results to this list, then clear the list
2458 if (!append)
2459 sc_list.Clear();
Sean Callanan213fdb82011-10-13 01:49:10 +00002460
Greg Clayton99558cc42015-08-24 23:46:31 +00002461 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
Ed Maste4c24b122013-10-17 20:13:14 +00002462 return 0;
Jim Ingham4cda6e02011-10-07 22:23:45 +00002463
2464 // If name is empty then we won't find anything.
2465 if (name.IsEmpty())
2466 return 0;
Greg Clayton0c5cd902010-06-28 21:30:43 +00002467
2468 // Remember how many sc_list are in the list before we search in case
2469 // we are appending the results to a variable list.
Greg Clayton9e315582011-09-02 04:03:59 +00002470
Jim Ingham4cda6e02011-10-07 22:23:45 +00002471 const char *name_cstr = name.GetCString();
Greg Clayton43fe2172013-04-03 02:00:15 +00002472
2473 const uint32_t original_size = sc_list.GetSize();
2474
Jim Ingham4cda6e02011-10-07 22:23:45 +00002475 DWARFDebugInfo* info = DebugInfo();
2476 if (info == NULL)
2477 return 0;
2478
Greg Clayton43fe2172013-04-03 02:00:15 +00002479 std::set<const DWARFDebugInfoEntry *> resolved_dies;
Greg Clayton97fbc342011-10-20 22:30:33 +00002480 if (m_using_apple_tables)
Greg Clayton4d01ace2011-09-29 16:58:15 +00002481 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002482 if (m_apple_names_ap.get())
Jim Ingham4cda6e02011-10-07 22:23:45 +00002483 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002484
2485 DIEArray die_offsets;
2486
2487 uint32_t num_matches = 0;
2488
Greg Clayton43fe2172013-04-03 02:00:15 +00002489 if (name_type_mask & eFunctionNameTypeFull)
Greg Claytonaa044962011-10-13 00:59:38 +00002490 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002491 // If they asked for the full name, match what they typed. At some point we may
2492 // want to canonicalize this (strip double spaces, etc. For now, we just add all the
2493 // dies that we find by exact match.
Jim Ingham4cda6e02011-10-07 22:23:45 +00002494 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
Jim Ingham4cda6e02011-10-07 22:23:45 +00002495 for (uint32_t i = 0; i < num_matches; i++)
2496 {
Greg Clayton95d87902011-11-11 03:16:25 +00002497 const dw_offset_t die_offset = die_offsets[i];
Greg Clayton6071e6f2015-08-26 22:57:51 +00002498 DWARFDIE die = info->GetDIE (die_offset);
Greg Claytonaa044962011-10-13 00:59:38 +00002499 if (die)
2500 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002501 if (!DIEInDeclContext(parent_decl_ctx, die))
Greg Clayton99558cc42015-08-24 23:46:31 +00002502 continue; // The containing decl contexts don't match
Greg Clayton8b4edba2015-08-14 20:02:05 +00002503
Greg Clayton6071e6f2015-08-26 22:57:51 +00002504 if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
Greg Clayton43fe2172013-04-03 02:00:15 +00002505 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002506 if (ResolveFunction (die, include_inlines, sc_list))
2507 resolved_dies.insert(die.GetDIE());
Greg Clayton43fe2172013-04-03 02:00:15 +00002508 }
Greg Claytonaa044962011-10-13 00:59:38 +00002509 }
Greg Clayton95d87902011-11-11 03:16:25 +00002510 else
2511 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00002512 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
2513 die_offset, name_cstr);
Greg Clayton95d87902011-11-11 03:16:25 +00002514 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00002515 }
Greg Clayton97fbc342011-10-20 22:30:33 +00002516 }
Greg Clayton43fe2172013-04-03 02:00:15 +00002517
2518 if (name_type_mask & eFunctionNameTypeSelector)
2519 {
Greg Clayton99558cc42015-08-24 23:46:31 +00002520 if (parent_decl_ctx && parent_decl_ctx->IsValid())
Greg Clayton43fe2172013-04-03 02:00:15 +00002521 return 0; // no selectors in namespaces
Greg Clayton97fbc342011-10-20 22:30:33 +00002522
Greg Clayton43fe2172013-04-03 02:00:15 +00002523 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
2524 // Now make sure these are actually ObjC methods. In this case we can simply look up the name,
2525 // and if it is an ObjC method name, we're good.
Greg Clayton97fbc342011-10-20 22:30:33 +00002526
Greg Clayton43fe2172013-04-03 02:00:15 +00002527 for (uint32_t i = 0; i < num_matches; i++)
Greg Clayton97fbc342011-10-20 22:30:33 +00002528 {
Greg Clayton43fe2172013-04-03 02:00:15 +00002529 const dw_offset_t die_offset = die_offsets[i];
Greg Clayton6071e6f2015-08-26 22:57:51 +00002530 DWARFDIE die = info->GetDIE (die_offset);
Greg Clayton43fe2172013-04-03 02:00:15 +00002531 if (die)
Greg Clayton97fbc342011-10-20 22:30:33 +00002532 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002533 const char *die_name = die.GetName();
Jim Inghamaa816b82015-09-02 01:59:14 +00002534 if (ObjCLanguage::IsPossibleObjCMethodName(die_name))
Greg Clayton97fbc342011-10-20 22:30:33 +00002535 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002536 if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
Greg Clayton43fe2172013-04-03 02:00:15 +00002537 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002538 if (ResolveFunction (die, include_inlines, sc_list))
2539 resolved_dies.insert(die.GetDIE());
Greg Clayton43fe2172013-04-03 02:00:15 +00002540 }
Greg Clayton97fbc342011-10-20 22:30:33 +00002541 }
2542 }
Greg Clayton43fe2172013-04-03 02:00:15 +00002543 else
2544 {
2545 GetObjectFile()->GetModule()->ReportError ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
2546 die_offset, name_cstr);
2547 }
Greg Clayton97fbc342011-10-20 22:30:33 +00002548 }
Greg Clayton43fe2172013-04-03 02:00:15 +00002549 die_offsets.clear();
2550 }
2551
Greg Clayton99558cc42015-08-24 23:46:31 +00002552 if (((name_type_mask & eFunctionNameTypeMethod) && !parent_decl_ctx) || name_type_mask & eFunctionNameTypeBase)
Greg Clayton43fe2172013-04-03 02:00:15 +00002553 {
2554 // The apple_names table stores just the "base name" of C++ methods in the table. So we have to
2555 // extract the base name, look that up, and if there is any other information in the name we were
2556 // passed in we have to post-filter based on that.
2557
2558 // FIXME: Arrange the logic above so that we don't calculate the base name twice:
2559 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
2560
2561 for (uint32_t i = 0; i < num_matches; i++)
2562 {
2563 const dw_offset_t die_offset = die_offsets[i];
Greg Clayton6071e6f2015-08-26 22:57:51 +00002564 DWARFDIE die = info->GetDIE (die_offset);
Greg Clayton43fe2172013-04-03 02:00:15 +00002565 if (die)
2566 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002567 if (!DIEInDeclContext(parent_decl_ctx, die))
Greg Clayton99558cc42015-08-24 23:46:31 +00002568 continue; // The containing decl contexts don't match
Greg Clayton8b4edba2015-08-14 20:02:05 +00002569
Greg Clayton43fe2172013-04-03 02:00:15 +00002570
2571 // If we get to here, the die is good, and we should add it:
Greg Clayton6071e6f2015-08-26 22:57:51 +00002572 if (resolved_dies.find(die.GetDIE()) == resolved_dies.end() && ResolveFunction (die, include_inlines, sc_list))
Greg Clayton43fe2172013-04-03 02:00:15 +00002573 {
2574 bool keep_die = true;
2575 if ((name_type_mask & (eFunctionNameTypeBase|eFunctionNameTypeMethod)) != (eFunctionNameTypeBase|eFunctionNameTypeMethod))
2576 {
2577 // We are looking for either basenames or methods, so we need to
2578 // trim out the ones we won't want by looking at the type
2579 SymbolContext sc;
2580 if (sc_list.GetLastContext(sc))
2581 {
2582 if (sc.block)
2583 {
2584 // We have an inlined function
2585 }
2586 else if (sc.function)
2587 {
2588 Type *type = sc.function->GetType();
2589
Sean Callananc370a8a2013-09-18 22:59:55 +00002590 if (type)
Greg Clayton43fe2172013-04-03 02:00:15 +00002591 {
Greg Clayton99558cc42015-08-24 23:46:31 +00002592 CompilerDeclContext decl_ctx = GetDeclContextContainingUID (type->GetID());
2593 if (decl_ctx.IsStructUnionOrClass())
Greg Clayton43fe2172013-04-03 02:00:15 +00002594 {
Sean Callananc370a8a2013-09-18 22:59:55 +00002595 if (name_type_mask & eFunctionNameTypeBase)
2596 {
2597 sc_list.RemoveContextAtIndex(sc_list.GetSize()-1);
2598 keep_die = false;
2599 }
2600 }
2601 else
2602 {
2603 if (name_type_mask & eFunctionNameTypeMethod)
2604 {
2605 sc_list.RemoveContextAtIndex(sc_list.GetSize()-1);
2606 keep_die = false;
2607 }
Greg Clayton43fe2172013-04-03 02:00:15 +00002608 }
2609 }
2610 else
2611 {
Sean Callananc370a8a2013-09-18 22:59:55 +00002612 GetObjectFile()->GetModule()->ReportWarning ("function at die offset 0x%8.8x had no function type",
2613 die_offset);
Greg Clayton43fe2172013-04-03 02:00:15 +00002614 }
2615 }
2616 }
2617 }
2618 if (keep_die)
Greg Clayton6071e6f2015-08-26 22:57:51 +00002619 resolved_dies.insert(die.GetDIE());
Greg Clayton43fe2172013-04-03 02:00:15 +00002620 }
2621 }
2622 else
2623 {
2624 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
2625 die_offset, name_cstr);
2626 }
2627 }
2628 die_offsets.clear();
Jim Ingham4cda6e02011-10-07 22:23:45 +00002629 }
2630 }
Greg Clayton7f995132011-10-04 22:41:51 +00002631 }
2632 else
2633 {
2634
2635 // Index the DWARF if we haven't already
2636 if (!m_indexed)
2637 Index ();
2638
Greg Clayton7f995132011-10-04 22:41:51 +00002639 if (name_type_mask & eFunctionNameTypeFull)
Matt Kopecd6089962013-05-10 17:53:48 +00002640 {
Pavel Labatha73d6572015-03-13 10:22:00 +00002641 FindFunctions (name, m_function_fullname_index, include_inlines, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00002642
Ed Mastefc7baa02013-09-09 18:00:45 +00002643 // FIXME Temporary workaround for global/anonymous namespace
Robert Flack5cbd3bf2015-05-13 18:20:02 +00002644 // functions debugging FreeBSD and Linux binaries.
Matt Kopecd6089962013-05-10 17:53:48 +00002645 // If we didn't find any functions in the global namespace try
2646 // looking in the basename index but ignore any returned
Robert Flackeb83fab2015-05-15 18:59:59 +00002647 // functions that have a namespace but keep functions which
2648 // have an anonymous namespace
2649 // TODO: The arch in the object file isn't correct for MSVC
2650 // binaries on windows, we should find a way to make it
2651 // correct and handle those symbols as well.
Matt Kopecd6089962013-05-10 17:53:48 +00002652 if (sc_list.GetSize() == 0)
2653 {
Robert Flackeb83fab2015-05-15 18:59:59 +00002654 ArchSpec arch;
Greg Clayton99558cc42015-08-24 23:46:31 +00002655 if (!parent_decl_ctx &&
Robert Flackeb83fab2015-05-15 18:59:59 +00002656 GetObjectFile()->GetArchitecture(arch) &&
2657 (arch.GetTriple().isOSFreeBSD() || arch.GetTriple().isOSLinux() ||
2658 arch.GetMachine() == llvm::Triple::hexagon))
Matt Kopecd6089962013-05-10 17:53:48 +00002659 {
Robert Flackeb83fab2015-05-15 18:59:59 +00002660 SymbolContextList temp_sc_list;
2661 FindFunctions (name, m_function_basename_index, include_inlines, temp_sc_list);
Matt Kopecd6089962013-05-10 17:53:48 +00002662 SymbolContext sc;
2663 for (uint32_t i = 0; i < temp_sc_list.GetSize(); i++)
2664 {
2665 if (temp_sc_list.GetContextAtIndex(i, sc))
2666 {
Matt Kopeca189d492013-05-10 22:55:24 +00002667 ConstString mangled_name = sc.GetFunctionName(Mangled::ePreferMangled);
2668 ConstString demangled_name = sc.GetFunctionName(Mangled::ePreferDemangled);
Robert Flackeb83fab2015-05-15 18:59:59 +00002669 // Mangled names on Linux and FreeBSD are of the form:
2670 // _ZN18function_namespace13function_nameEv.
Matt Kopec04e5d582013-05-14 19:00:41 +00002671 if (strncmp(mangled_name.GetCString(), "_ZN", 3) ||
2672 !strncmp(demangled_name.GetCString(), "(anonymous namespace)", 21))
Matt Kopecd6089962013-05-10 17:53:48 +00002673 {
2674 sc_list.Append(sc);
2675 }
2676 }
2677 }
2678 }
2679 }
Matt Kopecd6089962013-05-10 17:53:48 +00002680 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00002681 DIEArray die_offsets;
Greg Clayton43fe2172013-04-03 02:00:15 +00002682 if (name_type_mask & eFunctionNameTypeBase)
Jim Ingham4cda6e02011-10-07 22:23:45 +00002683 {
Greg Clayton43fe2172013-04-03 02:00:15 +00002684 uint32_t num_base = m_function_basename_index.Find(name, die_offsets);
Greg Claytonaa044962011-10-13 00:59:38 +00002685 for (uint32_t i = 0; i < num_base; i++)
Jim Ingham4cda6e02011-10-07 22:23:45 +00002686 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002687 DWARFDIE die = info->GetDIE (die_offsets[i]);
Greg Claytonaa044962011-10-13 00:59:38 +00002688 if (die)
2689 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002690 if (!DIEInDeclContext(parent_decl_ctx, die))
Greg Clayton99558cc42015-08-24 23:46:31 +00002691 continue; // The containing decl contexts don't match
Greg Clayton8b4edba2015-08-14 20:02:05 +00002692
Greg Claytonaa044962011-10-13 00:59:38 +00002693 // If we get to here, the die is good, and we should add it:
Greg Clayton6071e6f2015-08-26 22:57:51 +00002694 if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
Greg Clayton43fe2172013-04-03 02:00:15 +00002695 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002696 if (ResolveFunction (die, include_inlines, sc_list))
2697 resolved_dies.insert(die.GetDIE());
Greg Clayton43fe2172013-04-03 02:00:15 +00002698 }
Greg Claytonaa044962011-10-13 00:59:38 +00002699 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00002700 }
2701 die_offsets.clear();
2702 }
2703
Greg Clayton43fe2172013-04-03 02:00:15 +00002704 if (name_type_mask & eFunctionNameTypeMethod)
Jim Ingham4cda6e02011-10-07 22:23:45 +00002705 {
Greg Clayton99558cc42015-08-24 23:46:31 +00002706 if (parent_decl_ctx && parent_decl_ctx->IsValid())
Sean Callanan213fdb82011-10-13 01:49:10 +00002707 return 0; // no methods in namespaces
2708
Greg Clayton43fe2172013-04-03 02:00:15 +00002709 uint32_t num_base = m_function_method_index.Find(name, die_offsets);
Jim Ingham4cda6e02011-10-07 22:23:45 +00002710 {
Greg Claytonaa044962011-10-13 00:59:38 +00002711 for (uint32_t i = 0; i < num_base; i++)
2712 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002713 DWARFDIE die = info->GetDIE (die_offsets[i]);
Greg Claytonaa044962011-10-13 00:59:38 +00002714 if (die)
2715 {
Greg Claytonaa044962011-10-13 00:59:38 +00002716 // If we get to here, the die is good, and we should add it:
Greg Clayton6071e6f2015-08-26 22:57:51 +00002717 if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
Greg Clayton43fe2172013-04-03 02:00:15 +00002718 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002719 if (ResolveFunction (die, include_inlines, sc_list))
2720 resolved_dies.insert(die.GetDIE());
Greg Clayton43fe2172013-04-03 02:00:15 +00002721 }
Greg Claytonaa044962011-10-13 00:59:38 +00002722 }
2723 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00002724 }
2725 die_offsets.clear();
2726 }
Greg Clayton7f995132011-10-04 22:41:51 +00002727
Greg Clayton99558cc42015-08-24 23:46:31 +00002728 if ((name_type_mask & eFunctionNameTypeSelector) && (!parent_decl_ctx || !parent_decl_ctx->IsValid()))
Jim Ingham4cda6e02011-10-07 22:23:45 +00002729 {
Pavel Labatha73d6572015-03-13 10:22:00 +00002730 FindFunctions (name, m_function_selector_index, include_inlines, sc_list);
Jim Ingham4cda6e02011-10-07 22:23:45 +00002731 }
2732
Greg Clayton4d01ace2011-09-29 16:58:15 +00002733 }
2734
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002735 // Return the number of variable that were appended to the list
Greg Clayton437a1352012-04-09 22:43:43 +00002736 const uint32_t num_matches = sc_list.GetSize() - original_size;
2737
2738 if (log && num_matches > 0)
2739 {
Greg Clayton5160ce52013-03-27 23:08:40 +00002740 GetObjectFile()->GetModule()->LogMessage (log,
Pavel Labatha73d6572015-03-13 10:22:00 +00002741 "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, include_inlines=%d, append=%u, sc_list) => %u",
Greg Clayton437a1352012-04-09 22:43:43 +00002742 name.GetCString(),
2743 name_type_mask,
Pavel Labatha73d6572015-03-13 10:22:00 +00002744 include_inlines,
Greg Clayton437a1352012-04-09 22:43:43 +00002745 append,
2746 num_matches);
2747 }
2748 return num_matches;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002749}
2750
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002751uint32_t
Sean Callanan9df05fb2012-02-10 22:52:19 +00002752SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002753{
2754 Timer scoped_timer (__PRETTY_FUNCTION__,
2755 "SymbolFileDWARF::FindFunctions (regex = '%s')",
2756 regex.GetText());
2757
Greg Clayton5160ce52013-03-27 23:08:40 +00002758 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Greg Clayton21f2a492011-10-06 00:09:08 +00002759
2760 if (log)
2761 {
Greg Clayton5160ce52013-03-27 23:08:40 +00002762 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytone38a5ed2012-01-05 03:57:59 +00002763 "SymbolFileDWARF::FindFunctions (regex=\"%s\", append=%u, sc_list)",
2764 regex.GetText(),
2765 append);
Greg Clayton21f2a492011-10-06 00:09:08 +00002766 }
2767
2768
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002769 // If we aren't appending the results to this list, then clear the list
2770 if (!append)
2771 sc_list.Clear();
2772
2773 // Remember how many sc_list are in the list before we search in case
2774 // we are appending the results to a variable list.
2775 uint32_t original_size = sc_list.GetSize();
2776
Greg Clayton97fbc342011-10-20 22:30:33 +00002777 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00002778 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002779 if (m_apple_names_ap.get())
Pavel Labatha73d6572015-03-13 10:22:00 +00002780 FindFunctions (regex, *m_apple_names_ap, include_inlines, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00002781 }
2782 else
2783 {
Jim Ingham4cda6e02011-10-07 22:23:45 +00002784 // Index the DWARF if we haven't already
Greg Clayton7f995132011-10-04 22:41:51 +00002785 if (!m_indexed)
2786 Index ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002787
Pavel Labatha73d6572015-03-13 10:22:00 +00002788 FindFunctions (regex, m_function_basename_index, include_inlines, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002789
Pavel Labatha73d6572015-03-13 10:22:00 +00002790 FindFunctions (regex, m_function_fullname_index, include_inlines, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00002791 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002792
2793 // Return the number of variable that were appended to the list
2794 return sc_list.GetSize() - original_size;
2795}
Jim Ingham318c9f22011-08-26 19:44:13 +00002796
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002797uint32_t
Greg Claytond1767f02011-12-08 02:13:16 +00002798SymbolFileDWARF::FindTypes (const SymbolContext& sc,
2799 const ConstString &name,
Greg Clayton99558cc42015-08-24 23:46:31 +00002800 const CompilerDeclContext *parent_decl_ctx,
Greg Claytond1767f02011-12-08 02:13:16 +00002801 bool append,
2802 uint32_t max_matches,
2803 TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002804{
Greg Claytonc685f8e2010-09-15 04:15:46 +00002805 DWARFDebugInfo* info = DebugInfo();
2806 if (info == NULL)
2807 return 0;
2808
Greg Clayton5160ce52013-03-27 23:08:40 +00002809 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002810
Greg Clayton21f2a492011-10-06 00:09:08 +00002811 if (log)
2812 {
Greg Clayton99558cc42015-08-24 23:46:31 +00002813 if (parent_decl_ctx)
Greg Clayton5160ce52013-03-27 23:08:40 +00002814 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton99558cc42015-08-24 23:46:31 +00002815 "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = %p (\"%s\"), append=%u, max_matches=%u, type_list)",
Greg Clayton437a1352012-04-09 22:43:43 +00002816 name.GetCString(),
Greg Clayton99558cc42015-08-24 23:46:31 +00002817 static_cast<const void*>(parent_decl_ctx),
2818 parent_decl_ctx->GetName().AsCString("<NULL>"),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002819 append, max_matches);
Greg Clayton437a1352012-04-09 22:43:43 +00002820 else
Greg Clayton5160ce52013-03-27 23:08:40 +00002821 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton99558cc42015-08-24 23:46:31 +00002822 "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = NULL, append=%u, max_matches=%u, type_list)",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002823 name.GetCString(), append,
Greg Clayton437a1352012-04-09 22:43:43 +00002824 max_matches);
Greg Clayton21f2a492011-10-06 00:09:08 +00002825 }
2826
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002827 // If we aren't appending the results to this list, then clear the list
2828 if (!append)
2829 types.Clear();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002830
Greg Clayton99558cc42015-08-24 23:46:31 +00002831 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
Ed Maste4c24b122013-10-17 20:13:14 +00002832 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002833
Greg Claytond4a2b372011-09-12 23:21:58 +00002834 DIEArray die_offsets;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002835
Greg Clayton97fbc342011-10-20 22:30:33 +00002836 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00002837 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002838 if (m_apple_types_ap.get())
2839 {
2840 const char *name_cstr = name.GetCString();
2841 m_apple_types_ap->FindByName (name_cstr, die_offsets);
2842 }
Greg Clayton7f995132011-10-04 22:41:51 +00002843 }
2844 else
2845 {
2846 if (!m_indexed)
2847 Index ();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002848
Greg Clayton7f995132011-10-04 22:41:51 +00002849 m_type_index.Find (name, die_offsets);
2850 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002851
Greg Clayton437a1352012-04-09 22:43:43 +00002852 const size_t num_die_matches = die_offsets.size();
Greg Clayton7f995132011-10-04 22:41:51 +00002853
Greg Clayton437a1352012-04-09 22:43:43 +00002854 if (num_die_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002855 {
Greg Clayton7f995132011-10-04 22:41:51 +00002856 const uint32_t initial_types_size = types.GetSize();
Greg Claytond4a2b372011-09-12 23:21:58 +00002857 DWARFDebugInfo* debug_info = DebugInfo();
Greg Clayton437a1352012-04-09 22:43:43 +00002858 for (size_t i=0; i<num_die_matches; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002859 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002860 const dw_offset_t die_offset = die_offsets[i];
Greg Clayton6071e6f2015-08-26 22:57:51 +00002861 DWARFDIE die = debug_info->GetDIE (die_offset);
Greg Claytond4a2b372011-09-12 23:21:58 +00002862
Greg Clayton95d87902011-11-11 03:16:25 +00002863 if (die)
Greg Clayton73bf5db2011-06-17 01:22:15 +00002864 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002865 if (!DIEInDeclContext(parent_decl_ctx, die))
Greg Clayton99558cc42015-08-24 23:46:31 +00002866 continue; // The containing decl contexts don't match
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002867
Greg Clayton6071e6f2015-08-26 22:57:51 +00002868 Type *matching_type = ResolveType (die);
Greg Clayton95d87902011-11-11 03:16:25 +00002869 if (matching_type)
2870 {
2871 // We found a type pointer, now find the shared pointer form our type list
Greg Claytone1cd1be2012-01-29 20:56:30 +00002872 types.InsertUnique (matching_type->shared_from_this());
Greg Clayton95d87902011-11-11 03:16:25 +00002873 if (types.GetSize() >= max_matches)
2874 break;
2875 }
Greg Clayton73bf5db2011-06-17 01:22:15 +00002876 }
Greg Clayton95d87902011-11-11 03:16:25 +00002877 else
2878 {
2879 if (m_using_apple_tables)
2880 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00002881 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
2882 die_offset, name.GetCString());
Greg Clayton95d87902011-11-11 03:16:25 +00002883 }
2884 }
2885
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002886 }
Greg Clayton437a1352012-04-09 22:43:43 +00002887 const uint32_t num_matches = types.GetSize() - initial_types_size;
2888 if (log && num_matches)
2889 {
Greg Clayton99558cc42015-08-24 23:46:31 +00002890 if (parent_decl_ctx)
Greg Clayton437a1352012-04-09 22:43:43 +00002891 {
Greg Clayton5160ce52013-03-27 23:08:40 +00002892 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton99558cc42015-08-24 23:46:31 +00002893 "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = %p (\"%s\"), append=%u, max_matches=%u, type_list) => %u",
Greg Clayton437a1352012-04-09 22:43:43 +00002894 name.GetCString(),
Greg Clayton99558cc42015-08-24 23:46:31 +00002895 static_cast<const void*>(parent_decl_ctx),
2896 parent_decl_ctx->GetName().AsCString("<NULL>"),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002897 append, max_matches,
Greg Clayton437a1352012-04-09 22:43:43 +00002898 num_matches);
2899 }
2900 else
2901 {
Greg Clayton5160ce52013-03-27 23:08:40 +00002902 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton99558cc42015-08-24 23:46:31 +00002903 "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = NULL, append=%u, max_matches=%u, type_list) => %u",
Greg Clayton437a1352012-04-09 22:43:43 +00002904 name.GetCString(),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002905 append, max_matches,
Greg Clayton437a1352012-04-09 22:43:43 +00002906 num_matches);
2907 }
2908 }
2909 return num_matches;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002910 }
Greg Clayton7f995132011-10-04 22:41:51 +00002911 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002912}
2913
2914
Greg Clayton99558cc42015-08-24 23:46:31 +00002915CompilerDeclContext
Greg Clayton96d7d742010-11-10 23:42:09 +00002916SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
Sean Callanan213fdb82011-10-13 01:49:10 +00002917 const ConstString &name,
Greg Clayton99558cc42015-08-24 23:46:31 +00002918 const CompilerDeclContext *parent_decl_ctx)
Greg Clayton96d7d742010-11-10 23:42:09 +00002919{
Greg Clayton5160ce52013-03-27 23:08:40 +00002920 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Greg Clayton21f2a492011-10-06 00:09:08 +00002921
2922 if (log)
2923 {
Greg Clayton5160ce52013-03-27 23:08:40 +00002924 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytone38a5ed2012-01-05 03:57:59 +00002925 "SymbolFileDWARF::FindNamespace (sc, name=\"%s\")",
2926 name.GetCString());
Greg Clayton21f2a492011-10-06 00:09:08 +00002927 }
2928
Greg Clayton99558cc42015-08-24 23:46:31 +00002929 CompilerDeclContext namespace_decl_ctx;
2930
2931 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
2932 return namespace_decl_ctx;
2933
2934
Greg Clayton96d7d742010-11-10 23:42:09 +00002935 DWARFDebugInfo* info = DebugInfo();
Greg Clayton526e5af2010-11-13 03:52:47 +00002936 if (info)
Greg Clayton96d7d742010-11-10 23:42:09 +00002937 {
Greg Clayton7f995132011-10-04 22:41:51 +00002938 DIEArray die_offsets;
2939
Greg Clayton526e5af2010-11-13 03:52:47 +00002940 // Index if we already haven't to make sure the compile units
2941 // get indexed and make their global DIE index list
Greg Clayton97fbc342011-10-20 22:30:33 +00002942 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00002943 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002944 if (m_apple_namespaces_ap.get())
2945 {
2946 const char *name_cstr = name.GetCString();
2947 m_apple_namespaces_ap->FindByName (name_cstr, die_offsets);
2948 }
Greg Clayton7f995132011-10-04 22:41:51 +00002949 }
2950 else
2951 {
2952 if (!m_indexed)
2953 Index ();
Greg Clayton96d7d742010-11-10 23:42:09 +00002954
Greg Clayton7f995132011-10-04 22:41:51 +00002955 m_namespace_index.Find (name, die_offsets);
2956 }
Greg Claytond4a2b372011-09-12 23:21:58 +00002957
Greg Clayton7f995132011-10-04 22:41:51 +00002958 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00002959 if (num_matches)
Greg Clayton526e5af2010-11-13 03:52:47 +00002960 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002961 DWARFDebugInfo* debug_info = DebugInfo();
2962 for (size_t i=0; i<num_matches; ++i)
Greg Clayton526e5af2010-11-13 03:52:47 +00002963 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002964 const dw_offset_t die_offset = die_offsets[i];
Greg Clayton6071e6f2015-08-26 22:57:51 +00002965 DWARFDIE die = debug_info->GetDIE (die_offset);
2966
Greg Clayton95d87902011-11-11 03:16:25 +00002967 if (die)
Greg Claytond4a2b372011-09-12 23:21:58 +00002968 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002969 if (!DIEInDeclContext (parent_decl_ctx, die))
Greg Clayton99558cc42015-08-24 23:46:31 +00002970 continue; // The containing decl contexts don't match
Greg Clayton95d87902011-11-11 03:16:25 +00002971
Greg Clayton261ac3f2015-08-28 01:01:03 +00002972 DWARFASTParser *dwarf_ast = die.GetDWARFParser();
2973 if (dwarf_ast)
Greg Clayton8b4edba2015-08-14 20:02:05 +00002974 {
Greg Clayton261ac3f2015-08-28 01:01:03 +00002975 namespace_decl_ctx = dwarf_ast->GetDeclContextForUIDFromDWARF (die);
Greg Clayton99558cc42015-08-24 23:46:31 +00002976 if (namespace_decl_ctx)
Greg Clayton8b4edba2015-08-14 20:02:05 +00002977 break;
Greg Clayton95d87902011-11-11 03:16:25 +00002978 }
Greg Claytond4a2b372011-09-12 23:21:58 +00002979 }
Greg Clayton95d87902011-11-11 03:16:25 +00002980 else
2981 {
2982 if (m_using_apple_tables)
2983 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00002984 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_namespaces accelerator table had bad die 0x%8.8x for '%s')\n",
2985 die_offset, name.GetCString());
Greg Clayton95d87902011-11-11 03:16:25 +00002986 }
2987 }
2988
Greg Clayton526e5af2010-11-13 03:52:47 +00002989 }
2990 }
Greg Clayton96d7d742010-11-10 23:42:09 +00002991 }
Greg Clayton99558cc42015-08-24 23:46:31 +00002992 if (log && namespace_decl_ctx)
Greg Clayton437a1352012-04-09 22:43:43 +00002993 {
Greg Clayton5160ce52013-03-27 23:08:40 +00002994 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton99558cc42015-08-24 23:46:31 +00002995 "SymbolFileDWARF::FindNamespace (sc, name=\"%s\") => CompilerDeclContext(%p/%p) \"%s\"",
Greg Clayton437a1352012-04-09 22:43:43 +00002996 name.GetCString(),
Greg Clayton99558cc42015-08-24 23:46:31 +00002997 static_cast<const void*>(namespace_decl_ctx.GetTypeSystem()),
2998 static_cast<const void*>(namespace_decl_ctx.GetOpaqueDeclContext()),
2999 namespace_decl_ctx.GetName().AsCString("<NULL>"));
Greg Clayton437a1352012-04-09 22:43:43 +00003000 }
3001
Greg Clayton99558cc42015-08-24 23:46:31 +00003002 return namespace_decl_ctx;
Greg Clayton96d7d742010-11-10 23:42:09 +00003003}
3004
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003005uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003006SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003007{
3008 // Remember how many sc_list are in the list before we search in case
3009 // we are appending the results to a variable list.
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003010 uint32_t original_size = types.GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003011
3012 const uint32_t num_die_offsets = die_offsets.size();
3013 // Parse all of the types we found from the pubtypes matches
3014 uint32_t i;
3015 uint32_t num_matches = 0;
3016 for (i = 0; i < num_die_offsets; ++i)
3017 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003018 Type *matching_type = ResolveTypeUID (die_offsets[i]);
3019 if (matching_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003020 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003021 // We found a type pointer, now find the shared pointer form our type list
Greg Claytone1cd1be2012-01-29 20:56:30 +00003022 types.InsertUnique (matching_type->shared_from_this());
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003023 ++num_matches;
3024 if (num_matches >= max_matches)
3025 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003026 }
3027 }
3028
3029 // Return the number of variable that were appended to the list
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003030 return types.GetSize() - original_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003031}
3032
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003033
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003034TypeSP
Greg Clayton6071e6f2015-08-26 22:57:51 +00003035SymbolFileDWARF::GetTypeForDIE (const DWARFDIE &die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003036{
3037 TypeSP type_sp;
Greg Clayton6071e6f2015-08-26 22:57:51 +00003038 if (die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003039 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003040 Type *type_ptr = m_die_to_type.lookup (die.GetDIE());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003041 if (type_ptr == NULL)
3042 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003043 CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(die.GetCU());
Greg Claytonca512b32011-01-14 04:54:56 +00003044 assert (lldb_cu);
3045 SymbolContext sc(lldb_cu);
Greg Clayton6071e6f2015-08-26 22:57:51 +00003046 type_sp = ParseType(sc, die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003047 }
3048 else if (type_ptr != DIE_IS_BEING_PARSED)
3049 {
3050 // Grab the existing type from the master types lists
Greg Claytone1cd1be2012-01-29 20:56:30 +00003051 type_sp = type_ptr->shared_from_this();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003052 }
3053
3054 }
3055 return type_sp;
3056}
3057
Greg Clayton2bc22f82011-09-30 03:20:47 +00003058
Greg Clayton6071e6f2015-08-26 22:57:51 +00003059DWARFDIE
3060SymbolFileDWARF::GetDeclContextDIEContainingDIE (const DWARFDIE &orig_die)
Greg Clayton2bc22f82011-09-30 03:20:47 +00003061{
Greg Clayton6071e6f2015-08-26 22:57:51 +00003062 if (orig_die)
Greg Clayton2bc22f82011-09-30 03:20:47 +00003063 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003064 DWARFDIE die = orig_die;
Greg Clayton2bc22f82011-09-30 03:20:47 +00003065
Greg Clayton6071e6f2015-08-26 22:57:51 +00003066 while (die)
Greg Clayton2bc22f82011-09-30 03:20:47 +00003067 {
3068 // If this is the original DIE that we are searching for a declaration
3069 // for, then don't look in the cache as we don't want our own decl
3070 // context to be our decl context...
Greg Clayton6071e6f2015-08-26 22:57:51 +00003071 if (orig_die != die)
Greg Clayton2bc22f82011-09-30 03:20:47 +00003072 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003073 switch (die.Tag())
Greg Clayton2bc22f82011-09-30 03:20:47 +00003074 {
3075 case DW_TAG_compile_unit:
3076 case DW_TAG_namespace:
3077 case DW_TAG_structure_type:
3078 case DW_TAG_union_type:
3079 case DW_TAG_class_type:
3080 return die;
3081
3082 default:
3083 break;
3084 }
3085 }
Greg Clayton6071e6f2015-08-26 22:57:51 +00003086
3087 DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification);
3088 if (spec_die)
Greg Clayton2bc22f82011-09-30 03:20:47 +00003089 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003090 DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(spec_die);
3091 if (decl_ctx_die)
3092 return decl_ctx_die;
Greg Clayton2bc22f82011-09-30 03:20:47 +00003093 }
Greg Clayton6071e6f2015-08-26 22:57:51 +00003094
3095 DWARFDIE abs_die = die.GetReferencedDIE(DW_AT_abstract_origin);
3096 if (abs_die)
Greg Clayton2bc22f82011-09-30 03:20:47 +00003097 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003098 DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(abs_die);
3099 if (decl_ctx_die)
3100 return decl_ctx_die;
Greg Clayton2bc22f82011-09-30 03:20:47 +00003101 }
Greg Clayton6071e6f2015-08-26 22:57:51 +00003102
3103 die = die.GetParent();
Greg Clayton2bc22f82011-09-30 03:20:47 +00003104 }
3105 }
Greg Clayton6071e6f2015-08-26 22:57:51 +00003106 return DWARFDIE();
Greg Clayton2bc22f82011-09-30 03:20:47 +00003107}
3108
3109
Greg Clayton901c5ca2011-12-03 04:40:03 +00003110Symbol *
3111SymbolFileDWARF::GetObjCClassSymbol (const ConstString &objc_class_name)
3112{
3113 Symbol *objc_class_symbol = NULL;
3114 if (m_obj_file)
3115 {
Greg Clayton3046e662013-07-10 01:23:25 +00003116 Symtab *symtab = m_obj_file->GetSymtab ();
Greg Clayton901c5ca2011-12-03 04:40:03 +00003117 if (symtab)
3118 {
3119 objc_class_symbol = symtab->FindFirstSymbolWithNameAndType (objc_class_name,
3120 eSymbolTypeObjCClass,
3121 Symtab::eDebugNo,
3122 Symtab::eVisibilityAny);
3123 }
3124 }
3125 return objc_class_symbol;
3126}
3127
Greg Claytonc7f03b62012-01-12 04:33:28 +00003128// Some compilers don't emit the DW_AT_APPLE_objc_complete_type attribute. If they don't
3129// then we can end up looking through all class types for a complete type and never find
3130// the full definition. We need to know if this attribute is supported, so we determine
3131// this here and cache th result. We also need to worry about the debug map DWARF file
3132// if we are doing darwin DWARF in .o file debugging.
3133bool
3134SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type (DWARFCompileUnit *cu)
3135{
3136 if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate)
3137 {
3138 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
3139 if (cu && cu->Supports_DW_AT_APPLE_objc_complete_type())
3140 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
3141 else
3142 {
3143 DWARFDebugInfo* debug_info = DebugInfo();
3144 const uint32_t num_compile_units = GetNumCompileUnits();
3145 for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
3146 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00003147 DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
3148 if (dwarf_cu != cu && dwarf_cu->Supports_DW_AT_APPLE_objc_complete_type())
Greg Claytonc7f03b62012-01-12 04:33:28 +00003149 {
3150 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
3151 break;
3152 }
3153 }
3154 }
Greg Clayton1f746072012-08-29 21:13:06 +00003155 if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolNo && GetDebugMapSymfile ())
Greg Claytonc7f03b62012-01-12 04:33:28 +00003156 return m_debug_map_symfile->Supports_DW_AT_APPLE_objc_complete_type (this);
3157 }
3158 return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
3159}
Greg Clayton901c5ca2011-12-03 04:40:03 +00003160
3161// This function can be used when a DIE is found that is a forward declaration
3162// DIE and we want to try and find a type that has the complete definition.
3163TypeSP
Greg Clayton6071e6f2015-08-26 22:57:51 +00003164SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE (const DWARFDIE &die,
Greg Claytonc7f03b62012-01-12 04:33:28 +00003165 const ConstString &type_name,
3166 bool must_be_implementation)
Greg Clayton901c5ca2011-12-03 04:40:03 +00003167{
3168
3169 TypeSP type_sp;
3170
Greg Claytonc7f03b62012-01-12 04:33:28 +00003171 if (!type_name || (must_be_implementation && !GetObjCClassSymbol (type_name)))
Greg Clayton901c5ca2011-12-03 04:40:03 +00003172 return type_sp;
3173
3174 DIEArray die_offsets;
3175
3176 if (m_using_apple_tables)
3177 {
3178 if (m_apple_types_ap.get())
3179 {
3180 const char *name_cstr = type_name.GetCString();
Greg Clayton68221ec2012-01-18 20:58:12 +00003181 m_apple_types_ap->FindCompleteObjCClassByName (name_cstr, die_offsets, must_be_implementation);
Greg Clayton901c5ca2011-12-03 04:40:03 +00003182 }
3183 }
3184 else
3185 {
3186 if (!m_indexed)
3187 Index ();
3188
3189 m_type_index.Find (type_name, die_offsets);
3190 }
3191
Greg Clayton901c5ca2011-12-03 04:40:03 +00003192 const size_t num_matches = die_offsets.size();
3193
Greg Clayton901c5ca2011-12-03 04:40:03 +00003194 if (num_matches)
3195 {
3196 DWARFDebugInfo* debug_info = DebugInfo();
3197 for (size_t i=0; i<num_matches; ++i)
3198 {
3199 const dw_offset_t die_offset = die_offsets[i];
Greg Clayton6071e6f2015-08-26 22:57:51 +00003200 DWARFDIE type_die = debug_info->GetDIE (die_offset);
Greg Clayton901c5ca2011-12-03 04:40:03 +00003201
3202 if (type_die)
3203 {
3204 bool try_resolving_type = false;
3205
3206 // Don't try and resolve the DIE we are looking for with the DIE itself!
3207 if (type_die != die)
3208 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003209 switch (type_die.Tag())
Greg Clayton901c5ca2011-12-03 04:40:03 +00003210 {
Greg Claytonc7f03b62012-01-12 04:33:28 +00003211 case DW_TAG_class_type:
3212 case DW_TAG_structure_type:
3213 try_resolving_type = true;
3214 break;
3215 default:
3216 break;
Greg Clayton901c5ca2011-12-03 04:40:03 +00003217 }
3218 }
3219
3220 if (try_resolving_type)
3221 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003222 if (must_be_implementation && type_die.Supports_DW_AT_APPLE_objc_complete_type())
3223 try_resolving_type = type_die.GetAttributeValueAsUnsigned (DW_AT_APPLE_objc_complete_type, 0);
Greg Clayton901c5ca2011-12-03 04:40:03 +00003224
3225 if (try_resolving_type)
3226 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003227 Type *resolved_type = ResolveType (type_die, false);
Greg Clayton901c5ca2011-12-03 04:40:03 +00003228 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
3229 {
Ed Mastea0191d12013-10-17 20:42:56 +00003230 DEBUG_PRINTF ("resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64 " (cu 0x%8.8" PRIx64 ")\n",
Greg Clayton6071e6f2015-08-26 22:57:51 +00003231 die.GetID(),
Jim Ingham4af59612014-12-19 19:20:44 +00003232 m_obj_file->GetFileSpec().GetFilename().AsCString("<Unknown>"),
Greg Clayton6071e6f2015-08-26 22:57:51 +00003233 type_die.GetID(),
3234 type_cu->GetID());
Greg Clayton901c5ca2011-12-03 04:40:03 +00003235
Greg Claytonc7f03b62012-01-12 04:33:28 +00003236 if (die)
Greg Clayton6071e6f2015-08-26 22:57:51 +00003237 m_die_to_type[die.GetDIE()] = resolved_type;
Greg Claytone1cd1be2012-01-29 20:56:30 +00003238 type_sp = resolved_type->shared_from_this();
Greg Clayton901c5ca2011-12-03 04:40:03 +00003239 break;
3240 }
3241 }
3242 }
3243 }
3244 else
3245 {
3246 if (m_using_apple_tables)
3247 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00003248 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
3249 die_offset, type_name.GetCString());
Greg Clayton901c5ca2011-12-03 04:40:03 +00003250 }
3251 }
3252
3253 }
3254 }
3255 return type_sp;
3256}
3257
Greg Claytona8022fa2012-04-24 21:22:41 +00003258
Greg Clayton80c26302012-02-05 06:12:47 +00003259//----------------------------------------------------------------------
3260// This function helps to ensure that the declaration contexts match for
3261// two different DIEs. Often times debug information will refer to a
3262// forward declaration of a type (the equivalent of "struct my_struct;".
3263// There will often be a declaration of that type elsewhere that has the
3264// full definition. When we go looking for the full type "my_struct", we
3265// will find one or more matches in the accelerator tables and we will
3266// then need to make sure the type was in the same declaration context
3267// as the original DIE. This function can efficiently compare two DIEs
3268// and will return true when the declaration context matches, and false
3269// when they don't.
3270//----------------------------------------------------------------------
Greg Clayton890ff562012-02-02 05:48:16 +00003271bool
Greg Clayton6071e6f2015-08-26 22:57:51 +00003272SymbolFileDWARF::DIEDeclContextsMatch (const DWARFDIE &die1,
3273 const DWARFDIE &die2)
Greg Clayton890ff562012-02-02 05:48:16 +00003274{
Greg Claytona8022fa2012-04-24 21:22:41 +00003275 if (die1 == die2)
3276 return true;
3277
Greg Clayton890ff562012-02-02 05:48:16 +00003278 DWARFDIECollection decl_ctx_1;
3279 DWARFDIECollection decl_ctx_2;
Greg Clayton80c26302012-02-05 06:12:47 +00003280 //The declaration DIE stack is a stack of the declaration context
3281 // DIEs all the way back to the compile unit. If a type "T" is
3282 // declared inside a class "B", and class "B" is declared inside
3283 // a class "A" and class "A" is in a namespace "lldb", and the
3284 // namespace is in a compile unit, there will be a stack of DIEs:
3285 //
3286 // [0] DW_TAG_class_type for "B"
3287 // [1] DW_TAG_class_type for "A"
3288 // [2] DW_TAG_namespace for "lldb"
3289 // [3] DW_TAG_compile_unit for the source file.
3290 //
3291 // We grab both contexts and make sure that everything matches
3292 // all the way back to the compiler unit.
3293
3294 // First lets grab the decl contexts for both DIEs
Greg Clayton6071e6f2015-08-26 22:57:51 +00003295 die1.GetDeclContextDIEs (decl_ctx_1);
3296 die2.GetDeclContextDIEs (decl_ctx_2);
Greg Clayton80c26302012-02-05 06:12:47 +00003297 // Make sure the context arrays have the same size, otherwise
3298 // we are done
Greg Clayton890ff562012-02-02 05:48:16 +00003299 const size_t count1 = decl_ctx_1.Size();
3300 const size_t count2 = decl_ctx_2.Size();
3301 if (count1 != count2)
3302 return false;
Greg Clayton80c26302012-02-05 06:12:47 +00003303
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00003304 // Make sure the DW_TAG values match all the way back up the
Greg Clayton80c26302012-02-05 06:12:47 +00003305 // compile unit. If they don't, then we are done.
Greg Clayton6071e6f2015-08-26 22:57:51 +00003306 DWARFDIE decl_ctx_die1;
3307 DWARFDIE decl_ctx_die2;
Greg Clayton890ff562012-02-02 05:48:16 +00003308 size_t i;
3309 for (i=0; i<count1; i++)
3310 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003311 decl_ctx_die1 = decl_ctx_1.GetDIEAtIndex (i);
3312 decl_ctx_die2 = decl_ctx_2.GetDIEAtIndex (i);
3313 if (decl_ctx_die1.Tag() != decl_ctx_die2.Tag())
Greg Clayton890ff562012-02-02 05:48:16 +00003314 return false;
3315 }
Greg Clayton890ff562012-02-02 05:48:16 +00003316#if defined LLDB_CONFIGURATION_DEBUG
Greg Clayton80c26302012-02-05 06:12:47 +00003317
3318 // Make sure the top item in the decl context die array is always
3319 // DW_TAG_compile_unit. If it isn't then something went wrong in
Greg Clayton5ce1a842015-08-27 18:09:44 +00003320 // the DWARFDIE::GetDeclContextDIEs() function...
Greg Clayton6071e6f2015-08-26 22:57:51 +00003321 assert (decl_ctx_1.GetDIEAtIndex (count1 - 1).Tag() == DW_TAG_compile_unit);
Greg Clayton80c26302012-02-05 06:12:47 +00003322
Greg Clayton890ff562012-02-02 05:48:16 +00003323#endif
3324 // Always skip the compile unit when comparing by only iterating up to
Greg Clayton80c26302012-02-05 06:12:47 +00003325 // "count - 1". Here we compare the names as we go.
Greg Clayton890ff562012-02-02 05:48:16 +00003326 for (i=0; i<count1 - 1; i++)
3327 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003328 decl_ctx_die1 = decl_ctx_1.GetDIEAtIndex (i);
3329 decl_ctx_die2 = decl_ctx_2.GetDIEAtIndex (i);
3330 const char *name1 = decl_ctx_die1.GetName();
3331 const char *name2 = decl_ctx_die2.GetName();
Greg Clayton890ff562012-02-02 05:48:16 +00003332 // If the string was from a DW_FORM_strp, then the pointer will often
3333 // be the same!
Greg Clayton5569e642012-02-06 01:44:54 +00003334 if (name1 == name2)
3335 continue;
3336
3337 // Name pointers are not equal, so only compare the strings
3338 // if both are not NULL.
3339 if (name1 && name2)
Greg Clayton890ff562012-02-02 05:48:16 +00003340 {
Greg Clayton5569e642012-02-06 01:44:54 +00003341 // If the strings don't compare, we are done...
3342 if (strcmp(name1, name2) != 0)
Greg Clayton890ff562012-02-02 05:48:16 +00003343 return false;
Greg Clayton5569e642012-02-06 01:44:54 +00003344 }
3345 else
3346 {
3347 // One name was NULL while the other wasn't
3348 return false;
Greg Clayton890ff562012-02-02 05:48:16 +00003349 }
3350 }
Greg Clayton80c26302012-02-05 06:12:47 +00003351 // We made it through all of the checks and the declaration contexts
3352 // are equal.
Greg Clayton890ff562012-02-02 05:48:16 +00003353 return true;
3354}
Greg Clayton220a0072011-12-09 08:48:30 +00003355
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003356
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003357TypeSP
Greg Claytona8022fa2012-04-24 21:22:41 +00003358SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &dwarf_decl_ctx)
3359{
3360 TypeSP type_sp;
3361
3362 const uint32_t dwarf_decl_ctx_count = dwarf_decl_ctx.GetSize();
3363 if (dwarf_decl_ctx_count > 0)
3364 {
3365 const ConstString type_name(dwarf_decl_ctx[0].name);
3366 const dw_tag_t tag = dwarf_decl_ctx[0].tag;
3367
3368 if (type_name)
3369 {
Greg Clayton5160ce52013-03-27 23:08:40 +00003370 Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION|DWARF_LOG_LOOKUPS));
Greg Claytona8022fa2012-04-24 21:22:41 +00003371 if (log)
3372 {
Greg Clayton5160ce52013-03-27 23:08:40 +00003373 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytona8022fa2012-04-24 21:22:41 +00003374 "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s')",
3375 DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
3376 dwarf_decl_ctx.GetQualifiedName());
3377 }
3378
3379 DIEArray die_offsets;
3380
3381 if (m_using_apple_tables)
3382 {
3383 if (m_apple_types_ap.get())
3384 {
Greg Claytoncb9c8cf2013-02-06 23:56:13 +00003385 const bool has_tag = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeTag);
3386 const bool has_qualified_name_hash = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeQualNameHash);
3387 if (has_tag && has_qualified_name_hash)
Greg Claytona8022fa2012-04-24 21:22:41 +00003388 {
Greg Claytoncb9c8cf2013-02-06 23:56:13 +00003389 const char *qualified_name = dwarf_decl_ctx.GetQualifiedName();
3390 const uint32_t qualified_name_hash = MappedHash::HashStringUsingDJB (qualified_name);
3391 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00003392 GetObjectFile()->GetModule()->LogMessage (log,"FindByNameAndTagAndQualifiedNameHash()");
Greg Claytoncb9c8cf2013-02-06 23:56:13 +00003393 m_apple_types_ap->FindByNameAndTagAndQualifiedNameHash (type_name.GetCString(), tag, qualified_name_hash, die_offsets);
3394 }
3395 else if (has_tag)
3396 {
3397 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00003398 GetObjectFile()->GetModule()->LogMessage (log,"FindByNameAndTag()");
Greg Claytona8022fa2012-04-24 21:22:41 +00003399 m_apple_types_ap->FindByNameAndTag (type_name.GetCString(), tag, die_offsets);
3400 }
3401 else
3402 {
3403 m_apple_types_ap->FindByName (type_name.GetCString(), die_offsets);
3404 }
3405 }
3406 }
3407 else
3408 {
3409 if (!m_indexed)
3410 Index ();
3411
3412 m_type_index.Find (type_name, die_offsets);
3413 }
3414
3415 const size_t num_matches = die_offsets.size();
3416
3417
Greg Claytona8022fa2012-04-24 21:22:41 +00003418 if (num_matches)
3419 {
3420 DWARFDebugInfo* debug_info = DebugInfo();
3421 for (size_t i=0; i<num_matches; ++i)
3422 {
3423 const dw_offset_t die_offset = die_offsets[i];
Greg Clayton6071e6f2015-08-26 22:57:51 +00003424 DWARFDIE type_die = debug_info->GetDIE (die_offset);
Greg Claytona8022fa2012-04-24 21:22:41 +00003425
3426 if (type_die)
3427 {
3428 bool try_resolving_type = false;
3429
3430 // Don't try and resolve the DIE we are looking for with the DIE itself!
Greg Clayton6071e6f2015-08-26 22:57:51 +00003431 const dw_tag_t type_tag = type_die.Tag();
Greg Claytona8022fa2012-04-24 21:22:41 +00003432 // Make sure the tags match
3433 if (type_tag == tag)
3434 {
3435 // The tags match, lets try resolving this type
3436 try_resolving_type = true;
3437 }
3438 else
3439 {
3440 // The tags don't match, but we need to watch our for a
3441 // forward declaration for a struct and ("struct foo")
3442 // ends up being a class ("class foo { ... };") or
3443 // vice versa.
3444 switch (type_tag)
3445 {
3446 case DW_TAG_class_type:
3447 // We had a "class foo", see if we ended up with a "struct foo { ... };"
3448 try_resolving_type = (tag == DW_TAG_structure_type);
3449 break;
3450 case DW_TAG_structure_type:
3451 // We had a "struct foo", see if we ended up with a "class foo { ... };"
3452 try_resolving_type = (tag == DW_TAG_class_type);
3453 break;
3454 default:
3455 // Tags don't match, don't event try to resolve
3456 // using this type whose name matches....
3457 break;
3458 }
3459 }
3460
3461 if (try_resolving_type)
3462 {
3463 DWARFDeclContext type_dwarf_decl_ctx;
Greg Clayton6071e6f2015-08-26 22:57:51 +00003464 type_die.GetDWARFDeclContext (type_dwarf_decl_ctx);
Greg Claytona8022fa2012-04-24 21:22:41 +00003465
3466 if (log)
3467 {
Greg Clayton5160ce52013-03-27 23:08:40 +00003468 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytona8022fa2012-04-24 21:22:41 +00003469 "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') trying die=0x%8.8x (%s)",
3470 DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
3471 dwarf_decl_ctx.GetQualifiedName(),
Greg Clayton6071e6f2015-08-26 22:57:51 +00003472 type_die.GetOffset(),
Greg Claytona8022fa2012-04-24 21:22:41 +00003473 type_dwarf_decl_ctx.GetQualifiedName());
3474 }
3475
3476 // Make sure the decl contexts match all the way up
3477 if (dwarf_decl_ctx == type_dwarf_decl_ctx)
3478 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003479 Type *resolved_type = ResolveType (type_die, false);
Greg Claytona8022fa2012-04-24 21:22:41 +00003480 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
3481 {
3482 type_sp = resolved_type->shared_from_this();
3483 break;
3484 }
3485 }
3486 }
3487 else
3488 {
3489 if (log)
3490 {
3491 std::string qualified_name;
Greg Clayton6071e6f2015-08-26 22:57:51 +00003492 type_die.GetQualifiedName(qualified_name);
Greg Clayton5160ce52013-03-27 23:08:40 +00003493 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytona8022fa2012-04-24 21:22:41 +00003494 "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') ignoring die=0x%8.8x (%s)",
3495 DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
3496 dwarf_decl_ctx.GetQualifiedName(),
Greg Clayton6071e6f2015-08-26 22:57:51 +00003497 type_die.GetOffset(),
Greg Claytona8022fa2012-04-24 21:22:41 +00003498 qualified_name.c_str());
3499 }
3500 }
3501 }
3502 else
3503 {
3504 if (m_using_apple_tables)
3505 {
3506 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
3507 die_offset, type_name.GetCString());
3508 }
3509 }
3510
3511 }
3512 }
3513 }
3514 }
3515 return type_sp;
3516}
3517
Greg Claytona8022fa2012-04-24 21:22:41 +00003518TypeSP
Greg Clayton6071e6f2015-08-26 22:57:51 +00003519SymbolFileDWARF::ParseType (const SymbolContext& sc, const DWARFDIE &die, bool *type_is_new_ptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003520{
Greg Clayton196e8cd2015-08-17 20:31:46 +00003521 TypeSP type_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003522
Greg Clayton6071e6f2015-08-26 22:57:51 +00003523 if (die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003524 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003525 TypeSystem *type_system = GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
3526
3527 if (type_system)
Greg Clayton196e8cd2015-08-17 20:31:46 +00003528 {
Greg Clayton261ac3f2015-08-28 01:01:03 +00003529 DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
3530 if (dwarf_ast)
Greg Clayton6071e6f2015-08-26 22:57:51 +00003531 {
Greg Clayton261ac3f2015-08-28 01:01:03 +00003532 Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
3533 type_sp = dwarf_ast->ParseTypeFromDWARF (sc, die, log, type_is_new_ptr);
3534 if (type_sp)
3535 {
3536 TypeList* type_list = GetTypeList();
3537 if (type_list)
3538 type_list->Insert(type_sp);
3539 }
Greg Clayton6071e6f2015-08-26 22:57:51 +00003540 }
Greg Clayton196e8cd2015-08-17 20:31:46 +00003541 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003542 }
Greg Clayton196e8cd2015-08-17 20:31:46 +00003543
3544 return type_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003545}
3546
3547size_t
Greg Clayton1be10fc2010-09-29 01:12:09 +00003548SymbolFileDWARF::ParseTypes
3549(
3550 const SymbolContext& sc,
Greg Clayton6071e6f2015-08-26 22:57:51 +00003551 const DWARFDIE &orig_die,
Greg Clayton1be10fc2010-09-29 01:12:09 +00003552 bool parse_siblings,
3553 bool parse_children
3554)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003555{
3556 size_t types_added = 0;
Greg Clayton6071e6f2015-08-26 22:57:51 +00003557 DWARFDIE die = orig_die;
3558 while (die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003559 {
3560 bool type_is_new = false;
Greg Clayton6071e6f2015-08-26 22:57:51 +00003561 if (ParseType(sc, die, &type_is_new).get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003562 {
3563 if (type_is_new)
3564 ++types_added;
3565 }
3566
Greg Clayton6071e6f2015-08-26 22:57:51 +00003567 if (parse_children && die.HasChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003568 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003569 if (die.Tag() == DW_TAG_subprogram)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003570 {
3571 SymbolContext child_sc(sc);
Greg Clayton6071e6f2015-08-26 22:57:51 +00003572 child_sc.function = sc.comp_unit->FindFunctionByUID(die.GetID()).get();
3573 types_added += ParseTypes(child_sc, die.GetFirstChild(), true, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003574 }
3575 else
Greg Clayton6071e6f2015-08-26 22:57:51 +00003576 types_added += ParseTypes(sc, die.GetFirstChild(), true, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003577 }
3578
3579 if (parse_siblings)
Greg Clayton6071e6f2015-08-26 22:57:51 +00003580 die = die.GetSibling();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003581 else
Greg Clayton6071e6f2015-08-26 22:57:51 +00003582 die.Clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003583 }
3584 return types_added;
3585}
3586
3587
3588size_t
3589SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
3590{
3591 assert(sc.comp_unit && sc.function);
3592 size_t functions_added = 0;
Greg Clayton1f746072012-08-29 21:13:06 +00003593 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003594 if (dwarf_cu)
3595 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003596 const dw_offset_t function_die_offset = sc.function->GetID();
3597 DWARFDIE function_die = dwarf_cu->GetDIE (function_die_offset);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003598 if (function_die)
3599 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003600 ParseFunctionBlocks(sc, &sc.function->GetBlock (false), function_die, LLDB_INVALID_ADDRESS, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003601 }
3602 }
3603
3604 return functions_added;
3605}
3606
3607
3608size_t
3609SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
3610{
3611 // At least a compile unit must be valid
3612 assert(sc.comp_unit);
3613 size_t types_added = 0;
Greg Clayton1f746072012-08-29 21:13:06 +00003614 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003615 if (dwarf_cu)
3616 {
3617 if (sc.function)
3618 {
3619 dw_offset_t function_die_offset = sc.function->GetID();
Greg Clayton6071e6f2015-08-26 22:57:51 +00003620 DWARFDIE func_die = dwarf_cu->GetDIE(function_die_offset);
3621 if (func_die && func_die.HasChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003622 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003623 types_added = ParseTypes(sc, func_die.GetFirstChild(), true, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003624 }
3625 }
3626 else
3627 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003628 DWARFDIE dwarf_cu_die = dwarf_cu->DIE();
3629 if (dwarf_cu_die && dwarf_cu_die.HasChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003630 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003631 types_added = ParseTypes(sc, dwarf_cu_die.GetFirstChild(), true, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003632 }
3633 }
3634 }
3635
3636 return types_added;
3637}
3638
3639size_t
3640SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
3641{
3642 if (sc.comp_unit != NULL)
3643 {
Greg Clayton4b3dc102010-11-01 20:32:12 +00003644 DWARFDebugInfo* info = DebugInfo();
3645 if (info == NULL)
3646 return 0;
3647
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003648 if (sc.function)
3649 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003650 DWARFDIE function_die = info->GetDIE(sc.function->GetID());
Greg Clayton9422dd62013-03-04 21:46:16 +00003651
Greg Clayton6071e6f2015-08-26 22:57:51 +00003652 const dw_addr_t func_lo_pc = function_die.GetAttributeValueAsUnsigned (DW_AT_low_pc, LLDB_INVALID_ADDRESS);
Greg Claytonc7bece562013-01-25 18:06:21 +00003653 if (func_lo_pc != LLDB_INVALID_ADDRESS)
Greg Claytone38a5ed2012-01-05 03:57:59 +00003654 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003655 const size_t num_variables = ParseVariables(sc, function_die.GetFirstChild(), func_lo_pc, true, true);
Greg Claytonc662ec82011-06-17 22:10:16 +00003656
Greg Claytone38a5ed2012-01-05 03:57:59 +00003657 // Let all blocks know they have parse all their variables
3658 sc.function->GetBlock (false).SetDidParseVariables (true, true);
3659 return num_variables;
3660 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003661 }
3662 else if (sc.comp_unit)
3663 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003664 DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID());
Greg Clayton9422dd62013-03-04 21:46:16 +00003665
3666 if (dwarf_cu == NULL)
3667 return 0;
3668
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003669 uint32_t vars_added = 0;
3670 VariableListSP variables (sc.comp_unit->GetVariableList(false));
3671
3672 if (variables.get() == NULL)
3673 {
3674 variables.reset(new VariableList());
3675 sc.comp_unit->SetVariableList(variables);
3676
Greg Claytond4a2b372011-09-12 23:21:58 +00003677 DIEArray die_offsets;
Greg Clayton97fbc342011-10-20 22:30:33 +00003678 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00003679 {
Greg Clayton97fbc342011-10-20 22:30:33 +00003680 if (m_apple_names_ap.get())
Greg Claytond1767f02011-12-08 02:13:16 +00003681 {
3682 DWARFMappedHash::DIEInfoArray hash_data_array;
3683 if (m_apple_names_ap->AppendAllDIEsInRange (dwarf_cu->GetOffset(),
3684 dwarf_cu->GetNextCompileUnitOffset(),
3685 hash_data_array))
3686 {
3687 DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
3688 }
3689 }
Greg Clayton7f995132011-10-04 22:41:51 +00003690 }
3691 else
3692 {
3693 // Index if we already haven't to make sure the compile units
3694 // get indexed and make their global DIE index list
3695 if (!m_indexed)
3696 Index ();
3697
3698 m_global_index.FindAllEntriesForCompileUnit (dwarf_cu->GetOffset(),
3699 dwarf_cu->GetNextCompileUnitOffset(),
3700 die_offsets);
3701 }
3702
3703 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00003704 if (num_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003705 {
Greg Claytond4a2b372011-09-12 23:21:58 +00003706 DWARFDebugInfo* debug_info = DebugInfo();
3707 for (size_t i=0; i<num_matches; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003708 {
Greg Claytond4a2b372011-09-12 23:21:58 +00003709 const dw_offset_t die_offset = die_offsets[i];
Greg Clayton6071e6f2015-08-26 22:57:51 +00003710 DWARFDIE die = debug_info->GetDIE (die_offset);
Greg Clayton95d87902011-11-11 03:16:25 +00003711 if (die)
Greg Claytond4a2b372011-09-12 23:21:58 +00003712 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003713 VariableSP var_sp (ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS));
Greg Clayton95d87902011-11-11 03:16:25 +00003714 if (var_sp)
3715 {
3716 variables->AddVariableIfUnique (var_sp);
3717 ++vars_added;
3718 }
Greg Claytond4a2b372011-09-12 23:21:58 +00003719 }
Greg Clayton95d87902011-11-11 03:16:25 +00003720 else
3721 {
3722 if (m_using_apple_tables)
3723 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00003724 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x)\n", die_offset);
Greg Clayton95d87902011-11-11 03:16:25 +00003725 }
3726 }
3727
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003728 }
3729 }
3730 }
3731 return vars_added;
3732 }
3733 }
3734 return 0;
3735}
3736
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003737VariableSP
3738SymbolFileDWARF::ParseVariableDIE
3739(
3740 const SymbolContext& sc,
Greg Clayton6071e6f2015-08-26 22:57:51 +00003741 const DWARFDIE &die,
Greg Clayton016a95e2010-09-14 02:20:48 +00003742 const lldb::addr_t func_low_pc
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003743)
3744{
Greg Clayton6071e6f2015-08-26 22:57:51 +00003745 VariableSP var_sp;
3746 if (!die)
3747 return var_sp;
3748
3749 var_sp = m_die_to_variable_sp[die.GetDIE()];
Greg Clayton83c5cd92010-11-14 22:13:40 +00003750 if (var_sp)
3751 return var_sp; // Already been parsed!
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003752
Greg Clayton6071e6f2015-08-26 22:57:51 +00003753 const dw_tag_t tag = die.Tag();
Richard Mitton0a558352013-10-17 21:14:00 +00003754 ModuleSP module = GetObjectFile()->GetModule();
Greg Clayton7f995132011-10-04 22:41:51 +00003755
3756 if ((tag == DW_TAG_variable) ||
3757 (tag == DW_TAG_constant) ||
3758 (tag == DW_TAG_formal_parameter && sc.function))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003759 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003760 DWARFAttributes attributes;
3761 const size_t num_attributes = die.GetAttributes(attributes);
Greg Clayton7f995132011-10-04 22:41:51 +00003762 if (num_attributes > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003763 {
Greg Clayton7f995132011-10-04 22:41:51 +00003764 const char *name = NULL;
3765 const char *mangled = NULL;
3766 Declaration decl;
3767 uint32_t i;
Greg Claytond1767f02011-12-08 02:13:16 +00003768 lldb::user_id_t type_uid = LLDB_INVALID_UID;
Greg Clayton6071e6f2015-08-26 22:57:51 +00003769 DWARFExpression location(die.GetCU());
Greg Clayton7f995132011-10-04 22:41:51 +00003770 bool is_external = false;
3771 bool is_artificial = false;
3772 bool location_is_const_value_data = false;
Andrew Kaylorb32581f2013-02-13 19:57:06 +00003773 bool has_explicit_location = false;
Enrico Granata4ec130d2014-08-11 19:16:35 +00003774 DWARFFormValue const_value;
Greg Clayton23f59502012-07-17 03:23:13 +00003775 //AccessType accessibility = eAccessNone;
Greg Clayton7f995132011-10-04 22:41:51 +00003776
3777 for (i=0; i<num_attributes; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003778 {
Greg Clayton7f995132011-10-04 22:41:51 +00003779 dw_attr_t attr = attributes.AttributeAtIndex(i);
3780 DWARFFormValue form_value;
Greg Clayton54166af2014-11-22 01:58:59 +00003781
Greg Clayton6071e6f2015-08-26 22:57:51 +00003782 if (attributes.ExtractFormValueAtIndex(i, form_value))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003783 {
Greg Clayton7f995132011-10-04 22:41:51 +00003784 switch (attr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003785 {
Greg Clayton7f995132011-10-04 22:41:51 +00003786 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3787 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3788 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
Greg Clayton6071e6f2015-08-26 22:57:51 +00003789 case DW_AT_name: name = form_value.AsCString(); break;
Greg Clayton71415542012-12-08 00:24:40 +00003790 case DW_AT_linkage_name:
Greg Clayton6071e6f2015-08-26 22:57:51 +00003791 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(); break;
Greg Clayton54166af2014-11-22 01:58:59 +00003792 case DW_AT_type: type_uid = form_value.Reference(); break;
Greg Clayton1c8ef472013-04-05 23:27:21 +00003793 case DW_AT_external: is_external = form_value.Boolean(); break;
Greg Clayton7f995132011-10-04 22:41:51 +00003794 case DW_AT_const_value:
Andrew Kaylorb32581f2013-02-13 19:57:06 +00003795 // If we have already found a DW_AT_location attribute, ignore this attribute.
3796 if (!has_explicit_location)
3797 {
3798 location_is_const_value_data = true;
3799 // The constant value will be either a block, a data value or a string.
Ed Masteeeae7212013-10-24 20:43:47 +00003800 const DWARFDataExtractor& debug_info_data = get_debug_info_data();
Andrew Kaylorb32581f2013-02-13 19:57:06 +00003801 if (DWARFFormValue::IsBlockForm(form_value.Form()))
3802 {
3803 // Retrieve the value as a block expression.
3804 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
3805 uint32_t block_length = form_value.Unsigned();
Richard Mitton0a558352013-10-17 21:14:00 +00003806 location.CopyOpcodeData(module, debug_info_data, block_offset, block_length);
Andrew Kaylorb32581f2013-02-13 19:57:06 +00003807 }
3808 else if (DWARFFormValue::IsDataForm(form_value.Form()))
3809 {
3810 // Retrieve the value as a data expression.
Tamas Berghammerb7c64652015-08-25 11:45:46 +00003811 DWARFFormValue::FixedFormSizes fixed_form_sizes =
3812 DWARFFormValue::GetFixedFormSizesForAddressSize (
3813 attributes.CompileUnitAtIndex(i)->GetAddressByteSize(),
3814 attributes.CompileUnitAtIndex(i)->IsDWARF64());
Andrew Kaylorb32581f2013-02-13 19:57:06 +00003815 uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
Tamas Berghammerb7c64652015-08-25 11:45:46 +00003816 uint32_t data_length = fixed_form_sizes.GetSize(form_value.Form());
Enrico Granata4ec130d2014-08-11 19:16:35 +00003817 if (data_length == 0)
3818 {
3819 const uint8_t *data_pointer = form_value.BlockData();
3820 if (data_pointer)
3821 {
Jason Molenda18f5fd32014-10-16 07:52:17 +00003822 form_value.Unsigned();
Enrico Granata4ec130d2014-08-11 19:16:35 +00003823 }
3824 else if (DWARFFormValue::IsDataForm(form_value.Form()))
3825 {
3826 // we need to get the byte size of the type later after we create the variable
3827 const_value = form_value;
3828 }
3829 }
3830 else
3831 location.CopyOpcodeData(module, debug_info_data, data_offset, data_length);
Andrew Kaylorb32581f2013-02-13 19:57:06 +00003832 }
3833 else
3834 {
3835 // Retrieve the value as a string expression.
3836 if (form_value.Form() == DW_FORM_strp)
3837 {
Tamas Berghammerb7c64652015-08-25 11:45:46 +00003838 DWARFFormValue::FixedFormSizes fixed_form_sizes =
3839 DWARFFormValue::GetFixedFormSizesForAddressSize (
3840 attributes.CompileUnitAtIndex(i)->GetAddressByteSize(),
3841 attributes.CompileUnitAtIndex(i)->IsDWARF64());
Andrew Kaylorb32581f2013-02-13 19:57:06 +00003842 uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
Tamas Berghammerb7c64652015-08-25 11:45:46 +00003843 uint32_t data_length = fixed_form_sizes.GetSize(form_value.Form());
Richard Mitton0a558352013-10-17 21:14:00 +00003844 location.CopyOpcodeData(module, debug_info_data, data_offset, data_length);
Andrew Kaylorb32581f2013-02-13 19:57:06 +00003845 }
3846 else
3847 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003848 const char *str = form_value.AsCString();
Andrew Kaylorb32581f2013-02-13 19:57:06 +00003849 uint32_t string_offset = str - (const char *)debug_info_data.GetDataStart();
3850 uint32_t string_length = strlen(str) + 1;
Richard Mitton0a558352013-10-17 21:14:00 +00003851 location.CopyOpcodeData(module, debug_info_data, string_offset, string_length);
Andrew Kaylorb32581f2013-02-13 19:57:06 +00003852 }
3853 }
3854 }
3855 break;
Greg Clayton7f995132011-10-04 22:41:51 +00003856 case DW_AT_location:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003857 {
Andrew Kaylorb32581f2013-02-13 19:57:06 +00003858 location_is_const_value_data = false;
3859 has_explicit_location = true;
Greg Clayton7f995132011-10-04 22:41:51 +00003860 if (form_value.BlockData())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003861 {
Ed Masteeeae7212013-10-24 20:43:47 +00003862 const DWARFDataExtractor& debug_info_data = get_debug_info_data();
Greg Clayton7f995132011-10-04 22:41:51 +00003863
3864 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
3865 uint32_t block_length = form_value.Unsigned();
Richard Mitton0a558352013-10-17 21:14:00 +00003866 location.CopyOpcodeData(module, get_debug_info_data(), block_offset, block_length);
Greg Clayton7f995132011-10-04 22:41:51 +00003867 }
3868 else
3869 {
Ed Masteeeae7212013-10-24 20:43:47 +00003870 const DWARFDataExtractor& debug_loc_data = get_debug_loc_data();
Greg Clayton7f995132011-10-04 22:41:51 +00003871 const dw_offset_t debug_loc_offset = form_value.Unsigned();
3872
3873 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
3874 if (loc_list_length > 0)
3875 {
Richard Mitton0a558352013-10-17 21:14:00 +00003876 location.CopyOpcodeData(module, debug_loc_data, debug_loc_offset, loc_list_length);
Greg Clayton7f995132011-10-04 22:41:51 +00003877 assert (func_low_pc != LLDB_INVALID_ADDRESS);
Greg Clayton54166af2014-11-22 01:58:59 +00003878 location.SetLocationListSlide (func_low_pc - attributes.CompileUnitAtIndex(i)->GetBaseAddress());
Greg Clayton7f995132011-10-04 22:41:51 +00003879 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003880 }
3881 }
Greg Clayton7f995132011-10-04 22:41:51 +00003882 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003883
Greg Clayton1c8ef472013-04-05 23:27:21 +00003884 case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
Greg Clayton23f59502012-07-17 03:23:13 +00003885 case DW_AT_accessibility: break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton7f995132011-10-04 22:41:51 +00003886 case DW_AT_declaration:
3887 case DW_AT_description:
3888 case DW_AT_endianity:
3889 case DW_AT_segment:
3890 case DW_AT_start_scope:
3891 case DW_AT_visibility:
3892 default:
3893 case DW_AT_abstract_origin:
3894 case DW_AT_sibling:
3895 case DW_AT_specification:
3896 break;
3897 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003898 }
3899 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003900
Greg Clayton6071e6f2015-08-26 22:57:51 +00003901 const DWARFDIE parent_context_die = GetDeclContextDIEContainingDIE(die);
3902 const dw_tag_t parent_tag = die.GetParent().Tag();
3903 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);
Paul Herman10bc1a42015-08-18 22:46:57 +00003904
Greg Clayton9e9f2192013-05-17 00:55:28 +00003905 ValueType scope = eValueTypeInvalid;
3906
Greg Clayton6071e6f2015-08-26 22:57:51 +00003907 const DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die);
Greg Clayton9e9f2192013-05-17 00:55:28 +00003908 SymbolContextScope * symbol_context_scope = NULL;
3909
Siva Chandra0783ab92015-03-24 18:32:27 +00003910 if (!mangled)
3911 {
3912 // LLDB relies on the mangled name (DW_TAG_linkage_name or DW_AT_MIPS_linkage_name) to
3913 // generate fully qualified names of global variables with commands like "frame var j".
3914 // For example, if j were an int variable holding a value 4 and declared in a namespace
3915 // B which in turn is contained in a namespace A, the command "frame var j" returns
3916 // "(int) A::B::j = 4". If the compiler does not emit a linkage name, we should be able
3917 // to generate a fully qualified name from the declaration context.
Greg Clayton6071e6f2015-08-26 22:57:51 +00003918 if (parent_tag == DW_TAG_compile_unit &&
Jim Ingham0e0984e2015-09-02 01:06:46 +00003919 Language::LanguageIsCPlusPlus(die.GetLanguage()))
Siva Chandra0783ab92015-03-24 18:32:27 +00003920 {
3921 DWARFDeclContext decl_ctx;
3922
Greg Clayton6071e6f2015-08-26 22:57:51 +00003923 die.GetDWARFDeclContext(decl_ctx);
Siva Chandra0783ab92015-03-24 18:32:27 +00003924 mangled = decl_ctx.GetQualifiedNameAsConstString().GetCString();
3925 }
3926 }
3927
Greg Clayton9e9f2192013-05-17 00:55:28 +00003928 // DWARF doesn't specify if a DW_TAG_variable is a local, global
3929 // or static variable, so we have to do a little digging by
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00003930 // looking at the location of a variable to see if it contains
Greg Clayton9e9f2192013-05-17 00:55:28 +00003931 // a DW_OP_addr opcode _somewhere_ in the definition. I say
3932 // somewhere because clang likes to combine small global variables
3933 // into the same symbol and have locations like:
3934 // DW_OP_addr(0x1000), DW_OP_constu(2), DW_OP_plus
3935 // So if we don't have a DW_TAG_formal_parameter, we can look at
3936 // the location to see if it contains a DW_OP_addr opcode, and
3937 // then we can correctly classify our variables.
3938 if (tag == DW_TAG_formal_parameter)
3939 scope = eValueTypeVariableArgument;
3940 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003941 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00003942 bool op_error = false;
3943 // Check if the location has a DW_OP_addr with any address value...
3944 lldb::addr_t location_DW_OP_addr = LLDB_INVALID_ADDRESS;
3945 if (!location_is_const_value_data)
Greg Clayton2fc93ea2011-11-13 04:15:56 +00003946 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00003947 location_DW_OP_addr = location.GetLocation_DW_OP_addr (0, op_error);
3948 if (op_error)
Greg Clayton96c09682012-01-04 22:56:43 +00003949 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00003950 StreamString strm;
3951 location.DumpLocationForAddress (&strm, eDescriptionLevelFull, 0, 0, NULL);
Greg Clayton6071e6f2015-08-26 22:57:51 +00003952 GetObjectFile()->GetModule()->ReportError ("0x%8.8x: %s has an invalid location: %s", die.GetOffset(), die.GetTagAsCString(), strm.GetString().c_str());
Greg Clayton96c09682012-01-04 22:56:43 +00003953 }
Greg Clayton9e9f2192013-05-17 00:55:28 +00003954 }
Greg Claytond1767f02011-12-08 02:13:16 +00003955
Greg Clayton9e9f2192013-05-17 00:55:28 +00003956 if (location_DW_OP_addr != LLDB_INVALID_ADDRESS)
3957 {
3958 if (is_external)
3959 scope = eValueTypeVariableGlobal;
3960 else
3961 scope = eValueTypeVariableStatic;
3962
3963
3964 SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile ();
3965
3966 if (debug_map_symfile)
Greg Clayton2fc93ea2011-11-13 04:15:56 +00003967 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00003968 // When leaving the DWARF in the .o files on darwin,
3969 // when we have a global variable that wasn't initialized,
3970 // the .o file might not have allocated a virtual
3971 // address for the global variable. In this case it will
3972 // have created a symbol for the global variable
3973 // that is undefined/data and external and the value will
3974 // be the byte size of the variable. When we do the
3975 // address map in SymbolFileDWARFDebugMap we rely on
3976 // having an address, we need to do some magic here
3977 // so we can get the correct address for our global
3978 // variable. The address for all of these entries
3979 // will be zero, and there will be an undefined symbol
3980 // in this object file, and the executable will have
3981 // a matching symbol with a good address. So here we
3982 // dig up the correct address and replace it in the
3983 // location for the variable, and set the variable's
3984 // symbol context scope to be that of the main executable
3985 // so the file address will resolve correctly.
3986 bool linked_oso_file_addr = false;
3987 if (is_external && location_DW_OP_addr == 0)
Greg Clayton9422dd62013-03-04 21:46:16 +00003988 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00003989 // we have a possible uninitialized extern global
3990 ConstString const_name(mangled ? mangled : name);
3991 ObjectFile *debug_map_objfile = debug_map_symfile->GetObjectFile();
3992 if (debug_map_objfile)
Greg Clayton2fc93ea2011-11-13 04:15:56 +00003993 {
Greg Clayton3046e662013-07-10 01:23:25 +00003994 Symtab *debug_map_symtab = debug_map_objfile->GetSymtab();
Greg Clayton9e9f2192013-05-17 00:55:28 +00003995 if (debug_map_symtab)
Greg Clayton2fc93ea2011-11-13 04:15:56 +00003996 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00003997 Symbol *exe_symbol = debug_map_symtab->FindFirstSymbolWithNameAndType (const_name,
3998 eSymbolTypeData,
3999 Symtab::eDebugYes,
4000 Symtab::eVisibilityExtern);
4001 if (exe_symbol)
Greg Clayton2fc93ea2011-11-13 04:15:56 +00004002 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00004003 if (exe_symbol->ValueIsAddress())
Greg Clayton2fc93ea2011-11-13 04:15:56 +00004004 {
Greg Clayton358cf1e2015-06-25 21:46:34 +00004005 const addr_t exe_file_addr = exe_symbol->GetAddressRef().GetFileAddress();
Greg Clayton9e9f2192013-05-17 00:55:28 +00004006 if (exe_file_addr != LLDB_INVALID_ADDRESS)
Greg Clayton2fc93ea2011-11-13 04:15:56 +00004007 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00004008 if (location.Update_DW_OP_addr (exe_file_addr))
Greg Clayton2fc93ea2011-11-13 04:15:56 +00004009 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00004010 linked_oso_file_addr = true;
4011 symbol_context_scope = exe_symbol;
Greg Clayton2fc93ea2011-11-13 04:15:56 +00004012 }
4013 }
4014 }
4015 }
4016 }
4017 }
Greg Clayton9e9f2192013-05-17 00:55:28 +00004018 }
Greg Clayton9422dd62013-03-04 21:46:16 +00004019
Greg Clayton9e9f2192013-05-17 00:55:28 +00004020 if (!linked_oso_file_addr)
4021 {
4022 // The DW_OP_addr is not zero, but it contains a .o file address which
4023 // needs to be linked up correctly.
4024 const lldb::addr_t exe_file_addr = debug_map_symfile->LinkOSOFileAddress(this, location_DW_OP_addr);
4025 if (exe_file_addr != LLDB_INVALID_ADDRESS)
Greg Clayton9422dd62013-03-04 21:46:16 +00004026 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00004027 // Update the file address for this variable
4028 location.Update_DW_OP_addr (exe_file_addr);
4029 }
4030 else
4031 {
4032 // Variable didn't make it into the final executable
4033 return var_sp;
Greg Clayton9422dd62013-03-04 21:46:16 +00004034 }
Greg Claytond1767f02011-12-08 02:13:16 +00004035 }
Greg Clayton2fc93ea2011-11-13 04:15:56 +00004036 }
Greg Clayton5cf58b92011-10-05 22:22:08 +00004037 }
4038 else
4039 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00004040 scope = eValueTypeVariableLocal;
Greg Clayton5cf58b92011-10-05 22:22:08 +00004041 }
Greg Clayton7f995132011-10-04 22:41:51 +00004042 }
Greg Clayton9e9f2192013-05-17 00:55:28 +00004043
4044 if (symbol_context_scope == NULL)
4045 {
4046 switch (parent_tag)
4047 {
4048 case DW_TAG_subprogram:
4049 case DW_TAG_inlined_subroutine:
4050 case DW_TAG_lexical_block:
4051 if (sc.function)
4052 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00004053 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
Greg Clayton9e9f2192013-05-17 00:55:28 +00004054 if (symbol_context_scope == NULL)
4055 symbol_context_scope = sc.function;
4056 }
4057 break;
4058
4059 default:
4060 symbol_context_scope = sc.comp_unit;
4061 break;
4062 }
4063 }
4064
4065 if (symbol_context_scope)
4066 {
Enrico Granata4ec130d2014-08-11 19:16:35 +00004067 SymbolFileTypeSP type_sp(new SymbolFileType(*this, type_uid));
4068
4069 if (const_value.Form() && type_sp && type_sp->GetType())
Greg Clayton6071e6f2015-08-26 22:57:51 +00004070 location.CopyOpcodeData(const_value.Unsigned(), type_sp->GetType()->GetByteSize(), die.GetCU()->GetAddressByteSize());
Enrico Granata4ec130d2014-08-11 19:16:35 +00004071
Greg Clayton6071e6f2015-08-26 22:57:51 +00004072 var_sp.reset (new Variable (die.GetID(),
Greg Clayton9e9f2192013-05-17 00:55:28 +00004073 name,
4074 mangled,
Enrico Granata4ec130d2014-08-11 19:16:35 +00004075 type_sp,
Greg Clayton9e9f2192013-05-17 00:55:28 +00004076 scope,
4077 symbol_context_scope,
4078 &decl,
4079 location,
4080 is_external,
Paul Herman10bc1a42015-08-18 22:46:57 +00004081 is_artificial,
4082 is_static_member));
Greg Clayton9e9f2192013-05-17 00:55:28 +00004083
4084 var_sp->SetLocationIsConstantValueData (location_is_const_value_data);
4085 }
4086 else
4087 {
4088 // Not ready to parse this variable yet. It might be a global
4089 // or static variable that is in a function scope and the function
4090 // in the symbol context wasn't filled in yet
4091 return var_sp;
4092 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004093 }
Greg Clayton7f995132011-10-04 22:41:51 +00004094 // Cache var_sp even if NULL (the variable was just a specification or
4095 // was missing vital information to be able to be displayed in the debugger
4096 // (missing location due to optimization, etc)) so we don't re-parse
4097 // this DIE over and over later...
Greg Clayton6071e6f2015-08-26 22:57:51 +00004098 m_die_to_variable_sp[die.GetDIE()] = var_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004099 }
4100 return var_sp;
4101}
4102
Greg Claytonc662ec82011-06-17 22:10:16 +00004103
Greg Clayton6071e6f2015-08-26 22:57:51 +00004104DWARFDIE
Greg Claytonc662ec82011-06-17 22:10:16 +00004105SymbolFileDWARF::FindBlockContainingSpecification (dw_offset_t func_die_offset,
Greg Clayton6071e6f2015-08-26 22:57:51 +00004106 dw_offset_t spec_block_die_offset)
Greg Claytonc662ec82011-06-17 22:10:16 +00004107{
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"
Greg Clayton6071e6f2015-08-26 22:57:51 +00004111 return FindBlockContainingSpecification (DebugInfo()->GetDIE (func_die_offset), spec_block_die_offset);
Greg Claytonc662ec82011-06-17 22:10:16 +00004112}
4113
4114
Greg Clayton6071e6f2015-08-26 22:57:51 +00004115DWARFDIE
4116SymbolFileDWARF::FindBlockContainingSpecification(const DWARFDIE &die,
4117 dw_offset_t spec_block_die_offset)
Greg Claytonc662ec82011-06-17 22:10:16 +00004118{
4119 if (die)
4120 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00004121 switch (die.Tag())
Greg Claytonc662ec82011-06-17 22:10:16 +00004122 {
4123 case DW_TAG_subprogram:
4124 case DW_TAG_inlined_subroutine:
4125 case DW_TAG_lexical_block:
4126 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00004127 if (die.GetAttributeValueAsReference (DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset)
Greg Claytonc662ec82011-06-17 22:10:16 +00004128 return die;
Greg Claytonc662ec82011-06-17 22:10:16 +00004129
Greg Clayton6071e6f2015-08-26 22:57:51 +00004130 if (die.GetAttributeValueAsReference (DW_AT_abstract_origin, DW_INVALID_OFFSET) == spec_block_die_offset)
Greg Claytonc662ec82011-06-17 22:10:16 +00004131 return die;
Greg Claytonc662ec82011-06-17 22:10:16 +00004132 }
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"
Greg Clayton6071e6f2015-08-26 22:57:51 +00004139 for (DWARFDIE child_die = die.GetFirstChild(); child_die; child_die = child_die.GetSibling())
Greg Claytonc662ec82011-06-17 22:10:16 +00004140 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00004141 DWARFDIE result_die = FindBlockContainingSpecification (child_die, spec_block_die_offset);
Greg Claytonc662ec82011-06-17 22:10:16 +00004142 if (result_die)
4143 return result_die;
4144 }
4145 }
4146
Greg Clayton6071e6f2015-08-26 22:57:51 +00004147 return DWARFDIE();
Greg Claytonc662ec82011-06-17 22:10:16 +00004148}
4149
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004150size_t
Greg Clayton6071e6f2015-08-26 22:57:51 +00004151SymbolFileDWARF::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)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004157{
Greg Clayton6071e6f2015-08-26 22:57:51 +00004158 if (!orig_die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004159 return 0;
4160
Greg Claytonc662ec82011-06-17 22:10:16 +00004161 VariableListSP variable_list_sp;
4162
4163 size_t vars_added = 0;
Greg Clayton6071e6f2015-08-26 22:57:51 +00004164 DWARFDIE die = orig_die;
4165 while (die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004166 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00004167 dw_tag_t tag = die.Tag();
Greg Claytonc662ec82011-06-17 22:10:16 +00004168
4169 // Check to see if we have already parsed this variable or constant?
Greg Clayton6071e6f2015-08-26 22:57:51 +00004170 VariableSP var_sp = m_die_to_variable_sp[die.GetDIE()];
4171 if (var_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004172 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004173 if (cc_variable_list)
Greg Clayton6071e6f2015-08-26 22:57:51 +00004174 cc_variable_list->AddVariableIfUnique (var_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004175 }
4176 else
4177 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004178 // 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))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004182 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004183 if (variable_list_sp.get() == NULL)
Greg Clayton73bf5db2011-06-17 01:22:15 +00004184 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00004185 DWARFDIE sc_parent_die = GetParentSymbolContextDIE(orig_die);
4186 dw_tag_t parent_tag = sc_parent_die.Tag();
Greg Claytonc662ec82011-06-17 22:10:16 +00004187 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 {
Daniel Malead01b2952012-11-29 21:49:15 +00004201 GetObjectFile()->GetModule()->ReportError ("parent 0x%8.8" PRIx64 " %s with no valid compile unit in symbol context for 0x%8.8" PRIx64 " %s.\n",
Greg Clayton6071e6f2015-08-26 22:57:51 +00004202 sc_parent_die.GetID(),
4203 sc_parent_die.GetTagAsCString(),
4204 orig_die.GetID(),
4205 orig_die.GetTagAsCString());
Greg Claytonc662ec82011-06-17 22:10:16 +00004206 }
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
Greg Clayton6071e6f2015-08-26 22:57:51 +00004216 Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
Greg Claytonc662ec82011-06-17 22:10:16 +00004217 if (block == NULL)
4218 {
4219 // This must be a specification or abstract origin with
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00004220 // a concrete block counterpart in the current function. We need
Greg Claytonc662ec82011-06-17 22:10:16 +00004221 // to find the concrete block so we can correctly add the
4222 // variable to it
Greg Clayton6071e6f2015-08-26 22:57:51 +00004223 const DWARFDIE concrete_block_die = FindBlockContainingSpecification (sc.function->GetID(),
4224 sc_parent_die.GetOffset());
Greg Claytonc662ec82011-06-17 22:10:16 +00004225 if (concrete_block_die)
Greg Clayton6071e6f2015-08-26 22:57:51 +00004226 block = sc.function->GetBlock(true).FindBlockByID(concrete_block_die.GetID());
Greg Claytonc662ec82011-06-17 22:10:16 +00004227 }
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:
Daniel Malead01b2952012-11-29 21:49:15 +00004243 GetObjectFile()->GetModule()->ReportError ("didn't find appropriate parent DIE for variable list for 0x%8.8" PRIx64 " %s.\n",
Greg Clayton6071e6f2015-08-26 22:57:51 +00004244 orig_die.GetID(),
4245 orig_die.GetTagAsCString());
Greg Claytonc662ec82011-06-17 22:10:16 +00004246 break;
4247 }
Greg Clayton73bf5db2011-06-17 01:22:15 +00004248 }
Greg Claytonc662ec82011-06-17 22:10:16 +00004249
4250 if (variable_list_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004251 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00004252 VariableSP var_sp (ParseVariableDIE(sc, die, func_low_pc));
Greg Clayton73bf5db2011-06-17 01:22:15 +00004253 if (var_sp)
4254 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004255 variable_list_sp->AddVariableIfUnique (var_sp);
Greg Clayton73bf5db2011-06-17 01:22:15 +00004256 if (cc_variable_list)
4257 cc_variable_list->AddVariableIfUnique (var_sp);
4258 ++vars_added;
4259 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004260 }
4261 }
4262 }
Greg Claytonc662ec82011-06-17 22:10:16 +00004263
4264 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
4265
Greg Clayton6071e6f2015-08-26 22:57:51 +00004266 if (!skip_children && parse_children && die.HasChildren())
Greg Claytonc662ec82011-06-17 22:10:16 +00004267 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00004268 vars_added += ParseVariables(sc, die.GetFirstChild(), func_low_pc, true, true, cc_variable_list);
Greg Claytonc662ec82011-06-17 22:10:16 +00004269 }
4270
4271 if (parse_siblings)
Greg Clayton6071e6f2015-08-26 22:57:51 +00004272 die = die.GetSibling();
Greg Claytonc662ec82011-06-17 22:10:16 +00004273 else
Greg Clayton6071e6f2015-08-26 22:57:51 +00004274 die.Clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004275 }
Greg Claytonc662ec82011-06-17 22:10:16 +00004276 return vars_added;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004277}
4278
4279//------------------------------------------------------------------
4280// PluginInterface protocol
4281//------------------------------------------------------------------
Greg Clayton57abc5d2013-05-10 21:47:16 +00004282ConstString
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004283SymbolFileDWARF::GetPluginName()
4284{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004285 return GetPluginNameStatic();
4286}
4287
4288uint32_t
4289SymbolFileDWARF::GetPluginVersion()
4290{
4291 return 1;
4292}
4293
4294void
Sean Callanancc427fa2011-07-30 02:42:06 +00004295SymbolFileDWARF::DumpIndexes ()
4296{
4297 StreamFile s(stdout, false);
4298
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00004299 s.Printf ("DWARF index for (%s) '%s':",
Sean Callanancc427fa2011-07-30 02:42:06 +00004300 GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(),
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00004301 GetObjectFile()->GetFileSpec().GetPath().c_str());
Sean Callanancc427fa2011-07-30 02:42:06 +00004302 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);
Bruce Mitchenere171da52015-07-22 00:16:02 +00004309 s.Printf("\nNamespaces:\n"); m_namespace_index.Dump (&s);
Sean Callanancc427fa2011-07-30 02:42:06 +00004310}
4311
Greg Claytoncaab74e2012-01-28 00:48:57 +00004312
Greg Clayton1f746072012-08-29 21:13:06 +00004313SymbolFileDWARFDebugMap *
4314SymbolFileDWARF::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
Greg Claytoncaab74e2012-01-28 00:48:57 +00004329