1 //===-- DWARFExpression.h ---------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef liblldb_DWARFExpression_h_ 11 #define liblldb_DWARFExpression_h_ 12 13 #include "lldb/lldb-private.h" 14 #include "lldb/Core/ClangForward.h" 15 #include "lldb/Core/Address.h" 16 #include "lldb/Core/DataExtractor.h" 17 #include "lldb/Core/Error.h" 18 #include "lldb/Core/Scalar.h" 19 20 namespace lldb_private { 21 22 class ClangExpressionVariable; 23 class ClangExpressionVariableList; 24 25 class ClangExpressionDeclMap; 26 27 //---------------------------------------------------------------------- 28 /// @class DWARFExpression DWARFExpression.h "lldb/Expression/DWARFExpression.h" 29 /// @brief Encapsulates a DWARF location expression and interprets it. 30 /// 31 /// DWARF location expressions are used in two ways by LLDB. The first 32 /// use is to find entities specified in the debug information, since 33 /// their locations are specified in precisely this language. The second 34 /// is to interpret expressions without having to run the target in cases 35 /// where the overhead from copying JIT-compiled code into the target is 36 /// too high or where the target cannot be run. This class encapsulates 37 /// a single DWARF location expression or a location list and interprets 38 /// it. 39 //---------------------------------------------------------------------- 40 class DWARFExpression 41 { 42 public: 43 //------------------------------------------------------------------ 44 /// Constructor 45 //------------------------------------------------------------------ 46 DWARFExpression(); 47 48 //------------------------------------------------------------------ 49 /// Constructor 50 /// 51 /// @param[in] data 52 /// A data extractor configured to read the DWARF location expression's 53 /// bytecode. 54 /// 55 /// @param[in] data_offset 56 /// The offset of the location expression in the extractor. 57 /// 58 /// @param[in] data_length 59 /// The byte length of the location expression. 60 //------------------------------------------------------------------ 61 DWARFExpression(const DataExtractor& data, 62 lldb::offset_t data_offset, 63 lldb::offset_t data_length); 64 65 //------------------------------------------------------------------ 66 /// Copy constructor 67 //------------------------------------------------------------------ 68 DWARFExpression(const DWARFExpression& rhs); 69 70 //------------------------------------------------------------------ 71 /// Destructor 72 //------------------------------------------------------------------ 73 virtual 74 ~DWARFExpression(); 75 76 //------------------------------------------------------------------ 77 /// Print the description of the expression to a stream 78 /// 79 /// @param[in] s 80 /// The stream to print to. 81 /// 82 /// @param[in] level 83 /// The level of verbosity to use. 84 /// 85 /// @param[in] location_list_base_addr 86 /// If this is a location list based expression, this is the 87 /// address of the object that owns it. NOTE: this value is 88 /// different from the DWARF version of the location list base 89 /// address which is compile unit relative. This base address 90 /// is the address of the object that owns the location list. 91 /// 92 /// @param[in] abi 93 /// An optional ABI plug-in that can be used to resolve register 94 /// names. 95 //------------------------------------------------------------------ 96 void 97 GetDescription (Stream *s, 98 lldb::DescriptionLevel level, 99 lldb::addr_t location_list_base_addr, 100 ABI *abi) const; 101 102 //------------------------------------------------------------------ 103 /// Return true if the location expression contains data 104 //------------------------------------------------------------------ 105 bool 106 IsValid() const; 107 108 //------------------------------------------------------------------ 109 /// Return true if a location list was provided 110 //------------------------------------------------------------------ 111 bool 112 IsLocationList() const; 113 114 //------------------------------------------------------------------ 115 /// Search for a load address in the location list 116 /// 117 /// @param[in] process 118 /// The process to use when resolving the load address 119 /// 120 /// @param[in] addr 121 /// The address to resolve 122 /// 123 /// @return 124 /// True if IsLocationList() is true and the address was found; 125 /// false otherwise. 126 //------------------------------------------------------------------ 127 // bool 128 // LocationListContainsLoadAddress (Process* process, const Address &addr) const; 129 // 130 bool 131 LocationListContainsAddress (lldb::addr_t loclist_base_addr, lldb::addr_t addr) const; 132 133 //------------------------------------------------------------------ 134 /// If a location is not a location list, return true if the location 135 /// contains a DW_OP_addr () opcode in the stream that matches \a 136 /// file_addr. If file_addr is LLDB_INVALID_ADDRESS, the this 137 /// function will return true if the variable there is any DW_OP_addr 138 /// in a location that (yet still is NOT a location list). This helps 139 /// us detect if a variable is a global or static variable since 140 /// there is no other indication from DWARF debug info. 141 /// 142 /// @param[in] op_addr_idx 143 /// The DW_OP_addr index to retrieve in case there is more than 144 /// one DW_OP_addr opcode in the location byte stream. 145 /// 146 /// @param[out] error 147 /// If the location stream contains unknown DW_OP opcodes or the 148 /// data is missing, \a error will be set to \b true. 149 /// 150 /// @return 151 /// LLDB_INVALID_ADDRESS if the location doesn't contain a 152 /// DW_OP_addr for \a op_addr_idx, otherwise a valid file address 153 //------------------------------------------------------------------ 154 lldb::addr_t 155 GetLocation_DW_OP_addr (uint32_t op_addr_idx, bool &error) const; 156 157 bool 158 Update_DW_OP_addr (lldb::addr_t file_addr); 159 160 //------------------------------------------------------------------ 161 /// Make the expression parser read its location information from a 162 /// given data source. Does not change the offset and length 163 /// 164 /// @param[in] data 165 /// A data extractor configured to read the DWARF location expression's 166 /// bytecode. 167 //------------------------------------------------------------------ 168 void 169 SetOpcodeData(const DataExtractor& data); 170 171 //------------------------------------------------------------------ 172 /// Make the expression parser read its location information from a 173 /// given data source 174 /// 175 /// @param[in] data 176 /// A data extractor configured to read the DWARF location expression's 177 /// bytecode. 178 /// 179 /// @param[in] data_offset 180 /// The offset of the location expression in the extractor. 181 /// 182 /// @param[in] data_length 183 /// The byte length of the location expression. 184 //------------------------------------------------------------------ 185 void 186 SetOpcodeData(const DataExtractor& data, lldb::offset_t data_offset, lldb::offset_t data_length); 187 188 //------------------------------------------------------------------ 189 /// Copy the DWARF location expression into a local buffer. 190 /// 191 /// It is a good idea to copy the data so we don't keep the entire 192 /// object file worth of data around just for a few bytes of location 193 /// expression. LLDB typically will mmap the entire contents of debug 194 /// information files, and if we use SetOpcodeData, it will get a 195 /// shared reference to all of this data for the and cause the object 196 /// file to have to stay around. Even worse, a very very large ".a" 197 /// that contains one or more .o files could end up being referenced. 198 /// Location lists are typically small so even though we are copying 199 /// the data, it shouldn't amount to that much for the variables we 200 /// end up parsing. 201 /// 202 /// @param[in] data 203 /// A data extractor configured to read and copy the DWARF 204 /// location expression's bytecode. 205 /// 206 /// @param[in] data_offset 207 /// The offset of the location expression in the extractor. 208 /// 209 /// @param[in] data_length 210 /// The byte length of the location expression. 211 //------------------------------------------------------------------ 212 void 213 CopyOpcodeData (const DataExtractor& data, 214 lldb::offset_t data_offset, 215 lldb::offset_t data_length); 216 217 218 //------------------------------------------------------------------ 219 /// Tells the expression that it refers to a location list. 220 /// 221 /// @param[in] slide 222 /// This value should be a slide that is applied to any values 223 /// in the location list data so the values become zero based 224 /// offsets into the object that owns the location list. We need 225 /// to make location lists relative to the objects that own them 226 /// so we can relink addresses on the fly. 227 //------------------------------------------------------------------ 228 void 229 SetLocationListSlide (lldb::addr_t slide); 230 231 //------------------------------------------------------------------ 232 /// Return the call-frame-info style register kind 233 //------------------------------------------------------------------ 234 int 235 GetRegisterKind (); 236 237 //------------------------------------------------------------------ 238 /// Set the call-frame-info style register kind 239 /// 240 /// @param[in] reg_kind 241 /// The register kind. 242 //------------------------------------------------------------------ 243 void 244 SetRegisterKind (lldb::RegisterKind reg_kind); 245 246 //------------------------------------------------------------------ 247 /// Wrapper for the static evaluate function that accepts an 248 /// ExecutionContextScope instead of an ExecutionContext and uses 249 /// member variables to populate many operands 250 //------------------------------------------------------------------ 251 bool 252 Evaluate (ExecutionContextScope *exe_scope, 253 ClangExpressionVariableList *expr_locals, 254 ClangExpressionDeclMap *decl_map, 255 lldb::addr_t loclist_base_load_addr, 256 const Value* initial_value_ptr, 257 Value& result, 258 Error *error_ptr) const; 259 260 //------------------------------------------------------------------ 261 /// Wrapper for the static evaluate function that uses member 262 /// variables to populate many operands 263 //------------------------------------------------------------------ 264 bool 265 Evaluate (ExecutionContext *exe_ctx, 266 ClangExpressionVariableList *expr_locals, 267 ClangExpressionDeclMap *decl_map, 268 RegisterContext *reg_ctx, 269 lldb::addr_t loclist_base_load_addr, 270 const Value* initial_value_ptr, 271 Value& result, 272 Error *error_ptr) const; 273 274 //------------------------------------------------------------------ 275 /// Evaluate a DWARF location expression in a particular context 276 /// 277 /// @param[in] exe_ctx 278 /// The execution context in which to evaluate the location 279 /// expression. The location expression may access the target's 280 /// memory, especially if it comes from the expression parser. 281 /// 282 /// @param[in] opcodes 283 /// This is a static method so the opcodes need to be provided 284 /// explicitly. 285 /// 286 /// @param[in] expr_locals 287 /// If the location expression was produced by the expression parser, 288 /// the list of local variables referenced by the DWARF expression. 289 /// This list should already have been populated during parsing; 290 /// the DWARF expression refers to variables by index. Can be NULL if 291 /// the location expression uses no locals. 292 /// 293 /// @param[in] decl_map 294 /// If the location expression was produced by the expression parser, 295 /// the list of external variables referenced by the location 296 /// expression. Can be NULL if the location expression uses no 297 /// external variables. 298 /// 299 /// @param[in] reg_ctx 300 /// An optional parameter which provides a RegisterContext for use 301 /// when evaluating the expression (i.e. for fetching register values). 302 /// Normally this will come from the ExecutionContext's StackFrame but 303 /// in the case where an expression needs to be evaluated while building 304 /// the stack frame list, this short-cut is available. 305 /// 306 /// @param[in] offset 307 /// The offset of the location expression in the data extractor. 308 /// 309 /// @param[in] length 310 /// The length in bytes of the location expression. 311 /// 312 /// @param[in] reg_set 313 /// The call-frame-info style register kind. 314 /// 315 /// @param[in] initial_value_ptr 316 /// A value to put on top of the interpreter stack before evaluating 317 /// the expression, if the expression is parametrized. Can be NULL. 318 /// 319 /// @param[in] result 320 /// A value into which the result of evaluating the expression is 321 /// to be placed. 322 /// 323 /// @param[in] error_ptr 324 /// If non-NULL, used to report errors in expression evaluation. 325 /// 326 /// @return 327 /// True on success; false otherwise. If error_ptr is non-NULL, 328 /// details of the failure are provided through it. 329 //------------------------------------------------------------------ 330 static bool 331 Evaluate (ExecutionContext *exe_ctx, 332 ClangExpressionVariableList *expr_locals, 333 ClangExpressionDeclMap *decl_map, 334 RegisterContext *reg_ctx, 335 const DataExtractor& opcodes, 336 const lldb::offset_t offset, 337 const lldb::offset_t length, 338 const uint32_t reg_set, 339 const Value* initial_value_ptr, 340 Value& result, 341 Error *error_ptr); 342 343 //------------------------------------------------------------------ 344 /// Loads a ClangExpressionVariableList into the object 345 /// 346 /// @param[in] locals 347 /// If non-NULL, the list of locals used by this expression. 348 /// See Evaluate(). 349 //------------------------------------------------------------------ 350 void 351 SetExpressionLocalVariableList (ClangExpressionVariableList *locals); 352 353 //------------------------------------------------------------------ 354 /// Loads a ClangExpressionDeclMap into the object 355 /// 356 /// @param[in] locals 357 /// If non-NULL, the list of external variables used by this 358 /// expression. See Evaluate(). 359 //------------------------------------------------------------------ 360 void 361 SetExpressionDeclMap (ClangExpressionDeclMap *decl_map); 362 363 bool GetExpressionData(DataExtractor & data)364 GetExpressionData (DataExtractor &data) const 365 { 366 data = m_data; 367 return data.GetByteSize() > 0; 368 } 369 370 bool 371 DumpLocationForAddress (Stream *s, 372 lldb::DescriptionLevel level, 373 lldb::addr_t loclist_base_load_addr, 374 lldb::addr_t address, 375 ABI *abi); 376 377 protected: 378 //------------------------------------------------------------------ 379 /// Pretty-prints the location expression to a stream 380 /// 381 /// @param[in] stream 382 /// The stream to use for pretty-printing. 383 /// 384 /// @param[in] offset 385 /// The offset into the data buffer of the opcodes to be printed. 386 /// 387 /// @param[in] length 388 /// The length in bytes of the opcodes to be printed. 389 /// 390 /// @param[in] level 391 /// The level of detail to use in pretty-printing. 392 /// 393 /// @param[in] abi 394 /// An optional ABI plug-in that can be used to resolve register 395 /// names. 396 //------------------------------------------------------------------ 397 void 398 DumpLocation(Stream *s, 399 lldb::offset_t offset, 400 lldb::offset_t length, 401 lldb::DescriptionLevel level, 402 ABI *abi) const; 403 404 bool 405 GetLocation (lldb::addr_t base_addr, 406 lldb::addr_t pc, 407 lldb::offset_t &offset, 408 lldb::offset_t &len); 409 410 //------------------------------------------------------------------ 411 /// Classes that inherit from DWARFExpression can see and modify these 412 //------------------------------------------------------------------ 413 414 DataExtractor m_data; ///< A data extractor capable of reading opcode bytes 415 lldb::RegisterKind m_reg_kind; ///< One of the defines that starts with LLDB_REGKIND_ 416 lldb::addr_t m_loclist_slide; ///< A value used to slide the location list offsets so that 417 ///< they are relative to the object that owns the location list 418 ///< (the function for frame base and variable location lists) 419 420 }; 421 422 } // namespace lldb_private 423 424 #endif // liblldb_DWARFExpression_h_ 425