@@ -61,53 +61,50 @@ DebugNamesDWARFIndex::GetUnits(const DebugNames &debug_names) {
61
61
return result;
62
62
}
63
63
64
- bool
65
- DebugNamesDWARFIndex::IsForeignTypeUnit (const DebugNames::Entry &entry,
66
- DWARFTypeUnit *&foreign_tu) const {
67
- foreign_tu = nullptr ;
64
+ std::optional<DWARFTypeUnit *>
65
+ DebugNamesDWARFIndex::IsForeignTypeUnit (const DebugNames::Entry &entry) const {
68
66
std::optional<uint64_t > type_sig = entry.getForeignTUTypeSignature ();
69
67
if (!type_sig.has_value ())
70
- return false ;
68
+ return std::nullopt ;
71
69
auto dwp_sp = m_debug_info.GetDwpSymbolFile ();
72
- if (dwp_sp) {
73
- // We have a .dwp file, just get the type unit from there.
74
- foreign_tu = dwp_sp->DebugInfo ().GetTypeUnitForHash (*type_sig);
75
- } else {
76
- // We have a .dwo file that contains the type unit.
77
- foreign_tu = nullptr ; // TODO: fixme before checkin
70
+ if (!dwp_sp) {
71
+ // No .dwp file, we need to load the .dwo file.
72
+
73
+ // Ask the entry for the skeleton compile unit offset and fetch the .dwo
74
+ // file from it and get the type unit by signature from there. If we find
75
+ // the type unit in the .dwo file, we don't need to check that the
76
+ // DW_AT_dwo_name matches because each .dwo file can have its own type unit.
77
+ std::optional<uint64_t > unit_offset = entry.getForeignTUSkeletonCUOffset ();
78
+ if (!unit_offset)
79
+ return nullptr ; // Return NULL, this is a type unit, but couldn't find it.
80
+ DWARFUnit *cu = m_debug_info.GetUnitAtOffset (DIERef::Section::DebugInfo,
81
+ *unit_offset);
82
+ if (!cu)
83
+ return nullptr ; // Return NULL, this is a type unit, but couldn't find it.
84
+ DWARFUnit &dwo_cu = cu->GetNonSkeletonUnit ();
85
+ // We don't need the check if the type unit matches the .dwo file if we have
86
+ // a .dwo file (not a .dwp), so we can just return the value here.
87
+ if (!dwo_cu.IsDWOUnit ())
88
+ return nullptr ; // We weren't able to load the .dwo file.
89
+ return dwo_cu.GetSymbolFileDWARF ().DebugInfo ().GetTypeUnitForHash (*type_sig);
78
90
}
79
- if (foreign_tu == nullptr )
80
- return true ;
81
- // If this entry represents a foreign type unit, we need to verify that
82
- // the type unit that ended up in the final .dwp file is the right type
83
- // unit. Type units have signatures which are the same across multiple
84
- // .dwo files, but only one of those type units will end up in the .dwp
85
- // file. The contents of type units for the same type can be different
86
- // in different .dwo file, which means the DIE offsets might not be the
87
- // same between two different type units. So we need to determine if this
88
- // accelerator table matches the type unit in the .dwp file. If it doesn't
89
- // match, then we need to ignore this accelerator table entry as the type
90
- // unit that is in the .dwp file will have its own index.
91
- // In order to determine if the type unit that ended up in a .dwp file
92
- // matches this DebugNames::Entry, we need to find the skeleton compile
93
- // unit for this entry. We rely on each DebugNames::Entry either having
94
- // both a DW_IDX_type_unit and a DW_IDX_compile_unit, or the .debug_names
95
- // table has only a single compile unit with multiple type units. Once
96
- // we find the skeleton compile unit, we make sure the DW_AT_dwo_name
97
- // attributes match.
98
- const llvm::DWARFDebugNames::NameIndex *name_index = entry.getNameIndex ();
99
- assert (name_index);
100
- // Ask the entry for the skeleton compile unit offset.
91
+ // We have a .dwp file, just get the type unit from there. We need to verify
92
+ // that the type unit that ended up in the final .dwp file is the right type
93
+ // unit. Type units have signatures which are the same across multiple .dwo
94
+ // files, but only one of those type units will end up in the .dwp file. The
95
+ // contents of type units for the same type can be different in different .dwo
96
+ // files, which means the DIE offsets might not be the same between two
97
+ // different type units. So we need to determine if this accelerator table
98
+ // matches the type unit that ended up in the .dwp file. If it doesn't match,
99
+ // then we need to ignore this accelerator table entry as the type unit that
100
+ // is in the .dwp file will have its own index. In order to determine if the
101
+ // type unit that ended up in a .dwp file matches this DebugNames::Entry, we
102
+ // need to find the skeleton compile unit for this entry.
103
+ DWARFTypeUnit *foreign_tu = dwp_sp->DebugInfo ().GetTypeUnitForHash (*type_sig);
104
+ if (!foreign_tu)
105
+ return nullptr ; // Return NULL, this is a type unit, but couldn't find it.
106
+
101
107
std::optional<uint64_t > cu_offset = entry.getForeignTUSkeletonCUOffset ();
102
- // If the entry doesn't specify the skeleton compile unit offset, then check
103
- // if the .debug_names table only has one compile unit. If so, then this is
104
- // the skeleton compile unit we should used.
105
- if (!cu_offset && name_index->getCUCount () == 1 )
106
- cu_offset = name_index->getCUOffset (0 );
107
-
108
- // If we couldn't find the skeleton compile unit offset, be safe and say there
109
- // is no match. We don't want to use an invalid DIE offset on the wrong type
110
- // unit.
111
108
if (cu_offset) {
112
109
DWARFUnit *cu = m_debug_info.GetUnitAtOffset (DIERef::DebugInfo, *cu_offset);
113
110
if (cu) {
@@ -117,27 +114,30 @@ DebugNamesDWARFIndex::IsForeignTypeUnit(const DebugNames::Entry &entry,
117
114
cu_die.GetAttributeValueAsString (DW_AT_dwo_name, nullptr );
118
115
llvm::StringRef tu_dwo_name =
119
116
tu_die.GetAttributeValueAsString (DW_AT_dwo_name, nullptr );
120
- if (cu_dwo_name != tu_dwo_name)
121
- foreign_tu = nullptr ; // Ignore this entry, the DWO name doesn't match.
122
- } else {
123
- foreign_tu = nullptr ; // Ignore this entry, we can find the skeleton CU
117
+ if (cu_dwo_name == tu_dwo_name)
118
+ return foreign_tu; // We found a match!
124
119
}
125
- } else {
126
- foreign_tu = nullptr ; // Ignore this entry, we can find the skeleton CU
127
120
}
128
- return true ;
121
+ return nullptr ; // Return NULL, this is a type unit, but couldn't find it.
129
122
}
130
123
131
124
DWARFUnit *
132
125
DebugNamesDWARFIndex::GetNonSkeletonUnit (const DebugNames::Entry &entry) const {
126
+
127
+ if (std::optional<DWARFTypeUnit *> foreign_tu = IsForeignTypeUnit (entry))
128
+ return foreign_tu.value ();
129
+
133
130
// Look for a DWARF unit offset (CU offset or local TU offset) as they are
134
131
// both offsets into the .debug_info section.
135
132
std::optional<uint64_t > unit_offset = entry.getCUOffset ();
136
133
if (!unit_offset)
137
134
unit_offset = entry.getLocalTUOffset ();
138
- DWARFUnit *cu =
139
- m_debug_info.GetUnitAtOffset (DIERef::Section::DebugInfo, *unit_offset);
140
- return cu ? &cu->GetNonSkeletonUnit () : nullptr ;
135
+ if (unit_offset) {
136
+ if (DWARFUnit *cu =
137
+ m_debug_info.GetUnitAtOffset (DIERef::Section::DebugInfo, *unit_offset))
138
+ return &cu->GetNonSkeletonUnit ();
139
+ }
140
+ return nullptr ;
141
141
}
142
142
143
143
DWARFDIE DebugNamesDWARFIndex::GetDIE (const DebugNames::Entry &entry) const {
@@ -349,14 +349,13 @@ void DebugNamesDWARFIndex::GetFullyQualifiedType(
349
349
if (!isType (entry.tag ()))
350
350
continue ;
351
351
352
-
353
- DWARFTypeUnit *foreign_tu = nullptr ;
354
- if (IsForeignTypeUnit (entry, foreign_tu)) {
355
- // If we get a NULL foreign_tu back, the entry doesn't match the type unit
356
- // in the .dwp file.
357
- if (!foreign_tu)
352
+ // If we get a NULL foreign_tu back, the entry doesn't match the type unit
353
+ // in the .dwp file, or we were not able to load the .dwo file or the DWO ID
354
+ // didn't match.
355
+ std::optional<DWARFTypeUnit *> foreign_tu = IsForeignTypeUnit (entry);
356
+ if (foreign_tu && foreign_tu.value () == nullptr )
358
357
continue ;
359
- }
358
+
360
359
// Grab at most one extra parent, subsequent parents are not necessary to
361
360
// test equality.
362
361
std::optional<llvm::SmallVector<Entry, 4 >> parent_chain =
0 commit comments