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