1321369Sdim//===- CoverageMappingReader.h - Code coverage mapping reader ---*- C++ -*-===//
2303231Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6303231Sdim//
7303231Sdim//===----------------------------------------------------------------------===//
8303231Sdim//
9303231Sdim// This file contains support for reading coverage mapping data for
10303231Sdim// instrumentation based coverage.
11303231Sdim//
12303231Sdim//===----------------------------------------------------------------------===//
13303231Sdim
14321369Sdim#ifndef LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPINGREADER_H
15321369Sdim#define LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPINGREADER_H
16303231Sdim
17303231Sdim#include "llvm/ADT/ArrayRef.h"
18303231Sdim#include "llvm/ADT/StringRef.h"
19303231Sdim#include "llvm/ProfileData/Coverage/CoverageMapping.h"
20303231Sdim#include "llvm/ProfileData/InstrProf.h"
21321369Sdim#include "llvm/Support/Error.h"
22303231Sdim#include "llvm/Support/MemoryBuffer.h"
23321369Sdim#include <cstddef>
24321369Sdim#include <cstdint>
25303231Sdim#include <iterator>
26321369Sdim#include <memory>
27321369Sdim#include <vector>
28303231Sdim
29303231Sdimnamespace llvm {
30303231Sdimnamespace coverage {
31303231Sdim
32303231Sdimclass CoverageMappingReader;
33303231Sdim
34341825Sdim/// Coverage mapping information for a single function.
35303231Sdimstruct CoverageMappingRecord {
36303231Sdim  StringRef FunctionName;
37303231Sdim  uint64_t FunctionHash;
38303231Sdim  ArrayRef<StringRef> Filenames;
39303231Sdim  ArrayRef<CounterExpression> Expressions;
40303231Sdim  ArrayRef<CounterMappingRegion> MappingRegions;
41303231Sdim};
42303231Sdim
43341825Sdim/// A file format agnostic iterator over coverage mapping data.
44303231Sdimclass CoverageMappingIterator
45303231Sdim    : public std::iterator<std::input_iterator_tag, CoverageMappingRecord> {
46327952Sdim  CoverageMappingReader *Reader;
47303231Sdim  CoverageMappingRecord Record;
48327952Sdim  coveragemap_error ReadErr;
49303231Sdim
50303231Sdim  void increment();
51303231Sdim
52303231Sdimpublic:
53327952Sdim  CoverageMappingIterator()
54327952Sdim      : Reader(nullptr), Record(), ReadErr(coveragemap_error::success) {}
55321369Sdim
56327952Sdim  CoverageMappingIterator(CoverageMappingReader *Reader)
57327952Sdim      : Reader(Reader), Record(), ReadErr(coveragemap_error::success) {
58303231Sdim    increment();
59303231Sdim  }
60303231Sdim
61327952Sdim  ~CoverageMappingIterator() {
62327952Sdim    if (ReadErr != coveragemap_error::success)
63327952Sdim      llvm_unreachable("Unexpected error in coverage mapping iterator");
64327952Sdim  }
65327952Sdim
66303231Sdim  CoverageMappingIterator &operator++() {
67303231Sdim    increment();
68303231Sdim    return *this;
69303231Sdim  }
70303231Sdim  bool operator==(const CoverageMappingIterator &RHS) {
71303231Sdim    return Reader == RHS.Reader;
72303231Sdim  }
73303231Sdim  bool operator!=(const CoverageMappingIterator &RHS) {
74303231Sdim    return Reader != RHS.Reader;
75303231Sdim  }
76327952Sdim  Expected<CoverageMappingRecord &> operator*() {
77327952Sdim    if (ReadErr != coveragemap_error::success) {
78327952Sdim      auto E = make_error<CoverageMapError>(ReadErr);
79327952Sdim      ReadErr = coveragemap_error::success;
80327952Sdim      return std::move(E);
81327952Sdim    }
82327952Sdim    return Record;
83327952Sdim  }
84327952Sdim  Expected<CoverageMappingRecord *> operator->() {
85327952Sdim    if (ReadErr != coveragemap_error::success) {
86327952Sdim      auto E = make_error<CoverageMapError>(ReadErr);
87327952Sdim      ReadErr = coveragemap_error::success;
88327952Sdim      return std::move(E);
89327952Sdim    }
90327952Sdim    return &Record;
91327952Sdim  }
92303231Sdim};
93303231Sdim
94303231Sdimclass CoverageMappingReader {
95303231Sdimpublic:
96321369Sdim  virtual ~CoverageMappingReader() = default;
97321369Sdim
98303231Sdim  virtual Error readNextRecord(CoverageMappingRecord &Record) = 0;
99303231Sdim  CoverageMappingIterator begin() { return CoverageMappingIterator(this); }
100303231Sdim  CoverageMappingIterator end() { return CoverageMappingIterator(); }
101303231Sdim};
102303231Sdim
103341825Sdim/// Base class for the raw coverage mapping and filenames data readers.
104303231Sdimclass RawCoverageReader {
105303231Sdimprotected:
106303231Sdim  StringRef Data;
107303231Sdim
108303231Sdim  RawCoverageReader(StringRef Data) : Data(Data) {}
109303231Sdim
110303231Sdim  Error readULEB128(uint64_t &Result);
111303231Sdim  Error readIntMax(uint64_t &Result, uint64_t MaxPlus1);
112303231Sdim  Error readSize(uint64_t &Result);
113303231Sdim  Error readString(StringRef &Result);
114303231Sdim};
115303231Sdim
116341825Sdim/// Reader for the raw coverage filenames.
117303231Sdimclass RawCoverageFilenamesReader : public RawCoverageReader {
118303231Sdim  std::vector<StringRef> &Filenames;
119303231Sdim
120321369Sdimpublic:
121321369Sdim  RawCoverageFilenamesReader(StringRef Data, std::vector<StringRef> &Filenames)
122321369Sdim      : RawCoverageReader(Data), Filenames(Filenames) {}
123303231Sdim  RawCoverageFilenamesReader(const RawCoverageFilenamesReader &) = delete;
124303231Sdim  RawCoverageFilenamesReader &
125303231Sdim  operator=(const RawCoverageFilenamesReader &) = delete;
126303231Sdim
127303231Sdim  Error read();
128303231Sdim};
129303231Sdim
130341825Sdim/// Checks if the given coverage mapping data is exported for
131303231Sdim/// an unused function.
132303231Sdimclass RawCoverageMappingDummyChecker : public RawCoverageReader {
133303231Sdimpublic:
134303231Sdim  RawCoverageMappingDummyChecker(StringRef MappingData)
135303231Sdim      : RawCoverageReader(MappingData) {}
136303231Sdim
137303231Sdim  Expected<bool> isDummy();
138303231Sdim};
139303231Sdim
140341825Sdim/// Reader for the raw coverage mapping data.
141303231Sdimclass RawCoverageMappingReader : public RawCoverageReader {
142303231Sdim  ArrayRef<StringRef> TranslationUnitFilenames;
143303231Sdim  std::vector<StringRef> &Filenames;
144303231Sdim  std::vector<CounterExpression> &Expressions;
145303231Sdim  std::vector<CounterMappingRegion> &MappingRegions;
146303231Sdim
147303231Sdimpublic:
148303231Sdim  RawCoverageMappingReader(StringRef MappingData,
149303231Sdim                           ArrayRef<StringRef> TranslationUnitFilenames,
150303231Sdim                           std::vector<StringRef> &Filenames,
151303231Sdim                           std::vector<CounterExpression> &Expressions,
152303231Sdim                           std::vector<CounterMappingRegion> &MappingRegions)
153303231Sdim      : RawCoverageReader(MappingData),
154303231Sdim        TranslationUnitFilenames(TranslationUnitFilenames),
155303231Sdim        Filenames(Filenames), Expressions(Expressions),
156303231Sdim        MappingRegions(MappingRegions) {}
157321369Sdim  RawCoverageMappingReader(const RawCoverageMappingReader &) = delete;
158321369Sdim  RawCoverageMappingReader &
159321369Sdim  operator=(const RawCoverageMappingReader &) = delete;
160303231Sdim
161303231Sdim  Error read();
162303231Sdim
163303231Sdimprivate:
164303231Sdim  Error decodeCounter(unsigned Value, Counter &C);
165303231Sdim  Error readCounter(Counter &C);
166303231Sdim  Error
167303231Sdim  readMappingRegionsSubArray(std::vector<CounterMappingRegion> &MappingRegions,
168303231Sdim                             unsigned InferredFileID, size_t NumFileIDs);
169303231Sdim};
170303231Sdim
171341825Sdim/// Reader for the coverage mapping data that is emitted by the
172303231Sdim/// frontend and stored in an object file.
173303231Sdimclass BinaryCoverageReader : public CoverageMappingReader {
174303231Sdimpublic:
175303231Sdim  struct ProfileMappingRecord {
176303231Sdim    CovMapVersion Version;
177303231Sdim    StringRef FunctionName;
178303231Sdim    uint64_t FunctionHash;
179303231Sdim    StringRef CoverageMapping;
180303231Sdim    size_t FilenamesBegin;
181303231Sdim    size_t FilenamesSize;
182303231Sdim
183303231Sdim    ProfileMappingRecord(CovMapVersion Version, StringRef FunctionName,
184303231Sdim                         uint64_t FunctionHash, StringRef CoverageMapping,
185303231Sdim                         size_t FilenamesBegin, size_t FilenamesSize)
186303231Sdim        : Version(Version), FunctionName(FunctionName),
187303231Sdim          FunctionHash(FunctionHash), CoverageMapping(CoverageMapping),
188303231Sdim          FilenamesBegin(FilenamesBegin), FilenamesSize(FilenamesSize) {}
189303231Sdim  };
190303231Sdim
191303231Sdimprivate:
192303231Sdim  std::vector<StringRef> Filenames;
193303231Sdim  std::vector<ProfileMappingRecord> MappingRecords;
194303231Sdim  InstrProfSymtab ProfileNames;
195321369Sdim  size_t CurrentRecord = 0;
196303231Sdim  std::vector<StringRef> FunctionsFilenames;
197303231Sdim  std::vector<CounterExpression> Expressions;
198303231Sdim  std::vector<CounterMappingRegion> MappingRegions;
199303231Sdim
200321369Sdim  BinaryCoverageReader() = default;
201321369Sdim
202321369Sdimpublic:
203303231Sdim  BinaryCoverageReader(const BinaryCoverageReader &) = delete;
204303231Sdim  BinaryCoverageReader &operator=(const BinaryCoverageReader &) = delete;
205303231Sdim
206353358Sdim  static Expected<std::vector<std::unique_ptr<BinaryCoverageReader>>>
207353358Sdim  create(MemoryBufferRef ObjectBuffer, StringRef Arch,
208353358Sdim         SmallVectorImpl<std::unique_ptr<MemoryBuffer>> &ObjectFileBuffers);
209353358Sdim
210303231Sdim  static Expected<std::unique_ptr<BinaryCoverageReader>>
211353358Sdim  createCoverageReaderFromBuffer(StringRef Coverage,
212353358Sdim                                 InstrProfSymtab &&ProfileNames,
213353358Sdim                                 uint8_t BytesInAddress,
214353358Sdim                                 support::endianness Endian);
215303231Sdim
216303231Sdim  Error readNextRecord(CoverageMappingRecord &Record) override;
217303231Sdim};
218303231Sdim
219303231Sdim} // end namespace coverage
220303231Sdim} // end namespace llvm
221303231Sdim
222321369Sdim#endif // LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPINGREADER_H
223