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