9
9
#ifndef LLVM_DEBUGINFO_DWARF_DWARFDEBUGFRAME_H
10
10
#define LLVM_DEBUGINFO_DWARF_DWARFDEBUGFRAME_H
11
11
12
- #include " llvm/ADT/ArrayRef.h"
13
12
#include " llvm/ADT/SmallString.h"
14
13
#include " llvm/ADT/iterator.h"
15
14
#include " llvm/DebugInfo/DWARF/DWARFCFIProgram.h"
16
15
#include " llvm/DebugInfo/DWARF/DWARFExpression.h"
16
+ #include " llvm/DebugInfo/DWARF/DWARFUnwindTable.h"
17
17
#include " llvm/Support/Error.h"
18
18
#include " llvm/TargetParser/Triple.h"
19
- #include < map>
20
19
#include < memory>
21
20
#include < vector>
22
21
@@ -29,358 +28,6 @@ struct DIDumpOptions;
29
28
30
29
namespace dwarf {
31
30
32
- constexpr uint32_t InvalidRegisterNumber = UINT32_MAX;
33
-
34
- // / A class that represents a location for the Call Frame Address (CFA) or a
35
- // / register. This is decoded from the DWARF Call Frame Information
36
- // / instructions and put into an UnwindRow.
37
- class UnwindLocation {
38
- public:
39
- enum Location {
40
- // / Not specified.
41
- Unspecified,
42
- // / Register is not available and can't be recovered.
43
- Undefined,
44
- // / Register value is in the register, nothing needs to be done to unwind
45
- // / it:
46
- // / reg = reg
47
- Same,
48
- // / Register is in or at the CFA plus an offset:
49
- // / reg = CFA + offset
50
- // / reg = defef(CFA + offset)
51
- CFAPlusOffset,
52
- // / Register or CFA is in or at a register plus offset, optionally in
53
- // / an address space:
54
- // / reg = reg + offset [in addrspace]
55
- // / reg = deref(reg + offset [in addrspace])
56
- RegPlusOffset,
57
- // / Register or CFA value is in or at a value found by evaluating a DWARF
58
- // / expression:
59
- // / reg = eval(dwarf_expr)
60
- // / reg = deref(eval(dwarf_expr))
61
- DWARFExpr,
62
- // / Value is a constant value contained in "Offset":
63
- // / reg = Offset
64
- Constant,
65
- };
66
-
67
- private:
68
- Location Kind; // / The type of the location that describes how to unwind it.
69
- uint32_t RegNum; // / The register number for Kind == RegPlusOffset.
70
- int32_t Offset; // / The offset for Kind == CFAPlusOffset or RegPlusOffset.
71
- std::optional<uint32_t > AddrSpace; // / The address space for Kind ==
72
- // / RegPlusOffset for CFA.
73
- std::optional<DWARFExpression> Expr; // / The DWARF expression for Kind ==
74
- // / DWARFExpression.
75
- bool Dereference; // / If true, the resulting location must be dereferenced
76
- // / after the location value is computed.
77
-
78
- // Constructors are private to force people to use the create static
79
- // functions.
80
- UnwindLocation (Location K)
81
- : Kind(K), RegNum(InvalidRegisterNumber), Offset(0 ),
82
- AddrSpace (std::nullopt), Dereference(false ) {}
83
-
84
- UnwindLocation (Location K, uint32_t Reg, int32_t Off,
85
- std::optional<uint32_t > AS, bool Deref)
86
- : Kind(K), RegNum(Reg), Offset(Off), AddrSpace(AS), Dereference(Deref) {}
87
-
88
- UnwindLocation (DWARFExpression E, bool Deref)
89
- : Kind(DWARFExpr), RegNum(InvalidRegisterNumber), Offset(0 ), Expr(E),
90
- Dereference(Deref) {}
91
-
92
- public:
93
- // / Create a location whose rule is set to Unspecified. This means the
94
- // / register value might be in the same register but it wasn't specified in
95
- // / the unwind opcodes.
96
- static UnwindLocation createUnspecified ();
97
- // / Create a location where the value is undefined and not available. This can
98
- // / happen when a register is volatile and can't be recovered.
99
- static UnwindLocation createUndefined ();
100
- // / Create a location where the value is known to be in the register itself.
101
- static UnwindLocation createSame ();
102
- // / Create a location that is in (Deref == false) or at (Deref == true) the
103
- // / CFA plus an offset. Most registers that are spilled onto the stack use
104
- // / this rule. The rule for the register will use this rule and specify a
105
- // / unique offset from the CFA with \a Deref set to true. This value will be
106
- // / relative to a CFA value which is typically defined using the register
107
- // / plus offset location. \see createRegisterPlusOffset(...) for more
108
- // / information.
109
- static UnwindLocation createIsCFAPlusOffset (int32_t Off);
110
- static UnwindLocation createAtCFAPlusOffset (int32_t Off);
111
- // / Create a location where the saved value is in (Deref == false) or at
112
- // / (Deref == true) a regiser plus an offset and, optionally, in the specified
113
- // / address space (used mostly for the CFA).
114
- // /
115
- // / The CFA is usually defined using this rule by using the stack pointer or
116
- // / frame pointer as the register, with an offset that accounts for all
117
- // / spilled registers and all local variables in a function, and Deref ==
118
- // / false.
119
- static UnwindLocation
120
- createIsRegisterPlusOffset (uint32_t Reg, int32_t Off,
121
- std::optional<uint32_t > AddrSpace = std::nullopt);
122
- static UnwindLocation
123
- createAtRegisterPlusOffset (uint32_t Reg, int32_t Off,
124
- std::optional<uint32_t > AddrSpace = std::nullopt);
125
- // / Create a location whose value is the result of evaluating a DWARF
126
- // / expression. This allows complex expressions to be evaluated in order to
127
- // / unwind a register or CFA value.
128
- static UnwindLocation createIsDWARFExpression (DWARFExpression Expr);
129
- static UnwindLocation createAtDWARFExpression (DWARFExpression Expr);
130
- static UnwindLocation createIsConstant (int32_t Value);
131
-
132
- Location getLocation () const { return Kind; }
133
- uint32_t getRegister () const { return RegNum; }
134
- int32_t getOffset () const { return Offset; }
135
- uint32_t getAddressSpace () const {
136
- assert (Kind == RegPlusOffset && AddrSpace);
137
- return *AddrSpace;
138
- }
139
- int32_t getConstant () const { return Offset; }
140
- // / Some opcodes will modify the CFA location's register only, so we need
141
- // / to be able to modify the CFA register when evaluating DWARF Call Frame
142
- // / Information opcodes.
143
- void setRegister (uint32_t NewRegNum) { RegNum = NewRegNum; }
144
- // / Some opcodes will modify the CFA location's offset only, so we need
145
- // / to be able to modify the CFA offset when evaluating DWARF Call Frame
146
- // / Information opcodes.
147
- void setOffset (int32_t NewOffset) { Offset = NewOffset; }
148
- // / Some opcodes modify a constant value and we need to be able to update
149
- // / the constant value (DW_CFA_GNU_window_save which is also known as
150
- // DW_CFA_AARCH64_negate_ra_state).
151
- void setConstant (int32_t Value) { Offset = Value; }
152
-
153
- std::optional<DWARFExpression> getDWARFExpressionBytes () const {
154
- return Expr;
155
- }
156
- // / Dump a location expression as text and use the register information if
157
- // / some is provided.
158
- // /
159
- // / \param OS the stream to use for output.
160
- // /
161
- // / \param MRI register information that helps emit register names insteead
162
- // / of raw register numbers.
163
- // /
164
- // / \param IsEH true if the DWARF Call Frame Information is from .eh_frame
165
- // / instead of from .debug_frame. This is needed for register number
166
- // / conversion because some register numbers differ between the two sections
167
- // / for certain architectures like x86.
168
- void dump (raw_ostream &OS, DIDumpOptions DumpOpts) const ;
169
-
170
- bool operator ==(const UnwindLocation &RHS) const ;
171
- };
172
-
173
- raw_ostream &operator <<(raw_ostream &OS, const UnwindLocation &R);
174
-
175
- // / A class that can track all registers with locations in a UnwindRow object.
176
- // /
177
- // / Register locations use a map where the key is the register number and the
178
- // / the value is a UnwindLocation.
179
- // /
180
- // / The register maps are put into a class so that all register locations can
181
- // / be copied when parsing the unwind opcodes DW_CFA_remember_state and
182
- // / DW_CFA_restore_state.
183
- class RegisterLocations {
184
- std::map<uint32_t , UnwindLocation> Locations;
185
-
186
- public:
187
- // / Return the location for the register in \a RegNum if there is a location.
188
- // /
189
- // / \param RegNum the register number to find a location for.
190
- // /
191
- // / \returns A location if one is available for \a RegNum, or std::nullopt
192
- // / otherwise.
193
- std::optional<UnwindLocation> getRegisterLocation (uint32_t RegNum) const {
194
- auto Pos = Locations.find (RegNum);
195
- if (Pos == Locations.end ())
196
- return std::nullopt;
197
- return Pos->second ;
198
- }
199
-
200
- // / Set the location for the register in \a RegNum to \a Location.
201
- // /
202
- // / \param RegNum the register number to set the location for.
203
- // /
204
- // / \param Location the UnwindLocation that describes how to unwind the value.
205
- void setRegisterLocation (uint32_t RegNum, const UnwindLocation &Location) {
206
- Locations.erase (RegNum);
207
- Locations.insert (std::make_pair (RegNum, Location));
208
- }
209
-
210
- // / Removes any rule for the register in \a RegNum.
211
- // /
212
- // / \param RegNum the register number to remove the location for.
213
- void removeRegisterLocation (uint32_t RegNum) { Locations.erase (RegNum); }
214
-
215
- // / Dump all registers + locations that are currently defined in this object.
216
- // /
217
- // / \param OS the stream to use for output.
218
- // /
219
- // / \param MRI register information that helps emit register names insteead
220
- // / of raw register numbers.
221
- // /
222
- // / \param IsEH true if the DWARF Call Frame Information is from .eh_frame
223
- // / instead of from .debug_frame. This is needed for register number
224
- // / conversion because some register numbers differ between the two sections
225
- // / for certain architectures like x86.
226
- void dump (raw_ostream &OS, DIDumpOptions DumpOpts) const ;
227
-
228
- // / Returns true if we have any register locations in this object.
229
- bool hasLocations () const { return !Locations.empty (); }
230
-
231
- size_t size () const { return Locations.size (); }
232
-
233
- bool operator ==(const RegisterLocations &RHS) const {
234
- return Locations == RHS.Locations ;
235
- }
236
- };
237
-
238
- raw_ostream &operator <<(raw_ostream &OS, const RegisterLocations &RL);
239
-
240
- // / A class that represents a single row in the unwind table that is decoded by
241
- // / parsing the DWARF Call Frame Information opcodes.
242
- // /
243
- // / The row consists of an optional address, the rule to unwind the CFA and all
244
- // / rules to unwind any registers. If the address doesn't have a value, this
245
- // / row represents the initial instructions for a CIE. If the address has a
246
- // / value the UnwindRow represents a row in the UnwindTable for a FDE. The
247
- // / address is the first address for which the CFA location and register rules
248
- // / are valid within a function.
249
- // /
250
- // / UnwindRow objects are created by parsing opcodes in the DWARF Call Frame
251
- // / Information and UnwindRow objects are lazily populated and pushed onto a
252
- // / stack in the UnwindTable when evaluating this state machine. Accessors are
253
- // / needed for the address, CFA value, and register locations as the opcodes
254
- // / encode a state machine that produces a sorted array of UnwindRow objects
255
- // / \see UnwindTable.
256
- class UnwindRow {
257
- // / The address will be valid when parsing the instructions in a FDE. If
258
- // / invalid, this object represents the initial instructions of a CIE.
259
- std::optional<uint64_t > Address; // /< Address for row in FDE, invalid for CIE.
260
- UnwindLocation CFAValue; // /< How to unwind the Call Frame Address (CFA).
261
- RegisterLocations RegLocs; // /< How to unwind all registers in this list.
262
-
263
- public:
264
- UnwindRow () : CFAValue(UnwindLocation::createUnspecified()) {}
265
-
266
- // / Returns true if the address is valid in this object.
267
- bool hasAddress () const { return Address.has_value (); }
268
-
269
- // / Get the address for this row.
270
- // /
271
- // / Clients should only call this function after verifying it has a valid
272
- // / address with a call to \see hasAddress().
273
- uint64_t getAddress () const { return *Address; }
274
-
275
- // / Set the address for this UnwindRow.
276
- // /
277
- // / The address represents the first address for which the CFAValue and
278
- // / RegLocs are valid within a function.
279
- void setAddress (uint64_t Addr) { Address = Addr; }
280
-
281
- // / Offset the address for this UnwindRow.
282
- // /
283
- // / The address represents the first address for which the CFAValue and
284
- // / RegLocs are valid within a function. Clients must ensure that this object
285
- // / already has an address (\see hasAddress()) prior to calling this
286
- // / function.
287
- void slideAddress (uint64_t Offset) { *Address += Offset; }
288
- UnwindLocation &getCFAValue () { return CFAValue; }
289
- const UnwindLocation &getCFAValue () const { return CFAValue; }
290
- RegisterLocations &getRegisterLocations () { return RegLocs; }
291
- const RegisterLocations &getRegisterLocations () const { return RegLocs; }
292
-
293
- // / Dump the UnwindRow to the stream.
294
- // /
295
- // / \param OS the stream to use for output.
296
- // /
297
- // / \param MRI register information that helps emit register names insteead
298
- // / of raw register numbers.
299
- // /
300
- // / \param IsEH true if the DWARF Call Frame Information is from .eh_frame
301
- // / instead of from .debug_frame. This is needed for register number
302
- // / conversion because some register numbers differ between the two sections
303
- // / for certain architectures like x86.
304
- // /
305
- // / \param IndentLevel specify the indent level as an integer. The UnwindRow
306
- // / will be output to the stream preceded by 2 * IndentLevel number of spaces.
307
- void dump (raw_ostream &OS, DIDumpOptions DumpOpts,
308
- unsigned IndentLevel = 0 ) const ;
309
- };
310
-
311
- raw_ostream &operator <<(raw_ostream &OS, const UnwindRow &Row);
312
-
313
- // / A class that contains all UnwindRow objects for an FDE or a single unwind
314
- // / row for a CIE. To unwind an address the rows, which are sorted by start
315
- // / address, can be searched to find the UnwindRow with the lowest starting
316
- // / address that is greater than or equal to the address that is being looked
317
- // / up.
318
- class UnwindTable {
319
- public:
320
- using RowContainer = std::vector<UnwindRow>;
321
- using iterator = RowContainer::iterator;
322
- using const_iterator = RowContainer::const_iterator;
323
-
324
- size_t size () const { return Rows.size (); }
325
- iterator begin () { return Rows.begin (); }
326
- const_iterator begin () const { return Rows.begin (); }
327
- iterator end () { return Rows.end (); }
328
- const_iterator end () const { return Rows.end (); }
329
- const UnwindRow &operator [](size_t Index) const {
330
- assert (Index < size ());
331
- return Rows[Index];
332
- }
333
- void insertRow (const UnwindRow &Row) { Rows.push_back (Row); }
334
-
335
- // / Set the last address that this unwinding table refers to.
336
- // /
337
- // / This is used when this table is created based on a FDE.
338
- void setEndAddress (uint64_t Addr) { EndAddress = Addr; }
339
-
340
- // / Dump the UnwindTable to the stream.
341
- // /
342
- // / \param OS the stream to use for output.
343
- // /
344
- // / \param MRI register information that helps emit register names insteead
345
- // / of raw register numbers.
346
- // /
347
- // / \param IsEH true if the DWARF Call Frame Information is from .eh_frame
348
- // / instead of from .debug_frame. This is needed for register number
349
- // / conversion because some register numbers differ between the two sections
350
- // / for certain architectures like x86.
351
- // /
352
- // / \param IndentLevel specify the indent level as an integer. The UnwindRow
353
- // / will be output to the stream preceded by 2 * IndentLevel number of spaces.
354
- void dump (raw_ostream &OS, DIDumpOptions DumpOpts,
355
- unsigned IndentLevel = 0 ) const ;
356
-
357
- // / Parse the information in the CFIProgram and update the CurrRow object
358
- // / that the state machine describes.
359
- // /
360
- // / This is an internal implementation that emulates the state machine
361
- // / described in the DWARF Call Frame Information opcodes and will push
362
- // / CurrRow onto the Rows container when needed.
363
- // /
364
- // / \param CFIP the CFI program that contains the opcodes from a CIE or FDE.
365
- // /
366
- // / \param CurrRow the current row to modify while parsing the state machine.
367
- // /
368
- // / \param InitialLocs If non-NULL, we are parsing a FDE and this contains
369
- // / the initial register locations from the CIE. If NULL, then a CIE's
370
- // / opcodes are being parsed and this is not needed. This is used for the
371
- // / DW_CFA_restore and DW_CFA_restore_extended opcodes.
372
- Error parseRows (const CFIProgram &CFIP, UnwindRow &CurrRow,
373
- const RegisterLocations *InitialLocs);
374
-
375
- private:
376
- RowContainer Rows;
377
- // / The end address when data is extracted from a FDE. This value will be
378
- // / invalid when a UnwindTable is extracted from a CIE.
379
- std::optional<uint64_t > EndAddress;
380
- };
381
-
382
- raw_ostream &operator <<(raw_ostream &OS, const UnwindTable &Rows);
383
-
384
31
class CIE ;
385
32
386
33
// / Create an UnwindTable from a Common Information Entry (CIE).
0 commit comments