]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/include/lldb/Expression/DWARFExpression.h
Merge ^/head r352764 through r353315.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / include / lldb / Expression / DWARFExpression.h
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"
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
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.
35 class DWARFExpression {
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   DWARFExpression();
47
48   /// Constructor
49   ///
50   /// \param[in] data
51   ///     A data extractor configured to read the DWARF location expression's
52   ///     bytecode.
53   ///
54   /// \param[in] data_offset
55   ///     The offset of the location expression in the extractor.
56   ///
57   /// \param[in] data_length
58   ///     The byte length of the location expression.
59   DWARFExpression(lldb::ModuleSP module, const DataExtractor &data,
60                   const DWARFUnit *dwarf_cu, lldb::offset_t data_offset,
61                   lldb::offset_t data_length);
62
63   /// Destructor
64   virtual ~DWARFExpression();
65
66   /// Print the description of the expression to a stream
67   ///
68   /// \param[in] s
69   ///     The stream to print to.
70   ///
71   /// \param[in] level
72   ///     The level of verbosity to use.
73   ///
74   /// \param[in] location_list_base_addr
75   ///     If this is a location list based expression, this is the
76   ///     address of the object that owns it. NOTE: this value is
77   ///     different from the DWARF version of the location list base
78   ///     address which is compile unit relative. This base address
79   ///     is the address of the object that owns the location list.
80   ///
81   /// \param[in] abi
82   ///     An optional ABI plug-in that can be used to resolve register
83   ///     names.
84   void GetDescription(Stream *s, lldb::DescriptionLevel level,
85                       lldb::addr_t location_list_base_addr, ABI *abi) const;
86
87   /// Return true if the location expression contains data
88   bool IsValid() const;
89
90   /// Return true if a location list was provided
91   bool IsLocationList() const;
92
93   /// Search for a load address in the location list
94   ///
95   /// \param[in] process
96   ///     The process to use when resolving the load address
97   ///
98   /// \param[in] addr
99   ///     The address to resolve
100   ///
101   /// \return
102   ///     True if IsLocationList() is true and the address was found;
103   ///     false otherwise.
104   //    bool
105   //    LocationListContainsLoadAddress (Process* process, const Address &addr)
106   //    const;
107   //
108   bool LocationListContainsAddress(lldb::addr_t loclist_base_addr,
109                                    lldb::addr_t addr) const;
110
111   /// If a location is not a location list, return true if the location
112   /// contains a DW_OP_addr () opcode in the stream that matches \a file_addr.
113   /// If file_addr is LLDB_INVALID_ADDRESS, the this function will return true
114   /// if the variable there is any DW_OP_addr in a location that (yet still is
115   /// NOT a location list). This helps us detect if a variable is a global or
116   /// static variable since there is no other indication from DWARF debug
117   /// info.
118   ///
119   /// \param[in] op_addr_idx
120   ///     The DW_OP_addr index to retrieve in case there is more than
121   ///     one DW_OP_addr opcode in the location byte stream.
122   ///
123   /// \param[out] error
124   ///     If the location stream contains unknown DW_OP opcodes or the
125   ///     data is missing, \a error will be set to \b true.
126   ///
127   /// \return
128   ///     LLDB_INVALID_ADDRESS if the location doesn't contain a
129   ///     DW_OP_addr for \a op_addr_idx, otherwise a valid file address
130   lldb::addr_t GetLocation_DW_OP_addr(uint32_t op_addr_idx, bool &error) const;
131
132   bool Update_DW_OP_addr(lldb::addr_t file_addr);
133
134   void UpdateValue(uint64_t const_value, lldb::offset_t const_value_byte_size,
135                    uint8_t addr_byte_size);
136
137   void SetModule(const lldb::ModuleSP &module) { m_module_wp = module; }
138
139   bool ContainsThreadLocalStorage() const;
140
141   bool LinkThreadLocalStorage(
142       lldb::ModuleSP new_module_sp,
143       std::function<lldb::addr_t(lldb::addr_t file_addr)> const
144           &link_address_callback);
145
146   /// Tells the expression that it refers to a location list.
147   ///
148   /// \param[in] slide
149   ///     This value should be a slide that is applied to any values
150   ///     in the location list data so the values become zero based
151   ///     offsets into the object that owns the location list. We need
152   ///     to make location lists relative to the objects that own them
153   ///     so we can relink addresses on the fly.
154   void SetLocationListSlide(lldb::addr_t slide);
155
156   /// Return the call-frame-info style register kind
157   int GetRegisterKind();
158
159   /// Set the call-frame-info style register kind
160   ///
161   /// \param[in] reg_kind
162   ///     The register kind.
163   void SetRegisterKind(lldb::RegisterKind reg_kind);
164
165   /// Wrapper for the static evaluate function that accepts an
166   /// ExecutionContextScope instead of an ExecutionContext and uses member
167   /// variables to populate many operands
168   bool Evaluate(ExecutionContextScope *exe_scope,
169                 lldb::addr_t loclist_base_load_addr,
170                 const Value *initial_value_ptr, const Value *object_address_ptr,
171                 Value &result, Status *error_ptr) const;
172
173   /// Wrapper for the static evaluate function that uses member variables to
174   /// populate many operands
175   bool Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
176                 lldb::addr_t loclist_base_load_addr,
177                 const Value *initial_value_ptr, const Value *object_address_ptr,
178                 Value &result, Status *error_ptr) const;
179
180   /// Evaluate a DWARF location expression in a particular context
181   ///
182   /// \param[in] exe_ctx
183   ///     The execution context in which to evaluate the location
184   ///     expression.  The location expression may access the target's
185   ///     memory, especially if it comes from the expression parser.
186   ///
187   /// \param[in] opcode_ctx
188   ///     The module which defined the expression.
189   ///
190   /// \param[in] opcodes
191   ///     This is a static method so the opcodes need to be provided
192   ///     explicitly.
193   ///
194   /// \param[in] expr_locals
195   ///     If the location expression was produced by the expression parser,
196   ///     the list of local variables referenced by the DWARF expression.
197   ///     This list should already have been populated during parsing;
198   ///     the DWARF expression refers to variables by index.  Can be NULL if
199   ///     the location expression uses no locals.
200   ///
201   /// \param[in] decl_map
202   ///     If the location expression was produced by the expression parser,
203   ///     the list of external variables referenced by the location
204   ///     expression.  Can be NULL if the location expression uses no
205   ///     external variables.
206   ///
207   ///  \param[in] reg_ctx
208   ///     An optional parameter which provides a RegisterContext for use
209   ///     when evaluating the expression (i.e. for fetching register values).
210   ///     Normally this will come from the ExecutionContext's StackFrame but
211   ///     in the case where an expression needs to be evaluated while building
212   ///     the stack frame list, this short-cut is available.
213   ///
214   /// \param[in] offset
215   ///     The offset of the location expression in the data extractor.
216   ///
217   /// \param[in] length
218   ///     The length in bytes of the location expression.
219   ///
220   /// \param[in] reg_set
221   ///     The call-frame-info style register kind.
222   ///
223   /// \param[in] initial_value_ptr
224   ///     A value to put on top of the interpreter stack before evaluating
225   ///     the expression, if the expression is parametrized.  Can be NULL.
226   ///
227   /// \param[in] result
228   ///     A value into which the result of evaluating the expression is
229   ///     to be placed.
230   ///
231   /// \param[in] error_ptr
232   ///     If non-NULL, used to report errors in expression evaluation.
233   ///
234   /// \return
235   ///     True on success; false otherwise.  If error_ptr is non-NULL,
236   ///     details of the failure are provided through it.
237   static bool Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
238                        lldb::ModuleSP opcode_ctx, const DataExtractor &opcodes,
239                        const DWARFUnit *dwarf_cu, const lldb::offset_t offset,
240                        const lldb::offset_t length,
241                        const lldb::RegisterKind reg_set,
242                        const Value *initial_value_ptr,
243                        const Value *object_address_ptr, Value &result,
244                        Status *error_ptr);
245
246   bool GetExpressionData(DataExtractor &data) const {
247     data = m_data;
248     return data.GetByteSize() > 0;
249   }
250
251   bool DumpLocationForAddress(Stream *s, lldb::DescriptionLevel level,
252                               lldb::addr_t loclist_base_load_addr,
253                               lldb::addr_t address, ABI *abi);
254
255   static size_t LocationListSize(const DWARFUnit *dwarf_cu,
256                                  const DataExtractor &debug_loc_data,
257                                  lldb::offset_t offset);
258
259   static bool PrintDWARFExpression(Stream &s, const DataExtractor &data,
260                                    int address_size, int dwarf_ref_size,
261                                    bool location_expression);
262
263   static void PrintDWARFLocationList(Stream &s, const DWARFUnit *cu,
264                                      const DataExtractor &debug_loc_data,
265                                      lldb::offset_t offset);
266
267   bool MatchesOperand(StackFrame &frame, const Instruction::Operand &op);
268
269 private:
270   /// Pretty-prints the location expression to a stream
271   ///
272   /// \param[in] stream
273   ///     The stream to use for pretty-printing.
274   ///
275   /// \param[in] offset
276   ///     The offset into the data buffer of the opcodes to be printed.
277   ///
278   /// \param[in] length
279   ///     The length in bytes of the opcodes to be printed.
280   ///
281   /// \param[in] level
282   ///     The level of detail to use in pretty-printing.
283   ///
284   /// \param[in] abi
285   ///     An optional ABI plug-in that can be used to resolve register
286   ///     names.
287   void DumpLocation(Stream *s, lldb::offset_t offset, lldb::offset_t length,
288                     lldb::DescriptionLevel level, ABI *abi) const;
289
290   bool GetLocation(lldb::addr_t base_addr, lldb::addr_t pc,
291                    lldb::offset_t &offset, lldb::offset_t &len);
292
293   static bool AddressRangeForLocationListEntry(
294       const DWARFUnit *dwarf_cu, const DataExtractor &debug_loc_data,
295       lldb::offset_t *offset_ptr, lldb::addr_t &low_pc, lldb::addr_t &high_pc);
296
297   bool GetOpAndEndOffsets(StackFrame &frame, lldb::offset_t &op_offset,
298                           lldb::offset_t &end_offset);
299
300   /// Module which defined this expression.
301   lldb::ModuleWP m_module_wp;
302
303   /// A data extractor capable of reading opcode bytes
304   DataExtractor m_data;
305
306   /// The DWARF compile unit this expression belongs to. It is used to evaluate
307   /// values indexing into the .debug_addr section (e.g. DW_OP_GNU_addr_index,
308   /// DW_OP_GNU_const_index)
309   const DWARFUnit *m_dwarf_cu;
310
311   /// One of the defines that starts with LLDB_REGKIND_
312   lldb::RegisterKind m_reg_kind;
313
314   /// A value used to slide the location list offsets so that m_c they are
315   /// relative to the object that owns the location list (the function for
316   /// frame base and variable location lists)
317   lldb::addr_t m_loclist_slide;
318 };
319
320 } // namespace lldb_private
321
322 #endif // liblldb_DWARFExpression_h_