CoverageMappingReader.cpp 20 KB

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