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 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_FRAME_ADDR)) 173 GetFrameCodeAddress(); 174 175 if (GetSymbolContext (eSymbolContextFunction).function) 176 { 177 m_id.SetStartAddress (m_sc.function->GetAddressRange().GetBaseAddress()); 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()); 184 } 185 } 186 return m_id; 187 } 188 189 Address& 190 StackFrame::GetFrameCodeAddress() 191 { 192 if (m_flags.IsClear(RESOLVED_FRAME_ADDR) && !m_pc.IsSectionOffset()) 193 { 194 m_flags.Set (RESOLVED_FRAME_ADDR); 195 196 // Resolve the PC into a temporary address because if ResolveLoadAddress 197 // fails to resolve the address, it will clear the address object... 198 Address resolved_pc; 199 if (m_thread.GetProcess().ResolveLoadAddress(m_pc.GetOffset(), resolved_pc)) 200 { 201 m_pc = resolved_pc; 202 const Section *section = m_pc.GetSection(); 203 if (section) 204 { 205 Module *module = section->GetModule(); 206 if (module) 207 { 208 m_sc.module_sp = module->GetSP(); 209 if (m_sc.module_sp) 210 m_flags.Set(eSymbolContextModule); 211 } 212 } 213 } 214 } 215 return m_pc; 216 } 217 218 void 219 StackFrame::ChangePC (addr_t pc) 220 { 221 m_pc.SetOffset(pc); 222 m_pc.SetSection(NULL); 223 m_sc.Clear(); 224 m_flags.SetAllFlagBits(0); 225 m_thread.ClearStackFrames (); 226 } 227 228 const char * 229 StackFrame::Disassemble () 230 { 231 if (m_disassembly.GetSize() == 0) 232 { 233 ExecutionContext exe_ctx; 234 Calculate(exe_ctx); 235 Target &target = m_thread.GetProcess().GetTarget(); 236 Disassembler::Disassemble (target.GetDebugger(), 237 target.GetArchitecture(), 238 exe_ctx, 239 0, 240 false, 241 m_disassembly); 242 if (m_disassembly.GetSize() == 0) 243 return NULL; 244 } 245 return m_disassembly.GetData(); 246 } 247 248 //---------------------------------------------------------------------- 249 // Get the symbol context if we already haven't done so by resolving the 250 // PC address as much as possible. This way when we pass around a 251 // StackFrame object, everyone will have as much information as 252 // possible and no one will ever have to look things up manually. 253 //---------------------------------------------------------------------- 254 const SymbolContext& 255 StackFrame::GetSymbolContext (uint32_t resolve_scope) 256 { 257 // Copy our internal symbol context into "sc". 258 if ((m_flags.GetAllFlagBits() & resolve_scope) != resolve_scope) 259 { 260 // Resolve our PC to section offset if we haven't alreday done so 261 // and if we don't have a module. The resolved address section will 262 // contain the module to which it belongs 263 if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_ADDR)) 264 GetFrameCodeAddress(); 265 266 // If this is not frame zero, then we need to subtract 1 from the PC 267 // value when doing address lookups since the PC will be on the 268 // instruction following the function call instruction... 269 270 Address lookup_addr(GetFrameCodeAddress()); 271 if (m_frame_index > 0 && lookup_addr.IsValid()) 272 { 273 addr_t offset = lookup_addr.GetOffset(); 274 if (offset > 0) 275 lookup_addr.SetOffset(offset - 1); 276 } 277 278 279 uint32_t resolved = 0; 280 if (m_sc.module_sp) 281 { 282 // We have something in our stack frame symbol context, lets check 283 // if we haven't already tried to lookup one of those things. If we 284 // haven't then we will do the query. 285 286 uint32_t actual_resolve_scope = 0; 287 288 if (resolve_scope & eSymbolContextCompUnit) 289 { 290 if (m_flags.IsClear (eSymbolContextCompUnit)) 291 { 292 if (m_sc.comp_unit) 293 resolved |= eSymbolContextCompUnit; 294 else 295 actual_resolve_scope |= eSymbolContextCompUnit; 296 } 297 } 298 299 if (resolve_scope & eSymbolContextFunction) 300 { 301 if (m_flags.IsClear (eSymbolContextFunction)) 302 { 303 if (m_sc.function) 304 resolved |= eSymbolContextFunction; 305 else 306 actual_resolve_scope |= eSymbolContextFunction; 307 } 308 } 309 310 if (resolve_scope & eSymbolContextBlock) 311 { 312 if (m_flags.IsClear (eSymbolContextBlock)) 313 { 314 if (m_sc.block) 315 resolved |= eSymbolContextBlock; 316 else 317 actual_resolve_scope |= eSymbolContextBlock; 318 } 319 } 320 321 if (resolve_scope & eSymbolContextSymbol) 322 { 323 if (m_flags.IsClear (eSymbolContextSymbol)) 324 { 325 if (m_sc.symbol) 326 resolved |= eSymbolContextSymbol; 327 else 328 actual_resolve_scope |= eSymbolContextSymbol; 329 } 330 } 331 332 if (resolve_scope & eSymbolContextLineEntry) 333 { 334 if (m_flags.IsClear (eSymbolContextLineEntry)) 335 { 336 if (m_sc.line_entry.IsValid()) 337 resolved |= eSymbolContextLineEntry; 338 else 339 actual_resolve_scope |= eSymbolContextLineEntry; 340 } 341 } 342 343 if (actual_resolve_scope) 344 { 345 // We might be resolving less information than what is already 346 // in our current symbol context so resolve into a temporary 347 // symbol context "sc" so we don't clear out data we have 348 // already found in "m_sc" 349 SymbolContext sc; 350 // Set flags that indicate what we have tried to resolve 351 resolved |= m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, actual_resolve_scope, sc); 352 // Only replace what we didn't already have as we may have 353 // information for an inlined function scope that won't match 354 // what a standard lookup by address would match 355 if ((resolved & eSymbolContextCompUnit) && m_sc.comp_unit == NULL) 356 m_sc.comp_unit = sc.comp_unit; 357 if ((resolved & eSymbolContextFunction) && m_sc.function == NULL) 358 m_sc.function = sc.function; 359 if ((resolved & eSymbolContextBlock) && m_sc.block == NULL) 360 m_sc.block = sc.block; 361 if ((resolved & eSymbolContextSymbol) && m_sc.symbol == NULL) 362 m_sc.symbol = sc.symbol; 363 if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid()) 364 m_sc.line_entry = sc.line_entry; 365 366 } 367 } 368 else 369 { 370 // If we don't have a module, then we can't have the compile unit, 371 // function, block, line entry or symbol, so we can safely call 372 // ResolveSymbolContextForAddress with our symbol context member m_sc. 373 resolved |= m_thread.GetProcess().GetTarget().GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc); 374 } 375 376 // If the target was requested add that: 377 if (m_sc.target_sp.get() == NULL) 378 { 379 m_sc.target_sp = CalculateProcess()->GetTarget().GetSP(); 380 if (m_sc.target_sp) 381 resolved |= eSymbolContextTarget; 382 } 383 384 // Update our internal flags so we remember what we have tried to locate so 385 // we don't have to keep trying when more calls to this function are made. 386 // We might have dug up more information that was requested (for example 387 // if we were asked to only get the block, we will have gotten the 388 // compile unit, and function) so set any additional bits that we resolved 389 m_flags.Set (resolve_scope | resolved); 390 } 391 392 // Return the symbol context with everything that was possible to resolve 393 // resolved. 394 return m_sc; 395 } 396 397 398 VariableList * 399 StackFrame::GetVariableList () 400 { 401 if (m_flags.IsClear(RESOLVED_VARIABLES)) 402 { 403 m_flags.Set(RESOLVED_VARIABLES); 404 405 if (GetSymbolContext (eSymbolContextFunction).function) 406 { 407 bool get_child_variables = true; 408 bool can_create = true; 409 m_variable_list_sp = m_sc.function->GetBlock (can_create).GetVariableList (get_child_variables, can_create); 410 } 411 } 412 return m_variable_list_sp.get(); 413 } 414 415 416 bool 417 StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr) 418 { 419 if (m_flags.IsClear(GOT_FRAME_BASE)) 420 { 421 if (m_sc.function) 422 { 423 m_frame_base.Clear(); 424 m_frame_base_error.Clear(); 425 426 m_flags.Set(GOT_FRAME_BASE); 427 ExecutionContext exe_ctx (&m_thread.GetProcess(), &m_thread, this); 428 Value expr_value; 429 if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, expr_value, &m_frame_base_error) < 0) 430 { 431 // We should really have an error if evaluate returns, but in case 432 // we don't, lets set the error to something at least. 433 if (m_frame_base_error.Success()) 434 m_frame_base_error.SetErrorString("Evaluation of the frame base expression failed."); 435 } 436 else 437 { 438 m_frame_base = expr_value.ResolveValue(&exe_ctx, NULL); 439 } 440 } 441 else 442 { 443 m_frame_base_error.SetErrorString ("No function in symbol context."); 444 } 445 } 446 447 if (m_frame_base_error.Success()) 448 frame_base = m_frame_base; 449 450 if (error_ptr) 451 *error_ptr = m_frame_base_error; 452 return m_frame_base_error.Success(); 453 } 454 455 RegisterContext * 456 StackFrame::GetRegisterContext () 457 { 458 if (m_reg_context_sp.get() == NULL) 459 m_reg_context_sp.reset (m_thread.CreateRegisterContextForFrame (this)); 460 return m_reg_context_sp.get(); 461 } 462 463 bool 464 StackFrame::HasDebugInformation () 465 { 466 GetSymbolContext (eSymbolContextLineEntry); 467 return m_sc.line_entry.IsValid(); 468 } 469 470 ValueObjectList & 471 StackFrame::GetValueObjectList() 472 { 473 return m_value_object_list; 474 } 475 476 477 Target * 478 StackFrame::CalculateTarget () 479 { 480 return m_thread.CalculateTarget(); 481 } 482 483 Process * 484 StackFrame::CalculateProcess () 485 { 486 return m_thread.CalculateProcess(); 487 } 488 489 Thread * 490 StackFrame::CalculateThread () 491 { 492 return &m_thread; 493 } 494 495 StackFrame * 496 StackFrame::CalculateStackFrame () 497 { 498 return this; 499 } 500 501 502 void 503 StackFrame::Calculate (ExecutionContext &exe_ctx) 504 { 505 m_thread.Calculate (exe_ctx); 506 exe_ctx.frame = this; 507 } 508 509 void 510 StackFrame::Dump (Stream *strm, bool show_frame_index) 511 { 512 if (strm == NULL) 513 return; 514 515 if (show_frame_index) 516 strm->Printf("frame #%u: ", m_frame_index); 517 strm->Printf("0x%0*llx", m_thread.GetProcess().GetAddressByteSize() * 2, GetFrameCodeAddress().GetLoadAddress(&m_thread.GetProcess())); 518 GetSymbolContext(eSymbolContextEverything); 519 strm->PutCString(", where = "); 520 // TODO: need to get the 521 const bool show_module = true; 522 const bool show_inline = true; 523 m_sc.DumpStopContext(strm, &m_thread.GetProcess(), GetFrameCodeAddress(), show_module, show_inline); 524 } 525 526