1 //===- CoverageMappingReader.cpp - Code coverage mapping reader -----------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file contains support for reading coverage mapping data for
10 // instrumentation based coverage.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/ProfileData/Coverage/CoverageMappingReader.h"
15 #include "llvm/ADT/ArrayRef.h"
16 #include "llvm/ADT/DenseMap.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/ADT/Triple.h"
21 #include "llvm/Object/Binary.h"
22 #include "llvm/Object/Error.h"
23 #include "llvm/Object/MachOUniversal.h"
24 #include "llvm/Object/ObjectFile.h"
25 #include "llvm/Object/COFF.h"
26 #include "llvm/ProfileData/InstrProf.h"
27 #include "llvm/Support/Casting.h"
28 #include "llvm/Support/Debug.h"
29 #include "llvm/Support/Endian.h"
30 #include "llvm/Support/Error.h"
31 #include "llvm/Support/ErrorHandling.h"
32 #include "llvm/Support/LEB128.h"
33 #include "llvm/Support/MathExtras.h"
34 #include "llvm/Support/raw_ostream.h"
38 using namespace coverage
;
39 using namespace object
;
41 #define DEBUG_TYPE "coverage-mapping"
43 void CoverageMappingIterator::increment() {
44 if (ReadErr
!= coveragemap_error::success
)
47 // Check if all the records were read or if an error occurred while reading
49 if (auto E
= Reader
->readNextRecord(Record
))
50 handleAllErrors(std::move(E
), [&](const CoverageMapError
&CME
) {
51 if (CME
.get() == coveragemap_error::eof
)
52 *this = CoverageMappingIterator();
58 Error
RawCoverageReader::readULEB128(uint64_t &Result
) {
60 return make_error
<CoverageMapError
>(coveragemap_error::truncated
);
62 Result
= decodeULEB128(Data
.bytes_begin(), &N
);
64 return make_error
<CoverageMapError
>(coveragemap_error::malformed
);
65 Data
= Data
.substr(N
);
66 return Error::success();
69 Error
RawCoverageReader::readIntMax(uint64_t &Result
, uint64_t MaxPlus1
) {
70 if (auto Err
= readULEB128(Result
))
72 if (Result
>= MaxPlus1
)
73 return make_error
<CoverageMapError
>(coveragemap_error::malformed
);
74 return Error::success();
77 Error
RawCoverageReader::readSize(uint64_t &Result
) {
78 if (auto Err
= readULEB128(Result
))
80 // Sanity check the number.
81 if (Result
> Data
.size())
82 return make_error
<CoverageMapError
>(coveragemap_error::malformed
);
83 return Error::success();
86 Error
RawCoverageReader::readString(StringRef
&Result
) {
88 if (auto Err
= readSize(Length
))
90 Result
= Data
.substr(0, Length
);
91 Data
= Data
.substr(Length
);
92 return Error::success();
95 Error
RawCoverageFilenamesReader::read() {
96 uint64_t NumFilenames
;
97 if (auto Err
= readSize(NumFilenames
))
99 for (size_t I
= 0; I
< NumFilenames
; ++I
) {
101 if (auto Err
= readString(Filename
))
103 Filenames
.push_back(Filename
);
105 return Error::success();
108 Error
RawCoverageMappingReader::decodeCounter(unsigned Value
, Counter
&C
) {
109 auto Tag
= Value
& Counter::EncodingTagMask
;
112 C
= Counter::getZero();
113 return Error::success();
114 case Counter::CounterValueReference
:
115 C
= Counter::getCounter(Value
>> Counter::EncodingTagBits
);
116 return Error::success();
120 Tag
-= Counter::Expression
;
122 case CounterExpression::Subtract
:
123 case CounterExpression::Add
: {
124 auto ID
= Value
>> Counter::EncodingTagBits
;
125 if (ID
>= Expressions
.size())
126 return make_error
<CoverageMapError
>(coveragemap_error::malformed
);
127 Expressions
[ID
].Kind
= CounterExpression::ExprKind(Tag
);
128 C
= Counter::getExpression(ID
);
132 return make_error
<CoverageMapError
>(coveragemap_error::malformed
);
134 return Error::success();
137 Error
RawCoverageMappingReader::readCounter(Counter
&C
) {
138 uint64_t EncodedCounter
;
140 readIntMax(EncodedCounter
, std::numeric_limits
<unsigned>::max()))
142 if (auto Err
= decodeCounter(EncodedCounter
, C
))
144 return Error::success();
147 static const unsigned EncodingExpansionRegionBit
= 1
148 << Counter::EncodingTagBits
;
150 /// Read the sub-array of regions for the given inferred file id.
151 /// \param NumFileIDs the number of file ids that are defined for this
153 Error
RawCoverageMappingReader::readMappingRegionsSubArray(
154 std::vector
<CounterMappingRegion
> &MappingRegions
, unsigned InferredFileID
,
157 if (auto Err
= readSize(NumRegions
))
159 unsigned LineStart
= 0;
160 for (size_t I
= 0; I
< NumRegions
; ++I
) {
162 CounterMappingRegion::RegionKind Kind
= CounterMappingRegion::CodeRegion
;
164 // Read the combined counter + region kind.
165 uint64_t EncodedCounterAndRegion
;
166 if (auto Err
= readIntMax(EncodedCounterAndRegion
,
167 std::numeric_limits
<unsigned>::max()))
169 unsigned Tag
= EncodedCounterAndRegion
& Counter::EncodingTagMask
;
170 uint64_t ExpandedFileID
= 0;
171 if (Tag
!= Counter::Zero
) {
172 if (auto Err
= decodeCounter(EncodedCounterAndRegion
, C
))
175 // Is it an expansion region?
176 if (EncodedCounterAndRegion
& EncodingExpansionRegionBit
) {
177 Kind
= CounterMappingRegion::ExpansionRegion
;
178 ExpandedFileID
= EncodedCounterAndRegion
>>
179 Counter::EncodingCounterTagAndExpansionRegionTagBits
;
180 if (ExpandedFileID
>= NumFileIDs
)
181 return make_error
<CoverageMapError
>(coveragemap_error::malformed
);
183 switch (EncodedCounterAndRegion
>>
184 Counter::EncodingCounterTagAndExpansionRegionTagBits
) {
185 case CounterMappingRegion::CodeRegion
:
186 // Don't do anything when we have a code region with a zero counter.
188 case CounterMappingRegion::SkippedRegion
:
189 Kind
= CounterMappingRegion::SkippedRegion
;
192 return make_error
<CoverageMapError
>(coveragemap_error::malformed
);
197 // Read the source range.
198 uint64_t LineStartDelta
, ColumnStart
, NumLines
, ColumnEnd
;
200 readIntMax(LineStartDelta
, std::numeric_limits
<unsigned>::max()))
202 if (auto Err
= readULEB128(ColumnStart
))
204 if (ColumnStart
> std::numeric_limits
<unsigned>::max())
205 return make_error
<CoverageMapError
>(coveragemap_error::malformed
);
206 if (auto Err
= readIntMax(NumLines
, std::numeric_limits
<unsigned>::max()))
208 if (auto Err
= readIntMax(ColumnEnd
, std::numeric_limits
<unsigned>::max()))
210 LineStart
+= LineStartDelta
;
212 // If the high bit of ColumnEnd is set, this is a gap region.
213 if (ColumnEnd
& (1U << 31)) {
214 Kind
= CounterMappingRegion::GapRegion
;
215 ColumnEnd
&= ~(1U << 31);
218 // Adjust the column locations for the empty regions that are supposed to
219 // cover whole lines. Those regions should be encoded with the
220 // column range (1 -> std::numeric_limits<unsigned>::max()), but because
221 // the encoded std::numeric_limits<unsigned>::max() is several bytes long,
222 // we set the column range to (0 -> 0) to ensure that the column start and
223 // column end take up one byte each.
224 // The std::numeric_limits<unsigned>::max() is used to represent a column
225 // position at the end of the line without knowing the length of that line.
226 if (ColumnStart
== 0 && ColumnEnd
== 0) {
228 ColumnEnd
= std::numeric_limits
<unsigned>::max();
232 dbgs() << "Counter in file " << InferredFileID
<< " " << LineStart
<< ":"
233 << ColumnStart
<< " -> " << (LineStart
+ NumLines
) << ":"
234 << ColumnEnd
<< ", ";
235 if (Kind
== CounterMappingRegion::ExpansionRegion
)
236 dbgs() << "Expands to file " << ExpandedFileID
;
238 CounterMappingContext(Expressions
).dump(C
, dbgs());
242 auto CMR
= CounterMappingRegion(C
, InferredFileID
, ExpandedFileID
,
243 LineStart
, ColumnStart
,
244 LineStart
+ NumLines
, ColumnEnd
, Kind
);
245 if (CMR
.startLoc() > CMR
.endLoc())
246 return make_error
<CoverageMapError
>(coveragemap_error::malformed
);
247 MappingRegions
.push_back(CMR
);
249 return Error::success();
252 Error
RawCoverageMappingReader::read() {
253 // Read the virtual file mapping.
254 SmallVector
<unsigned, 8> VirtualFileMapping
;
255 uint64_t NumFileMappings
;
256 if (auto Err
= readSize(NumFileMappings
))
258 for (size_t I
= 0; I
< NumFileMappings
; ++I
) {
259 uint64_t FilenameIndex
;
260 if (auto Err
= readIntMax(FilenameIndex
, TranslationUnitFilenames
.size()))
262 VirtualFileMapping
.push_back(FilenameIndex
);
265 // Construct the files using unique filenames and virtual file mapping.
266 for (auto I
: VirtualFileMapping
) {
267 Filenames
.push_back(TranslationUnitFilenames
[I
]);
270 // Read the expressions.
271 uint64_t NumExpressions
;
272 if (auto Err
= readSize(NumExpressions
))
274 // Create an array of dummy expressions that get the proper counters
275 // when the expressions are read, and the proper kinds when the counters
279 CounterExpression(CounterExpression::Subtract
, Counter(), Counter()));
280 for (size_t I
= 0; I
< NumExpressions
; ++I
) {
281 if (auto Err
= readCounter(Expressions
[I
].LHS
))
283 if (auto Err
= readCounter(Expressions
[I
].RHS
))
287 // Read the mapping regions sub-arrays.
288 for (unsigned InferredFileID
= 0, S
= VirtualFileMapping
.size();
289 InferredFileID
< S
; ++InferredFileID
) {
290 if (auto Err
= readMappingRegionsSubArray(MappingRegions
, InferredFileID
,
291 VirtualFileMapping
.size()))
295 // Set the counters for the expansion regions.
296 // i.e. Counter of expansion region = counter of the first region
297 // from the expanded file.
298 // Perform multiple passes to correctly propagate the counters through
299 // all the nested expansion regions.
300 SmallVector
<CounterMappingRegion
*, 8> FileIDExpansionRegionMapping
;
301 FileIDExpansionRegionMapping
.resize(VirtualFileMapping
.size(), nullptr);
302 for (unsigned Pass
= 1, S
= VirtualFileMapping
.size(); Pass
< S
; ++Pass
) {
303 for (auto &R
: MappingRegions
) {
304 if (R
.Kind
!= CounterMappingRegion::ExpansionRegion
)
306 assert(!FileIDExpansionRegionMapping
[R
.ExpandedFileID
]);
307 FileIDExpansionRegionMapping
[R
.ExpandedFileID
] = &R
;
309 for (auto &R
: MappingRegions
) {
310 if (FileIDExpansionRegionMapping
[R
.FileID
]) {
311 FileIDExpansionRegionMapping
[R
.FileID
]->Count
= R
.Count
;
312 FileIDExpansionRegionMapping
[R
.FileID
] = nullptr;
317 return Error::success();
320 Expected
<bool> RawCoverageMappingDummyChecker::isDummy() {
321 // A dummy coverage mapping data consists of just one region with zero count.
322 uint64_t NumFileMappings
;
323 if (Error Err
= readSize(NumFileMappings
))
324 return std::move(Err
);
325 if (NumFileMappings
!= 1)
327 // We don't expect any specific value for the filename index, just skip it.
328 uint64_t FilenameIndex
;
330 readIntMax(FilenameIndex
, std::numeric_limits
<unsigned>::max()))
331 return std::move(Err
);
332 uint64_t NumExpressions
;
333 if (Error Err
= readSize(NumExpressions
))
334 return std::move(Err
);
335 if (NumExpressions
!= 0)
338 if (Error Err
= readSize(NumRegions
))
339 return std::move(Err
);
342 uint64_t EncodedCounterAndRegion
;
343 if (Error Err
= readIntMax(EncodedCounterAndRegion
,
344 std::numeric_limits
<unsigned>::max()))
345 return std::move(Err
);
346 unsigned Tag
= EncodedCounterAndRegion
& Counter::EncodingTagMask
;
347 return Tag
== Counter::Zero
;
350 Error
InstrProfSymtab::create(SectionRef
&Section
) {
351 Expected
<StringRef
> DataOrErr
= Section
.getContents();
353 return DataOrErr
.takeError();
355 Address
= Section
.getAddress();
357 // If this is a linked PE/COFF file, then we have to skip over the null byte
358 // that is allocated in the .lprfn$A section in the LLVM profiling runtime.
359 const ObjectFile
*Obj
= Section
.getObject();
360 if (isa
<COFFObjectFile
>(Obj
) && !Obj
->isRelocatableObject())
361 Data
= Data
.drop_front(1);
363 return Error::success();
366 StringRef
InstrProfSymtab::getFuncName(uint64_t Pointer
, size_t Size
) {
367 if (Pointer
< Address
)
369 auto Offset
= Pointer
- Address
;
370 if (Offset
+ Size
> Data
.size())
372 return Data
.substr(Pointer
- Address
, Size
);
375 // Check if the mapping data is a dummy, i.e. is emitted for an unused function.
376 static Expected
<bool> isCoverageMappingDummy(uint64_t Hash
, StringRef Mapping
) {
377 // The hash value of dummy mapping records is always zero.
380 return RawCoverageMappingDummyChecker(Mapping
).isDummy();
385 struct CovMapFuncRecordReader
{
386 virtual ~CovMapFuncRecordReader() = default;
388 // The interface to read coverage mapping function records for a module.
390 // \p Buf points to the buffer containing the \c CovHeader of the coverage
391 // mapping data associated with the module.
393 // Returns a pointer to the next \c CovHeader if it exists, or a pointer
394 // greater than \p End if not.
395 virtual Expected
<const char *> readFunctionRecords(const char *Buf
,
396 const char *End
) = 0;
398 template <class IntPtrT
, support::endianness Endian
>
399 static Expected
<std::unique_ptr
<CovMapFuncRecordReader
>>
400 get(CovMapVersion Version
, InstrProfSymtab
&P
,
401 std::vector
<BinaryCoverageReader::ProfileMappingRecord
> &R
,
402 std::vector
<StringRef
> &F
);
405 // A class for reading coverage mapping function records for a module.
406 template <CovMapVersion Version
, class IntPtrT
, support::endianness Endian
>
407 class VersionedCovMapFuncRecordReader
: public CovMapFuncRecordReader
{
408 using FuncRecordType
=
409 typename CovMapTraits
<Version
, IntPtrT
>::CovMapFuncRecordType
;
410 using NameRefType
= typename CovMapTraits
<Version
, IntPtrT
>::NameRefType
;
412 // Maps function's name references to the indexes of their records
414 DenseMap
<NameRefType
, size_t> FunctionRecords
;
415 InstrProfSymtab
&ProfileNames
;
416 std::vector
<StringRef
> &Filenames
;
417 std::vector
<BinaryCoverageReader::ProfileMappingRecord
> &Records
;
419 // Add the record to the collection if we don't already have a record that
420 // points to the same function name. This is useful to ignore the redundant
421 // records for the functions with ODR linkage.
422 // In addition, prefer records with real coverage mapping data to dummy
423 // records, which were emitted for inline functions which were seen but
424 // not used in the corresponding translation unit.
425 Error
insertFunctionRecordIfNeeded(const FuncRecordType
*CFR
,
426 StringRef Mapping
, size_t FilenamesBegin
) {
427 uint64_t FuncHash
= CFR
->template getFuncHash
<Endian
>();
428 NameRefType NameRef
= CFR
->template getFuncNameRef
<Endian
>();
430 FunctionRecords
.insert(std::make_pair(NameRef
, Records
.size()));
431 if (InsertResult
.second
) {
433 if (Error Err
= CFR
->template getFuncName
<Endian
>(ProfileNames
, FuncName
))
435 if (FuncName
.empty())
436 return make_error
<InstrProfError
>(instrprof_error::malformed
);
437 Records
.emplace_back(Version
, FuncName
, FuncHash
, Mapping
, FilenamesBegin
,
438 Filenames
.size() - FilenamesBegin
);
439 return Error::success();
441 // Update the existing record if it's a dummy and the new record is real.
442 size_t OldRecordIndex
= InsertResult
.first
->second
;
443 BinaryCoverageReader::ProfileMappingRecord
&OldRecord
=
444 Records
[OldRecordIndex
];
445 Expected
<bool> OldIsDummyExpected
= isCoverageMappingDummy(
446 OldRecord
.FunctionHash
, OldRecord
.CoverageMapping
);
447 if (Error Err
= OldIsDummyExpected
.takeError())
449 if (!*OldIsDummyExpected
)
450 return Error::success();
451 Expected
<bool> NewIsDummyExpected
=
452 isCoverageMappingDummy(FuncHash
, Mapping
);
453 if (Error Err
= NewIsDummyExpected
.takeError())
455 if (*NewIsDummyExpected
)
456 return Error::success();
457 OldRecord
.FunctionHash
= FuncHash
;
458 OldRecord
.CoverageMapping
= Mapping
;
459 OldRecord
.FilenamesBegin
= FilenamesBegin
;
460 OldRecord
.FilenamesSize
= Filenames
.size() - FilenamesBegin
;
461 return Error::success();
465 VersionedCovMapFuncRecordReader(
467 std::vector
<BinaryCoverageReader::ProfileMappingRecord
> &R
,
468 std::vector
<StringRef
> &F
)
469 : ProfileNames(P
), Filenames(F
), Records(R
) {}
471 ~VersionedCovMapFuncRecordReader() override
= default;
473 Expected
<const char *> readFunctionRecords(const char *Buf
,
474 const char *End
) override
{
475 using namespace support
;
477 if (Buf
+ sizeof(CovMapHeader
) > End
)
478 return make_error
<CoverageMapError
>(coveragemap_error::malformed
);
479 auto CovHeader
= reinterpret_cast<const CovMapHeader
*>(Buf
);
480 uint32_t NRecords
= CovHeader
->getNRecords
<Endian
>();
481 uint32_t FilenamesSize
= CovHeader
->getFilenamesSize
<Endian
>();
482 uint32_t CoverageSize
= CovHeader
->getCoverageSize
<Endian
>();
483 assert((CovMapVersion
)CovHeader
->getVersion
<Endian
>() == Version
);
484 Buf
= reinterpret_cast<const char *>(CovHeader
+ 1);
486 // Skip past the function records, saving the start and end for later.
487 const char *FunBuf
= Buf
;
488 Buf
+= NRecords
* sizeof(FuncRecordType
);
489 const char *FunEnd
= Buf
;
491 // Get the filenames.
492 if (Buf
+ FilenamesSize
> End
)
493 return make_error
<CoverageMapError
>(coveragemap_error::malformed
);
494 size_t FilenamesBegin
= Filenames
.size();
495 RawCoverageFilenamesReader
Reader(StringRef(Buf
, FilenamesSize
), Filenames
);
496 if (auto Err
= Reader
.read())
497 return std::move(Err
);
498 Buf
+= FilenamesSize
;
500 // We'll read the coverage mapping records in the loop below.
501 const char *CovBuf
= Buf
;
503 const char *CovEnd
= Buf
;
506 return make_error
<CoverageMapError
>(coveragemap_error::malformed
);
507 // Each coverage map has an alignment of 8, so we need to adjust alignment
508 // before reading the next map.
509 Buf
+= offsetToAlignedAddr(Buf
, Align(8));
511 auto CFR
= reinterpret_cast<const FuncRecordType
*>(FunBuf
);
512 while ((const char *)CFR
< FunEnd
) {
513 // Read the function information
514 uint32_t DataSize
= CFR
->template getDataSize
<Endian
>();
516 // Now use that to read the coverage data.
517 if (CovBuf
+ DataSize
> CovEnd
)
518 return make_error
<CoverageMapError
>(coveragemap_error::malformed
);
519 auto Mapping
= StringRef(CovBuf
, DataSize
);
523 insertFunctionRecordIfNeeded(CFR
, Mapping
, FilenamesBegin
))
524 return std::move(Err
);
531 } // end anonymous namespace
533 template <class IntPtrT
, support::endianness Endian
>
534 Expected
<std::unique_ptr
<CovMapFuncRecordReader
>> CovMapFuncRecordReader::get(
535 CovMapVersion Version
, InstrProfSymtab
&P
,
536 std::vector
<BinaryCoverageReader::ProfileMappingRecord
> &R
,
537 std::vector
<StringRef
> &F
) {
538 using namespace coverage
;
541 case CovMapVersion::Version1
:
542 return std::make_unique
<VersionedCovMapFuncRecordReader
<
543 CovMapVersion::Version1
, IntPtrT
, Endian
>>(P
, R
, F
);
544 case CovMapVersion::Version2
:
545 case CovMapVersion::Version3
:
546 // Decompress the name data.
547 if (Error E
= P
.create(P
.getNameData()))
549 if (Version
== CovMapVersion::Version2
)
550 return std::make_unique
<VersionedCovMapFuncRecordReader
<
551 CovMapVersion::Version2
, IntPtrT
, Endian
>>(P
, R
, F
);
553 return std::make_unique
<VersionedCovMapFuncRecordReader
<
554 CovMapVersion::Version3
, IntPtrT
, Endian
>>(P
, R
, F
);
556 llvm_unreachable("Unsupported version");
559 template <typename T
, support::endianness Endian
>
560 static Error
readCoverageMappingData(
561 InstrProfSymtab
&ProfileNames
, StringRef Data
,
562 std::vector
<BinaryCoverageReader::ProfileMappingRecord
> &Records
,
563 std::vector
<StringRef
> &Filenames
) {
564 using namespace coverage
;
566 // Read the records in the coverage data section.
568 reinterpret_cast<const CovMapHeader
*>(Data
.data());
569 CovMapVersion Version
= (CovMapVersion
)CovHeader
->getVersion
<Endian
>();
570 if (Version
> CovMapVersion::CurrentVersion
)
571 return make_error
<CoverageMapError
>(coveragemap_error::unsupported_version
);
572 Expected
<std::unique_ptr
<CovMapFuncRecordReader
>> ReaderExpected
=
573 CovMapFuncRecordReader::get
<T
, Endian
>(Version
, ProfileNames
, Records
,
575 if (Error E
= ReaderExpected
.takeError())
577 auto Reader
= std::move(ReaderExpected
.get());
578 for (const char *Buf
= Data
.data(), *End
= Buf
+ Data
.size(); Buf
< End
;) {
579 auto NextHeaderOrErr
= Reader
->readFunctionRecords(Buf
, End
);
580 if (auto E
= NextHeaderOrErr
.takeError())
582 Buf
= NextHeaderOrErr
.get();
584 return Error::success();
587 static const char *TestingFormatMagic
= "llvmcovmtestdata";
589 Expected
<std::unique_ptr
<BinaryCoverageReader
>>
590 BinaryCoverageReader::createCoverageReaderFromBuffer(
591 StringRef Coverage
, InstrProfSymtab
&&ProfileNames
, uint8_t BytesInAddress
,
592 support::endianness Endian
) {
593 std::unique_ptr
<BinaryCoverageReader
> Reader(new BinaryCoverageReader());
594 Reader
->ProfileNames
= std::move(ProfileNames
);
595 if (BytesInAddress
== 4 && Endian
== support::endianness::little
) {
597 readCoverageMappingData
<uint32_t, support::endianness::little
>(
598 Reader
->ProfileNames
, Coverage
, Reader
->MappingRecords
,
601 } else if (BytesInAddress
== 4 && Endian
== support::endianness::big
) {
602 if (Error E
= readCoverageMappingData
<uint32_t, support::endianness::big
>(
603 Reader
->ProfileNames
, Coverage
, Reader
->MappingRecords
,
606 } else if (BytesInAddress
== 8 && Endian
== support::endianness::little
) {
608 readCoverageMappingData
<uint64_t, support::endianness::little
>(
609 Reader
->ProfileNames
, Coverage
, Reader
->MappingRecords
,
612 } else if (BytesInAddress
== 8 && Endian
== support::endianness::big
) {
613 if (Error E
= readCoverageMappingData
<uint64_t, support::endianness::big
>(
614 Reader
->ProfileNames
, Coverage
, Reader
->MappingRecords
,
618 return make_error
<CoverageMapError
>(coveragemap_error::malformed
);
619 return std::move(Reader
);
622 static Expected
<std::unique_ptr
<BinaryCoverageReader
>>
623 loadTestingFormat(StringRef Data
) {
624 uint8_t BytesInAddress
= 8;
625 support::endianness Endian
= support::endianness::little
;
627 Data
= Data
.substr(StringRef(TestingFormatMagic
).size());
629 return make_error
<CoverageMapError
>(coveragemap_error::truncated
);
631 uint64_t ProfileNamesSize
= decodeULEB128(Data
.bytes_begin(), &N
);
633 return make_error
<CoverageMapError
>(coveragemap_error::malformed
);
634 Data
= Data
.substr(N
);
636 return make_error
<CoverageMapError
>(coveragemap_error::truncated
);
638 uint64_t Address
= decodeULEB128(Data
.bytes_begin(), &N
);
640 return make_error
<CoverageMapError
>(coveragemap_error::malformed
);
641 Data
= Data
.substr(N
);
642 if (Data
.size() < ProfileNamesSize
)
643 return make_error
<CoverageMapError
>(coveragemap_error::malformed
);
644 InstrProfSymtab ProfileNames
;
645 if (Error E
= ProfileNames
.create(Data
.substr(0, ProfileNamesSize
), Address
))
647 StringRef CoverageMapping
= Data
.substr(ProfileNamesSize
);
648 // Skip the padding bytes because coverage map data has an alignment of 8.
649 if (CoverageMapping
.empty())
650 return make_error
<CoverageMapError
>(coveragemap_error::truncated
);
651 size_t Pad
= offsetToAlignedAddr(CoverageMapping
.data(), Align(8));
652 if (CoverageMapping
.size() < Pad
)
653 return make_error
<CoverageMapError
>(coveragemap_error::malformed
);
654 CoverageMapping
= CoverageMapping
.substr(Pad
);
655 return BinaryCoverageReader::createCoverageReaderFromBuffer(
656 CoverageMapping
, std::move(ProfileNames
), BytesInAddress
, Endian
);
659 static Expected
<SectionRef
> lookupSection(ObjectFile
&OF
, StringRef Name
) {
660 // On COFF, the object file section name may end in "$M". This tells the
661 // linker to sort these sections between "$A" and "$Z". The linker removes the
662 // dollar and everything after it in the final binary. Do the same to match.
663 bool IsCOFF
= isa
<COFFObjectFile
>(OF
);
664 auto stripSuffix
= [IsCOFF
](StringRef N
) {
665 return IsCOFF
? N
.split('$').first
: N
;
667 Name
= stripSuffix(Name
);
669 for (const auto &Section
: OF
.sections()) {
670 Expected
<StringRef
> NameOrErr
= Section
.getName();
672 return NameOrErr
.takeError();
673 if (stripSuffix(*NameOrErr
) == Name
)
676 return make_error
<CoverageMapError
>(coveragemap_error::no_data_found
);
679 static Expected
<std::unique_ptr
<BinaryCoverageReader
>>
680 loadBinaryFormat(std::unique_ptr
<Binary
> Bin
, StringRef Arch
) {
681 std::unique_ptr
<ObjectFile
> OF
;
682 if (auto *Universal
= dyn_cast
<MachOUniversalBinary
>(Bin
.get())) {
683 // If we have a universal binary, try to look up the object for the
684 // appropriate architecture.
685 auto ObjectFileOrErr
= Universal
->getMachOObjectForArch(Arch
);
686 if (!ObjectFileOrErr
)
687 return ObjectFileOrErr
.takeError();
688 OF
= std::move(ObjectFileOrErr
.get());
689 } else if (isa
<ObjectFile
>(Bin
.get())) {
690 // For any other object file, upcast and take ownership.
691 OF
.reset(cast
<ObjectFile
>(Bin
.release()));
692 // If we've asked for a particular arch, make sure they match.
693 if (!Arch
.empty() && OF
->getArch() != Triple(Arch
).getArch())
694 return errorCodeToError(object_error::arch_not_found
);
696 // We can only handle object files.
697 return make_error
<CoverageMapError
>(coveragemap_error::malformed
);
699 // The coverage uses native pointer sizes for the object it's written in.
700 uint8_t BytesInAddress
= OF
->getBytesInAddress();
701 support::endianness Endian
= OF
->isLittleEndian()
702 ? support::endianness::little
703 : support::endianness::big
;
705 // Look for the sections that we are interested in.
706 auto ObjFormat
= OF
->getTripleObjectFormat();
708 lookupSection(*OF
, getInstrProfSectionName(IPSK_name
, ObjFormat
,
709 /*AddSegmentInfo=*/false));
710 if (auto E
= NamesSection
.takeError())
712 auto CoverageSection
=
713 lookupSection(*OF
, getInstrProfSectionName(IPSK_covmap
, ObjFormat
,
714 /*AddSegmentInfo=*/false));
715 if (auto E
= CoverageSection
.takeError())
718 // Get the contents of the given sections.
719 auto CoverageMappingOrErr
= CoverageSection
->getContents();
720 if (!CoverageMappingOrErr
)
721 return CoverageMappingOrErr
.takeError();
723 InstrProfSymtab ProfileNames
;
724 if (Error E
= ProfileNames
.create(*NamesSection
))
727 return BinaryCoverageReader::createCoverageReaderFromBuffer(
728 CoverageMappingOrErr
.get(), std::move(ProfileNames
), BytesInAddress
,
732 Expected
<std::vector
<std::unique_ptr
<BinaryCoverageReader
>>>
733 BinaryCoverageReader::create(
734 MemoryBufferRef ObjectBuffer
, StringRef Arch
,
735 SmallVectorImpl
<std::unique_ptr
<MemoryBuffer
>> &ObjectFileBuffers
) {
736 std::vector
<std::unique_ptr
<BinaryCoverageReader
>> Readers
;
738 if (ObjectBuffer
.getBuffer().startswith(TestingFormatMagic
)) {
739 // This is a special format used for testing.
740 auto ReaderOrErr
= loadTestingFormat(ObjectBuffer
.getBuffer());
742 return ReaderOrErr
.takeError();
743 Readers
.push_back(std::move(ReaderOrErr
.get()));
744 return std::move(Readers
);
747 auto BinOrErr
= createBinary(ObjectBuffer
);
749 return BinOrErr
.takeError();
750 std::unique_ptr
<Binary
> Bin
= std::move(BinOrErr
.get());
752 // MachO universal binaries which contain archives need to be treated as
753 // archives, not as regular binaries.
754 if (auto *Universal
= dyn_cast
<MachOUniversalBinary
>(Bin
.get())) {
755 for (auto &ObjForArch
: Universal
->objects()) {
756 // Skip slices within the universal binary which target the wrong arch.
757 std::string ObjArch
= ObjForArch
.getArchFlagName();
761 auto ArchiveOrErr
= ObjForArch
.getAsArchive();
763 // If this is not an archive, try treating it as a regular object.
764 consumeError(ArchiveOrErr
.takeError());
768 return BinaryCoverageReader::create(
769 ArchiveOrErr
.get()->getMemoryBufferRef(), Arch
, ObjectFileBuffers
);
773 // Load coverage out of archive members.
774 if (auto *Ar
= dyn_cast
<Archive
>(Bin
.get())) {
775 Error Err
= Error::success();
776 for (auto &Child
: Ar
->children(Err
)) {
777 Expected
<MemoryBufferRef
> ChildBufOrErr
= Child
.getMemoryBufferRef();
779 return ChildBufOrErr
.takeError();
781 auto ChildReadersOrErr
= BinaryCoverageReader::create(
782 ChildBufOrErr
.get(), Arch
, ObjectFileBuffers
);
783 if (!ChildReadersOrErr
)
784 return ChildReadersOrErr
.takeError();
785 for (auto &Reader
: ChildReadersOrErr
.get())
786 Readers
.push_back(std::move(Reader
));
789 return std::move(Err
);
791 // Thin archives reference object files outside of the archive file, i.e.
792 // files which reside in memory not owned by the caller. Transfer ownership
795 for (auto &Buffer
: Ar
->takeThinBuffers())
796 ObjectFileBuffers
.push_back(std::move(Buffer
));
798 return std::move(Readers
);
801 auto ReaderOrErr
= loadBinaryFormat(std::move(Bin
), Arch
);
803 return ReaderOrErr
.takeError();
804 Readers
.push_back(std::move(ReaderOrErr
.get()));
805 return std::move(Readers
);
808 Error
BinaryCoverageReader::readNextRecord(CoverageMappingRecord
&Record
) {
809 if (CurrentRecord
>= MappingRecords
.size())
810 return make_error
<CoverageMapError
>(coveragemap_error::eof
);
812 FunctionsFilenames
.clear();
814 MappingRegions
.clear();
815 auto &R
= MappingRecords
[CurrentRecord
];
816 RawCoverageMappingReader
Reader(
818 makeArrayRef(Filenames
).slice(R
.FilenamesBegin
, R
.FilenamesSize
),
819 FunctionsFilenames
, Expressions
, MappingRegions
);
820 if (auto Err
= Reader
.read())
823 Record
.FunctionName
= R
.FunctionName
;
824 Record
.FunctionHash
= R
.FunctionHash
;
825 Record
.Filenames
= FunctionsFilenames
;
826 Record
.Expressions
= Expressions
;
827 Record
.MappingRegions
= MappingRegions
;
830 return Error::success();