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 16namespace lldb_private { 17 18namespace plugin { 19namespace dwarf { 20class 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. 27class DWARFExpressionList { 28public: 29 DWARFExpressionList() = default; 30 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 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 44 bool IsValid() const { return !m_exprs.IsEmpty(); } 45 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. 59 void Sort() { m_exprs.Sort(); } 60 61 void SetFuncFileAddress(lldb::addr_t func_file_addr) { 62 m_func_file_addr = func_file_addr; 63 } 64 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 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 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 121private: 122 // RangeDataVector requires a comparator for DWARFExpression, but it doesn't 123 // make sense to do so. 124 struct DWARFExpressionCompare { 125 public: 126 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; 150 const_iterator begin() const { return m_exprs.begin(); } 151 const_iterator end() const { return m_exprs.end(); } 152}; 153} // namespace lldb_private 154 155#endif // LLDB_EXPRESSION_DWARFEXPRESSIONLIST_H 156