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 (lldb::user_id_t frame_idx, Thread &thread, lldb::addr_t cfa, lldb::addr_t pc, const SymbolContext *sc_ptr) : 39 UserID (frame_idx), 40 m_thread (thread), 41 m_reg_context_sp(), 42 m_id(cfa), 43 m_pc(NULL, pc), 44 m_sc(), 45 m_flags(), 46 m_frame_base(), 47 m_frame_base_error(), 48 m_variable_list_sp (), 49 m_value_object_list () 50 { 51 if (sc_ptr != NULL) 52 m_sc = *sc_ptr; 53 } 54 55 StackFrame::StackFrame (lldb::user_id_t frame_idx, Thread &thread, RegisterContextSP ®_context_sp, lldb::addr_t cfa, lldb::addr_t pc, const SymbolContext *sc_ptr) : 56 UserID (frame_idx), 57 m_thread (thread), 58 m_reg_context_sp(reg_context_sp), 59 m_id(cfa), 60 m_pc(NULL, pc), 61 m_sc(), 62 m_flags(), 63 m_frame_base(), 64 m_frame_base_error(), 65 m_variable_list_sp (), 66 m_value_object_list () 67 { 68 if (sc_ptr != NULL) 69 m_sc = *sc_ptr; 70 } 71 72 73 //---------------------------------------------------------------------- 74 // Destructor 75 //---------------------------------------------------------------------- 76 StackFrame::~StackFrame() 77 { 78 } 79 80 StackID& 81 StackFrame::GetStackID() 82 { 83 // Make sure we have resolved our stack ID's address range before we give 84 // it out to any external clients 85 if (m_id.GetStartAddress().IsValid() == 0 && m_flags.IsClear(RESOLVED_FRAME_ID)) 86 { 87 m_flags.Set (RESOLVED_FRAME_ID); 88 89 // Resolve our PC to section offset if we haven't alreday done so 90 // and if we don't have a module. The resolved address section will 91 // contain the module to which it belongs. 92 if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_PC_SO_ADDR)) 93 GetPC(); 94 95 const uint32_t resolve_scope = eSymbolContextModule | 96 eSymbolContextCompUnit | 97 eSymbolContextFunction; 98 99 if (m_sc.module_sp) 100 { 101 if (m_sc.module_sp->ResolveSymbolContextForAddress (GetPC(), resolve_scope, m_sc) & eSymbolContextFunction) 102 { 103 assert (m_sc.function); 104 m_id.SetStartAddress(m_sc.function->GetAddressRange().GetBaseAddress()); 105 } 106 else if (m_sc.module_sp->ResolveSymbolContextForAddress (GetPC(), resolve_scope, m_sc) & eSymbolContextSymbol) 107 { 108 assert (m_sc.symbol); 109 AddressRange *symbol_range_ptr = m_sc.symbol->GetAddressRangePtr(); 110 if (symbol_range_ptr) 111 m_id.SetStartAddress(symbol_range_ptr->GetBaseAddress()); 112 } 113 } 114 // else if (m_sc.target != NULL) 115 // { 116 // if (m_sc.target->GetImages().ResolveSymbolContextForAddress (GetPC(), resolve_scope, m_sc) & eSymbolContextFunction) 117 // { 118 // assert (m_sc.function); 119 // m_id.GetAddressRange() = m_sc.function->GetAddressRange(); 120 // } 121 // else if (m_sc.target->GetImages().ResolveSymbolContextForAddress (GetPC(), resolve_scope, m_sc) & eSymbolContextSymbol) 122 // { 123 // assert (m_sc.symbol); 124 // AddressRange *symbol_range_ptr = m_sc.symbol->GetAddressRange(); 125 // if (symbol_range_ptr) 126 // m_id.GetAddressRange() = *symbol_range_ptr; 127 // } 128 // } 129 } 130 return m_id; 131 } 132 133 Address& 134 StackFrame::GetPC() 135 { 136 if (m_flags.IsClear(RESOLVED_PC_SO_ADDR) && !m_pc.IsSectionOffset()) 137 { 138 m_flags.Set (RESOLVED_PC_SO_ADDR); 139 140 // Resolve the PC into a temporary address because if ResolveLoadAddress 141 // fails to resolve the address, it will clear the address object... 142 Address resolved_pc; 143 if (m_thread.GetProcess().ResolveLoadAddress(m_pc.GetOffset(), resolved_pc)) 144 { 145 m_pc = resolved_pc; 146 const Section *section = m_pc.GetSection(); 147 if (section) 148 { 149 Module *module = section->GetModule(); 150 if (module) 151 { 152 m_sc.module_sp = module->GetSP(); 153 if (m_sc.module_sp) 154 m_flags.Set(eSymbolContextModule); 155 } 156 } 157 } 158 } 159 return m_pc; 160 } 161 162 void 163 StackFrame::ChangePC (addr_t pc) 164 { 165 m_pc.SetOffset(pc); 166 m_pc.SetSection(NULL); 167 m_sc.Clear(); 168 m_flags.SetAllFlagBits(0); 169 m_thread.ClearStackFrames (); 170 } 171 172 const char * 173 StackFrame::Disassemble () 174 { 175 if (m_disassembly.GetSize() == 0) 176 { 177 ExecutionContext exe_ctx; 178 Calculate(exe_ctx); 179 Disassembler::Disassemble (m_thread.GetProcess().GetTarget().GetArchitecture(), 180 exe_ctx, 181 0, 182 m_disassembly); 183 if (m_disassembly.GetSize() == 0) 184 return NULL; 185 } 186 return m_disassembly.GetData(); 187 } 188 189 //---------------------------------------------------------------------- 190 // Get the symbol context if we already haven't done so by resolving the 191 // PC address as much as possible. This way when we pass around a 192 // StackFrame object, everyone will have as much information as 193 // possible and no one will ever have to look things up manually. 194 //---------------------------------------------------------------------- 195 const SymbolContext& 196 StackFrame::GetSymbolContext (uint32_t resolve_scope) 197 { 198 // Copy our internal symbol context into "sc". 199 200 if ((m_flags.GetAllFlagBits() & resolve_scope) != resolve_scope) 201 { 202 // Resolve our PC to section offset if we haven't alreday done so 203 // and if we don't have a module. The resolved address section will 204 // contain the module to which it belongs 205 if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_PC_SO_ADDR)) 206 GetPC(); 207 208 // If this is not frame zero, then we need to subtract 1 from the PC 209 // value when doing address lookups since the PC will be on the 210 // instruction following the function call instruction... 211 212 Address lookup_addr(GetPC()); 213 if (GetID() > 0 && lookup_addr.IsValid()) 214 { 215 addr_t offset = lookup_addr.GetOffset(); 216 if (offset > 0) 217 lookup_addr.SetOffset(offset - 1); 218 } 219 220 if (m_sc.module_sp) 221 { 222 // We have something in our stack frame symbol context, lets check 223 // if we haven't already tried to lookup one of those things. If we 224 // haven't then we will do the query. 225 if ((m_sc.comp_unit == NULL && (resolve_scope & eSymbolContextCompUnit ) && m_flags.IsClear(eSymbolContextCompUnit )) || 226 (m_sc.function == NULL && (resolve_scope & eSymbolContextFunction ) && m_flags.IsClear(eSymbolContextFunction )) || 227 (m_sc.block == NULL && (resolve_scope & eSymbolContextBlock ) && m_flags.IsClear(eSymbolContextBlock )) || 228 (m_sc.symbol == NULL && (resolve_scope & eSymbolContextSymbol ) && m_flags.IsClear(eSymbolContextSymbol )) || 229 (!m_sc.line_entry.IsValid() && (resolve_scope & eSymbolContextLineEntry) && m_flags.IsClear(eSymbolContextLineEntry ))) 230 { 231 // We might be resolving less information than what is already 232 // in our current symbol context so resolve into a temporary 233 // symbol context "sc" so we don't clear out data we have 234 // already found in "m_sc" 235 SymbolContext sc; 236 // Set flags that indicate what we have tried to resolve 237 const uint32_t resolved = m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, resolve_scope, sc); 238 if (resolved & eSymbolContextCompUnit) m_sc.comp_unit = sc.comp_unit; 239 if (resolved & eSymbolContextFunction) m_sc.function = sc.function; 240 if (resolved & eSymbolContextBlock) m_sc.block = sc.block; 241 if (resolved & eSymbolContextSymbol) m_sc.symbol = sc.symbol; 242 if (resolved & eSymbolContextLineEntry) m_sc.line_entry = sc.line_entry; 243 } 244 } 245 else 246 { 247 // If we don't have a module, then we can't have the compile unit, 248 // function, block, line entry or symbol, so we can safely call 249 // ResolveSymbolContextForAddress with our symbol context member m_sc. 250 m_thread.GetProcess().GetTarget().GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc); 251 } 252 253 // If the target was requested add that: 254 if (m_sc.target_sp.get() == NULL) 255 m_sc.target_sp = CalculateProcess()->GetTarget().GetSP(); 256 257 // Update our internal flags so we remember what we have tried to locate so 258 // we don't have to keep trying when more calls to this function are made. 259 m_flags.Set(resolve_scope); 260 } 261 262 // Return the symbol context with everything that was possible to resolve 263 // resolved. 264 return m_sc; 265 } 266 267 268 VariableList * 269 StackFrame::GetVariableList () 270 { 271 if (m_flags.IsClear(RESOLVED_VARIABLES)) 272 { 273 m_flags.Set(RESOLVED_VARIABLES); 274 275 GetSymbolContext(eSymbolContextFunction); 276 if (m_sc.function) 277 { 278 bool get_child_variables = true; 279 bool can_create = true; 280 m_variable_list_sp = m_sc.function->GetBlocks(can_create).GetVariableList (Block::RootID, get_child_variables, can_create); 281 } 282 } 283 return m_variable_list_sp.get(); 284 } 285 286 287 bool 288 StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr) 289 { 290 if (m_flags.IsClear(GOT_FRAME_BASE)) 291 { 292 if (m_sc.function) 293 { 294 m_frame_base.Clear(); 295 m_frame_base_error.Clear(); 296 297 m_flags.Set(GOT_FRAME_BASE); 298 ExecutionContext exe_ctx (&m_thread.GetProcess(), &m_thread, this); 299 Value expr_value; 300 if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, expr_value, &m_frame_base_error) < 0) 301 { 302 // We should really have an error if evaluate returns, but in case 303 // we don't, lets set the error to something at least. 304 if (m_frame_base_error.Success()) 305 m_frame_base_error.SetErrorString("Evaluation of the frame base expression failed."); 306 } 307 else 308 { 309 m_frame_base = expr_value.ResolveValue(&exe_ctx, NULL); 310 } 311 } 312 else 313 { 314 m_frame_base_error.SetErrorString ("No function in symbol context."); 315 } 316 } 317 318 if (m_frame_base_error.Success()) 319 frame_base = m_frame_base; 320 321 if (error_ptr) 322 *error_ptr = m_frame_base_error; 323 return m_frame_base_error.Success(); 324 } 325 326 RegisterContext * 327 StackFrame::GetRegisterContext () 328 { 329 if (m_reg_context_sp.get() == NULL) 330 m_reg_context_sp.reset (m_thread.CreateRegisterContextForFrame (this)); 331 return m_reg_context_sp.get(); 332 } 333 334 bool 335 StackFrame::HasDebugInformation () 336 { 337 GetSymbolContext(eSymbolContextLineEntry); 338 return m_sc.line_entry.IsValid(); 339 } 340 341 ValueObjectList & 342 StackFrame::GetValueObjectList() 343 { 344 return m_value_object_list; 345 } 346 347 348 Target * 349 StackFrame::CalculateTarget () 350 { 351 return m_thread.CalculateTarget(); 352 } 353 354 Process * 355 StackFrame::CalculateProcess () 356 { 357 return m_thread.CalculateProcess(); 358 } 359 360 Thread * 361 StackFrame::CalculateThread () 362 { 363 return &m_thread; 364 } 365 366 StackFrame * 367 StackFrame::CalculateStackFrame () 368 { 369 return this; 370 } 371 372 373 void 374 StackFrame::Calculate (ExecutionContext &exe_ctx) 375 { 376 m_thread.Calculate (exe_ctx); 377 exe_ctx.frame = this; 378 } 379 380 void 381 StackFrame::Dump (Stream *strm, bool show_frame_index) 382 { 383 if (strm == NULL) 384 return; 385 386 if (show_frame_index) 387 strm->Printf("frame #%u: ", GetID()); 388 strm->Printf("pc = 0x%0*llx", m_thread.GetProcess().GetAddressByteSize() * 2, GetRegisterContext()->GetPC()); 389 SymbolContext sc (GetSymbolContext(eSymbolContextEverything)); 390 strm->PutCString(", where = "); 391 sc.DumpStopContext(strm, &m_thread.GetProcess(), GetPC()); 392 } 393 394