Skip to content

Commit 3e7d9f0

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.
1 parent 6e2dca3 commit 3e7d9f0

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
@@ -1982,14 +1982,16 @@ struct DIEToCASConverter {
19821982
bool IsLittleEndian;
19831983
uint8_t AddressSize;
19841984

1985-
Error convertInNewDIEBlock(
1986-
DWARFDie DIE, DistinctDataWriter &DistinctWriter,
1987-
AbbrevSetWriter &AbbrevWriter,
1988-
SmallVectorImpl<std::unique_ptr<DIEDataWriter>> &DIEWriters);
1985+
struct ParentAndChildDIE {
1986+
DWARFDie Parent;
1987+
bool ParentAlreadyWritten;
1988+
DIEDataWriter &Writer;
1989+
std::optional<DWARFDie> Child;
1990+
};
19891991

19901992
Error
1991-
convertImpl(DWARFDie &DIE, DIEDataWriter &DIEWriter,
1992-
DistinctDataWriter &DistinctWriter, AbbrevSetWriter &AbbrevWriter,
1993+
convertImpl(DWARFDie DIE, DistinctDataWriter &DistinctWriter,
1994+
AbbrevSetWriter &AbbrevWriter,
19931995
SmallVectorImpl<std::unique_ptr<DIEDataWriter>> &DIEWriters);
19941996
};
19951997

@@ -3006,6 +3008,12 @@ static void writeDIEAttrs(DWARFDie &DIE, ArrayRef<char> DebugInfoData,
30063008
}
30073009
}
30083010

3011+
static void
3012+
pushNewDIEWriter(SmallVectorImpl<std::unique_ptr<DIEDataWriter>> &DIEWriters) {
3013+
auto DIEWriter = std::make_unique<DIEDataWriter>();
3014+
DIEWriters.push_back(std::move(DIEWriter));
3015+
}
3016+
30093017
/// Creates an abbreviation for DIE using AbbrevWriter.
30103018
/// Stores the contents of the DIE using DistinctWriter and DIEWriter following
30113019
/// the format:
@@ -3021,61 +3029,54 @@ static void writeDIEAttrs(DWARFDie &DIE, ArrayRef<char> DebugInfoData,
30213029
/// DIEAbbrevSetRef block. In this case, raw_data should be interpreted
30223030
/// according to the corresponding DIEAbbrevRefs block.
30233031
Error DIEToCASConverter::convertImpl(
3024-
DWARFDie &DIE, DIEDataWriter &DIEWriter, DistinctDataWriter &DistinctWriter,
3032+
DWARFDie DIE, DistinctDataWriter &DistinctWriter,
30253033
AbbrevSetWriter &AbbrevWriter,
30263034
SmallVectorImpl<std::unique_ptr<DIEDataWriter>> &DIEWriters) {
3027-
Expected<unsigned> MaybeAbbrevIndex =
3028-
AbbrevWriter.createAbbrevEntry(DIE, CASBuilder);
3029-
if (!MaybeAbbrevIndex)
3030-
return MaybeAbbrevIndex.takeError();
3031-
3032-
DistinctWriter.writeULEB128(encodeAbbrevIndex(*MaybeAbbrevIndex));
3033-
writeDIEAttrs(DIE, DebugInfoData, DIEWriter, DistinctWriter, IsLittleEndian,
3034-
AddressSize);
3035-
3036-
for (DWARFDie Child = DIE.getFirstChild(); Child;
3037-
Child = Child.getSibling()) {
3038-
dwarf::Tag ChildTag = Child.getTag();
3039-
if (ChildTag == dwarf::Tag::DW_TAG_null) {
3040-
DistinctWriter.writeULEB128(getEndOfDIESiblingsMarker());
3041-
break;
3035+
SmallVector<ParentAndChildDIE> DIEStack;
3036+
pushNewDIEWriter(DIEWriters);
3037+
DIEStack.push_back({DIE, false, *DIEWriters.back(), std::nullopt});
3038+
while (!DIEStack.empty()) {
3039+
auto ParentAndChild = DIEStack.pop_back_val();
3040+
DWARFDie CurrDIE = ParentAndChild.Parent;
3041+
3042+
if (!ParentAndChild.ParentAlreadyWritten) {
3043+
Expected<unsigned> MaybeAbbrevIndex =
3044+
AbbrevWriter.createAbbrevEntry(CurrDIE, CASBuilder);
3045+
if (!MaybeAbbrevIndex)
3046+
return MaybeAbbrevIndex.takeError();
3047+
3048+
DistinctWriter.writeULEB128(encodeAbbrevIndex(*MaybeAbbrevIndex));
3049+
writeDIEAttrs(CurrDIE, DebugInfoData, ParentAndChild.Writer,
3050+
DistinctWriter, IsLittleEndian, AddressSize);
30423051
}
30433052

3044-
// FIXME: don't use recursion.
3045-
if (shouldCreateSeparateBlockFor(Child)) {
3046-
DistinctWriter.writeULEB128(getDIEInAnotherBlockMarker());
3047-
if (auto E = convertInNewDIEBlock(Child, DistinctWriter, AbbrevWriter,
3048-
DIEWriters))
3049-
return E;
3050-
continue;
3053+
DWARFDie Child = ParentAndChild.Child ? ParentAndChild.Child->getSibling()
3054+
: CurrDIE.getFirstChild();
3055+
if (Child) {
3056+
dwarf::Tag ChildTag = Child.getTag();
3057+
if (ChildTag == dwarf::Tag::DW_TAG_null)
3058+
DistinctWriter.writeULEB128(getEndOfDIESiblingsMarker());
3059+
else if (shouldCreateSeparateBlockFor(Child)) {
3060+
DistinctWriter.writeULEB128(getDIEInAnotherBlockMarker());
3061+
DIEStack.push_back({CurrDIE, true, ParentAndChild.Writer, Child});
3062+
pushNewDIEWriter(DIEWriters);
3063+
DIEStack.push_back({Child, false, *DIEWriters.back(), std::nullopt});
3064+
} else {
3065+
DIEStack.push_back({CurrDIE, true, ParentAndChild.Writer, Child});
3066+
DIEStack.push_back({Child, false, ParentAndChild.Writer, std::nullopt});
3067+
}
30513068
}
3052-
if (auto E = convertImpl(Child, DIEWriter, DistinctWriter, AbbrevWriter,
3053-
DIEWriters))
3054-
return E;
30553069
}
30563070
return Error::success();
30573071
}
30583072

3059-
Error DIEToCASConverter::convertInNewDIEBlock(
3060-
DWARFDie DIE, DistinctDataWriter &DistinctWriter,
3061-
AbbrevSetWriter &AbbrevWriter,
3062-
SmallVectorImpl<std::unique_ptr<DIEDataWriter>> &DIEWriters) {
3063-
auto DIEWriter = std::make_unique<DIEDataWriter>();
3064-
DIEWriters.push_back(std::move(DIEWriter));
3065-
if (auto E = convertImpl(DIE, *DIEWriters.back(), DistinctWriter,
3066-
AbbrevWriter, DIEWriters))
3067-
return E;
3068-
return Error::success();
3069-
}
3070-
30713073
Expected<DIETopLevelRef>
30723074
DIEToCASConverter::convert(DWARFDie DIE, ArrayRef<char> HeaderData,
30733075
AbbrevSetWriter &AbbrevWriter) {
30743076
DistinctDataWriter DistinctWriter;
30753077
DistinctWriter.writeData(HeaderData);
30763078
SmallVector<std::unique_ptr<DIEDataWriter>> DIEWriters;
3077-
if (Error E =
3078-
convertInNewDIEBlock(DIE, DistinctWriter, AbbrevWriter, DIEWriters))
3079+
if (Error E = convertImpl(DIE, DistinctWriter, AbbrevWriter, DIEWriters))
30793080
return std::move(E);
30803081

30813082
Expected<DIEAbbrevSetRef> MaybeAbbrevSet =

0 commit comments

Comments
 (0)