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