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