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