@@ -490,11 +490,13 @@ class DebugInfoBinaryPatcher : public SimpleBinaryPatcher {
490
490
PatchBaseClass,
491
491
PatchValue32,
492
492
PatchValue64to32,
493
+ PatchValue32GenericSize,
493
494
PatchValue64,
494
495
PatchValueVariable,
495
496
ReferencePatchValue,
496
497
DWARFUnitOffsetBaseLabel,
497
- DestinationReferenceLabel
498
+ DestinationReferenceLabel,
499
+ NewDebugEntry
498
500
};
499
501
500
502
struct Patch {
@@ -535,6 +537,22 @@ class DebugInfoBinaryPatcher : public SimpleBinaryPatcher {
535
537
uint32_t Value;
536
538
};
537
539
540
+ // / Patch for 4 byte entry, where original entry size is not 4 bytes or 8
541
+ // / bytes.
542
+ struct DebugPatch32GenericSize : public Patch {
543
+ DebugPatch32GenericSize (uint32_t O, uint32_t V, uint32_t OVS)
544
+ : Patch(O, DebugPatchKind::PatchValue32GenericSize) {
545
+ Value = V;
546
+ OldValueSize = OVS;
547
+ }
548
+
549
+ static bool classof (const Patch *Writer) {
550
+ return Writer->getKind () == DebugPatchKind::PatchValue32GenericSize;
551
+ }
552
+ uint32_t Value;
553
+ uint32_t OldValueSize;
554
+ };
555
+
538
556
struct DebugPatch64 : public Patch {
539
557
DebugPatch64 (uint32_t O, uint64_t V)
540
558
: Patch(O, DebugPatchKind::PatchValue64) {
@@ -605,6 +623,22 @@ class DebugInfoBinaryPatcher : public SimpleBinaryPatcher {
605
623
}
606
624
};
607
625
626
+ struct NewDebugEntry : public Patch {
627
+ NewDebugEntry () = delete ;
628
+ NewDebugEntry (uint32_t O, std::string &&V)
629
+ : Patch(O, DebugPatchKind::NewDebugEntry) {
630
+ CurrentOrder = NewDebugEntry::OrderCounter++;
631
+ Value = std::move (V);
632
+ }
633
+
634
+ static bool classof (const Patch *Writer) {
635
+ return Writer->getKind () == DebugPatchKind::NewDebugEntry;
636
+ }
637
+ static uint32_t OrderCounter;
638
+ uint32_t CurrentOrder;
639
+ std::string Value;
640
+ };
641
+
608
642
virtual PatcherKind getKind () const override {
609
643
return PatcherKind::DebugInfoBinaryPatcher;
610
644
}
@@ -646,6 +680,12 @@ class DebugInfoBinaryPatcher : public SimpleBinaryPatcher {
646
680
void addReferenceToPatch (uint64_t Offset, uint32_t DestinationOffset,
647
681
uint32_t OldValueSize, dwarf::Form Form);
648
682
683
+ // / Inserts a new uint32_t \p Value at the end of \p DIE .
684
+ void insertNewEntry (const DWARFDie &DIE, uint32_t );
685
+
686
+ // / Inserts a new encoded \p Value at the end of \p DIE .
687
+ void insertNewEntry (const DWARFDie &DIE, std::string &&Value);
688
+
649
689
// / Clears unordered set for DestinationLabels.
650
690
void clearDestinationLabels () { DestinationLabels.clear (); }
651
691
@@ -670,6 +710,9 @@ class DebugInfoBinaryPatcher : public SimpleBinaryPatcher {
670
710
case DebugPatchKind::PatchValue64to32:
671
711
delete reinterpret_cast <DebugPatch64to32 *>(P);
672
712
break ;
713
+ case DebugPatchKind::PatchValue32GenericSize:
714
+ delete reinterpret_cast <DebugPatch32GenericSize *>(P);
715
+ break ;
673
716
case DebugPatchKind::PatchValue64:
674
717
delete reinterpret_cast <DebugPatch64 *>(P);
675
718
break ;
@@ -685,6 +728,9 @@ class DebugInfoBinaryPatcher : public SimpleBinaryPatcher {
685
728
case DebugPatchKind::DestinationReferenceLabel:
686
729
delete reinterpret_cast <DestinationReferenceLabel *>(P);
687
730
break ;
731
+ case DebugPatchKind::NewDebugEntry:
732
+ delete reinterpret_cast <NewDebugEntry *>(P);
733
+ break ;
688
734
}
689
735
}
690
736
};
@@ -728,10 +774,19 @@ class DebugAbbrevWriter {
728
774
uint8_t NewAttrForm;
729
775
};
730
776
777
+ struct AbbrevEntry {
778
+ dwarf::Attribute Attr;
779
+ dwarf::Form Form;
780
+ };
781
+
731
782
using PatchesTy = std::unordered_map<const DWARFAbbreviationDeclaration *,
732
783
SmallVector<PatchInfo, 2 >>;
733
784
std::unordered_map<const DWARFUnit *, PatchesTy> Patches;
734
785
786
+ using AbbrevEntryTy = std::unordered_map<const DWARFAbbreviationDeclaration *,
787
+ SmallVector<AbbrevEntry, 2 >>;
788
+ std::unordered_map<const DWARFUnit *, AbbrevEntryTy> NewAbbrevEntries;
789
+
735
790
// / DWARF context containing abbreviations.
736
791
DWARFContext &Context;
737
792
@@ -777,6 +832,27 @@ class DebugAbbrevWriter {
777
832
PatchInfo{AttrTag, NewAttrTag, NewAttrForm});
778
833
}
779
834
835
+ // / Adds attribute \p AttrTag and \p NewAttrForm in abbreviation declaration
836
+ // / \p Abbrev belonging to CU \p Unit .
837
+ void addAttribute (const DWARFUnit &Unit,
838
+ const DWARFAbbreviationDeclaration *Abbrev,
839
+ dwarf::Attribute AttrTag, dwarf::Form AttrForm) {
840
+ assert (&Unit.getContext () == &Context &&
841
+ " cannot update attribute from a different DWARF context" );
842
+ std::lock_guard<std::mutex> Lock (WriterMutex);
843
+ bool AlreadyAdded = false ;
844
+ for (AbbrevEntry &E : NewAbbrevEntries[&Unit][Abbrev])
845
+ if (E.Attr == AttrTag) {
846
+ AlreadyAdded = true ;
847
+ break ;
848
+ }
849
+
850
+ if (AlreadyAdded)
851
+ return ;
852
+ NewAbbrevEntries[&Unit][Abbrev].emplace_back (
853
+ AbbrevEntry{AttrTag, AttrForm});
854
+ }
855
+
780
856
// / Return a buffer with concatenated abbrev sections for all CUs and TUs
781
857
// / in the associated DWARF context. Section offsets could be queried using
782
858
// / getAbbreviationsOffsetForUnit() interface. For DWP, we are using DWOId
@@ -882,6 +958,17 @@ class DwarfLineTable {
882
958
}
883
959
};
884
960
961
+ struct AttrInfo {
962
+ DWARFFormValue V;
963
+ uint64_t Offset;
964
+ uint32_t Size; // Size of the attribute.
965
+ };
966
+
967
+ Optional<AttrInfo>
968
+ findAttributeInfo (const DWARFDie DIE,
969
+ const DWARFAbbreviationDeclaration *AbbrevDecl,
970
+ uint32_t Index);
971
+
885
972
} // namespace bolt
886
973
} // namespace llvm
887
974
0 commit comments