@@ -505,12 +505,13 @@ static Error materializeDebugInfoOpt(MCCASReader &Reader,
505
505
StringRef FormData, bool ) {
506
506
if (Form == dwarf::Form::DW_FORM_ref4_cas ||
507
507
Form == dwarf::Form::DW_FORM_strp_cas) {
508
- auto Reader = BinaryStreamReader (FormData, support::endianness::little);
509
- uint64_t Data64;
510
- if (auto Err = Reader.readULEB128 (Data64))
511
- handleAllErrors (std::move (Err));
508
+ DataExtractor Extractor (FormData, true , 8 );
509
+ DataExtractor::Cursor Cursor (0 );
510
+ uint64_t Data64 = Extractor.getULEB128 (Cursor);
511
+ if (!Cursor)
512
+ handleAllErrors (Cursor.takeError ());
512
513
uint32_t Data32 = Data64;
513
- assert (Data32 == Data64 && Reader. empty ( ));
514
+ assert (Data32 == Data64 && Extractor. eof (Cursor ));
514
515
SectionStream->write (reinterpret_cast <char *>(&Data32), sizeof (Data32));
515
516
} else
516
517
*SectionStream << FormData;
@@ -1703,13 +1704,14 @@ Error MCCASBuilder::createStringSection(
1703
1704
// / Reads and returns the length field of a dwarf header contained in Reader,
1704
1705
// / assuming Reader is positioned at the beginning of the header. The Reader's
1705
1706
// / state is advanced to the first byte after the header.
1706
- static Expected<size_t > getSizeFromDwarfHeader (BinaryStreamReader &Reader) {
1707
+ static Expected<size_t > getSizeFromDwarfHeader (DataExtractor &Extractor,
1708
+ DataExtractor::Cursor &Cursor) {
1707
1709
// From DWARF 5 section 7.4:
1708
1710
// In the 32-bit DWARF format, an initial length field [...] is an unsigned
1709
1711
// 4-byte integer (which must be less than 0xfffffff0);
1710
- uint32_t Word1;
1711
- if (auto E = Reader. readInteger (Word1) )
1712
- return std::move (E );
1712
+ uint32_t Word1 = Extractor. getU32 (Cursor) ;
1713
+ if (!Cursor )
1714
+ return Cursor. takeError ( );
1713
1715
1714
1716
// TODO: handle 64-bit DWARF format.
1715
1717
if (Word1 >= 0xfffffff0 )
@@ -1719,17 +1721,6 @@ static Expected<size_t> getSizeFromDwarfHeader(BinaryStreamReader &Reader) {
1719
1721
return Word1;
1720
1722
}
1721
1723
1722
- // TODO: Remove
1723
- Expected<size_t >
1724
- mccasformats::v1::getSizeFromDwarfHeaderAndSkip (BinaryStreamReader &Reader) {
1725
- Expected<size_t > Size = getSizeFromDwarfHeader (Reader);
1726
- if (!Size)
1727
- return Size.takeError ();
1728
- if (auto E = Reader.skip (*Size))
1729
- return std::move (E);
1730
- return Size;
1731
- }
1732
-
1733
1724
// / Returns the Abbreviation Offset field of a Dwarf Compilation Unit (CU)
1734
1725
// / contained in CUData, as well as the total number of bytes taken by the CU.
1735
1726
// / Note: this is different from the length field of the Dwarf header, which
@@ -1738,43 +1729,45 @@ static Expected<CUInfo>
1738
1729
getAndSetDebugAbbrevOffsetAndSkip (MutableArrayRef<char > CUData,
1739
1730
support::endianness Endian,
1740
1731
std::optional<uint32_t > NewOffset) {
1741
- BinaryStreamReader Reader (toStringRef (CUData), Endian);
1742
- Expected<size_t > Size = getSizeFromDwarfHeader (Reader);
1732
+ DataExtractor Extractor (toStringRef (CUData),
1733
+ Endian == support::endianness::little, 8 );
1734
+ DataExtractor::Cursor Cursor (0 );
1735
+ Expected<size_t > Size = getSizeFromDwarfHeader (Extractor, Cursor);
1743
1736
if (!Size)
1744
1737
return Size.takeError ();
1745
1738
1746
- size_t AfterSizeOffset = Reader. getOffset ();
1739
+ size_t AfterSizeOffset = Cursor. tell ();
1747
1740
1748
1741
// 2-byte Dwarf version identifier.
1749
- uint16_t DwarfVersion;
1750
- if (auto E = Reader. readInteger (DwarfVersion) )
1751
- return std::move (E );
1742
+ uint16_t DwarfVersion = Extractor. getU16 (Cursor) ;
1743
+ if (!Cursor )
1744
+ return Cursor. takeError ( );
1752
1745
1753
1746
if (DwarfVersion >= 5 ) {
1754
1747
// From Dwarf 5 Section 7.5.1.1:
1755
1748
// Compile Unit Header Format is now changed with unit_type and address_size
1756
1749
// 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 );
1750
+ uint8_t UnitType = Extractor. getU8 (Cursor) ;
1751
+ if (!Cursor )
1752
+ return Cursor. takeError ( );
1760
1753
if (UnitType != dwarf::DW_UT_compile)
1761
1754
return createStringError (
1762
1755
inconvertibleErrorCode (),
1763
1756
" 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 );
1757
+ uint8_t AddressSize = Extractor. getU8 (Cursor) ;
1758
+ if (!Cursor )
1759
+ return Cursor. takeError ( );
1767
1760
if (AddressSize != 8 )
1768
1761
return createStringError (
1769
1762
inconvertibleErrorCode (),
1770
1763
" Address size is not 8 bytes, unsupported architecture for MCCAS!" );
1771
1764
}
1772
1765
1773
1766
// TODO: Handle Dwarf 64 format, which uses 8 bytes.
1774
- size_t AbbrevPosition = Reader. getOffset ();
1775
- uint32_t AbbrevOffset;
1776
- if (auto E = Reader. readInteger (AbbrevOffset) )
1777
- return std::move (E );
1767
+ size_t AbbrevPosition = Cursor. tell ();
1768
+ uint32_t AbbrevOffset = Extractor. getU32 (Cursor) ;
1769
+ if (!Cursor )
1770
+ return Cursor. takeError ( );
1778
1771
1779
1772
if (NewOffset.has_value ()) {
1780
1773
// FIXME: safe but ugly cast. Similar to: llvm::arrayRefFromStringRef.
@@ -1786,11 +1779,8 @@ getAndSetDebugAbbrevOffsetAndSkip(MutableArrayRef<char> CUData,
1786
1779
return std::move (E);
1787
1780
}
1788
1781
1789
- Reader.setOffset (AfterSizeOffset);
1790
- if (auto E = Reader.skip (*Size))
1791
- return std::move (E);
1792
-
1793
- return CUInfo{Reader.getOffset (), AbbrevOffset, DwarfVersion};
1782
+ Cursor.seek (AfterSizeOffset + *Size);
1783
+ return CUInfo{Cursor.tell (), AbbrevOffset, DwarfVersion};
1794
1784
}
1795
1785
1796
1786
// / Given a list of MCFragments, return a vector with the concatenation of their
@@ -3113,14 +3103,15 @@ struct DIEVisitor {
3113
3103
3114
3104
Error visitDIERef (DIEDedupeTopLevelRef Ref);
3115
3105
Error visitDIERef (ArrayRef<DIEDataRef> &DIEChildrenStack);
3116
- Error visitDIEAttrs (BinaryStreamReader &DataReader, StringRef DIEData ,
3117
- ArrayRef<AbbrevContent> DIEContents);
3106
+ Error visitDIEAttrs (DataExtractor &Extractor, DataExtractor::Cursor &Cursor ,
3107
+ StringRef DIEData, ArrayRef<AbbrevContent> DIEContents);
3118
3108
Error materializeAbbrevDIE (unsigned AbbrevIdx);
3119
3109
3120
3110
uint16_t DwarfVersion;
3121
3111
SmallVector<AbbrevEntry> AbbrevEntryCache;
3122
3112
ArrayRef<StringRef> AbbrevEntries;
3123
- BinaryStreamReader DistinctReader;
3113
+ DataExtractor DistinctExtractor;
3114
+ DataExtractor::Cursor DistinctCursor;
3124
3115
StringRef DistinctData;
3125
3116
3126
3117
std::function<void (StringRef)> HeaderCallback;
@@ -3131,7 +3122,8 @@ struct DIEVisitor {
3131
3122
std::function<void (StringRef)> NewBlockCallback;
3132
3123
};
3133
3124
3134
- Error DIEVisitor::visitDIEAttrs (BinaryStreamReader &DataReader,
3125
+ Error DIEVisitor::visitDIEAttrs (DataExtractor &Extractor,
3126
+ DataExtractor::Cursor &Cursor,
3135
3127
StringRef DIEData,
3136
3128
ArrayRef<AbbrevContent> DIEContents) {
3137
3129
constexpr auto IsLittleEndian = true ;
@@ -3141,29 +3133,32 @@ Error DIEVisitor::visitDIEAttrs(BinaryStreamReader &DataReader,
3141
3133
3142
3134
for (auto Contents : DIEContents) {
3143
3135
bool DataInDistinct = Contents.FormInDistinctData ;
3144
- auto &ReaderForData = DataInDistinct ? DistinctReader : DataReader;
3136
+ auto &ExtractorForData = DataInDistinct ? DistinctExtractor : Extractor;
3137
+ auto &CursorForData = DataInDistinct ? DistinctCursor : Cursor;
3145
3138
StringRef DataToUse = DataInDistinct ? DistinctData : DIEData;
3146
3139
Expected<uint64_t > FormSize =
3147
3140
Contents.FormSize
3148
3141
? *Contents.FormSize
3149
3142
: getFormSize (Contents.Form , FormParams, DataToUse,
3150
- ReaderForData. getOffset (), IsLittleEndian, AddrSize);
3143
+ CursorForData. tell (), IsLittleEndian, AddrSize);
3151
3144
if (!FormSize)
3152
3145
return FormSize.takeError ();
3153
3146
3154
- ArrayRef<char > RawBytes;
3155
- if (auto E = ReaderForData.readArray (RawBytes, *FormSize))
3156
- return E;
3157
- AttrCallback (Contents.Attr , Contents.Form , toStringRef (RawBytes),
3158
- DataInDistinct);
3147
+ StringRef RawBytes;
3148
+ if (*FormSize)
3149
+ RawBytes = ExtractorForData.getBytes (CursorForData, *FormSize);
3150
+ if (!CursorForData)
3151
+ return CursorForData.takeError ();
3152
+ AttrCallback (Contents.Attr , Contents.Form , RawBytes, DataInDistinct);
3159
3153
}
3160
3154
return Error::success ();
3161
3155
}
3162
3156
3163
- static Expected<uint64_t > readAbbrevIdx (BinaryStreamReader &Reader) {
3164
- uint64_t Idx;
3165
- if (auto E = Reader.readULEB128 (Idx))
3166
- return std::move (E);
3157
+ static Expected<uint64_t > readAbbrevIdx (DataExtractor &Extractor,
3158
+ DataExtractor::Cursor &Cursor) {
3159
+ uint64_t Idx = Extractor.getULEB128 (Cursor);
3160
+ if (!Cursor)
3161
+ return Cursor.takeError ();
3167
3162
return Idx;
3168
3163
}
3169
3164
@@ -3284,12 +3279,13 @@ Error DIEVisitor::materializeAbbrevDIE(unsigned AbbrevIdx) {
3284
3279
// / implementation of a Depth First Search, and this function is used to
3285
3280
// / simulate a return from a recursive callback, by restoring the locals to a
3286
3281
// / previous stack frame.
3287
- static void popStack (BinaryStreamReader &Reader, StringRef &Data,
3282
+ static void popStack (DataExtractor &Extractor, DataExtractor::Cursor &Cursor,
3283
+ StringRef &Data,
3288
3284
std::stack<std::pair<StringRef, unsigned >> &StackOfNodes) {
3289
3285
auto DataAndOffset = StackOfNodes.top ();
3290
- Reader = BinaryStreamReader (DataAndOffset.first , support::endianness::little );
3286
+ Extractor = DataExtractor (DataAndOffset.first , true , 8 );
3291
3287
Data = DataAndOffset.first ;
3292
- Reader. setOffset (DataAndOffset.second );
3288
+ Cursor. seek (DataAndOffset.second );
3293
3289
StackOfNodes.pop ();
3294
3290
}
3295
3291
@@ -3303,11 +3299,13 @@ Error DIEVisitor::visitDIERef(ArrayRef<DIEDataRef> &DIEChildrenStack) {
3303
3299
std::stack<std::pair<StringRef, unsigned >> StackOfNodes;
3304
3300
auto Data = DIEChildrenStack.empty () ? StringRef ()
3305
3301
: DIEChildrenStack.front ().getData ();
3306
- BinaryStreamReader Reader (Data, support::endianness::little);
3302
+ DataExtractor Extractor (Data, true , 8 );
3303
+ DataExtractor::Cursor Cursor (0 );
3307
3304
3308
- while (!DistinctReader. empty ( )) {
3305
+ while (!DistinctExtractor. eof (DistinctCursor )) {
3309
3306
3310
- Expected<uint64_t > MaybeAbbrevIdx = readAbbrevIdx (DistinctReader);
3307
+ Expected<uint64_t > MaybeAbbrevIdx =
3308
+ readAbbrevIdx (DistinctExtractor, DistinctCursor);
3311
3309
if (!MaybeAbbrevIdx)
3312
3310
return MaybeAbbrevIdx.takeError ();
3313
3311
auto AbbrevIdx = *MaybeAbbrevIdx;
@@ -3317,20 +3315,21 @@ Error DIEVisitor::visitDIERef(ArrayRef<DIEDataRef> &DIEChildrenStack) {
3317
3315
// continue materialization of the parent's siblings that may exist.
3318
3316
if (AbbrevIdx == getEndOfDIESiblingsMarker ()) {
3319
3317
EndTagCallback (true /* HadChildren*/ );
3320
- if (!StackOfNodes.empty () && Reader. empty ( ))
3321
- popStack (Reader , Data, StackOfNodes);
3318
+ if (!StackOfNodes.empty () && Extractor. eof (Cursor ))
3319
+ popStack (Extractor, Cursor , Data, StackOfNodes);
3322
3320
continue ;
3323
3321
}
3324
3322
3325
3323
// If we see a DIEInAnotherBlockMarker, we know that the next DIE is in
3326
3324
// another CAS Block, we have to push the current CAS Object on the stack,
3327
3325
// and materialize the next DIE from the DIEChildrenStack.
3328
3326
if (AbbrevIdx == getDIEInAnotherBlockMarker ()) {
3329
- StackOfNodes.push (std::make_pair (Data, Reader. getOffset ()));
3327
+ StackOfNodes.push (std::make_pair (Data, Cursor. tell ()));
3330
3328
DIEChildrenStack = DIEChildrenStack.drop_front ();
3331
3329
Data = DIEChildrenStack.front ().getData ();
3332
3330
NewBlockCallback (DIEChildrenStack.front ().getID ().toString ());
3333
- Reader = BinaryStreamReader (Data, support::endianness::little);
3331
+ Extractor = DataExtractor (Data, true , 8 );
3332
+ Cursor.seek (0 );
3334
3333
continue ;
3335
3334
}
3336
3335
@@ -3339,16 +3338,16 @@ Error DIEVisitor::visitDIERef(ArrayRef<DIEDataRef> &DIEChildrenStack) {
3339
3338
AbbrevEntryCache[decodeAbbrevIndexAsAbbrevSetIdx (AbbrevIdx)];
3340
3339
StartTagCallback (AbbrevEntryCacheVal.Tag , AbbrevIdx);
3341
3340
3342
- if (auto E =
3343
- visitDIEAttrs (Reader, Data, AbbrevEntryCacheVal.AbbrevContents ))
3341
+ if (auto E = visitDIEAttrs (Extractor, Cursor, Data,
3342
+ AbbrevEntryCacheVal.AbbrevContents ))
3344
3343
return E;
3345
3344
3346
3345
// If the current DIE doesn't have any children, the current CAS Object will
3347
3346
// not contain any more data, pop the stack to continue materializing its
3348
3347
// parent's siblings that may exist.
3349
3348
if (!AbbrevEntryCacheVal.HasChildren ) {
3350
- if (!StackOfNodes.empty () && Reader. empty ( ))
3351
- popStack (Reader , Data, StackOfNodes);
3349
+ if (!StackOfNodes.empty () && Extractor. eof (Cursor ))
3350
+ popStack (Extractor, Cursor , Data, StackOfNodes);
3352
3351
EndTagCallback (false /* HadChildren*/ );
3353
3352
}
3354
3353
}
@@ -3357,8 +3356,9 @@ Error DIEVisitor::visitDIERef(ArrayRef<DIEDataRef> &DIEChildrenStack) {
3357
3356
3358
3357
Error DIEVisitor::visitDIERef (DIEDedupeTopLevelRef StartDIERef) {
3359
3358
3360
- auto Offset = DistinctReader.getOffset ();
3361
- Expected<uint64_t > MaybeAbbrevIdx = readAbbrevIdx (DistinctReader);
3359
+ auto Offset = DistinctCursor.tell ();
3360
+ Expected<uint64_t > MaybeAbbrevIdx =
3361
+ readAbbrevIdx (DistinctExtractor, DistinctCursor);
3362
3362
if (!MaybeAbbrevIdx)
3363
3363
return MaybeAbbrevIdx.takeError ();
3364
3364
auto AbbrevIdx = *MaybeAbbrevIdx;
@@ -3367,7 +3367,7 @@ Error DIEVisitor::visitDIERef(DIEDedupeTopLevelRef StartDIERef) {
3367
3367
assert (AbbrevIdx != getEndOfDIESiblingsMarker () &&
3368
3368
AbbrevIdx != getDIEInAnotherBlockMarker ());
3369
3369
3370
- DistinctReader. setOffset (Offset);
3370
+ DistinctCursor. seek (Offset);
3371
3371
3372
3372
NewBlockCallback (StartDIERef.getID ().toString ());
3373
3373
@@ -3405,34 +3405,36 @@ Error mccasformats::v1::visitDebugInfo(
3405
3405
compression::zlib::decompress (BuffRef, OutBuff, UncompressedSize))
3406
3406
return E;
3407
3407
DistinctData = toStringRef (OutBuff);
3408
- BinaryStreamReader DistinctReader (DistinctData, support::endianness::little);
3409
- #else
3410
- BinaryStreamReader DistinctReader (DistinctData, support::endianness::little);
3411
3408
#endif
3412
- ArrayRef<char > HeaderData;
3409
+ DataExtractor DistinctExtractor (DistinctData, true , 8 );
3410
+ DataExtractor::Cursor DistinctCursor (0 );
3413
3411
3414
- auto BeginOffset = DistinctReader.getOffset ();
3415
- auto Size = getSizeFromDwarfHeader (DistinctReader);
3412
+ auto Size = getSizeFromDwarfHeader (DistinctExtractor, DistinctCursor);
3416
3413
if (!Size)
3417
3414
return Size.takeError ();
3418
3415
3419
3416
// 2-byte Dwarf version identifier.
3420
- uint16_t DwarfVersion;
3421
- if (auto E = DistinctReader.readInteger (DwarfVersion))
3422
- return E;
3423
-
3424
- DistinctReader.setOffset (BeginOffset);
3417
+ uint16_t DwarfVersion = DistinctExtractor.getU16 (DistinctCursor);
3418
+ DistinctCursor.seek (0 );
3425
3419
3426
- if (auto E = DistinctReader.readArray (
3427
- HeaderData,
3428
- DwarfVersion >= 5 ? Dwarf5HeaderSize32Bit : Dwarf4HeaderSize32Bit))
3429
- return E;
3430
- HeaderCallback (toStringRef (HeaderData));
3420
+ StringRef HeaderData = DistinctExtractor.getBytes (
3421
+ DistinctCursor,
3422
+ DwarfVersion >= 5 ? Dwarf5HeaderSize32Bit : Dwarf4HeaderSize32Bit);
3423
+ if (!DistinctCursor)
3424
+ return DistinctCursor.takeError ();
3425
+ HeaderCallback (HeaderData);
3431
3426
3432
3427
append_range (TotAbbrevEntries, LoadedTopRef->AbbrevEntries );
3433
- DIEVisitor Visitor{DwarfVersion, {}, TotAbbrevEntries,
3434
- DistinctReader, DistinctData, HeaderCallback,
3435
- StartTagCallback, AttrCallback, EndTagCallback,
3428
+ DIEVisitor Visitor{DwarfVersion,
3429
+ {},
3430
+ TotAbbrevEntries,
3431
+ DistinctExtractor,
3432
+ DataExtractor::Cursor (DistinctCursor.tell ()),
3433
+ DistinctData,
3434
+ HeaderCallback,
3435
+ StartTagCallback,
3436
+ AttrCallback,
3437
+ EndTagCallback,
3436
3438
NewBlockCallback};
3437
3439
return Visitor.visitDIERef (LoadedTopRef->RootDIE );
3438
3440
}
0 commit comments