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(Data.bytes_begin(), &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  Expected<StringRef> DataOrErr = Section.getContents();
352  if (!DataOrErr)
353  return DataOrErr.takeError();
354  Data = *DataOrErr;
355  Address = Section.getAddress();
356 
357  // If this is a linked PE/COFF file, then we have to skip over the null byte
358  // that is allocated in the .lprfn$A section in the LLVM profiling runtime.
359  const ObjectFile *Obj = Section.getObject();
360  if (isa<COFFObjectFile>(Obj) && !Obj->isRelocatableObject())
361  Data = Data.drop_front(1);
362 
363  return Error::success();
364 }
365 
366 StringRef InstrProfSymtab::getFuncName(uint64_t Pointer, size_t Size) {
367  if (Pointer < Address)
368  return StringRef();
369  auto Offset = Pointer - Address;
370  if (Offset + Size > Data.size())
371  return StringRef();
372  return Data.substr(Pointer - Address, Size);
373 }
374 
375 // Check if the mapping data is a dummy, i.e. is emitted for an unused function.
376 static Expected<bool> isCoverageMappingDummy(uint64_t Hash, StringRef Mapping) {
377  // The hash value of dummy mapping records is always zero.
378  if (Hash)
379  return false;
380  return RawCoverageMappingDummyChecker(Mapping).isDummy();
381 }
382 
383 namespace {
384 
385 struct CovMapFuncRecordReader {
386  virtual ~CovMapFuncRecordReader() = default;
387 
388  // The interface to read coverage mapping function records for a module.
389  //
390  // \p Buf points to the buffer containing the \c CovHeader of the coverage
391  // mapping data associated with the module.
392  //
393  // Returns a pointer to the next \c CovHeader if it exists, or a pointer
394  // greater than \p End if not.
395  virtual Expected<const char *> readFunctionRecords(const char *Buf,
396  const char *End) = 0;
397 
398  template <class IntPtrT, support::endianness Endian>
401  std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
402  std::vector<StringRef> &F);
403 };
404 
405 // A class for reading coverage mapping function records for a module.
406 template <CovMapVersion Version, class IntPtrT, support::endianness Endian>
407 class VersionedCovMapFuncRecordReader : public CovMapFuncRecordReader {
408  using FuncRecordType =
410  using NameRefType = typename CovMapTraits<Version, IntPtrT>::NameRefType;
411 
412  // Maps function's name references to the indexes of their records
413  // in \c Records.
414  DenseMap<NameRefType, size_t> FunctionRecords;
415  InstrProfSymtab &ProfileNames;
416  std::vector<StringRef> &Filenames;
417  std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records;
418 
419  // Add the record to the collection if we don't already have a record that
420  // points to the same function name. This is useful to ignore the redundant
421  // records for the functions with ODR linkage.
422  // In addition, prefer records with real coverage mapping data to dummy
423  // records, which were emitted for inline functions which were seen but
424  // not used in the corresponding translation unit.
425  Error insertFunctionRecordIfNeeded(const FuncRecordType *CFR,
426  StringRef Mapping, size_t FilenamesBegin) {
427  uint64_t FuncHash = CFR->template getFuncHash<Endian>();
428  NameRefType NameRef = CFR->template getFuncNameRef<Endian>();
429  auto InsertResult =
430  FunctionRecords.insert(std::make_pair(NameRef, Records.size()));
431  if (InsertResult.second) {
432  StringRef FuncName;
433  if (Error Err = CFR->template getFuncName<Endian>(ProfileNames, FuncName))
434  return Err;
435  if (FuncName.empty())
436  return make_error<InstrProfError>(instrprof_error::malformed);
437  Records.emplace_back(Version, FuncName, FuncHash, Mapping, FilenamesBegin,
438  Filenames.size() - FilenamesBegin);
439  return Error::success();
440  }
441  // Update the existing record if it's a dummy and the new record is real.
442  size_t OldRecordIndex = InsertResult.first->second;
444  Records[OldRecordIndex];
445  Expected<bool> OldIsDummyExpected = isCoverageMappingDummy(
446  OldRecord.FunctionHash, OldRecord.CoverageMapping);
447  if (Error Err = OldIsDummyExpected.takeError())
448  return Err;
449  if (!*OldIsDummyExpected)
450  return Error::success();
451  Expected<bool> NewIsDummyExpected =
452  isCoverageMappingDummy(FuncHash, Mapping);
453  if (Error Err = NewIsDummyExpected.takeError())
454  return Err;
455  if (*NewIsDummyExpected)
456  return Error::success();
457  OldRecord.FunctionHash = FuncHash;
458  OldRecord.CoverageMapping = Mapping;
459  OldRecord.FilenamesBegin = FilenamesBegin;
460  OldRecord.FilenamesSize = Filenames.size() - FilenamesBegin;
461  return Error::success();
462  }
463 
464 public:
465  VersionedCovMapFuncRecordReader(
467  std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
468  std::vector<StringRef> &F)
469  : ProfileNames(P), Filenames(F), Records(R) {}
470 
471  ~VersionedCovMapFuncRecordReader() override = default;
472 
473  Expected<const char *> readFunctionRecords(const char *Buf,
474  const char *End) override {
475  using namespace support;
476 
477  if (Buf + sizeof(CovMapHeader) > End)
478  return make_error<CoverageMapError>(coveragemap_error::malformed);
479  auto CovHeader = reinterpret_cast<const CovMapHeader *>(Buf);
480  uint32_t NRecords = CovHeader->getNRecords<Endian>();
481  uint32_t FilenamesSize = CovHeader->getFilenamesSize<Endian>();
482  uint32_t CoverageSize = CovHeader->getCoverageSize<Endian>();
483  assert((CovMapVersion)CovHeader->getVersion<Endian>() == Version);
484  Buf = reinterpret_cast<const char *>(CovHeader + 1);
485 
486  // Skip past the function records, saving the start and end for later.
487  const char *FunBuf = Buf;
488  Buf += NRecords * sizeof(FuncRecordType);
489  const char *FunEnd = Buf;
490 
491  // Get the filenames.
492  if (Buf + FilenamesSize > End)
493  return make_error<CoverageMapError>(coveragemap_error::malformed);
494  size_t FilenamesBegin = Filenames.size();
495  RawCoverageFilenamesReader Reader(StringRef(Buf, FilenamesSize), Filenames);
496  if (auto Err = Reader.read())
497  return std::move(Err);
498  Buf += FilenamesSize;
499 
500  // We'll read the coverage mapping records in the loop below.
501  const char *CovBuf = Buf;
502  Buf += CoverageSize;
503  const char *CovEnd = Buf;
504 
505  if (Buf > End)
506  return make_error<CoverageMapError>(coveragemap_error::malformed);
507  // Each coverage map has an alignment of 8, so we need to adjust alignment
508  // before reading the next map.
509  Buf += alignmentAdjustment(Buf, 8);
510 
511  auto CFR = reinterpret_cast<const FuncRecordType *>(FunBuf);
512  while ((const char *)CFR < FunEnd) {
513  // Read the function information
514  uint32_t DataSize = CFR->template getDataSize<Endian>();
515 
516  // Now use that to read the coverage data.
517  if (CovBuf + DataSize > CovEnd)
518  return make_error<CoverageMapError>(coveragemap_error::malformed);
519  auto Mapping = StringRef(CovBuf, DataSize);
520  CovBuf += DataSize;
521 
522  if (Error Err =
523  insertFunctionRecordIfNeeded(CFR, Mapping, FilenamesBegin))
524  return std::move(Err);
525  CFR++;
526  }
527  return Buf;
528  }
529 };
530 
531 } // end anonymous namespace
532 
533 template <class IntPtrT, support::endianness Endian>
534 Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get(
536  std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
537  std::vector<StringRef> &F) {
538  using namespace coverage;
539 
540  switch (Version) {
542  return llvm::make_unique<VersionedCovMapFuncRecordReader<
543  CovMapVersion::Version1, IntPtrT, Endian>>(P, R, F);
546  // Decompress the name data.
547  if (Error E = P.create(P.getNameData()))
548  return std::move(E);
550  return llvm::make_unique<VersionedCovMapFuncRecordReader<
551  CovMapVersion::Version2, IntPtrT, Endian>>(P, R, F);
552  else
553  return llvm::make_unique<VersionedCovMapFuncRecordReader<
554  CovMapVersion::Version3, IntPtrT, Endian>>(P, R, F);
555  }
556  llvm_unreachable("Unsupported version");
557 }
558 
559 template <typename T, support::endianness Endian>
561  InstrProfSymtab &ProfileNames, StringRef Data,
562  std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
563  std::vector<StringRef> &Filenames) {
564  using namespace coverage;
565 
566  // Read the records in the coverage data section.
567  auto CovHeader =
568  reinterpret_cast<const CovMapHeader *>(Data.data());
569  CovMapVersion Version = (CovMapVersion)CovHeader->getVersion<Endian>();
570  if (Version > CovMapVersion::CurrentVersion)
571  return make_error<CoverageMapError>(coveragemap_error::unsupported_version);
573  CovMapFuncRecordReader::get<T, Endian>(Version, ProfileNames, Records,
574  Filenames);
575  if (Error E = ReaderExpected.takeError())
576  return E;
577  auto Reader = std::move(ReaderExpected.get());
578  for (const char *Buf = Data.data(), *End = Buf + Data.size(); Buf < End;) {
579  auto NextHeaderOrErr = Reader->readFunctionRecords(Buf, End);
580  if (auto E = NextHeaderOrErr.takeError())
581  return E;
582  Buf = NextHeaderOrErr.get();
583  }
584  return Error::success();
585 }
586 
587 static const char *TestingFormatMagic = "llvmcovmtestdata";
588 
591  uint8_t &BytesInAddress,
592  support::endianness &Endian) {
593  BytesInAddress = 8;
595 
596  Data = Data.substr(StringRef(TestingFormatMagic).size());
597  if (Data.empty())
598  return make_error<CoverageMapError>(coveragemap_error::truncated);
599  unsigned N = 0;
600  uint64_t ProfileNamesSize = decodeULEB128(Data.bytes_begin(), &N);
601  if (N > Data.size())
602  return make_error<CoverageMapError>(coveragemap_error::malformed);
603  Data = Data.substr(N);
604  if (Data.empty())
605  return make_error<CoverageMapError>(coveragemap_error::truncated);
606  N = 0;
607  uint64_t Address = decodeULEB128(Data.bytes_begin(), &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 (Expected<StringRef> E = CoverageSection->getContents())
693  CoverageMapping = *E;
694  else
695  return E.takeError();
696 
697  if (Error E = ProfileNames.create(*NamesSection))
698  return E;
699 
700  return Error::success();
701 }
702 
704 BinaryCoverageReader::create(std::unique_ptr<MemoryBuffer> &ObjectBuffer,
705  StringRef Arch) {
706  std::unique_ptr<BinaryCoverageReader> Reader(new BinaryCoverageReader());
707 
708  StringRef Coverage;
709  uint8_t BytesInAddress;
710  support::endianness Endian;
711  Error E = Error::success();
712  consumeError(std::move(E));
713  if (ObjectBuffer->getBuffer().startswith(TestingFormatMagic))
714  // This is a special format used for testing.
715  E = loadTestingFormat(ObjectBuffer->getBuffer(), Reader->ProfileNames,
716  Coverage, BytesInAddress, Endian);
717  else
718  E = loadBinaryFormat(ObjectBuffer->getMemBufferRef(), Reader->ProfileNames,
719  Coverage, BytesInAddress, Endian, Arch);
720  if (E)
721  return std::move(E);
722 
723  if (BytesInAddress == 4 && Endian == support::endianness::little)
724  E = readCoverageMappingData<uint32_t, support::endianness::little>(
725  Reader->ProfileNames, Coverage, Reader->MappingRecords,
726  Reader->Filenames);
727  else if (BytesInAddress == 4 && Endian == support::endianness::big)
728  E = readCoverageMappingData<uint32_t, support::endianness::big>(
729  Reader->ProfileNames, Coverage, Reader->MappingRecords,
730  Reader->Filenames);
731  else if (BytesInAddress == 8 && Endian == support::endianness::little)
732  E = readCoverageMappingData<uint64_t, support::endianness::little>(
733  Reader->ProfileNames, Coverage, Reader->MappingRecords,
734  Reader->Filenames);
735  else if (BytesInAddress == 8 && Endian == support::endianness::big)
736  E = readCoverageMappingData<uint64_t, support::endianness::big>(
737  Reader->ProfileNames, Coverage, Reader->MappingRecords,
738  Reader->Filenames);
739  else
740  return make_error<CoverageMapError>(coveragemap_error::malformed);
741  if (E)
742  return std::move(E);
743  return std::move(Reader);
744 }
745 
747  if (CurrentRecord >= MappingRecords.size())
748  return make_error<CoverageMapError>(coveragemap_error::eof);
749 
750  FunctionsFilenames.clear();
751  Expressions.clear();
752  MappingRegions.clear();
753  auto &R = MappingRecords[CurrentRecord];
755  R.CoverageMapping,
756  makeArrayRef(Filenames).slice(R.FilenamesBegin, R.FilenamesSize),
757  FunctionsFilenames, Expressions, MappingRegions);
758  if (auto Err = Reader.read())
759  return Err;
760 
761  Record.FunctionName = R.FunctionName;
762  Record.FunctionHash = R.FunctionHash;
763  Record.Filenames = FunctionsFilenames;
764  Record.Expressions = Expressions;
765  Record.MappingRegions = MappingRegions;
766 
767  ++CurrentRecord;
768  return Error::success();
769 }
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: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:1403
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:294
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)
const unsigned char * bytes_begin() const
Definition: StringRef.h:105
#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:984
static Counter getCounter(unsigned CounterId)
Return the counter that corresponds to a specific profile counter.
void resize(size_type N)
Definition: SmallVector.h:344