LLVM  4.0.0
CoverageMappingReader.cpp
Go to the documentation of this file.
1 //=-- CoverageMappingReader.cpp - Code coverage mapping reader ----*- C++ -*-=//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains support for reading coverage mapping data for
11 // instrumentation based coverage.
12 //
13 //===----------------------------------------------------------------------===//
14 
16 #include "llvm/ADT/DenseMap.h"
18 #include "llvm/Object/ObjectFile.h"
19 #include "llvm/Support/Debug.h"
20 #include "llvm/Support/Endian.h"
21 #include "llvm/Support/LEB128.h"
24 
25 using namespace llvm;
26 using namespace coverage;
27 using namespace object;
28 
29 #define DEBUG_TYPE "coverage-mapping"
30 
31 void CoverageMappingIterator::increment() {
32  // Check if all the records were read or if an error occurred while reading
33  // the next record.
34  if (auto E = Reader->readNextRecord(Record)) {
35  handleAllErrors(std::move(E), [&](const CoverageMapError &CME) {
36  if (CME.get() == coveragemap_error::eof)
37  *this = CoverageMappingIterator();
38  else
39  llvm_unreachable("Unexpected error in coverage mapping iterator");
40  });
41  }
42 }
43 
45  if (Data.size() < 1)
46  return make_error<CoverageMapError>(coveragemap_error::truncated);
47  unsigned N = 0;
48  Result = decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
49  if (N > Data.size())
50  return make_error<CoverageMapError>(coveragemap_error::malformed);
51  Data = Data.substr(N);
52  return Error::success();
53 }
54 
55 Error RawCoverageReader::readIntMax(uint64_t &Result, uint64_t MaxPlus1) {
56  if (auto Err = readULEB128(Result))
57  return Err;
58  if (Result >= MaxPlus1)
59  return make_error<CoverageMapError>(coveragemap_error::malformed);
60  return Error::success();
61 }
62 
64  if (auto Err = readULEB128(Result))
65  return Err;
66  // Sanity check the number.
67  if (Result > Data.size())
68  return make_error<CoverageMapError>(coveragemap_error::malformed);
69  return Error::success();
70 }
71 
73  uint64_t Length;
74  if (auto Err = readSize(Length))
75  return Err;
76  Result = Data.substr(0, Length);
77  Data = Data.substr(Length);
78  return Error::success();
79 }
80 
82  uint64_t NumFilenames;
83  if (auto Err = readSize(NumFilenames))
84  return Err;
85  for (size_t I = 0; I < NumFilenames; ++I) {
86  StringRef Filename;
87  if (auto Err = readString(Filename))
88  return Err;
89  Filenames.push_back(Filename);
90  }
91  return Error::success();
92 }
93 
94 Error RawCoverageMappingReader::decodeCounter(unsigned Value, Counter &C) {
95  auto Tag = Value & Counter::EncodingTagMask;
96  switch (Tag) {
97  case Counter::Zero:
98  C = Counter::getZero();
99  return Error::success();
102  return Error::success();
103  default:
104  break;
105  }
107  switch (Tag) {
109  case CounterExpression::Add: {
110  auto ID = Value >> Counter::EncodingTagBits;
111  if (ID >= Expressions.size())
112  return make_error<CoverageMapError>(coveragemap_error::malformed);
115  break;
116  }
117  default:
118  return make_error<CoverageMapError>(coveragemap_error::malformed);
119  }
120  return Error::success();
121 }
122 
123 Error RawCoverageMappingReader::readCounter(Counter &C) {
124  uint64_t EncodedCounter;
125  if (auto Err =
126  readIntMax(EncodedCounter, std::numeric_limits<unsigned>::max()))
127  return Err;
128  if (auto Err = decodeCounter(EncodedCounter, C))
129  return Err;
130  return Error::success();
131 }
132 
133 static const unsigned EncodingExpansionRegionBit = 1
135 
136 /// \brief Read the sub-array of regions for the given inferred file id.
137 /// \param NumFileIDs the number of file ids that are defined for this
138 /// function.
139 Error RawCoverageMappingReader::readMappingRegionsSubArray(
140  std::vector<CounterMappingRegion> &MappingRegions, unsigned InferredFileID,
141  size_t NumFileIDs) {
142  uint64_t NumRegions;
143  if (auto Err = readSize(NumRegions))
144  return Err;
145  unsigned LineStart = 0;
146  for (size_t I = 0; I < NumRegions; ++I) {
147  Counter C;
149 
150  // Read the combined counter + region kind.
151  uint64_t EncodedCounterAndRegion;
152  if (auto Err = readIntMax(EncodedCounterAndRegion,
153  std::numeric_limits<unsigned>::max()))
154  return Err;
155  unsigned Tag = EncodedCounterAndRegion & Counter::EncodingTagMask;
156  uint64_t ExpandedFileID = 0;
157  if (Tag != Counter::Zero) {
158  if (auto Err = decodeCounter(EncodedCounterAndRegion, C))
159  return Err;
160  } else {
161  // Is it an expansion region?
162  if (EncodedCounterAndRegion & EncodingExpansionRegionBit) {
164  ExpandedFileID = EncodedCounterAndRegion >>
166  if (ExpandedFileID >= NumFileIDs)
167  return make_error<CoverageMapError>(coveragemap_error::malformed);
168  } else {
169  switch (EncodedCounterAndRegion >>
172  // Don't do anything when we have a code region with a zero counter.
173  break;
176  break;
177  default:
178  return make_error<CoverageMapError>(coveragemap_error::malformed);
179  }
180  }
181  }
182 
183  // Read the source range.
184  uint64_t LineStartDelta, ColumnStart, NumLines, ColumnEnd;
185  if (auto Err =
186  readIntMax(LineStartDelta, std::numeric_limits<unsigned>::max()))
187  return Err;
188  if (auto Err = readULEB128(ColumnStart))
189  return Err;
190  if (ColumnStart > std::numeric_limits<unsigned>::max())
191  return make_error<CoverageMapError>(coveragemap_error::malformed);
192  if (auto Err = readIntMax(NumLines, std::numeric_limits<unsigned>::max()))
193  return Err;
194  if (auto Err = readIntMax(ColumnEnd, std::numeric_limits<unsigned>::max()))
195  return Err;
196  LineStart += LineStartDelta;
197  // Adjust the column locations for the empty regions that are supposed to
198  // cover whole lines. Those regions should be encoded with the
199  // column range (1 -> std::numeric_limits<unsigned>::max()), but because
200  // the encoded std::numeric_limits<unsigned>::max() is several bytes long,
201  // we set the column range to (0 -> 0) to ensure that the column start and
202  // column end take up one byte each.
203  // The std::numeric_limits<unsigned>::max() is used to represent a column
204  // position at the end of the line without knowing the length of that line.
205  if (ColumnStart == 0 && ColumnEnd == 0) {
206  ColumnStart = 1;
207  ColumnEnd = std::numeric_limits<unsigned>::max();
208  }
209 
210  DEBUG({
211  dbgs() << "Counter in file " << InferredFileID << " " << LineStart << ":"
212  << ColumnStart << " -> " << (LineStart + NumLines) << ":"
213  << ColumnEnd << ", ";
215  dbgs() << "Expands to file " << ExpandedFileID;
216  else
218  dbgs() << "\n";
219  });
220 
221  MappingRegions.push_back(CounterMappingRegion(
222  C, InferredFileID, ExpandedFileID, LineStart, ColumnStart,
223  LineStart + NumLines, ColumnEnd, Kind));
224  }
225  return Error::success();
226 }
227 
229 
230  // Read the virtual file mapping.
231  llvm::SmallVector<unsigned, 8> VirtualFileMapping;
232  uint64_t NumFileMappings;
233  if (auto Err = readSize(NumFileMappings))
234  return Err;
235  for (size_t I = 0; I < NumFileMappings; ++I) {
236  uint64_t FilenameIndex;
237  if (auto Err = readIntMax(FilenameIndex, TranslationUnitFilenames.size()))
238  return Err;
239  VirtualFileMapping.push_back(FilenameIndex);
240  }
241 
242  // Construct the files using unique filenames and virtual file mapping.
243  for (auto I : VirtualFileMapping) {
244  Filenames.push_back(TranslationUnitFilenames[I]);
245  }
246 
247  // Read the expressions.
248  uint64_t NumExpressions;
249  if (auto Err = readSize(NumExpressions))
250  return Err;
251  // Create an array of dummy expressions that get the proper counters
252  // when the expressions are read, and the proper kinds when the counters
253  // are decoded.
254  Expressions.resize(
255  NumExpressions,
257  for (size_t I = 0; I < NumExpressions; ++I) {
258  if (auto Err = readCounter(Expressions[I].LHS))
259  return Err;
260  if (auto Err = readCounter(Expressions[I].RHS))
261  return Err;
262  }
263 
264  // Read the mapping regions sub-arrays.
265  for (unsigned InferredFileID = 0, S = VirtualFileMapping.size();
266  InferredFileID < S; ++InferredFileID) {
267  if (auto Err = readMappingRegionsSubArray(MappingRegions, InferredFileID,
268  VirtualFileMapping.size()))
269  return Err;
270  }
271 
272  // Set the counters for the expansion regions.
273  // i.e. Counter of expansion region = counter of the first region
274  // from the expanded file.
275  // Perform multiple passes to correctly propagate the counters through
276  // all the nested expansion regions.
277  SmallVector<CounterMappingRegion *, 8> FileIDExpansionRegionMapping;
278  FileIDExpansionRegionMapping.resize(VirtualFileMapping.size(), nullptr);
279  for (unsigned Pass = 1, S = VirtualFileMapping.size(); Pass < S; ++Pass) {
280  for (auto &R : MappingRegions) {
282  continue;
283  assert(!FileIDExpansionRegionMapping[R.ExpandedFileID]);
284  FileIDExpansionRegionMapping[R.ExpandedFileID] = &R;
285  }
286  for (auto &R : MappingRegions) {
287  if (FileIDExpansionRegionMapping[R.FileID]) {
288  FileIDExpansionRegionMapping[R.FileID]->Count = R.Count;
289  FileIDExpansionRegionMapping[R.FileID] = nullptr;
290  }
291  }
292  }
293 
294  return Error::success();
295 }
296 
298  // A dummy coverage mapping data consists of just one region with zero count.
299  uint64_t NumFileMappings;
300  if (Error Err = readSize(NumFileMappings))
301  return std::move(Err);
302  if (NumFileMappings != 1)
303  return false;
304  // We don't expect any specific value for the filename index, just skip it.
305  uint64_t FilenameIndex;
306  if (Error Err =
307  readIntMax(FilenameIndex, std::numeric_limits<unsigned>::max()))
308  return std::move(Err);
309  uint64_t NumExpressions;
310  if (Error Err = readSize(NumExpressions))
311  return std::move(Err);
312  if (NumExpressions != 0)
313  return false;
314  uint64_t NumRegions;
315  if (Error Err = readSize(NumRegions))
316  return std::move(Err);
317  if (NumRegions != 1)
318  return false;
319  uint64_t EncodedCounterAndRegion;
320  if (Error Err = readIntMax(EncodedCounterAndRegion,
321  std::numeric_limits<unsigned>::max()))
322  return std::move(Err);
323  unsigned Tag = EncodedCounterAndRegion & Counter::EncodingTagMask;
324  return Tag == Counter::Zero;
325 }
326 
328  if (auto EC = Section.getContents(Data))
329  return errorCodeToError(EC);
330  Address = Section.getAddress();
331  return Error::success();
332 }
333 
334 StringRef InstrProfSymtab::getFuncName(uint64_t Pointer, size_t Size) {
335  if (Pointer < Address)
336  return StringRef();
337  auto Offset = Pointer - Address;
338  if (Offset + Size > Data.size())
339  return StringRef();
340  return Data.substr(Pointer - Address, Size);
341 }
342 
343 // Check if the mapping data is a dummy, i.e. is emitted for an unused function.
345  // The hash value of dummy mapping records is always zero.
346  if (Hash)
347  return false;
348  return RawCoverageMappingDummyChecker(Mapping).isDummy();
349 }
350 
351 namespace {
352 struct CovMapFuncRecordReader {
353  // The interface to read coverage mapping function records for a module.
354  //
355  // \p Buf points to the buffer containing the \c CovHeader of the coverage
356  // mapping data associated with the module.
357  //
358  // Returns a pointer to the next \c CovHeader if it exists, or a pointer
359  // greater than \p End if not.
360  virtual Expected<const char *> readFunctionRecords(const char *Buf,
361  const char *End) = 0;
362  virtual ~CovMapFuncRecordReader() {}
363  template <class IntPtrT, support::endianness Endian>
366  std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
367  std::vector<StringRef> &F);
368 };
369 
370 // A class for reading coverage mapping function records for a module.
371 template <coverage::CovMapVersion Version, class IntPtrT,
372  support::endianness Endian>
373 class VersionedCovMapFuncRecordReader : public CovMapFuncRecordReader {
374  typedef typename coverage::CovMapTraits<
375  Version, IntPtrT>::CovMapFuncRecordType FuncRecordType;
377  NameRefType;
378 
379  // Maps function's name references to the indexes of their records
380  // in \c Records.
381  llvm::DenseMap<NameRefType, size_t> FunctionRecords;
382  InstrProfSymtab &ProfileNames;
383  std::vector<StringRef> &Filenames;
384  std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records;
385 
386  // Add the record to the collection if we don't already have a record that
387  // points to the same function name. This is useful to ignore the redundant
388  // records for the functions with ODR linkage.
389  // In addition, prefer records with real coverage mapping data to dummy
390  // records, which were emitted for inline functions which were seen but
391  // not used in the corresponding translation unit.
392  Error insertFunctionRecordIfNeeded(const FuncRecordType *CFR,
393  StringRef Mapping, size_t FilenamesBegin) {
394  uint64_t FuncHash = CFR->template getFuncHash<Endian>();
395  NameRefType NameRef = CFR->template getFuncNameRef<Endian>();
396  auto InsertResult =
397  FunctionRecords.insert(std::make_pair(NameRef, Records.size()));
398  if (InsertResult.second) {
399  StringRef FuncName;
400  if (Error Err = CFR->template getFuncName<Endian>(ProfileNames, FuncName))
401  return Err;
402  Records.emplace_back(Version, FuncName, FuncHash, Mapping, FilenamesBegin,
403  Filenames.size() - FilenamesBegin);
404  return Error::success();
405  }
406  // Update the existing record if it's a dummy and the new record is real.
407  size_t OldRecordIndex = InsertResult.first->second;
409  Records[OldRecordIndex];
410  Expected<bool> OldIsDummyExpected = isCoverageMappingDummy(
411  OldRecord.FunctionHash, OldRecord.CoverageMapping);
412  if (Error Err = OldIsDummyExpected.takeError())
413  return Err;
414  if (!*OldIsDummyExpected)
415  return Error::success();
416  Expected<bool> NewIsDummyExpected =
417  isCoverageMappingDummy(FuncHash, Mapping);
418  if (Error Err = NewIsDummyExpected.takeError())
419  return Err;
420  if (*NewIsDummyExpected)
421  return Error::success();
422  OldRecord.FunctionHash = FuncHash;
423  OldRecord.CoverageMapping = Mapping;
424  OldRecord.FilenamesBegin = FilenamesBegin;
425  OldRecord.FilenamesSize = Filenames.size() - FilenamesBegin;
426  return Error::success();
427  }
428 
429 public:
430  VersionedCovMapFuncRecordReader(
432  std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
433  std::vector<StringRef> &F)
434  : ProfileNames(P), Filenames(F), Records(R) {}
435  ~VersionedCovMapFuncRecordReader() override {}
436 
437  Expected<const char *> readFunctionRecords(const char *Buf,
438  const char *End) override {
439  using namespace support;
440  if (Buf + sizeof(CovMapHeader) > End)
441  return make_error<CoverageMapError>(coveragemap_error::malformed);
442  auto CovHeader = reinterpret_cast<const coverage::CovMapHeader *>(Buf);
443  uint32_t NRecords = CovHeader->getNRecords<Endian>();
444  uint32_t FilenamesSize = CovHeader->getFilenamesSize<Endian>();
445  uint32_t CoverageSize = CovHeader->getCoverageSize<Endian>();
446  assert((CovMapVersion)CovHeader->getVersion<Endian>() == Version);
447  Buf = reinterpret_cast<const char *>(CovHeader + 1);
448 
449  // Skip past the function records, saving the start and end for later.
450  const char *FunBuf = Buf;
451  Buf += NRecords * sizeof(FuncRecordType);
452  const char *FunEnd = Buf;
453 
454  // Get the filenames.
455  if (Buf + FilenamesSize > End)
456  return make_error<CoverageMapError>(coveragemap_error::malformed);
457  size_t FilenamesBegin = Filenames.size();
458  RawCoverageFilenamesReader Reader(StringRef(Buf, FilenamesSize), Filenames);
459  if (auto Err = Reader.read())
460  return std::move(Err);
461  Buf += FilenamesSize;
462 
463  // We'll read the coverage mapping records in the loop below.
464  const char *CovBuf = Buf;
465  Buf += CoverageSize;
466  const char *CovEnd = Buf;
467 
468  if (Buf > End)
469  return make_error<CoverageMapError>(coveragemap_error::malformed);
470  // Each coverage map has an alignment of 8, so we need to adjust alignment
471  // before reading the next map.
472  Buf += alignmentAdjustment(Buf, 8);
473 
474  auto CFR = reinterpret_cast<const FuncRecordType *>(FunBuf);
475  while ((const char *)CFR < FunEnd) {
476  // Read the function information
477  uint32_t DataSize = CFR->template getDataSize<Endian>();
478 
479  // Now use that to read the coverage data.
480  if (CovBuf + DataSize > CovEnd)
481  return make_error<CoverageMapError>(coveragemap_error::malformed);
482  auto Mapping = StringRef(CovBuf, DataSize);
483  CovBuf += DataSize;
484 
485  if (Error Err =
486  insertFunctionRecordIfNeeded(CFR, Mapping, FilenamesBegin))
487  return std::move(Err);
488  CFR++;
489  }
490  return Buf;
491  }
492 };
493 } // end anonymous namespace
494 
495 template <class IntPtrT, support::endianness Endian>
496 Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get(
498  std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
499  std::vector<StringRef> &F) {
500  using namespace coverage;
501  switch (Version) {
503  return llvm::make_unique<VersionedCovMapFuncRecordReader<
504  CovMapVersion::Version1, IntPtrT, Endian>>(P, R, F);
506  // Decompress the name data.
507  if (Error E = P.create(P.getNameData()))
508  return std::move(E);
509  return llvm::make_unique<VersionedCovMapFuncRecordReader<
510  CovMapVersion::Version2, IntPtrT, Endian>>(P, R, F);
511  }
512  llvm_unreachable("Unsupported version");
513 }
514 
515 template <typename T, support::endianness Endian>
517  InstrProfSymtab &ProfileNames, StringRef Data,
518  std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
519  std::vector<StringRef> &Filenames) {
520  using namespace coverage;
521  // Read the records in the coverage data section.
522  auto CovHeader =
523  reinterpret_cast<const coverage::CovMapHeader *>(Data.data());
524  CovMapVersion Version = (CovMapVersion)CovHeader->getVersion<Endian>();
526  return make_error<CoverageMapError>(coveragemap_error::unsupported_version);
528  CovMapFuncRecordReader::get<T, Endian>(Version, ProfileNames, Records,
529  Filenames);
530  if (Error E = ReaderExpected.takeError())
531  return E;
532  auto Reader = std::move(ReaderExpected.get());
533  for (const char *Buf = Data.data(), *End = Buf + Data.size(); Buf < End;) {
534  auto NextHeaderOrErr = Reader->readFunctionRecords(Buf, End);
535  if (auto E = NextHeaderOrErr.takeError())
536  return E;
537  Buf = NextHeaderOrErr.get();
538  }
539  return Error::success();
540 }
541 static const char *TestingFormatMagic = "llvmcovmtestdata";
542 
545  uint8_t &BytesInAddress,
546  support::endianness &Endian) {
547  BytesInAddress = 8;
549 
550  Data = Data.substr(StringRef(TestingFormatMagic).size());
551  if (Data.size() < 1)
552  return make_error<CoverageMapError>(coveragemap_error::truncated);
553  unsigned N = 0;
554  auto ProfileNamesSize =
555  decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
556  if (N > Data.size())
557  return make_error<CoverageMapError>(coveragemap_error::malformed);
558  Data = Data.substr(N);
559  if (Data.size() < 1)
560  return make_error<CoverageMapError>(coveragemap_error::truncated);
561  N = 0;
562  uint64_t Address =
563  decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
564  if (N > Data.size())
565  return make_error<CoverageMapError>(coveragemap_error::malformed);
566  Data = Data.substr(N);
567  if (Data.size() < ProfileNamesSize)
568  return make_error<CoverageMapError>(coveragemap_error::malformed);
569  if (Error E = ProfileNames.create(Data.substr(0, ProfileNamesSize), Address))
570  return E;
571  CoverageMapping = Data.substr(ProfileNamesSize);
572  // Skip the padding bytes because coverage map data has an alignment of 8.
573  if (CoverageMapping.size() < 1)
574  return make_error<CoverageMapError>(coveragemap_error::truncated);
575  size_t Pad = alignmentAdjustment(CoverageMapping.data(), 8);
576  if (CoverageMapping.size() < Pad)
577  return make_error<CoverageMapError>(coveragemap_error::malformed);
578  CoverageMapping = CoverageMapping.substr(Pad);
579  return Error::success();
580 }
581 
583  StringRef FoundName;
584  for (const auto &Section : OF.sections()) {
585  if (auto EC = Section.getName(FoundName))
586  return errorCodeToError(EC);
587  if (FoundName == Name)
588  return Section;
589  }
590  return make_error<CoverageMapError>(coveragemap_error::no_data_found);
591 }
592 
594  InstrProfSymtab &ProfileNames,
596  uint8_t &BytesInAddress,
597  support::endianness &Endian, StringRef Arch) {
598  auto BinOrErr = object::createBinary(ObjectBuffer);
599  if (!BinOrErr)
600  return BinOrErr.takeError();
601  auto Bin = std::move(BinOrErr.get());
602  std::unique_ptr<ObjectFile> OF;
603  if (auto *Universal = dyn_cast<object::MachOUniversalBinary>(Bin.get())) {
604  // If we have a universal binary, try to look up the object for the
605  // appropriate architecture.
606  auto ObjectFileOrErr = Universal->getObjectForArch(Arch);
607  if (!ObjectFileOrErr)
608  return ObjectFileOrErr.takeError();
609  OF = std::move(ObjectFileOrErr.get());
610  } else if (isa<object::ObjectFile>(Bin.get())) {
611  // For any other object file, upcast and take ownership.
612  OF.reset(cast<object::ObjectFile>(Bin.release()));
613  // If we've asked for a particular arch, make sure they match.
614  if (!Arch.empty() && OF->getArch() != Triple(Arch).getArch())
615  return errorCodeToError(object_error::arch_not_found);
616  } else
617  // We can only handle object files.
618  return make_error<CoverageMapError>(coveragemap_error::malformed);
619 
620  // The coverage uses native pointer sizes for the object it's written in.
621  BytesInAddress = OF->getBytesInAddress();
622  Endian = OF->isLittleEndian() ? support::endianness::little
624 
625  // Look for the sections that we are interested in.
626  auto NamesSection = lookupSection(*OF, getInstrProfNameSectionName(false));
627  if (auto E = NamesSection.takeError())
628  return E;
629  auto CoverageSection =
631  if (auto E = CoverageSection.takeError())
632  return E;
633 
634  // Get the contents of the given sections.
635  if (auto EC = CoverageSection->getContents(CoverageMapping))
636  return errorCodeToError(EC);
637  if (Error E = ProfileNames.create(*NamesSection))
638  return E;
639 
640  return Error::success();
641 }
642 
644 BinaryCoverageReader::create(std::unique_ptr<MemoryBuffer> &ObjectBuffer,
645  StringRef Arch) {
646  std::unique_ptr<BinaryCoverageReader> Reader(new BinaryCoverageReader());
647 
648  StringRef Coverage;
649  uint8_t BytesInAddress;
650  support::endianness Endian;
651  Error E = Error::success();
652  consumeError(std::move(E));
653  if (ObjectBuffer->getBuffer().startswith(TestingFormatMagic))
654  // This is a special format used for testing.
655  E = loadTestingFormat(ObjectBuffer->getBuffer(), Reader->ProfileNames,
656  Coverage, BytesInAddress, Endian);
657  else
658  E = loadBinaryFormat(ObjectBuffer->getMemBufferRef(), Reader->ProfileNames,
659  Coverage, BytesInAddress, Endian, Arch);
660  if (E)
661  return std::move(E);
662 
663  if (BytesInAddress == 4 && Endian == support::endianness::little)
664  E = readCoverageMappingData<uint32_t, support::endianness::little>(
665  Reader->ProfileNames, Coverage, Reader->MappingRecords,
666  Reader->Filenames);
667  else if (BytesInAddress == 4 && Endian == support::endianness::big)
668  E = readCoverageMappingData<uint32_t, support::endianness::big>(
669  Reader->ProfileNames, Coverage, Reader->MappingRecords,
670  Reader->Filenames);
671  else if (BytesInAddress == 8 && Endian == support::endianness::little)
672  E = readCoverageMappingData<uint64_t, support::endianness::little>(
673  Reader->ProfileNames, Coverage, Reader->MappingRecords,
674  Reader->Filenames);
675  else if (BytesInAddress == 8 && Endian == support::endianness::big)
676  E = readCoverageMappingData<uint64_t, support::endianness::big>(
677  Reader->ProfileNames, Coverage, Reader->MappingRecords,
678  Reader->Filenames);
679  else
680  return make_error<CoverageMapError>(coveragemap_error::malformed);
681  if (E)
682  return std::move(E);
683  return std::move(Reader);
684 }
685 
687  if (CurrentRecord >= MappingRecords.size())
688  return make_error<CoverageMapError>(coveragemap_error::eof);
689 
690  FunctionsFilenames.clear();
691  Expressions.clear();
692  MappingRegions.clear();
693  auto &R = MappingRecords[CurrentRecord];
695  R.CoverageMapping,
696  makeArrayRef(Filenames).slice(R.FilenamesBegin, R.FilenamesSize),
697  FunctionsFilenames, Expressions, MappingRegions);
698  if (auto Err = Reader.read())
699  return Err;
700 
701  Record.FunctionName = R.FunctionName;
702  Record.FunctionHash = R.FunctionHash;
703  Record.Filenames = FunctionsFilenames;
704  Record.Expressions = Expressions;
705  Record.MappingRegions = MappingRegions;
706 
707  ++CurrentRecord;
708  return Error::success();
709 }
Pass interface - Implemented by all 'passes'.
Definition: Pass.h:81
void push_back(const T &Elt)
Definition: SmallVector.h:211
A symbol table used for function PGO name look-up with keys (such as pointers, md5hash values) to the...
Definition: InstrProf.h:416
static const unsigned EncodingTagMask
Reader for the raw coverage mapping data.
static Counter getZero()
Return the counter that represents the number zero.
aarch64 AArch64 CCMP Pass
coveragemap_error get() const
static int Counter
Checks if the given coverage mapping data is exported for an unused function.
This class is the base class for all object file types.
Definition: ObjectFile.h:178
A Counter expression is a value that represents an arithmetic operation with two counters.
Error takeError()
Take ownership of the stored error.
ArrayRef< CounterMappingRegion > MappingRegions
gvn Early GVN Hoisting of Expressions
Definition: GVNHoist.cpp:998
Error create(object::SectionRef &Section)
Create InstrProfSymtab from an object file section which contains function PGO names.
Expected< std::unique_ptr< Binary > > createBinary(MemoryBufferRef Source, LLVMContext *Context=nullptr)
Create a Binary from Source, autodetecting the file type.
Definition: Binary.cpp:39
Reader for the coverage mapping data that is emitted by the frontend and stored in an object file...
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:440
ArrayRef< CounterExpression > Expressions
StringRef getInstrProfCoverageSectionName(bool AddSegment)
Return the name of the section containing function coverage mapping data.
Definition: InstrProf.h:84
Tagged union holding either a T or a Error.
#define F(x, y, z)
Definition: MD5.cpp:51
StringRef getFuncName(uint64_t FuncNameAddress, size_t NameSize)
Return function's PGO name from the function name's symbol address in the object file.
ArchType getArch() const
getArch - Get the parsed architecture type of this triple.
Definition: Triple.h:270
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
Definition: StringRef.h:135
Error readIntMax(uint64_t &Result, uint64_t MaxPlus1)
Error readNextRecord(CoverageMappingRecord &Record) override
uint64_t decodeULEB128(const uint8_t *p, unsigned *n=nullptr)
Utility function to decode a ULEB128 value.
Definition: LEB128.h:80
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
#define P(N)
std::enable_if<!std::is_array< T >::value, std::unique_ptr< T > >::type make_unique(Args &&...args)
Constructs a new T() with the given args and returns a unique_ptr<T> which owns the object...
Definition: STLExtras.h:845
Coverage mapping information for a single function.
void dump(const Counter &C, llvm::raw_ostream &OS) const
static Error readCoverageMappingData(InstrProfSymtab &ProfileNames, StringRef Data, std::vector< BinaryCoverageReader::ProfileMappingRecord > &Records, std::vector< StringRef > &Filenames)
size_t alignmentAdjustment(const void *Ptr, size_t Alignment)
Returns the necessary adjustment for aligning Ptr to Alignment bytes, rounding up.
Definition: MathExtras.h:613
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Reader for the raw coverage filenames.
A CodeRegion associates some code with a counter.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:587
A Counter mapping context is used to connect the counters, expressions and the obtained counter value...
A Counter mapping region associates a source range with a specific counter.
uint32_t Offset
static const unsigned End
void handleAllErrors(Error E, HandlerTs &&...Handlers)
Behaves the same as handleErrors, except that it requires that all errors be handled by the given han...
section_iterator_range sections() const
Definition: ObjectFile.h:257
uint64_t getAddress() const
Definition: ObjectFile.h:376
void consumeError(Error Err)
Consume a Error without doing anything.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
A file format agnostic iterator over coverage mapping data.
static ErrorSuccess success()
Create a success value.
static Expected< SectionRef > lookupSection(ObjectFile &OF, StringRef Name)
static const unsigned EncodingExpansionRegionBit
static Error loadBinaryFormat(MemoryBufferRef ObjectBuffer, InstrProfSymtab &ProfileNames, StringRef &CoverageMapping, uint8_t &BytesInAddress, support::endianness &Endian, StringRef Arch)
static const char * TestingFormatMagic
static Expected< std::unique_ptr< BinaryCoverageReader > > create(std::unique_ptr< MemoryBuffer > &ObjectBuffer, StringRef Arch)
An ExpansionRegion represents a file expansion region that associates a source range with the expansi...
A SkippedRegion represents a source range with code that was skipped by a preprocessor or similar mea...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
static const unsigned EncodingCounterTagAndExpansionRegionTagBits
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:130
std::error_code getContents(StringRef &Result) const
Definition: ObjectFile.h:384
The mapping of profile information to coverage data.
static Error loadTestingFormat(StringRef Data, InstrProfSymtab &ProfileNames, StringRef &CoverageMapping, uint8_t &BytesInAddress, support::endianness &Endian)
#define I(x, y, z)
Definition: MD5.cpp:54
#define N
const unsigned Kind
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static const unsigned EncodingTagBits
static Expected< bool > isCoverageMappingDummy(uint64_t Hash, StringRef Mapping)
LLVM Value Representation.
Definition: Value.h:71
Lightweight error class with error context and mandatory checking.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:125
#define DEBUG(X)
Definition: Debug.h:100
std::string Hash(const Unit &U)
Definition: FuzzerSHA1.cpp:216
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
static Counter getExpression(unsigned ExpressionId)
Return the counter that corresponds to a specific addition counter expression.
StringRef getInstrProfNameSectionName(bool AddSegment)
Return the name of data section containing names of instrumented functions.
Definition: InstrProf.h:49
A Counter is an abstract value that describes how to compute the execution count for a region of code...
const uint64_t Version
Definition: InstrProf.h:799
static Counter getCounter(unsigned CounterId)
Return the counter that corresponds to a specific profile counter.
This is a value type class that represents a single section in the list of sections in the object fil...
Definition: ObjectFile.h:70
void resize(size_type N)
Definition: SmallVector.h:352