@@ -77,7 +77,8 @@ void GDBIndex::updateGdbIndexSection(
77
77
exit (1 );
78
78
}
79
79
DenseSet<uint64_t > OriginalOffsets;
80
- for (unsigned Index = 0 , Units = BC.DwCtx ->getNumCompileUnits ();
80
+ for (unsigned Index = 0 , PresentUnitsIndex = 0 ,
81
+ Units = BC.DwCtx ->getNumCompileUnits ();
81
82
Index < Units; ++Index) {
82
83
const DWARFUnit *CU = BC.DwCtx ->getUnitAtIndex (Index);
83
84
if (SkipTypeUnits && CU->isTypeUnit ())
@@ -90,7 +91,7 @@ void GDBIndex::updateGdbIndexSection(
90
91
}
91
92
92
93
OriginalOffsets.insert (Offset);
93
- OffsetToIndexMap[Offset] = Index ;
94
+ OffsetToIndexMap[Offset] = PresentUnitsIndex++ ;
94
95
}
95
96
96
97
// Ignore old address table.
@@ -125,16 +126,52 @@ void GDBIndex::updateGdbIndexSection(
125
126
126
127
using MapEntry = std::pair<uint32_t , CUInfo>;
127
128
std::vector<MapEntry> CUVector (CUMap.begin (), CUMap.end ());
129
+ // Remove the CUs we won't emit anyway.
130
+ CUVector.erase (std::remove_if (CUVector.begin (), CUVector.end (),
131
+ [&OriginalOffsets](const MapEntry &It) {
132
+ // Skipping TU for DWARF5 when they are not
133
+ // included in CU list.
134
+ return OriginalOffsets.count (It.first ) == 0 ;
135
+ }),
136
+ CUVector.end ());
128
137
// Need to sort since we write out all of TUs in .debug_info before CUs.
129
138
std::sort (CUVector.begin (), CUVector.end (),
130
139
[](const MapEntry &E1 , const MapEntry &E2 ) -> bool {
131
140
return E1 .second .Offset < E2 .second .Offset ;
132
141
});
142
+ // Create the original CU index -> updated CU index mapping,
143
+ // as the sort above could've changed the order and we have to update
144
+ // indices correspondingly in address map and constant pool.
145
+ std::unordered_map<uint32_t , uint32_t > OriginalCUIndexToUpdatedCUIndexMap;
146
+ OriginalCUIndexToUpdatedCUIndexMap.reserve (CUVector.size ());
147
+ for (uint32_t I = 0 ; I < CUVector.size (); ++I) {
148
+ OriginalCUIndexToUpdatedCUIndexMap[OffsetToIndexMap.at (CUVector[I].first )] =
149
+ I;
150
+ }
151
+ const auto RemapCUIndex = [&OriginalCUIndexToUpdatedCUIndexMap,
152
+ CUVectorSize = CUVector.size (),
153
+ TUVectorSize = getGDBIndexTUEntryVector ().size ()](
154
+ uint32_t OriginalIndex) {
155
+ if (OriginalIndex >= CUVectorSize) {
156
+ if (OriginalIndex >= CUVectorSize + TUVectorSize) {
157
+ errs () << " BOLT-ERROR: .gdb_index unknown CU index\n " ;
158
+ exit (1 );
159
+ }
160
+ // The index is into TU CU List, which we don't reorder, so return as is.
161
+ return OriginalIndex;
162
+ }
163
+
164
+ const auto It = OriginalCUIndexToUpdatedCUIndexMap.find (OriginalIndex);
165
+ if (It == OriginalCUIndexToUpdatedCUIndexMap.end ()) {
166
+ errs () << " BOLT-ERROR: .gdb_index unknown CU index\n " ;
167
+ exit (1 );
168
+ }
169
+
170
+ return It->second ;
171
+ };
172
+
133
173
// Writing out CU List <Offset, Size>
134
174
for (auto &CUInfo : CUVector) {
135
- // Skipping TU for DWARF5 when they are not included in CU list.
136
- if (!OriginalOffsets.count (CUInfo.first ))
137
- continue ;
138
175
write64le (Buffer, CUInfo.second .Offset );
139
176
// Length encoded in CU doesn't contain first 4 bytes that encode length.
140
177
write64le (Buffer + 8 , CUInfo.second .Length + 4 );
@@ -160,12 +197,13 @@ void GDBIndex::updateGdbIndexSection(
160
197
// Generate new address table.
161
198
for (const std::pair<const uint64_t , DebugAddressRangesVector> &CURangesPair :
162
199
ARangesSectionWriter.getCUAddressRanges ()) {
163
- const uint32_t CUIndex = OffsetToIndexMap[CURangesPair.first ];
200
+ const uint32_t OriginalCUIndex = OffsetToIndexMap[CURangesPair.first ];
201
+ const uint32_t UpdatedCUIndex = RemapCUIndex (OriginalCUIndex);
164
202
const DebugAddressRangesVector &Ranges = CURangesPair.second ;
165
203
for (const DebugAddressRange &Range : Ranges) {
166
204
write64le (Buffer, Range.LowPC );
167
205
write64le (Buffer + 8 , Range.HighPC );
168
- write32le (Buffer + 16 , CUIndex );
206
+ write32le (Buffer + 16 , UpdatedCUIndex );
169
207
Buffer += 20 ;
170
208
}
171
209
}
@@ -178,6 +216,56 @@ void GDBIndex::updateGdbIndexSection(
178
216
// Copy over the rest of the original data.
179
217
memcpy (Buffer, Data, TrailingSize);
180
218
219
+ // Fixup CU-indices in constant pool.
220
+ const char *const OriginalConstantPoolData =
221
+ GdbIndexContents.data () + ConstantPoolOffset;
222
+ uint8_t *const UpdatedConstantPoolData =
223
+ NewGdbIndexContents + ConstantPoolOffset + Delta;
224
+
225
+ const char *OriginalSymbolTableData =
226
+ GdbIndexContents.data () + SymbolTableOffset;
227
+ std::set<uint32_t > CUVectorOffsets;
228
+ // Parse the symbol map and extract constant pool CU offsets from it.
229
+ while (OriginalSymbolTableData < OriginalConstantPoolData) {
230
+ const uint32_t NameOffset = read32le (OriginalSymbolTableData);
231
+ const uint32_t CUVectorOffset = read32le (OriginalSymbolTableData + 4 );
232
+ OriginalSymbolTableData += 8 ;
233
+
234
+ // Iff both are zero, then the slot is considered empty in the hash-map.
235
+ if (NameOffset || CUVectorOffset) {
236
+ CUVectorOffsets.insert (CUVectorOffset);
237
+ }
238
+ }
239
+
240
+ // Update the CU-indicies in the constant pool
241
+ for (const auto CUVectorOffset : CUVectorOffsets) {
242
+ const char *CurrentOriginalConstantPoolData =
243
+ OriginalConstantPoolData + CUVectorOffset;
244
+ uint8_t *CurrentUpdatedConstantPoolData =
245
+ UpdatedConstantPoolData + CUVectorOffset;
246
+
247
+ const uint32_t Num = read32le (CurrentOriginalConstantPoolData);
248
+ CurrentOriginalConstantPoolData += 4 ;
249
+ CurrentUpdatedConstantPoolData += 4 ;
250
+
251
+ for (uint32_t J = 0 ; J < Num; ++J) {
252
+ const uint32_t OriginalCUIndexAndAttributes =
253
+ read32le (CurrentOriginalConstantPoolData);
254
+ CurrentOriginalConstantPoolData += 4 ;
255
+
256
+ // We only care for the index, which is the lowest 24 bits, other bits are
257
+ // left as is.
258
+ const uint32_t OriginalCUIndex =
259
+ OriginalCUIndexAndAttributes & ((1 << 24 ) - 1 );
260
+ const uint32_t Attributes = OriginalCUIndexAndAttributes >> 24 ;
261
+ const uint32_t UpdatedCUIndexAndAttributes =
262
+ RemapCUIndex (OriginalCUIndex) | (Attributes << 24 );
263
+
264
+ write32le (CurrentUpdatedConstantPoolData, UpdatedCUIndexAndAttributes);
265
+ CurrentUpdatedConstantPoolData += 4 ;
266
+ }
267
+ }
268
+
181
269
// Register the new section.
182
270
BC.registerOrUpdateNoteSection (" .gdb_index" , NewGdbIndexContents,
183
271
NewGdbIndexSize);
0 commit comments