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