LLVM  9.0.0svn
CoverageMappingReader.cpp
Go to the documentation of this file.
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.
11 //
12 //===----------------------------------------------------------------------===//
13 
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"
24 #include "llvm/Object/ObjectFile.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"
31 #include "llvm/Support/LEB128.h"
34 #include <vector>
35 
36 using namespace llvm;
37 using namespace coverage;
38 using namespace object;
39 
40 #define DEBUG_TYPE "coverage-mapping"
41 
42 void CoverageMappingIterator::increment() {
43  if (ReadErr != coveragemap_error::success)
44  return;
45 
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  });
55 }
56 
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();
66 }
67 
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();
74 }
75 
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();
83 }
84 
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();
92 }
93 
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);
103  }
104  return Error::success();
105 }
106 
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();
115  return Error::success();
116  default:
117  break;
118  }
119  Tag -= Counter::Expression;
120  switch (Tag) {
122  case CounterExpression::Add: {
123  auto ID = Value >> Counter::EncodingTagBits;
124  if (ID >= Expressions.size())
125  return make_error<CoverageMapError>(coveragemap_error::malformed);
128  break;
129  }
130  default:
131  return make_error<CoverageMapError>(coveragemap_error::malformed);
132  }
133  return Error::success();
134 }
135 
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();
144 }
145 
146 static const unsigned EncodingExpansionRegionBit = 1
148 
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;
162 
163  // Read the combined counter + region kind.
164  uint64_t EncodedCounterAndRegion;
165  if (auto Err = readIntMax(EncodedCounterAndRegion,
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) {
177  ExpandedFileID = EncodedCounterAndRegion >>
179  if (ExpandedFileID >= NumFileIDs)
180  return make_error<CoverageMapError>(coveragemap_error::malformed);
181  } else {
182  switch (EncodedCounterAndRegion >>
185  // Don't do anything when we have a code region with a zero counter.
186  break;
189  break;
190  default:
191  return make_error<CoverageMapError>(coveragemap_error::malformed);
192  }
193  }
194  }
195 
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;
210 
211  // If the high bit of ColumnEnd is set, this is a gap region.
212  if (ColumnEnd & (1U << 31)) {
214  ColumnEnd &= ~(1U << 31);
215  }
216 
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;
228  }
229 
230  LLVM_DEBUG({
231  dbgs() << "Counter in file " << InferredFileID << " " << LineStart << ":"
232  << ColumnStart << " -> " << (LineStart + NumLines) << ":"
233  << ColumnEnd << ", ";
235  dbgs() << "Expands to file " << ExpandedFileID;
236  else
238  dbgs() << "\n";
239  });
240 
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);
247  }
248  return Error::success();
249 }
250 
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);
262  }
263 
264  // Construct the files using unique filenames and virtual file mapping.
265  for (auto I : VirtualFileMapping) {
266  Filenames.push_back(TranslationUnitFilenames[I]);
267  }
268 
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,
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;
284  }
285 
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;
292  }
293 
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) {
304  continue;
305  assert(!FileIDExpansionRegionMapping[R.ExpandedFileID]);
306  FileIDExpansionRegionMapping[R.ExpandedFileID] = &R;
307  }
308  for (auto &R : MappingRegions) {
309  if (FileIDExpansionRegionMapping[R.FileID]) {
310  FileIDExpansionRegionMapping[R.FileID]->Count = R.Count;
311  FileIDExpansionRegionMapping[R.FileID] = nullptr;
312  }
313  }
314  }
315 
316  return Error::success();
317 }
318 
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,
344  return std::move(Err);
345  unsigned Tag = EncodedCounterAndRegion & Counter::EncodingTagMask;
346  return Tag == Counter::Zero;
347 }
348 
350  if (auto EC = Section.getContents(Data))
351  return errorCodeToError(EC);
352  Address = Section.getAddress();
353  return Error::success();
354 }
355 
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);
363 }
364 
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();
371 }
372 
373 namespace {
374 
375 struct CovMapFuncRecordReader {
376  virtual ~CovMapFuncRecordReader() = default;
377 
378  // The interface to read coverage mapping function records for a module.
379  //
380  // \p Buf points to the buffer containing the \c CovHeader of the coverage
381  // mapping data associated with the module.
382  //
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;
387 
388  template <class IntPtrT, support::endianness Endian>
391  std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
392  std::vector<StringRef> &F);
393 };
394 
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 =
400  using NameRefType = typename CovMapTraits<Version, IntPtrT>::NameRefType;
401 
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;
408 
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();
430  }
431  // Update the existing record if it's a dummy and the new record is real.
432  size_t OldRecordIndex = InsertResult.first->second;
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();
452  }
453 
454 public:
455  VersionedCovMapFuncRecordReader(
457  std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
458  std::vector<StringRef> &F)
459  : ProfileNames(P), Filenames(F), Records(R) {}
460 
461  ~VersionedCovMapFuncRecordReader() override = default;
462 
463  Expected<const char *> readFunctionRecords(const char *Buf,
464  const char *End) override {
465  using namespace support;
466 
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);
475 
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;
480 
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;
489 
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;
494 
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);
500 
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>();
505 
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;
511 
512  if (Error Err =
513  insertFunctionRecordIfNeeded(CFR, Mapping, FilenamesBegin))
514  return std::move(Err);
515  CFR++;
516  }
517  return Buf;
518  }
519 };
520 
521 } // end anonymous namespace
522 
523 template <class IntPtrT, support::endianness Endian>
524 Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get(
526  std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
527  std::vector<StringRef> &F) {
528  using namespace coverage;
529 
530  switch (Version) {
532  return llvm::make_unique<VersionedCovMapFuncRecordReader<
533  CovMapVersion::Version1, IntPtrT, Endian>>(P, R, F);
536  // Decompress the name data.
537  if (Error E = P.create(P.getNameData()))
538  return std::move(E);
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);
545  }
546  llvm_unreachable("Unsupported version");
547 }
548 
549 template <typename T, support::endianness Endian>
551  InstrProfSymtab &ProfileNames, StringRef Data,
552  std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
553  std::vector<StringRef> &Filenames) {
554  using namespace coverage;
555 
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);
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();
573  }
574  return Error::success();
575 }
576 
577 static const char *TestingFormatMagic = "llvmcovmtestdata";
578 
581  uint8_t &BytesInAddress,
582  support::endianness &Endian) {
583  BytesInAddress = 8;
585 
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();
616 }
617 
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;
625  }
626  return make_error<CoverageMapError>(coveragemap_error::no_data_found);
627 }
628 
630  InstrProfSymtab &ProfileNames,
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);
655 
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
660 
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;
673 
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;
679 
680  return Error::success();
681 }
682 
684 BinaryCoverageReader::create(std::unique_ptr<MemoryBuffer> &ObjectBuffer,
685  StringRef Arch) {
686  std::unique_ptr<BinaryCoverageReader> Reader(new BinaryCoverageReader());
687 
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);
702 
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);
724 }
725 
727  if (CurrentRecord >= MappingRecords.size())
728  return make_error<CoverageMapError>(coveragemap_error::eof);
729 
730  FunctionsFilenames.clear();
731  Expressions.clear();
732  MappingRegions.clear();
733  auto &R = MappingRecords[CurrentRecord];
735  R.CoverageMapping,
736  makeArrayRef(Filenames).slice(R.FilenamesBegin, R.FilenamesSize),
737  FunctionsFilenames, Expressions, MappingRegions);
738  if (auto Err = Reader.read())
739  return Err;
740 
741  Record.FunctionName = R.FunctionName;
742  Record.FunctionHash = R.FunctionHash;
743  Record.Filenames = FunctionsFilenames;
744  Record.Expressions = Expressions;
745  Record.MappingRegions = MappingRegions;
746 
747  ++CurrentRecord;
748  return Error::success();
749 }
Pass interface - Implemented by all &#39;passes&#39;.
Definition: Pass.h:80
uint64_t CallInst * C
A symbol table used for function PGO name look-up with keys (such as pointers, md5hash values) to the...
Definition: InstrProf.h:410
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
static const unsigned EncodingTagMask
Reader for the raw coverage mapping data.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
static Counter getZero()
Return the counter that represents the number zero.
void push_back(const T &Elt)
Definition: SmallVector.h:211
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:164
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:1348
Error takeError()
Take ownership of the stored error.
Definition: Error.h:552
ArrayRef< CounterMappingRegion > MappingRegions
gvn Early GVN Hoisting of Expressions
Definition: GVNHoist.cpp:1203
Expected< std::unique_ptr< Binary > > createBinary(MemoryBufferRef Source, LLVMContext *Context=nullptr)
Create a Binary from Source, autodetecting the file type.
Definition: Binary.cpp:44
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:221
amdgpu Simplify well known AMD library false Value Value const Twine & Name
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:450
ArrayRef< CounterExpression > Expressions
Tagged union holding either a T or a Error.
Definition: CachePruning.h:22
LLVM_NODISCARD StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:578
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:126
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:289
void dump(const Counter &C, raw_ostream &OS) const
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:130
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:633
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition: Error.cpp:87
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:128
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:981
#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:43
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:904
print lazy value Lazy Value Info Printer Pass
static ErrorSuccess success()
Create a success value.
Definition: Error.h:326
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:1166
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:132
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
uint32_t Size
Definition: Profile.cpp:46
const unsigned Kind
LLVM_NODISCARD const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:122
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:72
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
static Counter getExpression(unsigned ExpressionId)
Return the counter that corresponds to a specific addition counter expression.
#define LLVM_DEBUG(X)
Definition: Debug.h:122
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:894
static Counter getCounter(unsigned CounterId)
Return the counter that corresponds to a specific profile counter.
void resize(size_type N)
Definition: SmallVector.h:343