@@ -79,17 +79,26 @@ class AbbrevSetWriter;
79
79
// / debug info.
80
80
class InMemoryCASDWARFObject : public DWARFObject {
81
81
ArrayRef<char > DebugAbbrevSection;
82
+ DWARFSection DebugStringOffsetsSection;
82
83
bool IsLittleEndian;
83
84
84
85
public:
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) {}
87
92
bool isLittleEndian () const override { return IsLittleEndian; }
88
93
89
94
StringRef getAbbrevSection () const override {
90
95
return toStringRef (DebugAbbrevSection);
91
96
}
92
97
98
+ const DWARFSection &getStrOffsetsSection () const override {
99
+ return DebugStringOffsetsSection;
100
+ }
101
+
93
102
std::optional<RelocAddrEntry> find (const DWARFSection &Sec,
94
103
uint64_t Pos) const override {
95
104
return {};
@@ -103,12 +112,13 @@ class InMemoryCASDWARFObject : public DWARFObject {
103
112
// / unit.
104
113
Error partitionCUData (ArrayRef<char > DebugInfoData, uint64_t AbbrevOffset,
105
114
DWARFContext *Ctx, MCCASBuilder &Builder,
106
- AbbrevSetWriter &AbbrevWriter);
115
+ AbbrevSetWriter &AbbrevWriter, uint16_t DwarfVersion );
107
116
};
108
117
109
118
struct CUInfo {
110
119
uint64_t CUSize;
111
120
uint32_t AbbrevOffset;
121
+ uint16_t DwarfVersion;
112
122
};
113
123
static Expected<CUInfo> getAndSetDebugAbbrevOffsetAndSkip (
114
124
MutableArrayRef<char > CUData, support::endianness Endian,
@@ -807,9 +817,23 @@ getLineTableLengthInfoAndVersion(DWARFDataExtractor &LineTableDataReader,
807
817
auto Version = LineTableDataReader.getU16 (OffsetPtr, &Err);
808
818
if (Err)
809
819
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
+
813
837
Prologue.Version = Version;
814
838
// Since we do not support 64 bit DWARF, the prologue length is 4 bytes in
815
839
// size.
@@ -1461,7 +1485,8 @@ DwarfSectionsCache mccasformats::v1::getDwarfSections(MCAssembler &Asm) {
1461
1485
Asm.getContext ().getObjectFileInfo ()->getDwarfInfoSection (),
1462
1486
Asm.getContext ().getObjectFileInfo ()->getDwarfLineSection (),
1463
1487
Asm.getContext ().getObjectFileInfo ()->getDwarfStrSection (),
1464
- Asm.getContext ().getObjectFileInfo ()->getDwarfAbbrevSection ()};
1488
+ Asm.getContext ().getObjectFileInfo ()->getDwarfAbbrevSection (),
1489
+ Asm.getContext ().getObjectFileInfo ()->getDwarfStrOffSection ()};
1465
1490
}
1466
1491
1467
1492
Error MCCASBuilder::prepare () {
@@ -1725,10 +1750,25 @@ getAndSetDebugAbbrevOffsetAndSkip(MutableArrayRef<char> CUData,
1725
1750
if (auto E = Reader.readInteger (DwarfVersion))
1726
1751
return std::move (E);
1727
1752
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
+ }
1732
1772
1733
1773
// TODO: Handle Dwarf 64 format, which uses 8 bytes.
1734
1774
size_t AbbrevPosition = Reader.getOffset ();
@@ -1750,7 +1790,7 @@ getAndSetDebugAbbrevOffsetAndSkip(MutableArrayRef<char> CUData,
1750
1790
if (auto E = Reader.skip (*Size))
1751
1791
return std::move (E);
1752
1792
1753
- return CUInfo{Reader.getOffset (), AbbrevOffset};
1793
+ return CUInfo{Reader.getOffset (), AbbrevOffset, DwarfVersion };
1754
1794
}
1755
1795
1756
1796
// / Given a list of MCFragments, return a vector with the concatenation of their
@@ -1790,6 +1830,7 @@ MCCASBuilder::splitDebugInfoSectionData(MutableArrayRef<char> DebugInfoData) {
1790
1830
return Info.takeError ();
1791
1831
Split.SplitCUData .push_back (DebugInfoData.take_front (Info->CUSize ));
1792
1832
Split.AbbrevOffsets .push_back (Info->AbbrevOffset );
1833
+ Split.DwarfVersions .push_back (Info->DwarfVersion );
1793
1834
DebugInfoData = DebugInfoData.drop_front (Info->CUSize );
1794
1835
}
1795
1836
@@ -1938,7 +1979,8 @@ Error InMemoryCASDWARFObject::partitionCUData(ArrayRef<char> DebugInfoData,
1938
1979
uint64_t AbbrevOffset,
1939
1980
DWARFContext *Ctx,
1940
1981
MCCASBuilder &Builder,
1941
- AbbrevSetWriter &AbbrevWriter) {
1982
+ AbbrevSetWriter &AbbrevWriter,
1983
+ uint16_t DwarfVersion) {
1942
1984
StringRef AbbrevSectionContribution =
1943
1985
getAbbrevSection ().drop_front (AbbrevOffset);
1944
1986
DataExtractor Data (AbbrevSectionContribution, isLittleEndian (), 8 );
@@ -1957,13 +1999,24 @@ Error InMemoryCASDWARFObject::partitionCUData(ArrayRef<char> DebugInfoData,
1957
1999
1958
2000
DWARFDie CUDie = DCU.getUnitDIE (false );
1959
2001
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" );
1965
2017
1966
- ArrayRef<char > HeaderData = DebugInfoData.take_front (Dwarf4HeaderSize32Bit);
2018
+ HeaderData = DebugInfoData.take_front (Dwarf4HeaderSize32Bit);
2019
+ }
1967
2020
Expected<DIETopLevelRef> Converted =
1968
2021
DIEToCASConverter (DebugInfoData, Builder)
1969
2022
.convert (CUDie, HeaderData, AbbrevWriter);
@@ -1993,20 +2046,32 @@ Error MCCASBuilder::splitDebugInfoAndAbbrevSections() {
1993
2046
1994
2047
Expected<SmallVector<char , 0 >> FullAbbrevData =
1995
2048
mergeMCFragmentContents (AbbrevFragmentList);
2049
+
1996
2050
if (!FullAbbrevData)
1997
2051
return FullAbbrevData.takeError ();
1998
2052
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);
2001
2065
auto DWARFObj = std::make_unique<InMemoryCASDWARFObject>(CASObj);
2002
2066
auto DWARFContextHolder = std::make_unique<DWARFContext>(std::move (DWARFObj));
2003
2067
auto *DWARFCtx = DWARFContextHolder.get ();
2004
2068
2005
2069
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 )) {
2008
2073
if (auto E = CASObj.partitionCUData (CUData, AbbrevOffset, DWARFCtx, *this ,
2009
- AbbrevWriter))
2074
+ AbbrevWriter, DwarfVersion ))
2010
2075
return E;
2011
2076
}
2012
2077
return Error::success ();
@@ -2162,6 +2227,8 @@ Error MCCASBuilder::createDebugStrSection() {
2162
2227
startSection (DwarfSections.Str );
2163
2228
for (auto DebugStringRef : *DebugStringRefs)
2164
2229
addNode (DebugStringRef);
2230
+ if (auto E = createPaddingRef (DwarfSections.Str ))
2231
+ return E;
2165
2232
return finalizeSection<DebugStringSectionRef>();
2166
2233
}
2167
2234
@@ -3166,7 +3233,22 @@ Error mccasformats::v1::visitDebugInfo(
3166
3233
StringRef DistinctData = LoadedTopRef->DistinctData .getData ();
3167
3234
BinaryStreamReader DistinctReader (DistinctData, support::endianness::little);
3168
3235
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))
3170
3252
return E;
3171
3253
HeaderCallback (toStringRef (HeaderData));
3172
3254
0 commit comments