1 //===-- SBFrame.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/API/SBFrame.h" 11 12 #include <string> 13 #include <algorithm> 14 15 #include "lldb/lldb-types.h" 16 17 #include "lldb/Core/Address.h" 18 #include "lldb/Core/ConstString.h" 19 #include "lldb/Core/Stream.h" 20 #include "lldb/Core/StreamFile.h" 21 #include "lldb/Core/ValueObjectRegister.h" 22 #include "lldb/Core/ValueObjectVariable.h" 23 #include "lldb/Expression/ClangUserExpression.h" 24 #include "lldb/Symbol/Block.h" 25 #include "lldb/Symbol/SymbolContext.h" 26 #include "lldb/Symbol/VariableList.h" 27 #include "lldb/Symbol/Variable.h" 28 #include "lldb/Target/ExecutionContext.h" 29 #include "lldb/Target/Target.h" 30 #include "lldb/Target/Process.h" 31 #include "lldb/Target/RegisterContext.h" 32 #include "lldb/Target/StackFrame.h" 33 #include "lldb/Target/Thread.h" 34 35 #include "lldb/API/SBDebugger.h" 36 #include "lldb/API/SBValue.h" 37 #include "lldb/API/SBAddress.h" 38 #include "lldb/API/SBStream.h" 39 #include "lldb/API/SBSymbolContext.h" 40 #include "lldb/API/SBThread.h" 41 42 using namespace lldb; 43 using namespace lldb_private; 44 45 SBFrame::SBFrame () : 46 m_opaque_sp () 47 { 48 } 49 50 SBFrame::SBFrame (const lldb::StackFrameSP &lldb_object_sp) : 51 m_opaque_sp (lldb_object_sp) 52 { 53 } 54 55 SBFrame::~SBFrame() 56 { 57 } 58 59 60 void 61 SBFrame::SetFrame (const lldb::StackFrameSP &lldb_object_sp) 62 { 63 m_opaque_sp = lldb_object_sp; 64 } 65 66 67 bool 68 SBFrame::IsValid() const 69 { 70 return (m_opaque_sp.get() != NULL); 71 } 72 73 SBSymbolContext 74 SBFrame::GetSymbolContext (uint32_t resolve_scope) const 75 { 76 SBSymbolContext sb_sym_ctx; 77 if (m_opaque_sp) 78 sb_sym_ctx.SetSymbolContext(&m_opaque_sp->GetSymbolContext (resolve_scope)); 79 return sb_sym_ctx; 80 } 81 82 SBModule 83 SBFrame::GetModule () const 84 { 85 SBModule sb_module (m_opaque_sp->GetSymbolContext (eSymbolContextModule).module_sp); 86 return sb_module; 87 } 88 89 SBCompileUnit 90 SBFrame::GetCompileUnit () const 91 { 92 SBCompileUnit sb_comp_unit(m_opaque_sp->GetSymbolContext (eSymbolContextCompUnit).comp_unit); 93 return sb_comp_unit; 94 } 95 96 SBFunction 97 SBFrame::GetFunction () const 98 { 99 SBFunction sb_function(m_opaque_sp->GetSymbolContext (eSymbolContextFunction).function); 100 return sb_function; 101 } 102 103 SBSymbol 104 SBFrame::GetSymbol () const 105 { 106 SBSymbol sb_symbol(m_opaque_sp->GetSymbolContext (eSymbolContextSymbol).symbol); 107 return sb_symbol; 108 } 109 110 SBBlock 111 SBFrame::GetBlock () const 112 { 113 SBBlock sb_block(m_opaque_sp->GetSymbolContext (eSymbolContextBlock).block); 114 return sb_block; 115 } 116 117 SBBlock 118 SBFrame::GetFrameBlock () const 119 { 120 SBBlock sb_block(m_opaque_sp->GetFrameBlock ()); 121 return sb_block; 122 } 123 124 SBLineEntry 125 SBFrame::GetLineEntry () const 126 { 127 SBLineEntry sb_line_entry(&m_opaque_sp->GetSymbolContext (eSymbolContextLineEntry).line_entry); 128 return sb_line_entry; 129 } 130 131 uint32_t 132 SBFrame::GetFrameID () const 133 { 134 if (m_opaque_sp) 135 return m_opaque_sp->GetFrameIndex (); 136 else 137 return UINT32_MAX; 138 } 139 140 lldb::addr_t 141 SBFrame::GetPC () const 142 { 143 if (m_opaque_sp) 144 return m_opaque_sp->GetFrameCodeAddress().GetLoadAddress (&m_opaque_sp->GetThread().GetProcess().GetTarget()); 145 return LLDB_INVALID_ADDRESS; 146 } 147 148 bool 149 SBFrame::SetPC (lldb::addr_t new_pc) 150 { 151 if (m_opaque_sp) 152 return m_opaque_sp->GetRegisterContext()->SetPC (new_pc); 153 return false; 154 } 155 156 lldb::addr_t 157 SBFrame::GetSP () const 158 { 159 if (m_opaque_sp) 160 return m_opaque_sp->GetRegisterContext()->GetSP(); 161 return LLDB_INVALID_ADDRESS; 162 } 163 164 165 lldb::addr_t 166 SBFrame::GetFP () const 167 { 168 if (m_opaque_sp) 169 return m_opaque_sp->GetRegisterContext()->GetFP(); 170 return LLDB_INVALID_ADDRESS; 171 } 172 173 174 SBAddress 175 SBFrame::GetPCAddress () const 176 { 177 SBAddress sb_addr; 178 if (m_opaque_sp) 179 sb_addr.SetAddress (&m_opaque_sp->GetFrameCodeAddress()); 180 return sb_addr; 181 } 182 183 void 184 SBFrame::Clear() 185 { 186 m_opaque_sp.reset(); 187 } 188 189 SBValue 190 SBFrame::LookupVar (const char *var_name) 191 { 192 lldb::VariableSP var_sp; 193 if (IsValid ()) 194 { 195 lldb_private::VariableList variable_list; 196 SBSymbolContext sc = GetSymbolContext (eSymbolContextEverything); 197 198 SBBlock block = sc.GetBlock(); 199 if (block.IsValid()) 200 block.AppendVariables (true, true, &variable_list); 201 202 const uint32_t num_variables = variable_list.GetSize(); 203 204 bool found = false; 205 for (uint32_t i = 0; i < num_variables && !found; ++i) 206 { 207 var_sp = variable_list.GetVariableAtIndex(i); 208 if (var_sp 209 && (var_sp.get()->GetName() == lldb_private::ConstString(var_name))) 210 found = true; 211 } 212 if (!found) 213 var_sp.reset(); 214 } 215 if (var_sp) 216 { 217 SBValue sb_value (ValueObjectSP (new ValueObjectVariable (var_sp))); 218 return sb_value; 219 } 220 221 SBValue sb_value; 222 return sb_value; 223 } 224 225 SBValue 226 SBFrame::LookupVarInScope (const char *var_name, const char *scope) 227 { 228 lldb::VariableSP var_sp; 229 if (IsValid()) 230 { 231 std::string scope_str = scope; 232 lldb::ValueType var_scope = eValueTypeInvalid; 233 // Convert scope_str to be all lowercase; 234 std::transform (scope_str.begin(), scope_str.end(), scope_str.begin(), ::tolower); 235 236 if (scope_str.compare ("global") == 0) 237 var_scope = eValueTypeVariableGlobal; 238 else if (scope_str.compare ("local") == 0) 239 var_scope = eValueTypeVariableLocal; 240 else if (scope_str.compare ("parameter") == 0) 241 var_scope = eValueTypeVariableArgument; 242 243 if (var_scope != eValueTypeInvalid) 244 { 245 lldb_private::VariableList variable_list; 246 SBSymbolContext sc = GetSymbolContext (eSymbolContextEverything); 247 248 SBBlock block = sc.GetBlock(); 249 if (block.IsValid()) 250 block.AppendVariables (true, true, &variable_list); 251 252 const uint32_t num_variables = variable_list.GetSize(); 253 254 bool found = false; 255 for (uint32_t i = 0; i < num_variables && !found; ++i) 256 { 257 var_sp = variable_list.GetVariableAtIndex(i); 258 if (var_sp 259 && (var_sp.get()->GetName() == lldb_private::ConstString(var_name)) 260 && var_sp.get()->GetScope() == var_scope) 261 found = true; 262 } 263 if (!found) 264 var_sp.reset(); 265 } 266 } 267 268 if (var_sp) 269 { 270 SBValue sb_value (ValueObjectSP (new ValueObjectVariable (var_sp))); 271 return sb_value; 272 } 273 274 SBValue sb_value; 275 return sb_value; 276 } 277 278 bool 279 SBFrame::operator == (const SBFrame &rhs) const 280 { 281 return m_opaque_sp.get() == rhs.m_opaque_sp.get(); 282 } 283 284 bool 285 SBFrame::operator != (const SBFrame &rhs) const 286 { 287 return m_opaque_sp.get() != rhs.m_opaque_sp.get(); 288 } 289 290 lldb_private::StackFrame * 291 SBFrame::operator->() const 292 { 293 return m_opaque_sp.get(); 294 } 295 296 lldb_private::StackFrame * 297 SBFrame::get() const 298 { 299 return m_opaque_sp.get(); 300 } 301 302 303 SBThread 304 SBFrame::GetThread () const 305 { 306 SBThread sb_thread (m_opaque_sp->GetThread().GetSP()); 307 return sb_thread; 308 } 309 310 const char * 311 SBFrame::Disassemble () const 312 { 313 if (m_opaque_sp) 314 return m_opaque_sp->Disassemble(); 315 return NULL; 316 } 317 318 319 320 lldb_private::StackFrame * 321 SBFrame::GetLLDBObjectPtr () 322 { 323 return m_opaque_sp.get(); 324 } 325 326 SBValueList 327 SBFrame::GetVariables (bool arguments, 328 bool locals, 329 bool statics, 330 bool in_scope_only) 331 { 332 SBValueList value_list; 333 if (m_opaque_sp) 334 { 335 size_t i; 336 VariableList *variable_list = m_opaque_sp->GetVariableList(true); 337 if (variable_list) 338 { 339 const size_t num_variables = variable_list->GetSize(); 340 if (num_variables) 341 { 342 for (i = 0; i < num_variables; ++i) 343 { 344 VariableSP variable_sp (variable_list->GetVariableAtIndex(i)); 345 if (variable_sp) 346 { 347 bool add_variable = false; 348 switch (variable_sp->GetScope()) 349 { 350 case eValueTypeVariableGlobal: 351 case eValueTypeVariableStatic: 352 add_variable = statics; 353 break; 354 355 case eValueTypeVariableArgument: 356 add_variable = arguments; 357 break; 358 359 case eValueTypeVariableLocal: 360 add_variable = locals; 361 break; 362 363 default: 364 break; 365 } 366 if (add_variable) 367 { 368 if (in_scope_only && !variable_sp->IsInScope(m_opaque_sp.get())) 369 continue; 370 371 value_list.Append(m_opaque_sp->GetValueObjectForFrameVariable (variable_sp)); 372 } 373 } 374 } 375 } 376 } 377 } 378 return value_list; 379 } 380 381 lldb::SBValueList 382 SBFrame::GetRegisters () 383 { 384 SBValueList value_list; 385 if (m_opaque_sp) 386 { 387 RegisterContext *reg_ctx = m_opaque_sp->GetRegisterContext(); 388 if (reg_ctx) 389 { 390 const uint32_t num_sets = reg_ctx->GetRegisterSetCount(); 391 for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx) 392 { 393 value_list.Append(ValueObjectSP (new ValueObjectRegisterSet (NULL, reg_ctx, set_idx))); 394 } 395 } 396 } 397 return value_list; 398 } 399 400 bool 401 SBFrame::GetDescription (SBStream &description) 402 { 403 if (m_opaque_sp) 404 { 405 description.Printf("SBFrame: idx = %u", m_opaque_sp->GetFrameIndex()); 406 } 407 else 408 description.Printf ("No value"); 409 410 return true; 411 } 412 413 lldb::SBValue 414 SBFrame::EvaluateExpression (const char *expr) 415 { 416 lldb::SBValue expr_result_value; 417 if (m_opaque_sp) 418 { 419 ExecutionContext exe_ctx; 420 m_opaque_sp->CalculateExecutionContext (exe_ctx); 421 *expr_result_value = ClangUserExpression::Evaluate (exe_ctx, expr); 422 } 423 return expr_result_value; 424 } 425