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 class ClangExpressionDeclMap;
26 class ClangExpressionVariable;
27 class ClangExpressionVariableList;
29 //----------------------------------------------------------------------
30 /// @class DWARFExpression DWARFExpression.h "lldb/Expression/DWARFExpression.h"
31 /// @brief Encapsulates a DWARF location expression and interprets it.
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
35 /// their locations are specified in precisely this language. The second
36 /// is to interpret expressions without having to run the target in cases
37 /// where the overhead from copying JIT-compiled code into the target is
38 /// too high or where the target cannot be run. This class encapsulates
39 /// a single DWARF location expression or a location list and interprets
41 //----------------------------------------------------------------------
42 class DWARFExpression {
44 enum LocationListFormat : uint8_t {
45 NonLocationList, // Not a location list
46 RegularLocationList, // Location list format used in non-split dwarf files
47 SplitDwarfLocationList, // Location list format used in split dwarf files
50 //------------------------------------------------------------------
52 //------------------------------------------------------------------
53 explicit DWARFExpression(DWARFCompileUnit *dwarf_cu);
55 //------------------------------------------------------------------
59 /// A data extractor configured to read the DWARF location expression's
62 /// @param[in] data_offset
63 /// The offset of the location expression in the extractor.
65 /// @param[in] data_length
66 /// The byte length of the location expression.
67 //------------------------------------------------------------------
68 DWARFExpression(lldb::ModuleSP module, const DataExtractor &data,
69 DWARFCompileUnit *dwarf_cu, lldb::offset_t data_offset,
70 lldb::offset_t data_length);
72 //------------------------------------------------------------------
74 //------------------------------------------------------------------
75 DWARFExpression(const DWARFExpression &rhs);
77 //------------------------------------------------------------------
79 //------------------------------------------------------------------
80 virtual ~DWARFExpression();
82 //------------------------------------------------------------------
83 /// Print the description of the expression to a stream
86 /// The stream to print to.
89 /// The level of verbosity to use.
91 /// @param[in] location_list_base_addr
92 /// If this is a location list based expression, this is the
93 /// address of the object that owns it. NOTE: this value is
94 /// different from the DWARF version of the location list base
95 /// address which is compile unit relative. This base address
96 /// is the address of the object that owns the location list.
99 /// An optional ABI plug-in that can be used to resolve register
101 //------------------------------------------------------------------
102 void GetDescription(Stream *s, lldb::DescriptionLevel level,
103 lldb::addr_t location_list_base_addr, ABI *abi) const;
105 //------------------------------------------------------------------
106 /// Return true if the location expression contains data
107 //------------------------------------------------------------------
108 bool IsValid() const;
110 //------------------------------------------------------------------
111 /// Return true if a location list was provided
112 //------------------------------------------------------------------
113 bool IsLocationList() const;
115 //------------------------------------------------------------------
116 /// Search for a load address in the location list
118 /// @param[in] process
119 /// The process to use when resolving the load address
122 /// The address to resolve
125 /// True if IsLocationList() is true and the address was found;
127 //------------------------------------------------------------------
129 // LocationListContainsLoadAddress (Process* process, const Address &addr)
132 bool LocationListContainsAddress(lldb::addr_t loclist_base_addr,
133 lldb::addr_t addr) const;
135 //------------------------------------------------------------------
136 /// If a location is not a location list, return true if the location
137 /// contains a DW_OP_addr () opcode in the stream that matches \a
138 /// file_addr. If file_addr is LLDB_INVALID_ADDRESS, the this
139 /// function will return true if the variable there is any DW_OP_addr
140 /// in a location that (yet still is NOT a location list). This helps
141 /// us detect if a variable is a global or static variable since
142 /// there is no other indication from DWARF debug info.
144 /// @param[in] op_addr_idx
145 /// The DW_OP_addr index to retrieve in case there is more than
146 /// one DW_OP_addr opcode in the location byte stream.
148 /// @param[out] error
149 /// If the location stream contains unknown DW_OP opcodes or the
150 /// data is missing, \a error will be set to \b true.
153 /// LLDB_INVALID_ADDRESS if the location doesn't contain a
154 /// DW_OP_addr for \a op_addr_idx, otherwise a valid file address
155 //------------------------------------------------------------------
156 lldb::addr_t GetLocation_DW_OP_addr(uint32_t op_addr_idx, bool &error) const;
158 bool Update_DW_OP_addr(lldb::addr_t file_addr);
160 bool ContainsThreadLocalStorage() const;
162 bool LinkThreadLocalStorage(
163 lldb::ModuleSP new_module_sp,
164 std::function<lldb::addr_t(lldb::addr_t file_addr)> const
165 &link_address_callback);
167 //------------------------------------------------------------------
168 /// Make the expression parser read its location information from a
169 /// given data source. Does not change the offset and length
172 /// A data extractor configured to read the DWARF location expression's
174 //------------------------------------------------------------------
175 void SetOpcodeData(const DataExtractor &data);
177 //------------------------------------------------------------------
178 /// Make the expression parser read its location information from a
179 /// given data source
181 /// @param[in] module_sp
182 /// The module that defines the DWARF expression.
185 /// A data extractor configured to read the DWARF location expression's
188 /// @param[in] data_offset
189 /// The offset of the location expression in the extractor.
191 /// @param[in] data_length
192 /// The byte length of the location expression.
193 //------------------------------------------------------------------
194 void SetOpcodeData(lldb::ModuleSP module_sp, const DataExtractor &data,
195 lldb::offset_t data_offset, lldb::offset_t data_length);
197 //------------------------------------------------------------------
198 /// Copy the DWARF location expression into a local buffer.
200 /// It is a good idea to copy the data so we don't keep the entire
201 /// object file worth of data around just for a few bytes of location
202 /// expression. LLDB typically will mmap the entire contents of debug
203 /// information files, and if we use SetOpcodeData, it will get a
204 /// shared reference to all of this data for the and cause the object
205 /// file to have to stay around. Even worse, a very very large ".a"
206 /// that contains one or more .o files could end up being referenced.
207 /// Location lists are typically small so even though we are copying
208 /// the data, it shouldn't amount to that much for the variables we
211 /// @param[in] module_sp
212 /// The module that defines the DWARF expression.
215 /// A data extractor configured to read and copy the DWARF
216 /// location expression's bytecode.
218 /// @param[in] data_offset
219 /// The offset of the location expression in the extractor.
221 /// @param[in] data_length
222 /// The byte length of the location expression.
223 //------------------------------------------------------------------
224 void CopyOpcodeData(lldb::ModuleSP module_sp, const DataExtractor &data,
225 lldb::offset_t data_offset, lldb::offset_t data_length);
227 void CopyOpcodeData(const void *data, lldb::offset_t data_length,
228 lldb::ByteOrder byte_order, uint8_t addr_byte_size);
230 void CopyOpcodeData(uint64_t const_value,
231 lldb::offset_t const_value_byte_size,
232 uint8_t addr_byte_size);
234 //------------------------------------------------------------------
235 /// Tells the expression that it refers to a location list.
238 /// This value should be a slide that is applied to any values
239 /// in the location list data so the values become zero based
240 /// offsets into the object that owns the location list. We need
241 /// to make location lists relative to the objects that own them
242 /// so we can relink addresses on the fly.
243 //------------------------------------------------------------------
244 void SetLocationListSlide(lldb::addr_t slide);
246 //------------------------------------------------------------------
247 /// Return the call-frame-info style register kind
248 //------------------------------------------------------------------
249 int GetRegisterKind();
251 //------------------------------------------------------------------
252 /// Set the call-frame-info style register kind
254 /// @param[in] reg_kind
255 /// The register kind.
256 //------------------------------------------------------------------
257 void SetRegisterKind(lldb::RegisterKind reg_kind);
259 //------------------------------------------------------------------
260 /// Wrapper for the static evaluate function that accepts an
261 /// ExecutionContextScope instead of an ExecutionContext and uses
262 /// member variables to populate many operands
263 //------------------------------------------------------------------
264 bool Evaluate(ExecutionContextScope *exe_scope,
265 ClangExpressionVariableList *expr_locals,
266 ClangExpressionDeclMap *decl_map,
267 lldb::addr_t loclist_base_load_addr,
268 const Value *initial_value_ptr, const Value *object_address_ptr,
269 Value &result, Status *error_ptr) const;
271 //------------------------------------------------------------------
272 /// Wrapper for the static evaluate function that uses member
273 /// variables to populate many operands
274 //------------------------------------------------------------------
275 bool Evaluate(ExecutionContext *exe_ctx,
276 ClangExpressionVariableList *expr_locals,
277 ClangExpressionDeclMap *decl_map, RegisterContext *reg_ctx,
278 lldb::addr_t loclist_base_load_addr,
279 const Value *initial_value_ptr, const Value *object_address_ptr,
280 Value &result, Status *error_ptr) const;
282 //------------------------------------------------------------------
283 /// Evaluate a DWARF location expression in a particular context
285 /// @param[in] exe_ctx
286 /// The execution context in which to evaluate the location
287 /// expression. The location expression may access the target's
288 /// memory, especially if it comes from the expression parser.
290 /// @param[in] opcode_ctx
291 /// The module which defined the expression.
293 /// @param[in] opcodes
294 /// This is a static method so the opcodes need to be provided
297 /// @param[in] expr_locals
298 /// If the location expression was produced by the expression parser,
299 /// the list of local variables referenced by the DWARF expression.
300 /// This list should already have been populated during parsing;
301 /// the DWARF expression refers to variables by index. Can be NULL if
302 /// the location expression uses no locals.
304 /// @param[in] decl_map
305 /// If the location expression was produced by the expression parser,
306 /// the list of external variables referenced by the location
307 /// expression. Can be NULL if the location expression uses no
308 /// external variables.
310 /// @param[in] reg_ctx
311 /// An optional parameter which provides a RegisterContext for use
312 /// when evaluating the expression (i.e. for fetching register values).
313 /// Normally this will come from the ExecutionContext's StackFrame but
314 /// in the case where an expression needs to be evaluated while building
315 /// the stack frame list, this short-cut is available.
317 /// @param[in] offset
318 /// The offset of the location expression in the data extractor.
320 /// @param[in] length
321 /// The length in bytes of the location expression.
323 /// @param[in] reg_set
324 /// The call-frame-info style register kind.
326 /// @param[in] initial_value_ptr
327 /// A value to put on top of the interpreter stack before evaluating
328 /// the expression, if the expression is parametrized. Can be NULL.
330 /// @param[in] result
331 /// A value into which the result of evaluating the expression is
334 /// @param[in] error_ptr
335 /// If non-NULL, used to report errors in expression evaluation.
338 /// True on success; false otherwise. If error_ptr is non-NULL,
339 /// details of the failure are provided through it.
340 //------------------------------------------------------------------
342 Evaluate(ExecutionContext *exe_ctx, ClangExpressionVariableList *expr_locals,
343 ClangExpressionDeclMap *decl_map, RegisterContext *reg_ctx,
344 lldb::ModuleSP opcode_ctx, const DataExtractor &opcodes,
345 DWARFCompileUnit *dwarf_cu, const lldb::offset_t offset,
346 const lldb::offset_t length, const lldb::RegisterKind reg_set,
347 const Value *initial_value_ptr, const Value *object_address_ptr,
348 Value &result, Status *error_ptr);
350 //------------------------------------------------------------------
351 /// Loads a ClangExpressionVariableList into the object
353 /// @param[in] locals
354 /// If non-NULL, the list of locals used by this expression.
356 //------------------------------------------------------------------
357 void SetExpressionLocalVariableList(ClangExpressionVariableList *locals);
359 //------------------------------------------------------------------
360 /// Loads a ClangExpressionDeclMap into the object
362 /// @param[in] locals
363 /// If non-NULL, the list of external variables used by this
364 /// expression. See Evaluate().
365 //------------------------------------------------------------------
366 void SetExpressionDeclMap(ClangExpressionDeclMap *decl_map);
368 bool GetExpressionData(DataExtractor &data) const {
370 return data.GetByteSize() > 0;
373 bool DumpLocationForAddress(Stream *s, lldb::DescriptionLevel level,
374 lldb::addr_t loclist_base_load_addr,
375 lldb::addr_t address, ABI *abi);
377 static size_t LocationListSize(const DWARFCompileUnit *dwarf_cu,
378 const DataExtractor &debug_loc_data,
379 lldb::offset_t offset);
381 static bool PrintDWARFExpression(Stream &s, const DataExtractor &data,
382 int address_size, int dwarf_ref_size,
383 bool location_expression);
385 static void PrintDWARFLocationList(Stream &s, const DWARFCompileUnit *cu,
386 const DataExtractor &debug_loc_data,
387 lldb::offset_t offset);
389 bool MatchesOperand(StackFrame &frame, const Instruction::Operand &op);
392 //------------------------------------------------------------------
393 /// Pretty-prints the location expression to a stream
395 /// @param[in] stream
396 /// The stream to use for pretty-printing.
398 /// @param[in] offset
399 /// The offset into the data buffer of the opcodes to be printed.
401 /// @param[in] length
402 /// The length in bytes of the opcodes to be printed.
405 /// The level of detail to use in pretty-printing.
408 /// An optional ABI plug-in that can be used to resolve register
410 //------------------------------------------------------------------
411 void DumpLocation(Stream *s, lldb::offset_t offset, lldb::offset_t length,
412 lldb::DescriptionLevel level, ABI *abi) const;
414 bool GetLocation(lldb::addr_t base_addr, lldb::addr_t pc,
415 lldb::offset_t &offset, lldb::offset_t &len);
417 static bool AddressRangeForLocationListEntry(
418 const DWARFCompileUnit *dwarf_cu, const DataExtractor &debug_loc_data,
419 lldb::offset_t *offset_ptr, lldb::addr_t &low_pc, lldb::addr_t &high_pc);
421 bool GetOpAndEndOffsets(StackFrame &frame, lldb::offset_t &op_offset,
422 lldb::offset_t &end_offset);
424 //------------------------------------------------------------------
425 /// Classes that inherit from DWARFExpression can see and modify these
426 //------------------------------------------------------------------
428 lldb::ModuleWP m_module_wp; ///< Module which defined this expression.
429 DataExtractor m_data; ///< A data extractor capable of reading opcode bytes
430 DWARFCompileUnit *m_dwarf_cu; ///< The DWARF compile unit this expression
431 ///belongs to. It is used
432 ///< to evaluate values indexing into the .debug_addr section (e.g.
433 ///< DW_OP_GNU_addr_index, DW_OP_GNU_const_index)
435 m_reg_kind; ///< One of the defines that starts with LLDB_REGKIND_
436 lldb::addr_t m_loclist_slide; ///< A value used to slide the location list
438 ///< they are relative to the object that owns the location list
439 ///< (the function for frame base and variable location lists)
442 } // namespace lldb_private
444 #endif // liblldb_DWARFExpression_h_