1254721Semaste//===-- StackFrame.cpp ------------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/lldb-python.h" 11254721Semaste 12254721Semaste#include "lldb/Target/StackFrame.h" 13254721Semaste 14254721Semaste// C Includes 15254721Semaste// C++ Includes 16254721Semaste// Other libraries and framework includes 17254721Semaste// Project includes 18254721Semaste#include "lldb/Core/Module.h" 19254721Semaste#include "lldb/Core/Debugger.h" 20254721Semaste#include "lldb/Core/Disassembler.h" 21254721Semaste#include "lldb/Core/Value.h" 22254721Semaste#include "lldb/Core/ValueObjectVariable.h" 23254721Semaste#include "lldb/Core/ValueObjectConstResult.h" 24254721Semaste#include "lldb/Symbol/CompileUnit.h" 25254721Semaste#include "lldb/Symbol/Function.h" 26254721Semaste#include "lldb/Symbol/Symbol.h" 27254721Semaste#include "lldb/Symbol/SymbolContextScope.h" 28254721Semaste#include "lldb/Symbol/VariableList.h" 29254721Semaste#include "lldb/Target/ExecutionContext.h" 30254721Semaste#include "lldb/Target/Process.h" 31254721Semaste#include "lldb/Target/RegisterContext.h" 32254721Semaste#include "lldb/Target/Target.h" 33254721Semaste#include "lldb/Target/Thread.h" 34254721Semaste 35254721Semasteusing namespace lldb; 36254721Semasteusing namespace lldb_private; 37254721Semaste 38254721Semaste// The first bits in the flags are reserved for the SymbolContext::Scope bits 39254721Semaste// so we know if we have tried to look up information in our internal symbol 40254721Semaste// context (m_sc) already. 41254721Semaste#define RESOLVED_FRAME_CODE_ADDR (uint32_t(eSymbolContextEverything + 1)) 42254721Semaste#define RESOLVED_FRAME_ID_SYMBOL_SCOPE (RESOLVED_FRAME_CODE_ADDR << 1) 43254721Semaste#define GOT_FRAME_BASE (RESOLVED_FRAME_ID_SYMBOL_SCOPE << 1) 44254721Semaste#define RESOLVED_VARIABLES (GOT_FRAME_BASE << 1) 45254721Semaste#define RESOLVED_GLOBAL_VARIABLES (RESOLVED_VARIABLES << 1) 46254721Semaste 47254721SemasteStackFrame::StackFrame (const ThreadSP &thread_sp, 48254721Semaste user_id_t frame_idx, 49254721Semaste user_id_t unwind_frame_index, 50254721Semaste addr_t cfa, 51263363Semaste bool cfa_is_valid, 52254721Semaste addr_t pc, 53263363Semaste uint32_t stop_id, 54263363Semaste bool stop_id_is_valid, 55263363Semaste bool is_history_frame, 56254721Semaste const SymbolContext *sc_ptr) : 57254721Semaste m_thread_wp (thread_sp), 58254721Semaste m_frame_index (frame_idx), 59254721Semaste m_concrete_frame_index (unwind_frame_index), 60254721Semaste m_reg_context_sp (), 61254721Semaste m_id (pc, cfa, NULL), 62254721Semaste m_frame_code_addr (pc), 63254721Semaste m_sc (), 64254721Semaste m_flags (), 65254721Semaste m_frame_base (), 66254721Semaste m_frame_base_error (), 67263363Semaste m_cfa_is_valid (cfa_is_valid), 68263363Semaste m_stop_id (stop_id), 69263363Semaste m_stop_id_is_valid (stop_id_is_valid), 70263363Semaste m_is_history_frame (is_history_frame), 71254721Semaste m_variable_list_sp (), 72254721Semaste m_variable_list_value_objects (), 73254721Semaste m_disassembly () 74254721Semaste{ 75263363Semaste // If we don't have a CFA value, use the frame index for our StackID so that recursive 76263363Semaste // functions properly aren't confused with one another on a history stack. 77263363Semaste if (m_is_history_frame && m_cfa_is_valid == false) 78263363Semaste { 79263363Semaste m_id.SetCFA (m_frame_index); 80263363Semaste } 81263363Semaste 82254721Semaste if (sc_ptr != NULL) 83254721Semaste { 84254721Semaste m_sc = *sc_ptr; 85254721Semaste m_flags.Set(m_sc.GetResolvedMask ()); 86254721Semaste } 87254721Semaste} 88254721Semaste 89254721SemasteStackFrame::StackFrame (const ThreadSP &thread_sp, 90254721Semaste user_id_t frame_idx, 91254721Semaste user_id_t unwind_frame_index, 92254721Semaste const RegisterContextSP ®_context_sp, 93254721Semaste addr_t cfa, 94254721Semaste addr_t pc, 95254721Semaste const SymbolContext *sc_ptr) : 96254721Semaste m_thread_wp (thread_sp), 97254721Semaste m_frame_index (frame_idx), 98254721Semaste m_concrete_frame_index (unwind_frame_index), 99254721Semaste m_reg_context_sp (reg_context_sp), 100254721Semaste m_id (pc, cfa, NULL), 101254721Semaste m_frame_code_addr (pc), 102254721Semaste m_sc (), 103254721Semaste m_flags (), 104254721Semaste m_frame_base (), 105254721Semaste m_frame_base_error (), 106263363Semaste m_cfa_is_valid (true), 107263363Semaste m_stop_id (0), 108263363Semaste m_stop_id_is_valid (false), 109263363Semaste m_is_history_frame (false), 110254721Semaste m_variable_list_sp (), 111254721Semaste m_variable_list_value_objects (), 112254721Semaste m_disassembly () 113254721Semaste{ 114254721Semaste if (sc_ptr != NULL) 115254721Semaste { 116254721Semaste m_sc = *sc_ptr; 117254721Semaste m_flags.Set(m_sc.GetResolvedMask ()); 118254721Semaste } 119254721Semaste 120254721Semaste if (reg_context_sp && !m_sc.target_sp) 121254721Semaste { 122254721Semaste m_sc.target_sp = reg_context_sp->CalculateTarget(); 123254721Semaste if (m_sc.target_sp) 124254721Semaste m_flags.Set (eSymbolContextTarget); 125254721Semaste } 126254721Semaste} 127254721Semaste 128254721SemasteStackFrame::StackFrame (const ThreadSP &thread_sp, 129254721Semaste user_id_t frame_idx, 130254721Semaste user_id_t unwind_frame_index, 131254721Semaste const RegisterContextSP ®_context_sp, 132254721Semaste addr_t cfa, 133254721Semaste const Address& pc_addr, 134254721Semaste const SymbolContext *sc_ptr) : 135254721Semaste m_thread_wp (thread_sp), 136254721Semaste m_frame_index (frame_idx), 137254721Semaste m_concrete_frame_index (unwind_frame_index), 138254721Semaste m_reg_context_sp (reg_context_sp), 139254721Semaste m_id (pc_addr.GetLoadAddress (thread_sp->CalculateTarget().get()), cfa, NULL), 140254721Semaste m_frame_code_addr (pc_addr), 141254721Semaste m_sc (), 142254721Semaste m_flags (), 143254721Semaste m_frame_base (), 144254721Semaste m_frame_base_error (), 145263363Semaste m_cfa_is_valid (true), 146263363Semaste m_stop_id (0), 147263363Semaste m_stop_id_is_valid (false), 148263363Semaste m_is_history_frame (false), 149254721Semaste m_variable_list_sp (), 150254721Semaste m_variable_list_value_objects (), 151254721Semaste m_disassembly () 152254721Semaste{ 153254721Semaste if (sc_ptr != NULL) 154254721Semaste { 155254721Semaste m_sc = *sc_ptr; 156254721Semaste m_flags.Set(m_sc.GetResolvedMask ()); 157254721Semaste } 158254721Semaste 159254721Semaste if (m_sc.target_sp.get() == NULL && reg_context_sp) 160254721Semaste { 161254721Semaste m_sc.target_sp = reg_context_sp->CalculateTarget(); 162254721Semaste if (m_sc.target_sp) 163254721Semaste m_flags.Set (eSymbolContextTarget); 164254721Semaste } 165254721Semaste 166254721Semaste ModuleSP pc_module_sp (pc_addr.GetModule()); 167254721Semaste if (!m_sc.module_sp || m_sc.module_sp != pc_module_sp) 168254721Semaste { 169254721Semaste if (pc_module_sp) 170254721Semaste { 171254721Semaste m_sc.module_sp = pc_module_sp; 172254721Semaste m_flags.Set (eSymbolContextModule); 173254721Semaste } 174254721Semaste else 175254721Semaste { 176254721Semaste m_sc.module_sp.reset(); 177254721Semaste } 178254721Semaste } 179254721Semaste} 180254721Semaste 181254721Semaste 182254721Semaste//---------------------------------------------------------------------- 183254721Semaste// Destructor 184254721Semaste//---------------------------------------------------------------------- 185254721SemasteStackFrame::~StackFrame() 186254721Semaste{ 187254721Semaste} 188254721Semaste 189254721SemasteStackID& 190254721SemasteStackFrame::GetStackID() 191254721Semaste{ 192254721Semaste // Make sure we have resolved the StackID object's symbol context scope if 193254721Semaste // we already haven't looked it up. 194254721Semaste 195254721Semaste if (m_flags.IsClear (RESOLVED_FRAME_ID_SYMBOL_SCOPE)) 196254721Semaste { 197254721Semaste if (m_id.GetSymbolContextScope ()) 198254721Semaste { 199254721Semaste // We already have a symbol context scope, we just don't have our 200254721Semaste // flag bit set. 201254721Semaste m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE); 202254721Semaste } 203254721Semaste else 204254721Semaste { 205254721Semaste // Calculate the frame block and use this for the stack ID symbol 206254721Semaste // context scope if we have one. 207254721Semaste SymbolContextScope *scope = GetFrameBlock (); 208254721Semaste if (scope == NULL) 209254721Semaste { 210254721Semaste // We don't have a block, so use the symbol 211254721Semaste if (m_flags.IsClear (eSymbolContextSymbol)) 212254721Semaste GetSymbolContext (eSymbolContextSymbol); 213254721Semaste 214254721Semaste // It is ok if m_sc.symbol is NULL here 215254721Semaste scope = m_sc.symbol; 216254721Semaste } 217254721Semaste // Set the symbol context scope (the accessor will set the 218254721Semaste // RESOLVED_FRAME_ID_SYMBOL_SCOPE bit in m_flags). 219254721Semaste SetSymbolContextScope (scope); 220254721Semaste } 221254721Semaste } 222254721Semaste return m_id; 223254721Semaste} 224254721Semaste 225254721Semasteuint32_t 226254721SemasteStackFrame::GetFrameIndex () const 227254721Semaste{ 228254721Semaste ThreadSP thread_sp = GetThread(); 229254721Semaste if (thread_sp) 230254721Semaste return thread_sp->GetStackFrameList()->GetVisibleStackFrameIndex(m_frame_index); 231254721Semaste else 232254721Semaste return m_frame_index; 233254721Semaste} 234254721Semaste 235254721Semastevoid 236254721SemasteStackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope) 237254721Semaste{ 238254721Semaste m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE); 239254721Semaste m_id.SetSymbolContextScope (symbol_scope); 240254721Semaste} 241254721Semaste 242254721Semasteconst Address& 243254721SemasteStackFrame::GetFrameCodeAddress() 244254721Semaste{ 245254721Semaste if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) && !m_frame_code_addr.IsSectionOffset()) 246254721Semaste { 247254721Semaste m_flags.Set (RESOLVED_FRAME_CODE_ADDR); 248254721Semaste 249254721Semaste // Resolve the PC into a temporary address because if ResolveLoadAddress 250254721Semaste // fails to resolve the address, it will clear the address object... 251254721Semaste ThreadSP thread_sp (GetThread()); 252254721Semaste if (thread_sp) 253254721Semaste { 254254721Semaste TargetSP target_sp (thread_sp->CalculateTarget()); 255254721Semaste if (target_sp) 256254721Semaste { 257254721Semaste if (m_frame_code_addr.SetOpcodeLoadAddress (m_frame_code_addr.GetOffset(), target_sp.get())) 258254721Semaste { 259254721Semaste ModuleSP module_sp (m_frame_code_addr.GetModule()); 260254721Semaste if (module_sp) 261254721Semaste { 262254721Semaste m_sc.module_sp = module_sp; 263254721Semaste m_flags.Set(eSymbolContextModule); 264254721Semaste } 265254721Semaste } 266254721Semaste } 267254721Semaste } 268254721Semaste } 269254721Semaste return m_frame_code_addr; 270254721Semaste} 271254721Semaste 272263363Semastebool 273254721SemasteStackFrame::ChangePC (addr_t pc) 274254721Semaste{ 275263363Semaste // We can't change the pc value of a history stack frame - it is immutable. 276263363Semaste if (m_is_history_frame) 277263363Semaste return false; 278254721Semaste m_frame_code_addr.SetRawAddress(pc); 279254721Semaste m_sc.Clear(false); 280254721Semaste m_flags.Reset(0); 281254721Semaste ThreadSP thread_sp (GetThread()); 282254721Semaste if (thread_sp) 283254721Semaste thread_sp->ClearStackFrames (); 284263363Semaste return true; 285254721Semaste} 286254721Semaste 287254721Semasteconst char * 288254721SemasteStackFrame::Disassemble () 289254721Semaste{ 290254721Semaste if (m_disassembly.GetSize() == 0) 291254721Semaste { 292254721Semaste ExecutionContext exe_ctx (shared_from_this()); 293254721Semaste Target *target = exe_ctx.GetTargetPtr(); 294254721Semaste if (target) 295254721Semaste { 296254721Semaste const char *plugin_name = NULL; 297254721Semaste const char *flavor = NULL; 298254721Semaste Disassembler::Disassemble (target->GetDebugger(), 299254721Semaste target->GetArchitecture(), 300254721Semaste plugin_name, 301254721Semaste flavor, 302254721Semaste exe_ctx, 303254721Semaste 0, 304254721Semaste 0, 305254721Semaste 0, 306254721Semaste m_disassembly); 307254721Semaste } 308254721Semaste if (m_disassembly.GetSize() == 0) 309254721Semaste return NULL; 310254721Semaste } 311254721Semaste return m_disassembly.GetData(); 312254721Semaste} 313254721Semaste 314254721SemasteBlock * 315254721SemasteStackFrame::GetFrameBlock () 316254721Semaste{ 317254721Semaste if (m_sc.block == NULL && m_flags.IsClear (eSymbolContextBlock)) 318254721Semaste GetSymbolContext (eSymbolContextBlock); 319254721Semaste 320254721Semaste if (m_sc.block) 321254721Semaste { 322254721Semaste Block *inline_block = m_sc.block->GetContainingInlinedBlock(); 323254721Semaste if (inline_block) 324254721Semaste { 325254721Semaste // Use the block with the inlined function info 326254721Semaste // as the frame block we want this frame to have only the variables 327254721Semaste // for the inlined function and its non-inlined block child blocks. 328254721Semaste return inline_block; 329254721Semaste } 330254721Semaste else 331254721Semaste { 332254721Semaste // This block is not contained withing any inlined function blocks 333254721Semaste // with so we want to use the top most function block. 334254721Semaste return &m_sc.function->GetBlock (false); 335254721Semaste } 336254721Semaste } 337254721Semaste return NULL; 338254721Semaste} 339254721Semaste 340254721Semaste//---------------------------------------------------------------------- 341254721Semaste// Get the symbol context if we already haven't done so by resolving the 342254721Semaste// PC address as much as possible. This way when we pass around a 343254721Semaste// StackFrame object, everyone will have as much information as 344254721Semaste// possible and no one will ever have to look things up manually. 345254721Semaste//---------------------------------------------------------------------- 346254721Semasteconst SymbolContext& 347254721SemasteStackFrame::GetSymbolContext (uint32_t resolve_scope) 348254721Semaste{ 349254721Semaste // Copy our internal symbol context into "sc". 350254721Semaste if ((m_flags.Get() & resolve_scope) != resolve_scope) 351254721Semaste { 352254721Semaste uint32_t resolved = 0; 353254721Semaste 354254721Semaste // If the target was requested add that: 355254721Semaste if (!m_sc.target_sp) 356254721Semaste { 357254721Semaste m_sc.target_sp = CalculateTarget(); 358254721Semaste if (m_sc.target_sp) 359254721Semaste resolved |= eSymbolContextTarget; 360254721Semaste } 361254721Semaste 362254721Semaste 363254721Semaste // Resolve our PC to section offset if we haven't alreday done so 364254721Semaste // and if we don't have a module. The resolved address section will 365254721Semaste // contain the module to which it belongs 366254721Semaste if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR)) 367254721Semaste GetFrameCodeAddress(); 368254721Semaste 369254721Semaste // If this is not frame zero, then we need to subtract 1 from the PC 370254721Semaste // value when doing address lookups since the PC will be on the 371254721Semaste // instruction following the function call instruction... 372254721Semaste 373254721Semaste Address lookup_addr(GetFrameCodeAddress()); 374254721Semaste if (m_frame_index > 0 && lookup_addr.IsValid()) 375254721Semaste { 376254721Semaste addr_t offset = lookup_addr.GetOffset(); 377254721Semaste if (offset > 0) 378254721Semaste lookup_addr.SetOffset(offset - 1); 379254721Semaste } 380254721Semaste 381254721Semaste 382254721Semaste if (m_sc.module_sp) 383254721Semaste { 384254721Semaste // We have something in our stack frame symbol context, lets check 385254721Semaste // if we haven't already tried to lookup one of those things. If we 386254721Semaste // haven't then we will do the query. 387254721Semaste 388254721Semaste uint32_t actual_resolve_scope = 0; 389254721Semaste 390254721Semaste if (resolve_scope & eSymbolContextCompUnit) 391254721Semaste { 392254721Semaste if (m_flags.IsClear (eSymbolContextCompUnit)) 393254721Semaste { 394254721Semaste if (m_sc.comp_unit) 395254721Semaste resolved |= eSymbolContextCompUnit; 396254721Semaste else 397254721Semaste actual_resolve_scope |= eSymbolContextCompUnit; 398254721Semaste } 399254721Semaste } 400254721Semaste 401254721Semaste if (resolve_scope & eSymbolContextFunction) 402254721Semaste { 403254721Semaste if (m_flags.IsClear (eSymbolContextFunction)) 404254721Semaste { 405254721Semaste if (m_sc.function) 406254721Semaste resolved |= eSymbolContextFunction; 407254721Semaste else 408254721Semaste actual_resolve_scope |= eSymbolContextFunction; 409254721Semaste } 410254721Semaste } 411254721Semaste 412254721Semaste if (resolve_scope & eSymbolContextBlock) 413254721Semaste { 414254721Semaste if (m_flags.IsClear (eSymbolContextBlock)) 415254721Semaste { 416254721Semaste if (m_sc.block) 417254721Semaste resolved |= eSymbolContextBlock; 418254721Semaste else 419254721Semaste actual_resolve_scope |= eSymbolContextBlock; 420254721Semaste } 421254721Semaste } 422254721Semaste 423254721Semaste if (resolve_scope & eSymbolContextSymbol) 424254721Semaste { 425254721Semaste if (m_flags.IsClear (eSymbolContextSymbol)) 426254721Semaste { 427254721Semaste if (m_sc.symbol) 428254721Semaste resolved |= eSymbolContextSymbol; 429254721Semaste else 430254721Semaste actual_resolve_scope |= eSymbolContextSymbol; 431254721Semaste } 432254721Semaste } 433254721Semaste 434254721Semaste if (resolve_scope & eSymbolContextLineEntry) 435254721Semaste { 436254721Semaste if (m_flags.IsClear (eSymbolContextLineEntry)) 437254721Semaste { 438254721Semaste if (m_sc.line_entry.IsValid()) 439254721Semaste resolved |= eSymbolContextLineEntry; 440254721Semaste else 441254721Semaste actual_resolve_scope |= eSymbolContextLineEntry; 442254721Semaste } 443254721Semaste } 444254721Semaste 445254721Semaste if (actual_resolve_scope) 446254721Semaste { 447254721Semaste // We might be resolving less information than what is already 448254721Semaste // in our current symbol context so resolve into a temporary 449254721Semaste // symbol context "sc" so we don't clear out data we have 450254721Semaste // already found in "m_sc" 451254721Semaste SymbolContext sc; 452254721Semaste // Set flags that indicate what we have tried to resolve 453254721Semaste resolved |= m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, actual_resolve_scope, sc); 454254721Semaste // Only replace what we didn't already have as we may have 455254721Semaste // information for an inlined function scope that won't match 456254721Semaste // what a standard lookup by address would match 457254721Semaste if ((resolved & eSymbolContextCompUnit) && m_sc.comp_unit == NULL) 458254721Semaste m_sc.comp_unit = sc.comp_unit; 459254721Semaste if ((resolved & eSymbolContextFunction) && m_sc.function == NULL) 460254721Semaste m_sc.function = sc.function; 461254721Semaste if ((resolved & eSymbolContextBlock) && m_sc.block == NULL) 462254721Semaste m_sc.block = sc.block; 463254721Semaste if ((resolved & eSymbolContextSymbol) && m_sc.symbol == NULL) 464254721Semaste m_sc.symbol = sc.symbol; 465254721Semaste if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid()) 466254721Semaste { 467254721Semaste m_sc.line_entry = sc.line_entry; 468254721Semaste if (m_sc.target_sp) 469254721Semaste { 470254721Semaste // Be sure to apply and file remappings to our file and line 471254721Semaste // entries when handing out a line entry 472254721Semaste FileSpec new_file_spec; 473254721Semaste if (m_sc.target_sp->GetSourcePathMap().FindFile (m_sc.line_entry.file, new_file_spec)) 474254721Semaste m_sc.line_entry.file = new_file_spec; 475254721Semaste } 476254721Semaste } 477254721Semaste } 478254721Semaste } 479254721Semaste else 480254721Semaste { 481254721Semaste // If we don't have a module, then we can't have the compile unit, 482254721Semaste // function, block, line entry or symbol, so we can safely call 483254721Semaste // ResolveSymbolContextForAddress with our symbol context member m_sc. 484254721Semaste if (m_sc.target_sp) 485254721Semaste { 486254721Semaste resolved |= m_sc.target_sp->GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc); 487254721Semaste } 488254721Semaste } 489254721Semaste 490254721Semaste // Update our internal flags so we remember what we have tried to locate so 491254721Semaste // we don't have to keep trying when more calls to this function are made. 492254721Semaste // We might have dug up more information that was requested (for example 493254721Semaste // if we were asked to only get the block, we will have gotten the 494254721Semaste // compile unit, and function) so set any additional bits that we resolved 495254721Semaste m_flags.Set (resolve_scope | resolved); 496254721Semaste } 497254721Semaste 498254721Semaste // Return the symbol context with everything that was possible to resolve 499254721Semaste // resolved. 500254721Semaste return m_sc; 501254721Semaste} 502254721Semaste 503254721Semaste 504254721SemasteVariableList * 505254721SemasteStackFrame::GetVariableList (bool get_file_globals) 506254721Semaste{ 507254721Semaste if (m_flags.IsClear(RESOLVED_VARIABLES)) 508254721Semaste { 509254721Semaste m_flags.Set(RESOLVED_VARIABLES); 510254721Semaste 511254721Semaste Block *frame_block = GetFrameBlock(); 512254721Semaste 513254721Semaste if (frame_block) 514254721Semaste { 515254721Semaste const bool get_child_variables = true; 516254721Semaste const bool can_create = true; 517254721Semaste const bool stop_if_child_block_is_inlined_function = true; 518254721Semaste m_variable_list_sp.reset(new VariableList()); 519254721Semaste frame_block->AppendBlockVariables(can_create, get_child_variables, stop_if_child_block_is_inlined_function, m_variable_list_sp.get()); 520254721Semaste } 521254721Semaste } 522254721Semaste 523254721Semaste if (m_flags.IsClear(RESOLVED_GLOBAL_VARIABLES) && 524254721Semaste get_file_globals) 525254721Semaste { 526254721Semaste m_flags.Set(RESOLVED_GLOBAL_VARIABLES); 527254721Semaste 528254721Semaste if (m_flags.IsClear (eSymbolContextCompUnit)) 529254721Semaste GetSymbolContext (eSymbolContextCompUnit); 530254721Semaste 531254721Semaste if (m_sc.comp_unit) 532254721Semaste { 533254721Semaste VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true)); 534254721Semaste if (m_variable_list_sp) 535254721Semaste m_variable_list_sp->AddVariables (global_variable_list_sp.get()); 536254721Semaste else 537254721Semaste m_variable_list_sp = global_variable_list_sp; 538254721Semaste } 539254721Semaste } 540254721Semaste 541254721Semaste return m_variable_list_sp.get(); 542254721Semaste} 543254721Semaste 544254721SemasteVariableListSP 545254721SemasteStackFrame::GetInScopeVariableList (bool get_file_globals) 546254721Semaste{ 547263363Semaste // We can't fetch variable information for a history stack frame. 548263363Semaste if (m_is_history_frame) 549263363Semaste return VariableListSP(); 550263363Semaste 551254721Semaste VariableListSP var_list_sp(new VariableList); 552254721Semaste GetSymbolContext (eSymbolContextCompUnit | eSymbolContextBlock); 553254721Semaste 554254721Semaste if (m_sc.block) 555254721Semaste { 556254721Semaste const bool can_create = true; 557254721Semaste const bool get_parent_variables = true; 558254721Semaste const bool stop_if_block_is_inlined_function = true; 559254721Semaste m_sc.block->AppendVariables (can_create, 560254721Semaste get_parent_variables, 561254721Semaste stop_if_block_is_inlined_function, 562254721Semaste var_list_sp.get()); 563254721Semaste } 564254721Semaste 565254721Semaste if (m_sc.comp_unit) 566254721Semaste { 567254721Semaste VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true)); 568254721Semaste if (global_variable_list_sp) 569254721Semaste var_list_sp->AddVariables (global_variable_list_sp.get()); 570254721Semaste } 571254721Semaste 572254721Semaste return var_list_sp; 573254721Semaste} 574254721Semaste 575254721Semaste 576254721SemasteValueObjectSP 577254721SemasteStackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, 578254721Semaste DynamicValueType use_dynamic, 579254721Semaste uint32_t options, 580254721Semaste VariableSP &var_sp, 581254721Semaste Error &error) 582254721Semaste{ 583263363Semaste // We can't fetch variable information for a history stack frame. 584263363Semaste if (m_is_history_frame) 585263363Semaste return ValueObjectSP(); 586254721Semaste 587254721Semaste if (var_expr_cstr && var_expr_cstr[0]) 588254721Semaste { 589254721Semaste const bool check_ptr_vs_member = (options & eExpressionPathOptionCheckPtrVsMember) != 0; 590254721Semaste const bool no_fragile_ivar = (options & eExpressionPathOptionsNoFragileObjcIvar) != 0; 591254721Semaste const bool no_synth_child = (options & eExpressionPathOptionsNoSyntheticChildren) != 0; 592254721Semaste //const bool no_synth_array = (options & eExpressionPathOptionsNoSyntheticArrayRange) != 0; 593254721Semaste error.Clear(); 594254721Semaste bool deref = false; 595254721Semaste bool address_of = false; 596254721Semaste ValueObjectSP valobj_sp; 597254721Semaste const bool get_file_globals = true; 598254721Semaste // When looking up a variable for an expression, we need only consider the 599254721Semaste // variables that are in scope. 600254721Semaste VariableListSP var_list_sp (GetInScopeVariableList (get_file_globals)); 601254721Semaste VariableList *variable_list = var_list_sp.get(); 602254721Semaste 603254721Semaste if (variable_list) 604254721Semaste { 605254721Semaste // If first character is a '*', then show pointer contents 606254721Semaste const char *var_expr = var_expr_cstr; 607254721Semaste if (var_expr[0] == '*') 608254721Semaste { 609254721Semaste deref = true; 610254721Semaste var_expr++; // Skip the '*' 611254721Semaste } 612254721Semaste else if (var_expr[0] == '&') 613254721Semaste { 614254721Semaste address_of = true; 615254721Semaste var_expr++; // Skip the '&' 616254721Semaste } 617254721Semaste 618254721Semaste std::string var_path (var_expr); 619254721Semaste size_t separator_idx = var_path.find_first_of(".-[=+~|&^%#@!/?,<>{}"); 620254721Semaste StreamString var_expr_path_strm; 621254721Semaste 622254721Semaste ConstString name_const_string; 623254721Semaste if (separator_idx == std::string::npos) 624254721Semaste name_const_string.SetCString (var_path.c_str()); 625254721Semaste else 626254721Semaste name_const_string.SetCStringWithLength (var_path.c_str(), separator_idx); 627254721Semaste 628254721Semaste var_sp = variable_list->FindVariable(name_const_string); 629254721Semaste 630254721Semaste bool synthetically_added_instance_object = false; 631254721Semaste 632254721Semaste if (var_sp) 633254721Semaste { 634254721Semaste var_path.erase (0, name_const_string.GetLength ()); 635254721Semaste } 636254721Semaste else if (options & eExpressionPathOptionsAllowDirectIVarAccess) 637254721Semaste { 638254721Semaste // Check for direct ivars access which helps us with implicit 639254721Semaste // access to ivars with the "this->" or "self->" 640254721Semaste GetSymbolContext(eSymbolContextFunction|eSymbolContextBlock); 641254721Semaste lldb::LanguageType method_language = eLanguageTypeUnknown; 642254721Semaste bool is_instance_method = false; 643254721Semaste ConstString method_object_name; 644254721Semaste if (m_sc.GetFunctionMethodInfo (method_language, is_instance_method, method_object_name)) 645254721Semaste { 646254721Semaste if (is_instance_method && method_object_name) 647254721Semaste { 648254721Semaste var_sp = variable_list->FindVariable(method_object_name); 649254721Semaste if (var_sp) 650254721Semaste { 651254721Semaste separator_idx = 0; 652254721Semaste var_path.insert(0, "->"); 653254721Semaste synthetically_added_instance_object = true; 654254721Semaste } 655254721Semaste } 656254721Semaste } 657254721Semaste } 658254721Semaste 659254721Semaste if (var_sp) 660254721Semaste { 661254721Semaste valobj_sp = GetValueObjectForFrameVariable (var_sp, use_dynamic); 662254721Semaste if (!valobj_sp) 663254721Semaste return valobj_sp; 664254721Semaste 665254721Semaste // We are dumping at least one child 666254721Semaste while (separator_idx != std::string::npos) 667254721Semaste { 668254721Semaste // Calculate the next separator index ahead of time 669254721Semaste ValueObjectSP child_valobj_sp; 670254721Semaste const char separator_type = var_path[0]; 671254721Semaste switch (separator_type) 672254721Semaste { 673254721Semaste 674254721Semaste case '-': 675254721Semaste if (var_path.size() >= 2 && var_path[1] != '>') 676254721Semaste return ValueObjectSP(); 677254721Semaste 678254721Semaste if (no_fragile_ivar) 679254721Semaste { 680254721Semaste // Make sure we aren't trying to deref an objective 681254721Semaste // C ivar if this is not allowed 682254721Semaste const uint32_t pointer_type_flags = valobj_sp->GetClangType().GetTypeInfo (NULL); 683254721Semaste if ((pointer_type_flags & ClangASTType::eTypeIsObjC) && 684254721Semaste (pointer_type_flags & ClangASTType::eTypeIsPointer)) 685254721Semaste { 686254721Semaste // This was an objective C object pointer and 687254721Semaste // it was requested we skip any fragile ivars 688254721Semaste // so return nothing here 689254721Semaste return ValueObjectSP(); 690254721Semaste } 691254721Semaste } 692254721Semaste var_path.erase (0, 1); // Remove the '-' 693254721Semaste // Fall through 694254721Semaste case '.': 695254721Semaste { 696254721Semaste const bool expr_is_ptr = var_path[0] == '>'; 697254721Semaste 698254721Semaste var_path.erase (0, 1); // Remove the '.' or '>' 699254721Semaste separator_idx = var_path.find_first_of(".-["); 700254721Semaste ConstString child_name; 701254721Semaste if (separator_idx == std::string::npos) 702254721Semaste child_name.SetCString (var_path.c_str()); 703254721Semaste else 704254721Semaste child_name.SetCStringWithLength(var_path.c_str(), separator_idx); 705254721Semaste 706254721Semaste if (check_ptr_vs_member) 707254721Semaste { 708254721Semaste // We either have a pointer type and need to verify 709254721Semaste // valobj_sp is a pointer, or we have a member of a 710254721Semaste // class/union/struct being accessed with the . syntax 711254721Semaste // and need to verify we don't have a pointer. 712254721Semaste const bool actual_is_ptr = valobj_sp->IsPointerType (); 713254721Semaste 714254721Semaste if (actual_is_ptr != expr_is_ptr) 715254721Semaste { 716254721Semaste // Incorrect use of "." with a pointer, or "->" with 717254721Semaste // a class/union/struct instance or reference. 718254721Semaste valobj_sp->GetExpressionPath (var_expr_path_strm, false); 719254721Semaste if (actual_is_ptr) 720254721Semaste error.SetErrorStringWithFormat ("\"%s\" is a pointer and . was used to attempt to access \"%s\". Did you mean \"%s->%s\"?", 721254721Semaste var_expr_path_strm.GetString().c_str(), 722254721Semaste child_name.GetCString(), 723254721Semaste var_expr_path_strm.GetString().c_str(), 724254721Semaste var_path.c_str()); 725254721Semaste else 726254721Semaste error.SetErrorStringWithFormat ("\"%s\" is not a pointer and -> was used to attempt to access \"%s\". Did you mean \"%s.%s\"?", 727254721Semaste var_expr_path_strm.GetString().c_str(), 728254721Semaste child_name.GetCString(), 729254721Semaste var_expr_path_strm.GetString().c_str(), 730254721Semaste var_path.c_str()); 731254721Semaste return ValueObjectSP(); 732254721Semaste } 733254721Semaste } 734254721Semaste child_valobj_sp = valobj_sp->GetChildMemberWithName (child_name, true); 735254721Semaste if (!child_valobj_sp) 736254721Semaste { 737254721Semaste if (no_synth_child == false) 738254721Semaste { 739254721Semaste child_valobj_sp = valobj_sp->GetSyntheticValue(); 740254721Semaste if (child_valobj_sp) 741254721Semaste child_valobj_sp = child_valobj_sp->GetChildMemberWithName (child_name, true); 742254721Semaste } 743254721Semaste 744254721Semaste if (no_synth_child || !child_valobj_sp) 745254721Semaste { 746254721Semaste // No child member with name "child_name" 747254721Semaste if (synthetically_added_instance_object) 748254721Semaste { 749254721Semaste // We added a "this->" or "self->" to the beginning of the expression 750254721Semaste // and this is the first pointer ivar access, so just return the normal 751254721Semaste // error 752254721Semaste error.SetErrorStringWithFormat("no variable or instance variable named '%s' found in this frame", 753254721Semaste name_const_string.GetCString()); 754254721Semaste } 755254721Semaste else 756254721Semaste { 757254721Semaste valobj_sp->GetExpressionPath (var_expr_path_strm, false); 758254721Semaste if (child_name) 759254721Semaste { 760254721Semaste error.SetErrorStringWithFormat ("\"%s\" is not a member of \"(%s) %s\"", 761254721Semaste child_name.GetCString(), 762254721Semaste valobj_sp->GetTypeName().AsCString("<invalid type>"), 763254721Semaste var_expr_path_strm.GetString().c_str()); 764254721Semaste } 765254721Semaste else 766254721Semaste { 767254721Semaste error.SetErrorStringWithFormat ("incomplete expression path after \"%s\" in \"%s\"", 768254721Semaste var_expr_path_strm.GetString().c_str(), 769254721Semaste var_expr_cstr); 770254721Semaste } 771254721Semaste } 772254721Semaste return ValueObjectSP(); 773254721Semaste } 774254721Semaste } 775254721Semaste synthetically_added_instance_object = false; 776254721Semaste // Remove the child name from the path 777254721Semaste var_path.erase(0, child_name.GetLength()); 778254721Semaste if (use_dynamic != eNoDynamicValues) 779254721Semaste { 780254721Semaste ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic)); 781254721Semaste if (dynamic_value_sp) 782254721Semaste child_valobj_sp = dynamic_value_sp; 783254721Semaste } 784254721Semaste } 785254721Semaste break; 786254721Semaste 787254721Semaste case '[': 788254721Semaste // Array member access, or treating pointer as an array 789254721Semaste if (var_path.size() > 2) // Need at least two brackets and a number 790254721Semaste { 791254721Semaste char *end = NULL; 792254721Semaste long child_index = ::strtol (&var_path[1], &end, 0); 793254721Semaste if (end && *end == ']' 794254721Semaste && *(end-1) != '[') // this code forces an error in the case of arr[]. as bitfield[] is not a good syntax we're good to go 795254721Semaste { 796254721Semaste if (valobj_sp->GetClangType().IsPointerToScalarType() && deref) 797254721Semaste { 798254721Semaste // what we have is *ptr[low]. the most similar C++ syntax is to deref ptr 799254721Semaste // and extract bit low out of it. reading array item low 800254721Semaste // would be done by saying ptr[low], without a deref * sign 801254721Semaste Error error; 802254721Semaste ValueObjectSP temp(valobj_sp->Dereference(error)); 803254721Semaste if (error.Fail()) 804254721Semaste { 805254721Semaste valobj_sp->GetExpressionPath (var_expr_path_strm, false); 806254721Semaste error.SetErrorStringWithFormat ("could not dereference \"(%s) %s\"", 807254721Semaste valobj_sp->GetTypeName().AsCString("<invalid type>"), 808254721Semaste var_expr_path_strm.GetString().c_str()); 809254721Semaste return ValueObjectSP(); 810254721Semaste } 811254721Semaste valobj_sp = temp; 812254721Semaste deref = false; 813254721Semaste } 814254721Semaste else if (valobj_sp->GetClangType().IsArrayOfScalarType() && deref) 815254721Semaste { 816254721Semaste // what we have is *arr[low]. the most similar C++ syntax is to get arr[0] 817254721Semaste // (an operation that is equivalent to deref-ing arr) 818254721Semaste // and extract bit low out of it. reading array item low 819254721Semaste // would be done by saying arr[low], without a deref * sign 820254721Semaste Error error; 821254721Semaste ValueObjectSP temp(valobj_sp->GetChildAtIndex (0, true)); 822254721Semaste if (error.Fail()) 823254721Semaste { 824254721Semaste valobj_sp->GetExpressionPath (var_expr_path_strm, false); 825254721Semaste error.SetErrorStringWithFormat ("could not get item 0 for \"(%s) %s\"", 826254721Semaste valobj_sp->GetTypeName().AsCString("<invalid type>"), 827254721Semaste var_expr_path_strm.GetString().c_str()); 828254721Semaste return ValueObjectSP(); 829254721Semaste } 830254721Semaste valobj_sp = temp; 831254721Semaste deref = false; 832254721Semaste } 833254721Semaste 834254721Semaste bool is_incomplete_array = false; 835254721Semaste if (valobj_sp->IsPointerType ()) 836254721Semaste { 837254721Semaste bool is_objc_pointer = true; 838254721Semaste 839254721Semaste if (valobj_sp->GetClangType().GetMinimumLanguage() != eLanguageTypeObjC) 840254721Semaste is_objc_pointer = false; 841254721Semaste else if (!valobj_sp->GetClangType().IsPointerType()) 842254721Semaste is_objc_pointer = false; 843254721Semaste 844254721Semaste if (no_synth_child && is_objc_pointer) 845254721Semaste { 846254721Semaste error.SetErrorStringWithFormat("\"(%s) %s\" is an Objective-C pointer, and cannot be subscripted", 847254721Semaste valobj_sp->GetTypeName().AsCString("<invalid type>"), 848254721Semaste var_expr_path_strm.GetString().c_str()); 849254721Semaste 850254721Semaste return ValueObjectSP(); 851254721Semaste } 852254721Semaste else if (is_objc_pointer) 853254721Semaste { 854254721Semaste // dereferencing ObjC variables is not valid.. so let's try and recur to synthetic children 855254721Semaste ValueObjectSP synthetic = valobj_sp->GetSyntheticValue(); 856254721Semaste if (synthetic.get() == NULL /* no synthetic */ 857254721Semaste || synthetic == valobj_sp) /* synthetic is the same as the original object */ 858254721Semaste { 859254721Semaste valobj_sp->GetExpressionPath (var_expr_path_strm, false); 860254721Semaste error.SetErrorStringWithFormat ("\"(%s) %s\" is not an array type", 861254721Semaste valobj_sp->GetTypeName().AsCString("<invalid type>"), 862254721Semaste var_expr_path_strm.GetString().c_str()); 863254721Semaste } 864254721Semaste else if (child_index >= synthetic->GetNumChildren() /* synthetic does not have that many values */) 865254721Semaste { 866254721Semaste valobj_sp->GetExpressionPath (var_expr_path_strm, false); 867254721Semaste error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 868254721Semaste child_index, 869254721Semaste valobj_sp->GetTypeName().AsCString("<invalid type>"), 870254721Semaste var_expr_path_strm.GetString().c_str()); 871254721Semaste } 872254721Semaste else 873254721Semaste { 874254721Semaste child_valobj_sp = synthetic->GetChildAtIndex(child_index, true); 875254721Semaste if (!child_valobj_sp) 876254721Semaste { 877254721Semaste valobj_sp->GetExpressionPath (var_expr_path_strm, false); 878254721Semaste error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 879254721Semaste child_index, 880254721Semaste valobj_sp->GetTypeName().AsCString("<invalid type>"), 881254721Semaste var_expr_path_strm.GetString().c_str()); 882254721Semaste } 883254721Semaste } 884254721Semaste } 885254721Semaste else 886254721Semaste { 887254721Semaste child_valobj_sp = valobj_sp->GetSyntheticArrayMemberFromPointer (child_index, true); 888254721Semaste if (!child_valobj_sp) 889254721Semaste { 890254721Semaste valobj_sp->GetExpressionPath (var_expr_path_strm, false); 891254721Semaste error.SetErrorStringWithFormat ("failed to use pointer as array for index %ld for \"(%s) %s\"", 892254721Semaste child_index, 893254721Semaste valobj_sp->GetTypeName().AsCString("<invalid type>"), 894254721Semaste var_expr_path_strm.GetString().c_str()); 895254721Semaste } 896254721Semaste } 897254721Semaste } 898254721Semaste else if (valobj_sp->GetClangType().IsArrayType (NULL, NULL, &is_incomplete_array)) 899254721Semaste { 900254721Semaste // Pass false to dynamic_value here so we can tell the difference between 901254721Semaste // no dynamic value and no member of this type... 902254721Semaste child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true); 903254721Semaste if (!child_valobj_sp && (is_incomplete_array || no_synth_child == false)) 904254721Semaste child_valobj_sp = valobj_sp->GetSyntheticArrayMember (child_index, true); 905254721Semaste 906254721Semaste if (!child_valobj_sp) 907254721Semaste { 908254721Semaste valobj_sp->GetExpressionPath (var_expr_path_strm, false); 909254721Semaste error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 910254721Semaste child_index, 911254721Semaste valobj_sp->GetTypeName().AsCString("<invalid type>"), 912254721Semaste var_expr_path_strm.GetString().c_str()); 913254721Semaste } 914254721Semaste } 915254721Semaste else if (valobj_sp->GetClangType().IsScalarType()) 916254721Semaste { 917254721Semaste // this is a bitfield asking to display just one bit 918254721Semaste child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(child_index, child_index, true); 919254721Semaste if (!child_valobj_sp) 920254721Semaste { 921254721Semaste valobj_sp->GetExpressionPath (var_expr_path_strm, false); 922254721Semaste error.SetErrorStringWithFormat ("bitfield range %ld-%ld is not valid for \"(%s) %s\"", 923254721Semaste child_index, child_index, 924254721Semaste valobj_sp->GetTypeName().AsCString("<invalid type>"), 925254721Semaste var_expr_path_strm.GetString().c_str()); 926254721Semaste } 927254721Semaste } 928254721Semaste else 929254721Semaste { 930254721Semaste ValueObjectSP synthetic = valobj_sp->GetSyntheticValue(); 931254721Semaste if (no_synth_child /* synthetic is forbidden */ || 932254721Semaste synthetic.get() == NULL /* no synthetic */ 933254721Semaste || synthetic == valobj_sp) /* synthetic is the same as the original object */ 934254721Semaste { 935254721Semaste valobj_sp->GetExpressionPath (var_expr_path_strm, false); 936254721Semaste error.SetErrorStringWithFormat ("\"(%s) %s\" is not an array type", 937254721Semaste valobj_sp->GetTypeName().AsCString("<invalid type>"), 938254721Semaste var_expr_path_strm.GetString().c_str()); 939254721Semaste } 940254721Semaste else if (child_index >= synthetic->GetNumChildren() /* synthetic does not have that many values */) 941254721Semaste { 942254721Semaste valobj_sp->GetExpressionPath (var_expr_path_strm, false); 943254721Semaste error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 944254721Semaste child_index, 945254721Semaste valobj_sp->GetTypeName().AsCString("<invalid type>"), 946254721Semaste var_expr_path_strm.GetString().c_str()); 947254721Semaste } 948254721Semaste else 949254721Semaste { 950254721Semaste child_valobj_sp = synthetic->GetChildAtIndex(child_index, true); 951254721Semaste if (!child_valobj_sp) 952254721Semaste { 953254721Semaste valobj_sp->GetExpressionPath (var_expr_path_strm, false); 954254721Semaste error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 955254721Semaste child_index, 956254721Semaste valobj_sp->GetTypeName().AsCString("<invalid type>"), 957254721Semaste var_expr_path_strm.GetString().c_str()); 958254721Semaste } 959254721Semaste } 960254721Semaste } 961254721Semaste 962254721Semaste if (!child_valobj_sp) 963254721Semaste { 964254721Semaste // Invalid array index... 965254721Semaste return ValueObjectSP(); 966254721Semaste } 967254721Semaste 968254721Semaste // Erase the array member specification '[%i]' where 969254721Semaste // %i is the array index 970254721Semaste var_path.erase(0, (end - var_path.c_str()) + 1); 971254721Semaste separator_idx = var_path.find_first_of(".-["); 972254721Semaste if (use_dynamic != eNoDynamicValues) 973254721Semaste { 974254721Semaste ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic)); 975254721Semaste if (dynamic_value_sp) 976254721Semaste child_valobj_sp = dynamic_value_sp; 977254721Semaste } 978254721Semaste // Break out early from the switch since we were 979254721Semaste // able to find the child member 980254721Semaste break; 981254721Semaste } 982254721Semaste else if (end && *end == '-') 983254721Semaste { 984254721Semaste // this is most probably a BitField, let's take a look 985254721Semaste char *real_end = NULL; 986254721Semaste long final_index = ::strtol (end+1, &real_end, 0); 987254721Semaste bool expand_bitfield = true; 988254721Semaste if (real_end && *real_end == ']') 989254721Semaste { 990254721Semaste // if the format given is [high-low], swap range 991254721Semaste if (child_index > final_index) 992254721Semaste { 993254721Semaste long temp = child_index; 994254721Semaste child_index = final_index; 995254721Semaste final_index = temp; 996254721Semaste } 997254721Semaste 998254721Semaste if (valobj_sp->GetClangType().IsPointerToScalarType() && deref) 999254721Semaste { 1000254721Semaste // what we have is *ptr[low-high]. the most similar C++ syntax is to deref ptr 1001254721Semaste // and extract bits low thru high out of it. reading array items low thru high 1002254721Semaste // would be done by saying ptr[low-high], without a deref * sign 1003254721Semaste Error error; 1004254721Semaste ValueObjectSP temp(valobj_sp->Dereference(error)); 1005254721Semaste if (error.Fail()) 1006254721Semaste { 1007254721Semaste valobj_sp->GetExpressionPath (var_expr_path_strm, false); 1008254721Semaste error.SetErrorStringWithFormat ("could not dereference \"(%s) %s\"", 1009254721Semaste valobj_sp->GetTypeName().AsCString("<invalid type>"), 1010254721Semaste var_expr_path_strm.GetString().c_str()); 1011254721Semaste return ValueObjectSP(); 1012254721Semaste } 1013254721Semaste valobj_sp = temp; 1014254721Semaste deref = false; 1015254721Semaste } 1016254721Semaste else if (valobj_sp->GetClangType().IsArrayOfScalarType() && deref) 1017254721Semaste { 1018254721Semaste // what we have is *arr[low-high]. the most similar C++ syntax is to get arr[0] 1019254721Semaste // (an operation that is equivalent to deref-ing arr) 1020254721Semaste // and extract bits low thru high out of it. reading array items low thru high 1021254721Semaste // would be done by saying arr[low-high], without a deref * sign 1022254721Semaste Error error; 1023254721Semaste ValueObjectSP temp(valobj_sp->GetChildAtIndex (0, true)); 1024254721Semaste if (error.Fail()) 1025254721Semaste { 1026254721Semaste valobj_sp->GetExpressionPath (var_expr_path_strm, false); 1027254721Semaste error.SetErrorStringWithFormat ("could not get item 0 for \"(%s) %s\"", 1028254721Semaste valobj_sp->GetTypeName().AsCString("<invalid type>"), 1029254721Semaste var_expr_path_strm.GetString().c_str()); 1030254721Semaste return ValueObjectSP(); 1031254721Semaste } 1032254721Semaste valobj_sp = temp; 1033254721Semaste deref = false; 1034254721Semaste } 1035254721Semaste /*else if (valobj_sp->IsArrayType() || valobj_sp->IsPointerType()) 1036254721Semaste { 1037254721Semaste child_valobj_sp = valobj_sp->GetSyntheticArrayRangeChild(child_index, final_index, true); 1038254721Semaste expand_bitfield = false; 1039254721Semaste if (!child_valobj_sp) 1040254721Semaste { 1041254721Semaste valobj_sp->GetExpressionPath (var_expr_path_strm, false); 1042254721Semaste error.SetErrorStringWithFormat ("array range %i-%i is not valid for \"(%s) %s\"", 1043254721Semaste child_index, final_index, 1044254721Semaste valobj_sp->GetTypeName().AsCString("<invalid type>"), 1045254721Semaste var_expr_path_strm.GetString().c_str()); 1046254721Semaste } 1047254721Semaste }*/ 1048254721Semaste 1049254721Semaste if (expand_bitfield) 1050254721Semaste { 1051254721Semaste child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(child_index, final_index, true); 1052254721Semaste if (!child_valobj_sp) 1053254721Semaste { 1054254721Semaste valobj_sp->GetExpressionPath (var_expr_path_strm, false); 1055254721Semaste error.SetErrorStringWithFormat ("bitfield range %ld-%ld is not valid for \"(%s) %s\"", 1056254721Semaste child_index, final_index, 1057254721Semaste valobj_sp->GetTypeName().AsCString("<invalid type>"), 1058254721Semaste var_expr_path_strm.GetString().c_str()); 1059254721Semaste } 1060254721Semaste } 1061254721Semaste } 1062254721Semaste 1063254721Semaste if (!child_valobj_sp) 1064254721Semaste { 1065254721Semaste // Invalid bitfield range... 1066254721Semaste return ValueObjectSP(); 1067254721Semaste } 1068254721Semaste 1069254721Semaste // Erase the bitfield member specification '[%i-%i]' where 1070254721Semaste // %i is the index 1071254721Semaste var_path.erase(0, (real_end - var_path.c_str()) + 1); 1072254721Semaste separator_idx = var_path.find_first_of(".-["); 1073254721Semaste if (use_dynamic != eNoDynamicValues) 1074254721Semaste { 1075254721Semaste ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic)); 1076254721Semaste if (dynamic_value_sp) 1077254721Semaste child_valobj_sp = dynamic_value_sp; 1078254721Semaste } 1079254721Semaste // Break out early from the switch since we were 1080254721Semaste // able to find the child member 1081254721Semaste break; 1082254721Semaste 1083254721Semaste } 1084254721Semaste } 1085254721Semaste else 1086254721Semaste { 1087254721Semaste error.SetErrorStringWithFormat("invalid square bracket encountered after \"%s\" in \"%s\"", 1088254721Semaste var_expr_path_strm.GetString().c_str(), 1089254721Semaste var_path.c_str()); 1090254721Semaste } 1091254721Semaste return ValueObjectSP(); 1092254721Semaste 1093254721Semaste default: 1094254721Semaste // Failure... 1095254721Semaste { 1096254721Semaste valobj_sp->GetExpressionPath (var_expr_path_strm, false); 1097254721Semaste error.SetErrorStringWithFormat ("unexpected char '%c' encountered after \"%s\" in \"%s\"", 1098254721Semaste separator_type, 1099254721Semaste var_expr_path_strm.GetString().c_str(), 1100254721Semaste var_path.c_str()); 1101254721Semaste 1102254721Semaste return ValueObjectSP(); 1103254721Semaste } 1104254721Semaste } 1105254721Semaste 1106254721Semaste if (child_valobj_sp) 1107254721Semaste valobj_sp = child_valobj_sp; 1108254721Semaste 1109254721Semaste if (var_path.empty()) 1110254721Semaste break; 1111254721Semaste 1112254721Semaste } 1113254721Semaste if (valobj_sp) 1114254721Semaste { 1115254721Semaste if (deref) 1116254721Semaste { 1117254721Semaste ValueObjectSP deref_valobj_sp (valobj_sp->Dereference(error)); 1118254721Semaste valobj_sp = deref_valobj_sp; 1119254721Semaste } 1120254721Semaste else if (address_of) 1121254721Semaste { 1122254721Semaste ValueObjectSP address_of_valobj_sp (valobj_sp->AddressOf(error)); 1123254721Semaste valobj_sp = address_of_valobj_sp; 1124254721Semaste } 1125254721Semaste } 1126254721Semaste return valobj_sp; 1127254721Semaste } 1128254721Semaste else 1129254721Semaste { 1130254721Semaste error.SetErrorStringWithFormat("no variable named '%s' found in this frame", 1131254721Semaste name_const_string.GetCString()); 1132254721Semaste } 1133254721Semaste } 1134254721Semaste } 1135254721Semaste else 1136254721Semaste { 1137254721Semaste error.SetErrorStringWithFormat("invalid variable path '%s'", var_expr_cstr); 1138254721Semaste } 1139254721Semaste return ValueObjectSP(); 1140254721Semaste} 1141254721Semaste 1142254721Semastebool 1143254721SemasteStackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr) 1144254721Semaste{ 1145263363Semaste if (m_cfa_is_valid == false) 1146263363Semaste { 1147263363Semaste m_frame_base_error.SetErrorString("No frame base available for this historical stack frame."); 1148263363Semaste return false; 1149263363Semaste } 1150263363Semaste 1151254721Semaste if (m_flags.IsClear(GOT_FRAME_BASE)) 1152254721Semaste { 1153254721Semaste if (m_sc.function) 1154254721Semaste { 1155254721Semaste m_frame_base.Clear(); 1156254721Semaste m_frame_base_error.Clear(); 1157254721Semaste 1158254721Semaste m_flags.Set(GOT_FRAME_BASE); 1159254721Semaste ExecutionContext exe_ctx (shared_from_this()); 1160254721Semaste Value expr_value; 1161254721Semaste addr_t loclist_base_addr = LLDB_INVALID_ADDRESS; 1162254721Semaste if (m_sc.function->GetFrameBaseExpression().IsLocationList()) 1163254721Semaste loclist_base_addr = m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.GetTargetPtr()); 1164254721Semaste 1165254721Semaste if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, NULL, loclist_base_addr, NULL, expr_value, &m_frame_base_error) == false) 1166254721Semaste { 1167254721Semaste // We should really have an error if evaluate returns, but in case 1168254721Semaste // we don't, lets set the error to something at least. 1169254721Semaste if (m_frame_base_error.Success()) 1170254721Semaste m_frame_base_error.SetErrorString("Evaluation of the frame base expression failed."); 1171254721Semaste } 1172254721Semaste else 1173254721Semaste { 1174254721Semaste m_frame_base = expr_value.ResolveValue(&exe_ctx); 1175254721Semaste } 1176254721Semaste } 1177254721Semaste else 1178254721Semaste { 1179254721Semaste m_frame_base_error.SetErrorString ("No function in symbol context."); 1180254721Semaste } 1181254721Semaste } 1182254721Semaste 1183254721Semaste if (m_frame_base_error.Success()) 1184254721Semaste frame_base = m_frame_base; 1185254721Semaste 1186254721Semaste if (error_ptr) 1187254721Semaste *error_ptr = m_frame_base_error; 1188254721Semaste return m_frame_base_error.Success(); 1189254721Semaste} 1190254721Semaste 1191254721SemasteRegisterContextSP 1192254721SemasteStackFrame::GetRegisterContext () 1193254721Semaste{ 1194254721Semaste if (!m_reg_context_sp) 1195254721Semaste { 1196254721Semaste ThreadSP thread_sp (GetThread()); 1197254721Semaste if (thread_sp) 1198254721Semaste m_reg_context_sp = thread_sp->CreateRegisterContextForFrame (this); 1199254721Semaste } 1200254721Semaste return m_reg_context_sp; 1201254721Semaste} 1202254721Semaste 1203254721Semastebool 1204254721SemasteStackFrame::HasDebugInformation () 1205254721Semaste{ 1206254721Semaste GetSymbolContext (eSymbolContextLineEntry); 1207254721Semaste return m_sc.line_entry.IsValid(); 1208254721Semaste} 1209254721Semaste 1210254721Semaste 1211254721SemasteValueObjectSP 1212254721SemasteStackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic) 1213254721Semaste{ 1214254721Semaste ValueObjectSP valobj_sp; 1215263363Semaste if (m_is_history_frame) 1216263363Semaste { 1217263363Semaste return valobj_sp; 1218263363Semaste } 1219254721Semaste VariableList *var_list = GetVariableList (true); 1220254721Semaste if (var_list) 1221254721Semaste { 1222254721Semaste // Make sure the variable is a frame variable 1223254721Semaste const uint32_t var_idx = var_list->FindIndexForVariable (variable_sp.get()); 1224254721Semaste const uint32_t num_variables = var_list->GetSize(); 1225254721Semaste if (var_idx < num_variables) 1226254721Semaste { 1227254721Semaste valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex (var_idx); 1228254721Semaste if (valobj_sp.get() == NULL) 1229254721Semaste { 1230254721Semaste if (m_variable_list_value_objects.GetSize() < num_variables) 1231254721Semaste m_variable_list_value_objects.Resize(num_variables); 1232254721Semaste valobj_sp = ValueObjectVariable::Create (this, variable_sp); 1233254721Semaste m_variable_list_value_objects.SetValueObjectAtIndex (var_idx, valobj_sp); 1234254721Semaste } 1235254721Semaste } 1236254721Semaste } 1237254721Semaste if (use_dynamic != eNoDynamicValues && valobj_sp) 1238254721Semaste { 1239254721Semaste ValueObjectSP dynamic_sp = valobj_sp->GetDynamicValue (use_dynamic); 1240254721Semaste if (dynamic_sp) 1241254721Semaste return dynamic_sp; 1242254721Semaste } 1243254721Semaste return valobj_sp; 1244254721Semaste} 1245254721Semaste 1246254721SemasteValueObjectSP 1247254721SemasteStackFrame::TrackGlobalVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic) 1248254721Semaste{ 1249263363Semaste if (m_is_history_frame) 1250263363Semaste return ValueObjectSP(); 1251263363Semaste 1252254721Semaste // Check to make sure we aren't already tracking this variable? 1253254721Semaste ValueObjectSP valobj_sp (GetValueObjectForFrameVariable (variable_sp, use_dynamic)); 1254254721Semaste if (!valobj_sp) 1255254721Semaste { 1256254721Semaste // We aren't already tracking this global 1257254721Semaste VariableList *var_list = GetVariableList (true); 1258254721Semaste // If this frame has no variables, create a new list 1259254721Semaste if (var_list == NULL) 1260254721Semaste m_variable_list_sp.reset (new VariableList()); 1261254721Semaste 1262254721Semaste // Add the global/static variable to this frame 1263254721Semaste m_variable_list_sp->AddVariable (variable_sp); 1264254721Semaste 1265254721Semaste // Now make a value object for it so we can track its changes 1266254721Semaste valobj_sp = GetValueObjectForFrameVariable (variable_sp, use_dynamic); 1267254721Semaste } 1268254721Semaste return valobj_sp; 1269254721Semaste} 1270254721Semaste 1271254721Semastebool 1272254721SemasteStackFrame::IsInlined () 1273254721Semaste{ 1274254721Semaste if (m_sc.block == NULL) 1275254721Semaste GetSymbolContext (eSymbolContextBlock); 1276254721Semaste if (m_sc.block) 1277254721Semaste return m_sc.block->GetContainingInlinedBlock() != NULL; 1278254721Semaste return false; 1279254721Semaste} 1280254721Semaste 1281254721SemasteTargetSP 1282254721SemasteStackFrame::CalculateTarget () 1283254721Semaste{ 1284254721Semaste TargetSP target_sp; 1285254721Semaste ThreadSP thread_sp(GetThread()); 1286254721Semaste if (thread_sp) 1287254721Semaste { 1288254721Semaste ProcessSP process_sp (thread_sp->CalculateProcess()); 1289254721Semaste if (process_sp) 1290254721Semaste target_sp = process_sp->CalculateTarget(); 1291254721Semaste } 1292254721Semaste return target_sp; 1293254721Semaste} 1294254721Semaste 1295254721SemasteProcessSP 1296254721SemasteStackFrame::CalculateProcess () 1297254721Semaste{ 1298254721Semaste ProcessSP process_sp; 1299254721Semaste ThreadSP thread_sp(GetThread()); 1300254721Semaste if (thread_sp) 1301254721Semaste process_sp = thread_sp->CalculateProcess(); 1302254721Semaste return process_sp; 1303254721Semaste} 1304254721Semaste 1305254721SemasteThreadSP 1306254721SemasteStackFrame::CalculateThread () 1307254721Semaste{ 1308254721Semaste return GetThread(); 1309254721Semaste} 1310254721Semaste 1311254721SemasteStackFrameSP 1312254721SemasteStackFrame::CalculateStackFrame () 1313254721Semaste{ 1314254721Semaste return shared_from_this(); 1315254721Semaste} 1316254721Semaste 1317254721Semaste 1318254721Semastevoid 1319254721SemasteStackFrame::CalculateExecutionContext (ExecutionContext &exe_ctx) 1320254721Semaste{ 1321254721Semaste exe_ctx.SetContext (shared_from_this()); 1322254721Semaste} 1323254721Semaste 1324254721Semastevoid 1325263363SemasteStackFrame::DumpUsingSettingsFormat (Stream *strm, const char *frame_marker) 1326254721Semaste{ 1327254721Semaste if (strm == NULL) 1328254721Semaste return; 1329254721Semaste 1330254721Semaste GetSymbolContext(eSymbolContextEverything); 1331254721Semaste ExecutionContext exe_ctx (shared_from_this()); 1332254721Semaste StreamString s; 1333263363Semaste 1334263363Semaste if (frame_marker) 1335263363Semaste s.PutCString(frame_marker); 1336263363Semaste 1337254721Semaste const char *frame_format = NULL; 1338254721Semaste Target *target = exe_ctx.GetTargetPtr(); 1339254721Semaste if (target) 1340254721Semaste frame_format = target->GetDebugger().GetFrameFormat(); 1341254721Semaste if (frame_format && Debugger::FormatPrompt (frame_format, &m_sc, &exe_ctx, NULL, s)) 1342254721Semaste { 1343254721Semaste strm->Write(s.GetData(), s.GetSize()); 1344254721Semaste } 1345254721Semaste else 1346254721Semaste { 1347254721Semaste Dump (strm, true, false); 1348254721Semaste strm->EOL(); 1349254721Semaste } 1350254721Semaste} 1351254721Semaste 1352254721Semastevoid 1353254721SemasteStackFrame::Dump (Stream *strm, bool show_frame_index, bool show_fullpaths) 1354254721Semaste{ 1355254721Semaste if (strm == NULL) 1356254721Semaste return; 1357254721Semaste 1358254721Semaste if (show_frame_index) 1359254721Semaste strm->Printf("frame #%u: ", m_frame_index); 1360254721Semaste ExecutionContext exe_ctx (shared_from_this()); 1361254721Semaste Target *target = exe_ctx.GetTargetPtr(); 1362254721Semaste strm->Printf("0x%0*" PRIx64 " ", 1363254721Semaste target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16, 1364254721Semaste GetFrameCodeAddress().GetLoadAddress(target)); 1365254721Semaste GetSymbolContext(eSymbolContextEverything); 1366254721Semaste const bool show_module = true; 1367254721Semaste const bool show_inline = true; 1368254721Semaste m_sc.DumpStopContext (strm, 1369254721Semaste exe_ctx.GetBestExecutionContextScope(), 1370254721Semaste GetFrameCodeAddress(), 1371254721Semaste show_fullpaths, 1372254721Semaste show_module, 1373254721Semaste show_inline); 1374254721Semaste} 1375254721Semaste 1376254721Semastevoid 1377254721SemasteStackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame) 1378254721Semaste{ 1379254721Semaste assert (GetStackID() == prev_frame.GetStackID()); // TODO: remove this after some testing 1380254721Semaste m_variable_list_sp = prev_frame.m_variable_list_sp; 1381254721Semaste m_variable_list_value_objects.Swap (prev_frame.m_variable_list_value_objects); 1382254721Semaste if (!m_disassembly.GetString().empty()) 1383254721Semaste m_disassembly.GetString().swap (m_disassembly.GetString()); 1384254721Semaste} 1385254721Semaste 1386254721Semaste 1387254721Semastevoid 1388254721SemasteStackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame) 1389254721Semaste{ 1390254721Semaste assert (GetStackID() == curr_frame.GetStackID()); // TODO: remove this after some testing 1391254721Semaste m_id.SetPC (curr_frame.m_id.GetPC()); // Update the Stack ID PC value 1392254721Semaste assert (GetThread() == curr_frame.GetThread()); 1393254721Semaste m_frame_index = curr_frame.m_frame_index; 1394254721Semaste m_concrete_frame_index = curr_frame.m_concrete_frame_index; 1395254721Semaste m_reg_context_sp = curr_frame.m_reg_context_sp; 1396254721Semaste m_frame_code_addr = curr_frame.m_frame_code_addr; 1397254721Semaste assert (m_sc.target_sp.get() == NULL || curr_frame.m_sc.target_sp.get() == NULL || m_sc.target_sp.get() == curr_frame.m_sc.target_sp.get()); 1398254721Semaste assert (m_sc.module_sp.get() == NULL || curr_frame.m_sc.module_sp.get() == NULL || m_sc.module_sp.get() == curr_frame.m_sc.module_sp.get()); 1399254721Semaste assert (m_sc.comp_unit == NULL || curr_frame.m_sc.comp_unit == NULL || m_sc.comp_unit == curr_frame.m_sc.comp_unit); 1400254721Semaste assert (m_sc.function == NULL || curr_frame.m_sc.function == NULL || m_sc.function == curr_frame.m_sc.function); 1401254721Semaste m_sc = curr_frame.m_sc; 1402254721Semaste m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything); 1403254721Semaste m_flags.Set (m_sc.GetResolvedMask()); 1404254721Semaste m_frame_base.Clear(); 1405254721Semaste m_frame_base_error.Clear(); 1406254721Semaste} 1407254721Semaste 1408254721Semaste 1409254721Semastebool 1410254721SemasteStackFrame::HasCachedData () const 1411254721Semaste{ 1412254721Semaste if (m_variable_list_sp.get()) 1413254721Semaste return true; 1414254721Semaste if (m_variable_list_value_objects.GetSize() > 0) 1415254721Semaste return true; 1416254721Semaste if (!m_disassembly.GetString().empty()) 1417254721Semaste return true; 1418254721Semaste return false; 1419254721Semaste} 1420254721Semaste 1421254721Semastebool 1422254721SemasteStackFrame::GetStatus (Stream& strm, 1423254721Semaste bool show_frame_info, 1424263363Semaste bool show_source, 1425263363Semaste const char *frame_marker) 1426254721Semaste{ 1427254721Semaste 1428254721Semaste if (show_frame_info) 1429254721Semaste { 1430254721Semaste strm.Indent(); 1431263363Semaste DumpUsingSettingsFormat (&strm, frame_marker); 1432254721Semaste } 1433254721Semaste 1434254721Semaste if (show_source) 1435254721Semaste { 1436254721Semaste ExecutionContext exe_ctx (shared_from_this()); 1437254721Semaste bool have_source = false; 1438254721Semaste Debugger::StopDisassemblyType disasm_display = Debugger::eStopDisassemblyTypeNever; 1439254721Semaste Target *target = exe_ctx.GetTargetPtr(); 1440254721Semaste if (target) 1441254721Semaste { 1442254721Semaste Debugger &debugger = target->GetDebugger(); 1443254721Semaste const uint32_t source_lines_before = debugger.GetStopSourceLineCount(true); 1444254721Semaste const uint32_t source_lines_after = debugger.GetStopSourceLineCount(false); 1445254721Semaste disasm_display = debugger.GetStopDisassemblyDisplay (); 1446254721Semaste 1447254721Semaste if (source_lines_before > 0 || source_lines_after > 0) 1448254721Semaste { 1449254721Semaste GetSymbolContext(eSymbolContextCompUnit | eSymbolContextLineEntry); 1450254721Semaste 1451254721Semaste if (m_sc.comp_unit && m_sc.line_entry.IsValid()) 1452254721Semaste { 1453254721Semaste have_source = true; 1454254721Semaste target->GetSourceManager().DisplaySourceLinesWithLineNumbers (m_sc.line_entry.file, 1455254721Semaste m_sc.line_entry.line, 1456254721Semaste source_lines_before, 1457254721Semaste source_lines_after, 1458254721Semaste "->", 1459254721Semaste &strm); 1460254721Semaste } 1461254721Semaste } 1462254721Semaste switch (disasm_display) 1463254721Semaste { 1464254721Semaste case Debugger::eStopDisassemblyTypeNever: 1465254721Semaste break; 1466254721Semaste 1467254721Semaste case Debugger::eStopDisassemblyTypeNoSource: 1468254721Semaste if (have_source) 1469254721Semaste break; 1470254721Semaste // Fall through to next case 1471254721Semaste case Debugger::eStopDisassemblyTypeAlways: 1472254721Semaste if (target) 1473254721Semaste { 1474254721Semaste const uint32_t disasm_lines = debugger.GetDisassemblyLineCount(); 1475254721Semaste if (disasm_lines > 0) 1476254721Semaste { 1477254721Semaste const ArchSpec &target_arch = target->GetArchitecture(); 1478254721Semaste AddressRange pc_range; 1479254721Semaste pc_range.GetBaseAddress() = GetFrameCodeAddress(); 1480254721Semaste pc_range.SetByteSize(disasm_lines * target_arch.GetMaximumOpcodeByteSize()); 1481254721Semaste const char *plugin_name = NULL; 1482254721Semaste const char *flavor = NULL; 1483254721Semaste Disassembler::Disassemble (target->GetDebugger(), 1484254721Semaste target_arch, 1485254721Semaste plugin_name, 1486254721Semaste flavor, 1487254721Semaste exe_ctx, 1488254721Semaste pc_range, 1489254721Semaste disasm_lines, 1490254721Semaste 0, 1491254721Semaste Disassembler::eOptionMarkPCAddress, 1492254721Semaste strm); 1493254721Semaste } 1494254721Semaste } 1495254721Semaste break; 1496254721Semaste } 1497254721Semaste } 1498254721Semaste } 1499254721Semaste return true; 1500254721Semaste} 1501254721Semaste 1502