Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
35271 views
1
//===- CoverageMappingReader.cpp - Code coverage mapping reader -----------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file contains support for reading coverage mapping data for
10
// instrumentation based coverage.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "llvm/ProfileData/Coverage/CoverageMappingReader.h"
15
#include "llvm/ADT/ArrayRef.h"
16
#include "llvm/ADT/DenseMap.h"
17
#include "llvm/ADT/STLExtras.h"
18
#include "llvm/ADT/SmallVector.h"
19
#include "llvm/ADT/Statistic.h"
20
#include "llvm/ADT/StringRef.h"
21
#include "llvm/Object/Archive.h"
22
#include "llvm/Object/Binary.h"
23
#include "llvm/Object/COFF.h"
24
#include "llvm/Object/Error.h"
25
#include "llvm/Object/MachOUniversal.h"
26
#include "llvm/Object/ObjectFile.h"
27
#include "llvm/ProfileData/InstrProf.h"
28
#include "llvm/Support/Casting.h"
29
#include "llvm/Support/Compression.h"
30
#include "llvm/Support/Debug.h"
31
#include "llvm/Support/Endian.h"
32
#include "llvm/Support/Error.h"
33
#include "llvm/Support/ErrorHandling.h"
34
#include "llvm/Support/LEB128.h"
35
#include "llvm/Support/MathExtras.h"
36
#include "llvm/Support/Path.h"
37
#include "llvm/Support/raw_ostream.h"
38
#include "llvm/TargetParser/Triple.h"
39
#include <vector>
40
41
using namespace llvm;
42
using namespace coverage;
43
using namespace object;
44
45
#define DEBUG_TYPE "coverage-mapping"
46
47
STATISTIC(CovMapNumRecords, "The # of coverage function records");
48
STATISTIC(CovMapNumUsedRecords, "The # of used coverage function records");
49
50
void CoverageMappingIterator::increment() {
51
if (ReadErr != coveragemap_error::success)
52
return;
53
54
// Check if all the records were read or if an error occurred while reading
55
// the next record.
56
if (auto E = Reader->readNextRecord(Record))
57
handleAllErrors(std::move(E), [&](const CoverageMapError &CME) {
58
if (CME.get() == coveragemap_error::eof)
59
*this = CoverageMappingIterator();
60
else
61
ReadErr = CME.get();
62
});
63
}
64
65
Error RawCoverageReader::readULEB128(uint64_t &Result) {
66
if (Data.empty())
67
return make_error<CoverageMapError>(coveragemap_error::truncated);
68
unsigned N = 0;
69
Result = decodeULEB128(Data.bytes_begin(), &N);
70
if (N > Data.size())
71
return make_error<CoverageMapError>(coveragemap_error::malformed,
72
"the size of ULEB128 is too big");
73
Data = Data.substr(N);
74
return Error::success();
75
}
76
77
Error RawCoverageReader::readIntMax(uint64_t &Result, uint64_t MaxPlus1) {
78
if (auto Err = readULEB128(Result))
79
return Err;
80
if (Result >= MaxPlus1)
81
return make_error<CoverageMapError>(
82
coveragemap_error::malformed,
83
"the value of ULEB128 is greater than or equal to MaxPlus1");
84
return Error::success();
85
}
86
87
Error RawCoverageReader::readSize(uint64_t &Result) {
88
if (auto Err = readULEB128(Result))
89
return Err;
90
if (Result > Data.size())
91
return make_error<CoverageMapError>(coveragemap_error::malformed,
92
"the value of ULEB128 is too big");
93
return Error::success();
94
}
95
96
Error RawCoverageReader::readString(StringRef &Result) {
97
uint64_t Length;
98
if (auto Err = readSize(Length))
99
return Err;
100
Result = Data.substr(0, Length);
101
Data = Data.substr(Length);
102
return Error::success();
103
}
104
105
Error RawCoverageFilenamesReader::read(CovMapVersion Version) {
106
uint64_t NumFilenames;
107
if (auto Err = readSize(NumFilenames))
108
return Err;
109
if (!NumFilenames)
110
return make_error<CoverageMapError>(coveragemap_error::malformed,
111
"number of filenames is zero");
112
113
if (Version < CovMapVersion::Version4)
114
return readUncompressed(Version, NumFilenames);
115
116
// The uncompressed length may exceed the size of the encoded filenames.
117
// Skip size validation.
118
uint64_t UncompressedLen;
119
if (auto Err = readULEB128(UncompressedLen))
120
return Err;
121
122
uint64_t CompressedLen;
123
if (auto Err = readSize(CompressedLen))
124
return Err;
125
126
if (CompressedLen > 0) {
127
if (!compression::zlib::isAvailable())
128
return make_error<CoverageMapError>(
129
coveragemap_error::decompression_failed);
130
131
// Allocate memory for the decompressed filenames.
132
SmallVector<uint8_t, 0> StorageBuf;
133
134
// Read compressed filenames.
135
StringRef CompressedFilenames = Data.substr(0, CompressedLen);
136
Data = Data.substr(CompressedLen);
137
auto Err = compression::zlib::decompress(
138
arrayRefFromStringRef(CompressedFilenames), StorageBuf,
139
UncompressedLen);
140
if (Err) {
141
consumeError(std::move(Err));
142
return make_error<CoverageMapError>(
143
coveragemap_error::decompression_failed);
144
}
145
146
RawCoverageFilenamesReader Delegate(toStringRef(StorageBuf), Filenames,
147
CompilationDir);
148
return Delegate.readUncompressed(Version, NumFilenames);
149
}
150
151
return readUncompressed(Version, NumFilenames);
152
}
153
154
Error RawCoverageFilenamesReader::readUncompressed(CovMapVersion Version,
155
uint64_t NumFilenames) {
156
// Read uncompressed filenames.
157
if (Version < CovMapVersion::Version6) {
158
for (size_t I = 0; I < NumFilenames; ++I) {
159
StringRef Filename;
160
if (auto Err = readString(Filename))
161
return Err;
162
Filenames.push_back(Filename.str());
163
}
164
} else {
165
StringRef CWD;
166
if (auto Err = readString(CWD))
167
return Err;
168
Filenames.push_back(CWD.str());
169
170
for (size_t I = 1; I < NumFilenames; ++I) {
171
StringRef Filename;
172
if (auto Err = readString(Filename))
173
return Err;
174
if (sys::path::is_absolute(Filename)) {
175
Filenames.push_back(Filename.str());
176
} else {
177
SmallString<256> P;
178
if (!CompilationDir.empty())
179
P.assign(CompilationDir);
180
else
181
P.assign(CWD);
182
llvm::sys::path::append(P, Filename);
183
sys::path::remove_dots(P, /*remove_dot_dot=*/true);
184
Filenames.push_back(static_cast<std::string>(P.str()));
185
}
186
}
187
}
188
return Error::success();
189
}
190
191
Error RawCoverageMappingReader::decodeCounter(unsigned Value, Counter &C) {
192
auto Tag = Value & Counter::EncodingTagMask;
193
switch (Tag) {
194
case Counter::Zero:
195
C = Counter::getZero();
196
return Error::success();
197
case Counter::CounterValueReference:
198
C = Counter::getCounter(Value >> Counter::EncodingTagBits);
199
return Error::success();
200
default:
201
break;
202
}
203
Tag -= Counter::Expression;
204
switch (Tag) {
205
case CounterExpression::Subtract:
206
case CounterExpression::Add: {
207
auto ID = Value >> Counter::EncodingTagBits;
208
if (ID >= Expressions.size())
209
return make_error<CoverageMapError>(coveragemap_error::malformed,
210
"counter expression is invalid");
211
Expressions[ID].Kind = CounterExpression::ExprKind(Tag);
212
C = Counter::getExpression(ID);
213
break;
214
}
215
default:
216
return make_error<CoverageMapError>(coveragemap_error::malformed,
217
"counter expression kind is invalid");
218
}
219
return Error::success();
220
}
221
222
Error RawCoverageMappingReader::readCounter(Counter &C) {
223
uint64_t EncodedCounter;
224
if (auto Err =
225
readIntMax(EncodedCounter, std::numeric_limits<unsigned>::max()))
226
return Err;
227
if (auto Err = decodeCounter(EncodedCounter, C))
228
return Err;
229
return Error::success();
230
}
231
232
static const unsigned EncodingExpansionRegionBit = 1
233
<< Counter::EncodingTagBits;
234
235
/// Read the sub-array of regions for the given inferred file id.
236
/// \param NumFileIDs the number of file ids that are defined for this
237
/// function.
238
Error RawCoverageMappingReader::readMappingRegionsSubArray(
239
std::vector<CounterMappingRegion> &MappingRegions, unsigned InferredFileID,
240
size_t NumFileIDs) {
241
uint64_t NumRegions;
242
if (auto Err = readSize(NumRegions))
243
return Err;
244
unsigned LineStart = 0;
245
for (size_t I = 0; I < NumRegions; ++I) {
246
Counter C, C2;
247
uint64_t BIDX, NC;
248
// They are stored as internal values plus 1 (min is -1)
249
uint64_t ID1, TID1, FID1;
250
mcdc::Parameters Params;
251
CounterMappingRegion::RegionKind Kind = CounterMappingRegion::CodeRegion;
252
253
// Read the combined counter + region kind.
254
uint64_t EncodedCounterAndRegion;
255
if (auto Err = readIntMax(EncodedCounterAndRegion,
256
std::numeric_limits<unsigned>::max()))
257
return Err;
258
unsigned Tag = EncodedCounterAndRegion & Counter::EncodingTagMask;
259
uint64_t ExpandedFileID = 0;
260
261
// If Tag does not represent a ZeroCounter, then it is understood to refer
262
// to a counter or counter expression with region kind assumed to be
263
// "CodeRegion". In that case, EncodedCounterAndRegion actually encodes the
264
// referenced counter or counter expression (and nothing else).
265
//
266
// If Tag represents a ZeroCounter and EncodingExpansionRegionBit is set,
267
// then EncodedCounterAndRegion is interpreted to represent an
268
// ExpansionRegion. In all other cases, EncodedCounterAndRegion is
269
// interpreted to refer to a specific region kind, after which additional
270
// fields may be read (e.g. BranchRegions have two encoded counters that
271
// follow an encoded region kind value).
272
if (Tag != Counter::Zero) {
273
if (auto Err = decodeCounter(EncodedCounterAndRegion, C))
274
return Err;
275
} else {
276
// Is it an expansion region?
277
if (EncodedCounterAndRegion & EncodingExpansionRegionBit) {
278
Kind = CounterMappingRegion::ExpansionRegion;
279
ExpandedFileID = EncodedCounterAndRegion >>
280
Counter::EncodingCounterTagAndExpansionRegionTagBits;
281
if (ExpandedFileID >= NumFileIDs)
282
return make_error<CoverageMapError>(coveragemap_error::malformed,
283
"ExpandedFileID is invalid");
284
} else {
285
switch (EncodedCounterAndRegion >>
286
Counter::EncodingCounterTagAndExpansionRegionTagBits) {
287
case CounterMappingRegion::CodeRegion:
288
// Don't do anything when we have a code region with a zero counter.
289
break;
290
case CounterMappingRegion::SkippedRegion:
291
Kind = CounterMappingRegion::SkippedRegion;
292
break;
293
case CounterMappingRegion::BranchRegion:
294
// For a Branch Region, read two successive counters.
295
Kind = CounterMappingRegion::BranchRegion;
296
if (auto Err = readCounter(C))
297
return Err;
298
if (auto Err = readCounter(C2))
299
return Err;
300
break;
301
case CounterMappingRegion::MCDCBranchRegion:
302
// For a MCDC Branch Region, read two successive counters and 3 IDs.
303
Kind = CounterMappingRegion::MCDCBranchRegion;
304
if (auto Err = readCounter(C))
305
return Err;
306
if (auto Err = readCounter(C2))
307
return Err;
308
if (auto Err = readIntMax(ID1, std::numeric_limits<int16_t>::max()))
309
return Err;
310
if (auto Err = readIntMax(TID1, std::numeric_limits<int16_t>::max()))
311
return Err;
312
if (auto Err = readIntMax(FID1, std::numeric_limits<int16_t>::max()))
313
return Err;
314
if (ID1 == 0)
315
return make_error<CoverageMapError>(
316
coveragemap_error::malformed,
317
"MCDCConditionID shouldn't be zero");
318
Params = mcdc::BranchParameters{
319
static_cast<int16_t>(static_cast<int16_t>(ID1) - 1),
320
{static_cast<int16_t>(static_cast<int16_t>(FID1) - 1),
321
static_cast<int16_t>(static_cast<int16_t>(TID1) - 1)}};
322
break;
323
case CounterMappingRegion::MCDCDecisionRegion:
324
Kind = CounterMappingRegion::MCDCDecisionRegion;
325
if (auto Err = readIntMax(BIDX, std::numeric_limits<unsigned>::max()))
326
return Err;
327
if (auto Err = readIntMax(NC, std::numeric_limits<int16_t>::max()))
328
return Err;
329
Params = mcdc::DecisionParameters{static_cast<unsigned>(BIDX),
330
static_cast<uint16_t>(NC)};
331
break;
332
default:
333
return make_error<CoverageMapError>(coveragemap_error::malformed,
334
"region kind is incorrect");
335
}
336
}
337
}
338
339
// Read the source range.
340
uint64_t LineStartDelta, ColumnStart, NumLines, ColumnEnd;
341
if (auto Err =
342
readIntMax(LineStartDelta, std::numeric_limits<unsigned>::max()))
343
return Err;
344
if (auto Err = readULEB128(ColumnStart))
345
return Err;
346
if (ColumnStart > std::numeric_limits<unsigned>::max())
347
return make_error<CoverageMapError>(coveragemap_error::malformed,
348
"start column is too big");
349
if (auto Err = readIntMax(NumLines, std::numeric_limits<unsigned>::max()))
350
return Err;
351
if (auto Err = readIntMax(ColumnEnd, std::numeric_limits<unsigned>::max()))
352
return Err;
353
LineStart += LineStartDelta;
354
355
// If the high bit of ColumnEnd is set, this is a gap region.
356
if (ColumnEnd & (1U << 31)) {
357
Kind = CounterMappingRegion::GapRegion;
358
ColumnEnd &= ~(1U << 31);
359
}
360
361
// Adjust the column locations for the empty regions that are supposed to
362
// cover whole lines. Those regions should be encoded with the
363
// column range (1 -> std::numeric_limits<unsigned>::max()), but because
364
// the encoded std::numeric_limits<unsigned>::max() is several bytes long,
365
// we set the column range to (0 -> 0) to ensure that the column start and
366
// column end take up one byte each.
367
// The std::numeric_limits<unsigned>::max() is used to represent a column
368
// position at the end of the line without knowing the length of that line.
369
if (ColumnStart == 0 && ColumnEnd == 0) {
370
ColumnStart = 1;
371
ColumnEnd = std::numeric_limits<unsigned>::max();
372
}
373
374
LLVM_DEBUG({
375
dbgs() << "Counter in file " << InferredFileID << " " << LineStart << ":"
376
<< ColumnStart << " -> " << (LineStart + NumLines) << ":"
377
<< ColumnEnd << ", ";
378
if (Kind == CounterMappingRegion::ExpansionRegion)
379
dbgs() << "Expands to file " << ExpandedFileID;
380
else
381
CounterMappingContext(Expressions).dump(C, dbgs());
382
dbgs() << "\n";
383
});
384
385
auto CMR = CounterMappingRegion(
386
C, C2, InferredFileID, ExpandedFileID, LineStart, ColumnStart,
387
LineStart + NumLines, ColumnEnd, Kind, Params);
388
if (CMR.startLoc() > CMR.endLoc())
389
return make_error<CoverageMapError>(
390
coveragemap_error::malformed,
391
"counter mapping region locations are incorrect");
392
MappingRegions.push_back(CMR);
393
}
394
return Error::success();
395
}
396
397
Error RawCoverageMappingReader::read() {
398
// Read the virtual file mapping.
399
SmallVector<unsigned, 8> VirtualFileMapping;
400
uint64_t NumFileMappings;
401
if (auto Err = readSize(NumFileMappings))
402
return Err;
403
for (size_t I = 0; I < NumFileMappings; ++I) {
404
uint64_t FilenameIndex;
405
if (auto Err = readIntMax(FilenameIndex, TranslationUnitFilenames.size()))
406
return Err;
407
VirtualFileMapping.push_back(FilenameIndex);
408
}
409
410
// Construct the files using unique filenames and virtual file mapping.
411
for (auto I : VirtualFileMapping) {
412
Filenames.push_back(TranslationUnitFilenames[I]);
413
}
414
415
// Read the expressions.
416
uint64_t NumExpressions;
417
if (auto Err = readSize(NumExpressions))
418
return Err;
419
// Create an array of dummy expressions that get the proper counters
420
// when the expressions are read, and the proper kinds when the counters
421
// are decoded.
422
Expressions.resize(
423
NumExpressions,
424
CounterExpression(CounterExpression::Subtract, Counter(), Counter()));
425
for (size_t I = 0; I < NumExpressions; ++I) {
426
if (auto Err = readCounter(Expressions[I].LHS))
427
return Err;
428
if (auto Err = readCounter(Expressions[I].RHS))
429
return Err;
430
}
431
432
// Read the mapping regions sub-arrays.
433
for (unsigned InferredFileID = 0, S = VirtualFileMapping.size();
434
InferredFileID < S; ++InferredFileID) {
435
if (auto Err = readMappingRegionsSubArray(MappingRegions, InferredFileID,
436
VirtualFileMapping.size()))
437
return Err;
438
}
439
440
// Set the counters for the expansion regions.
441
// i.e. Counter of expansion region = counter of the first region
442
// from the expanded file.
443
// Perform multiple passes to correctly propagate the counters through
444
// all the nested expansion regions.
445
SmallVector<CounterMappingRegion *, 8> FileIDExpansionRegionMapping;
446
FileIDExpansionRegionMapping.resize(VirtualFileMapping.size(), nullptr);
447
for (unsigned Pass = 1, S = VirtualFileMapping.size(); Pass < S; ++Pass) {
448
for (auto &R : MappingRegions) {
449
if (R.Kind != CounterMappingRegion::ExpansionRegion)
450
continue;
451
assert(!FileIDExpansionRegionMapping[R.ExpandedFileID]);
452
FileIDExpansionRegionMapping[R.ExpandedFileID] = &R;
453
}
454
for (auto &R : MappingRegions) {
455
if (FileIDExpansionRegionMapping[R.FileID]) {
456
FileIDExpansionRegionMapping[R.FileID]->Count = R.Count;
457
FileIDExpansionRegionMapping[R.FileID] = nullptr;
458
}
459
}
460
}
461
462
return Error::success();
463
}
464
465
Expected<bool> RawCoverageMappingDummyChecker::isDummy() {
466
// A dummy coverage mapping data consists of just one region with zero count.
467
uint64_t NumFileMappings;
468
if (Error Err = readSize(NumFileMappings))
469
return std::move(Err);
470
if (NumFileMappings != 1)
471
return false;
472
// We don't expect any specific value for the filename index, just skip it.
473
uint64_t FilenameIndex;
474
if (Error Err =
475
readIntMax(FilenameIndex, std::numeric_limits<unsigned>::max()))
476
return std::move(Err);
477
uint64_t NumExpressions;
478
if (Error Err = readSize(NumExpressions))
479
return std::move(Err);
480
if (NumExpressions != 0)
481
return false;
482
uint64_t NumRegions;
483
if (Error Err = readSize(NumRegions))
484
return std::move(Err);
485
if (NumRegions != 1)
486
return false;
487
uint64_t EncodedCounterAndRegion;
488
if (Error Err = readIntMax(EncodedCounterAndRegion,
489
std::numeric_limits<unsigned>::max()))
490
return std::move(Err);
491
unsigned Tag = EncodedCounterAndRegion & Counter::EncodingTagMask;
492
return Tag == Counter::Zero;
493
}
494
495
Error InstrProfSymtab::create(SectionRef &Section) {
496
Expected<StringRef> DataOrErr = Section.getContents();
497
if (!DataOrErr)
498
return DataOrErr.takeError();
499
Data = *DataOrErr;
500
Address = Section.getAddress();
501
502
// If this is a linked PE/COFF file, then we have to skip over the null byte
503
// that is allocated in the .lprfn$A section in the LLVM profiling runtime.
504
// If the name section is .lprfcovnames, it doesn't have the null byte at the
505
// beginning.
506
const ObjectFile *Obj = Section.getObject();
507
if (isa<COFFObjectFile>(Obj) && !Obj->isRelocatableObject())
508
if (Expected<StringRef> NameOrErr = Section.getName())
509
if (*NameOrErr != getInstrProfSectionName(IPSK_covname, Triple::COFF))
510
Data = Data.drop_front(1);
511
512
return Error::success();
513
}
514
515
StringRef InstrProfSymtab::getFuncName(uint64_t Pointer, size_t Size) {
516
if (Pointer < Address)
517
return StringRef();
518
auto Offset = Pointer - Address;
519
if (Offset + Size > Data.size())
520
return StringRef();
521
return Data.substr(Pointer - Address, Size);
522
}
523
524
// Check if the mapping data is a dummy, i.e. is emitted for an unused function.
525
static Expected<bool> isCoverageMappingDummy(uint64_t Hash, StringRef Mapping) {
526
// The hash value of dummy mapping records is always zero.
527
if (Hash)
528
return false;
529
return RawCoverageMappingDummyChecker(Mapping).isDummy();
530
}
531
532
/// A range of filename indices. Used to specify the location of a batch of
533
/// filenames in a vector-like container.
534
struct FilenameRange {
535
unsigned StartingIndex;
536
unsigned Length;
537
538
FilenameRange(unsigned StartingIndex, unsigned Length)
539
: StartingIndex(StartingIndex), Length(Length) {}
540
541
void markInvalid() { Length = 0; }
542
bool isInvalid() const { return Length == 0; }
543
};
544
545
namespace {
546
547
/// The interface to read coverage mapping function records for a module.
548
struct CovMapFuncRecordReader {
549
virtual ~CovMapFuncRecordReader() = default;
550
551
// Read a coverage header.
552
//
553
// \p CovBuf points to the buffer containing the \c CovHeader of the coverage
554
// mapping data associated with the module.
555
//
556
// Returns a pointer to the next \c CovHeader if it exists, or to an address
557
// greater than \p CovEnd if not.
558
virtual Expected<const char *> readCoverageHeader(const char *CovBuf,
559
const char *CovBufEnd) = 0;
560
561
// Read function records.
562
//
563
// \p FuncRecBuf points to the buffer containing a batch of function records.
564
// \p FuncRecBufEnd points past the end of the batch of records.
565
//
566
// Prior to Version4, \p OutOfLineFileRange points to a sequence of filenames
567
// associated with the function records. It is unused in Version4.
568
//
569
// Prior to Version4, \p OutOfLineMappingBuf points to a sequence of coverage
570
// mappings associated with the function records. It is unused in Version4.
571
virtual Error
572
readFunctionRecords(const char *FuncRecBuf, const char *FuncRecBufEnd,
573
std::optional<FilenameRange> OutOfLineFileRange,
574
const char *OutOfLineMappingBuf,
575
const char *OutOfLineMappingBufEnd) = 0;
576
577
template <class IntPtrT, llvm::endianness Endian>
578
static Expected<std::unique_ptr<CovMapFuncRecordReader>>
579
get(CovMapVersion Version, InstrProfSymtab &P,
580
std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, StringRef D,
581
std::vector<std::string> &F);
582
};
583
584
// A class for reading coverage mapping function records for a module.
585
template <CovMapVersion Version, class IntPtrT, llvm::endianness Endian>
586
class VersionedCovMapFuncRecordReader : public CovMapFuncRecordReader {
587
using FuncRecordType =
588
typename CovMapTraits<Version, IntPtrT>::CovMapFuncRecordType;
589
using NameRefType = typename CovMapTraits<Version, IntPtrT>::NameRefType;
590
591
// Maps function's name references to the indexes of their records
592
// in \c Records.
593
DenseMap<NameRefType, size_t> FunctionRecords;
594
InstrProfSymtab &ProfileNames;
595
StringRef CompilationDir;
596
std::vector<std::string> &Filenames;
597
std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records;
598
599
// Maps a hash of the filenames in a TU to a \c FileRange. The range
600
// specifies the location of the hashed filenames in \c Filenames.
601
DenseMap<uint64_t, FilenameRange> FileRangeMap;
602
603
// Add the record to the collection if we don't already have a record that
604
// points to the same function name. This is useful to ignore the redundant
605
// records for the functions with ODR linkage.
606
// In addition, prefer records with real coverage mapping data to dummy
607
// records, which were emitted for inline functions which were seen but
608
// not used in the corresponding translation unit.
609
Error insertFunctionRecordIfNeeded(const FuncRecordType *CFR,
610
StringRef Mapping,
611
FilenameRange FileRange) {
612
++CovMapNumRecords;
613
uint64_t FuncHash = CFR->template getFuncHash<Endian>();
614
NameRefType NameRef = CFR->template getFuncNameRef<Endian>();
615
auto InsertResult =
616
FunctionRecords.insert(std::make_pair(NameRef, Records.size()));
617
if (InsertResult.second) {
618
StringRef FuncName;
619
if (Error Err = CFR->template getFuncName<Endian>(ProfileNames, FuncName))
620
return Err;
621
if (FuncName.empty())
622
return make_error<InstrProfError>(instrprof_error::malformed,
623
"function name is empty");
624
++CovMapNumUsedRecords;
625
Records.emplace_back(Version, FuncName, FuncHash, Mapping,
626
FileRange.StartingIndex, FileRange.Length);
627
return Error::success();
628
}
629
// Update the existing record if it's a dummy and the new record is real.
630
size_t OldRecordIndex = InsertResult.first->second;
631
BinaryCoverageReader::ProfileMappingRecord &OldRecord =
632
Records[OldRecordIndex];
633
Expected<bool> OldIsDummyExpected = isCoverageMappingDummy(
634
OldRecord.FunctionHash, OldRecord.CoverageMapping);
635
if (Error Err = OldIsDummyExpected.takeError())
636
return Err;
637
if (!*OldIsDummyExpected)
638
return Error::success();
639
Expected<bool> NewIsDummyExpected =
640
isCoverageMappingDummy(FuncHash, Mapping);
641
if (Error Err = NewIsDummyExpected.takeError())
642
return Err;
643
if (*NewIsDummyExpected)
644
return Error::success();
645
++CovMapNumUsedRecords;
646
OldRecord.FunctionHash = FuncHash;
647
OldRecord.CoverageMapping = Mapping;
648
OldRecord.FilenamesBegin = FileRange.StartingIndex;
649
OldRecord.FilenamesSize = FileRange.Length;
650
return Error::success();
651
}
652
653
public:
654
VersionedCovMapFuncRecordReader(
655
InstrProfSymtab &P,
656
std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, StringRef D,
657
std::vector<std::string> &F)
658
: ProfileNames(P), CompilationDir(D), Filenames(F), Records(R) {}
659
660
~VersionedCovMapFuncRecordReader() override = default;
661
662
Expected<const char *> readCoverageHeader(const char *CovBuf,
663
const char *CovBufEnd) override {
664
using namespace support;
665
666
if (CovBuf + sizeof(CovMapHeader) > CovBufEnd)
667
return make_error<CoverageMapError>(
668
coveragemap_error::malformed,
669
"coverage mapping header section is larger than buffer size");
670
auto CovHeader = reinterpret_cast<const CovMapHeader *>(CovBuf);
671
uint32_t NRecords = CovHeader->getNRecords<Endian>();
672
uint32_t FilenamesSize = CovHeader->getFilenamesSize<Endian>();
673
uint32_t CoverageSize = CovHeader->getCoverageSize<Endian>();
674
assert((CovMapVersion)CovHeader->getVersion<Endian>() == Version);
675
CovBuf = reinterpret_cast<const char *>(CovHeader + 1);
676
677
// Skip past the function records, saving the start and end for later.
678
// This is a no-op in Version4 (function records are read after all headers
679
// are read).
680
const char *FuncRecBuf = nullptr;
681
const char *FuncRecBufEnd = nullptr;
682
if (Version < CovMapVersion::Version4)
683
FuncRecBuf = CovBuf;
684
CovBuf += NRecords * sizeof(FuncRecordType);
685
if (Version < CovMapVersion::Version4)
686
FuncRecBufEnd = CovBuf;
687
688
// Get the filenames.
689
if (CovBuf + FilenamesSize > CovBufEnd)
690
return make_error<CoverageMapError>(
691
coveragemap_error::malformed,
692
"filenames section is larger than buffer size");
693
size_t FilenamesBegin = Filenames.size();
694
StringRef FilenameRegion(CovBuf, FilenamesSize);
695
RawCoverageFilenamesReader Reader(FilenameRegion, Filenames,
696
CompilationDir);
697
if (auto Err = Reader.read(Version))
698
return std::move(Err);
699
CovBuf += FilenamesSize;
700
FilenameRange FileRange(FilenamesBegin, Filenames.size() - FilenamesBegin);
701
702
if (Version >= CovMapVersion::Version4) {
703
// Map a hash of the filenames region to the filename range associated
704
// with this coverage header.
705
int64_t FilenamesRef =
706
llvm::IndexedInstrProf::ComputeHash(FilenameRegion);
707
auto Insert =
708
FileRangeMap.insert(std::make_pair(FilenamesRef, FileRange));
709
if (!Insert.second) {
710
// The same filenames ref was encountered twice. It's possible that
711
// the associated filenames are the same.
712
auto It = Filenames.begin();
713
FilenameRange &OrigRange = Insert.first->getSecond();
714
if (std::equal(It + OrigRange.StartingIndex,
715
It + OrigRange.StartingIndex + OrigRange.Length,
716
It + FileRange.StartingIndex,
717
It + FileRange.StartingIndex + FileRange.Length))
718
// Map the new range to the original one.
719
FileRange = OrigRange;
720
else
721
// This is a hash collision. Mark the filenames ref invalid.
722
OrigRange.markInvalid();
723
}
724
}
725
726
// We'll read the coverage mapping records in the loop below.
727
// This is a no-op in Version4 (coverage mappings are not affixed to the
728
// coverage header).
729
const char *MappingBuf = CovBuf;
730
if (Version >= CovMapVersion::Version4 && CoverageSize != 0)
731
return make_error<CoverageMapError>(coveragemap_error::malformed,
732
"coverage mapping size is not zero");
733
CovBuf += CoverageSize;
734
const char *MappingEnd = CovBuf;
735
736
if (CovBuf > CovBufEnd)
737
return make_error<CoverageMapError>(
738
coveragemap_error::malformed,
739
"function records section is larger than buffer size");
740
741
if (Version < CovMapVersion::Version4) {
742
// Read each function record.
743
if (Error E = readFunctionRecords(FuncRecBuf, FuncRecBufEnd, FileRange,
744
MappingBuf, MappingEnd))
745
return std::move(E);
746
}
747
748
// Each coverage map has an alignment of 8, so we need to adjust alignment
749
// before reading the next map.
750
CovBuf += offsetToAlignedAddr(CovBuf, Align(8));
751
752
return CovBuf;
753
}
754
755
Error readFunctionRecords(const char *FuncRecBuf, const char *FuncRecBufEnd,
756
std::optional<FilenameRange> OutOfLineFileRange,
757
const char *OutOfLineMappingBuf,
758
const char *OutOfLineMappingBufEnd) override {
759
auto CFR = reinterpret_cast<const FuncRecordType *>(FuncRecBuf);
760
while ((const char *)CFR < FuncRecBufEnd) {
761
// Validate the length of the coverage mapping for this function.
762
const char *NextMappingBuf;
763
const FuncRecordType *NextCFR;
764
std::tie(NextMappingBuf, NextCFR) =
765
CFR->template advanceByOne<Endian>(OutOfLineMappingBuf);
766
if (Version < CovMapVersion::Version4)
767
if (NextMappingBuf > OutOfLineMappingBufEnd)
768
return make_error<CoverageMapError>(
769
coveragemap_error::malformed,
770
"next mapping buffer is larger than buffer size");
771
772
// Look up the set of filenames associated with this function record.
773
std::optional<FilenameRange> FileRange;
774
if (Version < CovMapVersion::Version4) {
775
FileRange = OutOfLineFileRange;
776
} else {
777
uint64_t FilenamesRef = CFR->template getFilenamesRef<Endian>();
778
auto It = FileRangeMap.find(FilenamesRef);
779
if (It == FileRangeMap.end())
780
return make_error<CoverageMapError>(
781
coveragemap_error::malformed,
782
"no filename found for function with hash=0x" +
783
Twine::utohexstr(FilenamesRef));
784
else
785
FileRange = It->getSecond();
786
}
787
788
// Now, read the coverage data.
789
if (FileRange && !FileRange->isInvalid()) {
790
StringRef Mapping =
791
CFR->template getCoverageMapping<Endian>(OutOfLineMappingBuf);
792
if (Version >= CovMapVersion::Version4 &&
793
Mapping.data() + Mapping.size() > FuncRecBufEnd)
794
return make_error<CoverageMapError>(
795
coveragemap_error::malformed,
796
"coverage mapping data is larger than buffer size");
797
if (Error Err = insertFunctionRecordIfNeeded(CFR, Mapping, *FileRange))
798
return Err;
799
}
800
801
std::tie(OutOfLineMappingBuf, CFR) = std::tie(NextMappingBuf, NextCFR);
802
}
803
return Error::success();
804
}
805
};
806
807
} // end anonymous namespace
808
809
template <class IntPtrT, llvm::endianness Endian>
810
Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get(
811
CovMapVersion Version, InstrProfSymtab &P,
812
std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, StringRef D,
813
std::vector<std::string> &F) {
814
using namespace coverage;
815
816
switch (Version) {
817
case CovMapVersion::Version1:
818
return std::make_unique<VersionedCovMapFuncRecordReader<
819
CovMapVersion::Version1, IntPtrT, Endian>>(P, R, D, F);
820
case CovMapVersion::Version2:
821
case CovMapVersion::Version3:
822
case CovMapVersion::Version4:
823
case CovMapVersion::Version5:
824
case CovMapVersion::Version6:
825
case CovMapVersion::Version7:
826
// Decompress the name data.
827
if (Error E = P.create(P.getNameData()))
828
return std::move(E);
829
if (Version == CovMapVersion::Version2)
830
return std::make_unique<VersionedCovMapFuncRecordReader<
831
CovMapVersion::Version2, IntPtrT, Endian>>(P, R, D, F);
832
else if (Version == CovMapVersion::Version3)
833
return std::make_unique<VersionedCovMapFuncRecordReader<
834
CovMapVersion::Version3, IntPtrT, Endian>>(P, R, D, F);
835
else if (Version == CovMapVersion::Version4)
836
return std::make_unique<VersionedCovMapFuncRecordReader<
837
CovMapVersion::Version4, IntPtrT, Endian>>(P, R, D, F);
838
else if (Version == CovMapVersion::Version5)
839
return std::make_unique<VersionedCovMapFuncRecordReader<
840
CovMapVersion::Version5, IntPtrT, Endian>>(P, R, D, F);
841
else if (Version == CovMapVersion::Version6)
842
return std::make_unique<VersionedCovMapFuncRecordReader<
843
CovMapVersion::Version6, IntPtrT, Endian>>(P, R, D, F);
844
else if (Version == CovMapVersion::Version7)
845
return std::make_unique<VersionedCovMapFuncRecordReader<
846
CovMapVersion::Version7, IntPtrT, Endian>>(P, R, D, F);
847
}
848
llvm_unreachable("Unsupported version");
849
}
850
851
template <typename T, llvm::endianness Endian>
852
static Error readCoverageMappingData(
853
InstrProfSymtab &ProfileNames, StringRef CovMap, StringRef FuncRecords,
854
std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
855
StringRef CompilationDir, std::vector<std::string> &Filenames) {
856
using namespace coverage;
857
858
// Read the records in the coverage data section.
859
auto CovHeader =
860
reinterpret_cast<const CovMapHeader *>(CovMap.data());
861
CovMapVersion Version = (CovMapVersion)CovHeader->getVersion<Endian>();
862
if (Version > CovMapVersion::CurrentVersion)
863
return make_error<CoverageMapError>(coveragemap_error::unsupported_version);
864
Expected<std::unique_ptr<CovMapFuncRecordReader>> ReaderExpected =
865
CovMapFuncRecordReader::get<T, Endian>(Version, ProfileNames, Records,
866
CompilationDir, Filenames);
867
if (Error E = ReaderExpected.takeError())
868
return E;
869
auto Reader = std::move(ReaderExpected.get());
870
const char *CovBuf = CovMap.data();
871
const char *CovBufEnd = CovBuf + CovMap.size();
872
const char *FuncRecBuf = FuncRecords.data();
873
const char *FuncRecBufEnd = FuncRecords.data() + FuncRecords.size();
874
while (CovBuf < CovBufEnd) {
875
// Read the current coverage header & filename data.
876
//
877
// Prior to Version4, this also reads all function records affixed to the
878
// header.
879
//
880
// Return a pointer to the next coverage header.
881
auto NextOrErr = Reader->readCoverageHeader(CovBuf, CovBufEnd);
882
if (auto E = NextOrErr.takeError())
883
return E;
884
CovBuf = NextOrErr.get();
885
}
886
// In Version4, function records are not affixed to coverage headers. Read
887
// the records from their dedicated section.
888
if (Version >= CovMapVersion::Version4)
889
return Reader->readFunctionRecords(FuncRecBuf, FuncRecBufEnd, std::nullopt,
890
nullptr, nullptr);
891
return Error::success();
892
}
893
894
Expected<std::unique_ptr<BinaryCoverageReader>>
895
BinaryCoverageReader::createCoverageReaderFromBuffer(
896
StringRef Coverage, FuncRecordsStorage &&FuncRecords,
897
std::unique_ptr<InstrProfSymtab> ProfileNamesPtr, uint8_t BytesInAddress,
898
llvm::endianness Endian, StringRef CompilationDir) {
899
if (ProfileNamesPtr == nullptr)
900
return make_error<CoverageMapError>(coveragemap_error::malformed,
901
"Caller must provide ProfileNames");
902
std::unique_ptr<BinaryCoverageReader> Reader(new BinaryCoverageReader(
903
std::move(ProfileNamesPtr), std::move(FuncRecords)));
904
InstrProfSymtab &ProfileNames = *Reader->ProfileNames;
905
StringRef FuncRecordsRef = Reader->FuncRecords->getBuffer();
906
if (BytesInAddress == 4 && Endian == llvm::endianness::little) {
907
if (Error E = readCoverageMappingData<uint32_t, llvm::endianness::little>(
908
ProfileNames, Coverage, FuncRecordsRef, Reader->MappingRecords,
909
CompilationDir, Reader->Filenames))
910
return std::move(E);
911
} else if (BytesInAddress == 4 && Endian == llvm::endianness::big) {
912
if (Error E = readCoverageMappingData<uint32_t, llvm::endianness::big>(
913
ProfileNames, Coverage, FuncRecordsRef, Reader->MappingRecords,
914
CompilationDir, Reader->Filenames))
915
return std::move(E);
916
} else if (BytesInAddress == 8 && Endian == llvm::endianness::little) {
917
if (Error E = readCoverageMappingData<uint64_t, llvm::endianness::little>(
918
ProfileNames, Coverage, FuncRecordsRef, Reader->MappingRecords,
919
CompilationDir, Reader->Filenames))
920
return std::move(E);
921
} else if (BytesInAddress == 8 && Endian == llvm::endianness::big) {
922
if (Error E = readCoverageMappingData<uint64_t, llvm::endianness::big>(
923
ProfileNames, Coverage, FuncRecordsRef, Reader->MappingRecords,
924
CompilationDir, Reader->Filenames))
925
return std::move(E);
926
} else
927
return make_error<CoverageMapError>(
928
coveragemap_error::malformed,
929
"not supported endianness or bytes in address");
930
return std::move(Reader);
931
}
932
933
static Expected<std::unique_ptr<BinaryCoverageReader>>
934
loadTestingFormat(StringRef Data, StringRef CompilationDir) {
935
uint8_t BytesInAddress = 8;
936
llvm::endianness Endian = llvm::endianness::little;
937
938
// Read the magic and version.
939
Data = Data.substr(sizeof(TestingFormatMagic));
940
if (Data.size() < sizeof(uint64_t))
941
return make_error<CoverageMapError>(coveragemap_error::malformed,
942
"the size of data is too small");
943
auto TestingVersion =
944
support::endian::byte_swap<uint64_t, llvm::endianness::little>(
945
*reinterpret_cast<const uint64_t *>(Data.data()));
946
Data = Data.substr(sizeof(uint64_t));
947
948
// Read the ProfileNames data.
949
if (Data.empty())
950
return make_error<CoverageMapError>(coveragemap_error::truncated);
951
unsigned N = 0;
952
uint64_t ProfileNamesSize = decodeULEB128(Data.bytes_begin(), &N);
953
if (N > Data.size())
954
return make_error<CoverageMapError>(
955
coveragemap_error::malformed,
956
"the size of TestingFormatMagic is too big");
957
Data = Data.substr(N);
958
if (Data.empty())
959
return make_error<CoverageMapError>(coveragemap_error::truncated);
960
N = 0;
961
uint64_t Address = decodeULEB128(Data.bytes_begin(), &N);
962
if (N > Data.size())
963
return make_error<CoverageMapError>(coveragemap_error::malformed,
964
"the size of ULEB128 is too big");
965
Data = Data.substr(N);
966
if (Data.size() < ProfileNamesSize)
967
return make_error<CoverageMapError>(coveragemap_error::malformed,
968
"the size of ProfileNames is too big");
969
auto ProfileNames = std::make_unique<InstrProfSymtab>();
970
if (Error E = ProfileNames->create(Data.substr(0, ProfileNamesSize), Address))
971
return std::move(E);
972
Data = Data.substr(ProfileNamesSize);
973
974
// In Version2, the size of CoverageMapping is stored directly.
975
uint64_t CoverageMappingSize;
976
if (TestingVersion == uint64_t(TestingFormatVersion::Version2)) {
977
N = 0;
978
CoverageMappingSize = decodeULEB128(Data.bytes_begin(), &N);
979
if (N > Data.size())
980
return make_error<CoverageMapError>(coveragemap_error::malformed,
981
"the size of ULEB128 is too big");
982
Data = Data.substr(N);
983
if (CoverageMappingSize < sizeof(CovMapHeader))
984
return make_error<CoverageMapError>(
985
coveragemap_error::malformed,
986
"the size of CoverageMapping is teoo small");
987
} else if (TestingVersion != uint64_t(TestingFormatVersion::Version1)) {
988
return make_error<CoverageMapError>(coveragemap_error::unsupported_version);
989
}
990
991
// Skip the padding bytes because coverage map data has an alignment of 8.
992
auto Pad = offsetToAlignedAddr(Data.data(), Align(8));
993
if (Data.size() < Pad)
994
return make_error<CoverageMapError>(coveragemap_error::malformed,
995
"insufficient padding");
996
Data = Data.substr(Pad);
997
if (Data.size() < sizeof(CovMapHeader))
998
return make_error<CoverageMapError>(
999
coveragemap_error::malformed,
1000
"coverage mapping header section is larger than data size");
1001
auto const *CovHeader = reinterpret_cast<const CovMapHeader *>(
1002
Data.substr(0, sizeof(CovMapHeader)).data());
1003
auto Version =
1004
CovMapVersion(CovHeader->getVersion<llvm::endianness::little>());
1005
1006
// In Version1, the size of CoverageMapping is calculated.
1007
if (TestingVersion == uint64_t(TestingFormatVersion::Version1)) {
1008
if (Version < CovMapVersion::Version4) {
1009
CoverageMappingSize = Data.size();
1010
} else {
1011
auto FilenamesSize =
1012
CovHeader->getFilenamesSize<llvm::endianness::little>();
1013
CoverageMappingSize = sizeof(CovMapHeader) + FilenamesSize;
1014
}
1015
}
1016
1017
auto CoverageMapping = Data.substr(0, CoverageMappingSize);
1018
Data = Data.substr(CoverageMappingSize);
1019
1020
// Read the CoverageRecords data.
1021
if (Version < CovMapVersion::Version4) {
1022
if (!Data.empty())
1023
return make_error<CoverageMapError>(coveragemap_error::malformed,
1024
"data is not empty");
1025
} else {
1026
// Skip the padding bytes because coverage records data has an alignment
1027
// of 8.
1028
Pad = offsetToAlignedAddr(Data.data(), Align(8));
1029
if (Data.size() < Pad)
1030
return make_error<CoverageMapError>(coveragemap_error::malformed,
1031
"insufficient padding");
1032
Data = Data.substr(Pad);
1033
}
1034
BinaryCoverageReader::FuncRecordsStorage CoverageRecords =
1035
MemoryBuffer::getMemBuffer(Data);
1036
1037
return BinaryCoverageReader::createCoverageReaderFromBuffer(
1038
CoverageMapping, std::move(CoverageRecords), std::move(ProfileNames),
1039
BytesInAddress, Endian, CompilationDir);
1040
}
1041
1042
/// Find all sections that match \p IPSK name. There may be more than one if
1043
/// comdats are in use, e.g. for the __llvm_covfun section on ELF.
1044
static Expected<std::vector<SectionRef>>
1045
lookupSections(ObjectFile &OF, InstrProfSectKind IPSK) {
1046
auto ObjFormat = OF.getTripleObjectFormat();
1047
auto Name =
1048
getInstrProfSectionName(IPSK, ObjFormat, /*AddSegmentInfo=*/false);
1049
// On COFF, the object file section name may end in "$M". This tells the
1050
// linker to sort these sections between "$A" and "$Z". The linker removes the
1051
// dollar and everything after it in the final binary. Do the same to match.
1052
bool IsCOFF = isa<COFFObjectFile>(OF);
1053
auto stripSuffix = [IsCOFF](StringRef N) {
1054
return IsCOFF ? N.split('$').first : N;
1055
};
1056
Name = stripSuffix(Name);
1057
1058
std::vector<SectionRef> Sections;
1059
for (const auto &Section : OF.sections()) {
1060
Expected<StringRef> NameOrErr = Section.getName();
1061
if (!NameOrErr)
1062
return NameOrErr.takeError();
1063
if (stripSuffix(*NameOrErr) == Name) {
1064
// COFF profile name section contains two null bytes indicating the
1065
// start/end of the section. If its size is 2 bytes, it's empty.
1066
if (IsCOFF && IPSK == IPSK_name && Section.getSize() == 2)
1067
continue;
1068
Sections.push_back(Section);
1069
}
1070
}
1071
if (Sections.empty())
1072
return make_error<CoverageMapError>(coveragemap_error::no_data_found);
1073
return Sections;
1074
}
1075
1076
static Expected<std::unique_ptr<BinaryCoverageReader>>
1077
loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch,
1078
StringRef CompilationDir = "",
1079
object::BuildIDRef *BinaryID = nullptr) {
1080
std::unique_ptr<ObjectFile> OF;
1081
if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin.get())) {
1082
// If we have a universal binary, try to look up the object for the
1083
// appropriate architecture.
1084
auto ObjectFileOrErr = Universal->getMachOObjectForArch(Arch);
1085
if (!ObjectFileOrErr)
1086
return ObjectFileOrErr.takeError();
1087
OF = std::move(ObjectFileOrErr.get());
1088
} else if (isa<ObjectFile>(Bin.get())) {
1089
// For any other object file, upcast and take ownership.
1090
OF.reset(cast<ObjectFile>(Bin.release()));
1091
// If we've asked for a particular arch, make sure they match.
1092
if (!Arch.empty() && OF->getArch() != Triple(Arch).getArch())
1093
return errorCodeToError(object_error::arch_not_found);
1094
} else
1095
// We can only handle object files.
1096
return make_error<CoverageMapError>(coveragemap_error::malformed,
1097
"binary is not an object file");
1098
1099
// The coverage uses native pointer sizes for the object it's written in.
1100
uint8_t BytesInAddress = OF->getBytesInAddress();
1101
llvm::endianness Endian =
1102
OF->isLittleEndian() ? llvm::endianness::little : llvm::endianness::big;
1103
1104
// Look for the sections that we are interested in.
1105
auto ProfileNames = std::make_unique<InstrProfSymtab>();
1106
std::vector<SectionRef> NamesSectionRefs;
1107
// If IPSK_name is not found, fallback to search for IPK_covname, which is
1108
// used when binary correlation is enabled.
1109
auto NamesSection = lookupSections(*OF, IPSK_name);
1110
if (auto E = NamesSection.takeError()) {
1111
consumeError(std::move(E));
1112
NamesSection = lookupSections(*OF, IPSK_covname);
1113
if (auto E = NamesSection.takeError())
1114
return std::move(E);
1115
}
1116
NamesSectionRefs = *NamesSection;
1117
1118
if (NamesSectionRefs.size() != 1)
1119
return make_error<CoverageMapError>(
1120
coveragemap_error::malformed,
1121
"the size of coverage mapping section is not one");
1122
if (Error E = ProfileNames->create(NamesSectionRefs.back()))
1123
return std::move(E);
1124
1125
auto CoverageSection = lookupSections(*OF, IPSK_covmap);
1126
if (auto E = CoverageSection.takeError())
1127
return std::move(E);
1128
std::vector<SectionRef> CoverageSectionRefs = *CoverageSection;
1129
if (CoverageSectionRefs.size() != 1)
1130
return make_error<CoverageMapError>(coveragemap_error::malformed,
1131
"the size of name section is not one");
1132
auto CoverageMappingOrErr = CoverageSectionRefs.back().getContents();
1133
if (!CoverageMappingOrErr)
1134
return CoverageMappingOrErr.takeError();
1135
StringRef CoverageMapping = CoverageMappingOrErr.get();
1136
1137
// Look for the coverage records section (Version4 only).
1138
auto CoverageRecordsSections = lookupSections(*OF, IPSK_covfun);
1139
1140
BinaryCoverageReader::FuncRecordsStorage FuncRecords;
1141
if (auto E = CoverageRecordsSections.takeError()) {
1142
consumeError(std::move(E));
1143
FuncRecords = MemoryBuffer::getMemBuffer("");
1144
} else {
1145
// Compute the FuncRecordsBuffer of the buffer, taking into account the
1146
// padding between each record, and making sure the first block is aligned
1147
// in memory to maintain consistency between buffer address and size
1148
// alignment.
1149
const Align RecordAlignment(8);
1150
uint64_t FuncRecordsSize = 0;
1151
for (SectionRef Section : *CoverageRecordsSections) {
1152
auto CoverageRecordsOrErr = Section.getContents();
1153
if (!CoverageRecordsOrErr)
1154
return CoverageRecordsOrErr.takeError();
1155
FuncRecordsSize += alignTo(CoverageRecordsOrErr->size(), RecordAlignment);
1156
}
1157
auto WritableBuffer =
1158
WritableMemoryBuffer::getNewUninitMemBuffer(FuncRecordsSize);
1159
char *FuncRecordsBuffer = WritableBuffer->getBufferStart();
1160
assert(isAddrAligned(RecordAlignment, FuncRecordsBuffer) &&
1161
"Allocated memory is correctly aligned");
1162
1163
for (SectionRef Section : *CoverageRecordsSections) {
1164
auto CoverageRecordsOrErr = Section.getContents();
1165
if (!CoverageRecordsOrErr)
1166
return CoverageRecordsOrErr.takeError();
1167
const auto &CoverageRecords = CoverageRecordsOrErr.get();
1168
FuncRecordsBuffer = std::copy(CoverageRecords.begin(),
1169
CoverageRecords.end(), FuncRecordsBuffer);
1170
FuncRecordsBuffer =
1171
std::fill_n(FuncRecordsBuffer,
1172
alignAddr(FuncRecordsBuffer, RecordAlignment) -
1173
(uintptr_t)FuncRecordsBuffer,
1174
'\0');
1175
}
1176
assert(FuncRecordsBuffer == WritableBuffer->getBufferEnd() &&
1177
"consistent init");
1178
FuncRecords = std::move(WritableBuffer);
1179
}
1180
1181
if (BinaryID)
1182
*BinaryID = getBuildID(OF.get());
1183
1184
return BinaryCoverageReader::createCoverageReaderFromBuffer(
1185
CoverageMapping, std::move(FuncRecords), std::move(ProfileNames),
1186
BytesInAddress, Endian, CompilationDir);
1187
}
1188
1189
/// Determine whether \p Arch is invalid or empty, given \p Bin.
1190
static bool isArchSpecifierInvalidOrMissing(Binary *Bin, StringRef Arch) {
1191
// If we have a universal binary and Arch doesn't identify any of its slices,
1192
// it's user error.
1193
if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin)) {
1194
for (auto &ObjForArch : Universal->objects())
1195
if (Arch == ObjForArch.getArchFlagName())
1196
return false;
1197
return true;
1198
}
1199
return false;
1200
}
1201
1202
Expected<std::vector<std::unique_ptr<BinaryCoverageReader>>>
1203
BinaryCoverageReader::create(
1204
MemoryBufferRef ObjectBuffer, StringRef Arch,
1205
SmallVectorImpl<std::unique_ptr<MemoryBuffer>> &ObjectFileBuffers,
1206
StringRef CompilationDir, SmallVectorImpl<object::BuildIDRef> *BinaryIDs) {
1207
std::vector<std::unique_ptr<BinaryCoverageReader>> Readers;
1208
1209
if (ObjectBuffer.getBuffer().size() > sizeof(TestingFormatMagic)) {
1210
uint64_t Magic =
1211
support::endian::byte_swap<uint64_t, llvm::endianness::little>(
1212
*reinterpret_cast<const uint64_t *>(ObjectBuffer.getBufferStart()));
1213
if (Magic == TestingFormatMagic) {
1214
// This is a special format used for testing.
1215
auto ReaderOrErr =
1216
loadTestingFormat(ObjectBuffer.getBuffer(), CompilationDir);
1217
if (!ReaderOrErr)
1218
return ReaderOrErr.takeError();
1219
Readers.push_back(std::move(ReaderOrErr.get()));
1220
return std::move(Readers);
1221
}
1222
}
1223
1224
auto BinOrErr = createBinary(ObjectBuffer);
1225
if (!BinOrErr)
1226
return BinOrErr.takeError();
1227
std::unique_ptr<Binary> Bin = std::move(BinOrErr.get());
1228
1229
if (isArchSpecifierInvalidOrMissing(Bin.get(), Arch))
1230
return make_error<CoverageMapError>(
1231
coveragemap_error::invalid_or_missing_arch_specifier);
1232
1233
// MachO universal binaries which contain archives need to be treated as
1234
// archives, not as regular binaries.
1235
if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin.get())) {
1236
for (auto &ObjForArch : Universal->objects()) {
1237
// Skip slices within the universal binary which target the wrong arch.
1238
std::string ObjArch = ObjForArch.getArchFlagName();
1239
if (Arch != ObjArch)
1240
continue;
1241
1242
auto ArchiveOrErr = ObjForArch.getAsArchive();
1243
if (!ArchiveOrErr) {
1244
// If this is not an archive, try treating it as a regular object.
1245
consumeError(ArchiveOrErr.takeError());
1246
break;
1247
}
1248
1249
return BinaryCoverageReader::create(
1250
ArchiveOrErr.get()->getMemoryBufferRef(), Arch, ObjectFileBuffers,
1251
CompilationDir, BinaryIDs);
1252
}
1253
}
1254
1255
// Load coverage out of archive members.
1256
if (auto *Ar = dyn_cast<Archive>(Bin.get())) {
1257
Error Err = Error::success();
1258
for (auto &Child : Ar->children(Err)) {
1259
Expected<MemoryBufferRef> ChildBufOrErr = Child.getMemoryBufferRef();
1260
if (!ChildBufOrErr)
1261
return ChildBufOrErr.takeError();
1262
1263
auto ChildReadersOrErr = BinaryCoverageReader::create(
1264
ChildBufOrErr.get(), Arch, ObjectFileBuffers, CompilationDir,
1265
BinaryIDs);
1266
if (!ChildReadersOrErr)
1267
return ChildReadersOrErr.takeError();
1268
for (auto &Reader : ChildReadersOrErr.get())
1269
Readers.push_back(std::move(Reader));
1270
}
1271
if (Err)
1272
return std::move(Err);
1273
1274
// Thin archives reference object files outside of the archive file, i.e.
1275
// files which reside in memory not owned by the caller. Transfer ownership
1276
// to the caller.
1277
if (Ar->isThin())
1278
for (auto &Buffer : Ar->takeThinBuffers())
1279
ObjectFileBuffers.push_back(std::move(Buffer));
1280
1281
return std::move(Readers);
1282
}
1283
1284
object::BuildIDRef BinaryID;
1285
auto ReaderOrErr = loadBinaryFormat(std::move(Bin), Arch, CompilationDir,
1286
BinaryIDs ? &BinaryID : nullptr);
1287
if (!ReaderOrErr)
1288
return ReaderOrErr.takeError();
1289
Readers.push_back(std::move(ReaderOrErr.get()));
1290
if (!BinaryID.empty())
1291
BinaryIDs->push_back(BinaryID);
1292
return std::move(Readers);
1293
}
1294
1295
Error BinaryCoverageReader::readNextRecord(CoverageMappingRecord &Record) {
1296
if (CurrentRecord >= MappingRecords.size())
1297
return make_error<CoverageMapError>(coveragemap_error::eof);
1298
1299
FunctionsFilenames.clear();
1300
Expressions.clear();
1301
MappingRegions.clear();
1302
auto &R = MappingRecords[CurrentRecord];
1303
auto F = ArrayRef(Filenames).slice(R.FilenamesBegin, R.FilenamesSize);
1304
RawCoverageMappingReader Reader(R.CoverageMapping, F, FunctionsFilenames,
1305
Expressions, MappingRegions);
1306
if (auto Err = Reader.read())
1307
return Err;
1308
1309
Record.FunctionName = R.FunctionName;
1310
Record.FunctionHash = R.FunctionHash;
1311
Record.Filenames = FunctionsFilenames;
1312
Record.Expressions = Expressions;
1313
Record.MappingRegions = MappingRegions;
1314
1315
++CurrentRecord;
1316
return Error::success();
1317
}
1318
1319