Skip to content

Commit f8122d3

Browse files
committed
Add the ability to extract the unwind rows from DWARF Call Frame Information.
This patch adds the ability to evaluate the state machine for CIE and FDE unwind objects and produce a UnwindTable with all UnwindRow objects needed to unwind registers. It will also dump the UnwindTable for each CIE and FDE when dumping DWARF .debug_frame or .eh_frame sections in llvm-dwarfdump or llvm-objdump. This allows users to see what the unwind rows actually look like for a given CIE or FDE instead of just seeing a list of opcodes. This patch adds new classes: UnwindLocation, RegisterLocations, UnwindRow, and UnwindTable. UnwindLocation is a class that describes how to unwind a register or Call Frame Address (CFA). RegisterLocations is a class that tracks registers and their UnwindLocations. It gets populated when parsing the DWARF call frame instruction opcodes for a unwind row. The registers are mapped from their register numbers to the UnwindLocation in a map. UnwindRow contains the result of evaluating a row of DWARF call frame instructions for the CIE, or a row from a FDE. The CIE can produce a set of initial instructions that each FDE that points to that CIE will use as the seed for the state machine when parsing FDE opcodes. A UnwindRow for a CIE will not have a valid address, whille a UnwindRow for a FDE will have a valid address. The UnwindTable is a class that contains a sorted (by address) vector of UnwindRow objects and is the result of parsing all opcodes in a CIE, or FDE. Parsing a CIE should produce a UnwindTable with a single row. Parsing a FDE will produce a UnwindTable with one or more UnwindRow objects where all UnwindRow objects have valid addresses. The rows in the UnwindTable will be sorted from lowest Address to highest after parsing the state machine, or an error will be returned if the table isn't sorted. To parse a UnwindTable clients can use the following methods: static Expected<UnwindTable> UnwindTable::create(const CIE *Cie); static Expected<UnwindTable> UnwindTable::create(const FDE *Fde); A valid table will be returned if the DWARF call frame instruction opcodes have no encoding errors. There are a few things that can go wrong during the evaluation of the state machine and these create functions will catch and return them. Differential Revision: https://reviews.llvm.org/D89845
1 parent bacf9cf commit f8122d3

File tree

8 files changed

+2121
-10
lines changed

8 files changed

+2121
-10
lines changed

llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h

Lines changed: 372 additions & 1 deletion
Large diffs are not rendered by default.

llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ class DWARFExpression {
8080
friend class DWARFExpression::iterator;
8181
uint8_t Opcode; ///< The Op Opcode, DW_OP_<something>.
8282
Description Desc;
83-
bool Error;
83+
bool Error = false;
8484
uint64_t EndOffset;
8585
uint64_t Operands[2];
8686
uint64_t OperandEndOffsets[2];
@@ -157,6 +157,8 @@ class DWARFExpression {
157157

158158
bool verify(DWARFUnit *U);
159159

160+
bool operator==(const DWARFExpression &RHS) const;
161+
160162
private:
161163
DataExtractor Data;
162164
uint8_t AddressSize;

0 commit comments

Comments
 (0)