LLDB  mainline
DWARFExpression.h
Go to the documentation of this file.
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 liblldb_DWARFExpression_h_
10 #define liblldb_DWARFExpression_h_
11 
12 #include "lldb/Core/Address.h"
13 #include "lldb/Core/Disassembler.h"
15 #include "lldb/Utility/Scalar.h"
16 #include "lldb/Utility/Status.h"
17 #include "lldb/lldb-private.h"
18 #include <functional>
19 
20 class DWARFUnit;
21 
22 namespace 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.
36 public:
37  enum LocationListFormat : uint8_t {
38  NonLocationList, // Not a location list
39  RegularLocationList, // Location list format used in non-split dwarf files
40  SplitDwarfLocationList, // Location list format used in pre-DWARF v5 split
41  // dwarf files (.debug_loc.dwo)
42  LocLists, // Location list format used in DWARF v5
43  // (.debug_loclists/.debug_loclists.dwo).
44  };
45 
46  /// Constructor
47  explicit DWARFExpression(DWARFUnit *dwarf_cu);
48 
49  /// Constructor
50  ///
51  /// \param[in] data
52  /// A data extractor configured to read the DWARF location expression's
53  /// bytecode.
54  ///
55  /// \param[in] data_offset
56  /// The offset of the location expression in the extractor.
57  ///
58  /// \param[in] data_length
59  /// The byte length of the location expression.
60  DWARFExpression(lldb::ModuleSP module, const DataExtractor &data,
61  DWARFUnit *dwarf_cu, lldb::offset_t data_offset,
62  lldb::offset_t data_length);
63 
64  /// Copy constructor
65  DWARFExpression(const DWARFExpression &rhs);
66 
67  /// Destructor
68  virtual ~DWARFExpression();
69 
70  /// Print the description of the expression to a stream
71  ///
72  /// \param[in] s
73  /// The stream to print to.
74  ///
75  /// \param[in] level
76  /// The level of verbosity to use.
77  ///
78  /// \param[in] location_list_base_addr
79  /// If this is a location list based expression, this is the
80  /// address of the object that owns it. NOTE: this value is
81  /// different from the DWARF version of the location list base
82  /// address which is compile unit relative. This base address
83  /// is the address of the object that owns the location list.
84  ///
85  /// \param[in] abi
86  /// An optional ABI plug-in that can be used to resolve register
87  /// names.
89  lldb::addr_t location_list_base_addr, ABI *abi) const;
90 
91  /// Return true if the location expression contains data
92  bool IsValid() const;
93 
94  /// Return true if a location list was provided
95  bool IsLocationList() const;
96 
97  /// Search for a load address in the location list
98  ///
99  /// \param[in] process
100  /// The process to use when resolving the load address
101  ///
102  /// \param[in] addr
103  /// The address to resolve
104  ///
105  /// \return
106  /// True if IsLocationList() is true and the address was found;
107  /// false otherwise.
108  // bool
109  // LocationListContainsLoadAddress (Process* process, const Address &addr)
110  // const;
111  //
112  bool LocationListContainsAddress(lldb::addr_t loclist_base_addr,
113  lldb::addr_t addr) const;
114 
115  /// If a location is not a location list, return true if the location
116  /// contains a DW_OP_addr () opcode in the stream that matches \a file_addr.
117  /// If file_addr is LLDB_INVALID_ADDRESS, the this function will return true
118  /// if the variable there is any DW_OP_addr in a location that (yet still is
119  /// NOT a location list). This helps us detect if a variable is a global or
120  /// static variable since there is no other indication from DWARF debug
121  /// info.
122  ///
123  /// \param[in] op_addr_idx
124  /// The DW_OP_addr index to retrieve in case there is more than
125  /// one DW_OP_addr opcode in the location byte stream.
126  ///
127  /// \param[out] error
128  /// If the location stream contains unknown DW_OP opcodes or the
129  /// data is missing, \a error will be set to \b true.
130  ///
131  /// \return
132  /// LLDB_INVALID_ADDRESS if the location doesn't contain a
133  /// DW_OP_addr for \a op_addr_idx, otherwise a valid file address
134  lldb::addr_t GetLocation_DW_OP_addr(uint32_t op_addr_idx, bool &error) const;
135 
136  bool Update_DW_OP_addr(lldb::addr_t file_addr);
137 
138  void SetModule(const lldb::ModuleSP &module) { m_module_wp = module; }
139 
140  bool ContainsThreadLocalStorage() const;
141 
143  lldb::ModuleSP new_module_sp,
144  std::function<lldb::addr_t(lldb::addr_t file_addr)> const
145  &link_address_callback);
146 
147  /// Make the expression parser read its location information from a given
148  /// data source. Does not change the offset and length
149  ///
150  /// \param[in] data
151  /// A data extractor configured to read the DWARF location expression's
152  /// bytecode.
153  void SetOpcodeData(const DataExtractor &data);
154 
155  /// Make the expression parser read its location information from a given
156  /// data source
157  ///
158  /// \param[in] module_sp
159  /// The module that defines the DWARF expression.
160  ///
161  /// \param[in] data
162  /// A data extractor configured to read the DWARF location expression's
163  /// bytecode.
164  ///
165  /// \param[in] data_offset
166  /// The offset of the location expression in the extractor.
167  ///
168  /// \param[in] data_length
169  /// The byte length of the location expression.
170  void SetOpcodeData(lldb::ModuleSP module_sp, const DataExtractor &data,
171  lldb::offset_t data_offset, lldb::offset_t data_length);
172 
173  /// Copy the DWARF location expression into a local buffer.
174  ///
175  /// It is a good idea to copy the data so we don't keep the entire object
176  /// file worth of data around just for a few bytes of location expression.
177  /// LLDB typically will mmap the entire contents of debug information files,
178  /// and if we use SetOpcodeData, it will get a shared reference to all of
179  /// this data for the and cause the object file to have to stay around. Even
180  /// worse, a very very large ".a" that contains one or more .o files could
181  /// end up being referenced. Location lists are typically small so even
182  /// though we are copying the data, it shouldn't amount to that much for the
183  /// variables we end up parsing.
184  ///
185  /// \param[in] module_sp
186  /// The module that defines the DWARF expression.
187  ///
188  /// \param[in] data
189  /// A data extractor configured to read and copy the DWARF
190  /// location expression's bytecode.
191  ///
192  /// \param[in] data_offset
193  /// The offset of the location expression in the extractor.
194  ///
195  /// \param[in] data_length
196  /// The byte length of the location expression.
197  void CopyOpcodeData(lldb::ModuleSP module_sp, const DataExtractor &data,
198  lldb::offset_t data_offset, lldb::offset_t data_length);
199 
200  void CopyOpcodeData(const void *data, lldb::offset_t data_length,
201  lldb::ByteOrder byte_order, uint8_t addr_byte_size);
202 
203  void CopyOpcodeData(uint64_t const_value,
204  lldb::offset_t const_value_byte_size,
205  uint8_t addr_byte_size);
206 
207  /// Tells the expression that it refers to a location list.
208  ///
209  /// \param[in] slide
210  /// This value should be a slide that is applied to any values
211  /// in the location list data so the values become zero based
212  /// offsets into the object that owns the location list. We need
213  /// to make location lists relative to the objects that own them
214  /// so we can relink addresses on the fly.
216 
217  /// Return the call-frame-info style register kind
218  int GetRegisterKind();
219 
220  /// Set the call-frame-info style register kind
221  ///
222  /// \param[in] reg_kind
223  /// The register kind.
224  void SetRegisterKind(lldb::RegisterKind reg_kind);
225 
226  /// Wrapper for the static evaluate function that accepts an
227  /// ExecutionContextScope instead of an ExecutionContext and uses member
228  /// variables to populate many operands
229  bool Evaluate(ExecutionContextScope *exe_scope,
230  lldb::addr_t loclist_base_load_addr,
231  const Value *initial_value_ptr, const Value *object_address_ptr,
232  Value &result, Status *error_ptr) const;
233 
234  /// Wrapper for the static evaluate function that uses member variables to
235  /// populate many operands
236  bool Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
237  lldb::addr_t loclist_base_load_addr,
238  const Value *initial_value_ptr, const Value *object_address_ptr,
239  Value &result, Status *error_ptr) const;
240 
241  /// Evaluate a DWARF location expression in a particular context
242  ///
243  /// \param[in] exe_ctx
244  /// The execution context in which to evaluate the location
245  /// expression. The location expression may access the target's
246  /// memory, especially if it comes from the expression parser.
247  ///
248  /// \param[in] opcode_ctx
249  /// The module which defined the expression.
250  ///
251  /// \param[in] opcodes
252  /// This is a static method so the opcodes need to be provided
253  /// explicitly.
254  ///
255  /// \param[in] expr_locals
256  /// If the location expression was produced by the expression parser,
257  /// the list of local variables referenced by the DWARF expression.
258  /// This list should already have been populated during parsing;
259  /// the DWARF expression refers to variables by index. Can be NULL if
260  /// the location expression uses no locals.
261  ///
262  /// \param[in] decl_map
263  /// If the location expression was produced by the expression parser,
264  /// the list of external variables referenced by the location
265  /// expression. Can be NULL if the location expression uses no
266  /// external variables.
267  ///
268  /// \param[in] reg_ctx
269  /// An optional parameter which provides a RegisterContext for use
270  /// when evaluating the expression (i.e. for fetching register values).
271  /// Normally this will come from the ExecutionContext's StackFrame but
272  /// in the case where an expression needs to be evaluated while building
273  /// the stack frame list, this short-cut is available.
274  ///
275  /// \param[in] offset
276  /// The offset of the location expression in the data extractor.
277  ///
278  /// \param[in] length
279  /// The length in bytes of the location expression.
280  ///
281  /// \param[in] reg_set
282  /// The call-frame-info style register kind.
283  ///
284  /// \param[in] initial_value_ptr
285  /// A value to put on top of the interpreter stack before evaluating
286  /// the expression, if the expression is parametrized. Can be NULL.
287  ///
288  /// \param[in] result
289  /// A value into which the result of evaluating the expression is
290  /// to be placed.
291  ///
292  /// \param[in] error_ptr
293  /// If non-NULL, used to report errors in expression evaluation.
294  ///
295  /// \return
296  /// True on success; false otherwise. If error_ptr is non-NULL,
297  /// details of the failure are provided through it.
298  static bool Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
299  lldb::ModuleSP opcode_ctx, const DataExtractor &opcodes,
300  DWARFUnit *dwarf_cu, const lldb::offset_t offset,
301  const lldb::offset_t length,
302  const lldb::RegisterKind reg_set,
303  const Value *initial_value_ptr,
304  const Value *object_address_ptr, Value &result,
305  Status *error_ptr);
306 
307  bool GetExpressionData(DataExtractor &data) const {
308  data = m_data;
309  return data.GetByteSize() > 0;
310  }
311 
313  lldb::addr_t loclist_base_load_addr,
314  lldb::addr_t address, ABI *abi);
315 
316  static size_t LocationListSize(const DWARFUnit *dwarf_cu,
317  const DataExtractor &debug_loc_data,
318  lldb::offset_t offset);
319 
320  static bool PrintDWARFExpression(Stream &s, const DataExtractor &data,
321  int address_size, int dwarf_ref_size,
322  bool location_expression);
323 
324  static void PrintDWARFLocationList(Stream &s, const DWARFUnit *cu,
325  const DataExtractor &debug_loc_data,
326  lldb::offset_t offset);
327 
328  bool MatchesOperand(StackFrame &frame, const Instruction::Operand &op);
329 
330 protected:
331  /// Pretty-prints the location expression to a stream
332  ///
333  /// \param[in] stream
334  /// The stream to use for pretty-printing.
335  ///
336  /// \param[in] offset
337  /// The offset into the data buffer of the opcodes to be printed.
338  ///
339  /// \param[in] length
340  /// The length in bytes of the opcodes to be printed.
341  ///
342  /// \param[in] level
343  /// The level of detail to use in pretty-printing.
344  ///
345  /// \param[in] abi
346  /// An optional ABI plug-in that can be used to resolve register
347  /// names.
348  void DumpLocation(Stream *s, lldb::offset_t offset, lldb::offset_t length,
349  lldb::DescriptionLevel level, ABI *abi) const;
350 
351  bool GetLocation(lldb::addr_t base_addr, lldb::addr_t pc,
352  lldb::offset_t &offset, lldb::offset_t &len);
353 
355  const DWARFUnit *dwarf_cu, const DataExtractor &debug_loc_data,
356  lldb::offset_t *offset_ptr, lldb::addr_t &low_pc, lldb::addr_t &high_pc);
357 
358  bool GetOpAndEndOffsets(StackFrame &frame, lldb::offset_t &op_offset,
359  lldb::offset_t &end_offset);
360 
361  /// Classes that inherit from DWARFExpression can see and modify these
362 
363  lldb::ModuleWP m_module_wp; ///< Module which defined this expression.
364  DataExtractor m_data; ///< A data extractor capable of reading opcode bytes
365  DWARFUnit *m_dwarf_cu; ///< The DWARF compile unit this expression
366  ///belongs to. It is used
367  ///< to evaluate values indexing into the .debug_addr section (e.g.
368  ///< DW_OP_GNU_addr_index, DW_OP_GNU_const_index)
370  m_reg_kind; ///< One of the defines that starts with LLDB_REGKIND_
371  lldb::addr_t m_loclist_slide; ///< A value used to slide the location list
372  ///offsets so that
373  ///< they are relative to the object that owns the location list
374  ///< (the function for frame base and variable location lists)
375 };
376 
377 } // namespace lldb_private
378 
379 #endif // liblldb_DWARFExpression_h_
An data extractor class.
Definition: DataExtractor.h:47
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
void SetOpcodeData(const DataExtractor &data)
Make the expression parser read its location information from a given data source.
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
void SetRegisterKind(lldb::RegisterKind reg_kind)
Set the call-frame-info style register kind.
bool GetLocation(lldb::addr_t base_addr, lldb::addr_t pc, lldb::offset_t &offset, lldb::offset_t &len)
"lldb/Expression/DWARFExpression.h" Encapsulates a DWARF location expression and interprets it...
static size_t LocationListSize(const DWARFUnit *dwarf_cu, const DataExtractor &debug_loc_data, lldb::offset_t offset)
lldb::addr_t m_loclist_slide
A value used to slide the location list offsets so that.
static bool PrintDWARFExpression(Stream &s, const DataExtractor &data, int address_size, int dwarf_ref_size, bool location_expression)
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
bool GetOpAndEndOffsets(StackFrame &frame, lldb::offset_t &op_offset, lldb::offset_t &end_offset)
static void PrintDWARFLocationList(Stream &s, const DWARFUnit *cu, const DataExtractor &debug_loc_data, lldb::offset_t offset)
void SetLocationListSlide(lldb::addr_t slide)
Tells the expression that it refers to a location list.
lldb::ModuleWP m_module_wp
Classes that inherit from DWARFExpression can see and modify these.
bool DumpLocationForAddress(Stream *s, lldb::DescriptionLevel level, lldb::addr_t loclist_base_load_addr, lldb::addr_t address, ABI *abi)
bool IsValid() const
Return true if the location expression contains data.
uint64_t offset_t
Definition: lldb-types.h:87
void GetDescription(Stream *s, lldb::DescriptionLevel level, lldb::addr_t location_list_base_addr, ABI *abi) const
Print the description of the expression to a stream.
virtual ~DWARFExpression()
Destructor.
"lldb/Target/ExecutionContextScope.h" Inherit from this if your object can reconstruct its execution ...
void DumpLocation(Stream *s, lldb::offset_t offset, lldb::offset_t length, lldb::DescriptionLevel level, ABI *abi) const
Pretty-prints the location expression to a stream.
static bool AddressRangeForLocationListEntry(const DWARFUnit *dwarf_cu, const DataExtractor &debug_loc_data, lldb::offset_t *offset_ptr, lldb::addr_t &low_pc, lldb::addr_t &high_pc)
bool Update_DW_OP_addr(lldb::addr_t file_addr)
DataExtractor m_data
A data extractor capable of reading opcode bytes.
lldb::RegisterKind m_reg_kind
belongs to.
uint64_t GetByteSize() const
Get the number of bytes contained in this object.
bool Evaluate(ExecutionContextScope *exe_scope, lldb::addr_t loclist_base_load_addr, const Value *initial_value_ptr, const Value *object_address_ptr, Value &result, Status *error_ptr) const
Wrapper for the static evaluate function that accepts an ExecutionContextScope instead of an Executio...
uint64_t addr_t
Definition: lldb-types.h:83
void CopyOpcodeData(lldb::ModuleSP module_sp, const DataExtractor &data, lldb::offset_t data_offset, lldb::offset_t data_length)
Copy the DWARF location expression into a local buffer.
lldb::addr_t GetLocation_DW_OP_addr(uint32_t op_addr_idx, bool &error) const
If a location is not a location list, return true if the location contains a DW_OP_addr () opcode in ...
bool LocationListContainsAddress(lldb::addr_t loclist_base_addr, lldb::addr_t addr) const
Search for a load address in the location list.
bool MatchesOperand(StackFrame &frame, const Instruction::Operand &op)
DWARFExpression(DWARFUnit *dwarf_cu)
Constructor.
DWARFUnit * m_dwarf_cu
The DWARF compile unit this expression.
int GetRegisterKind()
Return the call-frame-info style register kind.
bool LinkThreadLocalStorage(lldb::ModuleSP new_module_sp, std::function< lldb::addr_t(lldb::addr_t file_addr)> const &link_address_callback)
void SetModule(const lldb::ModuleSP &module)
bool IsLocationList() const
Return true if a location list was provided.
bool GetExpressionData(DataExtractor &data) const
This base class provides an interface to stack frames.
Definition: StackFrame.h:40
An error handling class.
Definition: Status.h:44