[RISCV] Fix mgather -> riscv.masked.strided.load combine not extending indices (...
[llvm-project.git] / llvm / lib / ProfileData / Coverage / CoverageMappingReader.cpp
blobac8e6b56379f213fb740b8babf4b48175649ec61
1 //===- CoverageMappingReader.cpp - Code coverage mapping reader -----------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
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/Statistic.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/Object/Archive.h"
22 #include "llvm/Object/Binary.h"
23 #include "llvm/Object/COFF.h"
24 #include "llvm/Object/Error.h"
25 #include "llvm/Object/MachOUniversal.h"
26 #include "llvm/Object/ObjectFile.h"
27 #include "llvm/ProfileData/InstrProf.h"
28 #include "llvm/Support/Casting.h"
29 #include "llvm/Support/Compression.h"
30 #include "llvm/Support/Debug.h"
31 #include "llvm/Support/Endian.h"
32 #include "llvm/Support/Error.h"
33 #include "llvm/Support/ErrorHandling.h"
34 #include "llvm/Support/LEB128.h"
35 #include "llvm/Support/MathExtras.h"
36 #include "llvm/Support/Path.h"
37 #include "llvm/Support/raw_ostream.h"
38 #include "llvm/TargetParser/Triple.h"
39 #include <vector>
41 using namespace llvm;
42 using namespace coverage;
43 using namespace object;
45 #define DEBUG_TYPE "coverage-mapping"
47 STATISTIC(CovMapNumRecords, "The # of coverage function records");
48 STATISTIC(CovMapNumUsedRecords, "The # of used coverage function records");
50 void CoverageMappingIterator::increment() {
51 if (ReadErr != coveragemap_error::success)
52 return;
54 // Check if all the records were read or if an error occurred while reading
55 // the next record.
56 if (auto E = Reader->readNextRecord(Record))
57 handleAllErrors(std::move(E), [&](const CoverageMapError &CME) {
58 if (CME.get() == coveragemap_error::eof)
59 *this = CoverageMappingIterator();
60 else
61 ReadErr = CME.get();
62 });
65 Error RawCoverageReader::readULEB128(uint64_t &Result) {
66 if (Data.empty())
67 return make_error<CoverageMapError>(coveragemap_error::truncated);
68 unsigned N = 0;
69 Result = decodeULEB128(Data.bytes_begin(), &N);
70 if (N > Data.size())
71 return make_error<CoverageMapError>(coveragemap_error::malformed,
72 "the size of ULEB128 is too big");
73 Data = Data.substr(N);
74 return Error::success();
77 Error RawCoverageReader::readIntMax(uint64_t &Result, uint64_t MaxPlus1) {
78 if (auto Err = readULEB128(Result))
79 return Err;
80 if (Result >= MaxPlus1)
81 return make_error<CoverageMapError>(
82 coveragemap_error::malformed,
83 "the value of ULEB128 is greater than or equal to MaxPlus1");
84 return Error::success();
87 Error RawCoverageReader::readSize(uint64_t &Result) {
88 if (auto Err = readULEB128(Result))
89 return Err;
90 if (Result > Data.size())
91 return make_error<CoverageMapError>(coveragemap_error::malformed,
92 "the value of ULEB128 is too big");
93 return Error::success();
96 Error RawCoverageReader::readString(StringRef &Result) {
97 uint64_t Length;
98 if (auto Err = readSize(Length))
99 return Err;
100 Result = Data.substr(0, Length);
101 Data = Data.substr(Length);
102 return Error::success();
105 Error RawCoverageFilenamesReader::read(CovMapVersion Version) {
106 uint64_t NumFilenames;
107 if (auto Err = readSize(NumFilenames))
108 return Err;
109 if (!NumFilenames)
110 return make_error<CoverageMapError>(coveragemap_error::malformed,
111 "number of filenames is zero");
113 if (Version < CovMapVersion::Version4)
114 return readUncompressed(Version, NumFilenames);
116 // The uncompressed length may exceed the size of the encoded filenames.
117 // Skip size validation.
118 uint64_t UncompressedLen;
119 if (auto Err = readULEB128(UncompressedLen))
120 return Err;
122 uint64_t CompressedLen;
123 if (auto Err = readSize(CompressedLen))
124 return Err;
126 if (CompressedLen > 0) {
127 if (!compression::zlib::isAvailable())
128 return make_error<CoverageMapError>(
129 coveragemap_error::decompression_failed);
131 // Allocate memory for the decompressed filenames.
132 SmallVector<uint8_t, 0> StorageBuf;
134 // Read compressed filenames.
135 StringRef CompressedFilenames = Data.substr(0, CompressedLen);
136 Data = Data.substr(CompressedLen);
137 auto Err = compression::zlib::decompress(
138 arrayRefFromStringRef(CompressedFilenames), StorageBuf,
139 UncompressedLen);
140 if (Err) {
141 consumeError(std::move(Err));
142 return make_error<CoverageMapError>(
143 coveragemap_error::decompression_failed);
146 RawCoverageFilenamesReader Delegate(toStringRef(StorageBuf), Filenames,
147 CompilationDir);
148 return Delegate.readUncompressed(Version, NumFilenames);
151 return readUncompressed(Version, NumFilenames);
154 Error RawCoverageFilenamesReader::readUncompressed(CovMapVersion Version,
155 uint64_t NumFilenames) {
156 // Read uncompressed filenames.
157 if (Version < CovMapVersion::Version6) {
158 for (size_t I = 0; I < NumFilenames; ++I) {
159 StringRef Filename;
160 if (auto Err = readString(Filename))
161 return Err;
162 Filenames.push_back(Filename.str());
164 } else {
165 StringRef CWD;
166 if (auto Err = readString(CWD))
167 return Err;
168 Filenames.push_back(CWD.str());
170 for (size_t I = 1; I < NumFilenames; ++I) {
171 StringRef Filename;
172 if (auto Err = readString(Filename))
173 return Err;
174 if (sys::path::is_absolute(Filename)) {
175 Filenames.push_back(Filename.str());
176 } else {
177 SmallString<256> P;
178 if (!CompilationDir.empty())
179 P.assign(CompilationDir);
180 else
181 P.assign(CWD);
182 llvm::sys::path::append(P, Filename);
183 sys::path::remove_dots(P, /*remove_dot_dot=*/true);
184 Filenames.push_back(static_cast<std::string>(P.str()));
188 return Error::success();
191 Error RawCoverageMappingReader::decodeCounter(unsigned Value, Counter &C) {
192 auto Tag = Value & Counter::EncodingTagMask;
193 switch (Tag) {
194 case Counter::Zero:
195 C = Counter::getZero();
196 return Error::success();
197 case Counter::CounterValueReference:
198 C = Counter::getCounter(Value >> Counter::EncodingTagBits);
199 return Error::success();
200 default:
201 break;
203 Tag -= Counter::Expression;
204 switch (Tag) {
205 case CounterExpression::Subtract:
206 case CounterExpression::Add: {
207 auto ID = Value >> Counter::EncodingTagBits;
208 if (ID >= Expressions.size())
209 return make_error<CoverageMapError>(coveragemap_error::malformed,
210 "counter expression is invalid");
211 Expressions[ID].Kind = CounterExpression::ExprKind(Tag);
212 C = Counter::getExpression(ID);
213 break;
215 default:
216 return make_error<CoverageMapError>(coveragemap_error::malformed,
217 "counter expression kind is invalid");
219 return Error::success();
222 Error RawCoverageMappingReader::readCounter(Counter &C) {
223 uint64_t EncodedCounter;
224 if (auto Err =
225 readIntMax(EncodedCounter, std::numeric_limits<unsigned>::max()))
226 return Err;
227 if (auto Err = decodeCounter(EncodedCounter, C))
228 return Err;
229 return Error::success();
232 static const unsigned EncodingExpansionRegionBit = 1
233 << Counter::EncodingTagBits;
235 /// Read the sub-array of regions for the given inferred file id.
236 /// \param NumFileIDs the number of file ids that are defined for this
237 /// function.
238 Error RawCoverageMappingReader::readMappingRegionsSubArray(
239 std::vector<CounterMappingRegion> &MappingRegions, unsigned InferredFileID,
240 size_t NumFileIDs) {
241 uint64_t NumRegions;
242 if (auto Err = readSize(NumRegions))
243 return Err;
244 unsigned LineStart = 0;
245 for (size_t I = 0; I < NumRegions; ++I) {
246 Counter C, C2;
247 uint64_t BIDX = 0, NC = 0, ID = 0, TID = 0, FID = 0;
248 CounterMappingRegion::RegionKind Kind = CounterMappingRegion::CodeRegion;
250 // Read the combined counter + region kind.
251 uint64_t EncodedCounterAndRegion;
252 if (auto Err = readIntMax(EncodedCounterAndRegion,
253 std::numeric_limits<unsigned>::max()))
254 return Err;
255 unsigned Tag = EncodedCounterAndRegion & Counter::EncodingTagMask;
256 uint64_t ExpandedFileID = 0;
258 // If Tag does not represent a ZeroCounter, then it is understood to refer
259 // to a counter or counter expression with region kind assumed to be
260 // "CodeRegion". In that case, EncodedCounterAndRegion actually encodes the
261 // referenced counter or counter expression (and nothing else).
263 // If Tag represents a ZeroCounter and EncodingExpansionRegionBit is set,
264 // then EncodedCounterAndRegion is interpreted to represent an
265 // ExpansionRegion. In all other cases, EncodedCounterAndRegion is
266 // interpreted to refer to a specific region kind, after which additional
267 // fields may be read (e.g. BranchRegions have two encoded counters that
268 // follow an encoded region kind value).
269 if (Tag != Counter::Zero) {
270 if (auto Err = decodeCounter(EncodedCounterAndRegion, C))
271 return Err;
272 } else {
273 // Is it an expansion region?
274 if (EncodedCounterAndRegion & EncodingExpansionRegionBit) {
275 Kind = CounterMappingRegion::ExpansionRegion;
276 ExpandedFileID = EncodedCounterAndRegion >>
277 Counter::EncodingCounterTagAndExpansionRegionTagBits;
278 if (ExpandedFileID >= NumFileIDs)
279 return make_error<CoverageMapError>(coveragemap_error::malformed,
280 "ExpandedFileID is invalid");
281 } else {
282 switch (EncodedCounterAndRegion >>
283 Counter::EncodingCounterTagAndExpansionRegionTagBits) {
284 case CounterMappingRegion::CodeRegion:
285 // Don't do anything when we have a code region with a zero counter.
286 break;
287 case CounterMappingRegion::SkippedRegion:
288 Kind = CounterMappingRegion::SkippedRegion;
289 break;
290 case CounterMappingRegion::BranchRegion:
291 // For a Branch Region, read two successive counters.
292 Kind = CounterMappingRegion::BranchRegion;
293 if (auto Err = readCounter(C))
294 return Err;
295 if (auto Err = readCounter(C2))
296 return Err;
297 break;
298 case CounterMappingRegion::MCDCBranchRegion:
299 // For a MCDC Branch Region, read two successive counters and 3 IDs.
300 Kind = CounterMappingRegion::MCDCBranchRegion;
301 if (auto Err = readCounter(C))
302 return Err;
303 if (auto Err = readCounter(C2))
304 return Err;
305 if (auto Err = readIntMax(ID, std::numeric_limits<unsigned>::max()))
306 return Err;
307 if (auto Err = readIntMax(TID, std::numeric_limits<unsigned>::max()))
308 return Err;
309 if (auto Err = readIntMax(FID, std::numeric_limits<unsigned>::max()))
310 return Err;
311 break;
312 case CounterMappingRegion::MCDCDecisionRegion:
313 Kind = CounterMappingRegion::MCDCDecisionRegion;
314 if (auto Err = readIntMax(BIDX, std::numeric_limits<unsigned>::max()))
315 return Err;
316 if (auto Err = readIntMax(NC, std::numeric_limits<unsigned>::max()))
317 return Err;
318 break;
319 default:
320 return make_error<CoverageMapError>(coveragemap_error::malformed,
321 "region kind is incorrect");
326 // Read the source range.
327 uint64_t LineStartDelta, ColumnStart, NumLines, ColumnEnd;
328 if (auto Err =
329 readIntMax(LineStartDelta, std::numeric_limits<unsigned>::max()))
330 return Err;
331 if (auto Err = readULEB128(ColumnStart))
332 return Err;
333 if (ColumnStart > std::numeric_limits<unsigned>::max())
334 return make_error<CoverageMapError>(coveragemap_error::malformed,
335 "start column is too big");
336 if (auto Err = readIntMax(NumLines, std::numeric_limits<unsigned>::max()))
337 return Err;
338 if (auto Err = readIntMax(ColumnEnd, std::numeric_limits<unsigned>::max()))
339 return Err;
340 LineStart += LineStartDelta;
342 // If the high bit of ColumnEnd is set, this is a gap region.
343 if (ColumnEnd & (1U << 31)) {
344 Kind = CounterMappingRegion::GapRegion;
345 ColumnEnd &= ~(1U << 31);
348 // Adjust the column locations for the empty regions that are supposed to
349 // cover whole lines. Those regions should be encoded with the
350 // column range (1 -> std::numeric_limits<unsigned>::max()), but because
351 // the encoded std::numeric_limits<unsigned>::max() is several bytes long,
352 // we set the column range to (0 -> 0) to ensure that the column start and
353 // column end take up one byte each.
354 // The std::numeric_limits<unsigned>::max() is used to represent a column
355 // position at the end of the line without knowing the length of that line.
356 if (ColumnStart == 0 && ColumnEnd == 0) {
357 ColumnStart = 1;
358 ColumnEnd = std::numeric_limits<unsigned>::max();
361 LLVM_DEBUG({
362 dbgs() << "Counter in file " << InferredFileID << " " << LineStart << ":"
363 << ColumnStart << " -> " << (LineStart + NumLines) << ":"
364 << ColumnEnd << ", ";
365 if (Kind == CounterMappingRegion::ExpansionRegion)
366 dbgs() << "Expands to file " << ExpandedFileID;
367 else
368 CounterMappingContext(Expressions).dump(C, dbgs());
369 dbgs() << "\n";
372 auto CMR = CounterMappingRegion(
373 C, C2,
374 CounterMappingRegion::MCDCParameters{
375 static_cast<unsigned>(BIDX), static_cast<unsigned>(NC),
376 static_cast<unsigned>(ID), static_cast<unsigned>(TID),
377 static_cast<unsigned>(FID)},
378 InferredFileID, ExpandedFileID, LineStart, ColumnStart,
379 LineStart + NumLines, ColumnEnd, Kind);
380 if (CMR.startLoc() > CMR.endLoc())
381 return make_error<CoverageMapError>(
382 coveragemap_error::malformed,
383 "counter mapping region locations are incorrect");
384 MappingRegions.push_back(CMR);
386 return Error::success();
389 Error RawCoverageMappingReader::read() {
390 // Read the virtual file mapping.
391 SmallVector<unsigned, 8> VirtualFileMapping;
392 uint64_t NumFileMappings;
393 if (auto Err = readSize(NumFileMappings))
394 return Err;
395 for (size_t I = 0; I < NumFileMappings; ++I) {
396 uint64_t FilenameIndex;
397 if (auto Err = readIntMax(FilenameIndex, TranslationUnitFilenames.size()))
398 return Err;
399 VirtualFileMapping.push_back(FilenameIndex);
402 // Construct the files using unique filenames and virtual file mapping.
403 for (auto I : VirtualFileMapping) {
404 Filenames.push_back(TranslationUnitFilenames[I]);
407 // Read the expressions.
408 uint64_t NumExpressions;
409 if (auto Err = readSize(NumExpressions))
410 return Err;
411 // Create an array of dummy expressions that get the proper counters
412 // when the expressions are read, and the proper kinds when the counters
413 // are decoded.
414 Expressions.resize(
415 NumExpressions,
416 CounterExpression(CounterExpression::Subtract, Counter(), Counter()));
417 for (size_t I = 0; I < NumExpressions; ++I) {
418 if (auto Err = readCounter(Expressions[I].LHS))
419 return Err;
420 if (auto Err = readCounter(Expressions[I].RHS))
421 return Err;
424 // Read the mapping regions sub-arrays.
425 for (unsigned InferredFileID = 0, S = VirtualFileMapping.size();
426 InferredFileID < S; ++InferredFileID) {
427 if (auto Err = readMappingRegionsSubArray(MappingRegions, InferredFileID,
428 VirtualFileMapping.size()))
429 return Err;
432 // Set the counters for the expansion regions.
433 // i.e. Counter of expansion region = counter of the first region
434 // from the expanded file.
435 // Perform multiple passes to correctly propagate the counters through
436 // all the nested expansion regions.
437 SmallVector<CounterMappingRegion *, 8> FileIDExpansionRegionMapping;
438 FileIDExpansionRegionMapping.resize(VirtualFileMapping.size(), nullptr);
439 for (unsigned Pass = 1, S = VirtualFileMapping.size(); Pass < S; ++Pass) {
440 for (auto &R : MappingRegions) {
441 if (R.Kind != CounterMappingRegion::ExpansionRegion)
442 continue;
443 assert(!FileIDExpansionRegionMapping[R.ExpandedFileID]);
444 FileIDExpansionRegionMapping[R.ExpandedFileID] = &R;
446 for (auto &R : MappingRegions) {
447 if (FileIDExpansionRegionMapping[R.FileID]) {
448 FileIDExpansionRegionMapping[R.FileID]->Count = R.Count;
449 FileIDExpansionRegionMapping[R.FileID] = nullptr;
454 return Error::success();
457 Expected<bool> RawCoverageMappingDummyChecker::isDummy() {
458 // A dummy coverage mapping data consists of just one region with zero count.
459 uint64_t NumFileMappings;
460 if (Error Err = readSize(NumFileMappings))
461 return std::move(Err);
462 if (NumFileMappings != 1)
463 return false;
464 // We don't expect any specific value for the filename index, just skip it.
465 uint64_t FilenameIndex;
466 if (Error Err =
467 readIntMax(FilenameIndex, std::numeric_limits<unsigned>::max()))
468 return std::move(Err);
469 uint64_t NumExpressions;
470 if (Error Err = readSize(NumExpressions))
471 return std::move(Err);
472 if (NumExpressions != 0)
473 return false;
474 uint64_t NumRegions;
475 if (Error Err = readSize(NumRegions))
476 return std::move(Err);
477 if (NumRegions != 1)
478 return false;
479 uint64_t EncodedCounterAndRegion;
480 if (Error Err = readIntMax(EncodedCounterAndRegion,
481 std::numeric_limits<unsigned>::max()))
482 return std::move(Err);
483 unsigned Tag = EncodedCounterAndRegion & Counter::EncodingTagMask;
484 return Tag == Counter::Zero;
487 Error InstrProfSymtab::create(SectionRef &Section) {
488 Expected<StringRef> DataOrErr = Section.getContents();
489 if (!DataOrErr)
490 return DataOrErr.takeError();
491 Data = *DataOrErr;
492 Address = Section.getAddress();
494 // If this is a linked PE/COFF file, then we have to skip over the null byte
495 // that is allocated in the .lprfn$A section in the LLVM profiling runtime.
496 // If the name section is .lprfcovnames, it doesn't have the null byte at the
497 // beginning.
498 const ObjectFile *Obj = Section.getObject();
499 if (isa<COFFObjectFile>(Obj) && !Obj->isRelocatableObject())
500 if (Expected<StringRef> NameOrErr = Section.getName())
501 if (*NameOrErr != getInstrProfSectionName(IPSK_covname, Triple::COFF))
502 Data = Data.drop_front(1);
504 return Error::success();
507 StringRef InstrProfSymtab::getFuncName(uint64_t Pointer, size_t Size) {
508 if (Pointer < Address)
509 return StringRef();
510 auto Offset = Pointer - Address;
511 if (Offset + Size > Data.size())
512 return StringRef();
513 return Data.substr(Pointer - Address, Size);
516 // Check if the mapping data is a dummy, i.e. is emitted for an unused function.
517 static Expected<bool> isCoverageMappingDummy(uint64_t Hash, StringRef Mapping) {
518 // The hash value of dummy mapping records is always zero.
519 if (Hash)
520 return false;
521 return RawCoverageMappingDummyChecker(Mapping).isDummy();
524 /// A range of filename indices. Used to specify the location of a batch of
525 /// filenames in a vector-like container.
526 struct FilenameRange {
527 unsigned StartingIndex;
528 unsigned Length;
530 FilenameRange(unsigned StartingIndex, unsigned Length)
531 : StartingIndex(StartingIndex), Length(Length) {}
533 void markInvalid() { Length = 0; }
534 bool isInvalid() const { return Length == 0; }
537 namespace {
539 /// The interface to read coverage mapping function records for a module.
540 struct CovMapFuncRecordReader {
541 virtual ~CovMapFuncRecordReader() = default;
543 // Read a coverage header.
545 // \p CovBuf points to the buffer containing the \c CovHeader of the coverage
546 // mapping data associated with the module.
548 // Returns a pointer to the next \c CovHeader if it exists, or to an address
549 // greater than \p CovEnd if not.
550 virtual Expected<const char *> readCoverageHeader(const char *CovBuf,
551 const char *CovBufEnd) = 0;
553 // Read function records.
555 // \p FuncRecBuf points to the buffer containing a batch of function records.
556 // \p FuncRecBufEnd points past the end of the batch of records.
558 // Prior to Version4, \p OutOfLineFileRange points to a sequence of filenames
559 // associated with the function records. It is unused in Version4.
561 // Prior to Version4, \p OutOfLineMappingBuf points to a sequence of coverage
562 // mappings associated with the function records. It is unused in Version4.
563 virtual Error
564 readFunctionRecords(const char *FuncRecBuf, const char *FuncRecBufEnd,
565 std::optional<FilenameRange> OutOfLineFileRange,
566 const char *OutOfLineMappingBuf,
567 const char *OutOfLineMappingBufEnd) = 0;
569 template <class IntPtrT, llvm::endianness Endian>
570 static Expected<std::unique_ptr<CovMapFuncRecordReader>>
571 get(CovMapVersion Version, InstrProfSymtab &P,
572 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, StringRef D,
573 std::vector<std::string> &F);
576 // A class for reading coverage mapping function records for a module.
577 template <CovMapVersion Version, class IntPtrT, llvm::endianness Endian>
578 class VersionedCovMapFuncRecordReader : public CovMapFuncRecordReader {
579 using FuncRecordType =
580 typename CovMapTraits<Version, IntPtrT>::CovMapFuncRecordType;
581 using NameRefType = typename CovMapTraits<Version, IntPtrT>::NameRefType;
583 // Maps function's name references to the indexes of their records
584 // in \c Records.
585 DenseMap<NameRefType, size_t> FunctionRecords;
586 InstrProfSymtab &ProfileNames;
587 StringRef CompilationDir;
588 std::vector<std::string> &Filenames;
589 std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records;
591 // Maps a hash of the filenames in a TU to a \c FileRange. The range
592 // specifies the location of the hashed filenames in \c Filenames.
593 DenseMap<uint64_t, FilenameRange> FileRangeMap;
595 // Add the record to the collection if we don't already have a record that
596 // points to the same function name. This is useful to ignore the redundant
597 // records for the functions with ODR linkage.
598 // In addition, prefer records with real coverage mapping data to dummy
599 // records, which were emitted for inline functions which were seen but
600 // not used in the corresponding translation unit.
601 Error insertFunctionRecordIfNeeded(const FuncRecordType *CFR,
602 StringRef Mapping,
603 FilenameRange FileRange) {
604 ++CovMapNumRecords;
605 uint64_t FuncHash = CFR->template getFuncHash<Endian>();
606 NameRefType NameRef = CFR->template getFuncNameRef<Endian>();
607 auto InsertResult =
608 FunctionRecords.insert(std::make_pair(NameRef, Records.size()));
609 if (InsertResult.second) {
610 StringRef FuncName;
611 if (Error Err = CFR->template getFuncName<Endian>(ProfileNames, FuncName))
612 return Err;
613 if (FuncName.empty())
614 return make_error<InstrProfError>(instrprof_error::malformed,
615 "function name is empty");
616 ++CovMapNumUsedRecords;
617 Records.emplace_back(Version, FuncName, FuncHash, Mapping,
618 FileRange.StartingIndex, FileRange.Length);
619 return Error::success();
621 // Update the existing record if it's a dummy and the new record is real.
622 size_t OldRecordIndex = InsertResult.first->second;
623 BinaryCoverageReader::ProfileMappingRecord &OldRecord =
624 Records[OldRecordIndex];
625 Expected<bool> OldIsDummyExpected = isCoverageMappingDummy(
626 OldRecord.FunctionHash, OldRecord.CoverageMapping);
627 if (Error Err = OldIsDummyExpected.takeError())
628 return Err;
629 if (!*OldIsDummyExpected)
630 return Error::success();
631 Expected<bool> NewIsDummyExpected =
632 isCoverageMappingDummy(FuncHash, Mapping);
633 if (Error Err = NewIsDummyExpected.takeError())
634 return Err;
635 if (*NewIsDummyExpected)
636 return Error::success();
637 ++CovMapNumUsedRecords;
638 OldRecord.FunctionHash = FuncHash;
639 OldRecord.CoverageMapping = Mapping;
640 OldRecord.FilenamesBegin = FileRange.StartingIndex;
641 OldRecord.FilenamesSize = FileRange.Length;
642 return Error::success();
645 public:
646 VersionedCovMapFuncRecordReader(
647 InstrProfSymtab &P,
648 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, StringRef D,
649 std::vector<std::string> &F)
650 : ProfileNames(P), CompilationDir(D), Filenames(F), Records(R) {}
652 ~VersionedCovMapFuncRecordReader() override = default;
654 Expected<const char *> readCoverageHeader(const char *CovBuf,
655 const char *CovBufEnd) override {
656 using namespace support;
658 if (CovBuf + sizeof(CovMapHeader) > CovBufEnd)
659 return make_error<CoverageMapError>(
660 coveragemap_error::malformed,
661 "coverage mapping header section is larger than buffer size");
662 auto CovHeader = reinterpret_cast<const CovMapHeader *>(CovBuf);
663 uint32_t NRecords = CovHeader->getNRecords<Endian>();
664 uint32_t FilenamesSize = CovHeader->getFilenamesSize<Endian>();
665 uint32_t CoverageSize = CovHeader->getCoverageSize<Endian>();
666 assert((CovMapVersion)CovHeader->getVersion<Endian>() == Version);
667 CovBuf = reinterpret_cast<const char *>(CovHeader + 1);
669 // Skip past the function records, saving the start and end for later.
670 // This is a no-op in Version4 (function records are read after all headers
671 // are read).
672 const char *FuncRecBuf = nullptr;
673 const char *FuncRecBufEnd = nullptr;
674 if (Version < CovMapVersion::Version4)
675 FuncRecBuf = CovBuf;
676 CovBuf += NRecords * sizeof(FuncRecordType);
677 if (Version < CovMapVersion::Version4)
678 FuncRecBufEnd = CovBuf;
680 // Get the filenames.
681 if (CovBuf + FilenamesSize > CovBufEnd)
682 return make_error<CoverageMapError>(
683 coveragemap_error::malformed,
684 "filenames section is larger than buffer size");
685 size_t FilenamesBegin = Filenames.size();
686 StringRef FilenameRegion(CovBuf, FilenamesSize);
687 RawCoverageFilenamesReader Reader(FilenameRegion, Filenames,
688 CompilationDir);
689 if (auto Err = Reader.read(Version))
690 return std::move(Err);
691 CovBuf += FilenamesSize;
692 FilenameRange FileRange(FilenamesBegin, Filenames.size() - FilenamesBegin);
694 if (Version >= CovMapVersion::Version4) {
695 // Map a hash of the filenames region to the filename range associated
696 // with this coverage header.
697 int64_t FilenamesRef =
698 llvm::IndexedInstrProf::ComputeHash(FilenameRegion);
699 auto Insert =
700 FileRangeMap.insert(std::make_pair(FilenamesRef, FileRange));
701 if (!Insert.second) {
702 // The same filenames ref was encountered twice. It's possible that
703 // the associated filenames are the same.
704 auto It = Filenames.begin();
705 FilenameRange &OrigRange = Insert.first->getSecond();
706 if (std::equal(It + OrigRange.StartingIndex,
707 It + OrigRange.StartingIndex + OrigRange.Length,
708 It + FileRange.StartingIndex,
709 It + FileRange.StartingIndex + FileRange.Length))
710 // Map the new range to the original one.
711 FileRange = OrigRange;
712 else
713 // This is a hash collision. Mark the filenames ref invalid.
714 OrigRange.markInvalid();
718 // We'll read the coverage mapping records in the loop below.
719 // This is a no-op in Version4 (coverage mappings are not affixed to the
720 // coverage header).
721 const char *MappingBuf = CovBuf;
722 if (Version >= CovMapVersion::Version4 && CoverageSize != 0)
723 return make_error<CoverageMapError>(coveragemap_error::malformed,
724 "coverage mapping size is not zero");
725 CovBuf += CoverageSize;
726 const char *MappingEnd = CovBuf;
728 if (CovBuf > CovBufEnd)
729 return make_error<CoverageMapError>(
730 coveragemap_error::malformed,
731 "function records section is larger than buffer size");
733 if (Version < CovMapVersion::Version4) {
734 // Read each function record.
735 if (Error E = readFunctionRecords(FuncRecBuf, FuncRecBufEnd, FileRange,
736 MappingBuf, MappingEnd))
737 return std::move(E);
740 // Each coverage map has an alignment of 8, so we need to adjust alignment
741 // before reading the next map.
742 CovBuf += offsetToAlignedAddr(CovBuf, Align(8));
744 return CovBuf;
747 Error readFunctionRecords(const char *FuncRecBuf, const char *FuncRecBufEnd,
748 std::optional<FilenameRange> OutOfLineFileRange,
749 const char *OutOfLineMappingBuf,
750 const char *OutOfLineMappingBufEnd) override {
751 auto CFR = reinterpret_cast<const FuncRecordType *>(FuncRecBuf);
752 while ((const char *)CFR < FuncRecBufEnd) {
753 // Validate the length of the coverage mapping for this function.
754 const char *NextMappingBuf;
755 const FuncRecordType *NextCFR;
756 std::tie(NextMappingBuf, NextCFR) =
757 CFR->template advanceByOne<Endian>(OutOfLineMappingBuf);
758 if (Version < CovMapVersion::Version4)
759 if (NextMappingBuf > OutOfLineMappingBufEnd)
760 return make_error<CoverageMapError>(
761 coveragemap_error::malformed,
762 "next mapping buffer is larger than buffer size");
764 // Look up the set of filenames associated with this function record.
765 std::optional<FilenameRange> FileRange;
766 if (Version < CovMapVersion::Version4) {
767 FileRange = OutOfLineFileRange;
768 } else {
769 uint64_t FilenamesRef = CFR->template getFilenamesRef<Endian>();
770 auto It = FileRangeMap.find(FilenamesRef);
771 if (It == FileRangeMap.end())
772 return make_error<CoverageMapError>(
773 coveragemap_error::malformed,
774 "no filename found for function with hash=0x" +
775 Twine::utohexstr(FilenamesRef));
776 else
777 FileRange = It->getSecond();
780 // Now, read the coverage data.
781 if (FileRange && !FileRange->isInvalid()) {
782 StringRef Mapping =
783 CFR->template getCoverageMapping<Endian>(OutOfLineMappingBuf);
784 if (Version >= CovMapVersion::Version4 &&
785 Mapping.data() + Mapping.size() > FuncRecBufEnd)
786 return make_error<CoverageMapError>(
787 coveragemap_error::malformed,
788 "coverage mapping data is larger than buffer size");
789 if (Error Err = insertFunctionRecordIfNeeded(CFR, Mapping, *FileRange))
790 return Err;
793 std::tie(OutOfLineMappingBuf, CFR) = std::tie(NextMappingBuf, NextCFR);
795 return Error::success();
799 } // end anonymous namespace
801 template <class IntPtrT, llvm::endianness Endian>
802 Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get(
803 CovMapVersion Version, InstrProfSymtab &P,
804 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, StringRef D,
805 std::vector<std::string> &F) {
806 using namespace coverage;
808 switch (Version) {
809 case CovMapVersion::Version1:
810 return std::make_unique<VersionedCovMapFuncRecordReader<
811 CovMapVersion::Version1, IntPtrT, Endian>>(P, R, D, F);
812 case CovMapVersion::Version2:
813 case CovMapVersion::Version3:
814 case CovMapVersion::Version4:
815 case CovMapVersion::Version5:
816 case CovMapVersion::Version6:
817 case CovMapVersion::Version7:
818 // Decompress the name data.
819 if (Error E = P.create(P.getNameData()))
820 return std::move(E);
821 if (Version == CovMapVersion::Version2)
822 return std::make_unique<VersionedCovMapFuncRecordReader<
823 CovMapVersion::Version2, IntPtrT, Endian>>(P, R, D, F);
824 else if (Version == CovMapVersion::Version3)
825 return std::make_unique<VersionedCovMapFuncRecordReader<
826 CovMapVersion::Version3, IntPtrT, Endian>>(P, R, D, F);
827 else if (Version == CovMapVersion::Version4)
828 return std::make_unique<VersionedCovMapFuncRecordReader<
829 CovMapVersion::Version4, IntPtrT, Endian>>(P, R, D, F);
830 else if (Version == CovMapVersion::Version5)
831 return std::make_unique<VersionedCovMapFuncRecordReader<
832 CovMapVersion::Version5, IntPtrT, Endian>>(P, R, D, F);
833 else if (Version == CovMapVersion::Version6)
834 return std::make_unique<VersionedCovMapFuncRecordReader<
835 CovMapVersion::Version6, IntPtrT, Endian>>(P, R, D, F);
836 else if (Version == CovMapVersion::Version7)
837 return std::make_unique<VersionedCovMapFuncRecordReader<
838 CovMapVersion::Version7, IntPtrT, Endian>>(P, R, D, F);
840 llvm_unreachable("Unsupported version");
843 template <typename T, llvm::endianness Endian>
844 static Error readCoverageMappingData(
845 InstrProfSymtab &ProfileNames, StringRef CovMap, StringRef FuncRecords,
846 std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
847 StringRef CompilationDir, std::vector<std::string> &Filenames) {
848 using namespace coverage;
850 // Read the records in the coverage data section.
851 auto CovHeader =
852 reinterpret_cast<const CovMapHeader *>(CovMap.data());
853 CovMapVersion Version = (CovMapVersion)CovHeader->getVersion<Endian>();
854 if (Version > CovMapVersion::CurrentVersion)
855 return make_error<CoverageMapError>(coveragemap_error::unsupported_version);
856 Expected<std::unique_ptr<CovMapFuncRecordReader>> ReaderExpected =
857 CovMapFuncRecordReader::get<T, Endian>(Version, ProfileNames, Records,
858 CompilationDir, Filenames);
859 if (Error E = ReaderExpected.takeError())
860 return E;
861 auto Reader = std::move(ReaderExpected.get());
862 const char *CovBuf = CovMap.data();
863 const char *CovBufEnd = CovBuf + CovMap.size();
864 const char *FuncRecBuf = FuncRecords.data();
865 const char *FuncRecBufEnd = FuncRecords.data() + FuncRecords.size();
866 while (CovBuf < CovBufEnd) {
867 // Read the current coverage header & filename data.
869 // Prior to Version4, this also reads all function records affixed to the
870 // header.
872 // Return a pointer to the next coverage header.
873 auto NextOrErr = Reader->readCoverageHeader(CovBuf, CovBufEnd);
874 if (auto E = NextOrErr.takeError())
875 return E;
876 CovBuf = NextOrErr.get();
878 // In Version4, function records are not affixed to coverage headers. Read
879 // the records from their dedicated section.
880 if (Version >= CovMapVersion::Version4)
881 return Reader->readFunctionRecords(FuncRecBuf, FuncRecBufEnd, std::nullopt,
882 nullptr, nullptr);
883 return Error::success();
886 Expected<std::unique_ptr<BinaryCoverageReader>>
887 BinaryCoverageReader::createCoverageReaderFromBuffer(
888 StringRef Coverage, FuncRecordsStorage &&FuncRecords,
889 InstrProfSymtab &&ProfileNames, uint8_t BytesInAddress,
890 llvm::endianness Endian, StringRef CompilationDir) {
891 std::unique_ptr<BinaryCoverageReader> Reader(
892 new BinaryCoverageReader(std::move(FuncRecords)));
893 Reader->ProfileNames = std::move(ProfileNames);
894 StringRef FuncRecordsRef = Reader->FuncRecords->getBuffer();
895 if (BytesInAddress == 4 && Endian == llvm::endianness::little) {
896 if (Error E = readCoverageMappingData<uint32_t, llvm::endianness::little>(
897 Reader->ProfileNames, Coverage, FuncRecordsRef,
898 Reader->MappingRecords, CompilationDir, Reader->Filenames))
899 return std::move(E);
900 } else if (BytesInAddress == 4 && Endian == llvm::endianness::big) {
901 if (Error E = readCoverageMappingData<uint32_t, llvm::endianness::big>(
902 Reader->ProfileNames, Coverage, FuncRecordsRef,
903 Reader->MappingRecords, CompilationDir, Reader->Filenames))
904 return std::move(E);
905 } else if (BytesInAddress == 8 && Endian == llvm::endianness::little) {
906 if (Error E = readCoverageMappingData<uint64_t, llvm::endianness::little>(
907 Reader->ProfileNames, Coverage, FuncRecordsRef,
908 Reader->MappingRecords, CompilationDir, Reader->Filenames))
909 return std::move(E);
910 } else if (BytesInAddress == 8 && Endian == llvm::endianness::big) {
911 if (Error E = readCoverageMappingData<uint64_t, llvm::endianness::big>(
912 Reader->ProfileNames, Coverage, FuncRecordsRef,
913 Reader->MappingRecords, CompilationDir, Reader->Filenames))
914 return std::move(E);
915 } else
916 return make_error<CoverageMapError>(
917 coveragemap_error::malformed,
918 "not supported endianness or bytes in address");
919 return std::move(Reader);
922 static Expected<std::unique_ptr<BinaryCoverageReader>>
923 loadTestingFormat(StringRef Data, StringRef CompilationDir) {
924 uint8_t BytesInAddress = 8;
925 llvm::endianness Endian = llvm::endianness::little;
927 // Read the magic and version.
928 Data = Data.substr(sizeof(TestingFormatMagic));
929 if (Data.size() < sizeof(uint64_t))
930 return make_error<CoverageMapError>(coveragemap_error::malformed,
931 "the size of data is too small");
932 auto TestingVersion =
933 support::endian::byte_swap<uint64_t, llvm::endianness::little>(
934 *reinterpret_cast<const uint64_t *>(Data.data()));
935 Data = Data.substr(sizeof(uint64_t));
937 // Read the ProfileNames data.
938 if (Data.empty())
939 return make_error<CoverageMapError>(coveragemap_error::truncated);
940 unsigned N = 0;
941 uint64_t ProfileNamesSize = decodeULEB128(Data.bytes_begin(), &N);
942 if (N > Data.size())
943 return make_error<CoverageMapError>(
944 coveragemap_error::malformed,
945 "the size of TestingFormatMagic is too big");
946 Data = Data.substr(N);
947 if (Data.empty())
948 return make_error<CoverageMapError>(coveragemap_error::truncated);
949 N = 0;
950 uint64_t Address = decodeULEB128(Data.bytes_begin(), &N);
951 if (N > Data.size())
952 return make_error<CoverageMapError>(coveragemap_error::malformed,
953 "the size of ULEB128 is too big");
954 Data = Data.substr(N);
955 if (Data.size() < ProfileNamesSize)
956 return make_error<CoverageMapError>(coveragemap_error::malformed,
957 "the size of ProfileNames is too big");
958 InstrProfSymtab ProfileNames;
959 if (Error E = ProfileNames.create(Data.substr(0, ProfileNamesSize), Address))
960 return std::move(E);
961 Data = Data.substr(ProfileNamesSize);
963 // In Version2, the size of CoverageMapping is stored directly.
964 uint64_t CoverageMappingSize;
965 if (TestingVersion == uint64_t(TestingFormatVersion::Version2)) {
966 N = 0;
967 CoverageMappingSize = decodeULEB128(Data.bytes_begin(), &N);
968 if (N > Data.size())
969 return make_error<CoverageMapError>(coveragemap_error::malformed,
970 "the size of ULEB128 is too big");
971 Data = Data.substr(N);
972 if (CoverageMappingSize < sizeof(CovMapHeader))
973 return make_error<CoverageMapError>(
974 coveragemap_error::malformed,
975 "the size of CoverageMapping is teoo small");
976 } else if (TestingVersion != uint64_t(TestingFormatVersion::Version1)) {
977 return make_error<CoverageMapError>(coveragemap_error::unsupported_version);
980 // Skip the padding bytes because coverage map data has an alignment of 8.
981 auto Pad = offsetToAlignedAddr(Data.data(), Align(8));
982 if (Data.size() < Pad)
983 return make_error<CoverageMapError>(coveragemap_error::malformed,
984 "insufficient padding");
985 Data = Data.substr(Pad);
986 if (Data.size() < sizeof(CovMapHeader))
987 return make_error<CoverageMapError>(
988 coveragemap_error::malformed,
989 "coverage mapping header section is larger than data size");
990 auto const *CovHeader = reinterpret_cast<const CovMapHeader *>(
991 Data.substr(0, sizeof(CovMapHeader)).data());
992 auto Version =
993 CovMapVersion(CovHeader->getVersion<llvm::endianness::little>());
995 // In Version1, the size of CoverageMapping is calculated.
996 if (TestingVersion == uint64_t(TestingFormatVersion::Version1)) {
997 if (Version < CovMapVersion::Version4) {
998 CoverageMappingSize = Data.size();
999 } else {
1000 auto FilenamesSize =
1001 CovHeader->getFilenamesSize<llvm::endianness::little>();
1002 CoverageMappingSize = sizeof(CovMapHeader) + FilenamesSize;
1006 auto CoverageMapping = Data.substr(0, CoverageMappingSize);
1007 Data = Data.substr(CoverageMappingSize);
1009 // Read the CoverageRecords data.
1010 if (Version < CovMapVersion::Version4) {
1011 if (!Data.empty())
1012 return make_error<CoverageMapError>(coveragemap_error::malformed,
1013 "data is not empty");
1014 } else {
1015 // Skip the padding bytes because coverage records data has an alignment
1016 // of 8.
1017 Pad = offsetToAlignedAddr(Data.data(), Align(8));
1018 if (Data.size() < Pad)
1019 return make_error<CoverageMapError>(coveragemap_error::malformed,
1020 "insufficient padding");
1021 Data = Data.substr(Pad);
1023 BinaryCoverageReader::FuncRecordsStorage CoverageRecords =
1024 MemoryBuffer::getMemBuffer(Data);
1026 return BinaryCoverageReader::createCoverageReaderFromBuffer(
1027 CoverageMapping, std::move(CoverageRecords), std::move(ProfileNames),
1028 BytesInAddress, Endian, CompilationDir);
1031 /// Find all sections that match \p IPSK name. There may be more than one if
1032 /// comdats are in use, e.g. for the __llvm_covfun section on ELF.
1033 static Expected<std::vector<SectionRef>>
1034 lookupSections(ObjectFile &OF, InstrProfSectKind IPSK) {
1035 auto ObjFormat = OF.getTripleObjectFormat();
1036 auto Name =
1037 getInstrProfSectionName(IPSK, ObjFormat, /*AddSegmentInfo=*/false);
1038 // On COFF, the object file section name may end in "$M". This tells the
1039 // linker to sort these sections between "$A" and "$Z". The linker removes the
1040 // dollar and everything after it in the final binary. Do the same to match.
1041 bool IsCOFF = isa<COFFObjectFile>(OF);
1042 auto stripSuffix = [IsCOFF](StringRef N) {
1043 return IsCOFF ? N.split('$').first : N;
1045 Name = stripSuffix(Name);
1047 std::vector<SectionRef> Sections;
1048 for (const auto &Section : OF.sections()) {
1049 Expected<StringRef> NameOrErr = Section.getName();
1050 if (!NameOrErr)
1051 return NameOrErr.takeError();
1052 if (stripSuffix(*NameOrErr) == Name) {
1053 // COFF profile name section contains two null bytes indicating the
1054 // start/end of the section. If its size is 2 bytes, it's empty.
1055 if (IsCOFF && IPSK == IPSK_name && Section.getSize() == 2)
1056 continue;
1057 Sections.push_back(Section);
1060 if (Sections.empty())
1061 return make_error<CoverageMapError>(coveragemap_error::no_data_found);
1062 return Sections;
1065 static Expected<std::unique_ptr<BinaryCoverageReader>>
1066 loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch,
1067 StringRef CompilationDir = "",
1068 object::BuildIDRef *BinaryID = nullptr) {
1069 std::unique_ptr<ObjectFile> OF;
1070 if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin.get())) {
1071 // If we have a universal binary, try to look up the object for the
1072 // appropriate architecture.
1073 auto ObjectFileOrErr = Universal->getMachOObjectForArch(Arch);
1074 if (!ObjectFileOrErr)
1075 return ObjectFileOrErr.takeError();
1076 OF = std::move(ObjectFileOrErr.get());
1077 } else if (isa<ObjectFile>(Bin.get())) {
1078 // For any other object file, upcast and take ownership.
1079 OF.reset(cast<ObjectFile>(Bin.release()));
1080 // If we've asked for a particular arch, make sure they match.
1081 if (!Arch.empty() && OF->getArch() != Triple(Arch).getArch())
1082 return errorCodeToError(object_error::arch_not_found);
1083 } else
1084 // We can only handle object files.
1085 return make_error<CoverageMapError>(coveragemap_error::malformed,
1086 "binary is not an object file");
1088 // The coverage uses native pointer sizes for the object it's written in.
1089 uint8_t BytesInAddress = OF->getBytesInAddress();
1090 llvm::endianness Endian =
1091 OF->isLittleEndian() ? llvm::endianness::little : llvm::endianness::big;
1093 // Look for the sections that we are interested in.
1094 InstrProfSymtab ProfileNames;
1095 std::vector<SectionRef> NamesSectionRefs;
1096 // If IPSK_name is not found, fallback to search for IPK_covname, which is
1097 // used when binary correlation is enabled.
1098 auto NamesSection = lookupSections(*OF, IPSK_name);
1099 if (auto E = NamesSection.takeError()) {
1100 consumeError(std::move(E));
1101 NamesSection = lookupSections(*OF, IPSK_covname);
1102 if (auto E = NamesSection.takeError())
1103 return std::move(E);
1105 NamesSectionRefs = *NamesSection;
1107 if (NamesSectionRefs.size() != 1)
1108 return make_error<CoverageMapError>(
1109 coveragemap_error::malformed,
1110 "the size of coverage mapping section is not one");
1111 if (Error E = ProfileNames.create(NamesSectionRefs.back()))
1112 return std::move(E);
1114 auto CoverageSection = lookupSections(*OF, IPSK_covmap);
1115 if (auto E = CoverageSection.takeError())
1116 return std::move(E);
1117 std::vector<SectionRef> CoverageSectionRefs = *CoverageSection;
1118 if (CoverageSectionRefs.size() != 1)
1119 return make_error<CoverageMapError>(coveragemap_error::malformed,
1120 "the size of name section is not one");
1121 auto CoverageMappingOrErr = CoverageSectionRefs.back().getContents();
1122 if (!CoverageMappingOrErr)
1123 return CoverageMappingOrErr.takeError();
1124 StringRef CoverageMapping = CoverageMappingOrErr.get();
1126 // Look for the coverage records section (Version4 only).
1127 auto CoverageRecordsSections = lookupSections(*OF, IPSK_covfun);
1129 BinaryCoverageReader::FuncRecordsStorage FuncRecords;
1130 if (auto E = CoverageRecordsSections.takeError()) {
1131 consumeError(std::move(E));
1132 FuncRecords = MemoryBuffer::getMemBuffer("");
1133 } else {
1134 // Compute the FuncRecordsBuffer of the buffer, taking into account the
1135 // padding between each record, and making sure the first block is aligned
1136 // in memory to maintain consistency between buffer address and size
1137 // alignment.
1138 const Align RecordAlignment(8);
1139 uint64_t FuncRecordsSize = 0;
1140 for (SectionRef Section : *CoverageRecordsSections) {
1141 auto CoverageRecordsOrErr = Section.getContents();
1142 if (!CoverageRecordsOrErr)
1143 return CoverageRecordsOrErr.takeError();
1144 FuncRecordsSize += alignTo(CoverageRecordsOrErr->size(), RecordAlignment);
1146 auto WritableBuffer =
1147 WritableMemoryBuffer::getNewUninitMemBuffer(FuncRecordsSize);
1148 char *FuncRecordsBuffer = WritableBuffer->getBufferStart();
1149 assert(isAddrAligned(RecordAlignment, FuncRecordsBuffer) &&
1150 "Allocated memory is correctly aligned");
1152 for (SectionRef Section : *CoverageRecordsSections) {
1153 auto CoverageRecordsOrErr = Section.getContents();
1154 if (!CoverageRecordsOrErr)
1155 return CoverageRecordsOrErr.takeError();
1156 const auto &CoverageRecords = CoverageRecordsOrErr.get();
1157 FuncRecordsBuffer = std::copy(CoverageRecords.begin(),
1158 CoverageRecords.end(), FuncRecordsBuffer);
1159 FuncRecordsBuffer =
1160 std::fill_n(FuncRecordsBuffer,
1161 alignAddr(FuncRecordsBuffer, RecordAlignment) -
1162 (uintptr_t)FuncRecordsBuffer,
1163 '\0');
1165 assert(FuncRecordsBuffer == WritableBuffer->getBufferEnd() &&
1166 "consistent init");
1167 FuncRecords = std::move(WritableBuffer);
1170 if (BinaryID)
1171 *BinaryID = getBuildID(OF.get());
1173 return BinaryCoverageReader::createCoverageReaderFromBuffer(
1174 CoverageMapping, std::move(FuncRecords), std::move(ProfileNames),
1175 BytesInAddress, Endian, CompilationDir);
1178 /// Determine whether \p Arch is invalid or empty, given \p Bin.
1179 static bool isArchSpecifierInvalidOrMissing(Binary *Bin, StringRef Arch) {
1180 // If we have a universal binary and Arch doesn't identify any of its slices,
1181 // it's user error.
1182 if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin)) {
1183 for (auto &ObjForArch : Universal->objects())
1184 if (Arch == ObjForArch.getArchFlagName())
1185 return false;
1186 return true;
1188 return false;
1191 Expected<std::vector<std::unique_ptr<BinaryCoverageReader>>>
1192 BinaryCoverageReader::create(
1193 MemoryBufferRef ObjectBuffer, StringRef Arch,
1194 SmallVectorImpl<std::unique_ptr<MemoryBuffer>> &ObjectFileBuffers,
1195 StringRef CompilationDir, SmallVectorImpl<object::BuildIDRef> *BinaryIDs) {
1196 std::vector<std::unique_ptr<BinaryCoverageReader>> Readers;
1198 if (ObjectBuffer.getBuffer().size() > sizeof(TestingFormatMagic)) {
1199 uint64_t Magic =
1200 support::endian::byte_swap<uint64_t, llvm::endianness::little>(
1201 *reinterpret_cast<const uint64_t *>(ObjectBuffer.getBufferStart()));
1202 if (Magic == TestingFormatMagic) {
1203 // This is a special format used for testing.
1204 auto ReaderOrErr =
1205 loadTestingFormat(ObjectBuffer.getBuffer(), CompilationDir);
1206 if (!ReaderOrErr)
1207 return ReaderOrErr.takeError();
1208 Readers.push_back(std::move(ReaderOrErr.get()));
1209 return std::move(Readers);
1213 auto BinOrErr = createBinary(ObjectBuffer);
1214 if (!BinOrErr)
1215 return BinOrErr.takeError();
1216 std::unique_ptr<Binary> Bin = std::move(BinOrErr.get());
1218 if (isArchSpecifierInvalidOrMissing(Bin.get(), Arch))
1219 return make_error<CoverageMapError>(
1220 coveragemap_error::invalid_or_missing_arch_specifier);
1222 // MachO universal binaries which contain archives need to be treated as
1223 // archives, not as regular binaries.
1224 if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin.get())) {
1225 for (auto &ObjForArch : Universal->objects()) {
1226 // Skip slices within the universal binary which target the wrong arch.
1227 std::string ObjArch = ObjForArch.getArchFlagName();
1228 if (Arch != ObjArch)
1229 continue;
1231 auto ArchiveOrErr = ObjForArch.getAsArchive();
1232 if (!ArchiveOrErr) {
1233 // If this is not an archive, try treating it as a regular object.
1234 consumeError(ArchiveOrErr.takeError());
1235 break;
1238 return BinaryCoverageReader::create(
1239 ArchiveOrErr.get()->getMemoryBufferRef(), Arch, ObjectFileBuffers,
1240 CompilationDir, BinaryIDs);
1244 // Load coverage out of archive members.
1245 if (auto *Ar = dyn_cast<Archive>(Bin.get())) {
1246 Error Err = Error::success();
1247 for (auto &Child : Ar->children(Err)) {
1248 Expected<MemoryBufferRef> ChildBufOrErr = Child.getMemoryBufferRef();
1249 if (!ChildBufOrErr)
1250 return ChildBufOrErr.takeError();
1252 auto ChildReadersOrErr = BinaryCoverageReader::create(
1253 ChildBufOrErr.get(), Arch, ObjectFileBuffers, CompilationDir,
1254 BinaryIDs);
1255 if (!ChildReadersOrErr)
1256 return ChildReadersOrErr.takeError();
1257 for (auto &Reader : ChildReadersOrErr.get())
1258 Readers.push_back(std::move(Reader));
1260 if (Err)
1261 return std::move(Err);
1263 // Thin archives reference object files outside of the archive file, i.e.
1264 // files which reside in memory not owned by the caller. Transfer ownership
1265 // to the caller.
1266 if (Ar->isThin())
1267 for (auto &Buffer : Ar->takeThinBuffers())
1268 ObjectFileBuffers.push_back(std::move(Buffer));
1270 return std::move(Readers);
1273 object::BuildIDRef BinaryID;
1274 auto ReaderOrErr = loadBinaryFormat(std::move(Bin), Arch, CompilationDir,
1275 BinaryIDs ? &BinaryID : nullptr);
1276 if (!ReaderOrErr)
1277 return ReaderOrErr.takeError();
1278 Readers.push_back(std::move(ReaderOrErr.get()));
1279 if (!BinaryID.empty())
1280 BinaryIDs->push_back(BinaryID);
1281 return std::move(Readers);
1284 Error BinaryCoverageReader::readNextRecord(CoverageMappingRecord &Record) {
1285 if (CurrentRecord >= MappingRecords.size())
1286 return make_error<CoverageMapError>(coveragemap_error::eof);
1288 FunctionsFilenames.clear();
1289 Expressions.clear();
1290 MappingRegions.clear();
1291 auto &R = MappingRecords[CurrentRecord];
1292 auto F = ArrayRef(Filenames).slice(R.FilenamesBegin, R.FilenamesSize);
1293 RawCoverageMappingReader Reader(R.CoverageMapping, F, FunctionsFilenames,
1294 Expressions, MappingRegions);
1295 if (auto Err = Reader.read())
1296 return Err;
1298 Record.FunctionName = R.FunctionName;
1299 Record.FunctionHash = R.FunctionHash;
1300 Record.Filenames = FunctionsFilenames;
1301 Record.Expressions = Expressions;
1302 Record.MappingRegions = MappingRegions;
1304 ++CurrentRecord;
1305 return Error::success();