@@ -79,17 +79,26 @@ class AbbrevSetWriter;
7979// / debug info.
8080class InMemoryCASDWARFObject : public DWARFObject {
8181 ArrayRef<char > DebugAbbrevSection;
82+ DWARFSection DebugStringOffsetsSection;
8283 bool IsLittleEndian;
8384
8485public:
85- InMemoryCASDWARFObject (ArrayRef<char > AbbrevContents, bool IsLittleEndian)
86- : DebugAbbrevSection(AbbrevContents), IsLittleEndian(IsLittleEndian) {}
86+ InMemoryCASDWARFObject (ArrayRef<char > AbbrevContents,
87+ ArrayRef<char > StringOffsetsContents,
88+ bool IsLittleEndian)
89+ : DebugAbbrevSection(AbbrevContents),
90+ DebugStringOffsetsSection ({toStringRef (StringOffsetsContents)}),
91+ IsLittleEndian(IsLittleEndian) {}
8792 bool isLittleEndian () const override { return IsLittleEndian; }
8893
8994 StringRef getAbbrevSection () const override {
9095 return toStringRef (DebugAbbrevSection);
9196 }
9297
98+ const DWARFSection &getStrOffsetsSection () const override {
99+ return DebugStringOffsetsSection;
100+ }
101+
93102 std::optional<RelocAddrEntry> find (const DWARFSection &Sec,
94103 uint64_t Pos) const override {
95104 return {};
@@ -103,12 +112,13 @@ class InMemoryCASDWARFObject : public DWARFObject {
103112 // / unit.
104113 Error partitionCUData (ArrayRef<char > DebugInfoData, uint64_t AbbrevOffset,
105114 DWARFContext *Ctx, MCCASBuilder &Builder,
106- AbbrevSetWriter &AbbrevWriter);
115+ AbbrevSetWriter &AbbrevWriter, uint16_t DwarfVersion );
107116};
108117
109118struct CUInfo {
110119 uint64_t CUSize;
111120 uint32_t AbbrevOffset;
121+ uint16_t DwarfVersion;
112122};
113123static Expected<CUInfo> getAndSetDebugAbbrevOffsetAndSkip (
114124 MutableArrayRef<char > CUData, support::endianness Endian,
@@ -807,9 +817,23 @@ getLineTableLengthInfoAndVersion(DWARFDataExtractor &LineTableDataReader,
807817 auto Version = LineTableDataReader.getU16 (OffsetPtr, &Err);
808818 if (Err)
809819 return std::move (Err);
810- if (Version >= 5 )
811- return createStringError (inconvertibleErrorCode (),
812- " DWARF 5 and above is not currently supported" );
820+ if (Version >= 5 ) {
821+ // Dwarf 5 Section 6.2.4:
822+ // Line Table Header Format is now changed with an address_size and
823+ // segment_selector_size after the version. Parse both values from the
824+ // header.
825+ auto AddressSize = LineTableDataReader.getU8 (OffsetPtr, &Err);
826+ if (Err)
827+ return std::move (Err);
828+ if (AddressSize != 8 )
829+ return createStringError (
830+ inconvertibleErrorCode (),
831+ " Address size is not 8 bytes, unsupported architecture for MCCAS!" );
832+ LineTableDataReader.getU8 (OffsetPtr, &Err);
833+ if (Err)
834+ return std::move (Err);
835+ }
836+
813837 Prologue.Version = Version;
814838 // Since we do not support 64 bit DWARF, the prologue length is 4 bytes in
815839 // size.
@@ -1461,7 +1485,8 @@ DwarfSectionsCache mccasformats::v1::getDwarfSections(MCAssembler &Asm) {
14611485 Asm.getContext ().getObjectFileInfo ()->getDwarfInfoSection (),
14621486 Asm.getContext ().getObjectFileInfo ()->getDwarfLineSection (),
14631487 Asm.getContext ().getObjectFileInfo ()->getDwarfStrSection (),
1464- Asm.getContext ().getObjectFileInfo ()->getDwarfAbbrevSection ()};
1488+ Asm.getContext ().getObjectFileInfo ()->getDwarfAbbrevSection (),
1489+ Asm.getContext ().getObjectFileInfo ()->getDwarfStrOffSection ()};
14651490}
14661491
14671492Error MCCASBuilder::prepare () {
@@ -1725,10 +1750,25 @@ getAndSetDebugAbbrevOffsetAndSkip(MutableArrayRef<char> CUData,
17251750 if (auto E = Reader.readInteger (DwarfVersion))
17261751 return std::move (E);
17271752
1728- // TODO: Dwarf 5 has a different order for the next fields.
1729- if (DwarfVersion != 4 )
1730- return createStringError (inconvertibleErrorCode (),
1731- " Expected Dwarf 4 input" );
1753+ if (DwarfVersion >= 5 ) {
1754+ // From Dwarf 5 Section 7.5.1.1:
1755+ // Compile Unit Header Format is now changed with unit_type and address_size
1756+ // after the version. Parse both values from the header.
1757+ uint8_t UnitType;
1758+ if (auto E = Reader.readInteger (UnitType))
1759+ return std::move (E);
1760+ if (UnitType != dwarf::DW_UT_compile)
1761+ return createStringError (
1762+ inconvertibleErrorCode (),
1763+ " Unit type is not DW_UT_compile, and is incompatible with MCCAS!" );
1764+ uint8_t AddressSize;
1765+ if (auto E = Reader.readInteger (AddressSize))
1766+ return std::move (E);
1767+ if (AddressSize != 8 )
1768+ return createStringError (
1769+ inconvertibleErrorCode (),
1770+ " Address size is not 8 bytes, unsupported architecture for MCCAS!" );
1771+ }
17321772
17331773 // TODO: Handle Dwarf 64 format, which uses 8 bytes.
17341774 size_t AbbrevPosition = Reader.getOffset ();
@@ -1750,7 +1790,7 @@ getAndSetDebugAbbrevOffsetAndSkip(MutableArrayRef<char> CUData,
17501790 if (auto E = Reader.skip (*Size))
17511791 return std::move (E);
17521792
1753- return CUInfo{Reader.getOffset (), AbbrevOffset};
1793+ return CUInfo{Reader.getOffset (), AbbrevOffset, DwarfVersion };
17541794}
17551795
17561796// / Given a list of MCFragments, return a vector with the concatenation of their
@@ -1790,6 +1830,7 @@ MCCASBuilder::splitDebugInfoSectionData(MutableArrayRef<char> DebugInfoData) {
17901830 return Info.takeError ();
17911831 Split.SplitCUData .push_back (DebugInfoData.take_front (Info->CUSize ));
17921832 Split.AbbrevOffsets .push_back (Info->AbbrevOffset );
1833+ Split.DwarfVersions .push_back (Info->DwarfVersion );
17931834 DebugInfoData = DebugInfoData.drop_front (Info->CUSize );
17941835 }
17951836
@@ -1938,7 +1979,8 @@ Error InMemoryCASDWARFObject::partitionCUData(ArrayRef<char> DebugInfoData,
19381979 uint64_t AbbrevOffset,
19391980 DWARFContext *Ctx,
19401981 MCCASBuilder &Builder,
1941- AbbrevSetWriter &AbbrevWriter) {
1982+ AbbrevSetWriter &AbbrevWriter,
1983+ uint16_t DwarfVersion) {
19421984 StringRef AbbrevSectionContribution =
19431985 getAbbrevSection ().drop_front (AbbrevOffset);
19441986 DataExtractor Data (AbbrevSectionContribution, isLittleEndian (), 8 );
@@ -1957,13 +1999,24 @@ Error InMemoryCASDWARFObject::partitionCUData(ArrayRef<char> DebugInfoData,
19571999
19582000 DWARFDie CUDie = DCU.getUnitDIE (false );
19592001 assert (CUDie);
1960- // Copy 11 bytes which represents the 32-bit DWARF Header for DWARF4.
1961- if (DebugInfoData.size () < Dwarf4HeaderSize32Bit)
1962- return createStringError (inconvertibleErrorCode (),
1963- " DebugInfoData is too small, it doesn't even "
1964- " contain a 32-bit DWARF Header" );
2002+ ArrayRef<char > HeaderData;
2003+ if (DwarfVersion >= 5 ) {
2004+ // Copy 12 bytes which represents the 32-bit DWARF Header for DWARF5.
2005+ if (DebugInfoData.size () < Dwarf5HeaderSize32Bit)
2006+ return createStringError (inconvertibleErrorCode (),
2007+ " DebugInfoData is too small, it doesn't even "
2008+ " contain a 32-bit DWARF5 Header" );
2009+
2010+ HeaderData = DebugInfoData.take_front (Dwarf5HeaderSize32Bit);
2011+ } else {
2012+ // Copy 11 bytes which represents the 32-bit DWARF Header for DWARF4.
2013+ if (DebugInfoData.size () < Dwarf4HeaderSize32Bit)
2014+ return createStringError (inconvertibleErrorCode (),
2015+ " DebugInfoData is too small, it doesn't even "
2016+ " contain a 32-bit DWARF4 Header" );
19652017
1966- ArrayRef<char > HeaderData = DebugInfoData.take_front (Dwarf4HeaderSize32Bit);
2018+ HeaderData = DebugInfoData.take_front (Dwarf4HeaderSize32Bit);
2019+ }
19672020 Expected<DIETopLevelRef> Converted =
19682021 DIEToCASConverter (DebugInfoData, Builder)
19692022 .convert (CUDie, HeaderData, AbbrevWriter);
@@ -1993,20 +2046,32 @@ Error MCCASBuilder::splitDebugInfoAndAbbrevSections() {
19932046
19942047 Expected<SmallVector<char , 0 >> FullAbbrevData =
19952048 mergeMCFragmentContents (AbbrevFragmentList);
2049+
19962050 if (!FullAbbrevData)
19972051 return FullAbbrevData.takeError ();
19982052
1999- InMemoryCASDWARFObject CASObj (
2000- *FullAbbrevData, Asm.getBackend ().Endian == support::endianness::little);
2053+ const MCSection::FragmentListType &StringOffsetsFragmentList =
2054+ DwarfSections.StrOffsets ->getFragmentList ();
2055+
2056+ Expected<SmallVector<char , 0 >> FullStringOffsetsData =
2057+ mergeMCFragmentContents (StringOffsetsFragmentList);
2058+
2059+ if (!FullStringOffsetsData)
2060+ return FullStringOffsetsData.takeError ();
2061+
2062+ InMemoryCASDWARFObject CASObj (*FullAbbrevData, *FullStringOffsetsData,
2063+ Asm.getBackend ().Endian ==
2064+ support::endianness::little);
20012065 auto DWARFObj = std::make_unique<InMemoryCASDWARFObject>(CASObj);
20022066 auto DWARFContextHolder = std::make_unique<DWARFContext>(std::move (DWARFObj));
20032067 auto *DWARFCtx = DWARFContextHolder.get ();
20042068
20052069 AbbrevSetWriter AbbrevWriter;
2006- for (auto [CUData, AbbrevOffset] :
2007- llvm::zip (SplitInfo->SplitCUData , SplitInfo->AbbrevOffsets )) {
2070+ for (auto [CUData, AbbrevOffset, DwarfVersion] :
2071+ llvm::zip (SplitInfo->SplitCUData , SplitInfo->AbbrevOffsets ,
2072+ SplitInfo->DwarfVersions )) {
20082073 if (auto E = CASObj.partitionCUData (CUData, AbbrevOffset, DWARFCtx, *this ,
2009- AbbrevWriter))
2074+ AbbrevWriter, DwarfVersion ))
20102075 return E;
20112076 }
20122077 return Error::success ();
@@ -2162,6 +2227,8 @@ Error MCCASBuilder::createDebugStrSection() {
21622227 startSection (DwarfSections.Str );
21632228 for (auto DebugStringRef : *DebugStringRefs)
21642229 addNode (DebugStringRef);
2230+ if (auto E = createPaddingRef (DwarfSections.Str ))
2231+ return E;
21652232 return finalizeSection<DebugStringSectionRef>();
21662233}
21672234
@@ -3166,7 +3233,22 @@ Error mccasformats::v1::visitDebugInfo(
31663233 StringRef DistinctData = LoadedTopRef->DistinctData .getData ();
31673234 BinaryStreamReader DistinctReader (DistinctData, support::endianness::little);
31683235 ArrayRef<char > HeaderData;
3169- if (auto E = DistinctReader.readArray (HeaderData, Dwarf4HeaderSize32Bit))
3236+
3237+ auto BeginOffset = DistinctReader.getOffset ();
3238+ auto Size = getSizeFromDwarfHeader (DistinctReader);
3239+ if (!Size)
3240+ return Size.takeError ();
3241+
3242+ // 2-byte Dwarf version identifier.
3243+ uint16_t DwarfVersion;
3244+ if (auto E = DistinctReader.readInteger (DwarfVersion))
3245+ return E;
3246+
3247+ DistinctReader.setOffset (BeginOffset);
3248+
3249+ if (auto E = DistinctReader.readArray (
3250+ HeaderData,
3251+ DwarfVersion >= 5 ? Dwarf5HeaderSize32Bit : Dwarf4HeaderSize32Bit))
31703252 return E;
31713253 HeaderCallback (toStringRef (HeaderData));
31723254
0 commit comments