LLDB  mainline
DWARFUnit.cpp
Go to the documentation of this file.
1 //===-- DWARFUnit.cpp -------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "DWARFUnit.h"
10 
11 #include "lldb/Core/Module.h"
14 #include "lldb/Symbol/LineTable.h"
15 #include "lldb/Symbol/ObjectFile.h"
18 #include "lldb/Utility/Timer.h"
19 
20 #include "DWARFDebugAranges.h"
21 #include "DWARFDebugInfo.h"
22 #include "LogChannelDWARF.h"
24 #include "SymbolFileDWARFDwo.h"
25 
26 using namespace lldb;
27 using namespace lldb_private;
28 using namespace std;
29 
30 extern int g_verbose;
31 
33  : UserID(uid), m_dwarf(dwarf), m_cancel_scopes(false) {}
34 
36 
37 // Parses first DIE of a compile unit.
39  {
40  llvm::sys::ScopedReader lock(m_first_die_mutex);
41  if (m_first_die)
42  return; // Already parsed
43  }
44  llvm::sys::ScopedWriter lock(m_first_die_mutex);
45  if (m_first_die)
46  return; // Already parsed
47 
48  static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
49  Timer scoped_timer(
50  func_cat, "%8.8x: DWARFUnit::ExtractUnitDIEIfNeeded()", m_offset);
51 
52  // Set the offset to that of the first DIE and calculate the start of the
53  // next compilation unit header.
55 
56  // We are in our compile unit, parse starting at the offset we were told to
57  // parse
58  const DWARFDataExtractor &data = GetData();
59  DWARFFormValue::FixedFormSizes fixed_form_sizes =
61  if (offset < GetNextCompileUnitOffset() &&
62  m_first_die.FastExtract(data, this, fixed_form_sizes, &offset)) {
63  AddUnitDIE(m_first_die);
64  return;
65  }
66 }
67 
68 // Parses a compile unit and indexes its DIEs if it hasn't already been done.
69 // It will leave this compile unit extracted forever.
71  m_cancel_scopes = true;
72 
73  {
74  llvm::sys::ScopedReader lock(m_die_array_mutex);
75  if (!m_die_array.empty())
76  return; // Already parsed
77  }
78  llvm::sys::ScopedWriter lock(m_die_array_mutex);
79  if (!m_die_array.empty())
80  return; // Already parsed
81 
82  ExtractDIEsRWLocked();
83 }
84 
85 // Parses a compile unit and indexes its DIEs if it hasn't already been done.
86 // It will clear this compile unit after returned instance gets out of scope,
87 // no other ScopedExtractDIEs instance is running for this compile unit
88 // and no ExtractDIEsIfNeeded() has been executed during this ScopedExtractDIEs
89 // lifetime.
91  ScopedExtractDIEs scoped(this);
92 
93  {
94  llvm::sys::ScopedReader lock(m_die_array_mutex);
95  if (!m_die_array.empty())
96  return scoped; // Already parsed
97  }
98  llvm::sys::ScopedWriter lock(m_die_array_mutex);
99  if (!m_die_array.empty())
100  return scoped; // Already parsed
101 
102  // Otherwise m_die_array would be already populated.
104 
105  ExtractDIEsRWLocked();
106  scoped.m_clear_dies = true;
107  return scoped;
108 }
109 
111  lldbassert(m_cu);
112  m_cu->m_die_array_scoped_mutex.lock_shared();
113 }
114 
116  if (!m_cu)
117  return;
118  m_cu->m_die_array_scoped_mutex.unlock_shared();
119  if (!m_clear_dies || m_cu->m_cancel_scopes)
120  return;
121  // Be sure no other ScopedExtractDIEs is running anymore.
122  llvm::sys::ScopedWriter lock_scoped(m_cu->m_die_array_scoped_mutex);
123  llvm::sys::ScopedWriter lock(m_cu->m_die_array_mutex);
124  if (m_cu->m_cancel_scopes)
125  return;
126  m_cu->ClearDIEsRWLocked();
127 }
128 
130  : m_cu(rhs.m_cu), m_clear_dies(rhs.m_clear_dies) {
131  rhs.m_cu = nullptr;
132 }
133 
136  m_cu = rhs.m_cu;
137  rhs.m_cu = nullptr;
138  m_clear_dies = rhs.m_clear_dies;
139  return *this;
140 }
141 
142 // Parses a compile unit and indexes its DIEs, m_die_array_mutex must be
143 // held R/W and m_die_array must be empty.
144 void DWARFUnit::ExtractDIEsRWLocked() {
145  llvm::sys::ScopedWriter first_die_lock(m_first_die_mutex);
146 
147  static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
148  Timer scoped_timer(
149  func_cat, "%8.8x: DWARFUnit::ExtractDIEsIfNeeded()", m_offset);
150 
151  // Set the offset to that of the first DIE and calculate the start of the
152  // next compilation unit header.
154  lldb::offset_t next_cu_offset = GetNextCompileUnitOffset();
155 
157 
158  uint32_t depth = 0;
159  // We are in our compile unit, parse starting at the offset we were told to
160  // parse
161  const DWARFDataExtractor &data = GetData();
162  std::vector<uint32_t> die_index_stack;
163  die_index_stack.reserve(32);
164  die_index_stack.push_back(0);
165  bool prev_die_had_children = false;
166  DWARFFormValue::FixedFormSizes fixed_form_sizes =
168  while (offset < next_cu_offset &&
169  die.FastExtract(data, this, fixed_form_sizes, &offset)) {
170  const bool null_die = die.IsNULL();
171  if (depth == 0) {
172  assert(m_die_array.empty() && "Compile unit DIE already added");
173 
174  // The average bytes per DIE entry has been seen to be around 14-20 so
175  // lets pre-reserve half of that since we are now stripping the NULL
176  // tags.
177 
178  // Only reserve the memory if we are adding children of the main
179  // compile unit DIE. The compile unit DIE is always the first entry, so
180  // if our size is 1, then we are adding the first compile unit child
181  // DIE and should reserve the memory.
182  m_die_array.reserve(GetDebugInfoSize() / 24);
183  m_die_array.push_back(die);
184 
185  if (!m_first_die)
186  AddUnitDIE(m_die_array.front());
187  } else {
188  if (null_die) {
189  if (prev_die_had_children) {
190  // This will only happen if a DIE says is has children but all it
191  // contains is a NULL tag. Since we are removing the NULL DIEs from
192  // the list (saves up to 25% in C++ code), we need a way to let the
193  // DIE know that it actually doesn't have children.
194  if (!m_die_array.empty())
195  m_die_array.back().SetHasChildren(false);
196  }
197  } else {
198  die.SetParentIndex(m_die_array.size() - die_index_stack[depth - 1]);
199 
200  if (die_index_stack.back())
201  m_die_array[die_index_stack.back()].SetSiblingIndex(
202  m_die_array.size() - die_index_stack.back());
203 
204  // Only push the DIE if it isn't a NULL DIE
205  m_die_array.push_back(die);
206  }
207  }
208 
209  if (null_die) {
210  // NULL DIE.
211  if (!die_index_stack.empty())
212  die_index_stack.pop_back();
213 
214  if (depth > 0)
215  --depth;
216  prev_die_had_children = false;
217  } else {
218  die_index_stack.back() = m_die_array.size() - 1;
219  // Normal DIE
220  const bool die_has_children = die.HasChildren();
221  if (die_has_children) {
222  die_index_stack.push_back(0);
223  ++depth;
224  }
225  prev_die_had_children = die_has_children;
226  }
227 
228  if (depth == 0)
229  break; // We are done with this compile unit!
230  }
231 
232  if (!m_die_array.empty()) {
233  if (m_first_die) {
234  // Only needed for the assertion.
235  m_first_die.SetHasChildren(m_die_array.front().HasChildren());
236  lldbassert(m_first_die == m_die_array.front());
237  }
238  m_first_die = m_die_array.front();
239  }
240 
241  m_die_array.shrink_to_fit();
242 
243  if (m_dwo_symbol_file) {
244  DWARFUnit *dwo_cu = m_dwo_symbol_file->GetCompileUnit();
245  dwo_cu->ExtractDIEsIfNeeded();
246  }
247 }
248 
249 // This is used when a split dwarf is enabled.
250 // A skeleton compilation unit may contain the DW_AT_str_offsets_base attribute
251 // that points to the first string offset of the CU contribution to the
252 // .debug_str_offsets. At the same time, the corresponding split debug unit also
253 // may use DW_FORM_strx* forms pointing to its own .debug_str_offsets.dwo and
254 // for that case, we should find the offset (skip the section header).
255 static void SetDwoStrOffsetsBase(DWARFUnit *dwo_cu) {
256  lldb::offset_t baseOffset = 0;
257 
258  const DWARFDataExtractor &strOffsets =
260  uint64_t length = strOffsets.GetU32(&baseOffset);
261  if (length == 0xffffffff)
262  length = strOffsets.GetU64(&baseOffset);
263 
264  // Check version.
265  if (strOffsets.GetU16(&baseOffset) < 5)
266  return;
267 
268  // Skip padding.
269  baseOffset += 2;
270 
271  dwo_cu->SetStrOffsetsBase(baseOffset);
272 }
273 
274 // m_die_array_mutex must be already held as read/write.
275 void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
276  dw_addr_t addr_base = cu_die.GetAttributeValueAsUnsigned(
277  m_dwarf, this, DW_AT_addr_base, LLDB_INVALID_ADDRESS);
278  if (addr_base != LLDB_INVALID_ADDRESS)
279  SetAddrBase(addr_base);
280 
281  dw_addr_t ranges_base = cu_die.GetAttributeValueAsUnsigned(
282  m_dwarf, this, DW_AT_rnglists_base, LLDB_INVALID_ADDRESS);
283  if (ranges_base != LLDB_INVALID_ADDRESS)
284  SetRangesBase(ranges_base);
285 
287  m_dwarf, this, DW_AT_str_offsets_base, 0));
288 
289  uint64_t base_addr = cu_die.GetAttributeValueAsAddress(
290  m_dwarf, this, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
291  if (base_addr == LLDB_INVALID_ADDRESS)
292  base_addr = cu_die.GetAttributeValueAsAddress(
293  m_dwarf, this, DW_AT_entry_pc, 0);
294  SetBaseAddress(base_addr);
295 
296  std::unique_ptr<SymbolFileDWARFDwo> dwo_symbol_file =
297  m_dwarf->GetDwoSymbolFileForCompileUnit(*this, cu_die);
298  if (!dwo_symbol_file)
299  return;
300 
301  DWARFUnit *dwo_cu = dwo_symbol_file->GetCompileUnit();
302  if (!dwo_cu)
303  return; // Can't fetch the compile unit from the dwo file.
304 
305  DWARFBaseDIE dwo_cu_die = dwo_cu->GetUnitDIEOnly();
306  if (!dwo_cu_die.IsValid())
307  return; // Can't fetch the compile unit DIE from the dwo file.
308 
309  uint64_t main_dwo_id =
310  cu_die.GetAttributeValueAsUnsigned(m_dwarf, this, DW_AT_GNU_dwo_id, 0);
311  uint64_t sub_dwo_id =
312  dwo_cu_die.GetAttributeValueAsUnsigned(DW_AT_GNU_dwo_id, 0);
313  if (main_dwo_id != sub_dwo_id)
314  return; // The 2 dwo ID isn't match. Don't use the dwo file as it belongs to
315  // a differectn compilation.
316 
317  m_dwo_symbol_file = std::move(dwo_symbol_file);
318 
319  // Here for DWO CU we want to use the address base set in the skeleton unit
320  // (DW_AT_addr_base) if it is available and use the DW_AT_GNU_addr_base
321  // otherwise. We do that because pre-DWARF v5 could use the DW_AT_GNU_*
322  // attributes which were applicable to the DWO units. The corresponding
323  // DW_AT_* attributes standardized in DWARF v5 are also applicable to the main
324  // unit in contrast.
325  if (addr_base == LLDB_INVALID_ADDRESS)
326  addr_base = cu_die.GetAttributeValueAsUnsigned(m_dwarf, this,
327  DW_AT_GNU_addr_base, 0);
328  dwo_cu->SetAddrBase(addr_base);
329 
330  if (ranges_base == LLDB_INVALID_ADDRESS)
331  ranges_base = cu_die.GetAttributeValueAsUnsigned(m_dwarf, this,
332  DW_AT_GNU_ranges_base, 0);
333  dwo_cu->SetRangesBase(ranges_base);
334 
335  dwo_cu->SetBaseObjOffset(m_offset);
336 
337  SetDwoStrOffsetsBase(dwo_cu);
338 }
339 
341  if (DIE()) {
342  const DWARFDebugAranges &func_aranges = GetFunctionAranges();
343 
344  // Re-check the aranges auto pointer contents in case it was created above
345  if (!func_aranges.IsEmpty())
346  return GetDIE(func_aranges.FindAddress(address));
347  }
348  return DWARFDIE();
349 }
350 
352  std::vector<DWARFDIE> &dies,
353  uint32_t depth) const {
354  size_t old_size = dies.size();
355  {
356  llvm::sys::ScopedReader lock(m_die_array_mutex);
359  for (pos = m_die_array.begin(); pos != end; ++pos) {
360  if (pos->Tag() == tag)
361  dies.emplace_back(this, &(*pos));
362  }
363  }
364 
365  // Return the number of DIEs added to the collection
366  return dies.size() - old_size;
367 }
368 
370  return m_offset + GetLengthByteSize() + GetLength();
371 }
372 
375 }
376 
378  return m_abbrevs;
379 }
380 
383 }
384 
385 void DWARFUnit::SetAddrBase(dw_addr_t addr_base) { m_addr_base = addr_base; }
386 
388  m_ranges_base = ranges_base;
389 }
390 
392  m_base_obj_offset = base_obj_offset;
393 }
394 
396  m_str_offsets_base = str_offsets_base;
397 }
398 
399 // It may be called only with m_die_array_mutex held R/W.
400 void DWARFUnit::ClearDIEsRWLocked() {
401  m_die_array.clear();
402  m_die_array.shrink_to_fit();
403 
404  if (m_dwo_symbol_file)
405  m_dwo_symbol_file->GetCompileUnit()->ClearDIEsRWLocked();
406 }
407 
409  DWARFDebugAranges *debug_aranges) {
410  // This function is usually called if there in no .debug_aranges section in
411  // order to produce a compile unit level set of address ranges that is
412  // accurate.
413 
414  size_t num_debug_aranges = debug_aranges->GetNumRanges();
415 
416  // First get the compile unit DIE only and check if it has a DW_AT_ranges
417  const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly();
418 
419  const dw_offset_t cu_offset = GetOffset();
420  if (die) {
421  DWARFRangeList ranges;
422  const size_t num_ranges =
423  die->GetAttributeAddressRanges(dwarf, this, ranges, false);
424  if (num_ranges > 0) {
425  // This compile unit has DW_AT_ranges, assume this is correct if it is
426  // present since clang no longer makes .debug_aranges by default and it
427  // emits DW_AT_ranges for DW_TAG_compile_units. GCC also does this with
428  // recent GCC builds.
429  for (size_t i = 0; i < num_ranges; ++i) {
430  const DWARFRangeList::Entry &range = ranges.GetEntryRef(i);
431  debug_aranges->AppendRange(cu_offset, range.GetRangeBase(),
432  range.GetRangeEnd());
433  }
434 
435  return; // We got all of our ranges from the DW_AT_ranges attribute
436  }
437  }
438  // We don't have a DW_AT_ranges attribute, so we need to parse the DWARF
439 
440  // If the DIEs weren't parsed, then we don't want all dies for all compile
441  // units to stay loaded when they weren't needed. So we can end up parsing
442  // the DWARF and then throwing them all away to keep memory usage down.
443  ScopedExtractDIEs clear_dies(ExtractDIEsScoped());
444 
445  die = DIEPtr();
446  if (die)
447  die->BuildAddressRangeTable(dwarf, this, debug_aranges);
448 
449  if (debug_aranges->GetNumRanges() == num_debug_aranges) {
450  // We got nothing from the functions, maybe we have a line tables only
451  // situation. Check the line tables and build the arange table from this.
452  SymbolContext sc;
453  sc.comp_unit = dwarf->GetCompUnitForDWARFCompUnit(this);
454  if (sc.comp_unit) {
455  SymbolFileDWARFDebugMap *debug_map_sym_file =
457  if (debug_map_sym_file == NULL) {
458  LineTable *line_table = sc.comp_unit->GetLineTable();
459 
460  if (line_table) {
461  LineTable::FileAddressRanges file_ranges;
462  const bool append = true;
463  const size_t num_ranges =
464  line_table->GetContiguousFileAddressRanges(file_ranges, append);
465  for (uint32_t idx = 0; idx < num_ranges; ++idx) {
467  file_ranges.GetEntryRef(idx);
468  debug_aranges->AppendRange(cu_offset, range.GetRangeBase(),
469  range.GetRangeEnd());
470  }
471  }
472  } else
473  debug_map_sym_file->AddOSOARanges(dwarf, debug_aranges);
474  }
475  }
476 
477  if (debug_aranges->GetNumRanges() == num_debug_aranges) {
478  // We got nothing from the functions, maybe we have a line tables only
479  // situation. Check the line tables and build the arange table from this.
480  SymbolContext sc;
481  sc.comp_unit = dwarf->GetCompUnitForDWARFCompUnit(this);
482  if (sc.comp_unit) {
483  LineTable *line_table = sc.comp_unit->GetLineTable();
484 
485  if (line_table) {
486  LineTable::FileAddressRanges file_ranges;
487  const bool append = true;
488  const size_t num_ranges =
489  line_table->GetContiguousFileAddressRanges(file_ranges, append);
490  for (uint32_t idx = 0; idx < num_ranges; ++idx) {
492  file_ranges.GetEntryRef(idx);
493  debug_aranges->AppendRange(GetOffset(), range.GetRangeBase(),
494  range.GetRangeEnd());
495  }
496  }
497  }
498  }
499 }
500 
502  return m_dwarf->GetObjectFile()->GetByteOrder();
503 }
504 
506  if (m_dwarf)
508  else
509  return nullptr;
510 }
511 
514 }
515 
516 void DWARFUnit::SetBaseAddress(dw_addr_t base_addr) { m_base_addr = base_addr; }
517 
518 // Compare function DWARFDebugAranges::Range structures
519 static bool CompareDIEOffset(const DWARFDebugInfoEntry &die,
520  const dw_offset_t die_offset) {
521  return die.GetOffset() < die_offset;
522 }
523 
524 // GetDIE()
525 //
526 // Get the DIE (Debug Information Entry) with the specified offset by first
527 // checking if the DIE is contained within this compile unit and grabbing the
528 // DIE from this compile unit. Otherwise we grab the DIE from the DWARF file.
529 DWARFDIE
531  if (die_offset != DW_INVALID_OFFSET) {
532  if (GetDwoSymbolFile())
533  return GetDwoSymbolFile()->GetCompileUnit()->GetDIE(die_offset);
534 
535  if (ContainsDIEOffset(die_offset)) {
539  lower_bound(m_die_array.cbegin(), end, die_offset, CompareDIEOffset);
540  if (pos != end) {
541  if (die_offset == (*pos).GetOffset())
542  return DWARFDIE(this, &(*pos));
543  }
544  } else {
545  // Don't specify the compile unit offset as we don't know it because the
546  // DIE belongs to
547  // a different compile unit in the same symbol file.
548  return m_dwarf->DebugInfo()->GetDIEForDIEOffset(die_offset);
549  }
550  }
551  return DWARFDIE(); // Not found
552 }
553 
555  if (cu)
556  return cu->GetAddressByteSize();
558 }
559 
560 uint8_t DWARFUnit::GetDefaultAddressSize() { return 4; }
561 
562 void *DWARFUnit::GetUserData() const { return m_user_data; }
563 
564 void DWARFUnit::SetUserData(void *d) {
565  m_user_data = d;
566  if (m_dwo_symbol_file)
567  m_dwo_symbol_file->GetCompileUnit()->SetUserData(d);
568 }
569 
571  return GetProducer() != eProducerLLVMGCC;
572 }
573 
575  // llvm-gcc makes completely invalid decl file attributes and won't ever be
576  // fixed, so we need to know to ignore these.
577  return GetProducer() == eProducerLLVMGCC;
578 }
579 
581  if (GetProducer() == eProducerClang) {
582  const uint32_t major_version = GetProducerVersionMajor();
583  return major_version > 425 ||
584  (major_version == 425 && GetProducerVersionUpdate() >= 13);
585  }
586  return true; // Assume all other compilers didn't have incorrect ObjC bitfield
587  // info
588 }
589 
591 
592 void DWARFUnit::ParseProducerInfo() {
596 
597  const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly();
598  if (die) {
599 
600  const char *producer_cstr =
601  die->GetAttributeValueAsString(m_dwarf, this, DW_AT_producer, NULL);
602  if (producer_cstr) {
603  RegularExpression llvm_gcc_regex(
604  llvm::StringRef("^4\\.[012]\\.[01] \\(Based on Apple "
605  "Inc\\. build [0-9]+\\) \\(LLVM build "
606  "[\\.0-9]+\\)$"));
607  if (llvm_gcc_regex.Execute(llvm::StringRef(producer_cstr))) {
609  } else if (strstr(producer_cstr, "clang")) {
610  static RegularExpression g_clang_version_regex(
611  llvm::StringRef("clang-([0-9]+)\\.([0-9]+)\\.([0-9]+)"));
612  RegularExpression::Match regex_match(3);
613  if (g_clang_version_regex.Execute(llvm::StringRef(producer_cstr),
614  &regex_match)) {
615  std::string str;
616  if (regex_match.GetMatchAtIndex(producer_cstr, 1, str))
618  StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
619  if (regex_match.GetMatchAtIndex(producer_cstr, 2, str))
621  StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
622  if (regex_match.GetMatchAtIndex(producer_cstr, 3, str))
624  StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
625  }
627  } else if (strstr(producer_cstr, "GNU"))
629  }
630  }
633 }
634 
637  ParseProducerInfo();
638  return m_producer;
639 }
640 
642  if (m_producer_version_major == 0)
643  ParseProducerInfo();
645 }
646 
648  if (m_producer_version_minor == 0)
649  ParseProducerInfo();
651 }
652 
654  if (m_producer_version_update == 0)
655  ParseProducerInfo();
657 }
659  // Note: user languages between lo_user and hi_user must be handled
660  // explicitly here.
661  switch (val) {
662  case DW_LANG_Mips_Assembler:
664  case DW_LANG_GOOGLE_RenderScript:
666  default:
667  return static_cast<LanguageType>(val);
668  }
669 }
670 
673  return m_language_type;
674 
675  const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly();
676  if (die)
678  die->GetAttributeValueAsUnsigned(m_dwarf, this, DW_AT_language, 0));
679  return m_language_type;
680 }
681 
684  const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly();
685  if (die) {
687  if (die->GetAttributeValueAsUnsigned(m_dwarf, this, DW_AT_APPLE_optimized,
688  0) == 1) {
690  }
691  }
692  }
693  return m_is_optimized == eLazyBoolYes;
694 }
695 
697  if (!m_comp_dir)
698  ComputeCompDirAndGuessPathStyle();
699  return m_comp_dir->GetPathStyle();
700 }
701 
703  if (!m_comp_dir)
704  ComputeCompDirAndGuessPathStyle();
705  return *m_comp_dir;
706 }
707 
708 // DWARF2/3 suggests the form hostname:pathname for compilation directory.
709 // Remove the host part if present.
710 static llvm::StringRef
711 removeHostnameFromPathname(llvm::StringRef path_from_dwarf) {
712  llvm::StringRef host, path;
713  std::tie(host, path) = path_from_dwarf.split(':');
714 
715  if (host.contains('/'))
716  return path_from_dwarf;
717 
718  // check whether we have a windows path, and so the first character is a
719  // drive-letter not a hostname.
720  if (host.size() == 1 && llvm::isAlpha(host[0]) && path.startswith("\\"))
721  return path_from_dwarf;
722 
723  return path;
724 }
725 
726 static FileSpec resolveCompDir(const FileSpec &path) {
727  bool is_symlink = SymbolFileDWARF::GetSymlinkPaths().FindFileIndex(
728  0, path, /*full*/ true) != UINT32_MAX;
729 
730  if (!is_symlink)
731  return path;
732 
733  namespace fs = llvm::sys::fs;
734  if (fs::get_file_type(path.GetPath(), false) != fs::file_type::symlink_file)
735  return path;
736 
737  FileSpec resolved_symlink;
738  const auto error = FileSystem::Instance().Readlink(path, resolved_symlink);
739  if (error.Success())
740  return resolved_symlink;
741 
742  return path;
743 }
744 
745 void DWARFUnit::ComputeCompDirAndGuessPathStyle() {
746  m_comp_dir = FileSpec();
747  const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly();
748  if (!die)
749  return;
750 
751  llvm::StringRef comp_dir = removeHostnameFromPathname(
752  die->GetAttributeValueAsString(m_dwarf, this, DW_AT_comp_dir, NULL));
753  if (!comp_dir.empty()) {
754  FileSpec::Style comp_dir_style =
755  FileSpec::GuessPathStyle(comp_dir).getValueOr(FileSpec::Style::native);
756  m_comp_dir = resolveCompDir(FileSpec(comp_dir, comp_dir_style));
757  } else {
758  // Try to detect the style based on the DW_AT_name attribute, but just store
759  // the detected style in the m_comp_dir field.
760  const char *name =
761  die->GetAttributeValueAsString(m_dwarf, this, DW_AT_name, NULL);
763  "", FileSpec::GuessPathStyle(name).getValueOr(FileSpec::Style::native));
764  }
765 }
766 
768  return m_dwo_symbol_file.get();
769 }
770 
772 
774  if (m_func_aranges_up == NULL) {
776  const DWARFDebugInfoEntry *die = DIEPtr();
777  if (die)
779  m_func_aranges_up.get());
780 
781  if (m_dwo_symbol_file) {
782  DWARFUnit *dwo_cu = m_dwo_symbol_file->GetCompileUnit();
783  const DWARFDebugInfoEntry *dwo_die = dwo_cu->DIEPtr();
784  if (dwo_die)
785  dwo_die->BuildFunctionAddressRangeTable(m_dwo_symbol_file.get(), dwo_cu,
786  m_func_aranges_up.get());
787  }
788 
789  const bool minimize = false;
790  m_func_aranges_up->Sort(minimize);
791  }
792  return *m_func_aranges_up;
793 }
794 
ScopedExtractDIEs & operator=(ScopedExtractDIEs &&rhs)
Definition: DWARFUnit.cpp:134
DWARFBaseDIE GetUnitDIEOnly()
Definition: DWARFUnit.h:122
virtual const lldb_private::DWARFDataExtractor & get_debug_str_offsets_data()
uint32_t m_producer_version_update
Definition: DWARFUnit.h:202
lldb_private::LazyBool m_is_optimized
Definition: DWARFUnit.h:204
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
void * m_user_data
Definition: DWARFUnit.h:176
dw_offset_t FindAddress(dw_addr_t address) const
bool ContainsDIEOffset(dw_offset_t die_offset) const
Definition: DWARFUnit.h:85
static uint8_t GetDefaultAddressSize()
Definition: DWARFUnit.cpp:560
#define lldbassert(x)
Definition: LLDBAssert.h:15
uint32_t GetU32(lldb::offset_t *offset_ptr) const
Extract a uint32_t value from *offset_ptr.
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:33
DWARFDIE GetDIE(dw_offset_t die_offset)
Definition: DWARFUnit.cpp:530
void SetUserData(void *d)
Definition: DWARFUnit.cpp:564
size_t AppendDIEsWithTag(const dw_tag_t tag, std::vector< DWARFDIE > &dies, uint32_t depth=UINT32_MAX) const
Definition: DWARFUnit.cpp:351
static void SetDwoStrOffsetsBase(DWARFUnit *dwo_cu)
Definition: DWARFUnit.cpp:255
A mix in class that contains a generic user ID.
Definition: UserID.h:33
A file utility class.
Definition: FileSpec.h:55
"lldb/Utility/RegularExpression.h" A C++ wrapper class for regex.
A timer class that simplifies common timing metrics.
Definition: Timer.h:23
uint32_t m_producer_version_minor
Definition: DWARFUnit.h:201
CompileUnit * comp_unit
The CompileUnit for a given query.
size_t AddOSOARanges(SymbolFileDWARF *dwarf2Data, DWARFDebugAranges *debug_aranges)
std::unique_ptr< SymbolFileDWARFDwo > m_dwo_symbol_file
Definition: DWARFUnit.h:174
uint64_t dw_addr_t
Definition: dwarf.h:26
bool FastExtract(const lldb_private::DWARFDataExtractor &debug_info_data, const DWARFUnit *cu, const DWARFFormValue::FixedFormSizes &fixed_form_sizes, lldb::offset_t *offset_ptr)
lldb_private::TypeSystem * GetTypeSystemForLanguage(lldb::LanguageType language) override
dw_offset_t m_base_obj_offset
Definition: DWARFUnit.h:210
const DWARFAbbreviationDeclarationSet * m_abbrevs
Definition: DWARFUnit.h:175
lldb::LanguageType GetLanguageType()
Definition: DWARFUnit.cpp:671
virtual std::unique_ptr< SymbolFileDWARFDwo > GetDwoSymbolFileForCompileUnit(DWARFUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die)
size_t GetAttributeAddressRanges(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, DWARFRangeList &ranges, bool check_hi_lo_pc, bool check_specification_or_abstract_origin=false) const
DWARFProducer
Definition: DWARFUnit.h:26
lldb_private::FileSpec::Style GetPathStyle()
Definition: DWARFUnit.cpp:696
lldb::LanguageType m_language_type
Definition: DWARFUnit.h:203
void SetRangesBase(dw_addr_t ranges_base)
Definition: DWARFUnit.cpp:387
bool DW_AT_decl_file_attributes_are_invalid()
Definition: DWARFUnit.cpp:574
DWARFDIE DIE()
Definition: DWARFUnit.h:124
size_t GetNumRanges() const
const DWARFAbbreviationDeclarationSet * GetAbbreviations() const
Definition: DWARFUnit.cpp:377
uint32_t GetProducerVersionMinor()
Definition: DWARFUnit.cpp:647
SymbolFileDWARFDebugMap * GetDebugMapSymfile()
#define UINT32_MAX
Definition: lldb-defines.h:31
void SetParentIndex(uint32_t idx)
dw_offset_t m_str_offsets_base
Definition: DWARFUnit.h:211
static lldb::LanguageType LanguageTypeFromDWARF(uint64_t val)
Definition: DWARFUnit.cpp:658
#define LLDB_INVALID_ADDRESS
Invalid value definitions.
Definition: lldb-defines.h:85
uint32_t m_producer_version_major
Definition: DWARFUnit.h:200
uint64_t user_id_t
Definition: lldb-types.h:84
bool GetMatchAtIndex(llvm::StringRef s, uint32_t idx, std::string &match_str) const
LanguageType
Programming language type.
ScopedExtractDIEs ExtractDIEsScoped()
Definition: DWARFUnit.cpp:90
virtual ~DWARFUnit()
Definition: DWARFUnit.cpp:35
uint64_t offset_t
Definition: lldb-types.h:87
bool IsEmpty() const
dw_offset_t GetNextCompileUnitOffset() const
Definition: DWARFUnit.cpp:369
uint64_t GetAttributeValueAsUnsigned(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value, bool check_specification_or_abstract_origin=false) const
DWARFDebugInfoEntry::collection m_die_array
Definition: DWARFUnit.h:178
die_iterator_range dies()
Definition: DWARFUnit.h:165
bool Supports_unnamed_objc_bitfields()
Definition: DWARFUnit.cpp:580
void SetBaseObjOffset(dw_offset_t base_obj_offset)
Definition: DWARFUnit.cpp:391
dw_offset_t m_offset
Definition: DWARFUnit.h:213
uint64_t GetAttributeValueAsUnsigned(const dw_attr_t attr, uint64_t fail_value) const
A line table class.
Definition: LineTable.h:37
virtual const lldb_private::DWARFDataExtractor & GetData() const =0
Get the data that contains the DIE information for this unit.
void AppendRange(dw_offset_t cu_offset, dw_addr_t low_pc, dw_addr_t high_pc)
llvm::Optional< lldb_private::FileSpec > m_comp_dir
Definition: DWARFUnit.h:205
dw_offset_t GetAbbrevOffset() const
Definition: DWARFUnit.cpp:381
ScopedExtractDIEs(DWARFUnit *cu)
Definition: DWARFUnit.cpp:110
dw_offset_t GetOffset() const
uint8_t GetAddressByteSize() const
Definition: DWARFUnit.h:100
DWARFDebugInfo * DebugInfo()
LineTable * GetLineTable()
Get the line table for the compile unit.
const lldb_private::FileSpec & GetCompilationDirectory()
Definition: DWARFUnit.cpp:702
dw_offset_t GetOffset() const
Definition: DWARFUnit.h:76
dw_addr_t m_addr_base
Definition: DWARFUnit.h:206
int g_verbose
const Entry & GetEntryRef(size_t i) const
Definition: RangeMap.h:249
llvm::sys::path::Style Style
Definition: FileSpec.h:57
DWARFUnit(SymbolFileDWARF *dwarf, lldb::user_id_t uid)
Definition: DWARFUnit.cpp:32
static lldb_private::FileSpecList GetSymlinkPaths()
void ExtractUnitDIEIfNeeded()
Definition: DWARFUnit.cpp:38
void SetStrOffsetsBase(dw_offset_t str_offsets_base)
Definition: DWARFUnit.cpp:395
static FixedFormSizes GetFixedFormSizesForAddressSize(uint8_t addr_size)
llvm::sys::RWMutex m_die_array_mutex
Definition: DWARFUnit.h:179
const char * GetAttributeValueAsString(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, const dw_attr_t attr, const char *fail_value, bool check_specification_or_abstract_origin=false) const
DWARFUnit * GetCompileUnit()
std::atomic< bool > m_cancel_scopes
Definition: DWARFUnit.h:184
bool GetIsOptimized()
Definition: DWARFUnit.cpp:682
void BuildAddressRangeTable(SymbolFileDWARF *dwarf, DWARFDebugAranges *debug_aranges)
Definition: DWARFUnit.cpp:408
void SetBaseAddress(dw_addr_t base_addr)
Definition: DWARFUnit.cpp:516
bool Supports_DW_AT_APPLE_objc_complete_type()
Definition: DWARFUnit.cpp:570
llvm::sys::RWMutex m_die_array_scoped_mutex
Definition: DWARFUnit.h:181
void BuildFunctionAddressRangeTable(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const
Unknown or invalid language value.
DWARFDIE GetDIEForDIEOffset(dw_offset_t die_offset)
bool Execute(llvm::StringRef string, Match *match=nullptr) const
Executes a regular expression.
static llvm::StringRef removeHostnameFromPathname(llvm::StringRef path_from_dwarf)
Definition: DWARFUnit.cpp:711
SymbolFileDWARF * GetSymbolFileDWARF() const
Definition: DWARFUnit.cpp:590
uint32_t GetProducerVersionMajor()
Definition: DWARFUnit.cpp:641
void * GetUserData() const
Definition: DWARFUnit.cpp:562
Definition: SBAddress.h:15
virtual uint32_t GetHeaderByteSize() const =0
Get the size in bytes of the compile unit header.
std::unique_ptr< DWARFDebugAranges > m_func_aranges_up
Definition: DWARFUnit.h:192
bool IsValid() const
Definition: DWARFBaseDIE.h:43
uint32_t ToUInt32(const char *s, uint32_t fail_value=0, int base=0, bool *success_ptr=nullptr)
void ExtractDIEsIfNeeded()
Definition: DWARFUnit.cpp:70
ObjectFile * GetObjectFile()
Definition: SymbolFile.h:213
DWARFFormValue::FixedFormSizes GetFixedFormSizes()
Definition: DWARFUnit.cpp:512
#define DW_INVALID_OFFSET
Definition: dwarf.h:34
size_t GetDebugInfoSize() const
Definition: DWARFUnit.cpp:373
lldb::ByteOrder GetByteOrder() const
Definition: DWARFUnit.cpp:501
BaseType GetRangeEnd() const
Definition: RangeMap.h:62
DWARFDebugInfoEntry m_first_die
Definition: DWARFUnit.h:188
dw_offset_t GetBaseObjOffset() const
Definition: DWARFUnit.cpp:771
static bool CompareDIEOffset(const DWARFDebugInfoEntry &die, const dw_offset_t die_offset)
Definition: DWARFUnit.cpp:519
SymbolFileDWARF * m_dwarf
Definition: DWARFUnit.h:173
void SetAddrBase(dw_addr_t addr_base)
Definition: DWARFUnit.cpp:385
DWARFProducer m_producer
Definition: DWARFUnit.h:199
size_t GetLengthByteSize() const
Get the size in bytes of the length field in the header.
Definition: DWARFUnit.h:83
uint64_t GetAttributeValueAsAddress(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value, bool check_specification_or_abstract_origin=false) const
DWARFProducer GetProducer()
Definition: DWARFUnit.cpp:635
uint32_t GetLength() const
Definition: DWARFUnit.h:96
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:376
SymbolFileDWARFDwo * GetDwoSymbolFile() const
Definition: DWARFUnit.cpp:767
dw_addr_t m_base_addr
Definition: DWARFUnit.h:193
const DWARFDebugAranges & GetFunctionAranges()
Definition: DWARFUnit.cpp:773
static FileSpec resolveCompDir(const FileSpec &path)
Definition: DWARFUnit.cpp:726
uint16_t GetU16(lldb::offset_t *offset_ptr) const
Extract a uint16_t value from *offset_ptr.
size_t GetContiguousFileAddressRanges(FileAddressRanges &file_ranges, bool append)
Gets all contiguous file address ranges for the entire line table.
Definition: LineTable.cpp:416
lldb_private::TypeSystem * GetTypeSystem()
Definition: DWARFUnit.cpp:505
dw_addr_t m_ranges_base
Definition: DWARFUnit.h:207
lldb_private::CompileUnit * GetCompUnitForDWARFCompUnit(DWARFUnit *dwarf_cu, uint32_t cu_idx=UINT32_MAX)
llvm::sys::RWMutex m_first_die_mutex
Definition: DWARFUnit.h:189
collection::const_iterator const_iterator
void BuildAddressRangeTable(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const
DWARFDIE LookupAddress(const dw_addr_t address)
Definition: DWARFUnit.cpp:340
dw_offset_t GetFirstDIEOffset() const
Definition: DWARFUnit.h:89
uint64_t GetU64(lldb::offset_t *offset_ptr) const
Extract a uint64_t value from *offset_ptr.
BaseType GetRangeBase() const
Definition: RangeMap.h:46
virtual lldb::ByteOrder GetByteOrder() const =0
Gets whether endian swapping should occur when extracting data from this object file.
uint32_t GetProducerVersionUpdate()
Definition: DWARFUnit.cpp:653