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