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