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