Skip to content

Commit 315c12b

Browse files
Add support for Dwarf 5 debug_info section in MCCAS
This includes, parsing the Dwarf 5 Compile Unit header correctly and correctly creating and materializing from the CAS with the larger DWARFv5 header.
1 parent a7b359e commit 315c12b

File tree

3 files changed

+80
-19
lines changed

3 files changed

+80
-19
lines changed

llvm/include/llvm/MCCAS/MCCASDebugV1.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ namespace mccasformats {
2020
namespace v1 {
2121

2222
constexpr unsigned Dwarf4HeaderSize32Bit = 11;
23+
constexpr unsigned Dwarf5HeaderSize32Bit = 12;
2324

2425
/// Returns true if the values associated with a combination of Form and Attr
2526
/// are not expected to deduplicate.

llvm/include/llvm/MCCAS/MCCASObjectV1.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,10 @@ class MCCASBuilder {
581581
struct CUSplit {
582582
SmallVector<MutableArrayRef<char>> SplitCUData;
583583
SmallVector<size_t> AbbrevOffsets;
584+
/// A list of Dwarf versions of the compile units, to help determine what
585+
/// the Compile Unit header format and size is like when creating
586+
/// CASObjects.
587+
SmallVector<uint16_t> DwarfVersions;
584588
};
585589
/// Split the data of the __debug_info section it into multiple pieces, one
586590
/// per Compile Unit(CU) and return them. The abbreviation offset for each CU

llvm/lib/MCCAS/MCCASObjectV1.cpp

Lines changed: 75 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,13 @@ class InMemoryCASDWARFObject : public DWARFObject {
112112
/// unit.
113113
Error partitionCUData(ArrayRef<char> DebugInfoData, uint64_t AbbrevOffset,
114114
DWARFContext *Ctx, MCCASBuilder &Builder,
115-
AbbrevSetWriter &AbbrevWriter);
115+
AbbrevSetWriter &AbbrevWriter, uint16_t DwarfVersion);
116116
};
117117

118118
struct CUInfo {
119119
uint64_t CUSize;
120120
uint32_t AbbrevOffset;
121+
uint16_t DwarfVersion;
121122
};
122123
static Expected<CUInfo> getAndSetDebugAbbrevOffsetAndSkip(
123124
MutableArrayRef<char> CUData, support::endianness Endian,
@@ -1685,10 +1686,25 @@ getAndSetDebugAbbrevOffsetAndSkip(MutableArrayRef<char> CUData,
16851686
if (auto E = Reader.readInteger(DwarfVersion))
16861687
return std::move(E);
16871688

1688-
// TODO: Dwarf 5 has a different order for the next fields.
1689-
if (DwarfVersion != 4)
1690-
return createStringError(inconvertibleErrorCode(),
1691-
"Expected Dwarf 4 input");
1689+
if (DwarfVersion >= 5) {
1690+
// From Dwarf 5 Section 7.5.1.1:
1691+
// Compile Unit Header Format is now changed with unit_type and address_size
1692+
// after the version. Parse both values from the header.
1693+
uint8_t UnitType;
1694+
if (auto E = Reader.readInteger(UnitType))
1695+
return std::move(E);
1696+
if (UnitType != dwarf::DW_UT_compile)
1697+
return createStringError(
1698+
inconvertibleErrorCode(),
1699+
"Unit type is not DW_UT_compile, and is incompatible with MCCAS!");
1700+
uint8_t AddressSize;
1701+
if (auto E = Reader.readInteger(AddressSize))
1702+
return std::move(E);
1703+
if (AddressSize != 8)
1704+
return createStringError(
1705+
inconvertibleErrorCode(),
1706+
"Address size is not 8 bytes, unsupported architecture for MCCAS!");
1707+
}
16921708

16931709
// TODO: Handle Dwarf 64 format, which uses 8 bytes.
16941710
size_t AbbrevPosition = Reader.getOffset();
@@ -1710,7 +1726,7 @@ getAndSetDebugAbbrevOffsetAndSkip(MutableArrayRef<char> CUData,
17101726
if (auto E = Reader.skip(*Size))
17111727
return std::move(E);
17121728

1713-
return CUInfo{Reader.getOffset(), AbbrevOffset};
1729+
return CUInfo{Reader.getOffset(), AbbrevOffset, DwarfVersion};
17141730
}
17151731

17161732
/// Given a list of MCFragments, return a vector with the concatenation of their
@@ -1750,6 +1766,7 @@ MCCASBuilder::splitDebugInfoSectionData(MutableArrayRef<char> DebugInfoData) {
17501766
return Info.takeError();
17511767
Split.SplitCUData.push_back(DebugInfoData.take_front(Info->CUSize));
17521768
Split.AbbrevOffsets.push_back(Info->AbbrevOffset);
1769+
Split.DwarfVersions.push_back(Info->DwarfVersion);
17531770
DebugInfoData = DebugInfoData.drop_front(Info->CUSize);
17541771
}
17551772

@@ -1875,7 +1892,8 @@ Error InMemoryCASDWARFObject::partitionCUData(ArrayRef<char> DebugInfoData,
18751892
uint64_t AbbrevOffset,
18761893
DWARFContext *Ctx,
18771894
MCCASBuilder &Builder,
1878-
AbbrevSetWriter &AbbrevWriter) {
1895+
AbbrevSetWriter &AbbrevWriter,
1896+
uint16_t DwarfVersion) {
18791897
StringRef AbbrevSectionContribution =
18801898
getAbbrevSection().drop_front(AbbrevOffset);
18811899
DataExtractor Data(AbbrevSectionContribution, isLittleEndian(), 8);
@@ -1894,13 +1912,24 @@ Error InMemoryCASDWARFObject::partitionCUData(ArrayRef<char> DebugInfoData,
18941912

18951913
DWARFDie CUDie = DCU.getUnitDIE(false);
18961914
assert(CUDie);
1897-
// Copy 11 bytes which represents the 32-bit DWARF Header for DWARF4.
1898-
if (DebugInfoData.size() < Dwarf4HeaderSize32Bit)
1899-
return createStringError(inconvertibleErrorCode(),
1900-
"DebugInfoData is too small, it doesn't even "
1901-
"contain a 32-bit DWARF Header");
1915+
ArrayRef<char> HeaderData;
1916+
if (DwarfVersion >= 5) {
1917+
// Copy 12 bytes which represents the 32-bit DWARF Header for DWARF5.
1918+
if (DebugInfoData.size() < Dwarf5HeaderSize32Bit)
1919+
return createStringError(inconvertibleErrorCode(),
1920+
"DebugInfoData is too small, it doesn't even "
1921+
"contain a 32-bit DWARF5 Header");
19021922

1903-
ArrayRef<char> HeaderData = DebugInfoData.take_front(Dwarf4HeaderSize32Bit);
1923+
HeaderData = DebugInfoData.take_front(Dwarf5HeaderSize32Bit);
1924+
} else {
1925+
// Copy 11 bytes which represents the 32-bit DWARF Header for DWARF4.
1926+
if (DebugInfoData.size() < Dwarf4HeaderSize32Bit)
1927+
return createStringError(inconvertibleErrorCode(),
1928+
"DebugInfoData is too small, it doesn't even "
1929+
"contain a 32-bit DWARF4 Header");
1930+
1931+
HeaderData = DebugInfoData.take_front(Dwarf4HeaderSize32Bit);
1932+
}
19041933
Expected<DIETopLevelRef> Converted =
19051934
DIEToCASConverter(DebugInfoData, Builder)
19061935
.convert(CUDie, HeaderData, AbbrevWriter);
@@ -1930,20 +1959,32 @@ Error MCCASBuilder::splitDebugInfoAndAbbrevSections() {
19301959

19311960
Expected<SmallVector<char, 0>> FullAbbrevData =
19321961
mergeMCFragmentContents(AbbrevFragmentList);
1962+
19331963
if (!FullAbbrevData)
19341964
return FullAbbrevData.takeError();
19351965

1936-
InMemoryCASDWARFObject CASObj(
1937-
*FullAbbrevData, Asm.getBackend().Endian == support::endianness::little);
1966+
const MCSection::FragmentListType &StringOffsetsFragmentList =
1967+
DwarfSections.StrOffsets->getFragmentList();
1968+
1969+
Expected<SmallVector<char, 0>> FullStringOffsetsData =
1970+
mergeMCFragmentContents(StringOffsetsFragmentList);
1971+
1972+
if (!FullStringOffsetsData)
1973+
return FullStringOffsetsData.takeError();
1974+
1975+
InMemoryCASDWARFObject CASObj(*FullAbbrevData, *FullStringOffsetsData,
1976+
Asm.getBackend().Endian ==
1977+
support::endianness::little);
19381978
auto DWARFObj = std::make_unique<InMemoryCASDWARFObject>(CASObj);
19391979
auto DWARFContextHolder = std::make_unique<DWARFContext>(std::move(DWARFObj));
19401980
auto *DWARFCtx = DWARFContextHolder.get();
19411981

19421982
AbbrevSetWriter AbbrevWriter;
1943-
for (auto [CUData, AbbrevOffset] :
1944-
llvm::zip(SplitInfo->SplitCUData, SplitInfo->AbbrevOffsets)) {
1983+
for (auto [CUData, AbbrevOffset, DwarfVersion] :
1984+
llvm::zip(SplitInfo->SplitCUData, SplitInfo->AbbrevOffsets,
1985+
SplitInfo->DwarfVersions)) {
19451986
if (auto E = CASObj.partitionCUData(CUData, AbbrevOffset, DWARFCtx, *this,
1946-
AbbrevWriter))
1987+
AbbrevWriter, DwarfVersion))
19471988
return E;
19481989
}
19491990
return Error::success();
@@ -3074,7 +3115,22 @@ Error mccasformats::v1::visitDebugInfo(
30743115
StringRef DistinctData = LoadedTopRef->DistinctData.getData();
30753116
BinaryStreamReader DistinctReader(DistinctData, support::endianness::little);
30763117
ArrayRef<char> HeaderData;
3077-
if (auto E = DistinctReader.readArray(HeaderData, Dwarf4HeaderSize32Bit))
3118+
3119+
auto BeginOffset = DistinctReader.getOffset();
3120+
auto Size = getSizeFromDwarfHeader(DistinctReader);
3121+
if (!Size)
3122+
return Size.takeError();
3123+
3124+
// 2-byte Dwarf version identifier.
3125+
uint16_t DwarfVersion;
3126+
if (auto E = DistinctReader.readInteger(DwarfVersion))
3127+
return E;
3128+
3129+
DistinctReader.setOffset(BeginOffset);
3130+
3131+
if (auto E = DistinctReader.readArray(
3132+
HeaderData,
3133+
DwarfVersion >= 5 ? Dwarf5HeaderSize32Bit : Dwarf4HeaderSize32Bit))
30783134
return E;
30793135
HeaderCallback(toStringRef(HeaderData));
30803136

0 commit comments

Comments
 (0)