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