• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- DWARFExpressionList.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_DWARFEXPRESSIONLIST_H
10 #define LLDB_EXPRESSION_DWARFEXPRESSIONLIST_H
11 
12 #include "lldb/Expression/DWARFExpression.h"
13 #include "lldb/Utility/RangeMap.h"
14 #include "lldb/lldb-private.h"
15 
16 namespace lldb_private {
17 
18 namespace plugin {
19 namespace dwarf {
20 class DWARFUnit;
21 } // namespace dwarf
22 } // namespace plugin
23 
24 /// \class DWARFExpressionList DWARFExpressionList.h
25 /// "lldb/Expression/DWARFExpressionList.h" Encapsulates a range map from file
26 /// address range to a single DWARF location expression.
27 class DWARFExpressionList {
28 public:
29   DWARFExpressionList() = default;
30 
DWARFExpressionList(lldb::ModuleSP module_sp,const plugin::dwarf::DWARFUnit * dwarf_cu,lldb::addr_t func_file_addr)31   DWARFExpressionList(lldb::ModuleSP module_sp,
32                       const plugin::dwarf::DWARFUnit *dwarf_cu,
33                       lldb::addr_t func_file_addr)
34       : m_module_wp(module_sp), m_dwarf_cu(dwarf_cu),
35         m_func_file_addr(func_file_addr) {}
36 
DWARFExpressionList(lldb::ModuleSP module_sp,DWARFExpression expr,const plugin::dwarf::DWARFUnit * dwarf_cu)37   DWARFExpressionList(lldb::ModuleSP module_sp, DWARFExpression expr,
38                       const plugin::dwarf::DWARFUnit *dwarf_cu)
39       : m_module_wp(module_sp), m_dwarf_cu(dwarf_cu) {
40     AddExpression(0, LLDB_INVALID_ADDRESS, expr);
41   }
42 
43   /// Return true if the location expression contains data
IsValid()44   bool IsValid() const { return !m_exprs.IsEmpty(); }
45 
Clear()46   void Clear() { m_exprs.Clear(); }
47 
48   // Return true if the location expression is always valid.
49   bool IsAlwaysValidSingleExpr() const;
50 
51   bool AddExpression(lldb::addr_t base, lldb::addr_t end, DWARFExpression expr);
52 
53   /// Get the expression data at the file address.
54   bool GetExpressionData(DataExtractor &data,
55                          lldb::addr_t func_load_addr = LLDB_INVALID_ADDRESS,
56                          lldb::addr_t file_addr = 0) const;
57 
58   /// Sort m_expressions.
Sort()59   void Sort() { m_exprs.Sort(); }
60 
SetFuncFileAddress(lldb::addr_t func_file_addr)61   void SetFuncFileAddress(lldb::addr_t func_file_addr) {
62     m_func_file_addr = func_file_addr;
63   }
64 
GetFuncFileAddress()65   lldb::addr_t GetFuncFileAddress() { return m_func_file_addr; }
66 
67   const DWARFExpression *GetExpressionAtAddress(lldb::addr_t func_load_addr,
68                                                 lldb::addr_t load_addr) const;
69 
70   const DWARFExpression *GetAlwaysValidExpr() const;
71 
72   DWARFExpression *GetMutableExpressionAtAddress(
73       lldb::addr_t func_load_addr = LLDB_INVALID_ADDRESS,
74       lldb::addr_t load_addr = 0);
75 
GetSize()76   size_t GetSize() const { return m_exprs.GetSize(); }
77 
78   bool ContainsThreadLocalStorage() const;
79 
80   bool LinkThreadLocalStorage(
81       lldb::ModuleSP new_module_sp,
82       std::function<lldb::addr_t(lldb::addr_t file_addr)> const
83           &link_address_callback);
84 
85   bool MatchesOperand(StackFrame &frame,
86                       const Instruction::Operand &operand) const;
87 
88   /// Dump locations that contains file_addr if it's valid. Otherwise. dump all
89   /// locations.
90   bool DumpLocations(Stream *s, lldb::DescriptionLevel level,
91                      lldb::addr_t func_load_addr, lldb::addr_t file_addr,
92                      ABI *abi) const;
93 
94   /// Dump all locaitons with each seperated by new line.
95   void GetDescription(Stream *s, lldb::DescriptionLevel level, ABI *abi) const;
96 
97   /// Search for a load address in the dwarf location list
98   ///
99   /// \param[in] func_load_addr
100   ///     The actual address of the function containing this location list.
101   ///
102   /// \param[in] addr
103   ///     The address to resolve.
104   ///
105   /// \return
106   ///     True if IsLocationList() is true and the address was found;
107   ///     false otherwise.
108   //    bool
109   //    LocationListContainsLoadAddress (Process* process, const Address &addr)
110   //    const;
111   //
112   bool ContainsAddress(lldb::addr_t func_load_addr, lldb::addr_t addr) const;
113 
SetModule(const lldb::ModuleSP & module)114   void SetModule(const lldb::ModuleSP &module) { m_module_wp = module; }
115 
116   bool Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
117                 lldb::addr_t func_load_addr, const Value *initial_value_ptr,
118                 const Value *object_address_ptr, Value &result,
119                 Status *error_ptr) const;
120 
121 private:
122   // RangeDataVector requires a comparator for DWARFExpression, but it doesn't
123   // make sense to do so.
124   struct DWARFExpressionCompare {
125   public:
operatorDWARFExpressionCompare126     bool operator()(const DWARFExpression &lhs,
127                     const DWARFExpression &rhs) const {
128       return false;
129     }
130   };
131   using ExprVec = RangeDataVector<lldb::addr_t, lldb::addr_t, DWARFExpression,
132                                   0, DWARFExpressionCompare>;
133   using Entry = ExprVec::Entry;
134 
135   // File address range mapping to single dwarf expression.
136   ExprVec m_exprs;
137 
138   /// Module which defined this expression.
139   lldb::ModuleWP m_module_wp;
140 
141   /// The DWARF compile unit this expression belongs to. It is used to evaluate
142   /// values indexing into the .debug_addr section (e.g. DW_OP_GNU_addr_index,
143   /// DW_OP_GNU_const_index)
144   const plugin::dwarf::DWARFUnit *m_dwarf_cu = nullptr;
145 
146   // Function base file address.
147   lldb::addr_t m_func_file_addr = LLDB_INVALID_ADDRESS;
148 
149   using const_iterator = ExprVec::Collection::const_iterator;
begin()150   const_iterator begin() const { return m_exprs.begin(); }
end()151   const_iterator end() const { return m_exprs.end(); }
152 };
153 } // namespace lldb_private
154 
155 #endif // LLDB_EXPRESSION_DWARFEXPRESSIONLIST_H
156