Coverage Report

Created: 2025-11-11 06:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/keystone/llvm/include/llvm/MC/MCCodeView.h
Line
Count
Source
1
//===- MCCodeView.h - Machine Code CodeView support -------------*- 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
// Holds state from .cv_file and .cv_loc directives for later emission.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#ifndef LLVM_MC_MCCODEVIEW_H
15
#define LLVM_MC_MCCODEVIEW_H
16
17
#include "llvm/ADT/StringRef.h"
18
#include "llvm/ADT/StringMap.h"
19
#include "llvm/MC/MCObjectStreamer.h"
20
#include "llvm/MC/MCFragment.h"
21
#include <map>
22
#include <vector>
23
24
namespace llvm_ks {
25
class MCContext;
26
class MCObjectStreamer;
27
class MCStreamer;
28
29
/// \brief Instances of this class represent the information from a
30
/// .cv_loc directive.
31
class MCCVLoc {
32
  uint32_t FunctionId;
33
  uint32_t FileNum;
34
  uint32_t Line;
35
  uint16_t Column;
36
  uint16_t PrologueEnd : 1;
37
  uint16_t IsStmt : 1;
38
39
private: // MCContext manages these
40
  friend class MCContext;
41
  MCCVLoc(unsigned functionid, unsigned fileNum, unsigned line, unsigned column,
42
          bool prologueend, bool isstmt)
43
129k
      : FunctionId(functionid), FileNum(fileNum), Line(line), Column(column),
44
129k
        PrologueEnd(prologueend), IsStmt(isstmt) {}
45
46
  // Allow the default copy constructor and assignment operator to be used
47
  // for an MCCVLoc object.
48
49
public:
50
0
  unsigned getFunctionId() const { return FunctionId; }
51
52
  /// \brief Get the FileNum of this MCCVLoc.
53
0
  unsigned getFileNum() const { return FileNum; }
54
55
  /// \brief Get the Line of this MCCVLoc.
56
0
  unsigned getLine() const { return Line; }
57
58
  /// \brief Get the Column of this MCCVLoc.
59
0
  unsigned getColumn() const { return Column; }
60
61
0
  bool isPrologueEnd() const { return PrologueEnd; }
62
0
  bool isStmt() const { return IsStmt; }
63
64
0
  void setFunctionId(unsigned FID) { FunctionId = FID; }
65
66
  /// \brief Set the FileNum of this MCCVLoc.
67
0
  void setFileNum(unsigned fileNum) { FileNum = fileNum; }
68
69
  /// \brief Set the Line of this MCCVLoc.
70
0
  void setLine(unsigned line) { Line = line; }
71
72
  /// \brief Set the Column of this MCCVLoc.
73
0
  void setColumn(unsigned column) {
74
0
    assert(column <= UINT16_MAX);
75
0
    Column = column;
76
0
  }
77
78
0
  void setPrologueEnd(bool PE) { PrologueEnd = PE; }
79
0
  void setIsStmt(bool IS) { IsStmt = IS; }
80
};
81
82
/// \brief Instances of this class represent the line information for
83
/// the CodeView line table entries.  Which is created after a machine
84
/// instruction is assembled and uses an address from a temporary label
85
/// created at the current address in the current section and the info from
86
/// the last .cv_loc directive seen as stored in the context.
87
class MCCVLineEntry : public MCCVLoc {
88
  MCSymbol *Label;
89
90
private:
91
  // Allow the default copy constructor and assignment operator to be used
92
  // for an MCCVLineEntry object.
93
94
public:
95
  // Constructor to create an MCCVLineEntry given a symbol and the dwarf loc.
96
  MCCVLineEntry(MCSymbol *label, const MCCVLoc loc)
97
0
      : MCCVLoc(loc), Label(label) {}
98
99
0
  MCSymbol *getLabel() const { return Label; }
100
101
  // This is called when an instruction is assembled into the specified
102
  // section and if there is information from the last .cv_loc directive that
103
  // has yet to have a line entry made for it is made.
104
  static void Make(MCObjectStreamer *MCOS);
105
};
106
107
/// Holds state from .cv_file and .cv_loc directives for later emission.
108
class CodeViewContext {
109
public:
110
  CodeViewContext();
111
  ~CodeViewContext();
112
113
  bool isValidFileNumber(unsigned FileNumber) const;
114
  bool addFile(unsigned FileNumber, StringRef Filename);
115
0
  ArrayRef<StringRef> getFilenames() { return Filenames; }
116
117
  /// \brief Add a line entry.
118
0
  void addLineEntry(const MCCVLineEntry &LineEntry) {
119
0
    size_t Offset = MCCVLines.size();
120
0
    auto I =
121
0
        MCCVLineStartStop.insert({LineEntry.getFunctionId(), {Offset, Offset}});
122
0
    if (!I.second)
123
0
      I.first->second.second = Offset;
124
0
    MCCVLines.push_back(LineEntry);
125
0
  }
126
127
0
  std::vector<MCCVLineEntry> getFunctionLineEntries(unsigned FuncId) {
128
0
    std::vector<MCCVLineEntry> FilteredLines;
129
0
130
0
    auto I = MCCVLineStartStop.find(FuncId);
131
0
    if (I != MCCVLineStartStop.end())
132
0
      for (size_t Idx = I->second.first, End = I->second.second + 1; Idx != End;
133
0
           ++Idx)
134
0
        if (MCCVLines[Idx].getFunctionId() == FuncId)
135
0
          FilteredLines.push_back(MCCVLines[Idx]);
136
0
    return FilteredLines;
137
0
  }
138
139
  /// Emits a line table substream.
140
  void emitLineTableForFunction(MCObjectStreamer &OS, unsigned FuncId,
141
                                const MCSymbol *FuncBegin,
142
                                const MCSymbol *FuncEnd);
143
144
  void emitInlineLineTableForFunction(MCObjectStreamer &OS,
145
                                      unsigned PrimaryFunctionId,
146
                                      unsigned SourceFileId,
147
                                      unsigned SourceLineNum,
148
                                      ArrayRef<unsigned> SecondaryFunctionIds);
149
150
  /// Emits the string table substream.
151
  void emitStringTable(MCObjectStreamer &OS);
152
153
  /// Emits the file checksum substream.
154
  void emitFileChecksums(MCObjectStreamer &OS);
155
156
private:
157
  /// Map from string to string table offset.
158
  StringMap<unsigned> StringTable;
159
160
  /// The fragment that ultimately holds our strings.
161
  MCDataFragment *StrTabFragment = nullptr;
162
  bool InsertedStrTabFragment = false;
163
164
  MCDataFragment *getStringTableFragment();
165
166
  /// Add something to the string table.
167
  StringRef addToStringTable(StringRef S);
168
169
  /// Get a string table offset.
170
  unsigned getStringTableOffset(StringRef S);
171
172
  /// An array of absolute paths. Eventually this may include the file checksum.
173
  SmallVector<StringRef, 4> Filenames;
174
175
  /// The offset of the first and last .cv_loc directive for a given function
176
  /// id.
177
  std::map<unsigned, std::pair<size_t, size_t>> MCCVLineStartStop;
178
179
  /// A collection of MCCVLineEntry for each section.
180
  std::vector<MCCVLineEntry> MCCVLines;
181
};
182
183
} // end namespace llvm_ks
184
#endif