@@ -490,11 +490,13 @@ class DebugInfoBinaryPatcher : public SimpleBinaryPatcher {
490490 PatchBaseClass,
491491 PatchValue32,
492492 PatchValue64to32,
493+ PatchValue32GenericSize,
493494 PatchValue64,
494495 PatchValueVariable,
495496 ReferencePatchValue,
496497 DWARFUnitOffsetBaseLabel,
497- DestinationReferenceLabel
498+ DestinationReferenceLabel,
499+ NewDebugEntry
498500 };
499501
500502 struct Patch {
@@ -535,6 +537,22 @@ class DebugInfoBinaryPatcher : public SimpleBinaryPatcher {
535537 uint32_t Value;
536538 };
537539
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+
538556 struct DebugPatch64 : public Patch {
539557 DebugPatch64 (uint32_t O, uint64_t V)
540558 : Patch(O, DebugPatchKind::PatchValue64) {
@@ -605,6 +623,22 @@ class DebugInfoBinaryPatcher : public SimpleBinaryPatcher {
605623 }
606624 };
607625
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+
608642 virtual PatcherKind getKind () const override {
609643 return PatcherKind::DebugInfoBinaryPatcher;
610644 }
@@ -646,6 +680,12 @@ class DebugInfoBinaryPatcher : public SimpleBinaryPatcher {
646680 void addReferenceToPatch (uint64_t Offset, uint32_t DestinationOffset,
647681 uint32_t OldValueSize, dwarf::Form Form);
648682
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+
649689 // / Clears unordered set for DestinationLabels.
650690 void clearDestinationLabels () { DestinationLabels.clear (); }
651691
@@ -670,6 +710,9 @@ class DebugInfoBinaryPatcher : public SimpleBinaryPatcher {
670710 case DebugPatchKind::PatchValue64to32:
671711 delete reinterpret_cast <DebugPatch64to32 *>(P);
672712 break ;
713+ case DebugPatchKind::PatchValue32GenericSize:
714+ delete reinterpret_cast <DebugPatch32GenericSize *>(P);
715+ break ;
673716 case DebugPatchKind::PatchValue64:
674717 delete reinterpret_cast <DebugPatch64 *>(P);
675718 break ;
@@ -685,6 +728,9 @@ class DebugInfoBinaryPatcher : public SimpleBinaryPatcher {
685728 case DebugPatchKind::DestinationReferenceLabel:
686729 delete reinterpret_cast <DestinationReferenceLabel *>(P);
687730 break ;
731+ case DebugPatchKind::NewDebugEntry:
732+ delete reinterpret_cast <NewDebugEntry *>(P);
733+ break ;
688734 }
689735 }
690736 };
@@ -728,10 +774,19 @@ class DebugAbbrevWriter {
728774 uint8_t NewAttrForm;
729775 };
730776
777+ struct AbbrevEntry {
778+ dwarf::Attribute Attr;
779+ dwarf::Form Form;
780+ };
781+
731782 using PatchesTy = std::unordered_map<const DWARFAbbreviationDeclaration *,
732783 SmallVector<PatchInfo, 2 >>;
733784 std::unordered_map<const DWARFUnit *, PatchesTy> Patches;
734785
786+ using AbbrevEntryTy = std::unordered_map<const DWARFAbbreviationDeclaration *,
787+ SmallVector<AbbrevEntry, 2 >>;
788+ std::unordered_map<const DWARFUnit *, AbbrevEntryTy> NewAbbrevEntries;
789+
735790 // / DWARF context containing abbreviations.
736791 DWARFContext &Context;
737792
@@ -777,6 +832,27 @@ class DebugAbbrevWriter {
777832 PatchInfo{AttrTag, NewAttrTag, NewAttrForm});
778833 }
779834
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+
780856 // / Return a buffer with concatenated abbrev sections for all CUs and TUs
781857 // / in the associated DWARF context. Section offsets could be queried using
782858 // / getAbbreviationsOffsetForUnit() interface. For DWP, we are using DWOId
@@ -882,6 +958,17 @@ class DwarfLineTable {
882958 }
883959};
884960
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+
885972} // namespace bolt
886973} // namespace llvm
887974
0 commit comments