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