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