LLVM  10.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 += offsetToAlignedAddr(Buf, Align(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 std::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 std::make_unique<VersionedCovMapFuncRecordReader<
551  CovMapVersion::Version2, IntPtrT, Endian>>(P, R, F);
552  else
553  return std::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  StringRef Coverage, InstrProfSymtab &&ProfileNames, uint8_t BytesInAddress,
592  support::endianness Endian) {
593  std::unique_ptr<BinaryCoverageReader> Reader(new BinaryCoverageReader());
594  Reader->ProfileNames = std::move(ProfileNames);
595  if (BytesInAddress == 4 && Endian == support::endianness::little) {
596  if (Error E =
597  readCoverageMappingData<uint32_t, support::endianness::little>(
598  Reader->ProfileNames, Coverage, Reader->MappingRecords,
599  Reader->Filenames))
600  return std::move(E);
601  } else if (BytesInAddress == 4 && Endian == support::endianness::big) {
602  if (Error E = readCoverageMappingData<uint32_t, support::endianness::big>(
603  Reader->ProfileNames, Coverage, Reader->MappingRecords,
604  Reader->Filenames))
605  return std::move(E);
606  } else if (BytesInAddress == 8 && Endian == support::endianness::little) {
607  if (Error E =
608  readCoverageMappingData<uint64_t, support::endianness::little>(
609  Reader->ProfileNames, Coverage, Reader->MappingRecords,
610  Reader->Filenames))
611  return std::move(E);
612  } else if (BytesInAddress == 8 && Endian == support::endianness::big) {
613  if (Error E = readCoverageMappingData<uint64_t, support::endianness::big>(
614  Reader->ProfileNames, Coverage, Reader->MappingRecords,
615  Reader->Filenames))
616  return std::move(E);
617  } else
618  return make_error<CoverageMapError>(coveragemap_error::malformed);
619  return std::move(Reader);
620 }
621 
624  uint8_t BytesInAddress = 8;
626 
627  Data = Data.substr(StringRef(TestingFormatMagic).size());
628  if (Data.empty())
629  return make_error<CoverageMapError>(coveragemap_error::truncated);
630  unsigned N = 0;
631  uint64_t ProfileNamesSize = decodeULEB128(Data.bytes_begin(), &N);
632  if (N > Data.size())
633  return make_error<CoverageMapError>(coveragemap_error::malformed);
634  Data = Data.substr(N);
635  if (Data.empty())
636  return make_error<CoverageMapError>(coveragemap_error::truncated);
637  N = 0;
638  uint64_t Address = decodeULEB128(Data.bytes_begin(), &N);
639  if (N > Data.size())
640  return make_error<CoverageMapError>(coveragemap_error::malformed);
641  Data = Data.substr(N);
642  if (Data.size() < ProfileNamesSize)
643  return make_error<CoverageMapError>(coveragemap_error::malformed);
644  InstrProfSymtab ProfileNames;
645  if (Error E = ProfileNames.create(Data.substr(0, ProfileNamesSize), Address))
646  return std::move(E);
647  StringRef CoverageMapping = Data.substr(ProfileNamesSize);
648  // Skip the padding bytes because coverage map data has an alignment of 8.
649  if (CoverageMapping.empty())
650  return make_error<CoverageMapError>(coveragemap_error::truncated);
651  size_t Pad = offsetToAlignedAddr(CoverageMapping.data(), Align(8));
652  if (CoverageMapping.size() < Pad)
653  return make_error<CoverageMapError>(coveragemap_error::malformed);
654  CoverageMapping = CoverageMapping.substr(Pad);
656  CoverageMapping, std::move(ProfileNames), BytesInAddress, Endian);
657 }
658 
660  // On COFF, the object file section name may end in "$M". This tells the
661  // linker to sort these sections between "$A" and "$Z". The linker removes the
662  // dollar and everything after it in the final binary. Do the same to match.
663  bool IsCOFF = isa<COFFObjectFile>(OF);
664  auto stripSuffix = [IsCOFF](StringRef N) {
665  return IsCOFF ? N.split('$').first : N;
666  };
667  Name = stripSuffix(Name);
668 
669  for (const auto &Section : OF.sections()) {
670  Expected<StringRef> NameOrErr = Section.getName();
671  if (!NameOrErr)
672  return NameOrErr.takeError();
673  if (stripSuffix(*NameOrErr) == Name)
674  return Section;
675  }
676  return make_error<CoverageMapError>(coveragemap_error::no_data_found);
677 }
678 
680 loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch) {
681  std::unique_ptr<ObjectFile> OF;
682  if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin.get())) {
683  // If we have a universal binary, try to look up the object for the
684  // appropriate architecture.
685  auto ObjectFileOrErr = Universal->getMachOObjectForArch(Arch);
686  if (!ObjectFileOrErr)
687  return ObjectFileOrErr.takeError();
688  OF = std::move(ObjectFileOrErr.get());
689  } else if (isa<ObjectFile>(Bin.get())) {
690  // For any other object file, upcast and take ownership.
691  OF.reset(cast<ObjectFile>(Bin.release()));
692  // If we've asked for a particular arch, make sure they match.
693  if (!Arch.empty() && OF->getArch() != Triple(Arch).getArch())
694  return errorCodeToError(object_error::arch_not_found);
695  } else
696  // We can only handle object files.
697  return make_error<CoverageMapError>(coveragemap_error::malformed);
698 
699  // The coverage uses native pointer sizes for the object it's written in.
700  uint8_t BytesInAddress = OF->getBytesInAddress();
701  support::endianness Endian = OF->isLittleEndian()
704 
705  // Look for the sections that we are interested in.
706  auto ObjFormat = OF->getTripleObjectFormat();
707  auto NamesSection =
708  lookupSection(*OF, getInstrProfSectionName(IPSK_name, ObjFormat,
709  /*AddSegmentInfo=*/false));
710  if (auto E = NamesSection.takeError())
711  return std::move(E);
712  auto CoverageSection =
713  lookupSection(*OF, getInstrProfSectionName(IPSK_covmap, ObjFormat,
714  /*AddSegmentInfo=*/false));
715  if (auto E = CoverageSection.takeError())
716  return std::move(E);
717 
718  // Get the contents of the given sections.
719  auto CoverageMappingOrErr = CoverageSection->getContents();
720  if (!CoverageMappingOrErr)
721  return CoverageMappingOrErr.takeError();
722 
723  InstrProfSymtab ProfileNames;
724  if (Error E = ProfileNames.create(*NamesSection))
725  return std::move(E);
726 
728  CoverageMappingOrErr.get(), std::move(ProfileNames), BytesInAddress,
729  Endian);
730 }
731 
734  MemoryBufferRef ObjectBuffer, StringRef Arch,
735  SmallVectorImpl<std::unique_ptr<MemoryBuffer>> &ObjectFileBuffers) {
736  std::vector<std::unique_ptr<BinaryCoverageReader>> Readers;
737 
738  if (ObjectBuffer.getBuffer().startswith(TestingFormatMagic)) {
739  // This is a special format used for testing.
740  auto ReaderOrErr = loadTestingFormat(ObjectBuffer.getBuffer());
741  if (!ReaderOrErr)
742  return ReaderOrErr.takeError();
743  Readers.push_back(std::move(ReaderOrErr.get()));
744  return std::move(Readers);
745  }
746 
747  auto BinOrErr = createBinary(ObjectBuffer);
748  if (!BinOrErr)
749  return BinOrErr.takeError();
750  std::unique_ptr<Binary> Bin = std::move(BinOrErr.get());
751 
752  // MachO universal binaries which contain archives need to be treated as
753  // archives, not as regular binaries.
754  if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin.get())) {
755  for (auto &ObjForArch : Universal->objects()) {
756  // Skip slices within the universal binary which target the wrong arch.
757  std::string ObjArch = ObjForArch.getArchFlagName();
758  if (Arch != ObjArch)
759  continue;
760 
761  auto ArchiveOrErr = ObjForArch.getAsArchive();
762  if (!ArchiveOrErr) {
763  // If this is not an archive, try treating it as a regular object.
764  consumeError(ArchiveOrErr.takeError());
765  break;
766  }
767 
769  ArchiveOrErr.get()->getMemoryBufferRef(), Arch, ObjectFileBuffers);
770  }
771  }
772 
773  // Load coverage out of archive members.
774  if (auto *Ar = dyn_cast<Archive>(Bin.get())) {
775  Error Err = Error::success();
776  for (auto &Child : Ar->children(Err)) {
777  Expected<MemoryBufferRef> ChildBufOrErr = Child.getMemoryBufferRef();
778  if (!ChildBufOrErr)
779  return ChildBufOrErr.takeError();
780 
781  auto ChildReadersOrErr = BinaryCoverageReader::create(
782  ChildBufOrErr.get(), Arch, ObjectFileBuffers);
783  if (!ChildReadersOrErr)
784  return ChildReadersOrErr.takeError();
785  for (auto &Reader : ChildReadersOrErr.get())
786  Readers.push_back(std::move(Reader));
787  }
788  if (Err)
789  return std::move(Err);
790 
791  // Thin archives reference object files outside of the archive file, i.e.
792  // files which reside in memory not owned by the caller. Transfer ownership
793  // to the caller.
794  if (Ar->isThin())
795  for (auto &Buffer : Ar->takeThinBuffers())
796  ObjectFileBuffers.push_back(std::move(Buffer));
797 
798  return std::move(Readers);
799  }
800 
801  auto ReaderOrErr = loadBinaryFormat(std::move(Bin), Arch);
802  if (!ReaderOrErr)
803  return ReaderOrErr.takeError();
804  Readers.push_back(std::move(ReaderOrErr.get()));
805  return std::move(Readers);
806 }
807 
809  if (CurrentRecord >= MappingRecords.size())
810  return make_error<CoverageMapError>(coveragemap_error::eof);
811 
812  FunctionsFilenames.clear();
813  Expressions.clear();
814  MappingRegions.clear();
815  auto &R = MappingRecords[CurrentRecord];
817  R.CoverageMapping,
818  makeArrayRef(Filenames).slice(R.FilenamesBegin, R.FilenamesSize),
819  FunctionsFilenames, Expressions, MappingRegions);
820  if (auto Err = Reader.read())
821  return Err;
822 
823  Record.FunctionName = R.FunctionName;
824  Record.FunctionHash = R.FunctionHash;
825  Record.Filenames = FunctionsFilenames;
826  Record.Expressions = Expressions;
827  Record.MappingRegions = MappingRegions;
828 
829  ++CurrentRecord;
830  return Error::success();
831 }
Pass interface - Implemented by all &#39;passes&#39;.
Definition: Pass.h:80
uint64_t CallInst * C
static Expected< std::vector< std::unique_ptr< BinaryCoverageReader > > > create(MemoryBufferRef ObjectBuffer, StringRef Arch, SmallVectorImpl< std::unique_ptr< MemoryBuffer >> &ObjectFileBuffers)
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
A symbol table used for function PGO name look-up with keys (such as pointers, md5hash values) to the...
Definition: InstrProf.h:406
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.
uint64_t offsetToAlignedAddr(const void *Addr, Align Alignment)
Returns the necessary adjustment for aligning Addr to Alignment bytes, rounding up.
Definition: Alignment.h:199
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
LLVM_NODISCARD bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:270
void push_back(const T &Elt)
Definition: SmallVector.h:211
Checks if the given coverage mapping data is exported for an unused function.
static Expected< std::unique_ptr< BinaryCoverageReader > > loadTestingFormat(StringRef Data)
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.
Error takeError()
Take ownership of the stored error.
Definition: Error.h:552
ArrayRef< CounterMappingRegion > MappingRegions
gvn Early GVN Hoisting of Expressions
Definition: GVNHoist.cpp:1202
Expected< std::unique_ptr< Binary > > createBinary(MemoryBufferRef Source, LLVMContext *Context=nullptr)
Create a Binary from Source, autodetecting the file type.
Definition: Binary.cpp:46
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:195
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
StringRef getBuffer() const
Definition: MemoryBuffer.h:272
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:41
Tagged union holding either a T or a Error.
Definition: yaml2obj.h:21
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:592
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:140
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:296
void dump(const Counter &C, raw_ostream &OS) const
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:144
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")
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:1001
#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:924
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:1146
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:390
static Expected< SectionRef > lookupSection(ObjectFile &OF, StringRef Name)
static const unsigned EncodingExpansionRegionBit
static const char * TestingFormatMagic
reference get()
Returns a reference to the stored T value.
Definition: Error.h:532
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.
const unsigned char * bytes_begin() const
Definition: StringRef.h:119
#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:136
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static Expected< std::unique_ptr< BinaryCoverageReader > > createCoverageReaderFromBuffer(StringRef Coverage, InstrProfSymtab &&ProfileNames, uint8_t BytesInAddress, support::endianness Endian)
static const unsigned EncodingTagBits
static Expected< bool > isCoverageMappingDummy(uint64_t Hash, StringRef Mapping)
LLVM Value Representation.
Definition: Value.h:74
static Expected< std::unique_ptr< BinaryCoverageReader > > loadBinaryFormat(std::unique_ptr< Binary > Bin, StringRef Arch)
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:980
static Counter getCounter(unsigned CounterId)
Return the counter that corresponds to a specific profile counter.
void resize(size_type N)
Definition: SmallVector.h:344