• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //=-- CoverageMappingReader.h - Code coverage mapping reader ------*- C++ -*-=//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains support for reading coverage mapping data for
11 // instrumentation based coverage.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_PROFILEDATA_COVERAGEMAPPINGREADER_H
16 #define LLVM_PROFILEDATA_COVERAGEMAPPINGREADER_H
17 
18 #include "llvm/ADT/ArrayRef.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/ADT/Triple.h"
21 #include "llvm/Object/ObjectFile.h"
22 #include "llvm/ProfileData/Coverage/CoverageMapping.h"
23 #include "llvm/ProfileData/InstrProf.h"
24 #include "llvm/Support/FileSystem.h"
25 #include "llvm/Support/MemoryBuffer.h"
26 #include <iterator>
27 
28 namespace llvm {
29 namespace coverage {
30 
31 class CoverageMappingReader;
32 
33 /// \brief Coverage mapping information for a single function.
34 struct CoverageMappingRecord {
35   StringRef FunctionName;
36   uint64_t FunctionHash;
37   ArrayRef<StringRef> Filenames;
38   ArrayRef<CounterExpression> Expressions;
39   ArrayRef<CounterMappingRegion> MappingRegions;
40 };
41 
42 /// \brief A file format agnostic iterator over coverage mapping data.
43 class CoverageMappingIterator
44     : public std::iterator<std::input_iterator_tag, CoverageMappingRecord> {
45   CoverageMappingReader *Reader;
46   CoverageMappingRecord Record;
47 
48   void increment();
49 
50 public:
CoverageMappingIterator()51   CoverageMappingIterator() : Reader(nullptr) {}
CoverageMappingIterator(CoverageMappingReader * Reader)52   CoverageMappingIterator(CoverageMappingReader *Reader) : Reader(Reader) {
53     increment();
54   }
55 
56   CoverageMappingIterator &operator++() {
57     increment();
58     return *this;
59   }
60   bool operator==(const CoverageMappingIterator &RHS) {
61     return Reader == RHS.Reader;
62   }
63   bool operator!=(const CoverageMappingIterator &RHS) {
64     return Reader != RHS.Reader;
65   }
66   CoverageMappingRecord &operator*() { return Record; }
67   CoverageMappingRecord *operator->() { return &Record; }
68 };
69 
70 class CoverageMappingReader {
71 public:
72   virtual Error readNextRecord(CoverageMappingRecord &Record) = 0;
begin()73   CoverageMappingIterator begin() { return CoverageMappingIterator(this); }
end()74   CoverageMappingIterator end() { return CoverageMappingIterator(); }
~CoverageMappingReader()75   virtual ~CoverageMappingReader() {}
76 };
77 
78 /// \brief Base class for the raw coverage mapping and filenames data readers.
79 class RawCoverageReader {
80 protected:
81   StringRef Data;
82 
RawCoverageReader(StringRef Data)83   RawCoverageReader(StringRef Data) : Data(Data) {}
84 
85   Error readULEB128(uint64_t &Result);
86   Error readIntMax(uint64_t &Result, uint64_t MaxPlus1);
87   Error readSize(uint64_t &Result);
88   Error readString(StringRef &Result);
89 };
90 
91 /// \brief Reader for the raw coverage filenames.
92 class RawCoverageFilenamesReader : public RawCoverageReader {
93   std::vector<StringRef> &Filenames;
94 
95   RawCoverageFilenamesReader(const RawCoverageFilenamesReader &) = delete;
96   RawCoverageFilenamesReader &
97   operator=(const RawCoverageFilenamesReader &) = delete;
98 
99 public:
RawCoverageFilenamesReader(StringRef Data,std::vector<StringRef> & Filenames)100   RawCoverageFilenamesReader(StringRef Data, std::vector<StringRef> &Filenames)
101       : RawCoverageReader(Data), Filenames(Filenames) {}
102 
103   Error read();
104 };
105 
106 /// \brief Checks if the given coverage mapping data is exported for
107 /// an unused function.
108 class RawCoverageMappingDummyChecker : public RawCoverageReader {
109 public:
RawCoverageMappingDummyChecker(StringRef MappingData)110   RawCoverageMappingDummyChecker(StringRef MappingData)
111       : RawCoverageReader(MappingData) {}
112 
113   Expected<bool> isDummy();
114 };
115 
116 /// \brief Reader for the raw coverage mapping data.
117 class RawCoverageMappingReader : public RawCoverageReader {
118   ArrayRef<StringRef> TranslationUnitFilenames;
119   std::vector<StringRef> &Filenames;
120   std::vector<CounterExpression> &Expressions;
121   std::vector<CounterMappingRegion> &MappingRegions;
122 
123   RawCoverageMappingReader(const RawCoverageMappingReader &) = delete;
124   RawCoverageMappingReader &
125   operator=(const RawCoverageMappingReader &) = delete;
126 
127 public:
RawCoverageMappingReader(StringRef MappingData,ArrayRef<StringRef> TranslationUnitFilenames,std::vector<StringRef> & Filenames,std::vector<CounterExpression> & Expressions,std::vector<CounterMappingRegion> & MappingRegions)128   RawCoverageMappingReader(StringRef MappingData,
129                            ArrayRef<StringRef> TranslationUnitFilenames,
130                            std::vector<StringRef> &Filenames,
131                            std::vector<CounterExpression> &Expressions,
132                            std::vector<CounterMappingRegion> &MappingRegions)
133       : RawCoverageReader(MappingData),
134         TranslationUnitFilenames(TranslationUnitFilenames),
135         Filenames(Filenames), Expressions(Expressions),
136         MappingRegions(MappingRegions) {}
137 
138   Error read();
139 
140 private:
141   Error decodeCounter(unsigned Value, Counter &C);
142   Error readCounter(Counter &C);
143   Error
144   readMappingRegionsSubArray(std::vector<CounterMappingRegion> &MappingRegions,
145                              unsigned InferredFileID, size_t NumFileIDs);
146 };
147 
148 /// \brief Reader for the coverage mapping data that is emitted by the
149 /// frontend and stored in an object file.
150 class BinaryCoverageReader : public CoverageMappingReader {
151 public:
152   struct ProfileMappingRecord {
153     CovMapVersion Version;
154     StringRef FunctionName;
155     uint64_t FunctionHash;
156     StringRef CoverageMapping;
157     size_t FilenamesBegin;
158     size_t FilenamesSize;
159 
ProfileMappingRecordProfileMappingRecord160     ProfileMappingRecord(CovMapVersion Version, StringRef FunctionName,
161                          uint64_t FunctionHash, StringRef CoverageMapping,
162                          size_t FilenamesBegin, size_t FilenamesSize)
163         : Version(Version), FunctionName(FunctionName),
164           FunctionHash(FunctionHash), CoverageMapping(CoverageMapping),
165           FilenamesBegin(FilenamesBegin), FilenamesSize(FilenamesSize) {}
166   };
167 
168 private:
169   std::vector<StringRef> Filenames;
170   std::vector<ProfileMappingRecord> MappingRecords;
171   InstrProfSymtab ProfileNames;
172   size_t CurrentRecord;
173   std::vector<StringRef> FunctionsFilenames;
174   std::vector<CounterExpression> Expressions;
175   std::vector<CounterMappingRegion> MappingRegions;
176 
177   BinaryCoverageReader(const BinaryCoverageReader &) = delete;
178   BinaryCoverageReader &operator=(const BinaryCoverageReader &) = delete;
179 
BinaryCoverageReader()180   BinaryCoverageReader() : CurrentRecord(0) {}
181 
182 public:
183   static Expected<std::unique_ptr<BinaryCoverageReader>>
184   create(std::unique_ptr<MemoryBuffer> &ObjectBuffer,
185          StringRef Arch);
186 
187   Error readNextRecord(CoverageMappingRecord &Record) override;
188 };
189 
190 } // end namespace coverage
191 } // end namespace llvm
192 
193 #endif
194