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/Core/ValueObjectVariable.h" 20 #include "lldb/Symbol/Function.h" 21 #include "lldb/Symbol/VariableList.h" 22 #include "lldb/Target/ExecutionContext.h" 23 #include "lldb/Target/Process.h" 24 #include "lldb/Target/RegisterContext.h" 25 #include "lldb/Target/Target.h" 26 #include "lldb/Target/Thread.h" 27 28 using namespace lldb; 29 using namespace lldb_private; 30 31 // The first bits in the flags are reserved for the SymbolContext::Scope bits 32 // so we know if we have tried to look up information in our internal symbol 33 // context (m_sc) already. 34 #define RESOLVED_FRAME_CODE_ADDR (uint32_t(eSymbolContextEverything + 1)) 35 #define RESOLVED_FRAME_ID_SYMBOL_SCOPE (RESOLVED_FRAME_CODE_ADDR << 1) 36 #define GOT_FRAME_BASE (RESOLVED_FRAME_ID_SYMBOL_SCOPE << 1) 37 #define RESOLVED_VARIABLES (GOT_FRAME_BASE << 1) 38 39 StackFrame::StackFrame 40 ( 41 lldb::user_id_t frame_idx, 42 lldb::user_id_t unwind_frame_index, 43 Thread &thread, 44 lldb::addr_t cfa, 45 lldb::addr_t pc, 46 const SymbolContext *sc_ptr 47 ) : 48 m_frame_index (frame_idx), 49 m_unwind_frame_index (unwind_frame_index), 50 m_thread (thread), 51 m_reg_context_sp (), 52 m_id (pc, cfa, NULL), 53 m_frame_code_addr (NULL, pc), 54 m_sc (), 55 m_flags (), 56 m_frame_base (), 57 m_frame_base_error (), 58 m_variable_list_sp (), 59 m_variable_list_value_objects () 60 { 61 if (sc_ptr != NULL) 62 { 63 m_sc = *sc_ptr; 64 m_flags.Set(m_sc.GetResolvedMask ()); 65 } 66 } 67 68 StackFrame::StackFrame 69 ( 70 lldb::user_id_t frame_idx, 71 lldb::user_id_t unwind_frame_index, 72 Thread &thread, 73 const RegisterContextSP ®_context_sp, 74 lldb::addr_t cfa, 75 lldb::addr_t pc, 76 const SymbolContext *sc_ptr 77 ) : 78 m_frame_index (frame_idx), 79 m_unwind_frame_index (unwind_frame_index), 80 m_thread (thread), 81 m_reg_context_sp (reg_context_sp), 82 m_id (pc, cfa, NULL), 83 m_frame_code_addr (NULL, pc), 84 m_sc (), 85 m_flags (), 86 m_frame_base (), 87 m_frame_base_error (), 88 m_variable_list_sp (), 89 m_variable_list_value_objects () 90 { 91 if (sc_ptr != NULL) 92 { 93 m_sc = *sc_ptr; 94 m_flags.Set(m_sc.GetResolvedMask ()); 95 } 96 97 if (reg_context_sp && !m_sc.target_sp) 98 { 99 m_sc.target_sp = reg_context_sp->GetThread().GetProcess().GetTarget().GetSP(); 100 m_flags.Set (eSymbolContextTarget); 101 } 102 } 103 104 StackFrame::StackFrame 105 ( 106 lldb::user_id_t frame_idx, 107 lldb::user_id_t unwind_frame_index, 108 Thread &thread, 109 const RegisterContextSP ®_context_sp, 110 lldb::addr_t cfa, 111 const Address& pc_addr, 112 const SymbolContext *sc_ptr 113 ) : 114 m_frame_index (frame_idx), 115 m_unwind_frame_index (unwind_frame_index), 116 m_thread (thread), 117 m_reg_context_sp (reg_context_sp), 118 m_id (pc_addr.GetLoadAddress (&thread.GetProcess()), cfa, NULL), 119 m_frame_code_addr (pc_addr), 120 m_sc (), 121 m_flags (), 122 m_frame_base (), 123 m_frame_base_error (), 124 m_variable_list_sp (), 125 m_variable_list_value_objects () 126 { 127 if (sc_ptr != NULL) 128 { 129 m_sc = *sc_ptr; 130 m_flags.Set(m_sc.GetResolvedMask ()); 131 } 132 133 if (m_sc.target_sp.get() == NULL && reg_context_sp) 134 { 135 m_sc.target_sp = reg_context_sp->GetThread().GetProcess().GetTarget().GetSP(); 136 m_flags.Set (eSymbolContextTarget); 137 } 138 139 if (m_sc.module_sp.get() == NULL && pc_addr.GetSection()) 140 { 141 Module *pc_module = pc_addr.GetSection()->GetModule(); 142 if (pc_module) 143 { 144 m_sc.module_sp = pc_module->GetSP(); 145 m_flags.Set (eSymbolContextModule); 146 } 147 } 148 } 149 150 151 //---------------------------------------------------------------------- 152 // Destructor 153 //---------------------------------------------------------------------- 154 StackFrame::~StackFrame() 155 { 156 } 157 158 StackID& 159 StackFrame::GetStackID() 160 { 161 // Make sure we have resolved the StackID object's symbol context scope if 162 // we already haven't looked it up. 163 164 if (m_flags.IsClear (RESOLVED_FRAME_ID_SYMBOL_SCOPE)) 165 { 166 if (m_id.GetSymbolContextScope ()) 167 { 168 // We already have a symbol context scope, we just don't have our 169 // flag bit set. 170 m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE); 171 } 172 else 173 { 174 // Calculate the frame block and use this for the stack ID symbol 175 // context scope if we have one. 176 SymbolContextScope *scope = GetFrameBlock (); 177 if (scope == NULL) 178 { 179 // We don't have a block, so use the symbol 180 if (m_flags.IsClear (eSymbolContextSymbol)) 181 GetSymbolContext (eSymbolContextSymbol); 182 183 // It is ok if m_sc.symbol is NULL here 184 scope = m_sc.symbol; 185 } 186 // Set the symbol context scope (the accessor will set the 187 // RESOLVED_FRAME_ID_SYMBOL_SCOPE bit in m_flags). 188 SetSymbolContextScope (scope); 189 } 190 } 191 return m_id; 192 } 193 194 void 195 StackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope) 196 { 197 m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE); 198 m_id.SetSymbolContextScope (symbol_scope); 199 } 200 201 Address& 202 StackFrame::GetFrameCodeAddress() 203 { 204 if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) && !m_frame_code_addr.IsSectionOffset()) 205 { 206 m_flags.Set (RESOLVED_FRAME_CODE_ADDR); 207 208 // Resolve the PC into a temporary address because if ResolveLoadAddress 209 // fails to resolve the address, it will clear the address object... 210 Address resolved_pc; 211 if (m_thread.GetProcess().ResolveLoadAddress(m_frame_code_addr.GetOffset(), resolved_pc)) 212 { 213 m_frame_code_addr = resolved_pc; 214 const Section *section = m_frame_code_addr.GetSection(); 215 if (section) 216 { 217 Module *module = section->GetModule(); 218 if (module) 219 { 220 m_sc.module_sp = module->GetSP(); 221 if (m_sc.module_sp) 222 m_flags.Set(eSymbolContextModule); 223 } 224 } 225 } 226 } 227 return m_frame_code_addr; 228 } 229 230 void 231 StackFrame::ChangePC (addr_t pc) 232 { 233 m_frame_code_addr.SetOffset(pc); 234 m_frame_code_addr.SetSection(NULL); 235 m_sc.Clear(); 236 m_flags.SetAllFlagBits(0); 237 m_thread.ClearStackFrames (); 238 } 239 240 const char * 241 StackFrame::Disassemble () 242 { 243 if (m_disassembly.GetSize() == 0) 244 { 245 ExecutionContext exe_ctx; 246 Calculate(exe_ctx); 247 Target &target = m_thread.GetProcess().GetTarget(); 248 Disassembler::Disassemble (target.GetDebugger(), 249 target.GetArchitecture(), 250 exe_ctx, 251 0, 252 false, 253 m_disassembly); 254 if (m_disassembly.GetSize() == 0) 255 return NULL; 256 } 257 return m_disassembly.GetData(); 258 } 259 260 Block * 261 StackFrame::GetFrameBlock () 262 { 263 if (m_sc.block == NULL && m_flags.IsClear (eSymbolContextBlock)) 264 GetSymbolContext (eSymbolContextBlock); 265 266 if (m_sc.block) 267 { 268 Block *inline_block = m_sc.block->GetContainingInlinedBlock(); 269 if (inline_block) 270 { 271 // Use the block with the inlined function info 272 // as the frame block we want this frame to have only the variables 273 // for the inlined function and its non-inlined block child blocks. 274 return inline_block; 275 } 276 else 277 { 278 // This block is not contained withing any inlined function blocks 279 // with so we want to use the top most function block. 280 return &m_sc.function->GetBlock (false); 281 } 282 } 283 return NULL; 284 } 285 286 //---------------------------------------------------------------------- 287 // Get the symbol context if we already haven't done so by resolving the 288 // PC address as much as possible. This way when we pass around a 289 // StackFrame object, everyone will have as much information as 290 // possible and no one will ever have to look things up manually. 291 //---------------------------------------------------------------------- 292 const SymbolContext& 293 StackFrame::GetSymbolContext (uint32_t resolve_scope) 294 { 295 // Copy our internal symbol context into "sc". 296 if ((m_flags.GetAllFlagBits() & resolve_scope) != resolve_scope) 297 { 298 // Resolve our PC to section offset if we haven't alreday done so 299 // and if we don't have a module. The resolved address section will 300 // contain the module to which it belongs 301 if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR)) 302 GetFrameCodeAddress(); 303 304 // If this is not frame zero, then we need to subtract 1 from the PC 305 // value when doing address lookups since the PC will be on the 306 // instruction following the function call instruction... 307 308 Address lookup_addr(GetFrameCodeAddress()); 309 if (m_frame_index > 0 && lookup_addr.IsValid()) 310 { 311 addr_t offset = lookup_addr.GetOffset(); 312 if (offset > 0) 313 lookup_addr.SetOffset(offset - 1); 314 } 315 316 317 uint32_t resolved = 0; 318 if (m_sc.module_sp) 319 { 320 // We have something in our stack frame symbol context, lets check 321 // if we haven't already tried to lookup one of those things. If we 322 // haven't then we will do the query. 323 324 uint32_t actual_resolve_scope = 0; 325 326 if (resolve_scope & eSymbolContextCompUnit) 327 { 328 if (m_flags.IsClear (eSymbolContextCompUnit)) 329 { 330 if (m_sc.comp_unit) 331 resolved |= eSymbolContextCompUnit; 332 else 333 actual_resolve_scope |= eSymbolContextCompUnit; 334 } 335 } 336 337 if (resolve_scope & eSymbolContextFunction) 338 { 339 if (m_flags.IsClear (eSymbolContextFunction)) 340 { 341 if (m_sc.function) 342 resolved |= eSymbolContextFunction; 343 else 344 actual_resolve_scope |= eSymbolContextFunction; 345 } 346 } 347 348 if (resolve_scope & eSymbolContextBlock) 349 { 350 if (m_flags.IsClear (eSymbolContextBlock)) 351 { 352 if (m_sc.block) 353 resolved |= eSymbolContextBlock; 354 else 355 actual_resolve_scope |= eSymbolContextBlock; 356 } 357 } 358 359 if (resolve_scope & eSymbolContextSymbol) 360 { 361 if (m_flags.IsClear (eSymbolContextSymbol)) 362 { 363 if (m_sc.symbol) 364 resolved |= eSymbolContextSymbol; 365 else 366 actual_resolve_scope |= eSymbolContextSymbol; 367 } 368 } 369 370 if (resolve_scope & eSymbolContextLineEntry) 371 { 372 if (m_flags.IsClear (eSymbolContextLineEntry)) 373 { 374 if (m_sc.line_entry.IsValid()) 375 resolved |= eSymbolContextLineEntry; 376 else 377 actual_resolve_scope |= eSymbolContextLineEntry; 378 } 379 } 380 381 if (actual_resolve_scope) 382 { 383 // We might be resolving less information than what is already 384 // in our current symbol context so resolve into a temporary 385 // symbol context "sc" so we don't clear out data we have 386 // already found in "m_sc" 387 SymbolContext sc; 388 // Set flags that indicate what we have tried to resolve 389 resolved |= m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, actual_resolve_scope, sc); 390 // Only replace what we didn't already have as we may have 391 // information for an inlined function scope that won't match 392 // what a standard lookup by address would match 393 if ((resolved & eSymbolContextCompUnit) && m_sc.comp_unit == NULL) 394 m_sc.comp_unit = sc.comp_unit; 395 if ((resolved & eSymbolContextFunction) && m_sc.function == NULL) 396 m_sc.function = sc.function; 397 if ((resolved & eSymbolContextBlock) && m_sc.block == NULL) 398 m_sc.block = sc.block; 399 if ((resolved & eSymbolContextSymbol) && m_sc.symbol == NULL) 400 m_sc.symbol = sc.symbol; 401 if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid()) 402 m_sc.line_entry = sc.line_entry; 403 404 } 405 } 406 else 407 { 408 // If we don't have a module, then we can't have the compile unit, 409 // function, block, line entry or symbol, so we can safely call 410 // ResolveSymbolContextForAddress with our symbol context member m_sc. 411 resolved |= m_thread.GetProcess().GetTarget().GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc); 412 } 413 414 // If the target was requested add that: 415 if (m_sc.target_sp.get() == NULL) 416 { 417 m_sc.target_sp = CalculateProcess()->GetTarget().GetSP(); 418 if (m_sc.target_sp) 419 resolved |= eSymbolContextTarget; 420 } 421 422 // Update our internal flags so we remember what we have tried to locate so 423 // we don't have to keep trying when more calls to this function are made. 424 // We might have dug up more information that was requested (for example 425 // if we were asked to only get the block, we will have gotten the 426 // compile unit, and function) so set any additional bits that we resolved 427 m_flags.Set (resolve_scope | resolved); 428 } 429 430 // Return the symbol context with everything that was possible to resolve 431 // resolved. 432 return m_sc; 433 } 434 435 436 VariableList * 437 StackFrame::GetVariableList (bool get_file_globals) 438 { 439 if (m_flags.IsClear(RESOLVED_VARIABLES)) 440 { 441 m_flags.Set(RESOLVED_VARIABLES); 442 443 Block *frame_block = GetFrameBlock(); 444 445 if (frame_block) 446 { 447 const bool get_child_variables = true; 448 const bool can_create = true; 449 m_variable_list_sp = frame_block->GetVariableList (get_child_variables, can_create); 450 } 451 452 if (get_file_globals) 453 { 454 if (m_flags.IsClear (eSymbolContextCompUnit)) 455 GetSymbolContext (eSymbolContextCompUnit); 456 457 if (m_sc.comp_unit) 458 { 459 VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true)); 460 if (m_variable_list_sp) 461 m_variable_list_sp->AddVariables (global_variable_list_sp.get()); 462 else 463 m_variable_list_sp = global_variable_list_sp; 464 } 465 } 466 } 467 return m_variable_list_sp.get(); 468 } 469 470 471 bool 472 StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr) 473 { 474 if (m_flags.IsClear(GOT_FRAME_BASE)) 475 { 476 if (m_sc.function) 477 { 478 m_frame_base.Clear(); 479 m_frame_base_error.Clear(); 480 481 m_flags.Set(GOT_FRAME_BASE); 482 ExecutionContext exe_ctx (&m_thread.GetProcess(), &m_thread, this); 483 Value expr_value; 484 if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, expr_value, &m_frame_base_error) < 0) 485 { 486 // We should really have an error if evaluate returns, but in case 487 // we don't, lets set the error to something at least. 488 if (m_frame_base_error.Success()) 489 m_frame_base_error.SetErrorString("Evaluation of the frame base expression failed."); 490 } 491 else 492 { 493 m_frame_base = expr_value.ResolveValue(&exe_ctx, NULL); 494 } 495 } 496 else 497 { 498 m_frame_base_error.SetErrorString ("No function in symbol context."); 499 } 500 } 501 502 if (m_frame_base_error.Success()) 503 frame_base = m_frame_base; 504 505 if (error_ptr) 506 *error_ptr = m_frame_base_error; 507 return m_frame_base_error.Success(); 508 } 509 510 RegisterContext * 511 StackFrame::GetRegisterContext () 512 { 513 if (m_reg_context_sp.get() == NULL) 514 m_reg_context_sp.reset (m_thread.CreateRegisterContextForFrame (this)); 515 return m_reg_context_sp.get(); 516 } 517 518 bool 519 StackFrame::HasDebugInformation () 520 { 521 GetSymbolContext (eSymbolContextLineEntry); 522 return m_sc.line_entry.IsValid(); 523 } 524 525 526 ValueObjectSP 527 StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp) 528 { 529 ValueObjectSP valobj_sp; 530 VariableList *var_list = GetVariableList (true); 531 if (var_list) 532 { 533 // Make sure the variable is a frame variable 534 const uint32_t var_idx = var_list->FindIndexForVariable (variable_sp.get()); 535 const uint32_t num_variables = var_list->GetSize(); 536 if (var_idx < num_variables) 537 { 538 valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex (var_idx); 539 if (valobj_sp.get() == NULL) 540 { 541 if (m_variable_list_value_objects.GetSize() < num_variables) 542 m_variable_list_value_objects.Resize(num_variables); 543 valobj_sp.reset (new ValueObjectVariable (variable_sp)); 544 m_variable_list_value_objects.SetValueObjectAtIndex (var_idx, valobj_sp); 545 } 546 } 547 } 548 return valobj_sp; 549 } 550 551 ValueObjectSP 552 StackFrame::TrackGlobalVariable (const VariableSP &variable_sp) 553 { 554 // Check to make sure we aren't already tracking this variable? 555 ValueObjectSP valobj_sp (GetValueObjectForFrameVariable (variable_sp)); 556 if (!valobj_sp) 557 { 558 // We aren't already tracking this global 559 VariableList *var_list = GetVariableList (true); 560 // If this frame has no variables, create a new list 561 if (var_list == NULL) 562 m_variable_list_sp.reset (new VariableList()); 563 564 // Add the global/static variable to this frame 565 m_variable_list_sp->AddVariable (variable_sp); 566 567 // Now make a value object for it so we can track its changes 568 valobj_sp = GetValueObjectForFrameVariable (variable_sp); 569 } 570 return valobj_sp; 571 } 572 573 bool 574 StackFrame::IsInlined () 575 { 576 if (m_sc.block == NULL) 577 GetSymbolContext (eSymbolContextBlock); 578 if (m_sc.block) 579 return m_sc.block->GetContainingInlinedBlock() != NULL; 580 return false; 581 } 582 583 Target * 584 StackFrame::CalculateTarget () 585 { 586 return m_thread.CalculateTarget(); 587 } 588 589 Process * 590 StackFrame::CalculateProcess () 591 { 592 return m_thread.CalculateProcess(); 593 } 594 595 Thread * 596 StackFrame::CalculateThread () 597 { 598 return &m_thread; 599 } 600 601 StackFrame * 602 StackFrame::CalculateStackFrame () 603 { 604 return this; 605 } 606 607 608 void 609 StackFrame::Calculate (ExecutionContext &exe_ctx) 610 { 611 m_thread.Calculate (exe_ctx); 612 exe_ctx.frame = this; 613 } 614 615 void 616 StackFrame::Dump (Stream *strm, bool show_frame_index, bool show_fullpaths) 617 { 618 if (strm == NULL) 619 return; 620 621 if (show_frame_index) 622 strm->Printf("frame #%u: ", m_frame_index); 623 strm->Printf("0x%0*llx ", m_thread.GetProcess().GetAddressByteSize() * 2, GetFrameCodeAddress().GetLoadAddress(&m_thread.GetProcess())); 624 GetSymbolContext(eSymbolContextEverything); 625 const bool show_module = true; 626 const bool show_inline = true; 627 m_sc.DumpStopContext(strm, &m_thread.GetProcess(), GetFrameCodeAddress(), show_fullpaths, show_module, show_inline); 628 } 629 630 void 631 StackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame) 632 { 633 assert (GetStackID() == prev_frame.GetStackID()); // TODO: remove this after some testing 634 m_variable_list_sp = prev_frame.m_variable_list_sp; 635 m_variable_list_value_objects.Swap (prev_frame.m_variable_list_value_objects); 636 if (!m_disassembly.GetString().empty()) 637 m_disassembly.GetString().swap (m_disassembly.GetString()); 638 } 639 640 641 void 642 StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame) 643 { 644 assert (GetStackID() == curr_frame.GetStackID()); // TODO: remove this after some testing 645 m_id.SetPC (curr_frame.m_id.GetPC()); // Update the Stack ID PC value 646 assert (&m_thread == &curr_frame.m_thread); 647 m_frame_index = curr_frame.m_frame_index; 648 m_unwind_frame_index = curr_frame.m_unwind_frame_index; 649 m_reg_context_sp = curr_frame.m_reg_context_sp; 650 m_frame_code_addr = curr_frame.m_frame_code_addr; 651 assert (m_sc.target_sp.get() == NULL || curr_frame.m_sc.target_sp.get() == NULL || m_sc.target_sp.get() == curr_frame.m_sc.target_sp.get()); 652 assert (m_sc.module_sp.get() == NULL || curr_frame.m_sc.module_sp.get() == NULL || m_sc.module_sp.get() == curr_frame.m_sc.module_sp.get()); 653 assert (m_sc.comp_unit == NULL || curr_frame.m_sc.comp_unit == NULL || m_sc.comp_unit == curr_frame.m_sc.comp_unit); 654 assert (m_sc.function == NULL || curr_frame.m_sc.function == NULL || m_sc.function == curr_frame.m_sc.function); 655 m_sc = curr_frame.m_sc; 656 m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything); 657 m_flags.Set (m_sc.GetResolvedMask()); 658 m_frame_base.Clear(); 659 m_frame_base_error.Clear(); 660 } 661 662 663 bool 664 StackFrame::HasCachedData () const 665 { 666 if (m_variable_list_sp.get()) 667 return true; 668 if (m_variable_list_value_objects.GetSize() > 0) 669 return true; 670 if (!m_disassembly.GetString().empty()) 671 return true; 672 return false; 673 }