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