1*dc707122SEaswaran Raman //=-- CoverageMappingReader.cpp - Code coverage mapping reader ----*- C++ -*-=//
2*dc707122SEaswaran Raman //
3*dc707122SEaswaran Raman //                     The LLVM Compiler Infrastructure
4*dc707122SEaswaran Raman //
5*dc707122SEaswaran Raman // This file is distributed under the University of Illinois Open Source
6*dc707122SEaswaran Raman // License. See LICENSE.TXT for details.
7*dc707122SEaswaran Raman //
8*dc707122SEaswaran Raman //===----------------------------------------------------------------------===//
9*dc707122SEaswaran Raman //
10*dc707122SEaswaran Raman // This file contains support for reading coverage mapping data for
11*dc707122SEaswaran Raman // instrumentation based coverage.
12*dc707122SEaswaran Raman //
13*dc707122SEaswaran Raman //===----------------------------------------------------------------------===//
14*dc707122SEaswaran Raman 
15*dc707122SEaswaran Raman #include "llvm/ProfileData/Coverage/CoverageMappingReader.h"
16*dc707122SEaswaran Raman #include "llvm/ADT/DenseSet.h"
17*dc707122SEaswaran Raman #include "llvm/Object/MachOUniversal.h"
18*dc707122SEaswaran Raman #include "llvm/Object/ObjectFile.h"
19*dc707122SEaswaran Raman #include "llvm/Support/Debug.h"
20*dc707122SEaswaran Raman #include "llvm/Support/Endian.h"
21*dc707122SEaswaran Raman #include "llvm/Support/LEB128.h"
22*dc707122SEaswaran Raman #include "llvm/Support/MathExtras.h"
23*dc707122SEaswaran Raman #include "llvm/Support/raw_ostream.h"
24*dc707122SEaswaran Raman 
25*dc707122SEaswaran Raman using namespace llvm;
26*dc707122SEaswaran Raman using namespace coverage;
27*dc707122SEaswaran Raman using namespace object;
28*dc707122SEaswaran Raman 
29*dc707122SEaswaran Raman #define DEBUG_TYPE "coverage-mapping"
30*dc707122SEaswaran Raman 
31*dc707122SEaswaran Raman void CoverageMappingIterator::increment() {
32*dc707122SEaswaran Raman   // Check if all the records were read or if an error occurred while reading
33*dc707122SEaswaran Raman   // the next record.
34*dc707122SEaswaran Raman   if (Reader->readNextRecord(Record))
35*dc707122SEaswaran Raman     *this = CoverageMappingIterator();
36*dc707122SEaswaran Raman }
37*dc707122SEaswaran Raman 
38*dc707122SEaswaran Raman std::error_code RawCoverageReader::readULEB128(uint64_t &Result) {
39*dc707122SEaswaran Raman   if (Data.size() < 1)
40*dc707122SEaswaran Raman     return coveragemap_error::truncated;
41*dc707122SEaswaran Raman   unsigned N = 0;
42*dc707122SEaswaran Raman   Result = decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
43*dc707122SEaswaran Raman   if (N > Data.size())
44*dc707122SEaswaran Raman     return coveragemap_error::malformed;
45*dc707122SEaswaran Raman   Data = Data.substr(N);
46*dc707122SEaswaran Raman   return std::error_code();
47*dc707122SEaswaran Raman }
48*dc707122SEaswaran Raman 
49*dc707122SEaswaran Raman std::error_code RawCoverageReader::readIntMax(uint64_t &Result,
50*dc707122SEaswaran Raman                                               uint64_t MaxPlus1) {
51*dc707122SEaswaran Raman   if (auto Err = readULEB128(Result))
52*dc707122SEaswaran Raman     return Err;
53*dc707122SEaswaran Raman   if (Result >= MaxPlus1)
54*dc707122SEaswaran Raman     return coveragemap_error::malformed;
55*dc707122SEaswaran Raman   return std::error_code();
56*dc707122SEaswaran Raman }
57*dc707122SEaswaran Raman 
58*dc707122SEaswaran Raman std::error_code RawCoverageReader::readSize(uint64_t &Result) {
59*dc707122SEaswaran Raman   if (auto Err = readULEB128(Result))
60*dc707122SEaswaran Raman     return Err;
61*dc707122SEaswaran Raman   // Sanity check the number.
62*dc707122SEaswaran Raman   if (Result > Data.size())
63*dc707122SEaswaran Raman     return coveragemap_error::malformed;
64*dc707122SEaswaran Raman   return std::error_code();
65*dc707122SEaswaran Raman }
66*dc707122SEaswaran Raman 
67*dc707122SEaswaran Raman std::error_code RawCoverageReader::readString(StringRef &Result) {
68*dc707122SEaswaran Raman   uint64_t Length;
69*dc707122SEaswaran Raman   if (auto Err = readSize(Length))
70*dc707122SEaswaran Raman     return Err;
71*dc707122SEaswaran Raman   Result = Data.substr(0, Length);
72*dc707122SEaswaran Raman   Data = Data.substr(Length);
73*dc707122SEaswaran Raman   return std::error_code();
74*dc707122SEaswaran Raman }
75*dc707122SEaswaran Raman 
76*dc707122SEaswaran Raman std::error_code RawCoverageFilenamesReader::read() {
77*dc707122SEaswaran Raman   uint64_t NumFilenames;
78*dc707122SEaswaran Raman   if (auto Err = readSize(NumFilenames))
79*dc707122SEaswaran Raman     return Err;
80*dc707122SEaswaran Raman   for (size_t I = 0; I < NumFilenames; ++I) {
81*dc707122SEaswaran Raman     StringRef Filename;
82*dc707122SEaswaran Raman     if (auto Err = readString(Filename))
83*dc707122SEaswaran Raman       return Err;
84*dc707122SEaswaran Raman     Filenames.push_back(Filename);
85*dc707122SEaswaran Raman   }
86*dc707122SEaswaran Raman   return std::error_code();
87*dc707122SEaswaran Raman }
88*dc707122SEaswaran Raman 
89*dc707122SEaswaran Raman std::error_code RawCoverageMappingReader::decodeCounter(unsigned Value,
90*dc707122SEaswaran Raman                                                         Counter &C) {
91*dc707122SEaswaran Raman   auto Tag = Value & Counter::EncodingTagMask;
92*dc707122SEaswaran Raman   switch (Tag) {
93*dc707122SEaswaran Raman   case Counter::Zero:
94*dc707122SEaswaran Raman     C = Counter::getZero();
95*dc707122SEaswaran Raman     return std::error_code();
96*dc707122SEaswaran Raman   case Counter::CounterValueReference:
97*dc707122SEaswaran Raman     C = Counter::getCounter(Value >> Counter::EncodingTagBits);
98*dc707122SEaswaran Raman     return std::error_code();
99*dc707122SEaswaran Raman   default:
100*dc707122SEaswaran Raman     break;
101*dc707122SEaswaran Raman   }
102*dc707122SEaswaran Raman   Tag -= Counter::Expression;
103*dc707122SEaswaran Raman   switch (Tag) {
104*dc707122SEaswaran Raman   case CounterExpression::Subtract:
105*dc707122SEaswaran Raman   case CounterExpression::Add: {
106*dc707122SEaswaran Raman     auto ID = Value >> Counter::EncodingTagBits;
107*dc707122SEaswaran Raman     if (ID >= Expressions.size())
108*dc707122SEaswaran Raman       return coveragemap_error::malformed;
109*dc707122SEaswaran Raman     Expressions[ID].Kind = CounterExpression::ExprKind(Tag);
110*dc707122SEaswaran Raman     C = Counter::getExpression(ID);
111*dc707122SEaswaran Raman     break;
112*dc707122SEaswaran Raman   }
113*dc707122SEaswaran Raman   default:
114*dc707122SEaswaran Raman     return coveragemap_error::malformed;
115*dc707122SEaswaran Raman   }
116*dc707122SEaswaran Raman   return std::error_code();
117*dc707122SEaswaran Raman }
118*dc707122SEaswaran Raman 
119*dc707122SEaswaran Raman std::error_code RawCoverageMappingReader::readCounter(Counter &C) {
120*dc707122SEaswaran Raman   uint64_t EncodedCounter;
121*dc707122SEaswaran Raman   if (auto Err =
122*dc707122SEaswaran Raman           readIntMax(EncodedCounter, std::numeric_limits<unsigned>::max()))
123*dc707122SEaswaran Raman     return Err;
124*dc707122SEaswaran Raman   if (auto Err = decodeCounter(EncodedCounter, C))
125*dc707122SEaswaran Raman     return Err;
126*dc707122SEaswaran Raman   return std::error_code();
127*dc707122SEaswaran Raman }
128*dc707122SEaswaran Raman 
129*dc707122SEaswaran Raman static const unsigned EncodingExpansionRegionBit = 1
130*dc707122SEaswaran Raman                                                    << Counter::EncodingTagBits;
131*dc707122SEaswaran Raman 
132*dc707122SEaswaran Raman /// \brief Read the sub-array of regions for the given inferred file id.
133*dc707122SEaswaran Raman /// \param NumFileIDs the number of file ids that are defined for this
134*dc707122SEaswaran Raman /// function.
135*dc707122SEaswaran Raman std::error_code RawCoverageMappingReader::readMappingRegionsSubArray(
136*dc707122SEaswaran Raman     std::vector<CounterMappingRegion> &MappingRegions, unsigned InferredFileID,
137*dc707122SEaswaran Raman     size_t NumFileIDs) {
138*dc707122SEaswaran Raman   uint64_t NumRegions;
139*dc707122SEaswaran Raman   if (auto Err = readSize(NumRegions))
140*dc707122SEaswaran Raman     return Err;
141*dc707122SEaswaran Raman   unsigned LineStart = 0;
142*dc707122SEaswaran Raman   for (size_t I = 0; I < NumRegions; ++I) {
143*dc707122SEaswaran Raman     Counter C;
144*dc707122SEaswaran Raman     CounterMappingRegion::RegionKind Kind = CounterMappingRegion::CodeRegion;
145*dc707122SEaswaran Raman 
146*dc707122SEaswaran Raman     // Read the combined counter + region kind.
147*dc707122SEaswaran Raman     uint64_t EncodedCounterAndRegion;
148*dc707122SEaswaran Raman     if (auto Err = readIntMax(EncodedCounterAndRegion,
149*dc707122SEaswaran Raman                               std::numeric_limits<unsigned>::max()))
150*dc707122SEaswaran Raman       return Err;
151*dc707122SEaswaran Raman     unsigned Tag = EncodedCounterAndRegion & Counter::EncodingTagMask;
152*dc707122SEaswaran Raman     uint64_t ExpandedFileID = 0;
153*dc707122SEaswaran Raman     if (Tag != Counter::Zero) {
154*dc707122SEaswaran Raman       if (auto Err = decodeCounter(EncodedCounterAndRegion, C))
155*dc707122SEaswaran Raman         return Err;
156*dc707122SEaswaran Raman     } else {
157*dc707122SEaswaran Raman       // Is it an expansion region?
158*dc707122SEaswaran Raman       if (EncodedCounterAndRegion & EncodingExpansionRegionBit) {
159*dc707122SEaswaran Raman         Kind = CounterMappingRegion::ExpansionRegion;
160*dc707122SEaswaran Raman         ExpandedFileID = EncodedCounterAndRegion >>
161*dc707122SEaswaran Raman                          Counter::EncodingCounterTagAndExpansionRegionTagBits;
162*dc707122SEaswaran Raman         if (ExpandedFileID >= NumFileIDs)
163*dc707122SEaswaran Raman           return coveragemap_error::malformed;
164*dc707122SEaswaran Raman       } else {
165*dc707122SEaswaran Raman         switch (EncodedCounterAndRegion >>
166*dc707122SEaswaran Raman                 Counter::EncodingCounterTagAndExpansionRegionTagBits) {
167*dc707122SEaswaran Raman         case CounterMappingRegion::CodeRegion:
168*dc707122SEaswaran Raman           // Don't do anything when we have a code region with a zero counter.
169*dc707122SEaswaran Raman           break;
170*dc707122SEaswaran Raman         case CounterMappingRegion::SkippedRegion:
171*dc707122SEaswaran Raman           Kind = CounterMappingRegion::SkippedRegion;
172*dc707122SEaswaran Raman           break;
173*dc707122SEaswaran Raman         default:
174*dc707122SEaswaran Raman           return coveragemap_error::malformed;
175*dc707122SEaswaran Raman         }
176*dc707122SEaswaran Raman       }
177*dc707122SEaswaran Raman     }
178*dc707122SEaswaran Raman 
179*dc707122SEaswaran Raman     // Read the source range.
180*dc707122SEaswaran Raman     uint64_t LineStartDelta, ColumnStart, NumLines, ColumnEnd;
181*dc707122SEaswaran Raman     if (auto Err =
182*dc707122SEaswaran Raman             readIntMax(LineStartDelta, std::numeric_limits<unsigned>::max()))
183*dc707122SEaswaran Raman       return Err;
184*dc707122SEaswaran Raman     if (auto Err = readULEB128(ColumnStart))
185*dc707122SEaswaran Raman       return Err;
186*dc707122SEaswaran Raman     if (ColumnStart > std::numeric_limits<unsigned>::max())
187*dc707122SEaswaran Raman       return coveragemap_error::malformed;
188*dc707122SEaswaran Raman     if (auto Err = readIntMax(NumLines, std::numeric_limits<unsigned>::max()))
189*dc707122SEaswaran Raman       return Err;
190*dc707122SEaswaran Raman     if (auto Err = readIntMax(ColumnEnd, std::numeric_limits<unsigned>::max()))
191*dc707122SEaswaran Raman       return Err;
192*dc707122SEaswaran Raman     LineStart += LineStartDelta;
193*dc707122SEaswaran Raman     // Adjust the column locations for the empty regions that are supposed to
194*dc707122SEaswaran Raman     // cover whole lines. Those regions should be encoded with the
195*dc707122SEaswaran Raman     // column range (1 -> std::numeric_limits<unsigned>::max()), but because
196*dc707122SEaswaran Raman     // the encoded std::numeric_limits<unsigned>::max() is several bytes long,
197*dc707122SEaswaran Raman     // we set the column range to (0 -> 0) to ensure that the column start and
198*dc707122SEaswaran Raman     // column end take up one byte each.
199*dc707122SEaswaran Raman     // The std::numeric_limits<unsigned>::max() is used to represent a column
200*dc707122SEaswaran Raman     // position at the end of the line without knowing the length of that line.
201*dc707122SEaswaran Raman     if (ColumnStart == 0 && ColumnEnd == 0) {
202*dc707122SEaswaran Raman       ColumnStart = 1;
203*dc707122SEaswaran Raman       ColumnEnd = std::numeric_limits<unsigned>::max();
204*dc707122SEaswaran Raman     }
205*dc707122SEaswaran Raman 
206*dc707122SEaswaran Raman     DEBUG({
207*dc707122SEaswaran Raman       dbgs() << "Counter in file " << InferredFileID << " " << LineStart << ":"
208*dc707122SEaswaran Raman              << ColumnStart << " -> " << (LineStart + NumLines) << ":"
209*dc707122SEaswaran Raman              << ColumnEnd << ", ";
210*dc707122SEaswaran Raman       if (Kind == CounterMappingRegion::ExpansionRegion)
211*dc707122SEaswaran Raman         dbgs() << "Expands to file " << ExpandedFileID;
212*dc707122SEaswaran Raman       else
213*dc707122SEaswaran Raman         CounterMappingContext(Expressions).dump(C, dbgs());
214*dc707122SEaswaran Raman       dbgs() << "\n";
215*dc707122SEaswaran Raman     });
216*dc707122SEaswaran Raman 
217*dc707122SEaswaran Raman     MappingRegions.push_back(CounterMappingRegion(
218*dc707122SEaswaran Raman         C, InferredFileID, ExpandedFileID, LineStart, ColumnStart,
219*dc707122SEaswaran Raman         LineStart + NumLines, ColumnEnd, Kind));
220*dc707122SEaswaran Raman   }
221*dc707122SEaswaran Raman   return std::error_code();
222*dc707122SEaswaran Raman }
223*dc707122SEaswaran Raman 
224*dc707122SEaswaran Raman std::error_code RawCoverageMappingReader::read() {
225*dc707122SEaswaran Raman 
226*dc707122SEaswaran Raman   // Read the virtual file mapping.
227*dc707122SEaswaran Raman   llvm::SmallVector<unsigned, 8> VirtualFileMapping;
228*dc707122SEaswaran Raman   uint64_t NumFileMappings;
229*dc707122SEaswaran Raman   if (auto Err = readSize(NumFileMappings))
230*dc707122SEaswaran Raman     return Err;
231*dc707122SEaswaran Raman   for (size_t I = 0; I < NumFileMappings; ++I) {
232*dc707122SEaswaran Raman     uint64_t FilenameIndex;
233*dc707122SEaswaran Raman     if (auto Err = readIntMax(FilenameIndex, TranslationUnitFilenames.size()))
234*dc707122SEaswaran Raman       return Err;
235*dc707122SEaswaran Raman     VirtualFileMapping.push_back(FilenameIndex);
236*dc707122SEaswaran Raman   }
237*dc707122SEaswaran Raman 
238*dc707122SEaswaran Raman   // Construct the files using unique filenames and virtual file mapping.
239*dc707122SEaswaran Raman   for (auto I : VirtualFileMapping) {
240*dc707122SEaswaran Raman     Filenames.push_back(TranslationUnitFilenames[I]);
241*dc707122SEaswaran Raman   }
242*dc707122SEaswaran Raman 
243*dc707122SEaswaran Raman   // Read the expressions.
244*dc707122SEaswaran Raman   uint64_t NumExpressions;
245*dc707122SEaswaran Raman   if (auto Err = readSize(NumExpressions))
246*dc707122SEaswaran Raman     return Err;
247*dc707122SEaswaran Raman   // Create an array of dummy expressions that get the proper counters
248*dc707122SEaswaran Raman   // when the expressions are read, and the proper kinds when the counters
249*dc707122SEaswaran Raman   // are decoded.
250*dc707122SEaswaran Raman   Expressions.resize(
251*dc707122SEaswaran Raman       NumExpressions,
252*dc707122SEaswaran Raman       CounterExpression(CounterExpression::Subtract, Counter(), Counter()));
253*dc707122SEaswaran Raman   for (size_t I = 0; I < NumExpressions; ++I) {
254*dc707122SEaswaran Raman     if (auto Err = readCounter(Expressions[I].LHS))
255*dc707122SEaswaran Raman       return Err;
256*dc707122SEaswaran Raman     if (auto Err = readCounter(Expressions[I].RHS))
257*dc707122SEaswaran Raman       return Err;
258*dc707122SEaswaran Raman   }
259*dc707122SEaswaran Raman 
260*dc707122SEaswaran Raman   // Read the mapping regions sub-arrays.
261*dc707122SEaswaran Raman   for (unsigned InferredFileID = 0, S = VirtualFileMapping.size();
262*dc707122SEaswaran Raman        InferredFileID < S; ++InferredFileID) {
263*dc707122SEaswaran Raman     if (auto Err = readMappingRegionsSubArray(MappingRegions, InferredFileID,
264*dc707122SEaswaran Raman                                               VirtualFileMapping.size()))
265*dc707122SEaswaran Raman       return Err;
266*dc707122SEaswaran Raman   }
267*dc707122SEaswaran Raman 
268*dc707122SEaswaran Raman   // Set the counters for the expansion regions.
269*dc707122SEaswaran Raman   // i.e. Counter of expansion region = counter of the first region
270*dc707122SEaswaran Raman   // from the expanded file.
271*dc707122SEaswaran Raman   // Perform multiple passes to correctly propagate the counters through
272*dc707122SEaswaran Raman   // all the nested expansion regions.
273*dc707122SEaswaran Raman   SmallVector<CounterMappingRegion *, 8> FileIDExpansionRegionMapping;
274*dc707122SEaswaran Raman   FileIDExpansionRegionMapping.resize(VirtualFileMapping.size(), nullptr);
275*dc707122SEaswaran Raman   for (unsigned Pass = 1, S = VirtualFileMapping.size(); Pass < S; ++Pass) {
276*dc707122SEaswaran Raman     for (auto &R : MappingRegions) {
277*dc707122SEaswaran Raman       if (R.Kind != CounterMappingRegion::ExpansionRegion)
278*dc707122SEaswaran Raman         continue;
279*dc707122SEaswaran Raman       assert(!FileIDExpansionRegionMapping[R.ExpandedFileID]);
280*dc707122SEaswaran Raman       FileIDExpansionRegionMapping[R.ExpandedFileID] = &R;
281*dc707122SEaswaran Raman     }
282*dc707122SEaswaran Raman     for (auto &R : MappingRegions) {
283*dc707122SEaswaran Raman       if (FileIDExpansionRegionMapping[R.FileID]) {
284*dc707122SEaswaran Raman         FileIDExpansionRegionMapping[R.FileID]->Count = R.Count;
285*dc707122SEaswaran Raman         FileIDExpansionRegionMapping[R.FileID] = nullptr;
286*dc707122SEaswaran Raman       }
287*dc707122SEaswaran Raman     }
288*dc707122SEaswaran Raman   }
289*dc707122SEaswaran Raman 
290*dc707122SEaswaran Raman   return std::error_code();
291*dc707122SEaswaran Raman }
292*dc707122SEaswaran Raman 
293*dc707122SEaswaran Raman std::error_code InstrProfSymtab::create(SectionRef &Section) {
294*dc707122SEaswaran Raman   if (auto Err = Section.getContents(Data))
295*dc707122SEaswaran Raman     return Err;
296*dc707122SEaswaran Raman   Address = Section.getAddress();
297*dc707122SEaswaran Raman   return std::error_code();
298*dc707122SEaswaran Raman }
299*dc707122SEaswaran Raman 
300*dc707122SEaswaran Raman StringRef InstrProfSymtab::getFuncName(uint64_t Pointer, size_t Size) {
301*dc707122SEaswaran Raman   if (Pointer < Address)
302*dc707122SEaswaran Raman     return StringRef();
303*dc707122SEaswaran Raman   auto Offset = Pointer - Address;
304*dc707122SEaswaran Raman   if (Offset + Size > Data.size())
305*dc707122SEaswaran Raman     return StringRef();
306*dc707122SEaswaran Raman   return Data.substr(Pointer - Address, Size);
307*dc707122SEaswaran Raman }
308*dc707122SEaswaran Raman 
309*dc707122SEaswaran Raman namespace {
310*dc707122SEaswaran Raman struct CovMapFuncRecordReader {
311*dc707122SEaswaran Raman   // The interface to read coverage mapping function records for
312*dc707122SEaswaran Raman   // a module. \p Buf is a reference to the buffer pointer pointing
313*dc707122SEaswaran Raman   // to the \c CovHeader of coverage mapping data associated with
314*dc707122SEaswaran Raman   // the module.
315*dc707122SEaswaran Raman   virtual std::error_code readFunctionRecords(const char *&Buf,
316*dc707122SEaswaran Raman                                               const char *End) = 0;
317*dc707122SEaswaran Raman   virtual ~CovMapFuncRecordReader() {}
318*dc707122SEaswaran Raman   template <class IntPtrT, support::endianness Endian>
319*dc707122SEaswaran Raman   static std::unique_ptr<CovMapFuncRecordReader>
320*dc707122SEaswaran Raman   get(coverage::CovMapVersion Version, InstrProfSymtab &P,
321*dc707122SEaswaran Raman       std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
322*dc707122SEaswaran Raman       std::vector<StringRef> &F);
323*dc707122SEaswaran Raman };
324*dc707122SEaswaran Raman 
325*dc707122SEaswaran Raman // A class for reading coverage mapping function records for a module.
326*dc707122SEaswaran Raman template <coverage::CovMapVersion Version, class IntPtrT,
327*dc707122SEaswaran Raman           support::endianness Endian>
328*dc707122SEaswaran Raman class VersionedCovMapFuncRecordReader : public CovMapFuncRecordReader {
329*dc707122SEaswaran Raman   typedef typename coverage::CovMapTraits<
330*dc707122SEaswaran Raman       Version, IntPtrT>::CovMapFuncRecordType FuncRecordType;
331*dc707122SEaswaran Raman   typedef typename coverage::CovMapTraits<Version, IntPtrT>::NameRefType
332*dc707122SEaswaran Raman       NameRefType;
333*dc707122SEaswaran Raman 
334*dc707122SEaswaran Raman   llvm::DenseSet<NameRefType> UniqueFunctionMappingData;
335*dc707122SEaswaran Raman   InstrProfSymtab &ProfileNames;
336*dc707122SEaswaran Raman   std::vector<StringRef> &Filenames;
337*dc707122SEaswaran Raman   std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records;
338*dc707122SEaswaran Raman 
339*dc707122SEaswaran Raman public:
340*dc707122SEaswaran Raman   VersionedCovMapFuncRecordReader(
341*dc707122SEaswaran Raman       InstrProfSymtab &P,
342*dc707122SEaswaran Raman       std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
343*dc707122SEaswaran Raman       std::vector<StringRef> &F)
344*dc707122SEaswaran Raman       : ProfileNames(P), Filenames(F), Records(R) {}
345*dc707122SEaswaran Raman   ~VersionedCovMapFuncRecordReader() override {}
346*dc707122SEaswaran Raman 
347*dc707122SEaswaran Raman   std::error_code readFunctionRecords(const char *&Buf,
348*dc707122SEaswaran Raman                                       const char *End) override {
349*dc707122SEaswaran Raman     using namespace support;
350*dc707122SEaswaran Raman     if (Buf + sizeof(CovMapHeader) > End)
351*dc707122SEaswaran Raman       return coveragemap_error::malformed;
352*dc707122SEaswaran Raman     auto CovHeader = reinterpret_cast<const coverage::CovMapHeader *>(Buf);
353*dc707122SEaswaran Raman     uint32_t NRecords = CovHeader->getNRecords<Endian>();
354*dc707122SEaswaran Raman     uint32_t FilenamesSize = CovHeader->getFilenamesSize<Endian>();
355*dc707122SEaswaran Raman     uint32_t CoverageSize = CovHeader->getCoverageSize<Endian>();
356*dc707122SEaswaran Raman     assert((CovMapVersion)CovHeader->getVersion<Endian>() == Version);
357*dc707122SEaswaran Raman     Buf = reinterpret_cast<const char *>(CovHeader + 1);
358*dc707122SEaswaran Raman 
359*dc707122SEaswaran Raman     // Skip past the function records, saving the start and end for later.
360*dc707122SEaswaran Raman     const char *FunBuf = Buf;
361*dc707122SEaswaran Raman     Buf += NRecords * sizeof(FuncRecordType);
362*dc707122SEaswaran Raman     const char *FunEnd = Buf;
363*dc707122SEaswaran Raman 
364*dc707122SEaswaran Raman     // Get the filenames.
365*dc707122SEaswaran Raman     if (Buf + FilenamesSize > End)
366*dc707122SEaswaran Raman       return coveragemap_error::malformed;
367*dc707122SEaswaran Raman     size_t FilenamesBegin = Filenames.size();
368*dc707122SEaswaran Raman     RawCoverageFilenamesReader Reader(StringRef(Buf, FilenamesSize), Filenames);
369*dc707122SEaswaran Raman     if (auto Err = Reader.read())
370*dc707122SEaswaran Raman       return Err;
371*dc707122SEaswaran Raman     Buf += FilenamesSize;
372*dc707122SEaswaran Raman 
373*dc707122SEaswaran Raman     // We'll read the coverage mapping records in the loop below.
374*dc707122SEaswaran Raman     const char *CovBuf = Buf;
375*dc707122SEaswaran Raman     Buf += CoverageSize;
376*dc707122SEaswaran Raman     const char *CovEnd = Buf;
377*dc707122SEaswaran Raman 
378*dc707122SEaswaran Raman     if (Buf > End)
379*dc707122SEaswaran Raman       return coveragemap_error::malformed;
380*dc707122SEaswaran Raman     // Each coverage map has an alignment of 8, so we need to adjust alignment
381*dc707122SEaswaran Raman     // before reading the next map.
382*dc707122SEaswaran Raman     Buf += alignmentAdjustment(Buf, 8);
383*dc707122SEaswaran Raman 
384*dc707122SEaswaran Raman     auto CFR = reinterpret_cast<const FuncRecordType *>(FunBuf);
385*dc707122SEaswaran Raman     while ((const char *)CFR < FunEnd) {
386*dc707122SEaswaran Raman       // Read the function information
387*dc707122SEaswaran Raman       uint32_t DataSize = CFR->template getDataSize<Endian>();
388*dc707122SEaswaran Raman       uint64_t FuncHash = CFR->template getFuncHash<Endian>();
389*dc707122SEaswaran Raman 
390*dc707122SEaswaran Raman       // Now use that to read the coverage data.
391*dc707122SEaswaran Raman       if (CovBuf + DataSize > CovEnd)
392*dc707122SEaswaran Raman         return coveragemap_error::malformed;
393*dc707122SEaswaran Raman       auto Mapping = StringRef(CovBuf, DataSize);
394*dc707122SEaswaran Raman       CovBuf += DataSize;
395*dc707122SEaswaran Raman 
396*dc707122SEaswaran Raman       // Ignore this record if we already have a record that points to the same
397*dc707122SEaswaran Raman       // function name. This is useful to ignore the redundant records for the
398*dc707122SEaswaran Raman       // functions with ODR linkage.
399*dc707122SEaswaran Raman       NameRefType NameRef = CFR->template getFuncNameRef<Endian>();
400*dc707122SEaswaran Raman       if (!UniqueFunctionMappingData.insert(NameRef).second) {
401*dc707122SEaswaran Raman         CFR++;
402*dc707122SEaswaran Raman         continue;
403*dc707122SEaswaran Raman       }
404*dc707122SEaswaran Raman 
405*dc707122SEaswaran Raman       StringRef FuncName;
406*dc707122SEaswaran Raman       if (std::error_code EC =
407*dc707122SEaswaran Raman               CFR->template getFuncName<Endian>(ProfileNames, FuncName))
408*dc707122SEaswaran Raman         return EC;
409*dc707122SEaswaran Raman       Records.push_back(BinaryCoverageReader::ProfileMappingRecord(
410*dc707122SEaswaran Raman           Version, FuncName, FuncHash, Mapping, FilenamesBegin,
411*dc707122SEaswaran Raman           Filenames.size() - FilenamesBegin));
412*dc707122SEaswaran Raman       CFR++;
413*dc707122SEaswaran Raman     }
414*dc707122SEaswaran Raman     return std::error_code();
415*dc707122SEaswaran Raman   }
416*dc707122SEaswaran Raman };
417*dc707122SEaswaran Raman } // end anonymous namespace
418*dc707122SEaswaran Raman 
419*dc707122SEaswaran Raman template <class IntPtrT, support::endianness Endian>
420*dc707122SEaswaran Raman std::unique_ptr<CovMapFuncRecordReader> CovMapFuncRecordReader::get(
421*dc707122SEaswaran Raman     coverage::CovMapVersion Version, InstrProfSymtab &P,
422*dc707122SEaswaran Raman     std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
423*dc707122SEaswaran Raman     std::vector<StringRef> &F) {
424*dc707122SEaswaran Raman   using namespace coverage;
425*dc707122SEaswaran Raman   switch (Version) {
426*dc707122SEaswaran Raman   case CovMapVersion::Version1:
427*dc707122SEaswaran Raman     return llvm::make_unique<VersionedCovMapFuncRecordReader<
428*dc707122SEaswaran Raman         CovMapVersion::Version1, IntPtrT, Endian>>(P, R, F);
429*dc707122SEaswaran Raman   case CovMapVersion::Version2:
430*dc707122SEaswaran Raman     // Decompress the name data.
431*dc707122SEaswaran Raman     P.create(P.getNameData());
432*dc707122SEaswaran Raman     return llvm::make_unique<VersionedCovMapFuncRecordReader<
433*dc707122SEaswaran Raman         CovMapVersion::Version2, IntPtrT, Endian>>(P, R, F);
434*dc707122SEaswaran Raman   }
435*dc707122SEaswaran Raman   llvm_unreachable("Unsupported version");
436*dc707122SEaswaran Raman }
437*dc707122SEaswaran Raman 
438*dc707122SEaswaran Raman template <typename T, support::endianness Endian>
439*dc707122SEaswaran Raman static std::error_code readCoverageMappingData(
440*dc707122SEaswaran Raman     InstrProfSymtab &ProfileNames, StringRef Data,
441*dc707122SEaswaran Raman     std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
442*dc707122SEaswaran Raman     std::vector<StringRef> &Filenames) {
443*dc707122SEaswaran Raman   using namespace coverage;
444*dc707122SEaswaran Raman   // Read the records in the coverage data section.
445*dc707122SEaswaran Raman   auto CovHeader =
446*dc707122SEaswaran Raman       reinterpret_cast<const coverage::CovMapHeader *>(Data.data());
447*dc707122SEaswaran Raman   CovMapVersion Version = (CovMapVersion)CovHeader->getVersion<Endian>();
448*dc707122SEaswaran Raman   if (Version > coverage::CovMapVersion::CurrentVersion)
449*dc707122SEaswaran Raman     return coveragemap_error::unsupported_version;
450*dc707122SEaswaran Raman   std::unique_ptr<CovMapFuncRecordReader> Reader =
451*dc707122SEaswaran Raman       CovMapFuncRecordReader::get<T, Endian>(Version, ProfileNames, Records,
452*dc707122SEaswaran Raman                                              Filenames);
453*dc707122SEaswaran Raman   for (const char *Buf = Data.data(), *End = Buf + Data.size(); Buf < End;) {
454*dc707122SEaswaran Raman     if (std::error_code EC = Reader->readFunctionRecords(Buf, End))
455*dc707122SEaswaran Raman       return EC;
456*dc707122SEaswaran Raman   }
457*dc707122SEaswaran Raman   return std::error_code();
458*dc707122SEaswaran Raman }
459*dc707122SEaswaran Raman static const char *TestingFormatMagic = "llvmcovmtestdata";
460*dc707122SEaswaran Raman 
461*dc707122SEaswaran Raman static std::error_code loadTestingFormat(StringRef Data,
462*dc707122SEaswaran Raman                                          InstrProfSymtab &ProfileNames,
463*dc707122SEaswaran Raman                                          StringRef &CoverageMapping,
464*dc707122SEaswaran Raman                                          uint8_t &BytesInAddress,
465*dc707122SEaswaran Raman                                          support::endianness &Endian) {
466*dc707122SEaswaran Raman   BytesInAddress = 8;
467*dc707122SEaswaran Raman   Endian = support::endianness::little;
468*dc707122SEaswaran Raman 
469*dc707122SEaswaran Raman   Data = Data.substr(StringRef(TestingFormatMagic).size());
470*dc707122SEaswaran Raman   if (Data.size() < 1)
471*dc707122SEaswaran Raman     return coveragemap_error::truncated;
472*dc707122SEaswaran Raman   unsigned N = 0;
473*dc707122SEaswaran Raman   auto ProfileNamesSize =
474*dc707122SEaswaran Raman       decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
475*dc707122SEaswaran Raman   if (N > Data.size())
476*dc707122SEaswaran Raman     return coveragemap_error::malformed;
477*dc707122SEaswaran Raman   Data = Data.substr(N);
478*dc707122SEaswaran Raman   if (Data.size() < 1)
479*dc707122SEaswaran Raman     return coveragemap_error::truncated;
480*dc707122SEaswaran Raman   N = 0;
481*dc707122SEaswaran Raman   uint64_t Address =
482*dc707122SEaswaran Raman       decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
483*dc707122SEaswaran Raman   if (N > Data.size())
484*dc707122SEaswaran Raman     return coveragemap_error::malformed;
485*dc707122SEaswaran Raman   Data = Data.substr(N);
486*dc707122SEaswaran Raman   if (Data.size() < ProfileNamesSize)
487*dc707122SEaswaran Raman     return coveragemap_error::malformed;
488*dc707122SEaswaran Raman   ProfileNames.create(Data.substr(0, ProfileNamesSize), Address);
489*dc707122SEaswaran Raman   CoverageMapping = Data.substr(ProfileNamesSize);
490*dc707122SEaswaran Raman   return std::error_code();
491*dc707122SEaswaran Raman }
492*dc707122SEaswaran Raman 
493*dc707122SEaswaran Raman static ErrorOr<SectionRef> lookupSection(ObjectFile &OF, StringRef Name) {
494*dc707122SEaswaran Raman   StringRef FoundName;
495*dc707122SEaswaran Raman   for (const auto &Section : OF.sections()) {
496*dc707122SEaswaran Raman     if (auto EC = Section.getName(FoundName))
497*dc707122SEaswaran Raman       return EC;
498*dc707122SEaswaran Raman     if (FoundName == Name)
499*dc707122SEaswaran Raman       return Section;
500*dc707122SEaswaran Raman   }
501*dc707122SEaswaran Raman   return coveragemap_error::no_data_found;
502*dc707122SEaswaran Raman }
503*dc707122SEaswaran Raman 
504*dc707122SEaswaran Raman static std::error_code
505*dc707122SEaswaran Raman loadBinaryFormat(MemoryBufferRef ObjectBuffer, InstrProfSymtab &ProfileNames,
506*dc707122SEaswaran Raman                  StringRef &CoverageMapping, uint8_t &BytesInAddress,
507*dc707122SEaswaran Raman                  support::endianness &Endian, StringRef Arch) {
508*dc707122SEaswaran Raman   auto BinOrErr = object::createBinary(ObjectBuffer);
509*dc707122SEaswaran Raman   if (!BinOrErr)
510*dc707122SEaswaran Raman     return errorToErrorCode(BinOrErr.takeError());
511*dc707122SEaswaran Raman   auto Bin = std::move(BinOrErr.get());
512*dc707122SEaswaran Raman   std::unique_ptr<ObjectFile> OF;
513*dc707122SEaswaran Raman   if (auto *Universal = dyn_cast<object::MachOUniversalBinary>(Bin.get())) {
514*dc707122SEaswaran Raman     // If we have a universal binary, try to look up the object for the
515*dc707122SEaswaran Raman     // appropriate architecture.
516*dc707122SEaswaran Raman     auto ObjectFileOrErr = Universal->getObjectForArch(Arch);
517*dc707122SEaswaran Raman     if (std::error_code EC = ObjectFileOrErr.getError())
518*dc707122SEaswaran Raman       return EC;
519*dc707122SEaswaran Raman     OF = std::move(ObjectFileOrErr.get());
520*dc707122SEaswaran Raman   } else if (isa<object::ObjectFile>(Bin.get())) {
521*dc707122SEaswaran Raman     // For any other object file, upcast and take ownership.
522*dc707122SEaswaran Raman     OF.reset(cast<object::ObjectFile>(Bin.release()));
523*dc707122SEaswaran Raman     // If we've asked for a particular arch, make sure they match.
524*dc707122SEaswaran Raman     if (!Arch.empty() && OF->getArch() != Triple(Arch).getArch())
525*dc707122SEaswaran Raman       return object_error::arch_not_found;
526*dc707122SEaswaran Raman   } else
527*dc707122SEaswaran Raman     // We can only handle object files.
528*dc707122SEaswaran Raman     return coveragemap_error::malformed;
529*dc707122SEaswaran Raman 
530*dc707122SEaswaran Raman   // The coverage uses native pointer sizes for the object it's written in.
531*dc707122SEaswaran Raman   BytesInAddress = OF->getBytesInAddress();
532*dc707122SEaswaran Raman   Endian = OF->isLittleEndian() ? support::endianness::little
533*dc707122SEaswaran Raman                                 : support::endianness::big;
534*dc707122SEaswaran Raman 
535*dc707122SEaswaran Raman   // Look for the sections that we are interested in.
536*dc707122SEaswaran Raman   auto NamesSection = lookupSection(*OF, getInstrProfNameSectionName(false));
537*dc707122SEaswaran Raman   if (auto EC = NamesSection.getError())
538*dc707122SEaswaran Raman     return EC;
539*dc707122SEaswaran Raman   auto CoverageSection =
540*dc707122SEaswaran Raman       lookupSection(*OF, getInstrProfCoverageSectionName(false));
541*dc707122SEaswaran Raman   if (auto EC = CoverageSection.getError())
542*dc707122SEaswaran Raman     return EC;
543*dc707122SEaswaran Raman 
544*dc707122SEaswaran Raman   // Get the contents of the given sections.
545*dc707122SEaswaran Raman   if (std::error_code EC = CoverageSection->getContents(CoverageMapping))
546*dc707122SEaswaran Raman     return EC;
547*dc707122SEaswaran Raman   if (std::error_code EC = ProfileNames.create(*NamesSection))
548*dc707122SEaswaran Raman     return EC;
549*dc707122SEaswaran Raman 
550*dc707122SEaswaran Raman   return std::error_code();
551*dc707122SEaswaran Raman }
552*dc707122SEaswaran Raman 
553*dc707122SEaswaran Raman ErrorOr<std::unique_ptr<BinaryCoverageReader>>
554*dc707122SEaswaran Raman BinaryCoverageReader::create(std::unique_ptr<MemoryBuffer> &ObjectBuffer,
555*dc707122SEaswaran Raman                              StringRef Arch) {
556*dc707122SEaswaran Raman   std::unique_ptr<BinaryCoverageReader> Reader(new BinaryCoverageReader());
557*dc707122SEaswaran Raman 
558*dc707122SEaswaran Raman   StringRef Coverage;
559*dc707122SEaswaran Raman   uint8_t BytesInAddress;
560*dc707122SEaswaran Raman   support::endianness Endian;
561*dc707122SEaswaran Raman   std::error_code EC;
562*dc707122SEaswaran Raman   if (ObjectBuffer->getBuffer().startswith(TestingFormatMagic))
563*dc707122SEaswaran Raman     // This is a special format used for testing.
564*dc707122SEaswaran Raman     EC = loadTestingFormat(ObjectBuffer->getBuffer(), Reader->ProfileNames,
565*dc707122SEaswaran Raman                            Coverage, BytesInAddress, Endian);
566*dc707122SEaswaran Raman   else
567*dc707122SEaswaran Raman     EC = loadBinaryFormat(ObjectBuffer->getMemBufferRef(), Reader->ProfileNames,
568*dc707122SEaswaran Raman                           Coverage, BytesInAddress, Endian, Arch);
569*dc707122SEaswaran Raman   if (EC)
570*dc707122SEaswaran Raman     return EC;
571*dc707122SEaswaran Raman 
572*dc707122SEaswaran Raman   if (BytesInAddress == 4 && Endian == support::endianness::little)
573*dc707122SEaswaran Raman     EC = readCoverageMappingData<uint32_t, support::endianness::little>(
574*dc707122SEaswaran Raman         Reader->ProfileNames, Coverage, Reader->MappingRecords,
575*dc707122SEaswaran Raman         Reader->Filenames);
576*dc707122SEaswaran Raman   else if (BytesInAddress == 4 && Endian == support::endianness::big)
577*dc707122SEaswaran Raman     EC = readCoverageMappingData<uint32_t, support::endianness::big>(
578*dc707122SEaswaran Raman         Reader->ProfileNames, Coverage, Reader->MappingRecords,
579*dc707122SEaswaran Raman         Reader->Filenames);
580*dc707122SEaswaran Raman   else if (BytesInAddress == 8 && Endian == support::endianness::little)
581*dc707122SEaswaran Raman     EC = readCoverageMappingData<uint64_t, support::endianness::little>(
582*dc707122SEaswaran Raman         Reader->ProfileNames, Coverage, Reader->MappingRecords,
583*dc707122SEaswaran Raman         Reader->Filenames);
584*dc707122SEaswaran Raman   else if (BytesInAddress == 8 && Endian == support::endianness::big)
585*dc707122SEaswaran Raman     EC = readCoverageMappingData<uint64_t, support::endianness::big>(
586*dc707122SEaswaran Raman         Reader->ProfileNames, Coverage, Reader->MappingRecords,
587*dc707122SEaswaran Raman         Reader->Filenames);
588*dc707122SEaswaran Raman   else
589*dc707122SEaswaran Raman     return coveragemap_error::malformed;
590*dc707122SEaswaran Raman   if (EC)
591*dc707122SEaswaran Raman     return EC;
592*dc707122SEaswaran Raman   return std::move(Reader);
593*dc707122SEaswaran Raman }
594*dc707122SEaswaran Raman 
595*dc707122SEaswaran Raman std::error_code
596*dc707122SEaswaran Raman BinaryCoverageReader::readNextRecord(CoverageMappingRecord &Record) {
597*dc707122SEaswaran Raman   if (CurrentRecord >= MappingRecords.size())
598*dc707122SEaswaran Raman     return coveragemap_error::eof;
599*dc707122SEaswaran Raman 
600*dc707122SEaswaran Raman   FunctionsFilenames.clear();
601*dc707122SEaswaran Raman   Expressions.clear();
602*dc707122SEaswaran Raman   MappingRegions.clear();
603*dc707122SEaswaran Raman   auto &R = MappingRecords[CurrentRecord];
604*dc707122SEaswaran Raman   RawCoverageMappingReader Reader(
605*dc707122SEaswaran Raman       R.CoverageMapping,
606*dc707122SEaswaran Raman       makeArrayRef(Filenames).slice(R.FilenamesBegin, R.FilenamesSize),
607*dc707122SEaswaran Raman       FunctionsFilenames, Expressions, MappingRegions);
608*dc707122SEaswaran Raman   if (auto Err = Reader.read())
609*dc707122SEaswaran Raman     return Err;
610*dc707122SEaswaran Raman 
611*dc707122SEaswaran Raman   Record.FunctionName = R.FunctionName;
612*dc707122SEaswaran Raman   Record.FunctionHash = R.FunctionHash;
613*dc707122SEaswaran Raman   Record.Filenames = FunctionsFilenames;
614*dc707122SEaswaran Raman   Record.Expressions = Expressions;
615*dc707122SEaswaran Raman   Record.MappingRegions = MappingRegions;
616*dc707122SEaswaran Raman 
617*dc707122SEaswaran Raman   ++CurrentRecord;
618*dc707122SEaswaran Raman   return std::error_code();
619*dc707122SEaswaran Raman }
620