@@ -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_has_parsed_non_skeleton_unit( false ), m_dwo_id(header.GetDWOId()) {}
38
+ m_dwo_id(header.GetDWOId()) {}
39
39
40
40
DWARFUnit::~DWARFUnit () = default ;
41
41
42
- // Parses first DIE of a compile unit, excluding DWO .
43
- void DWARFUnit::ExtractUnitDIENoDwoIfNeeded () {
42
+ // Parses first DIE of a compile unit.
43
+ void DWARFUnit::ExtractUnitDIEIfNeeded () {
44
44
{
45
45
llvm::sys::ScopedReader lock (m_first_die_mutex);
46
46
if (m_first_die)
@@ -50,8 +50,7 @@ void DWARFUnit::ExtractUnitDIENoDwoIfNeeded() {
50
50
if (m_first_die)
51
51
return ; // Already parsed
52
52
53
- LLDB_SCOPED_TIMERF (" %8.8x: DWARFUnit::ExtractUnitDIENoDwoIfNeeded()" ,
54
- GetOffset ());
53
+ LLDB_SCOPED_TIMERF (" %8.8x: DWARFUnit::ExtractUnitDIEIfNeeded()" , GetOffset ());
55
54
56
55
// Set the offset to that of the first DIE and calculate the start of the
57
56
// next compilation unit header.
@@ -67,58 +66,6 @@ void DWARFUnit::ExtractUnitDIENoDwoIfNeeded() {
67
66
}
68
67
}
69
68
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
-
122
69
// Parses a compile unit and indexes its DIEs if it hasn't already been done.
123
70
// It will leave this compile unit extracted forever.
124
71
void DWARFUnit::ExtractDIEsIfNeeded () {
@@ -344,12 +291,14 @@ void DWARFUnit::SetDwoStrOffsetsBase() {
344
291
}
345
292
346
293
uint64_t DWARFUnit::GetDWOId () {
347
- ExtractUnitDIENoDwoIfNeeded ();
294
+ ExtractUnitDIEIfNeeded ();
348
295
return m_dwo_id;
349
296
}
350
297
351
298
// m_die_array_mutex must be already held as read/write.
352
299
void DWARFUnit::AddUnitDIE (const DWARFDebugInfoEntry &cu_die) {
300
+ llvm::Optional<uint64_t > addr_base, gnu_addr_base, gnu_ranges_base;
301
+
353
302
DWARFAttributes attributes;
354
303
size_t num_attributes = cu_die.GetAttributes (this , attributes);
355
304
@@ -359,7 +308,8 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
359
308
continue ;
360
309
DWARFFormValue form_value;
361
310
if (attributes.ExtractFormValueAtIndex (i, form_value)) {
362
- SetAddrBase (form_value.Unsigned ());
311
+ addr_base = form_value.Unsigned ();
312
+ SetAddrBase (*addr_base);
363
313
break ;
364
314
}
365
315
}
@@ -391,10 +341,10 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
391
341
m_line_table_offset = form_value.Unsigned ();
392
342
break ;
393
343
case DW_AT_GNU_addr_base:
394
- m_gnu_addr_base = form_value.Unsigned ();
344
+ gnu_addr_base = form_value.Unsigned ();
395
345
break ;
396
346
case DW_AT_GNU_ranges_base:
397
- m_gnu_ranges_base = form_value.Unsigned ();
347
+ gnu_ranges_base = form_value.Unsigned ();
398
348
break ;
399
349
case DW_AT_GNU_dwo_id:
400
350
m_dwo_id = form_value.Unsigned ();
@@ -403,10 +353,50 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
403
353
}
404
354
405
355
if (m_is_dwo) {
406
- m_has_parsed_non_skeleton_unit = true ;
407
356
SetDwoStrOffsetsBase ();
408
357
return ;
409
358
}
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);
410
400
}
411
401
412
402
size_t DWARFUnit::GetDebugInfoSize () const {
@@ -422,7 +412,7 @@ dw_offset_t DWARFUnit::GetAbbrevOffset() const {
422
412
}
423
413
424
414
dw_offset_t DWARFUnit::GetLineTableOffset () {
425
- ExtractUnitDIENoDwoIfNeeded ();
415
+ ExtractUnitDIEIfNeeded ();
426
416
return m_line_table_offset;
427
417
}
428
418
0 commit comments