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"
25 #include "llvm/Object/COFF.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 
355  // If this is a linked PE/COFF file, then we have to skip over the null byte
356  // that is allocated in the .lprfn$A section in the LLVM profiling runtime.
357  const ObjectFile *Obj = Section.getObject();
358  if (isa<COFFObjectFile>(Obj) && !Obj->isRelocatableObject())
359  Data = Data.drop_front(1);
360 
361  return Error::success();
362 }
363 
364 StringRef InstrProfSymtab::getFuncName(uint64_t Pointer, size_t Size) {
365  if (Pointer < Address)
366  return StringRef();
367  auto Offset = Pointer - Address;
368  if (Offset + Size > Data.size())
369  return StringRef();
370  return Data.substr(Pointer - Address, Size);
371 }
372 
373 // Check if the mapping data is a dummy, i.e. is emitted for an unused function.
374 static Expected<bool> isCoverageMappingDummy(uint64_t Hash, StringRef Mapping) {
375  // The hash value of dummy mapping records is always zero.
376  if (Hash)
377  return false;
378  return RawCoverageMappingDummyChecker(Mapping).isDummy();
379 }
380 
381 namespace {
382 
383 struct CovMapFuncRecordReader {
384  virtual ~CovMapFuncRecordReader() = default;
385 
386  // The interface to read coverage mapping function records for a module.
387  //
388  // \p Buf points to the buffer containing the \c CovHeader of the coverage
389  // mapping data associated with the module.
390  //
391  // Returns a pointer to the next \c CovHeader if it exists, or a pointer
392  // greater than \p End if not.
393  virtual Expected<const char *> readFunctionRecords(const char *Buf,
394  const char *End) = 0;
395 
396  template <class IntPtrT, support::endianness Endian>
399  std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
400  std::vector<StringRef> &F);
401 };
402 
403 // A class for reading coverage mapping function records for a module.
404 template <CovMapVersion Version, class IntPtrT, support::endianness Endian>
405 class VersionedCovMapFuncRecordReader : public CovMapFuncRecordReader {
406  using FuncRecordType =
408  using NameRefType = typename CovMapTraits<Version, IntPtrT>::NameRefType;
409 
410  // Maps function's name references to the indexes of their records
411  // in \c Records.
412  DenseMap<NameRefType, size_t> FunctionRecords;
413  InstrProfSymtab &ProfileNames;
414  std::vector<StringRef> &Filenames;
415  std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records;
416 
417  // Add the record to the collection if we don't already have a record that
418  // points to the same function name. This is useful to ignore the redundant
419  // records for the functions with ODR linkage.
420  // In addition, prefer records with real coverage mapping data to dummy
421  // records, which were emitted for inline functions which were seen but
422  // not used in the corresponding translation unit.
423  Error insertFunctionRecordIfNeeded(const FuncRecordType *CFR,
424  StringRef Mapping, size_t FilenamesBegin) {
425  uint64_t FuncHash = CFR->template getFuncHash<Endian>();
426  NameRefType NameRef = CFR->template getFuncNameRef<Endian>();
427  auto InsertResult =
428  FunctionRecords.insert(std::make_pair(NameRef, Records.size()));
429  if (InsertResult.second) {
430  StringRef FuncName;
431  if (Error Err = CFR->template getFuncName<Endian>(ProfileNames, FuncName))
432  return Err;
433  if (FuncName.empty())
434  return make_error<InstrProfError>(instrprof_error::malformed);
435  Records.emplace_back(Version, FuncName, FuncHash, Mapping, FilenamesBegin,
436  Filenames.size() - FilenamesBegin);
437  return Error::success();
438  }
439  // Update the existing record if it's a dummy and the new record is real.
440  size_t OldRecordIndex = InsertResult.first->second;
442  Records[OldRecordIndex];
443  Expected<bool> OldIsDummyExpected = isCoverageMappingDummy(
444  OldRecord.FunctionHash, OldRecord.CoverageMapping);
445  if (Error Err = OldIsDummyExpected.takeError())
446  return Err;
447  if (!*OldIsDummyExpected)
448  return Error::success();
449  Expected<bool> NewIsDummyExpected =
450  isCoverageMappingDummy(FuncHash, Mapping);
451  if (Error Err = NewIsDummyExpected.takeError())
452  return Err;
453  if (*NewIsDummyExpected)
454  return Error::success();
455  OldRecord.FunctionHash = FuncHash;
456  OldRecord.CoverageMapping = Mapping;
457  OldRecord.FilenamesBegin = FilenamesBegin;
458  OldRecord.FilenamesSize = Filenames.size() - FilenamesBegin;
459  return Error::success();
460  }
461 
462 public:
463  VersionedCovMapFuncRecordReader(
465  std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
466  std::vector<StringRef> &F)
467  : ProfileNames(P), Filenames(F), Records(R) {}
468 
469  ~VersionedCovMapFuncRecordReader() override = default;
470 
471  Expected<const char *> readFunctionRecords(const char *Buf,
472  const char *End) override {
473  using namespace support;
474 
475  if (Buf + sizeof(CovMapHeader) > End)
476  return make_error<CoverageMapError>(coveragemap_error::malformed);
477  auto CovHeader = reinterpret_cast<const CovMapHeader *>(Buf);
478  uint32_t NRecords = CovHeader->getNRecords<Endian>();
479  uint32_t FilenamesSize = CovHeader->getFilenamesSize<Endian>();
480  uint32_t CoverageSize = CovHeader->getCoverageSize<Endian>();
481  assert((CovMapVersion)CovHeader->getVersion<Endian>() == Version);
482  Buf = reinterpret_cast<const char *>(CovHeader + 1);
483 
484  // Skip past the function records, saving the start and end for later.
485  const char *FunBuf = Buf;
486  Buf += NRecords * sizeof(FuncRecordType);
487  const char *FunEnd = Buf;
488 
489  // Get the filenames.
490  if (Buf + FilenamesSize > End)
491  return make_error<CoverageMapError>(coveragemap_error::malformed);
492  size_t FilenamesBegin = Filenames.size();
493  RawCoverageFilenamesReader Reader(StringRef(Buf, FilenamesSize), Filenames);
494  if (auto Err = Reader.read())
495  return std::move(Err);
496  Buf += FilenamesSize;
497 
498  // We'll read the coverage mapping records in the loop below.
499  const char *CovBuf = Buf;
500  Buf += CoverageSize;
501  const char *CovEnd = Buf;
502 
503  if (Buf > End)
504  return make_error<CoverageMapError>(coveragemap_error::malformed);
505  // Each coverage map has an alignment of 8, so we need to adjust alignment
506  // before reading the next map.
507  Buf += alignmentAdjustment(Buf, 8);
508 
509  auto CFR = reinterpret_cast<const FuncRecordType *>(FunBuf);
510  while ((const char *)CFR < FunEnd) {
511  // Read the function information
512  uint32_t DataSize = CFR->template getDataSize<Endian>();
513 
514  // Now use that to read the coverage data.
515  if (CovBuf + DataSize > CovEnd)
516  return make_error<CoverageMapError>(coveragemap_error::malformed);
517  auto Mapping = StringRef(CovBuf, DataSize);
518  CovBuf += DataSize;
519 
520  if (Error Err =
521  insertFunctionRecordIfNeeded(CFR, Mapping, FilenamesBegin))
522  return std::move(Err);
523  CFR++;
524  }
525  return Buf;
526  }
527 };
528 
529 } // end anonymous namespace
530 
531 template <class IntPtrT, support::endianness Endian>
532 Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get(
534  std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
535  std::vector<StringRef> &F) {
536  using namespace coverage;
537 
538  switch (Version) {
540  return llvm::make_unique<VersionedCovMapFuncRecordReader<
541  CovMapVersion::Version1, IntPtrT, Endian>>(P, R, F);
544  // Decompress the name data.
545  if (Error E = P.create(P.getNameData()))
546  return std::move(E);
548  return llvm::make_unique<VersionedCovMapFuncRecordReader<
549  CovMapVersion::Version2, IntPtrT, Endian>>(P, R, F);
550  else
551  return llvm::make_unique<VersionedCovMapFuncRecordReader<
552  CovMapVersion::Version3, IntPtrT, Endian>>(P, R, F);
553  }
554  llvm_unreachable("Unsupported version");
555 }
556 
557 template <typename T, support::endianness Endian>
559  InstrProfSymtab &ProfileNames, StringRef Data,
560  std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
561  std::vector<StringRef> &Filenames) {
562  using namespace coverage;
563 
564  // Read the records in the coverage data section.
565  auto CovHeader =
566  reinterpret_cast<const CovMapHeader *>(Data.data());
567  CovMapVersion Version = (CovMapVersion)CovHeader->getVersion<Endian>();
568  if (Version > CovMapVersion::CurrentVersion)
569  return make_error<CoverageMapError>(coveragemap_error::unsupported_version);
571  CovMapFuncRecordReader::get<T, Endian>(Version, ProfileNames, Records,
572  Filenames);
573  if (Error E = ReaderExpected.takeError())
574  return E;
575  auto Reader = std::move(ReaderExpected.get());
576  for (const char *Buf = Data.data(), *End = Buf + Data.size(); Buf < End;) {
577  auto NextHeaderOrErr = Reader->readFunctionRecords(Buf, End);
578  if (auto E = NextHeaderOrErr.takeError())
579  return E;
580  Buf = NextHeaderOrErr.get();
581  }
582  return Error::success();
583 }
584 
585 static const char *TestingFormatMagic = "llvmcovmtestdata";
586 
589  uint8_t &BytesInAddress,
590  support::endianness &Endian) {
591  BytesInAddress = 8;
593 
594  Data = Data.substr(StringRef(TestingFormatMagic).size());
595  if (Data.empty())
596  return make_error<CoverageMapError>(coveragemap_error::truncated);
597  unsigned N = 0;
598  auto ProfileNamesSize =
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.empty())
604  return make_error<CoverageMapError>(coveragemap_error::truncated);
605  N = 0;
606  uint64_t Address =
607  decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
608  if (N > Data.size())
609  return make_error<CoverageMapError>(coveragemap_error::malformed);
610  Data = Data.substr(N);
611  if (Data.size() < ProfileNamesSize)
612  return make_error<CoverageMapError>(coveragemap_error::malformed);
613  if (Error E = ProfileNames.create(Data.substr(0, ProfileNamesSize), Address))
614  return E;
615  CoverageMapping = Data.substr(ProfileNamesSize);
616  // Skip the padding bytes because coverage map data has an alignment of 8.
617  if (CoverageMapping.empty())
618  return make_error<CoverageMapError>(coveragemap_error::truncated);
619  size_t Pad = alignmentAdjustment(CoverageMapping.data(), 8);
620  if (CoverageMapping.size() < Pad)
621  return make_error<CoverageMapError>(coveragemap_error::malformed);
622  CoverageMapping = CoverageMapping.substr(Pad);
623  return Error::success();
624 }
625 
627  // On COFF, the object file section name may end in "$M". This tells the
628  // linker to sort these sections between "$A" and "$Z". The linker removes the
629  // dollar and everything after it in the final binary. Do the same to match.
630  bool IsCOFF = isa<COFFObjectFile>(OF);
631  auto stripSuffix = [IsCOFF](StringRef N) {
632  return IsCOFF ? N.split('$').first : N;
633  };
634  Name = stripSuffix(Name);
635 
636  StringRef FoundName;
637  for (const auto &Section : OF.sections()) {
638  if (auto EC = Section.getName(FoundName))
639  return errorCodeToError(EC);
640  if (stripSuffix(FoundName) == Name)
641  return Section;
642  }
643  return make_error<CoverageMapError>(coveragemap_error::no_data_found);
644 }
645 
647  InstrProfSymtab &ProfileNames,
649  uint8_t &BytesInAddress,
650  support::endianness &Endian, StringRef Arch) {
651  auto BinOrErr = createBinary(ObjectBuffer);
652  if (!BinOrErr)
653  return BinOrErr.takeError();
654  auto Bin = std::move(BinOrErr.get());
655  std::unique_ptr<ObjectFile> OF;
656  if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin.get())) {
657  // If we have a universal binary, try to look up the object for the
658  // appropriate architecture.
659  auto ObjectFileOrErr = Universal->getObjectForArch(Arch);
660  if (!ObjectFileOrErr)
661  return ObjectFileOrErr.takeError();
662  OF = std::move(ObjectFileOrErr.get());
663  } else if (isa<ObjectFile>(Bin.get())) {
664  // For any other object file, upcast and take ownership.
665  OF.reset(cast<ObjectFile>(Bin.release()));
666  // If we've asked for a particular arch, make sure they match.
667  if (!Arch.empty() && OF->getArch() != Triple(Arch).getArch())
668  return errorCodeToError(object_error::arch_not_found);
669  } else
670  // We can only handle object files.
671  return make_error<CoverageMapError>(coveragemap_error::malformed);
672 
673  // The coverage uses native pointer sizes for the object it's written in.
674  BytesInAddress = OF->getBytesInAddress();
675  Endian = OF->isLittleEndian() ? support::endianness::little
677 
678  // Look for the sections that we are interested in.
679  auto ObjFormat = OF->getTripleObjectFormat();
680  auto NamesSection =
681  lookupSection(*OF, getInstrProfSectionName(IPSK_name, ObjFormat,
682  /*AddSegmentInfo=*/false));
683  if (auto E = NamesSection.takeError())
684  return E;
685  auto CoverageSection =
686  lookupSection(*OF, getInstrProfSectionName(IPSK_covmap, ObjFormat,
687  /*AddSegmentInfo=*/false));
688  if (auto E = CoverageSection.takeError())
689  return E;
690 
691  // Get the contents of the given sections.
692  if (auto EC = CoverageSection->getContents(CoverageMapping))
693  return errorCodeToError(EC);
694  if (Error E = ProfileNames.create(*NamesSection))
695  return E;
696 
697  return Error::success();
698 }
699 
701 BinaryCoverageReader::create(std::unique_ptr<MemoryBuffer> &ObjectBuffer,
702  StringRef Arch) {
703  std::unique_ptr<BinaryCoverageReader> Reader(new BinaryCoverageReader());
704 
705  StringRef Coverage;
706  uint8_t BytesInAddress;
707  support::endianness Endian;
708  Error E = Error::success();
709  consumeError(std::move(E));
710  if (ObjectBuffer->getBuffer().startswith(TestingFormatMagic))
711  // This is a special format used for testing.
712  E = loadTestingFormat(ObjectBuffer->getBuffer(), Reader->ProfileNames,
713  Coverage, BytesInAddress, Endian);
714  else
715  E = loadBinaryFormat(ObjectBuffer->getMemBufferRef(), Reader->ProfileNames,
716  Coverage, BytesInAddress, Endian, Arch);
717  if (E)
718  return std::move(E);
719 
720  if (BytesInAddress == 4 && Endian == support::endianness::little)
721  E = readCoverageMappingData<uint32_t, support::endianness::little>(
722  Reader->ProfileNames, Coverage, Reader->MappingRecords,
723  Reader->Filenames);
724  else if (BytesInAddress == 4 && Endian == support::endianness::big)
725  E = readCoverageMappingData<uint32_t, support::endianness::big>(
726  Reader->ProfileNames, Coverage, Reader->MappingRecords,
727  Reader->Filenames);
728  else if (BytesInAddress == 8 && Endian == support::endianness::little)
729  E = readCoverageMappingData<uint64_t, support::endianness::little>(
730  Reader->ProfileNames, Coverage, Reader->MappingRecords,
731  Reader->Filenames);
732  else if (BytesInAddress == 8 && Endian == support::endianness::big)
733  E = readCoverageMappingData<uint64_t, support::endianness::big>(
734  Reader->ProfileNames, Coverage, Reader->MappingRecords,
735  Reader->Filenames);
736  else
737  return make_error<CoverageMapError>(coveragemap_error::malformed);
738  if (E)
739  return std::move(E);
740  return std::move(Reader);
741 }
742 
744  if (CurrentRecord >= MappingRecords.size())
745  return make_error<CoverageMapError>(coveragemap_error::eof);
746 
747  FunctionsFilenames.clear();
748  Expressions.clear();
749  MappingRegions.clear();
750  auto &R = MappingRecords[CurrentRecord];
752  R.CoverageMapping,
753  makeArrayRef(Filenames).slice(R.FilenamesBegin, R.FilenamesSize),
754  FunctionsFilenames, Expressions, MappingRegions);
755  if (auto Err = Reader.read())
756  return Err;
757 
758  Record.FunctionName = R.FunctionName;
759  Record.FunctionHash = R.FunctionHash;
760  Record.Filenames = FunctionsFilenames;
761  Record.Expressions = Expressions;
762  Record.MappingRegions = MappingRegions;
763 
764  ++CurrentRecord;
765  return Error::success();
766 }
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.
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
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:45
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:221
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:290
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
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:904
static Counter getCounter(unsigned CounterId)
Return the counter that corresponds to a specific profile counter.
void resize(size_type N)
Definition: SmallVector.h:344