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/AddressRange.h" 13 #include "lldb/Core/Value.h" 14 #include "lldb/Expression/DWARFExpression.h" 15 #include "lldb/Utility/RangeMap.h" 16 #include "lldb/lldb-private.h" 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 DWARFExpression::Delegate * dwarf_cu,lldb::addr_t func_file_addr)27 DWARFExpressionList(lldb::ModuleSP module_sp, 28 const DWARFExpression::Delegate *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 DWARFExpressionList(lldb::ModuleSP module_sp,DWARFExpression expr,const DWARFExpression::Delegate * dwarf_cu)33 DWARFExpressionList(lldb::ModuleSP module_sp, DWARFExpression expr, 34 const DWARFExpression::Delegate *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 IsValid()40 bool IsValid() const { return !m_exprs.IsEmpty(); } 41 Clear()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. Sort()55 void Sort() { m_exprs.Sort(); } 56 SetFuncFileAddress(lldb::addr_t func_file_addr)57 void SetFuncFileAddress(lldb::addr_t func_file_addr) { 58 m_func_file_addr = func_file_addr; 59 } 60 GetFuncFileAddress()61 lldb::addr_t GetFuncFileAddress() { return m_func_file_addr; } 62 63 /// Represents an entry in the DWARFExpressionList with all needed metadata. 64 struct DWARFExpressionEntry { 65 /// Represents a DWARF location range in the DWARF unit’s file‐address space 66 std::optional<AddressRange> file_range; ///< None = always-valid single expr 67 const DWARFExpression *expr; 68 }; 69 70 /// Returns a DWARFExpressionEntry whose file_range contains the given 71 /// load‐address. `func_load_addr` is the load‐address of the function 72 /// start; `load_addr` is the full runtime PC. On success, `expr` is 73 /// non-null. 74 std::optional<DWARFExpressionEntry> 75 GetExpressionEntryAtAddress(lldb::addr_t func_load_addr, 76 lldb::addr_t load_addr) const; 77 78 const DWARFExpression *GetExpressionAtAddress(lldb::addr_t func_load_addr, 79 lldb::addr_t load_addr) const; 80 81 const DWARFExpression *GetAlwaysValidExpr() const; 82 83 DWARFExpression *GetMutableExpressionAtAddress( 84 lldb::addr_t func_load_addr = LLDB_INVALID_ADDRESS, 85 lldb::addr_t load_addr = 0); 86 GetSize()87 size_t GetSize() const { return m_exprs.GetSize(); } 88 89 bool ContainsThreadLocalStorage() const; 90 91 bool LinkThreadLocalStorage( 92 lldb::ModuleSP new_module_sp, 93 std::function<lldb::addr_t(lldb::addr_t file_addr)> const 94 &link_address_callback); 95 96 bool MatchesOperand(StackFrame &frame, 97 const Instruction::Operand &operand) const; 98 99 /// Dump locations that contains file_addr if it's valid. Otherwise. dump all 100 /// locations. 101 bool DumpLocations(Stream *s, lldb::DescriptionLevel level, 102 lldb::addr_t func_load_addr, lldb::addr_t file_addr, 103 ABI *abi) const; 104 105 /// Dump all locaitons with each separated by new line. 106 void GetDescription(Stream *s, lldb::DescriptionLevel level, ABI *abi) const; 107 108 /// Search for a load address in the dwarf location list 109 /// 110 /// \param[in] func_load_addr 111 /// The actual address of the function containing this location list. 112 /// 113 /// \param[in] addr 114 /// The address to resolve. 115 /// 116 /// \return 117 /// True if IsLocationList() is true and the address was found; 118 /// false otherwise. 119 bool ContainsAddress(lldb::addr_t func_load_addr, lldb::addr_t addr) const; 120 SetModule(const lldb::ModuleSP & module)121 void SetModule(const lldb::ModuleSP &module) { m_module_wp = module; } 122 123 llvm::Expected<Value> Evaluate(ExecutionContext *exe_ctx, 124 RegisterContext *reg_ctx, 125 lldb::addr_t func_load_addr, 126 const Value *initial_value_ptr, 127 const Value *object_address_ptr) const; 128 129 private: 130 // RangeDataVector requires a comparator for DWARFExpression, but it doesn't 131 // make sense to do so. 132 struct DWARFExpressionCompare { 133 public: operatorDWARFExpressionCompare134 bool operator()(const DWARFExpression &lhs, 135 const DWARFExpression &rhs) const { 136 return false; 137 } 138 }; 139 using ExprVec = RangeDataVector<lldb::addr_t, lldb::addr_t, DWARFExpression, 140 0, DWARFExpressionCompare>; 141 using Entry = ExprVec::Entry; 142 143 // File address range mapping to single dwarf expression. 144 ExprVec m_exprs; 145 146 /// Module which defined this expression. 147 lldb::ModuleWP m_module_wp; 148 149 /// The DWARF compile unit this expression belongs to. It is used to evaluate 150 /// values indexing into the .debug_addr section (e.g. DW_OP_GNU_addr_index, 151 /// DW_OP_GNU_const_index) 152 const DWARFExpression::Delegate *m_dwarf_cu = nullptr; 153 154 // Function base file address. 155 lldb::addr_t m_func_file_addr = LLDB_INVALID_ADDRESS; 156 157 using const_iterator = ExprVec::Collection::const_iterator; begin()158 const_iterator begin() const { return m_exprs.begin(); } end()159 const_iterator end() const { return m_exprs.end(); } 160 }; 161 } // namespace lldb_private 162 163 #endif // LLDB_EXPRESSION_DWARFEXPRESSIONLIST_H 164