1 //===-- DWARFExpression.h ---------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef liblldb_DWARFExpression_h_
11 #define liblldb_DWARFExpression_h_
13 #include "lldb/Core/Address.h"
14 #include "lldb/Core/Disassembler.h"
15 #include "lldb/Core/Scalar.h"
16 #include "lldb/Utility/DataExtractor.h"
17 #include "lldb/Utility/Status.h"
18 #include "lldb/lldb-private.h"
21 class DWARFCompileUnit;
23 namespace lldb_private {
25 //----------------------------------------------------------------------
26 /// @class DWARFExpression DWARFExpression.h "lldb/Expression/DWARFExpression.h"
27 /// @brief Encapsulates a DWARF location expression and interprets it.
29 /// DWARF location expressions are used in two ways by LLDB. The first
30 /// use is to find entities specified in the debug information, since
31 /// their locations are specified in precisely this language. The second
32 /// is to interpret expressions without having to run the target in cases
33 /// where the overhead from copying JIT-compiled code into the target is
34 /// too high or where the target cannot be run. This class encapsulates
35 /// a single DWARF location expression or a location list and interprets
37 //----------------------------------------------------------------------
38 class DWARFExpression {
40 enum LocationListFormat : uint8_t {
41 NonLocationList, // Not a location list
42 RegularLocationList, // Location list format used in non-split dwarf files
43 SplitDwarfLocationList, // Location list format used in split dwarf files
46 //------------------------------------------------------------------
48 //------------------------------------------------------------------
49 explicit DWARFExpression(DWARFCompileUnit *dwarf_cu);
51 //------------------------------------------------------------------
55 /// A data extractor configured to read the DWARF location expression's
58 /// @param[in] data_offset
59 /// The offset of the location expression in the extractor.
61 /// @param[in] data_length
62 /// The byte length of the location expression.
63 //------------------------------------------------------------------
64 DWARFExpression(lldb::ModuleSP module, const DataExtractor &data,
65 DWARFCompileUnit *dwarf_cu, lldb::offset_t data_offset,
66 lldb::offset_t data_length);
68 //------------------------------------------------------------------
70 //------------------------------------------------------------------
71 DWARFExpression(const DWARFExpression &rhs);
73 //------------------------------------------------------------------
75 //------------------------------------------------------------------
76 virtual ~DWARFExpression();
78 //------------------------------------------------------------------
79 /// Print the description of the expression to a stream
82 /// The stream to print to.
85 /// The level of verbosity to use.
87 /// @param[in] location_list_base_addr
88 /// If this is a location list based expression, this is the
89 /// address of the object that owns it. NOTE: this value is
90 /// different from the DWARF version of the location list base
91 /// address which is compile unit relative. This base address
92 /// is the address of the object that owns the location list.
95 /// An optional ABI plug-in that can be used to resolve register
97 //------------------------------------------------------------------
98 void GetDescription(Stream *s, lldb::DescriptionLevel level,
99 lldb::addr_t location_list_base_addr, ABI *abi) const;
101 //------------------------------------------------------------------
102 /// Return true if the location expression contains data
103 //------------------------------------------------------------------
104 bool IsValid() const;
106 //------------------------------------------------------------------
107 /// Return true if a location list was provided
108 //------------------------------------------------------------------
109 bool IsLocationList() const;
111 //------------------------------------------------------------------
112 /// Search for a load address in the location list
114 /// @param[in] process
115 /// The process to use when resolving the load address
118 /// The address to resolve
121 /// True if IsLocationList() is true and the address was found;
123 //------------------------------------------------------------------
125 // LocationListContainsLoadAddress (Process* process, const Address &addr)
128 bool LocationListContainsAddress(lldb::addr_t loclist_base_addr,
129 lldb::addr_t addr) const;
131 //------------------------------------------------------------------
132 /// If a location is not a location list, return true if the location
133 /// contains a DW_OP_addr () opcode in the stream that matches \a
134 /// file_addr. If file_addr is LLDB_INVALID_ADDRESS, the this
135 /// function will return true if the variable there is any DW_OP_addr
136 /// in a location that (yet still is NOT a location list). This helps
137 /// us detect if a variable is a global or static variable since
138 /// there is no other indication from DWARF debug info.
140 /// @param[in] op_addr_idx
141 /// The DW_OP_addr index to retrieve in case there is more than
142 /// one DW_OP_addr opcode in the location byte stream.
144 /// @param[out] error
145 /// If the location stream contains unknown DW_OP opcodes or the
146 /// data is missing, \a error will be set to \b true.
149 /// LLDB_INVALID_ADDRESS if the location doesn't contain a
150 /// DW_OP_addr for \a op_addr_idx, otherwise a valid file address
151 //------------------------------------------------------------------
152 lldb::addr_t GetLocation_DW_OP_addr(uint32_t op_addr_idx, bool &error) const;
154 bool Update_DW_OP_addr(lldb::addr_t file_addr);
156 bool ContainsThreadLocalStorage() const;
158 bool LinkThreadLocalStorage(
159 lldb::ModuleSP new_module_sp,
160 std::function<lldb::addr_t(lldb::addr_t file_addr)> const
161 &link_address_callback);
163 //------------------------------------------------------------------
164 /// Make the expression parser read its location information from a
165 /// given data source. Does not change the offset and length
168 /// A data extractor configured to read the DWARF location expression's
170 //------------------------------------------------------------------
171 void SetOpcodeData(const DataExtractor &data);
173 //------------------------------------------------------------------
174 /// Make the expression parser read its location information from a
175 /// given data source
177 /// @param[in] module_sp
178 /// The module that defines the DWARF expression.
181 /// A data extractor configured to read the DWARF location expression's
184 /// @param[in] data_offset
185 /// The offset of the location expression in the extractor.
187 /// @param[in] data_length
188 /// The byte length of the location expression.
189 //------------------------------------------------------------------
190 void SetOpcodeData(lldb::ModuleSP module_sp, const DataExtractor &data,
191 lldb::offset_t data_offset, lldb::offset_t data_length);
193 //------------------------------------------------------------------
194 /// Copy the DWARF location expression into a local buffer.
196 /// It is a good idea to copy the data so we don't keep the entire
197 /// object file worth of data around just for a few bytes of location
198 /// expression. LLDB typically will mmap the entire contents of debug
199 /// information files, and if we use SetOpcodeData, it will get a
200 /// shared reference to all of this data for the and cause the object
201 /// file to have to stay around. Even worse, a very very large ".a"
202 /// that contains one or more .o files could end up being referenced.
203 /// Location lists are typically small so even though we are copying
204 /// the data, it shouldn't amount to that much for the variables we
207 /// @param[in] module_sp
208 /// The module that defines the DWARF expression.
211 /// A data extractor configured to read and copy the DWARF
212 /// location expression's bytecode.
214 /// @param[in] data_offset
215 /// The offset of the location expression in the extractor.
217 /// @param[in] data_length
218 /// The byte length of the location expression.
219 //------------------------------------------------------------------
220 void CopyOpcodeData(lldb::ModuleSP module_sp, const DataExtractor &data,
221 lldb::offset_t data_offset, lldb::offset_t data_length);
223 void CopyOpcodeData(const void *data, lldb::offset_t data_length,
224 lldb::ByteOrder byte_order, uint8_t addr_byte_size);
226 void CopyOpcodeData(uint64_t const_value,
227 lldb::offset_t const_value_byte_size,
228 uint8_t addr_byte_size);
230 //------------------------------------------------------------------
231 /// Tells the expression that it refers to a location list.
234 /// This value should be a slide that is applied to any values
235 /// in the location list data so the values become zero based
236 /// offsets into the object that owns the location list. We need
237 /// to make location lists relative to the objects that own them
238 /// so we can relink addresses on the fly.
239 //------------------------------------------------------------------
240 void SetLocationListSlide(lldb::addr_t slide);
242 //------------------------------------------------------------------
243 /// Return the call-frame-info style register kind
244 //------------------------------------------------------------------
245 int GetRegisterKind();
247 //------------------------------------------------------------------
248 /// Set the call-frame-info style register kind
250 /// @param[in] reg_kind
251 /// The register kind.
252 //------------------------------------------------------------------
253 void SetRegisterKind(lldb::RegisterKind reg_kind);
255 //------------------------------------------------------------------
256 /// Wrapper for the static evaluate function that accepts an
257 /// ExecutionContextScope instead of an ExecutionContext and uses
258 /// member variables to populate many operands
259 //------------------------------------------------------------------
260 bool Evaluate(ExecutionContextScope *exe_scope,
261 lldb::addr_t loclist_base_load_addr,
262 const Value *initial_value_ptr, const Value *object_address_ptr,
263 Value &result, Status *error_ptr) const;
265 //------------------------------------------------------------------
266 /// Wrapper for the static evaluate function that uses member
267 /// variables to populate many operands
268 //------------------------------------------------------------------
269 bool Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
270 lldb::addr_t loclist_base_load_addr,
271 const Value *initial_value_ptr, const Value *object_address_ptr,
272 Value &result, Status *error_ptr) const;
274 //------------------------------------------------------------------
275 /// Evaluate a DWARF location expression in a particular context
277 /// @param[in] exe_ctx
278 /// The execution context in which to evaluate the location
279 /// expression. The location expression may access the target's
280 /// memory, especially if it comes from the expression parser.
282 /// @param[in] opcode_ctx
283 /// The module which defined the expression.
285 /// @param[in] opcodes
286 /// This is a static method so the opcodes need to be provided
289 /// @param[in] expr_locals
290 /// If the location expression was produced by the expression parser,
291 /// the list of local variables referenced by the DWARF expression.
292 /// This list should already have been populated during parsing;
293 /// the DWARF expression refers to variables by index. Can be NULL if
294 /// the location expression uses no locals.
296 /// @param[in] decl_map
297 /// If the location expression was produced by the expression parser,
298 /// the list of external variables referenced by the location
299 /// expression. Can be NULL if the location expression uses no
300 /// external variables.
302 /// @param[in] reg_ctx
303 /// An optional parameter which provides a RegisterContext for use
304 /// when evaluating the expression (i.e. for fetching register values).
305 /// Normally this will come from the ExecutionContext's StackFrame but
306 /// in the case where an expression needs to be evaluated while building
307 /// the stack frame list, this short-cut is available.
309 /// @param[in] offset
310 /// The offset of the location expression in the data extractor.
312 /// @param[in] length
313 /// The length in bytes of the location expression.
315 /// @param[in] reg_set
316 /// The call-frame-info style register kind.
318 /// @param[in] initial_value_ptr
319 /// A value to put on top of the interpreter stack before evaluating
320 /// the expression, if the expression is parametrized. Can be NULL.
322 /// @param[in] result
323 /// A value into which the result of evaluating the expression is
326 /// @param[in] error_ptr
327 /// If non-NULL, used to report errors in expression evaluation.
330 /// True on success; false otherwise. If error_ptr is non-NULL,
331 /// details of the failure are provided through it.
332 //------------------------------------------------------------------
333 static bool Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
334 lldb::ModuleSP opcode_ctx, const DataExtractor &opcodes,
335 DWARFCompileUnit *dwarf_cu, const lldb::offset_t offset,
336 const lldb::offset_t length,
337 const lldb::RegisterKind reg_set,
338 const Value *initial_value_ptr,
339 const Value *object_address_ptr, Value &result,
342 bool GetExpressionData(DataExtractor &data) const {
344 return data.GetByteSize() > 0;
347 bool DumpLocationForAddress(Stream *s, lldb::DescriptionLevel level,
348 lldb::addr_t loclist_base_load_addr,
349 lldb::addr_t address, ABI *abi);
351 static size_t LocationListSize(const DWARFCompileUnit *dwarf_cu,
352 const DataExtractor &debug_loc_data,
353 lldb::offset_t offset);
355 static bool PrintDWARFExpression(Stream &s, const DataExtractor &data,
356 int address_size, int dwarf_ref_size,
357 bool location_expression);
359 static void PrintDWARFLocationList(Stream &s, const DWARFCompileUnit *cu,
360 const DataExtractor &debug_loc_data,
361 lldb::offset_t offset);
363 bool MatchesOperand(StackFrame &frame, const Instruction::Operand &op);
366 //------------------------------------------------------------------
367 /// Pretty-prints the location expression to a stream
369 /// @param[in] stream
370 /// The stream to use for pretty-printing.
372 /// @param[in] offset
373 /// The offset into the data buffer of the opcodes to be printed.
375 /// @param[in] length
376 /// The length in bytes of the opcodes to be printed.
379 /// The level of detail to use in pretty-printing.
382 /// An optional ABI plug-in that can be used to resolve register
384 //------------------------------------------------------------------
385 void DumpLocation(Stream *s, lldb::offset_t offset, lldb::offset_t length,
386 lldb::DescriptionLevel level, ABI *abi) const;
388 bool GetLocation(lldb::addr_t base_addr, lldb::addr_t pc,
389 lldb::offset_t &offset, lldb::offset_t &len);
391 static bool AddressRangeForLocationListEntry(
392 const DWARFCompileUnit *dwarf_cu, const DataExtractor &debug_loc_data,
393 lldb::offset_t *offset_ptr, lldb::addr_t &low_pc, lldb::addr_t &high_pc);
395 bool GetOpAndEndOffsets(StackFrame &frame, lldb::offset_t &op_offset,
396 lldb::offset_t &end_offset);
398 //------------------------------------------------------------------
399 /// Classes that inherit from DWARFExpression can see and modify these
400 //------------------------------------------------------------------
402 lldb::ModuleWP m_module_wp; ///< Module which defined this expression.
403 DataExtractor m_data; ///< A data extractor capable of reading opcode bytes
404 DWARFCompileUnit *m_dwarf_cu; ///< The DWARF compile unit this expression
405 ///belongs to. It is used
406 ///< to evaluate values indexing into the .debug_addr section (e.g.
407 ///< DW_OP_GNU_addr_index, DW_OP_GNU_const_index)
409 m_reg_kind; ///< One of the defines that starts with LLDB_REGKIND_
410 lldb::addr_t m_loclist_slide; ///< A value used to slide the location list
412 ///< they are relative to the object that owns the location list
413 ///< (the function for frame base and variable location lists)
416 } // namespace lldb_private
418 #endif // liblldb_DWARFExpression_h_