@@ -155,7 +155,7 @@ class DebugRangesSectionWriter {
155
155
uint64_t getSectionOffset ();
156
156
157
157
// / Returns a buffer containing Ranges.
158
- virtual std::unique_ptr<DebugBufferVector> finalize () {
158
+ virtual std::unique_ptr<DebugBufferVector> releaseBuffer () {
159
159
return std::move (RangesBuffer);
160
160
}
161
161
@@ -165,6 +165,12 @@ class DebugRangesSectionWriter {
165
165
return Writer->getKind () == RangesWriterKind::DebugRangesWriter;
166
166
}
167
167
168
+ // / Writes out range lists for a current CU being processed.
169
+ void virtual finalizeSection (){};
170
+
171
+ // / Needs to be invoked before each \p CU is processed.
172
+ void virtual initSection (DWARFUnit &CU){};
173
+
168
174
protected:
169
175
std::unique_ptr<DebugBufferVector> RangesBuffer;
170
176
@@ -203,25 +209,27 @@ class DebugRangeListsSectionWriter : public DebugRangesSectionWriter {
203
209
// / Add ranges and return offset into section.
204
210
virtual uint64_t addRanges (const DebugAddressRangesVector &Ranges) override ;
205
211
206
- virtual std::unique_ptr<DebugBufferVector> finalize () override {
212
+ virtual std::unique_ptr<DebugBufferVector> releaseBuffer () override {
207
213
return std::move (RangesBuffer);
208
214
}
209
215
210
- // / Needs to be invoked before each CU is processed.
211
- // / \p CUID is a unique ID of each CU.
212
- void initSection (uint64_t CUID);
216
+ // / Needs to be invoked before each \p CU is processed.
217
+ void virtual initSection (DWARFUnit &CU) override ;
213
218
214
219
// / Writes out range lists for a current CU being processed.
215
- void finalizeSection ();
220
+ void virtual finalizeSection () override ;
221
+
222
+ // Returns true if section is empty.
223
+ bool empty () { return RangesBuffer->empty (); }
216
224
217
225
static bool classof (const DebugRangesSectionWriter *Writer) {
218
226
return Writer->getKind () == RangesWriterKind::DebugRangeListsWriter;
219
227
}
220
228
221
229
private:
222
230
static DebugAddrWriter *AddrWriter;
223
- // / Unique ID of CU being processed .
224
- uint64_t CUID{ 0 } ;
231
+ // / Used to find unique CU ID .
232
+ DWARFUnit *CU ;
225
233
// / Current relative offset of range list entry within this CUs rangelist
226
234
// / body.
227
235
uint32_t CurrentOffset{0 };
@@ -275,10 +283,10 @@ class DebugAddrWriter {
275
283
virtual ~DebugAddrWriter (){};
276
284
// / Given an address returns an index in .debug_addr.
277
285
// / Adds Address to map.
278
- uint32_t getIndexFromAddress (uint64_t Address, uint64_t CUID );
286
+ uint32_t getIndexFromAddress (uint64_t Address, DWARFUnit &CU );
279
287
280
- // / Adds {Address, Index} to DWO ID CU.
281
- void addIndexAddress (uint64_t Address, uint32_t Index, uint64_t CUID );
288
+ // / Adds {\p Address, \p Index} to \p CU.
289
+ void addIndexAddress (uint64_t Address, uint32_t Index, DWARFUnit &CU );
282
290
283
291
// / Creates consolidated .debug_addr section, and builds DWOID to offset map.
284
292
virtual AddressSectionBuffer finalize ();
@@ -338,6 +346,12 @@ class DebugAddrWriter {
338
346
IndexToAddressMap IndexToAddress;
339
347
uint32_t CurrentIndex{0 };
340
348
};
349
+
350
+ virtual uint64_t getCUID (DWARFUnit &Unit) {
351
+ assert (Unit.getDWOId () && " Unit is not Skeleton CU." );
352
+ return *Unit.getDWOId ();
353
+ }
354
+
341
355
BinaryContext *BC;
342
356
// / Maps DWOID to AddressForDWOCU.
343
357
std::unordered_map<uint64_t , AddressForDWOCU> AddressMaps;
@@ -357,14 +371,60 @@ class DebugAddrWriterDwarf5 : public DebugAddrWriter {
357
371
// / Given DWARFUnit \p Unit returns offset of this CU in to .debug_addr
358
372
// / section.
359
373
virtual uint64_t getOffset (DWARFUnit &Unit) override ;
374
+
375
+ protected:
376
+ // / Given DWARFUnit \p Unit returns either DWO ID or it's offset within
377
+ // / .debug_info.
378
+ virtual uint64_t getCUID (DWARFUnit &Unit) override {
379
+ if (Unit.isDWOUnit ()) {
380
+ DWARFUnit *SkeletonCU = Unit.getLinkedUnit ();
381
+ return SkeletonCU->getOffset ();
382
+ }
383
+ return Unit.getOffset ();
384
+ }
385
+ };
386
+
387
+ // / This class is NOT thread safe.
388
+ using DebugStrOffsetsBufferVector = SmallVector<char , 16 >;
389
+ class DebugStrOffsetsWriter {
390
+ public:
391
+ DebugStrOffsetsWriter () {
392
+ StrOffsetsBuffer = std::make_unique<DebugStrOffsetsBufferVector>();
393
+ StrOffsetsStream = std::make_unique<raw_svector_ostream>(*StrOffsetsBuffer);
394
+ }
395
+
396
+ // / Initializes Buffer and Stream.
397
+ void initialize (const DWARFSection &StrOffsetsSection,
398
+ const Optional<StrOffsetsContributionDescriptor> Contr);
399
+
400
+ // / Update Str offset in .debug_str in .debug_str_offsets.
401
+ void updateAddressMap (uint32_t Index, uint32_t Address);
402
+
403
+ // / Writes out current sections entry into .debug_str_offsets.
404
+ void finalizeSection ();
405
+
406
+ // / Returns False if no strings were added to .debug_str.
407
+ bool isFinalized () const { return !StrOffsetsBuffer->empty (); }
408
+
409
+ // / Returns buffer containing .debug_str_offsets.
410
+ std::unique_ptr<DebugStrOffsetsBufferVector> releaseBuffer () {
411
+ return std::move (StrOffsetsBuffer);
412
+ }
413
+
414
+ private:
415
+ std::unique_ptr<DebugStrOffsetsBufferVector> StrOffsetsBuffer;
416
+ std::unique_ptr<raw_svector_ostream> StrOffsetsStream;
417
+ std::map<uint32_t , uint32_t > IndexToAddressMap;
418
+ // Section size not including header.
419
+ uint32_t CurrentSectionSize{0 };
360
420
};
361
421
362
422
using DebugStrBufferVector = SmallVector<char , 16 >;
363
423
class DebugStrWriter {
364
424
public:
365
425
DebugStrWriter () = delete ;
366
- DebugStrWriter (BinaryContext *Bc ) : BC(Bc ) { create (); }
367
- std::unique_ptr<DebugStrBufferVector> finalize () {
426
+ DebugStrWriter (BinaryContext &BC ) : BC(BC ) { create (); }
427
+ std::unique_ptr<DebugStrBufferVector> releaseBuffer () {
368
428
return std::move (StrBuffer);
369
429
}
370
430
@@ -384,7 +444,7 @@ class DebugStrWriter {
384
444
void create ();
385
445
std::unique_ptr<DebugStrBufferVector> StrBuffer;
386
446
std::unique_ptr<raw_svector_ostream> StrStream;
387
- BinaryContext * BC;
447
+ BinaryContext & BC;
388
448
};
389
449
390
450
enum class LocWriterKind { DebugLocWriter, DebugLoclistWriter };
@@ -451,9 +511,9 @@ class DebugLoclistWriter : public DebugLocWriter {
451
511
public:
452
512
~DebugLoclistWriter () {}
453
513
DebugLoclistWriter () = delete ;
454
- DebugLoclistWriter (BinaryContext *BC, uint64_t CID ,
514
+ DebugLoclistWriter (BinaryContext *BC, DWARFUnit &Unit ,
455
515
uint32_t LocListsBaseAttrOffset, uint8_t DV, bool SD)
456
- : DebugLocWriter(BC), CUID(CID ),
516
+ : DebugLocWriter(BC), CU(Unit ),
457
517
LocListsBaseAttrOffset (LocListsBaseAttrOffset), IsSplitDwarf(SD) {
458
518
Kind = LocWriterKind::DebugLoclistWriter;
459
519
DwarfVersion = DV;
@@ -472,8 +532,12 @@ class DebugLoclistWriter : public DebugLocWriter {
472
532
void finalize (uint64_t SectionOffset,
473
533
SimpleBinaryPatcher &DebugInfoPatcher) override ;
474
534
475
- // / Returns DWO ID.
476
- uint64_t getCUID () const { return CUID; }
535
+ // / Returns CU ID.
536
+ // / For Skelton CU it is a CU Offset.
537
+ // / For DWO CU it is a DWO ID.
538
+ uint64_t getCUID () const {
539
+ return CU.isDWOUnit () ? *CU.getDWOId () : CU.getOffset ();
540
+ }
477
541
478
542
LocWriterKind getKind () const { return DebugLocWriter::getKind (); }
479
543
@@ -511,7 +575,7 @@ class DebugLoclistWriter : public DebugLocWriter {
511
575
uint64_t Address{0 };
512
576
};
513
577
static DebugAddrWriter *AddrWriter;
514
- uint64_t CUID{ 0 } ;
578
+ DWARFUnit &CU ;
515
579
uint32_t LocListsBaseAttrOffset{InvalidLocListsBaseAttrOffset};
516
580
bool IsSplitDwarf{false };
517
581
};
0 commit comments