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 <functional>
19
20class DWARFUnit;
21
22namespace lldb_private {
23
24/// \class DWARFExpression DWARFExpression.h
25/// "lldb/Expression/DWARFExpression.h" Encapsulates a DWARF location
26/// expression and interprets it.
27///
28/// DWARF location expressions are used in two ways by LLDB. The first
29/// use is to find entities specified in the debug information, since their
30/// locations are specified in precisely this language. The second is to
31/// interpret expressions without having to run the target in cases where the
32/// overhead from copying JIT-compiled code into the target is too high or
33/// where the target cannot be run. This class encapsulates a single DWARF
34/// location expression or a location list and interprets it.
35class DWARFExpression {
36public:
37 DWARFExpression();
38
39 /// Constructor
40 ///
41 /// \param[in] data
42 /// A data extractor configured to read the DWARF location expression's
43 /// bytecode.
44 DWARFExpression(lldb::ModuleSP module, const DataExtractor &data,
45 const DWARFUnit *dwarf_cu);
46
47 /// Destructor
48 virtual ~DWARFExpression();
49
50 /// Print the description of the expression to a stream
51 ///
52 /// \param[in] s
53 /// The stream to print to.
54 ///
55 /// \param[in] level
56 /// The level of verbosity to use.
57 ///
58 /// \param[in] location_list_base_addr
59 /// If this is a location list based expression, this is the
60 /// address of the object that owns it. NOTE: this value is
61 /// different from the DWARF version of the location list base
62 /// address which is compile unit relative. This base address
63 /// is the address of the object that owns the location list.
64 ///
65 /// \param[in] abi
66 /// An optional ABI plug-in that can be used to resolve register
67 /// names.
68 void GetDescription(Stream *s, lldb::DescriptionLevel level,
69 lldb::addr_t location_list_base_addr, ABI *abi) const;
70
71 /// Return true if the location expression contains data
72 bool IsValid() const;
73
74 /// Return true if a location list was provided
75 bool IsLocationList() const;
76
77 /// Search for a load address in the location list
78 ///
79 /// \param[in] func_load_addr
80 /// The actual address of the function containing this location list.
81 ///
82 /// \param[in] addr
83 /// The address to resolve
84 ///
85 /// \return
86 /// True if IsLocationList() is true and the address was found;
87 /// false otherwise.
88 // bool
89 // LocationListContainsLoadAddress (Process* process, const Address &addr)
90 // const;
91 //
92 bool LocationListContainsAddress(lldb::addr_t func_load_addr,
93 lldb::addr_t addr) const;
94
95 /// If a location is not a location list, return true if the location
96 /// contains a DW_OP_addr () opcode in the stream that matches \a file_addr.
97 /// If file_addr is LLDB_INVALID_ADDRESS, the this function will return true
98 /// if the variable there is any DW_OP_addr in a location that (yet still is
99 /// NOT a location list). This helps us detect if a variable is a global or
100 /// static variable since there is no other indication from DWARF debug
101 /// info.
102 ///
103 /// \param[in] op_addr_idx
104 /// The DW_OP_addr index to retrieve in case there is more than
105 /// one DW_OP_addr opcode in the location byte stream.
106 ///
107 /// \param[out] error
108 /// If the location stream contains unknown DW_OP opcodes or the
109 /// data is missing, \a error will be set to \b true.
110 ///
111 /// \return
112 /// LLDB_INVALID_ADDRESS if the location doesn't contain a
113 /// DW_OP_addr for \a op_addr_idx, otherwise a valid file address
114 lldb::addr_t GetLocation_DW_OP_addr(uint32_t op_addr_idx, bool &error) const;
115
116 bool Update_DW_OP_addr(lldb::addr_t file_addr);
117
118 void UpdateValue(uint64_t const_value, lldb::offset_t const_value_byte_size,
119 uint8_t addr_byte_size);
120
121 void SetModule(const lldb::ModuleSP &module) { m_module_wp = module; }
122
123 bool ContainsThreadLocalStorage() const;
124
125 bool LinkThreadLocalStorage(
126 lldb::ModuleSP new_module_sp,
127 std::function<lldb::addr_t(lldb::addr_t file_addr)> const
128 &link_address_callback);
129
130 /// Tells the expression that it refers to a location list.
131 ///
132 /// \param[in] cu_file_addr
133 /// The base address to use for interpreting relative location list
134 /// entries.
135 /// \param[in] func_file_addr
136 /// The file address of the function containing this location list. This
137 /// address will be used to relocate the location list on the fly (in
138 /// conjuction with the func_load_addr arguments).
139 void SetLocationListAddresses(lldb::addr_t cu_file_addr,
140 lldb::addr_t func_file_addr);
141
142 /// Return the call-frame-info style register kind
143 int GetRegisterKind();
144
145 /// Set the call-frame-info style register kind
146 ///
147 /// \param[in] reg_kind
148 /// The register kind.
149 void SetRegisterKind(lldb::RegisterKind reg_kind);
150
151 /// Wrapper for the static evaluate function that accepts an
152 /// ExecutionContextScope instead of an ExecutionContext and uses member
153 /// variables to populate many operands
154 bool Evaluate(ExecutionContextScope *exe_scope, lldb::addr_t func_load_addr,
155 const Value *initial_value_ptr, const Value *object_address_ptr,
156 Value &result, Status *error_ptr) const;
157
158 /// Wrapper for the static evaluate function that uses member variables to
159 /// populate many operands
160 bool Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
161 lldb::addr_t loclist_base_load_addr,
162 const Value *initial_value_ptr, const Value *object_address_ptr,
163 Value &result, Status *error_ptr) const;
164
165 /// Evaluate a DWARF location expression in a particular context
166 ///
167 /// \param[in] exe_ctx
168 /// The execution context in which to evaluate the location
169 /// expression. The location expression may access the target's
170 /// memory, especially if it comes from the expression parser.
171 ///
172 /// \param[in] opcode_ctx
173 /// The module which defined the expression.
174 ///
175 /// \param[in] opcodes
176 /// This is a static method so the opcodes need to be provided
177 /// explicitly.
178 ///
179 /// \param[in] reg_ctx
180 /// An optional parameter which provides a RegisterContext for use
181 /// when evaluating the expression (i.e. for fetching register values).
182 /// Normally this will come from the ExecutionContext's StackFrame but
183 /// in the case where an expression needs to be evaluated while building
184 /// the stack frame list, this short-cut is available.
185 ///
186 /// \param[in] reg_set
187 /// The call-frame-info style register kind.
188 ///
189 /// \param[in] initial_value_ptr
190 /// A value to put on top of the interpreter stack before evaluating
191 /// the expression, if the expression is parametrized. Can be NULL.
192 ///
193 /// \param[in] result
194 /// A value into which the result of evaluating the expression is
195 /// to be placed.
196 ///
197 /// \param[in] error_ptr
198 /// If non-NULL, used to report errors in expression evaluation.
199 ///
200 /// \return
201 /// True on success; false otherwise. If error_ptr is non-NULL,
202 /// details of the failure are provided through it.
203 static bool Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
204 lldb::ModuleSP opcode_ctx, const DataExtractor &opcodes,
205 const DWARFUnit *dwarf_cu,
206 const lldb::RegisterKind reg_set,
207 const Value *initial_value_ptr,
208 const Value *object_address_ptr, Value &result,
209 Status *error_ptr);
210
211 bool GetExpressionData(DataExtractor &data) const {
212 data = m_data;
213 return data.GetByteSize() > 0;
214 }
215
216 bool DumpLocationForAddress(Stream *s, lldb::DescriptionLevel level,
217 lldb::addr_t func_load_addr, lldb::addr_t address,
218 ABI *abi);
219
220 bool MatchesOperand(StackFrame &frame, const Instruction::Operand &op);
221
222 llvm::Optional<DataExtractor>
223 GetLocationExpression(lldb::addr_t load_function_start,
224 lldb::addr_t addr) const;
225
226private:
227 /// Pretty-prints the location expression to a stream
228 ///
229 /// \param[in] s
230 /// The stream to use for pretty-printing.
231 ///
232 /// \param[in] data
233 /// The data extractor.
234 ///
235 /// \param[in] level
236 /// The level of detail to use in pretty-printing.
237 ///
238 /// \param[in] abi
239 /// An optional ABI plug-in that can be used to resolve register
240 /// names.
241 void DumpLocation(Stream *s, const DataExtractor &data,
242 lldb::DescriptionLevel level, ABI *abi) const;
243
244 /// Module which defined this expression.
245 lldb::ModuleWP m_module_wp;
246
247 /// A data extractor capable of reading opcode bytes
248 DataExtractor m_data;
249
250 /// The DWARF compile unit this expression belongs to. It is used to evaluate
251 /// values indexing into the .debug_addr section (e.g. DW_OP_GNU_addr_index,
252 /// DW_OP_GNU_const_index)
253 const DWARFUnit *m_dwarf_cu;
254
255 /// One of the defines that starts with LLDB_REGKIND_
256 lldb::RegisterKind m_reg_kind;
257
258 struct LoclistAddresses {
259 lldb::addr_t cu_file_addr;
260 lldb::addr_t func_file_addr;
261 };
262 llvm::Optional<LoclistAddresses> m_loclist_addresses;
263};
264
265} // namespace lldb_private
266
267#endif // LLDB_EXPRESSION_DWARFEXPRESSION_H
268