1 //===-- StackFrame.cpp ------------------------------------------*- 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 #include "lldb/Target/StackFrame.h" 11 12 // C Includes 13 // C++ Includes 14 // Other libraries and framework includes 15 // Project includes 16 #include "lldb/Core/Module.h" 17 #include "lldb/Core/Disassembler.h" 18 #include "lldb/Core/Value.h" 19 #include "lldb/Symbol/Function.h" 20 #include "lldb/Target/ExecutionContext.h" 21 #include "lldb/Target/Process.h" 22 #include "lldb/Target/RegisterContext.h" 23 #include "lldb/Target/Target.h" 24 #include "lldb/Target/Thread.h" 25 26 using namespace lldb; 27 using namespace lldb_private; 28 29 // The first bits in the flags are reserved for the SymbolContext::Scope bits 30 // so we know if we have tried to look up information in our internal symbol 31 // context (m_sc) already. 32 #define RESOLVED_FRAME_ADDR (uint32_t(eSymbolContextEverything + 1)) 33 #define RESOLVED_FRAME_ID (RESOLVED_FRAME_ADDR << 1) 34 #define GOT_FRAME_BASE (RESOLVED_FRAME_ID << 1) 35 #define FRAME_IS_OBSOLETE (GOT_FRAME_BASE << 1) 36 #define RESOLVED_VARIABLES (FRAME_IS_OBSOLETE << 1) 37 38 StackFrame::StackFrame 39 ( 40 lldb::user_id_t frame_idx, 41 lldb::user_id_t concrete_frame_index, 42 Thread &thread, 43 lldb::addr_t cfa, 44 lldb::addr_t pc, 45 const SymbolContext *sc_ptr 46 ) : 47 m_frame_index (frame_idx), 48 m_concrete_frame_index (concrete_frame_index), 49 m_thread (thread), 50 m_reg_context_sp (), 51 m_id (LLDB_INVALID_UID, cfa, LLDB_INVALID_UID), 52 m_frame_code_addr (NULL, pc), 53 m_sc (), 54 m_flags (), 55 m_frame_base (), 56 m_frame_base_error (), 57 m_variable_list_sp (), 58 m_value_object_list () 59 { 60 if (sc_ptr != NULL) 61 { 62 m_sc = *sc_ptr; 63 m_flags.Set(m_sc.GetResolvedMask ()); 64 } 65 } 66 67 StackFrame::StackFrame 68 ( 69 lldb::user_id_t frame_idx, 70 lldb::user_id_t concrete_frame_index, 71 Thread &thread, 72 const RegisterContextSP ®_context_sp, 73 lldb::addr_t cfa, 74 lldb::addr_t pc, 75 const SymbolContext *sc_ptr 76 ) : 77 m_frame_index (frame_idx), 78 m_concrete_frame_index (concrete_frame_index), 79 m_thread (thread), 80 m_reg_context_sp (reg_context_sp), 81 m_id (LLDB_INVALID_UID, cfa, LLDB_INVALID_UID), 82 m_frame_code_addr (NULL, pc), 83 m_sc (), 84 m_flags (), 85 m_frame_base (), 86 m_frame_base_error (), 87 m_variable_list_sp (), 88 m_value_object_list () 89 { 90 if (sc_ptr != NULL) 91 { 92 m_sc = *sc_ptr; 93 m_flags.Set(m_sc.GetResolvedMask ()); 94 } 95 96 if (reg_context_sp && !m_sc.target_sp) 97 { 98 m_sc.target_sp = reg_context_sp->GetThread().GetProcess().GetTarget().GetSP(); 99 m_flags.Set (eSymbolContextTarget); 100 } 101 } 102 103 StackFrame::StackFrame 104 ( 105 lldb::user_id_t frame_idx, 106 lldb::user_id_t concrete_frame_index, 107 Thread &thread, 108 const RegisterContextSP ®_context_sp, 109 lldb::addr_t cfa, 110 const Address& pc_addr, 111 const SymbolContext *sc_ptr 112 ) : 113 m_frame_index (frame_idx), 114 m_concrete_frame_index (concrete_frame_index), 115 m_thread (thread), 116 m_reg_context_sp (reg_context_sp), 117 m_id (LLDB_INVALID_UID, cfa, LLDB_INVALID_UID), 118 m_frame_code_addr (pc_addr), 119 m_sc (), 120 m_flags (), 121 m_frame_base (), 122 m_frame_base_error (), 123 m_variable_list_sp (), 124 m_value_object_list () 125 { 126 if (sc_ptr != NULL) 127 { 128 m_sc = *sc_ptr; 129 m_flags.Set(m_sc.GetResolvedMask ()); 130 } 131 132 if (m_sc.target_sp.get() == NULL && reg_context_sp) 133 { 134 m_sc.target_sp = reg_context_sp->GetThread().GetProcess().GetTarget().GetSP(); 135 m_flags.Set (eSymbolContextTarget); 136 } 137 138 if (m_sc.module_sp.get() == NULL && pc_addr.GetSection()) 139 { 140 Module *pc_module = pc_addr.GetSection()->GetModule(); 141 if (pc_module) 142 { 143 m_sc.module_sp = pc_module->GetSP(); 144 m_flags.Set (eSymbolContextModule); 145 } 146 } 147 } 148 149 150 //---------------------------------------------------------------------- 151 // Destructor 152 //---------------------------------------------------------------------- 153 StackFrame::~StackFrame() 154 { 155 } 156 157 StackID& 158 StackFrame::GetStackID() 159 { 160 // Make sure we have resolved our stack ID's start PC before we give 161 // it out to any external clients. This allows us to not have to lookup 162 // this information if it is never asked for. 163 if (m_flags.IsClear(RESOLVED_FRAME_ID) && m_id.GetStartAddress() == LLDB_INVALID_ADDRESS) 164 { 165 m_flags.Set (RESOLVED_FRAME_ID); 166 167 // Resolve our PC to section offset if we haven't alreday done so 168 // and if we don't have a module. The resolved address section will 169 // contain the module to which it belongs. 170 if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_ADDR)) 171 GetFrameCodeAddress(); 172 173 if (GetSymbolContext (eSymbolContextFunction).function) 174 { 175 m_id.SetStartAddress (m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (&m_thread.GetProcess())); 176 } 177 else if (GetSymbolContext (eSymbolContextSymbol).symbol) 178 { 179 AddressRange *symbol_range_ptr = m_sc.symbol->GetAddressRangePtr(); 180 if (symbol_range_ptr) 181 m_id.SetStartAddress(symbol_range_ptr->GetBaseAddress().GetLoadAddress (&m_thread.GetProcess())); 182 } 183 184 // We didn't find a function or symbol, just use the frame code address 185 // which will be the same as the PC in the frame. 186 if (m_id.GetStartAddress() == LLDB_INVALID_ADDRESS) 187 m_id.SetStartAddress (m_frame_code_addr.GetLoadAddress (&m_thread.GetProcess())); 188 } 189 return m_id; 190 } 191 192 Address& 193 StackFrame::GetFrameCodeAddress() 194 { 195 if (m_flags.IsClear(RESOLVED_FRAME_ADDR) && !m_frame_code_addr.IsSectionOffset()) 196 { 197 m_flags.Set (RESOLVED_FRAME_ADDR); 198 199 // Resolve the PC into a temporary address because if ResolveLoadAddress 200 // fails to resolve the address, it will clear the address object... 201 Address resolved_pc; 202 if (m_thread.GetProcess().ResolveLoadAddress(m_frame_code_addr.GetOffset(), resolved_pc)) 203 { 204 m_frame_code_addr = resolved_pc; 205 const Section *section = m_frame_code_addr.GetSection(); 206 if (section) 207 { 208 Module *module = section->GetModule(); 209 if (module) 210 { 211 m_sc.module_sp = module->GetSP(); 212 if (m_sc.module_sp) 213 m_flags.Set(eSymbolContextModule); 214 } 215 } 216 } 217 } 218 return m_frame_code_addr; 219 } 220 221 void 222 StackFrame::ChangePC (addr_t pc) 223 { 224 m_frame_code_addr.SetOffset(pc); 225 m_frame_code_addr.SetSection(NULL); 226 m_sc.Clear(); 227 m_flags.SetAllFlagBits(0); 228 m_thread.ClearStackFrames (); 229 } 230 231 const char * 232 StackFrame::Disassemble () 233 { 234 if (m_disassembly.GetSize() == 0) 235 { 236 ExecutionContext exe_ctx; 237 Calculate(exe_ctx); 238 Target &target = m_thread.GetProcess().GetTarget(); 239 Disassembler::Disassemble (target.GetDebugger(), 240 target.GetArchitecture(), 241 exe_ctx, 242 0, 243 false, 244 m_disassembly); 245 if (m_disassembly.GetSize() == 0) 246 return NULL; 247 } 248 return m_disassembly.GetData(); 249 } 250 251 //---------------------------------------------------------------------- 252 // Get the symbol context if we already haven't done so by resolving the 253 // PC address as much as possible. This way when we pass around a 254 // StackFrame object, everyone will have as much information as 255 // possible and no one will ever have to look things up manually. 256 //---------------------------------------------------------------------- 257 const SymbolContext& 258 StackFrame::GetSymbolContext (uint32_t resolve_scope) 259 { 260 // Copy our internal symbol context into "sc". 261 if ((m_flags.GetAllFlagBits() & resolve_scope) != resolve_scope) 262 { 263 // Resolve our PC to section offset if we haven't alreday done so 264 // and if we don't have a module. The resolved address section will 265 // contain the module to which it belongs 266 if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_ADDR)) 267 GetFrameCodeAddress(); 268 269 // If this is not frame zero, then we need to subtract 1 from the PC 270 // value when doing address lookups since the PC will be on the 271 // instruction following the function call instruction... 272 273 Address lookup_addr(GetFrameCodeAddress()); 274 if (m_frame_index > 0 && lookup_addr.IsValid()) 275 { 276 addr_t offset = lookup_addr.GetOffset(); 277 if (offset > 0) 278 lookup_addr.SetOffset(offset - 1); 279 } 280 281 282 uint32_t resolved = 0; 283 if (m_sc.module_sp) 284 { 285 // We have something in our stack frame symbol context, lets check 286 // if we haven't already tried to lookup one of those things. If we 287 // haven't then we will do the query. 288 289 uint32_t actual_resolve_scope = 0; 290 291 if (resolve_scope & eSymbolContextCompUnit) 292 { 293 if (m_flags.IsClear (eSymbolContextCompUnit)) 294 { 295 if (m_sc.comp_unit) 296 resolved |= eSymbolContextCompUnit; 297 else 298 actual_resolve_scope |= eSymbolContextCompUnit; 299 } 300 } 301 302 if (resolve_scope & eSymbolContextFunction) 303 { 304 if (m_flags.IsClear (eSymbolContextFunction)) 305 { 306 if (m_sc.function) 307 resolved |= eSymbolContextFunction; 308 else 309 actual_resolve_scope |= eSymbolContextFunction; 310 } 311 } 312 313 if (resolve_scope & eSymbolContextBlock) 314 { 315 if (m_flags.IsClear (eSymbolContextBlock)) 316 { 317 if (m_sc.block) 318 resolved |= eSymbolContextBlock; 319 else 320 actual_resolve_scope |= eSymbolContextBlock; 321 } 322 } 323 324 if (resolve_scope & eSymbolContextSymbol) 325 { 326 if (m_flags.IsClear (eSymbolContextSymbol)) 327 { 328 if (m_sc.symbol) 329 resolved |= eSymbolContextSymbol; 330 else 331 actual_resolve_scope |= eSymbolContextSymbol; 332 } 333 } 334 335 if (resolve_scope & eSymbolContextLineEntry) 336 { 337 if (m_flags.IsClear (eSymbolContextLineEntry)) 338 { 339 if (m_sc.line_entry.IsValid()) 340 resolved |= eSymbolContextLineEntry; 341 else 342 actual_resolve_scope |= eSymbolContextLineEntry; 343 } 344 } 345 346 if (actual_resolve_scope) 347 { 348 // We might be resolving less information than what is already 349 // in our current symbol context so resolve into a temporary 350 // symbol context "sc" so we don't clear out data we have 351 // already found in "m_sc" 352 SymbolContext sc; 353 // Set flags that indicate what we have tried to resolve 354 resolved |= m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, actual_resolve_scope, sc); 355 // Only replace what we didn't already have as we may have 356 // information for an inlined function scope that won't match 357 // what a standard lookup by address would match 358 if ((resolved & eSymbolContextCompUnit) && m_sc.comp_unit == NULL) 359 m_sc.comp_unit = sc.comp_unit; 360 if ((resolved & eSymbolContextFunction) && m_sc.function == NULL) 361 m_sc.function = sc.function; 362 if ((resolved & eSymbolContextBlock) && m_sc.block == NULL) 363 m_sc.block = sc.block; 364 if ((resolved & eSymbolContextSymbol) && m_sc.symbol == NULL) 365 m_sc.symbol = sc.symbol; 366 if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid()) 367 m_sc.line_entry = sc.line_entry; 368 369 } 370 } 371 else 372 { 373 // If we don't have a module, then we can't have the compile unit, 374 // function, block, line entry or symbol, so we can safely call 375 // ResolveSymbolContextForAddress with our symbol context member m_sc. 376 resolved |= m_thread.GetProcess().GetTarget().GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc); 377 } 378 379 // If the target was requested add that: 380 if (m_sc.target_sp.get() == NULL) 381 { 382 m_sc.target_sp = CalculateProcess()->GetTarget().GetSP(); 383 if (m_sc.target_sp) 384 resolved |= eSymbolContextTarget; 385 } 386 387 // Update our internal flags so we remember what we have tried to locate so 388 // we don't have to keep trying when more calls to this function are made. 389 // We might have dug up more information that was requested (for example 390 // if we were asked to only get the block, we will have gotten the 391 // compile unit, and function) so set any additional bits that we resolved 392 m_flags.Set (resolve_scope | resolved); 393 } 394 395 // Return the symbol context with everything that was possible to resolve 396 // resolved. 397 return m_sc; 398 } 399 400 401 VariableList * 402 StackFrame::GetVariableList () 403 { 404 if (m_flags.IsClear(RESOLVED_VARIABLES)) 405 { 406 m_flags.Set(RESOLVED_VARIABLES); 407 408 if (GetSymbolContext (eSymbolContextFunction).function) 409 { 410 bool get_child_variables = true; 411 bool can_create = true; 412 m_variable_list_sp = m_sc.function->GetBlock (can_create).GetVariableList (get_child_variables, can_create); 413 } 414 } 415 return m_variable_list_sp.get(); 416 } 417 418 419 bool 420 StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr) 421 { 422 if (m_flags.IsClear(GOT_FRAME_BASE)) 423 { 424 if (m_sc.function) 425 { 426 m_frame_base.Clear(); 427 m_frame_base_error.Clear(); 428 429 m_flags.Set(GOT_FRAME_BASE); 430 ExecutionContext exe_ctx (&m_thread.GetProcess(), &m_thread, this); 431 Value expr_value; 432 if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, expr_value, &m_frame_base_error) < 0) 433 { 434 // We should really have an error if evaluate returns, but in case 435 // we don't, lets set the error to something at least. 436 if (m_frame_base_error.Success()) 437 m_frame_base_error.SetErrorString("Evaluation of the frame base expression failed."); 438 } 439 else 440 { 441 m_frame_base = expr_value.ResolveValue(&exe_ctx, NULL); 442 } 443 } 444 else 445 { 446 m_frame_base_error.SetErrorString ("No function in symbol context."); 447 } 448 } 449 450 if (m_frame_base_error.Success()) 451 frame_base = m_frame_base; 452 453 if (error_ptr) 454 *error_ptr = m_frame_base_error; 455 return m_frame_base_error.Success(); 456 } 457 458 RegisterContext * 459 StackFrame::GetRegisterContext () 460 { 461 if (m_reg_context_sp.get() == NULL) 462 m_reg_context_sp.reset (m_thread.CreateRegisterContextForFrame (this)); 463 return m_reg_context_sp.get(); 464 } 465 466 bool 467 StackFrame::HasDebugInformation () 468 { 469 GetSymbolContext (eSymbolContextLineEntry); 470 return m_sc.line_entry.IsValid(); 471 } 472 473 ValueObjectList & 474 StackFrame::GetValueObjectList() 475 { 476 return m_value_object_list; 477 } 478 479 bool 480 StackFrame::IsInlined () 481 { 482 return m_id.GetInlineBlockID() != LLDB_INVALID_UID; 483 } 484 485 Target * 486 StackFrame::CalculateTarget () 487 { 488 return m_thread.CalculateTarget(); 489 } 490 491 Process * 492 StackFrame::CalculateProcess () 493 { 494 return m_thread.CalculateProcess(); 495 } 496 497 Thread * 498 StackFrame::CalculateThread () 499 { 500 return &m_thread; 501 } 502 503 StackFrame * 504 StackFrame::CalculateStackFrame () 505 { 506 return this; 507 } 508 509 510 void 511 StackFrame::Calculate (ExecutionContext &exe_ctx) 512 { 513 m_thread.Calculate (exe_ctx); 514 exe_ctx.frame = this; 515 } 516 517 void 518 StackFrame::Dump (Stream *strm, bool show_frame_index) 519 { 520 if (strm == NULL) 521 return; 522 523 if (show_frame_index) 524 strm->Printf("frame #%u: ", m_frame_index); 525 strm->Printf("0x%0*llx", m_thread.GetProcess().GetAddressByteSize() * 2, GetFrameCodeAddress().GetLoadAddress(&m_thread.GetProcess())); 526 GetSymbolContext(eSymbolContextEverything); 527 strm->PutCString(", where = "); 528 // TODO: need to get the 529 const bool show_module = true; 530 const bool show_inline = true; 531 m_sc.DumpStopContext(strm, &m_thread.GetProcess(), GetFrameCodeAddress(), show_module, show_inline); 532 } 533 534 535 void 536 StackFrame::SetSymbolContext (const SymbolContext& sc) 537 { 538 m_sc = sc; 539 m_flags.Clear(eSymbolContextEverything); 540 m_flags.Set(m_sc.GetResolvedMask ()); 541 } 542