1 | //===-- DWARFExpression.h ---------------------------------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #ifndef LLDB_EXPRESSION_DWARFEXPRESSION_H |
10 | #define LLDB_EXPRESSION_DWARFEXPRESSION_H |
11 | |
12 | #include "lldb/Core/Address.h" |
13 | #include "lldb/Core/Disassembler.h" |
14 | #include "lldb/Utility/DataExtractor.h" |
15 | #include "lldb/Utility/Scalar.h" |
16 | #include "lldb/Utility/Status.h" |
17 | #include "lldb/lldb-private.h" |
18 | #include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h" |
19 | #include <functional> |
20 | |
21 | namespace lldb_private { |
22 | |
23 | namespace plugin { |
24 | namespace dwarf { |
25 | class DWARFUnit; |
26 | } // namespace dwarf |
27 | } // namespace plugin |
28 | |
29 | /// \class DWARFExpression DWARFExpression.h |
30 | /// "lldb/Expression/DWARFExpression.h" Encapsulates a DWARF location |
31 | /// expression and interprets it. |
32 | /// |
33 | /// DWARF location expressions are used in two ways by LLDB. The first |
34 | /// use is to find entities specified in the debug information, since their |
35 | /// locations are specified in precisely this language. The second is to |
36 | /// interpret expressions without having to run the target in cases where the |
37 | /// overhead from copying JIT-compiled code into the target is too high or |
38 | /// where the target cannot be run. This class encapsulates a single DWARF |
39 | /// location expression or a location list and interprets it. |
40 | class DWARFExpression { |
41 | public: |
42 | DWARFExpression(); |
43 | |
44 | /// Constructor |
45 | /// |
46 | /// \param[in] data |
47 | /// A data extractor configured to read the DWARF location expression's |
48 | /// bytecode. |
49 | (const DataExtractor &data); |
50 | |
51 | /// Destructor |
52 | ~DWARFExpression(); |
53 | |
54 | /// Return true if the location expression contains data |
55 | bool IsValid() const; |
56 | |
57 | /// Return the address specified by the first |
58 | /// DW_OP_{addr, addrx, GNU_addr_index} in the operation stream. |
59 | /// |
60 | /// \param[in] dwarf_cu |
61 | /// The dwarf unit this expression belongs to. Only required to resolve |
62 | /// DW_OP{addrx, GNU_addr_index}. |
63 | /// |
64 | /// \param[out] error |
65 | /// If the location stream contains unknown DW_OP opcodes or the |
66 | /// data is missing, \a error will be set to \b true. |
67 | /// |
68 | /// \return |
69 | /// The address specified by the operation, if the operation exists, or |
70 | /// LLDB_INVALID_ADDRESS otherwise. |
71 | lldb::addr_t GetLocation_DW_OP_addr(const plugin::dwarf::DWARFUnit *dwarf_cu, |
72 | bool &error) const; |
73 | |
74 | bool Update_DW_OP_addr(const plugin::dwarf::DWARFUnit *dwarf_cu, |
75 | lldb::addr_t file_addr); |
76 | |
77 | void UpdateValue(uint64_t const_value, lldb::offset_t const_value_byte_size, |
78 | uint8_t addr_byte_size); |
79 | |
80 | bool |
81 | ContainsThreadLocalStorage(const plugin::dwarf::DWARFUnit *dwarf_cu) const; |
82 | |
83 | bool LinkThreadLocalStorage( |
84 | const plugin::dwarf::DWARFUnit *dwarf_cu, |
85 | std::function<lldb::addr_t(lldb::addr_t file_addr)> const |
86 | &link_address_callback); |
87 | |
88 | /// Return the call-frame-info style register kind |
89 | lldb::RegisterKind GetRegisterKind() const; |
90 | |
91 | /// Set the call-frame-info style register kind |
92 | /// |
93 | /// \param[in] reg_kind |
94 | /// The register kind. |
95 | void SetRegisterKind(lldb::RegisterKind reg_kind); |
96 | |
97 | /// Evaluate a DWARF location expression in a particular context |
98 | /// |
99 | /// \param[in] exe_ctx |
100 | /// The execution context in which to evaluate the location |
101 | /// expression. The location expression may access the target's |
102 | /// memory, especially if it comes from the expression parser. |
103 | /// |
104 | /// \param[in] opcode_ctx |
105 | /// The module which defined the expression. |
106 | /// |
107 | /// \param[in] opcodes |
108 | /// This is a static method so the opcodes need to be provided |
109 | /// explicitly. |
110 | /// |
111 | /// \param[in] reg_ctx |
112 | /// An optional parameter which provides a RegisterContext for use |
113 | /// when evaluating the expression (i.e. for fetching register values). |
114 | /// Normally this will come from the ExecutionContext's StackFrame but |
115 | /// in the case where an expression needs to be evaluated while building |
116 | /// the stack frame list, this short-cut is available. |
117 | /// |
118 | /// \param[in] reg_set |
119 | /// The call-frame-info style register kind. |
120 | /// |
121 | /// \param[in] initial_value_ptr |
122 | /// A value to put on top of the interpreter stack before evaluating |
123 | /// the expression, if the expression is parametrized. Can be NULL. |
124 | /// |
125 | /// \param[in] result |
126 | /// A value into which the result of evaluating the expression is |
127 | /// to be placed. |
128 | /// |
129 | /// \param[in] error_ptr |
130 | /// If non-NULL, used to report errors in expression evaluation. |
131 | /// |
132 | /// \return |
133 | /// True on success; false otherwise. If error_ptr is non-NULL, |
134 | /// details of the failure are provided through it. |
135 | static bool (ExecutionContext *exe_ctx, RegisterContext *reg_ctx, |
136 | lldb::ModuleSP module_sp, const DataExtractor &opcodes, |
137 | const plugin::dwarf::DWARFUnit *dwarf_cu, |
138 | const lldb::RegisterKind reg_set, |
139 | const Value *initial_value_ptr, |
140 | const Value *object_address_ptr, Value &result, |
141 | Status *error_ptr); |
142 | |
143 | static bool (const plugin::dwarf::DWARFUnit *dwarf_cu, |
144 | const DataExtractor &data, |
145 | DWARFExpressionList *loc_list); |
146 | |
147 | bool (DataExtractor &data) const { |
148 | data = m_data; |
149 | return data.GetByteSize() > 0; |
150 | } |
151 | |
152 | void DumpLocation(Stream *s, lldb::DescriptionLevel level, ABI *abi) const; |
153 | |
154 | bool MatchesOperand(StackFrame &frame, const Instruction::Operand &op) const; |
155 | |
156 | private: |
157 | /// A data extractor capable of reading opcode bytes |
158 | DataExtractor m_data; |
159 | |
160 | /// One of the defines that starts with LLDB_REGKIND_ |
161 | lldb::RegisterKind m_reg_kind = lldb::eRegisterKindDWARF; |
162 | }; |
163 | |
164 | } // namespace lldb_private |
165 | |
166 | #endif // LLDB_EXPRESSION_DWARFEXPRESSION_H |
167 | |