Revert r354244 "[DAGCombiner] Eliminate dead stores to stack."
[llvm-complete.git] / lib / ProfileData / Coverage / CoverageMappingReader.cpp
blobaf09a611570938b881eb8c63bd888c12b22abd3b
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/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/ProfileData/InstrProf.h"
26 #include "llvm/Support/Casting.h"
27 #include "llvm/Support/Debug.h"
28 #include "llvm/Support/Endian.h"
29 #include "llvm/Support/Error.h"
30 #include "llvm/Support/ErrorHandling.h"
31 #include "llvm/Support/LEB128.h"
32 #include "llvm/Support/MathExtras.h"
33 #include "llvm/Support/raw_ostream.h"
34 #include <vector>
36 using namespace llvm;
37 using namespace coverage;
38 using namespace object;
40 #define DEBUG_TYPE "coverage-mapping"
42 void CoverageMappingIterator::increment() {
43 if (ReadErr != coveragemap_error::success)
44 return;
46 // Check if all the records were read or if an error occurred while reading
47 // the next record.
48 if (auto E = Reader->readNextRecord(Record))
49 handleAllErrors(std::move(E), [&](const CoverageMapError &CME) {
50 if (CME.get() == coveragemap_error::eof)
51 *this = CoverageMappingIterator();
52 else
53 ReadErr = CME.get();
54 });
57 Error RawCoverageReader::readULEB128(uint64_t &Result) {
58 if (Data.empty())
59 return make_error<CoverageMapError>(coveragemap_error::truncated);
60 unsigned N = 0;
61 Result = decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
62 if (N > Data.size())
63 return make_error<CoverageMapError>(coveragemap_error::malformed);
64 Data = Data.substr(N);
65 return Error::success();
68 Error RawCoverageReader::readIntMax(uint64_t &Result, uint64_t MaxPlus1) {
69 if (auto Err = readULEB128(Result))
70 return Err;
71 if (Result >= MaxPlus1)
72 return make_error<CoverageMapError>(coveragemap_error::malformed);
73 return Error::success();
76 Error RawCoverageReader::readSize(uint64_t &Result) {
77 if (auto Err = readULEB128(Result))
78 return Err;
79 // Sanity check the number.
80 if (Result > Data.size())
81 return make_error<CoverageMapError>(coveragemap_error::malformed);
82 return Error::success();
85 Error RawCoverageReader::readString(StringRef &Result) {
86 uint64_t Length;
87 if (auto Err = readSize(Length))
88 return Err;
89 Result = Data.substr(0, Length);
90 Data = Data.substr(Length);
91 return Error::success();
94 Error RawCoverageFilenamesReader::read() {
95 uint64_t NumFilenames;
96 if (auto Err = readSize(NumFilenames))
97 return Err;
98 for (size_t I = 0; I < NumFilenames; ++I) {
99 StringRef Filename;
100 if (auto Err = readString(Filename))
101 return Err;
102 Filenames.push_back(Filename);
104 return Error::success();
107 Error RawCoverageMappingReader::decodeCounter(unsigned Value, Counter &C) {
108 auto Tag = Value & Counter::EncodingTagMask;
109 switch (Tag) {
110 case Counter::Zero:
111 C = Counter::getZero();
112 return Error::success();
113 case Counter::CounterValueReference:
114 C = Counter::getCounter(Value >> Counter::EncodingTagBits);
115 return Error::success();
116 default:
117 break;
119 Tag -= Counter::Expression;
120 switch (Tag) {
121 case CounterExpression::Subtract:
122 case CounterExpression::Add: {
123 auto ID = Value >> Counter::EncodingTagBits;
124 if (ID >= Expressions.size())
125 return make_error<CoverageMapError>(coveragemap_error::malformed);
126 Expressions[ID].Kind = CounterExpression::ExprKind(Tag);
127 C = Counter::getExpression(ID);
128 break;
130 default:
131 return make_error<CoverageMapError>(coveragemap_error::malformed);
133 return Error::success();
136 Error RawCoverageMappingReader::readCounter(Counter &C) {
137 uint64_t EncodedCounter;
138 if (auto Err =
139 readIntMax(EncodedCounter, std::numeric_limits<unsigned>::max()))
140 return Err;
141 if (auto Err = decodeCounter(EncodedCounter, C))
142 return Err;
143 return Error::success();
146 static const unsigned EncodingExpansionRegionBit = 1
147 << Counter::EncodingTagBits;
149 /// Read the sub-array of regions for the given inferred file id.
150 /// \param NumFileIDs the number of file ids that are defined for this
151 /// function.
152 Error RawCoverageMappingReader::readMappingRegionsSubArray(
153 std::vector<CounterMappingRegion> &MappingRegions, unsigned InferredFileID,
154 size_t NumFileIDs) {
155 uint64_t NumRegions;
156 if (auto Err = readSize(NumRegions))
157 return Err;
158 unsigned LineStart = 0;
159 for (size_t I = 0; I < NumRegions; ++I) {
160 Counter C;
161 CounterMappingRegion::RegionKind Kind = CounterMappingRegion::CodeRegion;
163 // Read the combined counter + region kind.
164 uint64_t EncodedCounterAndRegion;
165 if (auto Err = readIntMax(EncodedCounterAndRegion,
166 std::numeric_limits<unsigned>::max()))
167 return Err;
168 unsigned Tag = EncodedCounterAndRegion & Counter::EncodingTagMask;
169 uint64_t ExpandedFileID = 0;
170 if (Tag != Counter::Zero) {
171 if (auto Err = decodeCounter(EncodedCounterAndRegion, C))
172 return Err;
173 } else {
174 // Is it an expansion region?
175 if (EncodedCounterAndRegion & EncodingExpansionRegionBit) {
176 Kind = CounterMappingRegion::ExpansionRegion;
177 ExpandedFileID = EncodedCounterAndRegion >>
178 Counter::EncodingCounterTagAndExpansionRegionTagBits;
179 if (ExpandedFileID >= NumFileIDs)
180 return make_error<CoverageMapError>(coveragemap_error::malformed);
181 } else {
182 switch (EncodedCounterAndRegion >>
183 Counter::EncodingCounterTagAndExpansionRegionTagBits) {
184 case CounterMappingRegion::CodeRegion:
185 // Don't do anything when we have a code region with a zero counter.
186 break;
187 case CounterMappingRegion::SkippedRegion:
188 Kind = CounterMappingRegion::SkippedRegion;
189 break;
190 default:
191 return make_error<CoverageMapError>(coveragemap_error::malformed);
196 // Read the source range.
197 uint64_t LineStartDelta, ColumnStart, NumLines, ColumnEnd;
198 if (auto Err =
199 readIntMax(LineStartDelta, std::numeric_limits<unsigned>::max()))
200 return Err;
201 if (auto Err = readULEB128(ColumnStart))
202 return Err;
203 if (ColumnStart > std::numeric_limits<unsigned>::max())
204 return make_error<CoverageMapError>(coveragemap_error::malformed);
205 if (auto Err = readIntMax(NumLines, std::numeric_limits<unsigned>::max()))
206 return Err;
207 if (auto Err = readIntMax(ColumnEnd, std::numeric_limits<unsigned>::max()))
208 return Err;
209 LineStart += LineStartDelta;
211 // If the high bit of ColumnEnd is set, this is a gap region.
212 if (ColumnEnd & (1U << 31)) {
213 Kind = CounterMappingRegion::GapRegion;
214 ColumnEnd &= ~(1U << 31);
217 // Adjust the column locations for the empty regions that are supposed to
218 // cover whole lines. Those regions should be encoded with the
219 // column range (1 -> std::numeric_limits<unsigned>::max()), but because
220 // the encoded std::numeric_limits<unsigned>::max() is several bytes long,
221 // we set the column range to (0 -> 0) to ensure that the column start and
222 // column end take up one byte each.
223 // The std::numeric_limits<unsigned>::max() is used to represent a column
224 // position at the end of the line without knowing the length of that line.
225 if (ColumnStart == 0 && ColumnEnd == 0) {
226 ColumnStart = 1;
227 ColumnEnd = std::numeric_limits<unsigned>::max();
230 LLVM_DEBUG({
231 dbgs() << "Counter in file " << InferredFileID << " " << LineStart << ":"
232 << ColumnStart << " -> " << (LineStart + NumLines) << ":"
233 << ColumnEnd << ", ";
234 if (Kind == CounterMappingRegion::ExpansionRegion)
235 dbgs() << "Expands to file " << ExpandedFileID;
236 else
237 CounterMappingContext(Expressions).dump(C, dbgs());
238 dbgs() << "\n";
241 auto CMR = CounterMappingRegion(C, InferredFileID, ExpandedFileID,
242 LineStart, ColumnStart,
243 LineStart + NumLines, ColumnEnd, Kind);
244 if (CMR.startLoc() > CMR.endLoc())
245 return make_error<CoverageMapError>(coveragemap_error::malformed);
246 MappingRegions.push_back(CMR);
248 return Error::success();
251 Error RawCoverageMappingReader::read() {
252 // Read the virtual file mapping.
253 SmallVector<unsigned, 8> VirtualFileMapping;
254 uint64_t NumFileMappings;
255 if (auto Err = readSize(NumFileMappings))
256 return Err;
257 for (size_t I = 0; I < NumFileMappings; ++I) {
258 uint64_t FilenameIndex;
259 if (auto Err = readIntMax(FilenameIndex, TranslationUnitFilenames.size()))
260 return Err;
261 VirtualFileMapping.push_back(FilenameIndex);
264 // Construct the files using unique filenames and virtual file mapping.
265 for (auto I : VirtualFileMapping) {
266 Filenames.push_back(TranslationUnitFilenames[I]);
269 // Read the expressions.
270 uint64_t NumExpressions;
271 if (auto Err = readSize(NumExpressions))
272 return Err;
273 // Create an array of dummy expressions that get the proper counters
274 // when the expressions are read, and the proper kinds when the counters
275 // are decoded.
276 Expressions.resize(
277 NumExpressions,
278 CounterExpression(CounterExpression::Subtract, Counter(), Counter()));
279 for (size_t I = 0; I < NumExpressions; ++I) {
280 if (auto Err = readCounter(Expressions[I].LHS))
281 return Err;
282 if (auto Err = readCounter(Expressions[I].RHS))
283 return Err;
286 // Read the mapping regions sub-arrays.
287 for (unsigned InferredFileID = 0, S = VirtualFileMapping.size();
288 InferredFileID < S; ++InferredFileID) {
289 if (auto Err = readMappingRegionsSubArray(MappingRegions, InferredFileID,
290 VirtualFileMapping.size()))
291 return Err;
294 // Set the counters for the expansion regions.
295 // i.e. Counter of expansion region = counter of the first region
296 // from the expanded file.
297 // Perform multiple passes to correctly propagate the counters through
298 // all the nested expansion regions.
299 SmallVector<CounterMappingRegion *, 8> FileIDExpansionRegionMapping;
300 FileIDExpansionRegionMapping.resize(VirtualFileMapping.size(), nullptr);
301 for (unsigned Pass = 1, S = VirtualFileMapping.size(); Pass < S; ++Pass) {
302 for (auto &R : MappingRegions) {
303 if (R.Kind != CounterMappingRegion::ExpansionRegion)
304 continue;
305 assert(!FileIDExpansionRegionMapping[R.ExpandedFileID]);
306 FileIDExpansionRegionMapping[R.ExpandedFileID] = &R;
308 for (auto &R : MappingRegions) {
309 if (FileIDExpansionRegionMapping[R.FileID]) {
310 FileIDExpansionRegionMapping[R.FileID]->Count = R.Count;
311 FileIDExpansionRegionMapping[R.FileID] = nullptr;
316 return Error::success();
319 Expected<bool> RawCoverageMappingDummyChecker::isDummy() {
320 // A dummy coverage mapping data consists of just one region with zero count.
321 uint64_t NumFileMappings;
322 if (Error Err = readSize(NumFileMappings))
323 return std::move(Err);
324 if (NumFileMappings != 1)
325 return false;
326 // We don't expect any specific value for the filename index, just skip it.
327 uint64_t FilenameIndex;
328 if (Error Err =
329 readIntMax(FilenameIndex, std::numeric_limits<unsigned>::max()))
330 return std::move(Err);
331 uint64_t NumExpressions;
332 if (Error Err = readSize(NumExpressions))
333 return std::move(Err);
334 if (NumExpressions != 0)
335 return false;
336 uint64_t NumRegions;
337 if (Error Err = readSize(NumRegions))
338 return std::move(Err);
339 if (NumRegions != 1)
340 return false;
341 uint64_t EncodedCounterAndRegion;
342 if (Error Err = readIntMax(EncodedCounterAndRegion,
343 std::numeric_limits<unsigned>::max()))
344 return std::move(Err);
345 unsigned Tag = EncodedCounterAndRegion & Counter::EncodingTagMask;
346 return Tag == Counter::Zero;
349 Error InstrProfSymtab::create(SectionRef &Section) {
350 if (auto EC = Section.getContents(Data))
351 return errorCodeToError(EC);
352 Address = Section.getAddress();
353 return Error::success();
356 StringRef InstrProfSymtab::getFuncName(uint64_t Pointer, size_t Size) {
357 if (Pointer < Address)
358 return StringRef();
359 auto Offset = Pointer - Address;
360 if (Offset + Size > Data.size())
361 return StringRef();
362 return Data.substr(Pointer - Address, Size);
365 // Check if the mapping data is a dummy, i.e. is emitted for an unused function.
366 static Expected<bool> isCoverageMappingDummy(uint64_t Hash, StringRef Mapping) {
367 // The hash value of dummy mapping records is always zero.
368 if (Hash)
369 return false;
370 return RawCoverageMappingDummyChecker(Mapping).isDummy();
373 namespace {
375 struct CovMapFuncRecordReader {
376 virtual ~CovMapFuncRecordReader() = default;
378 // The interface to read coverage mapping function records for a module.
380 // \p Buf points to the buffer containing the \c CovHeader of the coverage
381 // mapping data associated with the module.
383 // Returns a pointer to the next \c CovHeader if it exists, or a pointer
384 // greater than \p End if not.
385 virtual Expected<const char *> readFunctionRecords(const char *Buf,
386 const char *End) = 0;
388 template <class IntPtrT, support::endianness Endian>
389 static Expected<std::unique_ptr<CovMapFuncRecordReader>>
390 get(CovMapVersion Version, InstrProfSymtab &P,
391 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
392 std::vector<StringRef> &F);
395 // A class for reading coverage mapping function records for a module.
396 template <CovMapVersion Version, class IntPtrT, support::endianness Endian>
397 class VersionedCovMapFuncRecordReader : public CovMapFuncRecordReader {
398 using FuncRecordType =
399 typename CovMapTraits<Version, IntPtrT>::CovMapFuncRecordType;
400 using NameRefType = typename CovMapTraits<Version, IntPtrT>::NameRefType;
402 // Maps function's name references to the indexes of their records
403 // in \c Records.
404 DenseMap<NameRefType, size_t> FunctionRecords;
405 InstrProfSymtab &ProfileNames;
406 std::vector<StringRef> &Filenames;
407 std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records;
409 // Add the record to the collection if we don't already have a record that
410 // points to the same function name. This is useful to ignore the redundant
411 // records for the functions with ODR linkage.
412 // In addition, prefer records with real coverage mapping data to dummy
413 // records, which were emitted for inline functions which were seen but
414 // not used in the corresponding translation unit.
415 Error insertFunctionRecordIfNeeded(const FuncRecordType *CFR,
416 StringRef Mapping, size_t FilenamesBegin) {
417 uint64_t FuncHash = CFR->template getFuncHash<Endian>();
418 NameRefType NameRef = CFR->template getFuncNameRef<Endian>();
419 auto InsertResult =
420 FunctionRecords.insert(std::make_pair(NameRef, Records.size()));
421 if (InsertResult.second) {
422 StringRef FuncName;
423 if (Error Err = CFR->template getFuncName<Endian>(ProfileNames, FuncName))
424 return Err;
425 if (FuncName.empty())
426 return make_error<InstrProfError>(instrprof_error::malformed);
427 Records.emplace_back(Version, FuncName, FuncHash, Mapping, FilenamesBegin,
428 Filenames.size() - FilenamesBegin);
429 return Error::success();
431 // Update the existing record if it's a dummy and the new record is real.
432 size_t OldRecordIndex = InsertResult.first->second;
433 BinaryCoverageReader::ProfileMappingRecord &OldRecord =
434 Records[OldRecordIndex];
435 Expected<bool> OldIsDummyExpected = isCoverageMappingDummy(
436 OldRecord.FunctionHash, OldRecord.CoverageMapping);
437 if (Error Err = OldIsDummyExpected.takeError())
438 return Err;
439 if (!*OldIsDummyExpected)
440 return Error::success();
441 Expected<bool> NewIsDummyExpected =
442 isCoverageMappingDummy(FuncHash, Mapping);
443 if (Error Err = NewIsDummyExpected.takeError())
444 return Err;
445 if (*NewIsDummyExpected)
446 return Error::success();
447 OldRecord.FunctionHash = FuncHash;
448 OldRecord.CoverageMapping = Mapping;
449 OldRecord.FilenamesBegin = FilenamesBegin;
450 OldRecord.FilenamesSize = Filenames.size() - FilenamesBegin;
451 return Error::success();
454 public:
455 VersionedCovMapFuncRecordReader(
456 InstrProfSymtab &P,
457 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
458 std::vector<StringRef> &F)
459 : ProfileNames(P), Filenames(F), Records(R) {}
461 ~VersionedCovMapFuncRecordReader() override = default;
463 Expected<const char *> readFunctionRecords(const char *Buf,
464 const char *End) override {
465 using namespace support;
467 if (Buf + sizeof(CovMapHeader) > End)
468 return make_error<CoverageMapError>(coveragemap_error::malformed);
469 auto CovHeader = reinterpret_cast<const CovMapHeader *>(Buf);
470 uint32_t NRecords = CovHeader->getNRecords<Endian>();
471 uint32_t FilenamesSize = CovHeader->getFilenamesSize<Endian>();
472 uint32_t CoverageSize = CovHeader->getCoverageSize<Endian>();
473 assert((CovMapVersion)CovHeader->getVersion<Endian>() == Version);
474 Buf = reinterpret_cast<const char *>(CovHeader + 1);
476 // Skip past the function records, saving the start and end for later.
477 const char *FunBuf = Buf;
478 Buf += NRecords * sizeof(FuncRecordType);
479 const char *FunEnd = Buf;
481 // Get the filenames.
482 if (Buf + FilenamesSize > End)
483 return make_error<CoverageMapError>(coveragemap_error::malformed);
484 size_t FilenamesBegin = Filenames.size();
485 RawCoverageFilenamesReader Reader(StringRef(Buf, FilenamesSize), Filenames);
486 if (auto Err = Reader.read())
487 return std::move(Err);
488 Buf += FilenamesSize;
490 // We'll read the coverage mapping records in the loop below.
491 const char *CovBuf = Buf;
492 Buf += CoverageSize;
493 const char *CovEnd = Buf;
495 if (Buf > End)
496 return make_error<CoverageMapError>(coveragemap_error::malformed);
497 // Each coverage map has an alignment of 8, so we need to adjust alignment
498 // before reading the next map.
499 Buf += alignmentAdjustment(Buf, 8);
501 auto CFR = reinterpret_cast<const FuncRecordType *>(FunBuf);
502 while ((const char *)CFR < FunEnd) {
503 // Read the function information
504 uint32_t DataSize = CFR->template getDataSize<Endian>();
506 // Now use that to read the coverage data.
507 if (CovBuf + DataSize > CovEnd)
508 return make_error<CoverageMapError>(coveragemap_error::malformed);
509 auto Mapping = StringRef(CovBuf, DataSize);
510 CovBuf += DataSize;
512 if (Error Err =
513 insertFunctionRecordIfNeeded(CFR, Mapping, FilenamesBegin))
514 return std::move(Err);
515 CFR++;
517 return Buf;
521 } // end anonymous namespace
523 template <class IntPtrT, support::endianness Endian>
524 Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get(
525 CovMapVersion Version, InstrProfSymtab &P,
526 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
527 std::vector<StringRef> &F) {
528 using namespace coverage;
530 switch (Version) {
531 case CovMapVersion::Version1:
532 return llvm::make_unique<VersionedCovMapFuncRecordReader<
533 CovMapVersion::Version1, IntPtrT, Endian>>(P, R, F);
534 case CovMapVersion::Version2:
535 case CovMapVersion::Version3:
536 // Decompress the name data.
537 if (Error E = P.create(P.getNameData()))
538 return std::move(E);
539 if (Version == CovMapVersion::Version2)
540 return llvm::make_unique<VersionedCovMapFuncRecordReader<
541 CovMapVersion::Version2, IntPtrT, Endian>>(P, R, F);
542 else
543 return llvm::make_unique<VersionedCovMapFuncRecordReader<
544 CovMapVersion::Version3, IntPtrT, Endian>>(P, R, F);
546 llvm_unreachable("Unsupported version");
549 template <typename T, support::endianness Endian>
550 static Error readCoverageMappingData(
551 InstrProfSymtab &ProfileNames, StringRef Data,
552 std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
553 std::vector<StringRef> &Filenames) {
554 using namespace coverage;
556 // Read the records in the coverage data section.
557 auto CovHeader =
558 reinterpret_cast<const CovMapHeader *>(Data.data());
559 CovMapVersion Version = (CovMapVersion)CovHeader->getVersion<Endian>();
560 if (Version > CovMapVersion::CurrentVersion)
561 return make_error<CoverageMapError>(coveragemap_error::unsupported_version);
562 Expected<std::unique_ptr<CovMapFuncRecordReader>> ReaderExpected =
563 CovMapFuncRecordReader::get<T, Endian>(Version, ProfileNames, Records,
564 Filenames);
565 if (Error E = ReaderExpected.takeError())
566 return E;
567 auto Reader = std::move(ReaderExpected.get());
568 for (const char *Buf = Data.data(), *End = Buf + Data.size(); Buf < End;) {
569 auto NextHeaderOrErr = Reader->readFunctionRecords(Buf, End);
570 if (auto E = NextHeaderOrErr.takeError())
571 return E;
572 Buf = NextHeaderOrErr.get();
574 return Error::success();
577 static const char *TestingFormatMagic = "llvmcovmtestdata";
579 static Error loadTestingFormat(StringRef Data, InstrProfSymtab &ProfileNames,
580 StringRef &CoverageMapping,
581 uint8_t &BytesInAddress,
582 support::endianness &Endian) {
583 BytesInAddress = 8;
584 Endian = support::endianness::little;
586 Data = Data.substr(StringRef(TestingFormatMagic).size());
587 if (Data.empty())
588 return make_error<CoverageMapError>(coveragemap_error::truncated);
589 unsigned N = 0;
590 auto ProfileNamesSize =
591 decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
592 if (N > Data.size())
593 return make_error<CoverageMapError>(coveragemap_error::malformed);
594 Data = Data.substr(N);
595 if (Data.empty())
596 return make_error<CoverageMapError>(coveragemap_error::truncated);
597 N = 0;
598 uint64_t Address =
599 decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
600 if (N > Data.size())
601 return make_error<CoverageMapError>(coveragemap_error::malformed);
602 Data = Data.substr(N);
603 if (Data.size() < ProfileNamesSize)
604 return make_error<CoverageMapError>(coveragemap_error::malformed);
605 if (Error E = ProfileNames.create(Data.substr(0, ProfileNamesSize), Address))
606 return E;
607 CoverageMapping = Data.substr(ProfileNamesSize);
608 // Skip the padding bytes because coverage map data has an alignment of 8.
609 if (CoverageMapping.empty())
610 return make_error<CoverageMapError>(coveragemap_error::truncated);
611 size_t Pad = alignmentAdjustment(CoverageMapping.data(), 8);
612 if (CoverageMapping.size() < Pad)
613 return make_error<CoverageMapError>(coveragemap_error::malformed);
614 CoverageMapping = CoverageMapping.substr(Pad);
615 return Error::success();
618 static Expected<SectionRef> lookupSection(ObjectFile &OF, StringRef Name) {
619 StringRef FoundName;
620 for (const auto &Section : OF.sections()) {
621 if (auto EC = Section.getName(FoundName))
622 return errorCodeToError(EC);
623 if (FoundName == Name)
624 return Section;
626 return make_error<CoverageMapError>(coveragemap_error::no_data_found);
629 static Error loadBinaryFormat(MemoryBufferRef ObjectBuffer,
630 InstrProfSymtab &ProfileNames,
631 StringRef &CoverageMapping,
632 uint8_t &BytesInAddress,
633 support::endianness &Endian, StringRef Arch) {
634 auto BinOrErr = createBinary(ObjectBuffer);
635 if (!BinOrErr)
636 return BinOrErr.takeError();
637 auto Bin = std::move(BinOrErr.get());
638 std::unique_ptr<ObjectFile> OF;
639 if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin.get())) {
640 // If we have a universal binary, try to look up the object for the
641 // appropriate architecture.
642 auto ObjectFileOrErr = Universal->getObjectForArch(Arch);
643 if (!ObjectFileOrErr)
644 return ObjectFileOrErr.takeError();
645 OF = std::move(ObjectFileOrErr.get());
646 } else if (isa<ObjectFile>(Bin.get())) {
647 // For any other object file, upcast and take ownership.
648 OF.reset(cast<ObjectFile>(Bin.release()));
649 // If we've asked for a particular arch, make sure they match.
650 if (!Arch.empty() && OF->getArch() != Triple(Arch).getArch())
651 return errorCodeToError(object_error::arch_not_found);
652 } else
653 // We can only handle object files.
654 return make_error<CoverageMapError>(coveragemap_error::malformed);
656 // The coverage uses native pointer sizes for the object it's written in.
657 BytesInAddress = OF->getBytesInAddress();
658 Endian = OF->isLittleEndian() ? support::endianness::little
659 : support::endianness::big;
661 // Look for the sections that we are interested in.
662 auto ObjFormat = OF->getTripleObjectFormat();
663 auto NamesSection =
664 lookupSection(*OF, getInstrProfSectionName(IPSK_name, ObjFormat,
665 /*AddSegmentInfo=*/false));
666 if (auto E = NamesSection.takeError())
667 return E;
668 auto CoverageSection =
669 lookupSection(*OF, getInstrProfSectionName(IPSK_covmap, ObjFormat,
670 /*AddSegmentInfo=*/false));
671 if (auto E = CoverageSection.takeError())
672 return E;
674 // Get the contents of the given sections.
675 if (auto EC = CoverageSection->getContents(CoverageMapping))
676 return errorCodeToError(EC);
677 if (Error E = ProfileNames.create(*NamesSection))
678 return E;
680 return Error::success();
683 Expected<std::unique_ptr<BinaryCoverageReader>>
684 BinaryCoverageReader::create(std::unique_ptr<MemoryBuffer> &ObjectBuffer,
685 StringRef Arch) {
686 std::unique_ptr<BinaryCoverageReader> Reader(new BinaryCoverageReader());
688 StringRef Coverage;
689 uint8_t BytesInAddress;
690 support::endianness Endian;
691 Error E = Error::success();
692 consumeError(std::move(E));
693 if (ObjectBuffer->getBuffer().startswith(TestingFormatMagic))
694 // This is a special format used for testing.
695 E = loadTestingFormat(ObjectBuffer->getBuffer(), Reader->ProfileNames,
696 Coverage, BytesInAddress, Endian);
697 else
698 E = loadBinaryFormat(ObjectBuffer->getMemBufferRef(), Reader->ProfileNames,
699 Coverage, BytesInAddress, Endian, Arch);
700 if (E)
701 return std::move(E);
703 if (BytesInAddress == 4 && Endian == support::endianness::little)
704 E = readCoverageMappingData<uint32_t, support::endianness::little>(
705 Reader->ProfileNames, Coverage, Reader->MappingRecords,
706 Reader->Filenames);
707 else if (BytesInAddress == 4 && Endian == support::endianness::big)
708 E = readCoverageMappingData<uint32_t, support::endianness::big>(
709 Reader->ProfileNames, Coverage, Reader->MappingRecords,
710 Reader->Filenames);
711 else if (BytesInAddress == 8 && Endian == support::endianness::little)
712 E = readCoverageMappingData<uint64_t, support::endianness::little>(
713 Reader->ProfileNames, Coverage, Reader->MappingRecords,
714 Reader->Filenames);
715 else if (BytesInAddress == 8 && Endian == support::endianness::big)
716 E = readCoverageMappingData<uint64_t, support::endianness::big>(
717 Reader->ProfileNames, Coverage, Reader->MappingRecords,
718 Reader->Filenames);
719 else
720 return make_error<CoverageMapError>(coveragemap_error::malformed);
721 if (E)
722 return std::move(E);
723 return std::move(Reader);
726 Error BinaryCoverageReader::readNextRecord(CoverageMappingRecord &Record) {
727 if (CurrentRecord >= MappingRecords.size())
728 return make_error<CoverageMapError>(coveragemap_error::eof);
730 FunctionsFilenames.clear();
731 Expressions.clear();
732 MappingRegions.clear();
733 auto &R = MappingRecords[CurrentRecord];
734 RawCoverageMappingReader Reader(
735 R.CoverageMapping,
736 makeArrayRef(Filenames).slice(R.FilenamesBegin, R.FilenamesSize),
737 FunctionsFilenames, Expressions, MappingRegions);
738 if (auto Err = Reader.read())
739 return Err;
741 Record.FunctionName = R.FunctionName;
742 Record.FunctionHash = R.FunctionHash;
743 Record.Filenames = FunctionsFilenames;
744 Record.Expressions = Expressions;
745 Record.MappingRegions = MappingRegions;
747 ++CurrentRecord;
748 return Error::success();