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 LLDB_EXPRESSION_DWARFEXPRESSION_H
10 #define LLDB_EXPRESSION_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 "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
19 #include <functional>
20 
21 class DWARFUnit;
22 
23 namespace lldb_private {
24 
25 /// \class DWARFExpression DWARFExpression.h
26 /// "lldb/Expression/DWARFExpression.h" Encapsulates a DWARF location
27 /// expression and interprets it.
28 ///
29 /// DWARF location expressions are used in two ways by LLDB.  The first
30 /// use is to find entities specified in the debug information, since their
31 /// locations are specified in precisely this language.  The second is to
32 /// interpret expressions without having to run the target in cases where the
33 /// overhead from copying JIT-compiled code into the target is too high or
34 /// where the target cannot be run.  This class encapsulates a single DWARF
35 /// location expression or a location list and interprets it.
36 class DWARFExpression {
37 public:
38   DWARFExpression();
39 
40   /// Constructor
41   ///
42   /// \param[in] data
43   ///     A data extractor configured to read the DWARF location expression's
44   ///     bytecode.
45   DWARFExpression(const DataExtractor &data);
46 
47   /// Destructor
48   virtual ~DWARFExpression();
49 
50   /// Return true if the location expression contains data
51   bool IsValid() const;
52 
53   /// If a location is not a location list, return true if the location
54   /// contains a DW_OP_addr () opcode in the stream that matches \a file_addr.
55   /// If file_addr is LLDB_INVALID_ADDRESS, the this function will return true
56   /// if the variable there is any DW_OP_addr in a location that (yet still is
57   /// NOT a location list). This helps us detect if a variable is a global or
58   /// static variable since there is no other indication from DWARF debug
59   /// info.
60   ///
61   /// \param[in] dwarf_cu
62   ///     The dwarf unit this expression belongs to.
63   ///
64   /// \param[in] op_addr_idx
65   ///     The DW_OP_addr index to retrieve in case there is more than
66   ///     one DW_OP_addr opcode in the location byte stream.
67   ///
68   /// \param[out] error
69   ///     If the location stream contains unknown DW_OP opcodes or the
70   ///     data is missing, \a error will be set to \b true.
71   ///
72   /// \return
73   ///     LLDB_INVALID_ADDRESS if the location doesn't contain a
74   ///     DW_OP_addr for \a op_addr_idx, otherwise a valid file address
75   lldb::addr_t GetLocation_DW_OP_addr(const DWARFUnit *dwarf_cu,
76                                       uint32_t op_addr_idx, bool &error) const;
77 
78   bool Update_DW_OP_addr(lldb::addr_t file_addr);
79 
80   void UpdateValue(uint64_t const_value, lldb::offset_t const_value_byte_size,
81                    uint8_t addr_byte_size);
82 
83   bool ContainsThreadLocalStorage() const;
84 
85   bool LinkThreadLocalStorage(
86       std::function<lldb::addr_t(lldb::addr_t file_addr)> const
87           &link_address_callback);
88 
89   /// Return the call-frame-info style register kind
90   lldb::RegisterKind GetRegisterKind() const;
91 
92   /// Set the call-frame-info style register kind
93   ///
94   /// \param[in] reg_kind
95   ///     The register kind.
96   void SetRegisterKind(lldb::RegisterKind reg_kind);
97 
98   /// Evaluate a DWARF location expression in a particular context
99   ///
100   /// \param[in] exe_ctx
101   ///     The execution context in which to evaluate the location
102   ///     expression.  The location expression may access the target's
103   ///     memory, especially if it comes from the expression parser.
104   ///
105   /// \param[in] opcode_ctx
106   ///     The module which defined the expression.
107   ///
108   /// \param[in] opcodes
109   ///     This is a static method so the opcodes need to be provided
110   ///     explicitly.
111   ///
112   ///  \param[in] reg_ctx
113   ///     An optional parameter which provides a RegisterContext for use
114   ///     when evaluating the expression (i.e. for fetching register values).
115   ///     Normally this will come from the ExecutionContext's StackFrame but
116   ///     in the case where an expression needs to be evaluated while building
117   ///     the stack frame list, this short-cut is available.
118   ///
119   /// \param[in] reg_set
120   ///     The call-frame-info style register kind.
121   ///
122   /// \param[in] initial_value_ptr
123   ///     A value to put on top of the interpreter stack before evaluating
124   ///     the expression, if the expression is parametrized.  Can be NULL.
125   ///
126   /// \param[in] result
127   ///     A value into which the result of evaluating the expression is
128   ///     to be placed.
129   ///
130   /// \param[in] error_ptr
131   ///     If non-NULL, used to report errors in expression evaluation.
132   ///
133   /// \return
134   ///     True on success; false otherwise.  If error_ptr is non-NULL,
135   ///     details of the failure are provided through it.
136   static bool Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
137                        lldb::ModuleSP module_sp, const DataExtractor &opcodes,
138                        const DWARFUnit *dwarf_cu,
139                        const lldb::RegisterKind reg_set,
140                        const Value *initial_value_ptr,
141                        const Value *object_address_ptr, Value &result,
142                        Status *error_ptr);
143 
144   static bool ParseDWARFLocationList(const DWARFUnit *dwarf_cu,
145                                      const DataExtractor &data,
146                                      DWARFExpressionList *loc_list);
147 
148   bool GetExpressionData(DataExtractor &data) const {
149     data = m_data;
150     return data.GetByteSize() > 0;
151   }
152 
153   void DumpLocation(Stream *s, lldb::DescriptionLevel level, ABI *abi) const;
154 
155   bool MatchesOperand(StackFrame &frame, const Instruction::Operand &op) const;
156 
157 private:
158   /// A data extractor capable of reading opcode bytes
159   DataExtractor m_data;
160 
161   /// One of the defines that starts with LLDB_REGKIND_
162   lldb::RegisterKind m_reg_kind = lldb::eRegisterKindDWARF;
163 };
164 
165 } // namespace lldb_private
166 
167 #endif // LLDB_EXPRESSION_DWARFEXPRESSION_H
168