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