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/Object/ObjectFile.h"
21 #include "llvm/ProfileData/CoverageMapping.h"
22 #include "llvm/ProfileData/InstrProf.h"
23 #include "llvm/Support/FileSystem.h"
24 #include "llvm/Support/MemoryBuffer.h"
25 #include <iterator>
26 
27 namespace llvm {
28 namespace coverage {
29 
30 class ObjectFileCoverageMappingReader;
31 
32 /// \brief Coverage mapping information for a single function.
33 struct CoverageMappingRecord {
34   StringRef FunctionName;
35   uint64_t FunctionHash;
36   ArrayRef<StringRef> Filenames;
37   ArrayRef<CounterExpression> Expressions;
38   ArrayRef<CounterMappingRegion> MappingRegions;
39 };
40 
41 /// \brief A file format agnostic iterator over coverage mapping data.
42 class CoverageMappingIterator
43     : public std::iterator<std::input_iterator_tag, CoverageMappingRecord> {
44   ObjectFileCoverageMappingReader *Reader;
45   CoverageMappingRecord Record;
46 
47   void increment();
48 
49 public:
CoverageMappingIterator()50   CoverageMappingIterator() : Reader(nullptr) {}
CoverageMappingIterator(ObjectFileCoverageMappingReader * Reader)51   CoverageMappingIterator(ObjectFileCoverageMappingReader *Reader)
52       : 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 /// \brief Base class for the raw coverage mapping and filenames data readers.
71 class RawCoverageReader {
72 protected:
73   StringRef Data;
74 
75   /// \brief Return the error code.
error(std::error_code EC)76   std::error_code error(std::error_code EC) { return EC; }
77 
78   /// \brief Clear the current error code and return a successful one.
success()79   std::error_code success() { return error(instrprof_error::success); }
80 
RawCoverageReader(StringRef Data)81   RawCoverageReader(StringRef Data) : Data(Data) {}
82 
83   std::error_code readULEB128(uint64_t &Result);
84   std::error_code readIntMax(uint64_t &Result, uint64_t MaxPlus1);
85   std::error_code readSize(uint64_t &Result);
86   std::error_code readString(StringRef &Result);
87 };
88 
89 /// \brief Reader for the raw coverage filenames.
90 class RawCoverageFilenamesReader : public RawCoverageReader {
91   std::vector<StringRef> &Filenames;
92 
93   RawCoverageFilenamesReader(const RawCoverageFilenamesReader &)
94       LLVM_DELETED_FUNCTION;
95   RawCoverageFilenamesReader &
96   operator=(const RawCoverageFilenamesReader &) LLVM_DELETED_FUNCTION;
97 
98 public:
RawCoverageFilenamesReader(StringRef Data,std::vector<StringRef> & Filenames)99   RawCoverageFilenamesReader(StringRef Data, std::vector<StringRef> &Filenames)
100       : RawCoverageReader(Data), Filenames(Filenames) {}
101 
102   std::error_code read();
103 };
104 
105 /// \brief Reader for the raw coverage mapping data.
106 class RawCoverageMappingReader : public RawCoverageReader {
107   StringRef FunctionName;
108   ArrayRef<StringRef> TranslationUnitFilenames;
109   std::vector<StringRef> &Filenames;
110   std::vector<CounterExpression> &Expressions;
111   std::vector<CounterMappingRegion> &MappingRegions;
112 
113   RawCoverageMappingReader(const RawCoverageMappingReader &)
114       LLVM_DELETED_FUNCTION;
115   RawCoverageMappingReader &
116   operator=(const RawCoverageMappingReader &) LLVM_DELETED_FUNCTION;
117 
118 public:
RawCoverageMappingReader(StringRef FunctionName,StringRef MappingData,ArrayRef<StringRef> TranslationUnitFilenames,std::vector<StringRef> & Filenames,std::vector<CounterExpression> & Expressions,std::vector<CounterMappingRegion> & MappingRegions)119   RawCoverageMappingReader(StringRef FunctionName, StringRef MappingData,
120                            ArrayRef<StringRef> TranslationUnitFilenames,
121                            std::vector<StringRef> &Filenames,
122                            std::vector<CounterExpression> &Expressions,
123                            std::vector<CounterMappingRegion> &MappingRegions)
124       : RawCoverageReader(MappingData), FunctionName(FunctionName),
125         TranslationUnitFilenames(TranslationUnitFilenames),
126         Filenames(Filenames), Expressions(Expressions),
127         MappingRegions(MappingRegions) {}
128 
129   std::error_code read(CoverageMappingRecord &Record);
130 
131 private:
132   std::error_code decodeCounter(unsigned Value, Counter &C);
133   std::error_code readCounter(Counter &C);
134   std::error_code
135   readMappingRegionsSubArray(std::vector<CounterMappingRegion> &MappingRegions,
136                              unsigned InferredFileID, size_t NumFileIDs);
137 };
138 
139 /// \brief Reader for the coverage mapping data that is emitted by the
140 /// frontend and stored in an object file.
141 class ObjectFileCoverageMappingReader {
142 public:
143   struct ProfileMappingRecord {
144     CoverageMappingVersion Version;
145     StringRef FunctionName;
146     uint64_t FunctionHash;
147     StringRef CoverageMapping;
148     size_t FilenamesBegin;
149     size_t FilenamesSize;
150 
ProfileMappingRecordProfileMappingRecord151     ProfileMappingRecord(CoverageMappingVersion Version, StringRef FunctionName,
152                          uint64_t FunctionHash, StringRef CoverageMapping,
153                          size_t FilenamesBegin, size_t FilenamesSize)
154         : Version(Version), FunctionName(FunctionName),
155           FunctionHash(FunctionHash), CoverageMapping(CoverageMapping),
156           FilenamesBegin(FilenamesBegin), FilenamesSize(FilenamesSize) {}
157   };
158 
159 private:
160   std::error_code LastError;
161   object::OwningBinary<object::ObjectFile> Object;
162   std::vector<StringRef> Filenames;
163   std::vector<ProfileMappingRecord> MappingRecords;
164   size_t CurrentRecord;
165   std::vector<StringRef> FunctionsFilenames;
166   std::vector<CounterExpression> Expressions;
167   std::vector<CounterMappingRegion> MappingRegions;
168 
169   ObjectFileCoverageMappingReader(const ObjectFileCoverageMappingReader &)
170       LLVM_DELETED_FUNCTION;
171   ObjectFileCoverageMappingReader &
172   operator=(const ObjectFileCoverageMappingReader &) LLVM_DELETED_FUNCTION;
173 
174   /// \brief Set the current error_code and return same.
error(std::error_code EC)175   std::error_code error(std::error_code EC) {
176     LastError = EC;
177     return EC;
178   }
179 
180   /// \brief Clear the current error code and return a successful one.
success()181   std::error_code success() { return error(instrprof_error::success); }
182 
183 public:
184   ObjectFileCoverageMappingReader(StringRef FileName);
185   ObjectFileCoverageMappingReader(
186       std::unique_ptr<MemoryBuffer> &ObjectBuffer,
187       sys::fs::file_magic Type = sys::fs::file_magic::unknown);
188 
189   std::error_code readHeader();
190   std::error_code readNextRecord(CoverageMappingRecord &Record);
191 
192   /// Iterator over profile data.
begin()193   CoverageMappingIterator begin() { return CoverageMappingIterator(this); }
end()194   CoverageMappingIterator end() { return CoverageMappingIterator(); }
195 
196   /// \brief Return true if the reader has finished reading the profile data.
isEOF()197   bool isEOF() { return LastError == instrprof_error::eof; }
198   /// \brief Return true if the reader encountered an error reading profiling
199   /// data.
hasError()200   bool hasError() { return LastError && !isEOF(); }
201   /// \brief Get the current error code.
getError()202   std::error_code getError() { return LastError; }
203 };
204 
205 } // end namespace coverage
206 } // end namespace llvm
207 
208 #endif
209