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