@@ -35,12 +35,12 @@ DWARFUnit::DWARFUnit(SymbolFileDWARF &dwarf, lldb::user_id_t uid,
35
35
DIERef::Section section, bool is_dwo)
36
36
: UserID(uid), m_dwarf(dwarf), m_header(header), m_abbrevs(&abbrevs),
37
37
m_cancel_scopes(false ), m_section(section), m_is_dwo(is_dwo),
38
- m_dwo_id(header.GetDWOId()) {}
38
+ m_has_parsed_non_skeleton_unit( false ), m_dwo_id(header.GetDWOId()) {}
39
39
40
40
DWARFUnit::~DWARFUnit () = default ;
41
41
42
- // Parses first DIE of a compile unit.
43
- void DWARFUnit::ExtractUnitDIEIfNeeded () {
42
+ // Parses first DIE of a compile unit, excluding DWO .
43
+ void DWARFUnit::ExtractUnitDIENoDwoIfNeeded () {
44
44
{
45
45
llvm::sys::ScopedReader lock (m_first_die_mutex);
46
46
if (m_first_die)
@@ -50,7 +50,8 @@ void DWARFUnit::ExtractUnitDIEIfNeeded() {
50
50
if (m_first_die)
51
51
return ; // Already parsed
52
52
53
- LLDB_SCOPED_TIMERF (" %8.8x: DWARFUnit::ExtractUnitDIEIfNeeded()" , GetOffset ());
53
+ LLDB_SCOPED_TIMERF (" %8.8x: DWARFUnit::ExtractUnitDIENoDwoIfNeeded()" ,
54
+ GetOffset ());
54
55
55
56
// Set the offset to that of the first DIE and calculate the start of the
56
57
// next compilation unit header.
@@ -66,6 +67,58 @@ void DWARFUnit::ExtractUnitDIEIfNeeded() {
66
67
}
67
68
}
68
69
70
+ // Parses first DIE of a compile unit including DWO.
71
+ void DWARFUnit::ExtractUnitDIEIfNeeded () {
72
+ ExtractUnitDIENoDwoIfNeeded ();
73
+
74
+ if (m_has_parsed_non_skeleton_unit)
75
+ return ;
76
+
77
+ m_has_parsed_non_skeleton_unit = true ;
78
+
79
+ std::shared_ptr<SymbolFileDWARFDwo> dwo_symbol_file =
80
+ m_dwarf.GetDwoSymbolFileForCompileUnit (*this , m_first_die);
81
+ if (!dwo_symbol_file)
82
+ return ;
83
+
84
+ DWARFUnit *dwo_cu = dwo_symbol_file->GetDWOCompileUnitForHash (m_dwo_id);
85
+
86
+ if (!dwo_cu)
87
+ return ; // Can't fetch the compile unit from the dwo file.
88
+ dwo_cu->SetUserData (this );
89
+
90
+ DWARFBaseDIE dwo_cu_die = dwo_cu->GetUnitDIEOnly ();
91
+ if (!dwo_cu_die.IsValid ())
92
+ return ; // Can't fetch the compile unit DIE from the dwo file.
93
+
94
+ // Here for DWO CU we want to use the address base set in the skeleton unit
95
+ // (DW_AT_addr_base) if it is available and use the DW_AT_GNU_addr_base
96
+ // otherwise. We do that because pre-DWARF v5 could use the DW_AT_GNU_*
97
+ // attributes which were applicable to the DWO units. The corresponding
98
+ // DW_AT_* attributes standardized in DWARF v5 are also applicable to the
99
+ // main unit in contrast.
100
+ if (m_addr_base)
101
+ dwo_cu->SetAddrBase (*m_addr_base);
102
+ else if (m_gnu_addr_base)
103
+ dwo_cu->SetAddrBase (*m_gnu_addr_base);
104
+
105
+ if (GetVersion () <= 4 && m_gnu_ranges_base)
106
+ dwo_cu->SetRangesBase (*m_gnu_ranges_base);
107
+ else if (dwo_symbol_file->GetDWARFContext ()
108
+ .getOrLoadRngListsData ()
109
+ .GetByteSize () > 0 )
110
+ dwo_cu->SetRangesBase (llvm::DWARFListTableHeader::getHeaderSize (DWARF32));
111
+
112
+ if (GetVersion () >= 5 &&
113
+ dwo_symbol_file->GetDWARFContext ().getOrLoadLocListsData ().GetByteSize () >
114
+ 0 )
115
+ dwo_cu->SetLoclistsBase (llvm::DWARFListTableHeader::getHeaderSize (DWARF32));
116
+
117
+ dwo_cu->SetBaseAddress (GetBaseAddress ());
118
+
119
+ m_dwo = std::shared_ptr<DWARFUnit>(std::move (dwo_symbol_file), dwo_cu);
120
+ }
121
+
69
122
// Parses a compile unit and indexes its DIEs if it hasn't already been done.
70
123
// It will leave this compile unit extracted forever.
71
124
void DWARFUnit::ExtractDIEsIfNeeded () {
@@ -291,14 +344,12 @@ void DWARFUnit::SetDwoStrOffsetsBase() {
291
344
}
292
345
293
346
uint64_t DWARFUnit::GetDWOId () {
294
- ExtractUnitDIEIfNeeded ();
347
+ ExtractUnitDIENoDwoIfNeeded ();
295
348
return m_dwo_id;
296
349
}
297
350
298
351
// m_die_array_mutex must be already held as read/write.
299
352
void DWARFUnit::AddUnitDIE (const DWARFDebugInfoEntry &cu_die) {
300
- llvm::Optional<uint64_t > addr_base, gnu_addr_base, gnu_ranges_base;
301
-
302
353
DWARFAttributes attributes;
303
354
size_t num_attributes = cu_die.GetAttributes (this , attributes);
304
355
@@ -308,8 +359,7 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
308
359
continue ;
309
360
DWARFFormValue form_value;
310
361
if (attributes.ExtractFormValueAtIndex (i, form_value)) {
311
- addr_base = form_value.Unsigned ();
312
- SetAddrBase (*addr_base);
362
+ SetAddrBase (form_value.Unsigned ());
313
363
break ;
314
364
}
315
365
}
@@ -341,10 +391,10 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
341
391
m_line_table_offset = form_value.Unsigned ();
342
392
break ;
343
393
case DW_AT_GNU_addr_base:
344
- gnu_addr_base = form_value.Unsigned ();
394
+ m_gnu_addr_base = form_value.Unsigned ();
345
395
break ;
346
396
case DW_AT_GNU_ranges_base:
347
- gnu_ranges_base = form_value.Unsigned ();
397
+ m_gnu_ranges_base = form_value.Unsigned ();
348
398
break ;
349
399
case DW_AT_GNU_dwo_id:
350
400
m_dwo_id = form_value.Unsigned ();
@@ -353,50 +403,10 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
353
403
}
354
404
355
405
if (m_is_dwo) {
406
+ m_has_parsed_non_skeleton_unit = true ;
356
407
SetDwoStrOffsetsBase ();
357
408
return ;
358
409
}
359
-
360
- std::shared_ptr<SymbolFileDWARFDwo> dwo_symbol_file =
361
- m_dwarf.GetDwoSymbolFileForCompileUnit (*this , cu_die);
362
- if (!dwo_symbol_file)
363
- return ;
364
-
365
- DWARFUnit *dwo_cu = dwo_symbol_file->GetDWOCompileUnitForHash (m_dwo_id);
366
-
367
- if (!dwo_cu)
368
- return ; // Can't fetch the compile unit from the dwo file.
369
- dwo_cu->SetUserData (this );
370
-
371
- DWARFBaseDIE dwo_cu_die = dwo_cu->GetUnitDIEOnly ();
372
- if (!dwo_cu_die.IsValid ())
373
- return ; // Can't fetch the compile unit DIE from the dwo file.
374
-
375
- // Here for DWO CU we want to use the address base set in the skeleton unit
376
- // (DW_AT_addr_base) if it is available and use the DW_AT_GNU_addr_base
377
- // otherwise. We do that because pre-DWARF v5 could use the DW_AT_GNU_*
378
- // attributes which were applicable to the DWO units. The corresponding
379
- // DW_AT_* attributes standardized in DWARF v5 are also applicable to the main
380
- // unit in contrast.
381
- if (addr_base)
382
- dwo_cu->SetAddrBase (*addr_base);
383
- else if (gnu_addr_base)
384
- dwo_cu->SetAddrBase (*gnu_addr_base);
385
-
386
- if (GetVersion () <= 4 && gnu_ranges_base)
387
- dwo_cu->SetRangesBase (*gnu_ranges_base);
388
- else if (dwo_symbol_file->GetDWARFContext ()
389
- .getOrLoadRngListsData ()
390
- .GetByteSize () > 0 )
391
- dwo_cu->SetRangesBase (llvm::DWARFListTableHeader::getHeaderSize (DWARF32));
392
-
393
- if (GetVersion () >= 5 &&
394
- dwo_symbol_file->GetDWARFContext ().getOrLoadLocListsData ().GetByteSize () >
395
- 0 )
396
- dwo_cu->SetLoclistsBase (llvm::DWARFListTableHeader::getHeaderSize (DWARF32));
397
- dwo_cu->SetBaseAddress (GetBaseAddress ());
398
-
399
- m_dwo = std::shared_ptr<DWARFUnit>(std::move (dwo_symbol_file), dwo_cu);
400
410
}
401
411
402
412
size_t DWARFUnit::GetDebugInfoSize () const {
@@ -412,7 +422,7 @@ dw_offset_t DWARFUnit::GetAbbrevOffset() const {
412
422
}
413
423
414
424
dw_offset_t DWARFUnit::GetLineTableOffset () {
415
- ExtractUnitDIEIfNeeded ();
425
+ ExtractUnitDIENoDwoIfNeeded ();
416
426
return m_line_table_offset;
417
427
}
418
428
0 commit comments