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 () == NULL) 167 { 168 m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE); 169 } 170 else 171 { 172 GetSymbolContext (eSymbolContextFunction | eSymbolContextBlock); 173 174 if (m_sc.block) 175 { 176 Block *inline_block = m_sc.block->GetContainingInlinedBlock(); 177 if (inline_block) 178 { 179 // Use the block with the inlined function info 180 // as the symbol context since we want this frame 181 // to have only the variables for the inlined function 182 SetSymbolContextScope (inline_block); 183 } 184 else 185 { 186 // This block is not inlined with means it has no 187 // inlined parents either, so we want to use the top 188 // most function block. 189 SetSymbolContextScope (&m_sc.function->GetBlock(false)); 190 } 191 } 192 else 193 { 194 // The current stack frame doesn't have a block. Check to see 195 // if it has a symbol. If it does we will use this as the 196 // symbol scope. It is ok if "m_sc.symbol" is NULL below as 197 // it will set the symbol context to NULL and set the 198 // RESOLVED_FRAME_ID_SYMBOL_SCOPE flag bit. 199 GetSymbolContext (eSymbolContextSymbol); 200 SetSymbolContextScope (m_sc.symbol); 201 } 202 } 203 } 204 return m_id; 205 } 206 207 void 208 StackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope) 209 { 210 m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE); 211 m_id.SetSymbolContextScope (symbol_scope); 212 } 213 214 Address& 215 StackFrame::GetFrameCodeAddress() 216 { 217 if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) && !m_frame_code_addr.IsSectionOffset()) 218 { 219 m_flags.Set (RESOLVED_FRAME_CODE_ADDR); 220 221 // Resolve the PC into a temporary address because if ResolveLoadAddress 222 // fails to resolve the address, it will clear the address object... 223 Address resolved_pc; 224 if (m_thread.GetProcess().ResolveLoadAddress(m_frame_code_addr.GetOffset(), resolved_pc)) 225 { 226 m_frame_code_addr = resolved_pc; 227 const Section *section = m_frame_code_addr.GetSection(); 228 if (section) 229 { 230 Module *module = section->GetModule(); 231 if (module) 232 { 233 m_sc.module_sp = module->GetSP(); 234 if (m_sc.module_sp) 235 m_flags.Set(eSymbolContextModule); 236 } 237 } 238 } 239 } 240 return m_frame_code_addr; 241 } 242 243 void 244 StackFrame::ChangePC (addr_t pc) 245 { 246 m_frame_code_addr.SetOffset(pc); 247 m_frame_code_addr.SetSection(NULL); 248 m_sc.Clear(); 249 m_flags.SetAllFlagBits(0); 250 m_thread.ClearStackFrames (); 251 } 252 253 const char * 254 StackFrame::Disassemble () 255 { 256 if (m_disassembly.GetSize() == 0) 257 { 258 ExecutionContext exe_ctx; 259 Calculate(exe_ctx); 260 Target &target = m_thread.GetProcess().GetTarget(); 261 Disassembler::Disassemble (target.GetDebugger(), 262 target.GetArchitecture(), 263 exe_ctx, 264 0, 265 false, 266 m_disassembly); 267 if (m_disassembly.GetSize() == 0) 268 return NULL; 269 } 270 return m_disassembly.GetData(); 271 } 272 273 //---------------------------------------------------------------------- 274 // Get the symbol context if we already haven't done so by resolving the 275 // PC address as much as possible. This way when we pass around a 276 // StackFrame object, everyone will have as much information as 277 // possible and no one will ever have to look things up manually. 278 //---------------------------------------------------------------------- 279 const SymbolContext& 280 StackFrame::GetSymbolContext (uint32_t resolve_scope) 281 { 282 // Copy our internal symbol context into "sc". 283 if ((m_flags.GetAllFlagBits() & resolve_scope) != resolve_scope) 284 { 285 // Resolve our PC to section offset if we haven't alreday done so 286 // and if we don't have a module. The resolved address section will 287 // contain the module to which it belongs 288 if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR)) 289 GetFrameCodeAddress(); 290 291 // If this is not frame zero, then we need to subtract 1 from the PC 292 // value when doing address lookups since the PC will be on the 293 // instruction following the function call instruction... 294 295 Address lookup_addr(GetFrameCodeAddress()); 296 if (m_frame_index > 0 && lookup_addr.IsValid()) 297 { 298 addr_t offset = lookup_addr.GetOffset(); 299 if (offset > 0) 300 lookup_addr.SetOffset(offset - 1); 301 } 302 303 304 uint32_t resolved = 0; 305 if (m_sc.module_sp) 306 { 307 // We have something in our stack frame symbol context, lets check 308 // if we haven't already tried to lookup one of those things. If we 309 // haven't then we will do the query. 310 311 uint32_t actual_resolve_scope = 0; 312 313 if (resolve_scope & eSymbolContextCompUnit) 314 { 315 if (m_flags.IsClear (eSymbolContextCompUnit)) 316 { 317 if (m_sc.comp_unit) 318 resolved |= eSymbolContextCompUnit; 319 else 320 actual_resolve_scope |= eSymbolContextCompUnit; 321 } 322 } 323 324 if (resolve_scope & eSymbolContextFunction) 325 { 326 if (m_flags.IsClear (eSymbolContextFunction)) 327 { 328 if (m_sc.function) 329 resolved |= eSymbolContextFunction; 330 else 331 actual_resolve_scope |= eSymbolContextFunction; 332 } 333 } 334 335 if (resolve_scope & eSymbolContextBlock) 336 { 337 if (m_flags.IsClear (eSymbolContextBlock)) 338 { 339 if (m_sc.block) 340 resolved |= eSymbolContextBlock; 341 else 342 actual_resolve_scope |= eSymbolContextBlock; 343 } 344 } 345 346 if (resolve_scope & eSymbolContextSymbol) 347 { 348 if (m_flags.IsClear (eSymbolContextSymbol)) 349 { 350 if (m_sc.symbol) 351 resolved |= eSymbolContextSymbol; 352 else 353 actual_resolve_scope |= eSymbolContextSymbol; 354 } 355 } 356 357 if (resolve_scope & eSymbolContextLineEntry) 358 { 359 if (m_flags.IsClear (eSymbolContextLineEntry)) 360 { 361 if (m_sc.line_entry.IsValid()) 362 resolved |= eSymbolContextLineEntry; 363 else 364 actual_resolve_scope |= eSymbolContextLineEntry; 365 } 366 } 367 368 if (actual_resolve_scope) 369 { 370 // We might be resolving less information than what is already 371 // in our current symbol context so resolve into a temporary 372 // symbol context "sc" so we don't clear out data we have 373 // already found in "m_sc" 374 SymbolContext sc; 375 // Set flags that indicate what we have tried to resolve 376 resolved |= m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, actual_resolve_scope, sc); 377 // Only replace what we didn't already have as we may have 378 // information for an inlined function scope that won't match 379 // what a standard lookup by address would match 380 if ((resolved & eSymbolContextCompUnit) && m_sc.comp_unit == NULL) 381 m_sc.comp_unit = sc.comp_unit; 382 if ((resolved & eSymbolContextFunction) && m_sc.function == NULL) 383 m_sc.function = sc.function; 384 if ((resolved & eSymbolContextBlock) && m_sc.block == NULL) 385 m_sc.block = sc.block; 386 if ((resolved & eSymbolContextSymbol) && m_sc.symbol == NULL) 387 m_sc.symbol = sc.symbol; 388 if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid()) 389 m_sc.line_entry = sc.line_entry; 390 391 } 392 } 393 else 394 { 395 // If we don't have a module, then we can't have the compile unit, 396 // function, block, line entry or symbol, so we can safely call 397 // ResolveSymbolContextForAddress with our symbol context member m_sc. 398 resolved |= m_thread.GetProcess().GetTarget().GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc); 399 } 400 401 // If the target was requested add that: 402 if (m_sc.target_sp.get() == NULL) 403 { 404 m_sc.target_sp = CalculateProcess()->GetTarget().GetSP(); 405 if (m_sc.target_sp) 406 resolved |= eSymbolContextTarget; 407 } 408 409 // Update our internal flags so we remember what we have tried to locate so 410 // we don't have to keep trying when more calls to this function are made. 411 // We might have dug up more information that was requested (for example 412 // if we were asked to only get the block, we will have gotten the 413 // compile unit, and function) so set any additional bits that we resolved 414 m_flags.Set (resolve_scope | resolved); 415 } 416 417 // Return the symbol context with everything that was possible to resolve 418 // resolved. 419 return m_sc; 420 } 421 422 423 VariableList * 424 StackFrame::GetVariableList (bool get_file_globals) 425 { 426 if (m_flags.IsClear(RESOLVED_VARIABLES)) 427 { 428 m_flags.Set(RESOLVED_VARIABLES); 429 430 GetSymbolContext (eSymbolContextCompUnit | 431 eSymbolContextFunction | 432 eSymbolContextBlock); 433 434 if (m_sc.block) 435 { 436 bool get_child_variables = true; 437 bool can_create = true; 438 m_variable_list_sp = m_sc.function->GetBlock (can_create).GetVariableList (get_child_variables, can_create); 439 } 440 441 if (get_file_globals && m_sc.comp_unit) 442 { 443 VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true)); 444 if (m_variable_list_sp) 445 m_variable_list_sp->AddVariables (global_variable_list_sp.get()); 446 else 447 m_variable_list_sp = global_variable_list_sp; 448 } 449 } 450 return m_variable_list_sp.get(); 451 } 452 453 454 bool 455 StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr) 456 { 457 if (m_flags.IsClear(GOT_FRAME_BASE)) 458 { 459 if (m_sc.function) 460 { 461 m_frame_base.Clear(); 462 m_frame_base_error.Clear(); 463 464 m_flags.Set(GOT_FRAME_BASE); 465 ExecutionContext exe_ctx (&m_thread.GetProcess(), &m_thread, this); 466 Value expr_value; 467 if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, expr_value, &m_frame_base_error) < 0) 468 { 469 // We should really have an error if evaluate returns, but in case 470 // we don't, lets set the error to something at least. 471 if (m_frame_base_error.Success()) 472 m_frame_base_error.SetErrorString("Evaluation of the frame base expression failed."); 473 } 474 else 475 { 476 m_frame_base = expr_value.ResolveValue(&exe_ctx, NULL); 477 } 478 } 479 else 480 { 481 m_frame_base_error.SetErrorString ("No function in symbol context."); 482 } 483 } 484 485 if (m_frame_base_error.Success()) 486 frame_base = m_frame_base; 487 488 if (error_ptr) 489 *error_ptr = m_frame_base_error; 490 return m_frame_base_error.Success(); 491 } 492 493 RegisterContext * 494 StackFrame::GetRegisterContext () 495 { 496 if (m_reg_context_sp.get() == NULL) 497 m_reg_context_sp.reset (m_thread.CreateRegisterContextForFrame (this)); 498 return m_reg_context_sp.get(); 499 } 500 501 bool 502 StackFrame::HasDebugInformation () 503 { 504 GetSymbolContext (eSymbolContextLineEntry); 505 return m_sc.line_entry.IsValid(); 506 } 507 508 509 ValueObjectSP 510 StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp) 511 { 512 ValueObjectSP valobj_sp; 513 VariableList *var_list = GetVariableList (true); 514 if (var_list) 515 { 516 // Make sure the variable is a frame variable 517 const uint32_t var_idx = var_list->FindIndexForVariable (variable_sp.get()); 518 const uint32_t num_variables = var_list->GetSize(); 519 if (var_idx < num_variables) 520 { 521 valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex (var_idx); 522 if (valobj_sp.get() == NULL) 523 { 524 if (m_variable_list_value_objects.GetSize() < num_variables) 525 m_variable_list_value_objects.Resize(num_variables); 526 valobj_sp.reset (new ValueObjectVariable (variable_sp)); 527 m_variable_list_value_objects.SetValueObjectAtIndex (var_idx, valobj_sp); 528 } 529 } 530 } 531 return valobj_sp; 532 } 533 534 ValueObjectSP 535 StackFrame::TrackGlobalVariable (const VariableSP &variable_sp) 536 { 537 // Check to make sure we aren't already tracking this variable? 538 ValueObjectSP valobj_sp (GetValueObjectForFrameVariable (variable_sp)); 539 if (!valobj_sp) 540 { 541 // We aren't already tracking this global 542 VariableList *var_list = GetVariableList (true); 543 // If this frame has no variables, create a new list 544 if (var_list == NULL) 545 m_variable_list_sp.reset (new VariableList()); 546 547 // Add the global/static variable to this frame 548 m_variable_list_sp->AddVariable (variable_sp); 549 550 // Now make a value object for it so we can track its changes 551 valobj_sp = GetValueObjectForFrameVariable (variable_sp); 552 } 553 return valobj_sp; 554 } 555 556 bool 557 StackFrame::IsInlined () 558 { 559 if (m_sc.block == NULL) 560 GetSymbolContext (eSymbolContextBlock); 561 if (m_sc.block) 562 return m_sc.block->GetContainingInlinedBlock() != NULL; 563 return false; 564 } 565 566 Target * 567 StackFrame::CalculateTarget () 568 { 569 return m_thread.CalculateTarget(); 570 } 571 572 Process * 573 StackFrame::CalculateProcess () 574 { 575 return m_thread.CalculateProcess(); 576 } 577 578 Thread * 579 StackFrame::CalculateThread () 580 { 581 return &m_thread; 582 } 583 584 StackFrame * 585 StackFrame::CalculateStackFrame () 586 { 587 return this; 588 } 589 590 591 void 592 StackFrame::Calculate (ExecutionContext &exe_ctx) 593 { 594 m_thread.Calculate (exe_ctx); 595 exe_ctx.frame = this; 596 } 597 598 void 599 StackFrame::Dump (Stream *strm, bool show_frame_index, bool show_fullpaths) 600 { 601 if (strm == NULL) 602 return; 603 604 if (show_frame_index) 605 strm->Printf("frame #%u: ", m_frame_index); 606 strm->Printf("0x%0*llx ", m_thread.GetProcess().GetAddressByteSize() * 2, GetFrameCodeAddress().GetLoadAddress(&m_thread.GetProcess())); 607 GetSymbolContext(eSymbolContextEverything); 608 const bool show_module = true; 609 const bool show_inline = true; 610 m_sc.DumpStopContext(strm, &m_thread.GetProcess(), GetFrameCodeAddress(), show_fullpaths, show_module, show_inline); 611 } 612 613 void 614 StackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame) 615 { 616 assert (GetStackID() == prev_frame.GetStackID()); // TODO: remove this after some testing 617 m_variable_list_sp = prev_frame.m_variable_list_sp; 618 m_variable_list_value_objects.Swap (prev_frame.m_variable_list_value_objects); 619 if (!m_disassembly.GetString().empty()) 620 m_disassembly.GetString().swap (m_disassembly.GetString()); 621 } 622 623 624 void 625 StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame) 626 { 627 assert (GetStackID() == curr_frame.GetStackID()); // TODO: remove this after some testing 628 assert (&m_thread == &curr_frame.m_thread); 629 m_frame_index = curr_frame.m_frame_index; 630 m_unwind_frame_index = curr_frame.m_unwind_frame_index; 631 m_reg_context_sp = curr_frame.m_reg_context_sp; 632 m_frame_code_addr = curr_frame.m_frame_code_addr; 633 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()); 634 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()); 635 assert (m_sc.comp_unit == NULL || curr_frame.m_sc.comp_unit == NULL || m_sc.comp_unit == curr_frame.m_sc.comp_unit); 636 assert (m_sc.function == NULL || curr_frame.m_sc.function == NULL || m_sc.function == curr_frame.m_sc.function); 637 m_sc = curr_frame.m_sc; 638 m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything); 639 m_flags.Set (m_sc.GetResolvedMask()); 640 m_frame_base.Clear(); 641 m_frame_base_error.Clear(); 642 } 643 644 645