DWARFExpression.h revision 263363
1//===-- DWARFExpression.h ---------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef liblldb_DWARFExpression_h_
11#define liblldb_DWARFExpression_h_
12
13#include "lldb/lldb-private.h"
14#include "lldb/Core/ClangForward.h"
15#include "lldb/Core/Address.h"
16#include "lldb/Core/DataExtractor.h"
17#include "lldb/Core/Error.h"
18#include "lldb/Core/Scalar.h"
19
20namespace lldb_private {
21
22class ClangExpressionVariable;
23class ClangExpressionVariableList;
24
25class ClangExpressionDeclMap;
26
27//----------------------------------------------------------------------
28/// @class DWARFExpression DWARFExpression.h "lldb/Expression/DWARFExpression.h"
29/// @brief Encapsulates a DWARF location expression and interprets it.
30///
31/// DWARF location expressions are used in two ways by LLDB.  The first
32/// use is to find entities specified in the debug information, since
33/// their locations are specified in precisely this language.  The second
34/// is to interpret expressions without having to run the target in cases
35/// where the overhead from copying JIT-compiled code into the target is
36/// too high or where the target cannot be run.  This class encapsulates
37/// a single DWARF location expression or a location list and interprets
38/// it.
39//----------------------------------------------------------------------
40class DWARFExpression
41{
42public:
43    //------------------------------------------------------------------
44    /// Constructor
45    //------------------------------------------------------------------
46    DWARFExpression();
47
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    //------------------------------------------------------------------
61    DWARFExpression(lldb::ModuleSP module,
62                    const DataExtractor& data,
63                    lldb::offset_t data_offset,
64                    lldb::offset_t data_length);
65
66    //------------------------------------------------------------------
67    /// Copy constructor
68    //------------------------------------------------------------------
69    DWARFExpression(const DWARFExpression& rhs);
70
71    //------------------------------------------------------------------
72    /// Destructor
73    //------------------------------------------------------------------
74    virtual
75    ~DWARFExpression();
76
77    //------------------------------------------------------------------
78    /// Print the description of the expression to a stream
79    ///
80    /// @param[in] s
81    ///     The stream to print to.
82    ///
83    /// @param[in] level
84    ///     The level of verbosity to use.
85    ///
86    /// @param[in] location_list_base_addr
87    ///     If this is a location list based expression, this is the
88    ///     address of the object that owns it. NOTE: this value is
89    ///     different from the DWARF version of the location list base
90    ///     address which is compile unit relative. This base address
91    ///     is the address of the object that owns the location list.
92    ///
93    /// @param[in] abi
94    ///     An optional ABI plug-in that can be used to resolve register
95    ///     names.
96    //------------------------------------------------------------------
97    void
98    GetDescription (Stream *s,
99                    lldb::DescriptionLevel level,
100                    lldb::addr_t location_list_base_addr,
101                    ABI *abi) const;
102
103    //------------------------------------------------------------------
104    /// Return true if the location expression contains data
105    //------------------------------------------------------------------
106    bool
107    IsValid() const;
108
109    //------------------------------------------------------------------
110    /// Return true if a location list was provided
111    //------------------------------------------------------------------
112    bool
113    IsLocationList() const;
114
115    //------------------------------------------------------------------
116    /// Search for a load address in the location list
117    ///
118    /// @param[in] process
119    ///     The process to use when resolving the load address
120    ///
121    /// @param[in] addr
122    ///     The address to resolve
123    ///
124    /// @return
125    ///     True if IsLocationList() is true and the address was found;
126    ///     false otherwise.
127    //------------------------------------------------------------------
128//    bool
129//    LocationListContainsLoadAddress (Process* process, const Address &addr) const;
130//
131    bool
132    LocationListContainsAddress (lldb::addr_t loclist_base_addr, lldb::addr_t addr) const;
133
134    //------------------------------------------------------------------
135    /// If a location is not a location list, return true if the location
136    /// contains a DW_OP_addr () opcode in the stream that matches \a
137    /// file_addr. If file_addr is LLDB_INVALID_ADDRESS, the this
138    /// function will return true if the variable there is any DW_OP_addr
139    /// in a location that (yet still is NOT a location list). This helps
140    /// us detect if a variable is a global or static variable since
141    /// there is no other indication from DWARF debug info.
142    ///
143    /// @param[in] op_addr_idx
144    ///     The DW_OP_addr index to retrieve in case there is more than
145    ///     one DW_OP_addr opcode in the location byte stream.
146    ///
147    /// @param[out] error
148    ///     If the location stream contains unknown DW_OP opcodes or the
149    ///     data is missing, \a error will be set to \b true.
150    ///
151    /// @return
152    ///     LLDB_INVALID_ADDRESS if the location doesn't contain a
153    ///     DW_OP_addr for \a op_addr_idx, otherwise a valid file address
154    //------------------------------------------------------------------
155    lldb::addr_t
156    GetLocation_DW_OP_addr (uint32_t op_addr_idx, bool &error) const;
157
158    bool
159    Update_DW_OP_addr (lldb::addr_t file_addr);
160
161    //------------------------------------------------------------------
162    /// Make the expression parser read its location information from a
163    /// given data source.  Does not change the offset and length
164    ///
165    /// @param[in] data
166    ///     A data extractor configured to read the DWARF location expression's
167    ///     bytecode.
168    //------------------------------------------------------------------
169    void
170    SetOpcodeData(const DataExtractor& data);
171
172    //------------------------------------------------------------------
173    /// Make the expression parser read its location information from a
174    /// given data source
175    ///
176    /// @param[in] module_sp
177    ///     The module that defines the DWARF expression.
178    ///
179    /// @param[in] data
180    ///     A data extractor configured to read the DWARF location expression's
181    ///     bytecode.
182    ///
183    /// @param[in] data_offset
184    ///     The offset of the location expression in the extractor.
185    ///
186    /// @param[in] data_length
187    ///     The byte length of the location expression.
188    //------------------------------------------------------------------
189    void
190    SetOpcodeData(lldb::ModuleSP module_sp, const DataExtractor& data, lldb::offset_t data_offset, lldb::offset_t data_length);
191
192    //------------------------------------------------------------------
193    /// Copy the DWARF location expression into a local buffer.
194    ///
195    /// It is a good idea to copy the data so we don't keep the entire
196    /// object file worth of data around just for a few bytes of location
197    /// expression. LLDB typically will mmap the entire contents of debug
198    /// information files, and if we use SetOpcodeData, it will get a
199    /// shared reference to all of this data for the and cause the object
200    /// file to have to stay around. Even worse, a very very large ".a"
201    /// that contains one or more .o files could end up being referenced.
202    /// Location lists are typically small so even though we are copying
203    /// the data, it shouldn't amount to that much for the variables we
204    /// end up parsing.
205    ///
206    /// @param[in] module_sp
207    ///     The module that defines the DWARF expression.
208    ///
209    /// @param[in] data
210    ///     A data extractor configured to read and copy the DWARF
211    ///     location expression's bytecode.
212    ///
213    /// @param[in] data_offset
214    ///     The offset of the location expression in the extractor.
215    ///
216    /// @param[in] data_length
217    ///     The byte length of the location expression.
218    //------------------------------------------------------------------
219    void
220    CopyOpcodeData (lldb::ModuleSP module_sp,
221                    const DataExtractor& data,
222                    lldb::offset_t data_offset,
223                    lldb::offset_t data_length);
224
225
226    //------------------------------------------------------------------
227    /// Tells the expression that it refers to a location list.
228    ///
229    /// @param[in] slide
230    ///     This value should be a slide that is applied to any values
231    ///     in the location list data so the values become zero based
232    ///     offsets into the object that owns the location list. We need
233    ///     to make location lists relative to the objects that own them
234    ///     so we can relink addresses on the fly.
235    //------------------------------------------------------------------
236    void
237    SetLocationListSlide (lldb::addr_t slide);
238
239    //------------------------------------------------------------------
240    /// Return the call-frame-info style register kind
241    //------------------------------------------------------------------
242    int
243    GetRegisterKind ();
244
245    //------------------------------------------------------------------
246    /// Set the call-frame-info style register kind
247    ///
248    /// @param[in] reg_kind
249    ///     The register kind.
250    //------------------------------------------------------------------
251    void
252    SetRegisterKind (lldb::RegisterKind reg_kind);
253
254    //------------------------------------------------------------------
255    /// Wrapper for the static evaluate function that accepts an
256    /// ExecutionContextScope instead of an ExecutionContext and uses
257    /// member variables to populate many operands
258    //------------------------------------------------------------------
259    bool
260    Evaluate (ExecutionContextScope *exe_scope,
261              ClangExpressionVariableList *expr_locals,
262              ClangExpressionDeclMap *decl_map,
263              lldb::addr_t loclist_base_load_addr,
264              const Value* initial_value_ptr,
265              Value& result,
266              Error *error_ptr) const;
267
268    //------------------------------------------------------------------
269    /// Wrapper for the static evaluate function that uses member
270    /// variables to populate many operands
271    //------------------------------------------------------------------
272    bool
273    Evaluate (ExecutionContext *exe_ctx,
274              ClangExpressionVariableList *expr_locals,
275              ClangExpressionDeclMap *decl_map,
276              RegisterContext *reg_ctx,
277              lldb::addr_t loclist_base_load_addr,
278              const Value* initial_value_ptr,
279              Value& result,
280              Error *error_ptr) const;
281
282    //------------------------------------------------------------------
283    /// Evaluate a DWARF location expression in a particular context
284    ///
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.
289    ///
290    /// @param[in] opcode_ctx
291    ///     The module which defined the expression.
292    ///
293    /// @param[in] opcodes
294    ///     This is a static method so the opcodes need to be provided
295    ///     explicitly.
296    ///
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.
303    ///
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.
309    ///
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.
316    ///
317    /// @param[in] offset
318    ///     The offset of the location expression in the data extractor.
319    ///
320    /// @param[in] length
321    ///     The length in bytes of the location expression.
322    ///
323    /// @param[in] reg_set
324    ///     The call-frame-info style register kind.
325    ///
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.
329    ///
330    /// @param[in] result
331    ///     A value into which the result of evaluating the expression is
332    ///     to be placed.
333    ///
334    /// @param[in] error_ptr
335    ///     If non-NULL, used to report errors in expression evaluation.
336    ///
337    /// @return
338    ///     True on success; false otherwise.  If error_ptr is non-NULL,
339    ///     details of the failure are provided through it.
340    //------------------------------------------------------------------
341    static bool
342    Evaluate (ExecutionContext *exe_ctx,
343              ClangExpressionVariableList *expr_locals,
344              ClangExpressionDeclMap *decl_map,
345              RegisterContext *reg_ctx,
346              lldb::ModuleSP opcode_ctx,
347              const DataExtractor& opcodes,
348              const lldb::offset_t offset,
349              const lldb::offset_t length,
350              const uint32_t reg_set,
351              const Value* initial_value_ptr,
352              Value& result,
353              Error *error_ptr);
354
355    //------------------------------------------------------------------
356    /// Loads a ClangExpressionVariableList into the object
357    ///
358    /// @param[in] locals
359    ///     If non-NULL, the list of locals used by this expression.
360    ///     See Evaluate().
361    //------------------------------------------------------------------
362    void
363    SetExpressionLocalVariableList (ClangExpressionVariableList *locals);
364
365    //------------------------------------------------------------------
366    /// Loads a ClangExpressionDeclMap into the object
367    ///
368    /// @param[in] locals
369    ///     If non-NULL, the list of external variables used by this
370    ///     expression.  See Evaluate().
371    //------------------------------------------------------------------
372    void
373    SetExpressionDeclMap (ClangExpressionDeclMap *decl_map);
374
375    bool
376    GetExpressionData (DataExtractor &data) const
377    {
378        data = m_data;
379        return data.GetByteSize() > 0;
380    }
381
382    bool
383    DumpLocationForAddress (Stream *s,
384                            lldb::DescriptionLevel level,
385                            lldb::addr_t loclist_base_load_addr,
386                            lldb::addr_t address,
387                            ABI *abi);
388
389protected:
390    //------------------------------------------------------------------
391    /// Pretty-prints the location expression to a stream
392    ///
393    /// @param[in] stream
394    ///     The stream to use for pretty-printing.
395    ///
396    /// @param[in] offset
397    ///     The offset into the data buffer of the opcodes to be printed.
398    ///
399    /// @param[in] length
400    ///     The length in bytes of the opcodes to be printed.
401    ///
402    /// @param[in] level
403    ///     The level of detail to use in pretty-printing.
404    ///
405    /// @param[in] abi
406    ///     An optional ABI plug-in that can be used to resolve register
407    ///     names.
408    //------------------------------------------------------------------
409    void
410    DumpLocation(Stream *s,
411                 lldb::offset_t offset,
412                 lldb::offset_t length,
413                 lldb::DescriptionLevel level,
414                 ABI *abi) const;
415
416    bool
417    GetLocation (lldb::addr_t base_addr,
418                 lldb::addr_t pc,
419                 lldb::offset_t &offset,
420                 lldb::offset_t &len);
421
422    //------------------------------------------------------------------
423    /// Classes that inherit from DWARFExpression can see and modify these
424    //------------------------------------------------------------------
425
426    lldb::ModuleWP m_module_wp;                 ///< Module which defined this expression.
427    DataExtractor m_data;                       ///< A data extractor capable of reading opcode bytes
428    lldb::RegisterKind m_reg_kind;              ///< One of the defines that starts with LLDB_REGKIND_
429    lldb::addr_t m_loclist_slide;               ///< A value used to slide the location list offsets so that
430                                                ///< they are relative to the object that owns the location list
431                                                ///< (the function for frame base and variable location lists)
432
433};
434
435} // namespace lldb_private
436
437#endif  // liblldb_DWARFExpression_h_
438