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