1 //===-- DWARFExpression.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_DWARFEXPRESSION_H 10 #define LLDB_EXPRESSION_DWARFEXPRESSION_H 11 12 #include "lldb/Core/Address.h" 13 #include "lldb/Core/Disassembler.h" 14 #include "lldb/Utility/DataExtractor.h" 15 #include "lldb/Utility/Scalar.h" 16 #include "lldb/Utility/Status.h" 17 #include "lldb/lldb-private.h" 18 #include <functional> 19 20 class DWARFUnit; 21 22 namespace lldb_private { 23 24 /// \class DWARFExpression DWARFExpression.h 25 /// "lldb/Expression/DWARFExpression.h" Encapsulates a DWARF location 26 /// expression and interprets it. 27 /// 28 /// DWARF location expressions are used in two ways by LLDB. The first 29 /// use is to find entities specified in the debug information, since their 30 /// locations are specified in precisely this language. The second is to 31 /// interpret expressions without having to run the target in cases where the 32 /// overhead from copying JIT-compiled code into the target is too high or 33 /// where the target cannot be run. This class encapsulates a single DWARF 34 /// location expression or a location list and interprets it. 35 class DWARFExpression { 36 public: 37 DWARFExpression(); 38 39 /// Constructor 40 /// 41 /// \param[in] data 42 /// A data extractor configured to read the DWARF location expression's 43 /// bytecode. 44 DWARFExpression(lldb::ModuleSP module, const DataExtractor &data, 45 const DWARFUnit *dwarf_cu); 46 47 /// Destructor 48 virtual ~DWARFExpression(); 49 50 /// Print the description of the expression to a stream 51 /// 52 /// \param[in] s 53 /// The stream to print to. 54 /// 55 /// \param[in] level 56 /// The level of verbosity to use. 57 /// 58 /// \param[in] location_list_base_addr 59 /// If this is a location list based expression, this is the 60 /// address of the object that owns it. NOTE: this value is 61 /// different from the DWARF version of the location list base 62 /// address which is compile unit relative. This base address 63 /// is the address of the object that owns the location list. 64 /// 65 /// \param[in] abi 66 /// An optional ABI plug-in that can be used to resolve register 67 /// names. 68 void GetDescription(Stream *s, lldb::DescriptionLevel level, 69 lldb::addr_t location_list_base_addr, ABI *abi) const; 70 71 /// Return true if the location expression contains data 72 bool IsValid() const; 73 74 /// Return true if a location list was provided 75 bool IsLocationList() const; 76 77 /// Search for a load address in the location list 78 /// 79 /// \param[in] func_load_addr 80 /// The actual address of the function containing this location list. 81 /// 82 /// \param[in] addr 83 /// The address to resolve 84 /// 85 /// \return 86 /// True if IsLocationList() is true and the address was found; 87 /// false otherwise. 88 // bool 89 // LocationListContainsLoadAddress (Process* process, const Address &addr) 90 // const; 91 // 92 bool LocationListContainsAddress(lldb::addr_t func_load_addr, 93 lldb::addr_t addr) const; 94 95 /// If a location is not a location list, return true if the location 96 /// contains a DW_OP_addr () opcode in the stream that matches \a file_addr. 97 /// If file_addr is LLDB_INVALID_ADDRESS, the this function will return true 98 /// if the variable there is any DW_OP_addr in a location that (yet still is 99 /// NOT a location list). This helps us detect if a variable is a global or 100 /// static variable since there is no other indication from DWARF debug 101 /// info. 102 /// 103 /// \param[in] op_addr_idx 104 /// The DW_OP_addr index to retrieve in case there is more than 105 /// one DW_OP_addr opcode in the location byte stream. 106 /// 107 /// \param[out] error 108 /// If the location stream contains unknown DW_OP opcodes or the 109 /// data is missing, \a error will be set to \b true. 110 /// 111 /// \return 112 /// LLDB_INVALID_ADDRESS if the location doesn't contain a 113 /// DW_OP_addr for \a op_addr_idx, otherwise a valid file address 114 lldb::addr_t GetLocation_DW_OP_addr(uint32_t op_addr_idx, bool &error) const; 115 116 bool Update_DW_OP_addr(lldb::addr_t file_addr); 117 118 void UpdateValue(uint64_t const_value, lldb::offset_t const_value_byte_size, 119 uint8_t addr_byte_size); 120 121 void SetModule(const lldb::ModuleSP &module) { m_module_wp = module; } 122 123 bool ContainsThreadLocalStorage() const; 124 125 bool LinkThreadLocalStorage( 126 lldb::ModuleSP new_module_sp, 127 std::function<lldb::addr_t(lldb::addr_t file_addr)> const 128 &link_address_callback); 129 130 /// Tells the expression that it refers to a location list. 131 /// 132 /// \param[in] cu_file_addr 133 /// The base address to use for interpreting relative location list 134 /// entries. 135 /// \param[in] func_file_addr 136 /// The file address of the function containing this location list. This 137 /// address will be used to relocate the location list on the fly (in 138 /// conjuction with the func_load_addr arguments). 139 void SetLocationListAddresses(lldb::addr_t cu_file_addr, 140 lldb::addr_t func_file_addr); 141 142 /// Return the call-frame-info style register kind 143 int GetRegisterKind(); 144 145 /// Set the call-frame-info style register kind 146 /// 147 /// \param[in] reg_kind 148 /// The register kind. 149 void SetRegisterKind(lldb::RegisterKind reg_kind); 150 151 /// Wrapper for the static evaluate function that accepts an 152 /// ExecutionContextScope instead of an ExecutionContext and uses member 153 /// variables to populate many operands 154 bool Evaluate(ExecutionContextScope *exe_scope, lldb::addr_t func_load_addr, 155 const Value *initial_value_ptr, const Value *object_address_ptr, 156 Value &result, Status *error_ptr) const; 157 158 /// Wrapper for the static evaluate function that uses member variables to 159 /// populate many operands 160 bool Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx, 161 lldb::addr_t loclist_base_load_addr, 162 const Value *initial_value_ptr, const Value *object_address_ptr, 163 Value &result, Status *error_ptr) const; 164 165 /// Evaluate a DWARF location expression in a particular context 166 /// 167 /// \param[in] exe_ctx 168 /// The execution context in which to evaluate the location 169 /// expression. The location expression may access the target's 170 /// memory, especially if it comes from the expression parser. 171 /// 172 /// \param[in] opcode_ctx 173 /// The module which defined the expression. 174 /// 175 /// \param[in] opcodes 176 /// This is a static method so the opcodes need to be provided 177 /// explicitly. 178 /// 179 /// \param[in] reg_ctx 180 /// An optional parameter which provides a RegisterContext for use 181 /// when evaluating the expression (i.e. for fetching register values). 182 /// Normally this will come from the ExecutionContext's StackFrame but 183 /// in the case where an expression needs to be evaluated while building 184 /// the stack frame list, this short-cut is available. 185 /// 186 /// \param[in] reg_set 187 /// The call-frame-info style register kind. 188 /// 189 /// \param[in] initial_value_ptr 190 /// A value to put on top of the interpreter stack before evaluating 191 /// the expression, if the expression is parametrized. Can be NULL. 192 /// 193 /// \param[in] result 194 /// A value into which the result of evaluating the expression is 195 /// to be placed. 196 /// 197 /// \param[in] error_ptr 198 /// If non-NULL, used to report errors in expression evaluation. 199 /// 200 /// \return 201 /// True on success; false otherwise. If error_ptr is non-NULL, 202 /// details of the failure are provided through it. 203 static bool Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx, 204 lldb::ModuleSP opcode_ctx, const DataExtractor &opcodes, 205 const DWARFUnit *dwarf_cu, 206 const lldb::RegisterKind reg_set, 207 const Value *initial_value_ptr, 208 const Value *object_address_ptr, Value &result, 209 Status *error_ptr); 210 211 bool GetExpressionData(DataExtractor &data) const { 212 data = m_data; 213 return data.GetByteSize() > 0; 214 } 215 216 bool DumpLocationForAddress(Stream *s, lldb::DescriptionLevel level, 217 lldb::addr_t func_load_addr, lldb::addr_t address, 218 ABI *abi); 219 220 bool MatchesOperand(StackFrame &frame, const Instruction::Operand &op); 221 222 llvm::Optional<DataExtractor> 223 GetLocationExpression(lldb::addr_t load_function_start, 224 lldb::addr_t addr) const; 225 226 private: 227 /// Pretty-prints the location expression to a stream 228 /// 229 /// \param[in] s 230 /// The stream to use for pretty-printing. 231 /// 232 /// \param[in] data 233 /// The data extractor. 234 /// 235 /// \param[in] level 236 /// The level of detail to use in pretty-printing. 237 /// 238 /// \param[in] abi 239 /// An optional ABI plug-in that can be used to resolve register 240 /// names. 241 void DumpLocation(Stream *s, const DataExtractor &data, 242 lldb::DescriptionLevel level, ABI *abi) const; 243 244 /// Module which defined this expression. 245 lldb::ModuleWP m_module_wp; 246 247 /// A data extractor capable of reading opcode bytes 248 DataExtractor m_data; 249 250 /// The DWARF compile unit this expression belongs to. It is used to evaluate 251 /// values indexing into the .debug_addr section (e.g. DW_OP_GNU_addr_index, 252 /// DW_OP_GNU_const_index) 253 const DWARFUnit *m_dwarf_cu = nullptr; 254 255 /// One of the defines that starts with LLDB_REGKIND_ 256 lldb::RegisterKind m_reg_kind = lldb::eRegisterKindDWARF; 257 258 struct LoclistAddresses { 259 lldb::addr_t cu_file_addr; 260 lldb::addr_t func_file_addr; 261 }; 262 llvm::Optional<LoclistAddresses> m_loclist_addresses; 263 }; 264 265 } // namespace lldb_private 266 267 #endif // LLDB_EXPRESSION_DWARFEXPRESSION_H 268