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