Skip to content

Commit a1580b2

Browse files
Rewrite MCCAS Debug Info creation as iterative
The MCCAS code responsible for creating the debug info section representation is written recursively, which could lead to a stack overflow, this patches rewrites it to be recursive. (cherry picked from commit 3e7d9f0)
1 parent e09e318 commit a1580b2

File tree

1 file changed

+47
-46
lines changed

1 file changed

+47
-46
lines changed

llvm/lib/MCCAS/MCCASObjectV1.cpp

Lines changed: 47 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2298,14 +2298,16 @@ struct DIEToCASConverter {
22982298
bool IsLittleEndian;
22992299
uint8_t AddressSize;
23002300

2301-
Error convertInNewDIEBlock(
2302-
DWARFDie DIE, DistinctDataWriter &DistinctWriter,
2303-
AbbrevSetWriter &AbbrevWriter,
2304-
SmallVectorImpl<std::unique_ptr<DIEDataWriter>> &DIEWriters);
2301+
struct ParentAndChildDIE {
2302+
DWARFDie Parent;
2303+
bool ParentAlreadyWritten;
2304+
DIEDataWriter &Writer;
2305+
std::optional<DWARFDie> Child;
2306+
};
23052307

23062308
Error
2307-
convertImpl(DWARFDie &DIE, DIEDataWriter &DIEWriter,
2308-
DistinctDataWriter &DistinctWriter, AbbrevSetWriter &AbbrevWriter,
2309+
convertImpl(DWARFDie DIE, DistinctDataWriter &DistinctWriter,
2310+
AbbrevSetWriter &AbbrevWriter,
23092311
SmallVectorImpl<std::unique_ptr<DIEDataWriter>> &DIEWriters);
23102312
};
23112313

@@ -3650,6 +3652,12 @@ static void writeDIEAttrs(DWARFDie &DIE, ArrayRef<char> DebugInfoData,
36503652
}
36513653
}
36523654

3655+
static void
3656+
pushNewDIEWriter(SmallVectorImpl<std::unique_ptr<DIEDataWriter>> &DIEWriters) {
3657+
auto DIEWriter = std::make_unique<DIEDataWriter>();
3658+
DIEWriters.push_back(std::move(DIEWriter));
3659+
}
3660+
36533661
/// Creates an abbreviation for DIE using AbbrevWriter.
36543662
/// Stores the contents of the DIE using DistinctWriter and DIEWriter following
36553663
/// the format:
@@ -3665,61 +3673,54 @@ static void writeDIEAttrs(DWARFDie &DIE, ArrayRef<char> DebugInfoData,
36653673
/// DIEAbbrevSetRef block. In this case, raw_data should be interpreted
36663674
/// according to the corresponding DIEAbbrevRefs block.
36673675
Error DIEToCASConverter::convertImpl(
3668-
DWARFDie &DIE, DIEDataWriter &DIEWriter, DistinctDataWriter &DistinctWriter,
3676+
DWARFDie DIE, DistinctDataWriter &DistinctWriter,
36693677
AbbrevSetWriter &AbbrevWriter,
36703678
SmallVectorImpl<std::unique_ptr<DIEDataWriter>> &DIEWriters) {
3671-
Expected<unsigned> MaybeAbbrevIndex =
3672-
AbbrevWriter.createAbbrevEntry(DIE, CASBuilder);
3673-
if (!MaybeAbbrevIndex)
3674-
return MaybeAbbrevIndex.takeError();
3675-
3676-
DistinctWriter.writeULEB128(encodeAbbrevIndex(*MaybeAbbrevIndex));
3677-
writeDIEAttrs(DIE, DebugInfoData, DIEWriter, DistinctWriter, IsLittleEndian,
3678-
AddressSize);
3679-
3680-
for (DWARFDie Child = DIE.getFirstChild(); Child;
3681-
Child = Child.getSibling()) {
3682-
dwarf::Tag ChildTag = Child.getTag();
3683-
if (ChildTag == dwarf::Tag::DW_TAG_null) {
3684-
DistinctWriter.writeULEB128(getEndOfDIESiblingsMarker());
3685-
break;
3679+
SmallVector<ParentAndChildDIE> DIEStack;
3680+
pushNewDIEWriter(DIEWriters);
3681+
DIEStack.push_back({DIE, false, *DIEWriters.back(), std::nullopt});
3682+
while (!DIEStack.empty()) {
3683+
auto ParentAndChild = DIEStack.pop_back_val();
3684+
DWARFDie CurrDIE = ParentAndChild.Parent;
3685+
3686+
if (!ParentAndChild.ParentAlreadyWritten) {
3687+
Expected<unsigned> MaybeAbbrevIndex =
3688+
AbbrevWriter.createAbbrevEntry(CurrDIE, CASBuilder);
3689+
if (!MaybeAbbrevIndex)
3690+
return MaybeAbbrevIndex.takeError();
3691+
3692+
DistinctWriter.writeULEB128(encodeAbbrevIndex(*MaybeAbbrevIndex));
3693+
writeDIEAttrs(CurrDIE, DebugInfoData, ParentAndChild.Writer,
3694+
DistinctWriter, IsLittleEndian, AddressSize);
36863695
}
36873696

3688-
// FIXME: don't use recursion.
3689-
if (shouldCreateSeparateBlockFor(Child)) {
3690-
DistinctWriter.writeULEB128(getDIEInAnotherBlockMarker());
3691-
if (auto E = convertInNewDIEBlock(Child, DistinctWriter, AbbrevWriter,
3692-
DIEWriters))
3693-
return E;
3694-
continue;
3697+
DWARFDie Child = ParentAndChild.Child ? ParentAndChild.Child->getSibling()
3698+
: CurrDIE.getFirstChild();
3699+
if (Child) {
3700+
dwarf::Tag ChildTag = Child.getTag();
3701+
if (ChildTag == dwarf::Tag::DW_TAG_null)
3702+
DistinctWriter.writeULEB128(getEndOfDIESiblingsMarker());
3703+
else if (shouldCreateSeparateBlockFor(Child)) {
3704+
DistinctWriter.writeULEB128(getDIEInAnotherBlockMarker());
3705+
DIEStack.push_back({CurrDIE, true, ParentAndChild.Writer, Child});
3706+
pushNewDIEWriter(DIEWriters);
3707+
DIEStack.push_back({Child, false, *DIEWriters.back(), std::nullopt});
3708+
} else {
3709+
DIEStack.push_back({CurrDIE, true, ParentAndChild.Writer, Child});
3710+
DIEStack.push_back({Child, false, ParentAndChild.Writer, std::nullopt});
3711+
}
36953712
}
3696-
if (auto E = convertImpl(Child, DIEWriter, DistinctWriter, AbbrevWriter,
3697-
DIEWriters))
3698-
return E;
36993713
}
37003714
return Error::success();
37013715
}
37023716

3703-
Error DIEToCASConverter::convertInNewDIEBlock(
3704-
DWARFDie DIE, DistinctDataWriter &DistinctWriter,
3705-
AbbrevSetWriter &AbbrevWriter,
3706-
SmallVectorImpl<std::unique_ptr<DIEDataWriter>> &DIEWriters) {
3707-
auto DIEWriter = std::make_unique<DIEDataWriter>();
3708-
DIEWriters.push_back(std::move(DIEWriter));
3709-
if (auto E = convertImpl(DIE, *DIEWriters.back(), DistinctWriter,
3710-
AbbrevWriter, DIEWriters))
3711-
return E;
3712-
return Error::success();
3713-
}
3714-
37153717
Expected<DIETopLevelRef>
37163718
DIEToCASConverter::convert(DWARFDie DIE, ArrayRef<char> HeaderData,
37173719
AbbrevSetWriter &AbbrevWriter) {
37183720
DistinctDataWriter DistinctWriter;
37193721
DistinctWriter.writeData(HeaderData);
37203722
SmallVector<std::unique_ptr<DIEDataWriter>> DIEWriters;
3721-
if (Error E =
3722-
convertInNewDIEBlock(DIE, DistinctWriter, AbbrevWriter, DIEWriters))
3723+
if (Error E = convertImpl(DIE, DistinctWriter, AbbrevWriter, DIEWriters))
37233724
return std::move(E);
37243725

37253726
Expected<DIEAbbrevSetRef> MaybeAbbrevSet =

0 commit comments

Comments
 (0)