130fdc8d8SChris Lattner //===-- StackFrame.cpp ------------------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 330fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 430fdc8d8SChris Lattner // 530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 630fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 730fdc8d8SChris Lattner // 830fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 930fdc8d8SChris Lattner 1030fdc8d8SChris Lattner // C Includes 1130fdc8d8SChris Lattner // C++ Includes 1230fdc8d8SChris Lattner // Other libraries and framework includes 1330fdc8d8SChris Lattner // Project includes 14d70a6e71SEugene Zelenko #include "lldb/Target/StackFrame.h" 150603aa9dSGreg Clayton #include "lldb/Core/Debugger.h" 1630fdc8d8SChris Lattner #include "lldb/Core/Disassembler.h" 17554f68d3SGreg Clayton #include "lldb/Core/FormatEntity.h" 18592afe73SEnrico Granata #include "lldb/Core/Mangled.h" 19592afe73SEnrico Granata #include "lldb/Core/Module.h" 2030fdc8d8SChris Lattner #include "lldb/Core/Value.h" 21288bdf9cSGreg Clayton #include "lldb/Core/ValueObjectVariable.h" 2254979cddSGreg Clayton #include "lldb/Core/ValueObjectConstResult.h" 231f746071SGreg Clayton #include "lldb/Symbol/CompileUnit.h" 2430fdc8d8SChris Lattner #include "lldb/Symbol/Function.h" 251f746071SGreg Clayton #include "lldb/Symbol/Symbol.h" 261f746071SGreg Clayton #include "lldb/Symbol/SymbolContextScope.h" 2746252398SEnrico Granata #include "lldb/Symbol/Type.h" 28288bdf9cSGreg Clayton #include "lldb/Symbol/VariableList.h" 2930fdc8d8SChris Lattner #include "lldb/Target/ExecutionContext.h" 3030fdc8d8SChris Lattner #include "lldb/Target/Process.h" 3130fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h" 3230fdc8d8SChris Lattner #include "lldb/Target/Target.h" 3330fdc8d8SChris Lattner #include "lldb/Target/Thread.h" 3430fdc8d8SChris Lattner 3530fdc8d8SChris Lattner using namespace lldb; 3630fdc8d8SChris Lattner using namespace lldb_private; 3730fdc8d8SChris Lattner 3830fdc8d8SChris Lattner // The first bits in the flags are reserved for the SymbolContext::Scope bits 3930fdc8d8SChris Lattner // so we know if we have tried to look up information in our internal symbol 4030fdc8d8SChris Lattner // context (m_sc) already. 4159e8fc1cSGreg Clayton #define RESOLVED_FRAME_CODE_ADDR (uint32_t(eSymbolContextEverything + 1)) 426dadd508SGreg Clayton #define RESOLVED_FRAME_ID_SYMBOL_SCOPE (RESOLVED_FRAME_CODE_ADDR << 1) 4359e8fc1cSGreg Clayton #define GOT_FRAME_BASE (RESOLVED_FRAME_ID_SYMBOL_SCOPE << 1) 4459e8fc1cSGreg Clayton #define RESOLVED_VARIABLES (GOT_FRAME_BASE << 1) 457c0962dcSSean Callanan #define RESOLVED_GLOBAL_VARIABLES (RESOLVED_VARIABLES << 1) 4630fdc8d8SChris Lattner 47*bb19a13cSSaleem Abdulrasool StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx, user_id_t unwind_frame_index, addr_t cfa, 48*bb19a13cSSaleem Abdulrasool bool cfa_is_valid, addr_t pc, uint32_t stop_id, bool stop_id_is_valid, bool is_history_frame, 49*bb19a13cSSaleem Abdulrasool const SymbolContext *sc_ptr) 50*bb19a13cSSaleem Abdulrasool : m_thread_wp(thread_sp), 511b72fcb7SGreg Clayton m_frame_index(frame_idx), 525ccbd294SGreg Clayton m_concrete_frame_index(unwind_frame_index), 5330fdc8d8SChris Lattner m_reg_context_sp(), 54d70a6e71SEugene Zelenko m_id(pc, cfa, nullptr), 55e72dfb32SGreg Clayton m_frame_code_addr(pc), 5630fdc8d8SChris Lattner m_sc(), 5730fdc8d8SChris Lattner m_flags(), 5830fdc8d8SChris Lattner m_frame_base(), 5930fdc8d8SChris Lattner m_frame_base_error(), 6099618476SJason Molenda m_cfa_is_valid(cfa_is_valid), 6199618476SJason Molenda m_stop_id(stop_id), 6299618476SJason Molenda m_stop_id_is_valid(stop_id_is_valid), 6399618476SJason Molenda m_is_history_frame(is_history_frame), 6430fdc8d8SChris Lattner m_variable_list_sp(), 651a65ae11SGreg Clayton m_variable_list_value_objects(), 666a354705SJason Molenda m_disassembly(), 67*bb19a13cSSaleem Abdulrasool m_mutex() 6830fdc8d8SChris Lattner { 6999618476SJason Molenda // If we don't have a CFA value, use the frame index for our StackID so that recursive 7099618476SJason Molenda // functions properly aren't confused with one another on a history stack. 71d70a6e71SEugene Zelenko if (m_is_history_frame && !m_cfa_is_valid) 7299618476SJason Molenda { 7399618476SJason Molenda m_id.SetCFA(m_frame_index); 7499618476SJason Molenda } 7599618476SJason Molenda 76d70a6e71SEugene Zelenko if (sc_ptr != nullptr) 771b72fcb7SGreg Clayton { 7830fdc8d8SChris Lattner m_sc = *sc_ptr; 791b72fcb7SGreg Clayton m_flags.Set(m_sc.GetResolvedMask()); 801b72fcb7SGreg Clayton } 8130fdc8d8SChris Lattner } 8230fdc8d8SChris Lattner 83*bb19a13cSSaleem Abdulrasool StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx, user_id_t unwind_frame_index, 84*bb19a13cSSaleem Abdulrasool const RegisterContextSP ®_context_sp, addr_t cfa, addr_t pc, const SymbolContext *sc_ptr) 85*bb19a13cSSaleem Abdulrasool : m_thread_wp(thread_sp), 861b72fcb7SGreg Clayton m_frame_index(frame_idx), 875ccbd294SGreg Clayton m_concrete_frame_index(unwind_frame_index), 8830fdc8d8SChris Lattner m_reg_context_sp(reg_context_sp), 89d70a6e71SEugene Zelenko m_id(pc, cfa, nullptr), 90e72dfb32SGreg Clayton m_frame_code_addr(pc), 9130fdc8d8SChris Lattner m_sc(), 9230fdc8d8SChris Lattner m_flags(), 9330fdc8d8SChris Lattner m_frame_base(), 9430fdc8d8SChris Lattner m_frame_base_error(), 9599618476SJason Molenda m_cfa_is_valid(true), 9699618476SJason Molenda m_stop_id(0), 9799618476SJason Molenda m_stop_id_is_valid(false), 9899618476SJason Molenda m_is_history_frame(false), 9930fdc8d8SChris Lattner m_variable_list_sp(), 1001a65ae11SGreg Clayton m_variable_list_value_objects(), 1016a354705SJason Molenda m_disassembly(), 102*bb19a13cSSaleem Abdulrasool m_mutex() 10330fdc8d8SChris Lattner { 104d70a6e71SEugene Zelenko if (sc_ptr != nullptr) 1051b72fcb7SGreg Clayton { 10630fdc8d8SChris Lattner m_sc = *sc_ptr; 1071b72fcb7SGreg Clayton m_flags.Set(m_sc.GetResolvedMask()); 1081b72fcb7SGreg Clayton } 1091b72fcb7SGreg Clayton 1101b72fcb7SGreg Clayton if (reg_context_sp && !m_sc.target_sp) 1111b72fcb7SGreg Clayton { 112d9e416c0SGreg Clayton m_sc.target_sp = reg_context_sp->CalculateTarget(); 113d9e416c0SGreg Clayton if (m_sc.target_sp) 1141b72fcb7SGreg Clayton m_flags.Set(eSymbolContextTarget); 1151b72fcb7SGreg Clayton } 1161b72fcb7SGreg Clayton } 1171b72fcb7SGreg Clayton 118*bb19a13cSSaleem Abdulrasool StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx, user_id_t unwind_frame_index, 119*bb19a13cSSaleem Abdulrasool const RegisterContextSP ®_context_sp, addr_t cfa, const Address &pc_addr, 120*bb19a13cSSaleem Abdulrasool const SymbolContext *sc_ptr) 121*bb19a13cSSaleem Abdulrasool : m_thread_wp(thread_sp), 1221b72fcb7SGreg Clayton m_frame_index(frame_idx), 1235ccbd294SGreg Clayton m_concrete_frame_index(unwind_frame_index), 1241b72fcb7SGreg Clayton m_reg_context_sp(reg_context_sp), 125d70a6e71SEugene Zelenko m_id(pc_addr.GetLoadAddress(thread_sp->CalculateTarget().get()), cfa, nullptr), 12612fc3e0fSGreg Clayton m_frame_code_addr(pc_addr), 1271b72fcb7SGreg Clayton m_sc(), 1281b72fcb7SGreg Clayton m_flags(), 1291b72fcb7SGreg Clayton m_frame_base(), 1301b72fcb7SGreg Clayton m_frame_base_error(), 13199618476SJason Molenda m_cfa_is_valid(true), 13299618476SJason Molenda m_stop_id(0), 13399618476SJason Molenda m_stop_id_is_valid(false), 13499618476SJason Molenda m_is_history_frame(false), 1351b72fcb7SGreg Clayton m_variable_list_sp(), 1361a65ae11SGreg Clayton m_variable_list_value_objects(), 1376a354705SJason Molenda m_disassembly(), 138*bb19a13cSSaleem Abdulrasool m_mutex() 1391b72fcb7SGreg Clayton { 140d70a6e71SEugene Zelenko if (sc_ptr != nullptr) 1411b72fcb7SGreg Clayton { 1421b72fcb7SGreg Clayton m_sc = *sc_ptr; 1431b72fcb7SGreg Clayton m_flags.Set(m_sc.GetResolvedMask()); 1441b72fcb7SGreg Clayton } 1451b72fcb7SGreg Clayton 146d70a6e71SEugene Zelenko if (!m_sc.target_sp && reg_context_sp) 1471b72fcb7SGreg Clayton { 148d9e416c0SGreg Clayton m_sc.target_sp = reg_context_sp->CalculateTarget(); 149d9e416c0SGreg Clayton if (m_sc.target_sp) 1501b72fcb7SGreg Clayton m_flags.Set(eSymbolContextTarget); 1511b72fcb7SGreg Clayton } 1521b72fcb7SGreg Clayton 153e72dfb32SGreg Clayton ModuleSP pc_module_sp(pc_addr.GetModule()); 154e72dfb32SGreg Clayton if (!m_sc.module_sp || m_sc.module_sp != pc_module_sp) 1551b72fcb7SGreg Clayton { 156e72dfb32SGreg Clayton if (pc_module_sp) 1571b72fcb7SGreg Clayton { 158e72dfb32SGreg Clayton m_sc.module_sp = pc_module_sp; 1591b72fcb7SGreg Clayton m_flags.Set(eSymbolContextModule); 1601b72fcb7SGreg Clayton } 161ffc1d667SGreg Clayton else 162ffc1d667SGreg Clayton { 163ffc1d667SGreg Clayton m_sc.module_sp.reset(); 164ffc1d667SGreg Clayton } 1651b72fcb7SGreg Clayton } 16630fdc8d8SChris Lattner } 16730fdc8d8SChris Lattner 168d70a6e71SEugene Zelenko StackFrame::~StackFrame() = default; 16930fdc8d8SChris Lattner 17030fdc8d8SChris Lattner StackID& 17130fdc8d8SChris Lattner StackFrame::GetStackID() 17230fdc8d8SChris Lattner { 173*bb19a13cSSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex); 1746dadd508SGreg Clayton // Make sure we have resolved the StackID object's symbol context scope if 1756dadd508SGreg Clayton // we already haven't looked it up. 17659e8fc1cSGreg Clayton 17759e8fc1cSGreg Clayton if (m_flags.IsClear (RESOLVED_FRAME_ID_SYMBOL_SCOPE)) 17859e8fc1cSGreg Clayton { 1792cad65a5SGreg Clayton if (m_id.GetSymbolContextScope ()) 18059e8fc1cSGreg Clayton { 18195897c6aSGreg Clayton // We already have a symbol context scope, we just don't have our 18295897c6aSGreg Clayton // flag bit set. 18359e8fc1cSGreg Clayton m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE); 18459e8fc1cSGreg Clayton } 18559e8fc1cSGreg Clayton else 18659e8fc1cSGreg Clayton { 18795897c6aSGreg Clayton // Calculate the frame block and use this for the stack ID symbol 18895897c6aSGreg Clayton // context scope if we have one. 18995897c6aSGreg Clayton SymbolContextScope *scope = GetFrameBlock (); 190d70a6e71SEugene Zelenko if (scope == nullptr) 19159e8fc1cSGreg Clayton { 19295897c6aSGreg Clayton // We don't have a block, so use the symbol 19395897c6aSGreg Clayton if (m_flags.IsClear (eSymbolContextSymbol)) 19459e8fc1cSGreg Clayton GetSymbolContext (eSymbolContextSymbol); 19595897c6aSGreg Clayton 196d70a6e71SEugene Zelenko // It is ok if m_sc.symbol is nullptr here 19795897c6aSGreg Clayton scope = m_sc.symbol; 19859e8fc1cSGreg Clayton } 19995897c6aSGreg Clayton // Set the symbol context scope (the accessor will set the 20095897c6aSGreg Clayton // RESOLVED_FRAME_ID_SYMBOL_SCOPE bit in m_flags). 20195897c6aSGreg Clayton SetSymbolContextScope (scope); 20259e8fc1cSGreg Clayton } 20359e8fc1cSGreg Clayton } 20430fdc8d8SChris Lattner return m_id; 20530fdc8d8SChris Lattner } 20630fdc8d8SChris Lattner 207513c6bb8SJim Ingham uint32_t 208513c6bb8SJim Ingham StackFrame::GetFrameIndex () const 209513c6bb8SJim Ingham { 210513c6bb8SJim Ingham ThreadSP thread_sp = GetThread(); 211513c6bb8SJim Ingham if (thread_sp) 212b57e4a1bSJason Molenda return thread_sp->GetStackFrameList()->GetVisibleStackFrameIndex(m_frame_index); 213513c6bb8SJim Ingham else 214513c6bb8SJim Ingham return m_frame_index; 215513c6bb8SJim Ingham } 216513c6bb8SJim Ingham 21759e8fc1cSGreg Clayton void 21859e8fc1cSGreg Clayton StackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope) 21959e8fc1cSGreg Clayton { 220*bb19a13cSSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex); 22159e8fc1cSGreg Clayton m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE); 22259e8fc1cSGreg Clayton m_id.SetSymbolContextScope (symbol_scope); 22359e8fc1cSGreg Clayton } 22459e8fc1cSGreg Clayton 22534132754SGreg Clayton const Address& 2269da7bd07SGreg Clayton StackFrame::GetFrameCodeAddress() 22730fdc8d8SChris Lattner { 228*bb19a13cSSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex); 22959e8fc1cSGreg Clayton if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) && !m_frame_code_addr.IsSectionOffset()) 23030fdc8d8SChris Lattner { 23159e8fc1cSGreg Clayton m_flags.Set (RESOLVED_FRAME_CODE_ADDR); 23230fdc8d8SChris Lattner 23330fdc8d8SChris Lattner // Resolve the PC into a temporary address because if ResolveLoadAddress 23430fdc8d8SChris Lattner // fails to resolve the address, it will clear the address object... 235d9e416c0SGreg Clayton ThreadSP thread_sp (GetThread()); 236d9e416c0SGreg Clayton if (thread_sp) 237d9e416c0SGreg Clayton { 238d9e416c0SGreg Clayton TargetSP target_sp (thread_sp->CalculateTarget()); 239d9e416c0SGreg Clayton if (target_sp) 240d9e416c0SGreg Clayton { 24125b9f7ebSTamas Berghammer if (m_frame_code_addr.SetOpcodeLoadAddress (m_frame_code_addr.GetOffset(), target_sp.get(), eAddressClassCode)) 24230fdc8d8SChris Lattner { 243e72dfb32SGreg Clayton ModuleSP module_sp (m_frame_code_addr.GetModule()); 244e72dfb32SGreg Clayton if (module_sp) 24530fdc8d8SChris Lattner { 246e72dfb32SGreg Clayton m_sc.module_sp = module_sp; 24730fdc8d8SChris Lattner m_flags.Set(eSymbolContextModule); 24830fdc8d8SChris Lattner } 24930fdc8d8SChris Lattner } 25030fdc8d8SChris Lattner } 25130fdc8d8SChris Lattner } 252d9e416c0SGreg Clayton } 25312fc3e0fSGreg Clayton return m_frame_code_addr; 25430fdc8d8SChris Lattner } 25530fdc8d8SChris Lattner 25699618476SJason Molenda bool 25730fdc8d8SChris Lattner StackFrame::ChangePC (addr_t pc) 25830fdc8d8SChris Lattner { 259*bb19a13cSSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex); 26099618476SJason Molenda // We can't change the pc value of a history stack frame - it is immutable. 26199618476SJason Molenda if (m_is_history_frame) 26299618476SJason Molenda return false; 263e72dfb32SGreg Clayton m_frame_code_addr.SetRawAddress(pc); 26472310355SGreg Clayton m_sc.Clear(false); 26573b472d4SGreg Clayton m_flags.Reset(0); 266d9e416c0SGreg Clayton ThreadSP thread_sp (GetThread()); 267d9e416c0SGreg Clayton if (thread_sp) 268d9e416c0SGreg Clayton thread_sp->ClearStackFrames (); 26999618476SJason Molenda return true; 27030fdc8d8SChris Lattner } 27130fdc8d8SChris Lattner 27230fdc8d8SChris Lattner const char * 27330fdc8d8SChris Lattner StackFrame::Disassemble () 27430fdc8d8SChris Lattner { 275*bb19a13cSSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex); 27630fdc8d8SChris Lattner if (m_disassembly.GetSize() == 0) 27730fdc8d8SChris Lattner { 278d9e416c0SGreg Clayton ExecutionContext exe_ctx (shared_from_this()); 279d9e416c0SGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 280d9e416c0SGreg Clayton if (target) 281d9e416c0SGreg Clayton { 282d70a6e71SEugene Zelenko const char *plugin_name = nullptr; 283d70a6e71SEugene Zelenko const char *flavor = nullptr; 284d9e416c0SGreg Clayton Disassembler::Disassemble (target->GetDebugger(), 285d9e416c0SGreg Clayton target->GetArchitecture(), 2860f063ba6SJim Ingham plugin_name, 2870f063ba6SJim Ingham flavor, 28830fdc8d8SChris Lattner exe_ctx, 28930fdc8d8SChris Lattner 0, 29037023b06SJim Ingham 0, 2911da6f9d7SGreg Clayton 0, 29230fdc8d8SChris Lattner m_disassembly); 293d9e416c0SGreg Clayton } 29430fdc8d8SChris Lattner if (m_disassembly.GetSize() == 0) 295d70a6e71SEugene Zelenko return nullptr; 29630fdc8d8SChris Lattner } 29730fdc8d8SChris Lattner return m_disassembly.GetData(); 29830fdc8d8SChris Lattner } 29930fdc8d8SChris Lattner 30095897c6aSGreg Clayton Block * 30195897c6aSGreg Clayton StackFrame::GetFrameBlock () 30295897c6aSGreg Clayton { 303d70a6e71SEugene Zelenko if (m_sc.block == nullptr && m_flags.IsClear(eSymbolContextBlock)) 30495897c6aSGreg Clayton GetSymbolContext (eSymbolContextBlock); 30595897c6aSGreg Clayton 30695897c6aSGreg Clayton if (m_sc.block) 30795897c6aSGreg Clayton { 30895897c6aSGreg Clayton Block *inline_block = m_sc.block->GetContainingInlinedBlock(); 30995897c6aSGreg Clayton if (inline_block) 31095897c6aSGreg Clayton { 31195897c6aSGreg Clayton // Use the block with the inlined function info 31295897c6aSGreg Clayton // as the frame block we want this frame to have only the variables 31395897c6aSGreg Clayton // for the inlined function and its non-inlined block child blocks. 31495897c6aSGreg Clayton return inline_block; 31595897c6aSGreg Clayton } 31695897c6aSGreg Clayton else 31795897c6aSGreg Clayton { 31895897c6aSGreg Clayton // This block is not contained withing any inlined function blocks 31995897c6aSGreg Clayton // with so we want to use the top most function block. 32095897c6aSGreg Clayton return &m_sc.function->GetBlock (false); 32195897c6aSGreg Clayton } 32295897c6aSGreg Clayton } 323d70a6e71SEugene Zelenko return nullptr; 32495897c6aSGreg Clayton } 32595897c6aSGreg Clayton 32630fdc8d8SChris Lattner //---------------------------------------------------------------------- 32730fdc8d8SChris Lattner // Get the symbol context if we already haven't done so by resolving the 32830fdc8d8SChris Lattner // PC address as much as possible. This way when we pass around a 32930fdc8d8SChris Lattner // StackFrame object, everyone will have as much information as 33030fdc8d8SChris Lattner // possible and no one will ever have to look things up manually. 33130fdc8d8SChris Lattner //---------------------------------------------------------------------- 33230fdc8d8SChris Lattner const SymbolContext& 33330fdc8d8SChris Lattner StackFrame::GetSymbolContext (uint32_t resolve_scope) 33430fdc8d8SChris Lattner { 335*bb19a13cSSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex); 33630fdc8d8SChris Lattner // Copy our internal symbol context into "sc". 33773b472d4SGreg Clayton if ((m_flags.Get() & resolve_scope) != resolve_scope) 33830fdc8d8SChris Lattner { 33975a0333bSGreg Clayton uint32_t resolved = 0; 34075a0333bSGreg Clayton 34175a0333bSGreg Clayton // If the target was requested add that: 34275a0333bSGreg Clayton if (!m_sc.target_sp) 34375a0333bSGreg Clayton { 34475a0333bSGreg Clayton m_sc.target_sp = CalculateTarget(); 34575a0333bSGreg Clayton if (m_sc.target_sp) 34675a0333bSGreg Clayton resolved |= eSymbolContextTarget; 34775a0333bSGreg Clayton } 34875a0333bSGreg Clayton 349aaa0ba31SBruce Mitchener // Resolve our PC to section offset if we haven't already done so 35030fdc8d8SChris Lattner // and if we don't have a module. The resolved address section will 35130fdc8d8SChris Lattner // contain the module to which it belongs 35259e8fc1cSGreg Clayton if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR)) 3539da7bd07SGreg Clayton GetFrameCodeAddress(); 35430fdc8d8SChris Lattner 35530fdc8d8SChris Lattner // If this is not frame zero, then we need to subtract 1 from the PC 35630fdc8d8SChris Lattner // value when doing address lookups since the PC will be on the 35730fdc8d8SChris Lattner // instruction following the function call instruction... 35830fdc8d8SChris Lattner 3599da7bd07SGreg Clayton Address lookup_addr(GetFrameCodeAddress()); 3601b72fcb7SGreg Clayton if (m_frame_index > 0 && lookup_addr.IsValid()) 36130fdc8d8SChris Lattner { 36230fdc8d8SChris Lattner addr_t offset = lookup_addr.GetOffset(); 36330fdc8d8SChris Lattner if (offset > 0) 364cf29675dSJason Molenda { 36530fdc8d8SChris Lattner lookup_addr.SetOffset(offset - 1); 366cf29675dSJason Molenda 367cf29675dSJason Molenda } 368cf29675dSJason Molenda else 369cf29675dSJason Molenda { 370cf29675dSJason Molenda // lookup_addr is the start of a section. We need 371cf29675dSJason Molenda // do the math on the actual load address and re-compute 372cf29675dSJason Molenda // the section. We're working with a 'noreturn' function 373cf29675dSJason Molenda // at the end of a section. 374cf29675dSJason Molenda ThreadSP thread_sp (GetThread()); 375cf29675dSJason Molenda if (thread_sp) 376cf29675dSJason Molenda { 377cf29675dSJason Molenda TargetSP target_sp (thread_sp->CalculateTarget()); 378cf29675dSJason Molenda if (target_sp) 379cf29675dSJason Molenda { 380cf29675dSJason Molenda addr_t addr_minus_one = lookup_addr.GetLoadAddress(target_sp.get()) - 1; 381cf29675dSJason Molenda lookup_addr.SetLoadAddress (addr_minus_one, target_sp.get()); 382cf29675dSJason Molenda } 383cf29675dSJason Molenda else 384cf29675dSJason Molenda { 385cf29675dSJason Molenda lookup_addr.SetOffset(offset - 1); 386cf29675dSJason Molenda } 387cf29675dSJason Molenda } 388cf29675dSJason Molenda } 38930fdc8d8SChris Lattner } 39030fdc8d8SChris Lattner 39130fdc8d8SChris Lattner if (m_sc.module_sp) 39230fdc8d8SChris Lattner { 39330fdc8d8SChris Lattner // We have something in our stack frame symbol context, lets check 39430fdc8d8SChris Lattner // if we haven't already tried to lookup one of those things. If we 39530fdc8d8SChris Lattner // haven't then we will do the query. 3961b72fcb7SGreg Clayton 3971b72fcb7SGreg Clayton uint32_t actual_resolve_scope = 0; 3981b72fcb7SGreg Clayton 3991b72fcb7SGreg Clayton if (resolve_scope & eSymbolContextCompUnit) 4001b72fcb7SGreg Clayton { 4011b72fcb7SGreg Clayton if (m_flags.IsClear (eSymbolContextCompUnit)) 4021b72fcb7SGreg Clayton { 4031b72fcb7SGreg Clayton if (m_sc.comp_unit) 4049da7bd07SGreg Clayton resolved |= eSymbolContextCompUnit; 4051b72fcb7SGreg Clayton else 4061b72fcb7SGreg Clayton actual_resolve_scope |= eSymbolContextCompUnit; 4071b72fcb7SGreg Clayton } 4081b72fcb7SGreg Clayton } 4091b72fcb7SGreg Clayton 4101b72fcb7SGreg Clayton if (resolve_scope & eSymbolContextFunction) 4111b72fcb7SGreg Clayton { 4121b72fcb7SGreg Clayton if (m_flags.IsClear (eSymbolContextFunction)) 4131b72fcb7SGreg Clayton { 4141b72fcb7SGreg Clayton if (m_sc.function) 4159da7bd07SGreg Clayton resolved |= eSymbolContextFunction; 4161b72fcb7SGreg Clayton else 4171b72fcb7SGreg Clayton actual_resolve_scope |= eSymbolContextFunction; 4181b72fcb7SGreg Clayton } 4191b72fcb7SGreg Clayton } 4201b72fcb7SGreg Clayton 4211b72fcb7SGreg Clayton if (resolve_scope & eSymbolContextBlock) 4221b72fcb7SGreg Clayton { 4231b72fcb7SGreg Clayton if (m_flags.IsClear (eSymbolContextBlock)) 4241b72fcb7SGreg Clayton { 4251b72fcb7SGreg Clayton if (m_sc.block) 4269da7bd07SGreg Clayton resolved |= eSymbolContextBlock; 4271b72fcb7SGreg Clayton else 4281b72fcb7SGreg Clayton actual_resolve_scope |= eSymbolContextBlock; 4291b72fcb7SGreg Clayton } 4301b72fcb7SGreg Clayton } 4311b72fcb7SGreg Clayton 4321b72fcb7SGreg Clayton if (resolve_scope & eSymbolContextSymbol) 4331b72fcb7SGreg Clayton { 4341b72fcb7SGreg Clayton if (m_flags.IsClear (eSymbolContextSymbol)) 4351b72fcb7SGreg Clayton { 4361b72fcb7SGreg Clayton if (m_sc.symbol) 4379da7bd07SGreg Clayton resolved |= eSymbolContextSymbol; 4381b72fcb7SGreg Clayton else 4391b72fcb7SGreg Clayton actual_resolve_scope |= eSymbolContextSymbol; 4401b72fcb7SGreg Clayton } 4411b72fcb7SGreg Clayton } 4421b72fcb7SGreg Clayton 4431b72fcb7SGreg Clayton if (resolve_scope & eSymbolContextLineEntry) 4441b72fcb7SGreg Clayton { 4451b72fcb7SGreg Clayton if (m_flags.IsClear (eSymbolContextLineEntry)) 4461b72fcb7SGreg Clayton { 4471b72fcb7SGreg Clayton if (m_sc.line_entry.IsValid()) 4489da7bd07SGreg Clayton resolved |= eSymbolContextLineEntry; 4491b72fcb7SGreg Clayton else 4501b72fcb7SGreg Clayton actual_resolve_scope |= eSymbolContextLineEntry; 4511b72fcb7SGreg Clayton } 4521b72fcb7SGreg Clayton } 4531b72fcb7SGreg Clayton 4541b72fcb7SGreg Clayton if (actual_resolve_scope) 45530fdc8d8SChris Lattner { 45630fdc8d8SChris Lattner // We might be resolving less information than what is already 45730fdc8d8SChris Lattner // in our current symbol context so resolve into a temporary 45830fdc8d8SChris Lattner // symbol context "sc" so we don't clear out data we have 45930fdc8d8SChris Lattner // already found in "m_sc" 46030fdc8d8SChris Lattner SymbolContext sc; 46130fdc8d8SChris Lattner // Set flags that indicate what we have tried to resolve 4629da7bd07SGreg Clayton resolved |= m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, actual_resolve_scope, sc); 4631b72fcb7SGreg Clayton // Only replace what we didn't already have as we may have 4641b72fcb7SGreg Clayton // information for an inlined function scope that won't match 4651b72fcb7SGreg Clayton // what a standard lookup by address would match 466d70a6e71SEugene Zelenko if ((resolved & eSymbolContextCompUnit) && m_sc.comp_unit == nullptr) 4679da7bd07SGreg Clayton m_sc.comp_unit = sc.comp_unit; 468d70a6e71SEugene Zelenko if ((resolved & eSymbolContextFunction) && m_sc.function == nullptr) 4699da7bd07SGreg Clayton m_sc.function = sc.function; 470d70a6e71SEugene Zelenko if ((resolved & eSymbolContextBlock) && m_sc.block == nullptr) 4719da7bd07SGreg Clayton m_sc.block = sc.block; 472d70a6e71SEugene Zelenko if ((resolved & eSymbolContextSymbol) && m_sc.symbol == nullptr) 4739da7bd07SGreg Clayton m_sc.symbol = sc.symbol; 4749da7bd07SGreg Clayton if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid()) 47575a0333bSGreg Clayton { 4769da7bd07SGreg Clayton m_sc.line_entry = sc.line_entry; 477911d5784STed Woodward m_sc.line_entry.ApplyFileMappings(m_sc.target_sp); 47875a0333bSGreg Clayton } 47930fdc8d8SChris Lattner } 48030fdc8d8SChris Lattner } 48130fdc8d8SChris Lattner else 48230fdc8d8SChris Lattner { 48330fdc8d8SChris Lattner // If we don't have a module, then we can't have the compile unit, 48430fdc8d8SChris Lattner // function, block, line entry or symbol, so we can safely call 48530fdc8d8SChris Lattner // ResolveSymbolContextForAddress with our symbol context member m_sc. 4869da7bd07SGreg Clayton if (m_sc.target_sp) 487f4be227dSSean Callanan { 48875a0333bSGreg Clayton resolved |= m_sc.target_sp->GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc); 489f4be227dSSean Callanan } 4909da7bd07SGreg Clayton } 49130fdc8d8SChris Lattner 49230fdc8d8SChris Lattner // Update our internal flags so we remember what we have tried to locate so 49330fdc8d8SChris Lattner // we don't have to keep trying when more calls to this function are made. 4949da7bd07SGreg Clayton // We might have dug up more information that was requested (for example 4959da7bd07SGreg Clayton // if we were asked to only get the block, we will have gotten the 4969da7bd07SGreg Clayton // compile unit, and function) so set any additional bits that we resolved 4979da7bd07SGreg Clayton m_flags.Set (resolve_scope | resolved); 49830fdc8d8SChris Lattner } 49930fdc8d8SChris Lattner 50030fdc8d8SChris Lattner // Return the symbol context with everything that was possible to resolve 50130fdc8d8SChris Lattner // resolved. 50230fdc8d8SChris Lattner return m_sc; 50330fdc8d8SChris Lattner } 50430fdc8d8SChris Lattner 50530fdc8d8SChris Lattner VariableList * 506288bdf9cSGreg Clayton StackFrame::GetVariableList (bool get_file_globals) 50730fdc8d8SChris Lattner { 508*bb19a13cSSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex); 50930fdc8d8SChris Lattner if (m_flags.IsClear(RESOLVED_VARIABLES)) 51030fdc8d8SChris Lattner { 51130fdc8d8SChris Lattner m_flags.Set(RESOLVED_VARIABLES); 51230fdc8d8SChris Lattner 51395897c6aSGreg Clayton Block *frame_block = GetFrameBlock(); 514288bdf9cSGreg Clayton 51595897c6aSGreg Clayton if (frame_block) 51630fdc8d8SChris Lattner { 51795897c6aSGreg Clayton const bool get_child_variables = true; 51895897c6aSGreg Clayton const bool can_create = true; 519c662ec8bSGreg Clayton const bool stop_if_child_block_is_inlined_function = true; 520c662ec8bSGreg Clayton m_variable_list_sp.reset(new VariableList()); 52172ac8a84STamas Berghammer frame_block->AppendBlockVariables(can_create, 52272ac8a84STamas Berghammer get_child_variables, 52372ac8a84STamas Berghammer stop_if_child_block_is_inlined_function, 524a32532bfSGreg Clayton [this](Variable* v) { return true; }, 52572ac8a84STamas Berghammer m_variable_list_sp.get()); 52630fdc8d8SChris Lattner } 5277c0962dcSSean Callanan } 528288bdf9cSGreg Clayton 5297c0962dcSSean Callanan if (m_flags.IsClear(RESOLVED_GLOBAL_VARIABLES) && 5307c0962dcSSean Callanan get_file_globals) 53195897c6aSGreg Clayton { 5327c0962dcSSean Callanan m_flags.Set(RESOLVED_GLOBAL_VARIABLES); 5337c0962dcSSean Callanan 53495897c6aSGreg Clayton if (m_flags.IsClear (eSymbolContextCompUnit)) 53595897c6aSGreg Clayton GetSymbolContext (eSymbolContextCompUnit); 53695897c6aSGreg Clayton 53795897c6aSGreg Clayton if (m_sc.comp_unit) 538288bdf9cSGreg Clayton { 539288bdf9cSGreg Clayton VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true)); 540288bdf9cSGreg Clayton if (m_variable_list_sp) 541288bdf9cSGreg Clayton m_variable_list_sp->AddVariables (global_variable_list_sp.get()); 542288bdf9cSGreg Clayton else 543288bdf9cSGreg Clayton m_variable_list_sp = global_variable_list_sp; 544288bdf9cSGreg Clayton } 54530fdc8d8SChris Lattner } 5467c0962dcSSean Callanan 54730fdc8d8SChris Lattner return m_variable_list_sp.get(); 54830fdc8d8SChris Lattner } 54930fdc8d8SChris Lattner 550d41f032aSGreg Clayton VariableListSP 551cef46177SJim Ingham StackFrame::GetInScopeVariableList (bool get_file_globals, bool must_have_valid_location) 552d41f032aSGreg Clayton { 553*bb19a13cSSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex); 55499618476SJason Molenda // We can't fetch variable information for a history stack frame. 55599618476SJason Molenda if (m_is_history_frame) 55699618476SJason Molenda return VariableListSP(); 55799618476SJason Molenda 558d41f032aSGreg Clayton VariableListSP var_list_sp(new VariableList); 559d41f032aSGreg Clayton GetSymbolContext (eSymbolContextCompUnit | eSymbolContextBlock); 560d41f032aSGreg Clayton 561d41f032aSGreg Clayton if (m_sc.block) 562d41f032aSGreg Clayton { 563d41f032aSGreg Clayton const bool can_create = true; 564d41f032aSGreg Clayton const bool get_parent_variables = true; 565d41f032aSGreg Clayton const bool stop_if_block_is_inlined_function = true; 566d41f032aSGreg Clayton m_sc.block->AppendVariables (can_create, 567d41f032aSGreg Clayton get_parent_variables, 568d41f032aSGreg Clayton stop_if_block_is_inlined_function, 569cef46177SJim Ingham [this, must_have_valid_location](Variable* v) 570cef46177SJim Ingham { 571cef46177SJim Ingham return v->IsInScope(this) && (!must_have_valid_location || v->LocationIsValidForFrame(this)); 572cef46177SJim Ingham }, 573d41f032aSGreg Clayton var_list_sp.get()); 574d41f032aSGreg Clayton } 575d41f032aSGreg Clayton 576b90168ffSSiva Chandra if (m_sc.comp_unit && get_file_globals) 577d41f032aSGreg Clayton { 578d41f032aSGreg Clayton VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true)); 579d41f032aSGreg Clayton if (global_variable_list_sp) 580d41f032aSGreg Clayton var_list_sp->AddVariables (global_variable_list_sp.get()); 581d41f032aSGreg Clayton } 582d41f032aSGreg Clayton 583d41f032aSGreg Clayton return var_list_sp; 584d41f032aSGreg Clayton } 585d41f032aSGreg Clayton 5868b2fe6dcSGreg Clayton ValueObjectSP 5872837b766SJim Ingham StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, 5884d122c40SGreg Clayton DynamicValueType use_dynamic, 5892837b766SJim Ingham uint32_t options, 5904d122c40SGreg Clayton VariableSP &var_sp, 5912837b766SJim Ingham Error &error) 5928b2fe6dcSGreg Clayton { 59399618476SJason Molenda // We can't fetch variable information for a history stack frame. 59499618476SJason Molenda if (m_is_history_frame) 59599618476SJason Molenda return ValueObjectSP(); 59654979cddSGreg Clayton 59754979cddSGreg Clayton if (var_expr_cstr && var_expr_cstr[0]) 59854979cddSGreg Clayton { 5996d5e68eaSGreg Clayton const bool check_ptr_vs_member = (options & eExpressionPathOptionCheckPtrVsMember) != 0; 6006d5e68eaSGreg Clayton const bool no_fragile_ivar = (options & eExpressionPathOptionsNoFragileObjcIvar) != 0; 60127b625e1SEnrico Granata const bool no_synth_child = (options & eExpressionPathOptionsNoSyntheticChildren) != 0; 60258ad3344SEnrico Granata //const bool no_synth_array = (options & eExpressionPathOptionsNoSyntheticArrayRange) != 0; 60354979cddSGreg Clayton error.Clear(); 6048b2fe6dcSGreg Clayton bool deref = false; 6058b2fe6dcSGreg Clayton bool address_of = false; 6068b2fe6dcSGreg Clayton ValueObjectSP valobj_sp; 6078b2fe6dcSGreg Clayton const bool get_file_globals = true; 608d41f032aSGreg Clayton // When looking up a variable for an expression, we need only consider the 609d41f032aSGreg Clayton // variables that are in scope. 610d41f032aSGreg Clayton VariableListSP var_list_sp (GetInScopeVariableList (get_file_globals)); 611d41f032aSGreg Clayton VariableList *variable_list = var_list_sp.get(); 6128b2fe6dcSGreg Clayton 6138b2fe6dcSGreg Clayton if (variable_list) 6148b2fe6dcSGreg Clayton { 6158b2fe6dcSGreg Clayton // If first character is a '*', then show pointer contents 61654979cddSGreg Clayton const char *var_expr = var_expr_cstr; 6178b2fe6dcSGreg Clayton if (var_expr[0] == '*') 6188b2fe6dcSGreg Clayton { 6198b2fe6dcSGreg Clayton deref = true; 6208b2fe6dcSGreg Clayton var_expr++; // Skip the '*' 6218b2fe6dcSGreg Clayton } 6228b2fe6dcSGreg Clayton else if (var_expr[0] == '&') 6238b2fe6dcSGreg Clayton { 6248b2fe6dcSGreg Clayton address_of = true; 6258b2fe6dcSGreg Clayton var_expr++; // Skip the '&' 6268b2fe6dcSGreg Clayton } 6278b2fe6dcSGreg Clayton 6288b2fe6dcSGreg Clayton std::string var_path (var_expr); 62954979cddSGreg Clayton size_t separator_idx = var_path.find_first_of(".-[=+~|&^%#@!/?,<>{}"); 63054979cddSGreg Clayton StreamString var_expr_path_strm; 6318b2fe6dcSGreg Clayton 6328b2fe6dcSGreg Clayton ConstString name_const_string; 6338b2fe6dcSGreg Clayton if (separator_idx == std::string::npos) 6348b2fe6dcSGreg Clayton name_const_string.SetCString (var_path.c_str()); 6358b2fe6dcSGreg Clayton else 6368b2fe6dcSGreg Clayton name_const_string.SetCStringWithLength (var_path.c_str(), separator_idx); 6378b2fe6dcSGreg Clayton 63810bc1a4eSPaul Herman var_sp = variable_list->FindVariable(name_const_string, false); 639685c88c5SGreg Clayton 640685c88c5SGreg Clayton bool synthetically_added_instance_object = false; 641685c88c5SGreg Clayton 642685c88c5SGreg Clayton if (var_sp) 643685c88c5SGreg Clayton { 644685c88c5SGreg Clayton var_path.erase (0, name_const_string.GetLength ()); 645685c88c5SGreg Clayton } 64646252398SEnrico Granata 64746252398SEnrico Granata if (!var_sp && (options & eExpressionPathOptionsAllowDirectIVarAccess)) 648685c88c5SGreg Clayton { 649685c88c5SGreg Clayton // Check for direct ivars access which helps us with implicit 650685c88c5SGreg Clayton // access to ivars with the "this->" or "self->" 651685c88c5SGreg Clayton GetSymbolContext(eSymbolContextFunction|eSymbolContextBlock); 652685c88c5SGreg Clayton lldb::LanguageType method_language = eLanguageTypeUnknown; 653685c88c5SGreg Clayton bool is_instance_method = false; 654685c88c5SGreg Clayton ConstString method_object_name; 655685c88c5SGreg Clayton if (m_sc.GetFunctionMethodInfo (method_language, is_instance_method, method_object_name)) 656685c88c5SGreg Clayton { 657685c88c5SGreg Clayton if (is_instance_method && method_object_name) 658685c88c5SGreg Clayton { 659685c88c5SGreg Clayton var_sp = variable_list->FindVariable(method_object_name); 660685c88c5SGreg Clayton if (var_sp) 661685c88c5SGreg Clayton { 662685c88c5SGreg Clayton separator_idx = 0; 663685c88c5SGreg Clayton var_path.insert(0, "->"); 664685c88c5SGreg Clayton synthetically_added_instance_object = true; 665685c88c5SGreg Clayton } 666685c88c5SGreg Clayton } 667685c88c5SGreg Clayton } 668685c88c5SGreg Clayton } 669685c88c5SGreg Clayton 67046252398SEnrico Granata if (!var_sp && (options & eExpressionPathOptionsInspectAnonymousUnions)) 67146252398SEnrico Granata { 67246252398SEnrico Granata // Check if any anonymous unions are there which contain a variable with the name we need 67346252398SEnrico Granata for (size_t i = 0; 67446252398SEnrico Granata i < variable_list->GetSize(); 67546252398SEnrico Granata i++) 67646252398SEnrico Granata { 67746252398SEnrico Granata if (VariableSP variable_sp = variable_list->GetVariableAtIndex(i)) 67846252398SEnrico Granata { 67946252398SEnrico Granata if (variable_sp->GetName().IsEmpty()) 68046252398SEnrico Granata { 68146252398SEnrico Granata if (Type *var_type = variable_sp->GetType()) 68246252398SEnrico Granata { 68346252398SEnrico Granata if (var_type->GetForwardCompilerType().IsAnonymousType()) 68446252398SEnrico Granata { 68546252398SEnrico Granata valobj_sp = GetValueObjectForFrameVariable (variable_sp, use_dynamic); 68646252398SEnrico Granata if (!valobj_sp) 68746252398SEnrico Granata return valobj_sp; 68846252398SEnrico Granata valobj_sp = valobj_sp->GetChildMemberWithName(name_const_string, true); 68946252398SEnrico Granata if (valobj_sp) 69046252398SEnrico Granata break; 69146252398SEnrico Granata } 69246252398SEnrico Granata } 69346252398SEnrico Granata } 69446252398SEnrico Granata } 69546252398SEnrico Granata } 69646252398SEnrico Granata } 69746252398SEnrico Granata 69846252398SEnrico Granata if (var_sp && !valobj_sp) 6998b2fe6dcSGreg Clayton { 7002837b766SJim Ingham valobj_sp = GetValueObjectForFrameVariable (var_sp, use_dynamic); 70178a685aaSJim Ingham if (!valobj_sp) 70278a685aaSJim Ingham return valobj_sp; 70346252398SEnrico Granata } 70446252398SEnrico Granata if (valobj_sp) 70546252398SEnrico Granata { 7068b2fe6dcSGreg Clayton // We are dumping at least one child 7078b2fe6dcSGreg Clayton while (separator_idx != std::string::npos) 7088b2fe6dcSGreg Clayton { 7098b2fe6dcSGreg Clayton // Calculate the next separator index ahead of time 7108b2fe6dcSGreg Clayton ValueObjectSP child_valobj_sp; 7118b2fe6dcSGreg Clayton const char separator_type = var_path[0]; 7128b2fe6dcSGreg Clayton switch (separator_type) 7138b2fe6dcSGreg Clayton { 7148b2fe6dcSGreg Clayton case '-': 7158b2fe6dcSGreg Clayton if (var_path.size() >= 2 && var_path[1] != '>') 7168b2fe6dcSGreg Clayton return ValueObjectSP(); 7178b2fe6dcSGreg Clayton 7186d5e68eaSGreg Clayton if (no_fragile_ivar) 7196d5e68eaSGreg Clayton { 7206d5e68eaSGreg Clayton // Make sure we aren't trying to deref an objective 7216d5e68eaSGreg Clayton // C ivar if this is not allowed 722d70a6e71SEugene Zelenko const uint32_t pointer_type_flags = valobj_sp->GetCompilerType().GetTypeInfo(nullptr); 723622be238SEnrico Granata if ((pointer_type_flags & eTypeIsObjC) && 724622be238SEnrico Granata (pointer_type_flags & eTypeIsPointer)) 7256d5e68eaSGreg Clayton { 7266d5e68eaSGreg Clayton // This was an objective C object pointer and 7276d5e68eaSGreg Clayton // it was requested we skip any fragile ivars 7286d5e68eaSGreg Clayton // so return nothing here 7296d5e68eaSGreg Clayton return ValueObjectSP(); 7306d5e68eaSGreg Clayton } 7316d5e68eaSGreg Clayton } 7328b2fe6dcSGreg Clayton var_path.erase (0, 1); // Remove the '-' 73362e0681aSJason Molenda LLVM_FALLTHROUGH; 7348b2fe6dcSGreg Clayton case '.': 7358b2fe6dcSGreg Clayton { 73654979cddSGreg Clayton const bool expr_is_ptr = var_path[0] == '>'; 7378b2fe6dcSGreg Clayton 7388b2fe6dcSGreg Clayton var_path.erase (0, 1); // Remove the '.' or '>' 7398b2fe6dcSGreg Clayton separator_idx = var_path.find_first_of(".-["); 7408b2fe6dcSGreg Clayton ConstString child_name; 7418b2fe6dcSGreg Clayton if (separator_idx == std::string::npos) 7428b2fe6dcSGreg Clayton child_name.SetCString (var_path.c_str()); 7438b2fe6dcSGreg Clayton else 7448b2fe6dcSGreg Clayton child_name.SetCStringWithLength(var_path.c_str(), separator_idx); 7458b2fe6dcSGreg Clayton 74654979cddSGreg Clayton if (check_ptr_vs_member) 74754979cddSGreg Clayton { 74854979cddSGreg Clayton // We either have a pointer type and need to verify 74954979cddSGreg Clayton // valobj_sp is a pointer, or we have a member of a 75054979cddSGreg Clayton // class/union/struct being accessed with the . syntax 75154979cddSGreg Clayton // and need to verify we don't have a pointer. 75254979cddSGreg Clayton const bool actual_is_ptr = valobj_sp->IsPointerType (); 75354979cddSGreg Clayton 75454979cddSGreg Clayton if (actual_is_ptr != expr_is_ptr) 75554979cddSGreg Clayton { 75654979cddSGreg Clayton // Incorrect use of "." with a pointer, or "->" with 75754979cddSGreg Clayton // a class/union/struct instance or reference. 7586beaaa68SGreg Clayton valobj_sp->GetExpressionPath (var_expr_path_strm, false); 75954979cddSGreg Clayton if (actual_is_ptr) 76054979cddSGreg Clayton error.SetErrorStringWithFormat ("\"%s\" is a pointer and . was used to attempt to access \"%s\". Did you mean \"%s->%s\"?", 76154979cddSGreg Clayton var_expr_path_strm.GetString().c_str(), 76254979cddSGreg Clayton child_name.GetCString(), 76354979cddSGreg Clayton var_expr_path_strm.GetString().c_str(), 76454979cddSGreg Clayton var_path.c_str()); 76554979cddSGreg Clayton else 76654979cddSGreg Clayton error.SetErrorStringWithFormat ("\"%s\" is not a pointer and -> was used to attempt to access \"%s\". Did you mean \"%s.%s\"?", 76754979cddSGreg Clayton var_expr_path_strm.GetString().c_str(), 76854979cddSGreg Clayton child_name.GetCString(), 76954979cddSGreg Clayton var_expr_path_strm.GetString().c_str(), 77054979cddSGreg Clayton var_path.c_str()); 77154979cddSGreg Clayton return ValueObjectSP(); 77254979cddSGreg Clayton } 77354979cddSGreg Clayton } 7748b2fe6dcSGreg Clayton child_valobj_sp = valobj_sp->GetChildMemberWithName (child_name, true); 7758b2fe6dcSGreg Clayton if (!child_valobj_sp) 7768b2fe6dcSGreg Clayton { 777d70a6e71SEugene Zelenko if (!no_synth_child) 77886cc9829SEnrico Granata { 77986cc9829SEnrico Granata child_valobj_sp = valobj_sp->GetSyntheticValue(); 78086cc9829SEnrico Granata if (child_valobj_sp) 78186cc9829SEnrico Granata child_valobj_sp = child_valobj_sp->GetChildMemberWithName (child_name, true); 78286cc9829SEnrico Granata } 7838c9d3560SEnrico Granata 7848c9d3560SEnrico Granata if (no_synth_child || !child_valobj_sp) 7858c9d3560SEnrico Granata { 7868b2fe6dcSGreg Clayton // No child member with name "child_name" 787685c88c5SGreg Clayton if (synthetically_added_instance_object) 788685c88c5SGreg Clayton { 789685c88c5SGreg Clayton // We added a "this->" or "self->" to the beginning of the expression 790685c88c5SGreg Clayton // and this is the first pointer ivar access, so just return the normal 791685c88c5SGreg Clayton // error 792685c88c5SGreg Clayton error.SetErrorStringWithFormat("no variable or instance variable named '%s' found in this frame", 793685c88c5SGreg Clayton name_const_string.GetCString()); 794685c88c5SGreg Clayton } 795685c88c5SGreg Clayton else 796685c88c5SGreg Clayton { 7976beaaa68SGreg Clayton valobj_sp->GetExpressionPath (var_expr_path_strm, false); 79854979cddSGreg Clayton if (child_name) 79954979cddSGreg Clayton { 80054979cddSGreg Clayton error.SetErrorStringWithFormat ("\"%s\" is not a member of \"(%s) %s\"", 80154979cddSGreg Clayton child_name.GetCString(), 80254979cddSGreg Clayton valobj_sp->GetTypeName().AsCString("<invalid type>"), 80354979cddSGreg Clayton var_expr_path_strm.GetString().c_str()); 80454979cddSGreg Clayton } 80554979cddSGreg Clayton else 80654979cddSGreg Clayton { 80754979cddSGreg Clayton error.SetErrorStringWithFormat ("incomplete expression path after \"%s\" in \"%s\"", 80854979cddSGreg Clayton var_expr_path_strm.GetString().c_str(), 80954979cddSGreg Clayton var_expr_cstr); 81054979cddSGreg Clayton } 811685c88c5SGreg Clayton } 8128b2fe6dcSGreg Clayton return ValueObjectSP(); 8138b2fe6dcSGreg Clayton } 8148c9d3560SEnrico Granata } 815685c88c5SGreg Clayton synthetically_added_instance_object = false; 8168b2fe6dcSGreg Clayton // Remove the child name from the path 8178b2fe6dcSGreg Clayton var_path.erase(0, child_name.GetLength()); 8184d122c40SGreg Clayton if (use_dynamic != eNoDynamicValues) 81978a685aaSJim Ingham { 8202837b766SJim Ingham ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic)); 82178a685aaSJim Ingham if (dynamic_value_sp) 82278a685aaSJim Ingham child_valobj_sp = dynamic_value_sp; 82378a685aaSJim Ingham } 8248b2fe6dcSGreg Clayton } 8258b2fe6dcSGreg Clayton break; 8268b2fe6dcSGreg Clayton 8278b2fe6dcSGreg Clayton case '[': 8288b2fe6dcSGreg Clayton // Array member access, or treating pointer as an array 8298b2fe6dcSGreg Clayton if (var_path.size() > 2) // Need at least two brackets and a number 8308b2fe6dcSGreg Clayton { 831d70a6e71SEugene Zelenko char *end = nullptr; 8321a65ae11SGreg Clayton long child_index = ::strtol (&var_path[1], &end, 0); 8339fc1944eSEnrico Granata if (end && *end == ']' 8349fc1944eSEnrico Granata && *(end-1) != '[') // this code forces an error in the case of arr[]. as bitfield[] is not a good syntax we're good to go 8358b2fe6dcSGreg Clayton { 83699558cc4SGreg Clayton if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref) 8379fc1944eSEnrico Granata { 8389fc1944eSEnrico Granata // what we have is *ptr[low]. the most similar C++ syntax is to deref ptr 8399fc1944eSEnrico Granata // and extract bit low out of it. reading array item low 8409fc1944eSEnrico Granata // would be done by saying ptr[low], without a deref * sign 8419fc1944eSEnrico Granata Error error; 8429fc1944eSEnrico Granata ValueObjectSP temp(valobj_sp->Dereference(error)); 8439fc1944eSEnrico Granata if (error.Fail()) 8449fc1944eSEnrico Granata { 8459fc1944eSEnrico Granata valobj_sp->GetExpressionPath (var_expr_path_strm, false); 8469fc1944eSEnrico Granata error.SetErrorStringWithFormat ("could not dereference \"(%s) %s\"", 8479fc1944eSEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 8489fc1944eSEnrico Granata var_expr_path_strm.GetString().c_str()); 8499fc1944eSEnrico Granata return ValueObjectSP(); 8509fc1944eSEnrico Granata } 8519fc1944eSEnrico Granata valobj_sp = temp; 8529fc1944eSEnrico Granata deref = false; 8539fc1944eSEnrico Granata } 85499558cc4SGreg Clayton else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() && deref) 8559fc1944eSEnrico Granata { 8569fc1944eSEnrico Granata // what we have is *arr[low]. the most similar C++ syntax is to get arr[0] 8579fc1944eSEnrico Granata // (an operation that is equivalent to deref-ing arr) 8589fc1944eSEnrico Granata // and extract bit low out of it. reading array item low 8599fc1944eSEnrico Granata // would be done by saying arr[low], without a deref * sign 8609fc1944eSEnrico Granata Error error; 8619fc1944eSEnrico Granata ValueObjectSP temp(valobj_sp->GetChildAtIndex (0, true)); 8629fc1944eSEnrico Granata if (error.Fail()) 8639fc1944eSEnrico Granata { 8649fc1944eSEnrico Granata valobj_sp->GetExpressionPath (var_expr_path_strm, false); 8659fc1944eSEnrico Granata error.SetErrorStringWithFormat ("could not get item 0 for \"(%s) %s\"", 8669fc1944eSEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 8679fc1944eSEnrico Granata var_expr_path_strm.GetString().c_str()); 8689fc1944eSEnrico Granata return ValueObjectSP(); 8699fc1944eSEnrico Granata } 8709fc1944eSEnrico Granata valobj_sp = temp; 8719fc1944eSEnrico Granata deref = false; 8729fc1944eSEnrico Granata } 8738b2fe6dcSGreg Clayton 8744ef877f5SGreg Clayton bool is_incomplete_array = false; 8758b2fe6dcSGreg Clayton if (valobj_sp->IsPointerType ()) 8768b2fe6dcSGreg Clayton { 877226b70c1SSean Callanan bool is_objc_pointer = true; 878226b70c1SSean Callanan 87999558cc4SGreg Clayton if (valobj_sp->GetCompilerType().GetMinimumLanguage() != eLanguageTypeObjC) 880226b70c1SSean Callanan is_objc_pointer = false; 88199558cc4SGreg Clayton else if (!valobj_sp->GetCompilerType().IsPointerType()) 882226b70c1SSean Callanan is_objc_pointer = false; 883226b70c1SSean Callanan 884226b70c1SSean Callanan if (no_synth_child && is_objc_pointer) 885226b70c1SSean Callanan { 886226b70c1SSean Callanan error.SetErrorStringWithFormat("\"(%s) %s\" is an Objective-C pointer, and cannot be subscripted", 887226b70c1SSean Callanan valobj_sp->GetTypeName().AsCString("<invalid type>"), 888226b70c1SSean Callanan var_expr_path_strm.GetString().c_str()); 889226b70c1SSean Callanan 890226b70c1SSean Callanan return ValueObjectSP(); 891226b70c1SSean Callanan } 892226b70c1SSean Callanan else if (is_objc_pointer) 89327b625e1SEnrico Granata { 89427b625e1SEnrico Granata // dereferencing ObjC variables is not valid.. so let's try and recur to synthetic children 89586cc9829SEnrico Granata ValueObjectSP synthetic = valobj_sp->GetSyntheticValue(); 896d70a6e71SEugene Zelenko if (!synthetic /* no synthetic */ 89727b625e1SEnrico Granata || synthetic == valobj_sp) /* synthetic is the same as the original object */ 89827b625e1SEnrico Granata { 89927b625e1SEnrico Granata valobj_sp->GetExpressionPath (var_expr_path_strm, false); 90027b625e1SEnrico Granata error.SetErrorStringWithFormat ("\"(%s) %s\" is not an array type", 90127b625e1SEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 90227b625e1SEnrico Granata var_expr_path_strm.GetString().c_str()); 90327b625e1SEnrico Granata } 9043985c8c6SSaleem Abdulrasool else if (static_cast<uint32_t>(child_index) >= synthetic->GetNumChildren() /* synthetic does not have that many values */) 90527b625e1SEnrico Granata { 90627b625e1SEnrico Granata valobj_sp->GetExpressionPath (var_expr_path_strm, false); 9077e589a60SJason Molenda error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 90827b625e1SEnrico Granata child_index, 90927b625e1SEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 91027b625e1SEnrico Granata var_expr_path_strm.GetString().c_str()); 91127b625e1SEnrico Granata } 91227b625e1SEnrico Granata else 91327b625e1SEnrico Granata { 91427b625e1SEnrico Granata child_valobj_sp = synthetic->GetChildAtIndex(child_index, true); 91527b625e1SEnrico Granata if (!child_valobj_sp) 91627b625e1SEnrico Granata { 91727b625e1SEnrico Granata valobj_sp->GetExpressionPath (var_expr_path_strm, false); 9187e589a60SJason Molenda error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 91927b625e1SEnrico Granata child_index, 92027b625e1SEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 92127b625e1SEnrico Granata var_expr_path_strm.GetString().c_str()); 92227b625e1SEnrico Granata } 92327b625e1SEnrico Granata } 92427b625e1SEnrico Granata } 92527b625e1SEnrico Granata else 92627b625e1SEnrico Granata { 92711d86362SBruce Mitchener child_valobj_sp = valobj_sp->GetSyntheticArrayMember (child_index, true); 92854979cddSGreg Clayton if (!child_valobj_sp) 92954979cddSGreg Clayton { 9306beaaa68SGreg Clayton valobj_sp->GetExpressionPath (var_expr_path_strm, false); 9317e589a60SJason Molenda error.SetErrorStringWithFormat ("failed to use pointer as array for index %ld for \"(%s) %s\"", 93254979cddSGreg Clayton child_index, 93354979cddSGreg Clayton valobj_sp->GetTypeName().AsCString("<invalid type>"), 93454979cddSGreg Clayton var_expr_path_strm.GetString().c_str()); 93554979cddSGreg Clayton } 93654979cddSGreg Clayton } 93727b625e1SEnrico Granata } 938d70a6e71SEugene Zelenko else if (valobj_sp->GetCompilerType().IsArrayType(nullptr, nullptr, &is_incomplete_array)) 93954979cddSGreg Clayton { 94078a685aaSJim Ingham // Pass false to dynamic_value here so we can tell the difference between 94178a685aaSJim Ingham // no dynamic value and no member of this type... 94254979cddSGreg Clayton child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true); 943d70a6e71SEugene Zelenko if (!child_valobj_sp && (is_incomplete_array || !no_synth_child)) 9444ef877f5SGreg Clayton child_valobj_sp = valobj_sp->GetSyntheticArrayMember (child_index, true); 9454ef877f5SGreg Clayton 94654979cddSGreg Clayton if (!child_valobj_sp) 94754979cddSGreg Clayton { 9486beaaa68SGreg Clayton valobj_sp->GetExpressionPath (var_expr_path_strm, false); 9497e589a60SJason Molenda error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 95054979cddSGreg Clayton child_index, 95154979cddSGreg Clayton valobj_sp->GetTypeName().AsCString("<invalid type>"), 95254979cddSGreg Clayton var_expr_path_strm.GetString().c_str()); 95354979cddSGreg Clayton } 9548b2fe6dcSGreg Clayton } 95599558cc4SGreg Clayton else if (valobj_sp->GetCompilerType().IsScalarType()) 9569fc1944eSEnrico Granata { 9579fc1944eSEnrico Granata // this is a bitfield asking to display just one bit 9589fc1944eSEnrico Granata child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(child_index, child_index, true); 9599fc1944eSEnrico Granata if (!child_valobj_sp) 9609fc1944eSEnrico Granata { 9619fc1944eSEnrico Granata valobj_sp->GetExpressionPath (var_expr_path_strm, false); 9627e589a60SJason Molenda error.SetErrorStringWithFormat ("bitfield range %ld-%ld is not valid for \"(%s) %s\"", 9639fc1944eSEnrico Granata child_index, child_index, 9649fc1944eSEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 9659fc1944eSEnrico Granata var_expr_path_strm.GetString().c_str()); 9669fc1944eSEnrico Granata } 9679fc1944eSEnrico Granata } 9688b2fe6dcSGreg Clayton else 9698b2fe6dcSGreg Clayton { 97086cc9829SEnrico Granata ValueObjectSP synthetic = valobj_sp->GetSyntheticValue(); 97127b625e1SEnrico Granata if (no_synth_child /* synthetic is forbidden */ || 972d70a6e71SEugene Zelenko !synthetic /* no synthetic */ 97327b625e1SEnrico Granata || synthetic == valobj_sp) /* synthetic is the same as the original object */ 97427b625e1SEnrico Granata { 9756beaaa68SGreg Clayton valobj_sp->GetExpressionPath (var_expr_path_strm, false); 97654979cddSGreg Clayton error.SetErrorStringWithFormat ("\"(%s) %s\" is not an array type", 97754979cddSGreg Clayton valobj_sp->GetTypeName().AsCString("<invalid type>"), 97854979cddSGreg Clayton var_expr_path_strm.GetString().c_str()); 9798b2fe6dcSGreg Clayton } 9803985c8c6SSaleem Abdulrasool else if (static_cast<uint32_t>(child_index) >= synthetic->GetNumChildren() /* synthetic does not have that many values */) 98127b625e1SEnrico Granata { 98227b625e1SEnrico Granata valobj_sp->GetExpressionPath (var_expr_path_strm, false); 9837e589a60SJason Molenda error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 98427b625e1SEnrico Granata child_index, 98527b625e1SEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 98627b625e1SEnrico Granata var_expr_path_strm.GetString().c_str()); 98727b625e1SEnrico Granata } 98827b625e1SEnrico Granata else 98927b625e1SEnrico Granata { 99027b625e1SEnrico Granata child_valobj_sp = synthetic->GetChildAtIndex(child_index, true); 99127b625e1SEnrico Granata if (!child_valobj_sp) 99227b625e1SEnrico Granata { 99327b625e1SEnrico Granata valobj_sp->GetExpressionPath (var_expr_path_strm, false); 9947e589a60SJason Molenda error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 99527b625e1SEnrico Granata child_index, 99627b625e1SEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 99727b625e1SEnrico Granata var_expr_path_strm.GetString().c_str()); 99827b625e1SEnrico Granata } 99927b625e1SEnrico Granata } 100027b625e1SEnrico Granata } 10018b2fe6dcSGreg Clayton 10028b2fe6dcSGreg Clayton if (!child_valobj_sp) 10038b2fe6dcSGreg Clayton { 10048b2fe6dcSGreg Clayton // Invalid array index... 10058b2fe6dcSGreg Clayton return ValueObjectSP(); 10068b2fe6dcSGreg Clayton } 10078b2fe6dcSGreg Clayton 10088b2fe6dcSGreg Clayton // Erase the array member specification '[%i]' where 10098b2fe6dcSGreg Clayton // %i is the array index 10108b2fe6dcSGreg Clayton var_path.erase(0, (end - var_path.c_str()) + 1); 10118b2fe6dcSGreg Clayton separator_idx = var_path.find_first_of(".-["); 10124d122c40SGreg Clayton if (use_dynamic != eNoDynamicValues) 101378a685aaSJim Ingham { 10142837b766SJim Ingham ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic)); 101578a685aaSJim Ingham if (dynamic_value_sp) 101678a685aaSJim Ingham child_valobj_sp = dynamic_value_sp; 101778a685aaSJim Ingham } 10188b2fe6dcSGreg Clayton // Break out early from the switch since we were 10198b2fe6dcSGreg Clayton // able to find the child member 10208b2fe6dcSGreg Clayton break; 10218b2fe6dcSGreg Clayton } 10229fc1944eSEnrico Granata else if (end && *end == '-') 10239fc1944eSEnrico Granata { 10249fc1944eSEnrico Granata // this is most probably a BitField, let's take a look 1025d70a6e71SEugene Zelenko char *real_end = nullptr; 10269fc1944eSEnrico Granata long final_index = ::strtol (end+1, &real_end, 0); 1027d64d0bc0SEnrico Granata bool expand_bitfield = true; 10289fc1944eSEnrico Granata if (real_end && *real_end == ']') 10299fc1944eSEnrico Granata { 10309fc1944eSEnrico Granata // if the format given is [high-low], swap range 10319fc1944eSEnrico Granata if (child_index > final_index) 10329fc1944eSEnrico Granata { 10339fc1944eSEnrico Granata long temp = child_index; 10349fc1944eSEnrico Granata child_index = final_index; 10359fc1944eSEnrico Granata final_index = temp; 10369fc1944eSEnrico Granata } 10379fc1944eSEnrico Granata 103899558cc4SGreg Clayton if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref) 10399fc1944eSEnrico Granata { 10409fc1944eSEnrico Granata // what we have is *ptr[low-high]. the most similar C++ syntax is to deref ptr 10419fc1944eSEnrico Granata // and extract bits low thru high out of it. reading array items low thru high 10429fc1944eSEnrico Granata // would be done by saying ptr[low-high], without a deref * sign 10439fc1944eSEnrico Granata Error error; 10449fc1944eSEnrico Granata ValueObjectSP temp(valobj_sp->Dereference(error)); 10459fc1944eSEnrico Granata if (error.Fail()) 10469fc1944eSEnrico Granata { 10479fc1944eSEnrico Granata valobj_sp->GetExpressionPath (var_expr_path_strm, false); 10489fc1944eSEnrico Granata error.SetErrorStringWithFormat ("could not dereference \"(%s) %s\"", 10499fc1944eSEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 10509fc1944eSEnrico Granata var_expr_path_strm.GetString().c_str()); 10519fc1944eSEnrico Granata return ValueObjectSP(); 10529fc1944eSEnrico Granata } 10539fc1944eSEnrico Granata valobj_sp = temp; 10549fc1944eSEnrico Granata deref = false; 10559fc1944eSEnrico Granata } 105699558cc4SGreg Clayton else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() && deref) 10579fc1944eSEnrico Granata { 10589fc1944eSEnrico Granata // what we have is *arr[low-high]. the most similar C++ syntax is to get arr[0] 10599fc1944eSEnrico Granata // (an operation that is equivalent to deref-ing arr) 10609fc1944eSEnrico Granata // and extract bits low thru high out of it. reading array items low thru high 10619fc1944eSEnrico Granata // would be done by saying arr[low-high], without a deref * sign 10629fc1944eSEnrico Granata Error error; 10639fc1944eSEnrico Granata ValueObjectSP temp(valobj_sp->GetChildAtIndex (0, true)); 10649fc1944eSEnrico Granata if (error.Fail()) 10659fc1944eSEnrico Granata { 10669fc1944eSEnrico Granata valobj_sp->GetExpressionPath (var_expr_path_strm, false); 10679fc1944eSEnrico Granata error.SetErrorStringWithFormat ("could not get item 0 for \"(%s) %s\"", 10689fc1944eSEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 10699fc1944eSEnrico Granata var_expr_path_strm.GetString().c_str()); 10709fc1944eSEnrico Granata return ValueObjectSP(); 10719fc1944eSEnrico Granata } 10729fc1944eSEnrico Granata valobj_sp = temp; 10739fc1944eSEnrico Granata deref = false; 10749fc1944eSEnrico Granata } 1075d64d0bc0SEnrico Granata /*else if (valobj_sp->IsArrayType() || valobj_sp->IsPointerType()) 1076d64d0bc0SEnrico Granata { 1077d64d0bc0SEnrico Granata child_valobj_sp = valobj_sp->GetSyntheticArrayRangeChild(child_index, final_index, true); 1078d64d0bc0SEnrico Granata expand_bitfield = false; 1079d64d0bc0SEnrico Granata if (!child_valobj_sp) 1080d64d0bc0SEnrico Granata { 1081d64d0bc0SEnrico Granata valobj_sp->GetExpressionPath (var_expr_path_strm, false); 1082d64d0bc0SEnrico Granata error.SetErrorStringWithFormat ("array range %i-%i is not valid for \"(%s) %s\"", 1083d64d0bc0SEnrico Granata child_index, final_index, 1084d64d0bc0SEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 1085d64d0bc0SEnrico Granata var_expr_path_strm.GetString().c_str()); 1086d64d0bc0SEnrico Granata } 1087d64d0bc0SEnrico Granata }*/ 10889fc1944eSEnrico Granata 1089d64d0bc0SEnrico Granata if (expand_bitfield) 1090d64d0bc0SEnrico Granata { 10919fc1944eSEnrico Granata child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(child_index, final_index, true); 10929fc1944eSEnrico Granata if (!child_valobj_sp) 10939fc1944eSEnrico Granata { 10949fc1944eSEnrico Granata valobj_sp->GetExpressionPath (var_expr_path_strm, false); 10957e589a60SJason Molenda error.SetErrorStringWithFormat ("bitfield range %ld-%ld is not valid for \"(%s) %s\"", 10969fc1944eSEnrico Granata child_index, final_index, 10979fc1944eSEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 10989fc1944eSEnrico Granata var_expr_path_strm.GetString().c_str()); 10999fc1944eSEnrico Granata } 11009fc1944eSEnrico Granata } 1101d64d0bc0SEnrico Granata } 11029fc1944eSEnrico Granata 11039fc1944eSEnrico Granata if (!child_valobj_sp) 11049fc1944eSEnrico Granata { 11059fc1944eSEnrico Granata // Invalid bitfield range... 11069fc1944eSEnrico Granata return ValueObjectSP(); 11079fc1944eSEnrico Granata } 11089fc1944eSEnrico Granata 11099fc1944eSEnrico Granata // Erase the bitfield member specification '[%i-%i]' where 11109fc1944eSEnrico Granata // %i is the index 11119fc1944eSEnrico Granata var_path.erase(0, (real_end - var_path.c_str()) + 1); 11129fc1944eSEnrico Granata separator_idx = var_path.find_first_of(".-["); 11134d122c40SGreg Clayton if (use_dynamic != eNoDynamicValues) 11149fc1944eSEnrico Granata { 11159fc1944eSEnrico Granata ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic)); 11169fc1944eSEnrico Granata if (dynamic_value_sp) 11179fc1944eSEnrico Granata child_valobj_sp = dynamic_value_sp; 11189fc1944eSEnrico Granata } 11199fc1944eSEnrico Granata // Break out early from the switch since we were 11209fc1944eSEnrico Granata // able to find the child member 11219fc1944eSEnrico Granata break; 11229fc1944eSEnrico Granata 11239fc1944eSEnrico Granata } 11249fc1944eSEnrico Granata } 11259fc1944eSEnrico Granata else 11269fc1944eSEnrico Granata { 11279fc1944eSEnrico Granata error.SetErrorStringWithFormat("invalid square bracket encountered after \"%s\" in \"%s\"", 11289fc1944eSEnrico Granata var_expr_path_strm.GetString().c_str(), 11299fc1944eSEnrico Granata var_path.c_str()); 11308b2fe6dcSGreg Clayton } 11318b2fe6dcSGreg Clayton return ValueObjectSP(); 11328b2fe6dcSGreg Clayton 11338b2fe6dcSGreg Clayton default: 11348b2fe6dcSGreg Clayton // Failure... 113554979cddSGreg Clayton { 11366beaaa68SGreg Clayton valobj_sp->GetExpressionPath (var_expr_path_strm, false); 113754979cddSGreg Clayton error.SetErrorStringWithFormat ("unexpected char '%c' encountered after \"%s\" in \"%s\"", 113854979cddSGreg Clayton separator_type, 113954979cddSGreg Clayton var_expr_path_strm.GetString().c_str(), 114054979cddSGreg Clayton var_path.c_str()); 114154979cddSGreg Clayton 11428b2fe6dcSGreg Clayton return ValueObjectSP(); 11438b2fe6dcSGreg Clayton } 114454979cddSGreg Clayton } 11458b2fe6dcSGreg Clayton 11468b2fe6dcSGreg Clayton if (child_valobj_sp) 11478b2fe6dcSGreg Clayton valobj_sp = child_valobj_sp; 11488b2fe6dcSGreg Clayton 11498b2fe6dcSGreg Clayton if (var_path.empty()) 11508b2fe6dcSGreg Clayton break; 11518b2fe6dcSGreg Clayton } 11528b2fe6dcSGreg Clayton if (valobj_sp) 11538b2fe6dcSGreg Clayton { 11548b2fe6dcSGreg Clayton if (deref) 11558b2fe6dcSGreg Clayton { 1156af67cecdSGreg Clayton ValueObjectSP deref_valobj_sp (valobj_sp->Dereference(error)); 11578b2fe6dcSGreg Clayton valobj_sp = deref_valobj_sp; 11588b2fe6dcSGreg Clayton } 11598b2fe6dcSGreg Clayton else if (address_of) 11608b2fe6dcSGreg Clayton { 116154979cddSGreg Clayton ValueObjectSP address_of_valobj_sp (valobj_sp->AddressOf(error)); 11628b2fe6dcSGreg Clayton valobj_sp = address_of_valobj_sp; 11638b2fe6dcSGreg Clayton } 11648b2fe6dcSGreg Clayton } 11658b2fe6dcSGreg Clayton return valobj_sp; 11668b2fe6dcSGreg Clayton } 116754979cddSGreg Clayton else 116854979cddSGreg Clayton { 11692837b766SJim Ingham error.SetErrorStringWithFormat("no variable named '%s' found in this frame", 11702837b766SJim Ingham name_const_string.GetCString()); 117154979cddSGreg Clayton } 117254979cddSGreg Clayton } 117354979cddSGreg Clayton } 117454979cddSGreg Clayton else 117554979cddSGreg Clayton { 117654979cddSGreg Clayton error.SetErrorStringWithFormat("invalid variable path '%s'", var_expr_cstr); 11778b2fe6dcSGreg Clayton } 11788b2fe6dcSGreg Clayton return ValueObjectSP(); 11798b2fe6dcSGreg Clayton } 118030fdc8d8SChris Lattner 118130fdc8d8SChris Lattner bool 118230fdc8d8SChris Lattner StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr) 118330fdc8d8SChris Lattner { 1184*bb19a13cSSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex); 1185d70a6e71SEugene Zelenko if (!m_cfa_is_valid) 118699618476SJason Molenda { 118799618476SJason Molenda m_frame_base_error.SetErrorString("No frame base available for this historical stack frame."); 118899618476SJason Molenda return false; 118999618476SJason Molenda } 119099618476SJason Molenda 119130fdc8d8SChris Lattner if (m_flags.IsClear(GOT_FRAME_BASE)) 119230fdc8d8SChris Lattner { 119330fdc8d8SChris Lattner if (m_sc.function) 119430fdc8d8SChris Lattner { 119530fdc8d8SChris Lattner m_frame_base.Clear(); 119630fdc8d8SChris Lattner m_frame_base_error.Clear(); 119730fdc8d8SChris Lattner 119830fdc8d8SChris Lattner m_flags.Set(GOT_FRAME_BASE); 1199d9e416c0SGreg Clayton ExecutionContext exe_ctx (shared_from_this()); 120030fdc8d8SChris Lattner Value expr_value; 1201016a95ebSGreg Clayton addr_t loclist_base_addr = LLDB_INVALID_ADDRESS; 1202016a95ebSGreg Clayton if (m_sc.function->GetFrameBaseExpression().IsLocationList()) 1203d9e416c0SGreg Clayton loclist_base_addr = m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.GetTargetPtr()); 1204016a95ebSGreg Clayton 12055b42c7aaSTamas Berghammer if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, 12065b42c7aaSTamas Berghammer nullptr, 12075b42c7aaSTamas Berghammer nullptr, 12085b42c7aaSTamas Berghammer nullptr, 12095b42c7aaSTamas Berghammer loclist_base_addr, 12105b42c7aaSTamas Berghammer nullptr, 12115b42c7aaSTamas Berghammer nullptr, 12125b42c7aaSTamas Berghammer expr_value, 12135b42c7aaSTamas Berghammer &m_frame_base_error) == false) 121430fdc8d8SChris Lattner { 121530fdc8d8SChris Lattner // We should really have an error if evaluate returns, but in case 121630fdc8d8SChris Lattner // we don't, lets set the error to something at least. 121730fdc8d8SChris Lattner if (m_frame_base_error.Success()) 121830fdc8d8SChris Lattner m_frame_base_error.SetErrorString("Evaluation of the frame base expression failed."); 121930fdc8d8SChris Lattner } 122030fdc8d8SChris Lattner else 122130fdc8d8SChris Lattner { 122257ee3067SGreg Clayton m_frame_base = expr_value.ResolveValue(&exe_ctx); 122330fdc8d8SChris Lattner } 122430fdc8d8SChris Lattner } 122530fdc8d8SChris Lattner else 122630fdc8d8SChris Lattner { 122730fdc8d8SChris Lattner m_frame_base_error.SetErrorString ("No function in symbol context."); 122830fdc8d8SChris Lattner } 122930fdc8d8SChris Lattner } 123030fdc8d8SChris Lattner 123130fdc8d8SChris Lattner if (m_frame_base_error.Success()) 123230fdc8d8SChris Lattner frame_base = m_frame_base; 123330fdc8d8SChris Lattner 123430fdc8d8SChris Lattner if (error_ptr) 123530fdc8d8SChris Lattner *error_ptr = m_frame_base_error; 123630fdc8d8SChris Lattner return m_frame_base_error.Success(); 123730fdc8d8SChris Lattner } 123830fdc8d8SChris Lattner 12395ccbd294SGreg Clayton RegisterContextSP 124030fdc8d8SChris Lattner StackFrame::GetRegisterContext () 124130fdc8d8SChris Lattner { 1242*bb19a13cSSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex); 12435ccbd294SGreg Clayton if (!m_reg_context_sp) 1244d9e416c0SGreg Clayton { 1245d9e416c0SGreg Clayton ThreadSP thread_sp (GetThread()); 1246d9e416c0SGreg Clayton if (thread_sp) 1247d9e416c0SGreg Clayton m_reg_context_sp = thread_sp->CreateRegisterContextForFrame (this); 1248d9e416c0SGreg Clayton } 12495ccbd294SGreg Clayton return m_reg_context_sp; 125030fdc8d8SChris Lattner } 125130fdc8d8SChris Lattner 125230fdc8d8SChris Lattner bool 125330fdc8d8SChris Lattner StackFrame::HasDebugInformation () 125430fdc8d8SChris Lattner { 125530fdc8d8SChris Lattner GetSymbolContext (eSymbolContextLineEntry); 125630fdc8d8SChris Lattner return m_sc.line_entry.IsValid(); 125730fdc8d8SChris Lattner } 125830fdc8d8SChris Lattner 1259288bdf9cSGreg Clayton ValueObjectSP 12604d122c40SGreg Clayton StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic) 126130fdc8d8SChris Lattner { 1262*bb19a13cSSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex); 1263288bdf9cSGreg Clayton ValueObjectSP valobj_sp; 126499618476SJason Molenda if (m_is_history_frame) 126599618476SJason Molenda { 126699618476SJason Molenda return valobj_sp; 126799618476SJason Molenda } 1268288bdf9cSGreg Clayton VariableList *var_list = GetVariableList (true); 1269288bdf9cSGreg Clayton if (var_list) 1270288bdf9cSGreg Clayton { 1271288bdf9cSGreg Clayton // Make sure the variable is a frame variable 1272288bdf9cSGreg Clayton const uint32_t var_idx = var_list->FindIndexForVariable (variable_sp.get()); 1273288bdf9cSGreg Clayton const uint32_t num_variables = var_list->GetSize(); 1274288bdf9cSGreg Clayton if (var_idx < num_variables) 1275288bdf9cSGreg Clayton { 1276288bdf9cSGreg Clayton valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex (var_idx); 1277d70a6e71SEugene Zelenko if (!valobj_sp) 1278288bdf9cSGreg Clayton { 1279288bdf9cSGreg Clayton if (m_variable_list_value_objects.GetSize() < num_variables) 1280288bdf9cSGreg Clayton m_variable_list_value_objects.Resize(num_variables); 128158b59f95SJim Ingham valobj_sp = ValueObjectVariable::Create (this, variable_sp); 1282288bdf9cSGreg Clayton m_variable_list_value_objects.SetValueObjectAtIndex (var_idx, valobj_sp); 1283288bdf9cSGreg Clayton } 1284288bdf9cSGreg Clayton } 1285288bdf9cSGreg Clayton } 12864d122c40SGreg Clayton if (use_dynamic != eNoDynamicValues && valobj_sp) 128778a685aaSJim Ingham { 12882837b766SJim Ingham ValueObjectSP dynamic_sp = valobj_sp->GetDynamicValue (use_dynamic); 128978a685aaSJim Ingham if (dynamic_sp) 129078a685aaSJim Ingham return dynamic_sp; 129178a685aaSJim Ingham } 1292288bdf9cSGreg Clayton return valobj_sp; 1293288bdf9cSGreg Clayton } 1294288bdf9cSGreg Clayton 1295288bdf9cSGreg Clayton ValueObjectSP 12964d122c40SGreg Clayton StackFrame::TrackGlobalVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic) 1297288bdf9cSGreg Clayton { 1298*bb19a13cSSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex); 129999618476SJason Molenda if (m_is_history_frame) 130099618476SJason Molenda return ValueObjectSP(); 130199618476SJason Molenda 1302288bdf9cSGreg Clayton // Check to make sure we aren't already tracking this variable? 130378a685aaSJim Ingham ValueObjectSP valobj_sp (GetValueObjectForFrameVariable (variable_sp, use_dynamic)); 1304288bdf9cSGreg Clayton if (!valobj_sp) 1305288bdf9cSGreg Clayton { 1306288bdf9cSGreg Clayton // We aren't already tracking this global 1307288bdf9cSGreg Clayton VariableList *var_list = GetVariableList (true); 1308288bdf9cSGreg Clayton // If this frame has no variables, create a new list 1309d70a6e71SEugene Zelenko if (var_list == nullptr) 1310288bdf9cSGreg Clayton m_variable_list_sp.reset (new VariableList()); 1311288bdf9cSGreg Clayton 1312288bdf9cSGreg Clayton // Add the global/static variable to this frame 1313288bdf9cSGreg Clayton m_variable_list_sp->AddVariable (variable_sp); 1314288bdf9cSGreg Clayton 1315288bdf9cSGreg Clayton // Now make a value object for it so we can track its changes 131678a685aaSJim Ingham valobj_sp = GetValueObjectForFrameVariable (variable_sp, use_dynamic); 1317288bdf9cSGreg Clayton } 1318288bdf9cSGreg Clayton return valobj_sp; 131930fdc8d8SChris Lattner } 132030fdc8d8SChris Lattner 13216b8379c4SJim Ingham bool 13226b8379c4SJim Ingham StackFrame::IsInlined () 13236b8379c4SJim Ingham { 1324d70a6e71SEugene Zelenko if (m_sc.block == nullptr) 132559e8fc1cSGreg Clayton GetSymbolContext (eSymbolContextBlock); 132659e8fc1cSGreg Clayton if (m_sc.block) 1327d70a6e71SEugene Zelenko return m_sc.block->GetContainingInlinedBlock() != nullptr; 132859e8fc1cSGreg Clayton return false; 13296b8379c4SJim Ingham } 13306b8379c4SJim Ingham 1331009d110dSDawn Perchik lldb::LanguageType 1332009d110dSDawn Perchik StackFrame::GetLanguage () 1333009d110dSDawn Perchik { 1334009d110dSDawn Perchik CompileUnit *cu = GetSymbolContext(eSymbolContextCompUnit).comp_unit; 1335009d110dSDawn Perchik if (cu) 1336009d110dSDawn Perchik return cu->GetLanguage(); 1337009d110dSDawn Perchik return lldb::eLanguageTypeUnknown; 1338009d110dSDawn Perchik } 1339009d110dSDawn Perchik 1340592afe73SEnrico Granata lldb::LanguageType 1341592afe73SEnrico Granata StackFrame::GuessLanguage () 1342592afe73SEnrico Granata { 1343592afe73SEnrico Granata LanguageType lang_type = GetLanguage(); 1344592afe73SEnrico Granata 1345592afe73SEnrico Granata if (lang_type == eLanguageTypeUnknown) 1346592afe73SEnrico Granata { 1347592afe73SEnrico Granata Function *f = GetSymbolContext(eSymbolContextFunction).function; 1348592afe73SEnrico Granata if (f) 1349592afe73SEnrico Granata { 1350592afe73SEnrico Granata lang_type = f->GetMangled().GuessLanguage(); 1351592afe73SEnrico Granata } 1352592afe73SEnrico Granata } 1353592afe73SEnrico Granata 1354592afe73SEnrico Granata return lang_type; 1355592afe73SEnrico Granata } 1356592afe73SEnrico Granata 1357d9e416c0SGreg Clayton TargetSP 135830fdc8d8SChris Lattner StackFrame::CalculateTarget () 135930fdc8d8SChris Lattner { 1360d9e416c0SGreg Clayton TargetSP target_sp; 1361d9e416c0SGreg Clayton ThreadSP thread_sp(GetThread()); 1362d9e416c0SGreg Clayton if (thread_sp) 1363d9e416c0SGreg Clayton { 1364d9e416c0SGreg Clayton ProcessSP process_sp (thread_sp->CalculateProcess()); 1365d9e416c0SGreg Clayton if (process_sp) 1366d9e416c0SGreg Clayton target_sp = process_sp->CalculateTarget(); 1367d9e416c0SGreg Clayton } 1368d9e416c0SGreg Clayton return target_sp; 136930fdc8d8SChris Lattner } 137030fdc8d8SChris Lattner 1371d9e416c0SGreg Clayton ProcessSP 137230fdc8d8SChris Lattner StackFrame::CalculateProcess () 137330fdc8d8SChris Lattner { 1374d9e416c0SGreg Clayton ProcessSP process_sp; 1375d9e416c0SGreg Clayton ThreadSP thread_sp(GetThread()); 1376d9e416c0SGreg Clayton if (thread_sp) 1377d9e416c0SGreg Clayton process_sp = thread_sp->CalculateProcess(); 1378d9e416c0SGreg Clayton return process_sp; 137930fdc8d8SChris Lattner } 138030fdc8d8SChris Lattner 1381d9e416c0SGreg Clayton ThreadSP 138230fdc8d8SChris Lattner StackFrame::CalculateThread () 138330fdc8d8SChris Lattner { 1384d9e416c0SGreg Clayton return GetThread(); 138530fdc8d8SChris Lattner } 138630fdc8d8SChris Lattner 1387b57e4a1bSJason Molenda StackFrameSP 1388b57e4a1bSJason Molenda StackFrame::CalculateStackFrame () 138930fdc8d8SChris Lattner { 1390d9e416c0SGreg Clayton return shared_from_this(); 139130fdc8d8SChris Lattner } 139230fdc8d8SChris Lattner 139330fdc8d8SChris Lattner void 13940603aa9dSGreg Clayton StackFrame::CalculateExecutionContext (ExecutionContext &exe_ctx) 139530fdc8d8SChris Lattner { 1396d9e416c0SGreg Clayton exe_ctx.SetContext (shared_from_this()); 139730fdc8d8SChris Lattner } 139830fdc8d8SChris Lattner 139930fdc8d8SChris Lattner void 14008ec10efcSJim Ingham StackFrame::DumpUsingSettingsFormat (Stream *strm, const char *frame_marker) 14010603aa9dSGreg Clayton { 1402d70a6e71SEugene Zelenko if (strm == nullptr) 14030603aa9dSGreg Clayton return; 14040603aa9dSGreg Clayton 14050603aa9dSGreg Clayton GetSymbolContext(eSymbolContextEverything); 1406d9e416c0SGreg Clayton ExecutionContext exe_ctx (shared_from_this()); 14070603aa9dSGreg Clayton StreamString s; 14088ec10efcSJim Ingham 14098ec10efcSJim Ingham if (frame_marker) 14108ec10efcSJim Ingham s.PutCString(frame_marker); 14118ec10efcSJim Ingham 1412d70a6e71SEugene Zelenko const FormatEntity::Entry *frame_format = nullptr; 1413d9e416c0SGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 1414d9e416c0SGreg Clayton if (target) 1415d9e416c0SGreg Clayton frame_format = target->GetDebugger().GetFrameFormat(); 1416d70a6e71SEugene Zelenko if (frame_format && FormatEntity::Format(*frame_format, s, &m_sc, &exe_ctx, nullptr, nullptr, false, false)) 14170603aa9dSGreg Clayton { 14180603aa9dSGreg Clayton strm->Write(s.GetData(), s.GetSize()); 14190603aa9dSGreg Clayton } 14200603aa9dSGreg Clayton else 14210603aa9dSGreg Clayton { 14220603aa9dSGreg Clayton Dump (strm, true, false); 14230603aa9dSGreg Clayton strm->EOL(); 14240603aa9dSGreg Clayton } 14250603aa9dSGreg Clayton } 14260603aa9dSGreg Clayton 14270603aa9dSGreg Clayton void 14286dadd508SGreg Clayton StackFrame::Dump (Stream *strm, bool show_frame_index, bool show_fullpaths) 142930fdc8d8SChris Lattner { 1430d70a6e71SEugene Zelenko if (strm == nullptr) 143130fdc8d8SChris Lattner return; 143230fdc8d8SChris Lattner 143330fdc8d8SChris Lattner if (show_frame_index) 14341b72fcb7SGreg Clayton strm->Printf("frame #%u: ", m_frame_index); 1435d9e416c0SGreg Clayton ExecutionContext exe_ctx (shared_from_this()); 1436d9e416c0SGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 1437d01b2953SDaniel Malea strm->Printf("0x%0*" PRIx64 " ", 1438d9e416c0SGreg Clayton target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16, 1439d9e416c0SGreg Clayton GetFrameCodeAddress().GetLoadAddress(target)); 14409da7bd07SGreg Clayton GetSymbolContext(eSymbolContextEverything); 14411b72fcb7SGreg Clayton const bool show_module = true; 14421b72fcb7SGreg Clayton const bool show_inline = true; 1443aff1b357SJason Molenda const bool show_function_arguments = true; 1444c980fa92SJason Molenda const bool show_function_name = true; 1445d9e416c0SGreg Clayton m_sc.DumpStopContext (strm, 1446d9e416c0SGreg Clayton exe_ctx.GetBestExecutionContextScope(), 1447d9e416c0SGreg Clayton GetFrameCodeAddress(), 1448d9e416c0SGreg Clayton show_fullpaths, 1449d9e416c0SGreg Clayton show_module, 1450aff1b357SJason Molenda show_inline, 1451c980fa92SJason Molenda show_function_arguments, 1452c980fa92SJason Molenda show_function_name); 145330fdc8d8SChris Lattner } 145430fdc8d8SChris Lattner 14555082c5fdSGreg Clayton void 1456b57e4a1bSJason Molenda StackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame) 14575082c5fdSGreg Clayton { 1458*bb19a13cSSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex); 145959e8fc1cSGreg Clayton assert (GetStackID() == prev_frame.GetStackID()); // TODO: remove this after some testing 1460b57e4a1bSJason Molenda m_variable_list_sp = prev_frame.m_variable_list_sp; 1461b57e4a1bSJason Molenda m_variable_list_value_objects.Swap (prev_frame.m_variable_list_value_objects); 146268275d5eSGreg Clayton if (!m_disassembly.GetString().empty()) 146368275d5eSGreg Clayton m_disassembly.GetString().swap (m_disassembly.GetString()); 14645082c5fdSGreg Clayton } 146568275d5eSGreg Clayton 146659e8fc1cSGreg Clayton void 1467b57e4a1bSJason Molenda StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame) 146859e8fc1cSGreg Clayton { 1469*bb19a13cSSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex); 147059e8fc1cSGreg Clayton assert (GetStackID() == curr_frame.GetStackID()); // TODO: remove this after some testing 1471b57e4a1bSJason Molenda m_id.SetPC (curr_frame.m_id.GetPC()); // Update the Stack ID PC value 1472b57e4a1bSJason Molenda assert (GetThread() == curr_frame.GetThread()); 1473b57e4a1bSJason Molenda m_frame_index = curr_frame.m_frame_index; 1474b57e4a1bSJason Molenda m_concrete_frame_index = curr_frame.m_concrete_frame_index; 1475b57e4a1bSJason Molenda m_reg_context_sp = curr_frame.m_reg_context_sp; 1476b57e4a1bSJason Molenda m_frame_code_addr = curr_frame.m_frame_code_addr; 1477d70a6e71SEugene Zelenko assert (!m_sc.target_sp || !curr_frame.m_sc.target_sp || m_sc.target_sp.get() == curr_frame.m_sc.target_sp.get()); 1478d70a6e71SEugene Zelenko assert (!m_sc.module_sp || !curr_frame.m_sc.module_sp || m_sc.module_sp.get() == curr_frame.m_sc.module_sp.get()); 1479d70a6e71SEugene Zelenko assert (m_sc.comp_unit == nullptr || curr_frame.m_sc.comp_unit == nullptr || m_sc.comp_unit == curr_frame.m_sc.comp_unit); 1480d70a6e71SEugene Zelenko assert (m_sc.function == nullptr || curr_frame.m_sc.function == nullptr || m_sc.function == curr_frame.m_sc.function); 1481b57e4a1bSJason Molenda m_sc = curr_frame.m_sc; 148259e8fc1cSGreg Clayton m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything); 148359e8fc1cSGreg Clayton m_flags.Set (m_sc.GetResolvedMask()); 148459e8fc1cSGreg Clayton m_frame_base.Clear(); 148559e8fc1cSGreg Clayton m_frame_base_error.Clear(); 148659e8fc1cSGreg Clayton } 1487e4284b71SJim Ingham 14887260f620SGreg Clayton bool 1489b57e4a1bSJason Molenda StackFrame::HasCachedData () const 1490b57e4a1bSJason Molenda { 1491d70a6e71SEugene Zelenko if (m_variable_list_sp) 1492b57e4a1bSJason Molenda return true; 1493b57e4a1bSJason Molenda if (m_variable_list_value_objects.GetSize() > 0) 1494b57e4a1bSJason Molenda return true; 1495b57e4a1bSJason Molenda if (!m_disassembly.GetString().empty()) 1496b57e4a1bSJason Molenda return true; 1497b57e4a1bSJason Molenda return false; 1498b57e4a1bSJason Molenda } 1499b57e4a1bSJason Molenda 1500b57e4a1bSJason Molenda bool 15017260f620SGreg Clayton StackFrame::GetStatus (Stream& strm, 15027260f620SGreg Clayton bool show_frame_info, 15038ec10efcSJim Ingham bool show_source, 15048ec10efcSJim Ingham const char *frame_marker) 15057260f620SGreg Clayton { 150653eb7ad2SGreg Clayton 15077260f620SGreg Clayton if (show_frame_info) 15087260f620SGreg Clayton { 15097260f620SGreg Clayton strm.Indent(); 15108ec10efcSJim Ingham DumpUsingSettingsFormat (&strm, frame_marker); 15117260f620SGreg Clayton } 15127260f620SGreg Clayton 15137260f620SGreg Clayton if (show_source) 15147260f620SGreg Clayton { 1515d9e416c0SGreg Clayton ExecutionContext exe_ctx (shared_from_this()); 15168be74995SMohit K. Bhakkad bool have_source = false, have_debuginfo = false; 151767cc0636SGreg Clayton Debugger::StopDisassemblyType disasm_display = Debugger::eStopDisassemblyTypeNever; 1518d9e416c0SGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 151953eb7ad2SGreg Clayton if (target) 152053eb7ad2SGreg Clayton { 152153eb7ad2SGreg Clayton Debugger &debugger = target->GetDebugger(); 152253eb7ad2SGreg Clayton const uint32_t source_lines_before = debugger.GetStopSourceLineCount(true); 152353eb7ad2SGreg Clayton const uint32_t source_lines_after = debugger.GetStopSourceLineCount(false); 152453eb7ad2SGreg Clayton disasm_display = debugger.GetStopDisassemblyDisplay (); 152553eb7ad2SGreg Clayton 15267260f620SGreg Clayton GetSymbolContext(eSymbolContextCompUnit | eSymbolContextLineEntry); 15277260f620SGreg Clayton if (m_sc.comp_unit && m_sc.line_entry.IsValid()) 15287260f620SGreg Clayton { 15298be74995SMohit K. Bhakkad have_debuginfo = true; 15306d1fbc9cSTodd Fiala if (source_lines_before > 0 || source_lines_after > 0) 15316d1fbc9cSTodd Fiala { 15328be74995SMohit K. Bhakkad size_t num_lines = target->GetSourceManager().DisplaySourceLinesWithLineNumbers (m_sc.line_entry.file, 15337260f620SGreg Clayton m_sc.line_entry.line, 1534d9e416c0SGreg Clayton source_lines_before, 1535d9e416c0SGreg Clayton source_lines_after, 15367260f620SGreg Clayton "->", 15377cd81c55SJason Molenda &strm); 15388be74995SMohit K. Bhakkad if (num_lines != 0) 15398be74995SMohit K. Bhakkad have_source = true; 15408be74995SMohit K. Bhakkad // TODO: Give here a one time warning if source file is missing. 1541e372b98dSGreg Clayton } 1542e372b98dSGreg Clayton } 1543e372b98dSGreg Clayton switch (disasm_display) 1544e372b98dSGreg Clayton { 154567cc0636SGreg Clayton case Debugger::eStopDisassemblyTypeNever: 1546e372b98dSGreg Clayton break; 1547e372b98dSGreg Clayton 15488be74995SMohit K. Bhakkad case Debugger::eStopDisassemblyTypeNoDebugInfo: 15498be74995SMohit K. Bhakkad if (have_debuginfo) 15508be74995SMohit K. Bhakkad break; 155162e0681aSJason Molenda LLVM_FALLTHROUGH; 15528be74995SMohit K. Bhakkad 155367cc0636SGreg Clayton case Debugger::eStopDisassemblyTypeNoSource: 1554e372b98dSGreg Clayton if (have_source) 1555e372b98dSGreg Clayton break; 155662e0681aSJason Molenda LLVM_FALLTHROUGH; 15578be74995SMohit K. Bhakkad 155867cc0636SGreg Clayton case Debugger::eStopDisassemblyTypeAlways: 1559d9e416c0SGreg Clayton if (target) 1560e372b98dSGreg Clayton { 156153eb7ad2SGreg Clayton const uint32_t disasm_lines = debugger.GetDisassemblyLineCount(); 1562e372b98dSGreg Clayton if (disasm_lines > 0) 1563e372b98dSGreg Clayton { 1564d9e416c0SGreg Clayton const ArchSpec &target_arch = target->GetArchitecture(); 1565e372b98dSGreg Clayton AddressRange pc_range; 1566e372b98dSGreg Clayton pc_range.GetBaseAddress() = GetFrameCodeAddress(); 1567e372b98dSGreg Clayton pc_range.SetByteSize(disasm_lines * target_arch.GetMaximumOpcodeByteSize()); 1568d70a6e71SEugene Zelenko const char *plugin_name = nullptr; 1569d70a6e71SEugene Zelenko const char *flavor = nullptr; 1570d9e416c0SGreg Clayton Disassembler::Disassemble (target->GetDebugger(), 1571e372b98dSGreg Clayton target_arch, 15720f063ba6SJim Ingham plugin_name, 15730f063ba6SJim Ingham flavor, 1574e372b98dSGreg Clayton exe_ctx, 1575e372b98dSGreg Clayton pc_range, 1576e372b98dSGreg Clayton disasm_lines, 1577e372b98dSGreg Clayton 0, 1578e372b98dSGreg Clayton Disassembler::eOptionMarkPCAddress, 1579e372b98dSGreg Clayton strm); 1580e372b98dSGreg Clayton } 1581e372b98dSGreg Clayton } 1582e372b98dSGreg Clayton break; 15837260f620SGreg Clayton } 15847260f620SGreg Clayton } 158553eb7ad2SGreg Clayton } 15867260f620SGreg Clayton return true; 15877260f620SGreg Clayton } 1588