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" 2154979cddSGreg Clayton #include "lldb/Core/ValueObjectConstResult.h" 224740a734SSean Callanan #include "lldb/Core/ValueObjectMemory.h" 23*b9c1b51eSKate Stone #include "lldb/Core/ValueObjectVariable.h" 241f746071SGreg Clayton #include "lldb/Symbol/CompileUnit.h" 2530fdc8d8SChris Lattner #include "lldb/Symbol/Function.h" 261f746071SGreg Clayton #include "lldb/Symbol/Symbol.h" 271f746071SGreg Clayton #include "lldb/Symbol/SymbolContextScope.h" 2846252398SEnrico Granata #include "lldb/Symbol/Type.h" 29288bdf9cSGreg Clayton #include "lldb/Symbol/VariableList.h" 304740a734SSean Callanan #include "lldb/Target/ABI.h" 3130fdc8d8SChris Lattner #include "lldb/Target/ExecutionContext.h" 3230fdc8d8SChris Lattner #include "lldb/Target/Process.h" 3330fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h" 3430fdc8d8SChris Lattner #include "lldb/Target/Target.h" 3530fdc8d8SChris Lattner #include "lldb/Target/Thread.h" 3630fdc8d8SChris Lattner 3730fdc8d8SChris Lattner using namespace lldb; 3830fdc8d8SChris Lattner using namespace lldb_private; 3930fdc8d8SChris Lattner 4030fdc8d8SChris Lattner // The first bits in the flags are reserved for the SymbolContext::Scope bits 4130fdc8d8SChris Lattner // so we know if we have tried to look up information in our internal symbol 4230fdc8d8SChris Lattner // context (m_sc) already. 4359e8fc1cSGreg Clayton #define RESOLVED_FRAME_CODE_ADDR (uint32_t(eSymbolContextEverything + 1)) 446dadd508SGreg Clayton #define RESOLVED_FRAME_ID_SYMBOL_SCOPE (RESOLVED_FRAME_CODE_ADDR << 1) 4559e8fc1cSGreg Clayton #define GOT_FRAME_BASE (RESOLVED_FRAME_ID_SYMBOL_SCOPE << 1) 4659e8fc1cSGreg Clayton #define RESOLVED_VARIABLES (GOT_FRAME_BASE << 1) 477c0962dcSSean Callanan #define RESOLVED_GLOBAL_VARIABLES (RESOLVED_VARIABLES << 1) 4830fdc8d8SChris Lattner 49*b9c1b51eSKate Stone StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx, 50*b9c1b51eSKate Stone user_id_t unwind_frame_index, addr_t cfa, 51*b9c1b51eSKate Stone bool cfa_is_valid, addr_t pc, uint32_t stop_id, 52*b9c1b51eSKate Stone bool stop_id_is_valid, bool is_history_frame, 53bb19a13cSSaleem Abdulrasool const SymbolContext *sc_ptr) 54*b9c1b51eSKate Stone : m_thread_wp(thread_sp), m_frame_index(frame_idx), 55*b9c1b51eSKate Stone m_concrete_frame_index(unwind_frame_index), m_reg_context_sp(), 56*b9c1b51eSKate Stone m_id(pc, cfa, nullptr), m_frame_code_addr(pc), m_sc(), m_flags(), 57*b9c1b51eSKate Stone m_frame_base(), m_frame_base_error(), m_cfa_is_valid(cfa_is_valid), 58*b9c1b51eSKate Stone m_stop_id(stop_id), m_stop_id_is_valid(stop_id_is_valid), 59*b9c1b51eSKate Stone m_is_history_frame(is_history_frame), m_variable_list_sp(), 60*b9c1b51eSKate Stone m_variable_list_value_objects(), m_disassembly(), m_mutex() { 61*b9c1b51eSKate Stone // If we don't have a CFA value, use the frame index for our StackID so that 62*b9c1b51eSKate Stone // recursive 6399618476SJason Molenda // functions properly aren't confused with one another on a history stack. 64*b9c1b51eSKate Stone if (m_is_history_frame && !m_cfa_is_valid) { 6599618476SJason Molenda m_id.SetCFA(m_frame_index); 6699618476SJason Molenda } 6799618476SJason Molenda 68*b9c1b51eSKate Stone if (sc_ptr != nullptr) { 6930fdc8d8SChris Lattner m_sc = *sc_ptr; 701b72fcb7SGreg Clayton m_flags.Set(m_sc.GetResolvedMask()); 711b72fcb7SGreg Clayton } 7230fdc8d8SChris Lattner } 7330fdc8d8SChris Lattner 74*b9c1b51eSKate Stone StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx, 75*b9c1b51eSKate Stone user_id_t unwind_frame_index, 76*b9c1b51eSKate Stone const RegisterContextSP ®_context_sp, addr_t cfa, 77*b9c1b51eSKate Stone addr_t pc, const SymbolContext *sc_ptr) 78*b9c1b51eSKate Stone : m_thread_wp(thread_sp), m_frame_index(frame_idx), 795ccbd294SGreg Clayton m_concrete_frame_index(unwind_frame_index), 80*b9c1b51eSKate Stone m_reg_context_sp(reg_context_sp), m_id(pc, cfa, nullptr), 81*b9c1b51eSKate Stone m_frame_code_addr(pc), m_sc(), m_flags(), m_frame_base(), 82*b9c1b51eSKate Stone m_frame_base_error(), m_cfa_is_valid(true), m_stop_id(0), 83*b9c1b51eSKate Stone m_stop_id_is_valid(false), m_is_history_frame(false), 84*b9c1b51eSKate Stone m_variable_list_sp(), m_variable_list_value_objects(), m_disassembly(), 85*b9c1b51eSKate Stone m_mutex() { 86*b9c1b51eSKate Stone if (sc_ptr != nullptr) { 8730fdc8d8SChris Lattner m_sc = *sc_ptr; 881b72fcb7SGreg Clayton m_flags.Set(m_sc.GetResolvedMask()); 891b72fcb7SGreg Clayton } 901b72fcb7SGreg Clayton 91*b9c1b51eSKate Stone if (reg_context_sp && !m_sc.target_sp) { 92d9e416c0SGreg Clayton m_sc.target_sp = reg_context_sp->CalculateTarget(); 93d9e416c0SGreg Clayton if (m_sc.target_sp) 941b72fcb7SGreg Clayton m_flags.Set(eSymbolContextTarget); 951b72fcb7SGreg Clayton } 961b72fcb7SGreg Clayton } 971b72fcb7SGreg Clayton 98*b9c1b51eSKate Stone StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx, 99*b9c1b51eSKate Stone user_id_t unwind_frame_index, 100*b9c1b51eSKate Stone const RegisterContextSP ®_context_sp, addr_t cfa, 101*b9c1b51eSKate Stone const Address &pc_addr, const SymbolContext *sc_ptr) 102*b9c1b51eSKate Stone : m_thread_wp(thread_sp), m_frame_index(frame_idx), 1035ccbd294SGreg Clayton m_concrete_frame_index(unwind_frame_index), 1041b72fcb7SGreg Clayton m_reg_context_sp(reg_context_sp), 105*b9c1b51eSKate Stone m_id(pc_addr.GetLoadAddress(thread_sp->CalculateTarget().get()), cfa, 106*b9c1b51eSKate Stone nullptr), 107*b9c1b51eSKate Stone m_frame_code_addr(pc_addr), m_sc(), m_flags(), m_frame_base(), 108*b9c1b51eSKate Stone m_frame_base_error(), m_cfa_is_valid(true), m_stop_id(0), 109*b9c1b51eSKate Stone m_stop_id_is_valid(false), m_is_history_frame(false), 110*b9c1b51eSKate Stone m_variable_list_sp(), m_variable_list_value_objects(), m_disassembly(), 111*b9c1b51eSKate Stone m_mutex() { 112*b9c1b51eSKate Stone if (sc_ptr != nullptr) { 1131b72fcb7SGreg Clayton m_sc = *sc_ptr; 1141b72fcb7SGreg Clayton m_flags.Set(m_sc.GetResolvedMask()); 1151b72fcb7SGreg Clayton } 1161b72fcb7SGreg Clayton 117*b9c1b51eSKate Stone if (!m_sc.target_sp && reg_context_sp) { 118d9e416c0SGreg Clayton m_sc.target_sp = reg_context_sp->CalculateTarget(); 119d9e416c0SGreg Clayton if (m_sc.target_sp) 1201b72fcb7SGreg Clayton m_flags.Set(eSymbolContextTarget); 1211b72fcb7SGreg Clayton } 1221b72fcb7SGreg Clayton 123e72dfb32SGreg Clayton ModuleSP pc_module_sp(pc_addr.GetModule()); 124*b9c1b51eSKate Stone if (!m_sc.module_sp || m_sc.module_sp != pc_module_sp) { 125*b9c1b51eSKate Stone if (pc_module_sp) { 126e72dfb32SGreg Clayton m_sc.module_sp = pc_module_sp; 1271b72fcb7SGreg Clayton m_flags.Set(eSymbolContextModule); 128*b9c1b51eSKate Stone } else { 129ffc1d667SGreg Clayton m_sc.module_sp.reset(); 130ffc1d667SGreg Clayton } 1311b72fcb7SGreg Clayton } 13230fdc8d8SChris Lattner } 13330fdc8d8SChris Lattner 134d70a6e71SEugene Zelenko StackFrame::~StackFrame() = default; 13530fdc8d8SChris Lattner 136*b9c1b51eSKate Stone StackID &StackFrame::GetStackID() { 137bb19a13cSSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex); 1386dadd508SGreg Clayton // Make sure we have resolved the StackID object's symbol context scope if 1396dadd508SGreg Clayton // we already haven't looked it up. 14059e8fc1cSGreg Clayton 141*b9c1b51eSKate Stone if (m_flags.IsClear(RESOLVED_FRAME_ID_SYMBOL_SCOPE)) { 142*b9c1b51eSKate Stone if (m_id.GetSymbolContextScope()) { 14395897c6aSGreg Clayton // We already have a symbol context scope, we just don't have our 14495897c6aSGreg Clayton // flag bit set. 14559e8fc1cSGreg Clayton m_flags.Set(RESOLVED_FRAME_ID_SYMBOL_SCOPE); 146*b9c1b51eSKate Stone } else { 14795897c6aSGreg Clayton // Calculate the frame block and use this for the stack ID symbol 14895897c6aSGreg Clayton // context scope if we have one. 14995897c6aSGreg Clayton SymbolContextScope *scope = GetFrameBlock(); 150*b9c1b51eSKate Stone if (scope == nullptr) { 15195897c6aSGreg Clayton // We don't have a block, so use the symbol 15295897c6aSGreg Clayton if (m_flags.IsClear(eSymbolContextSymbol)) 15359e8fc1cSGreg Clayton GetSymbolContext(eSymbolContextSymbol); 15495897c6aSGreg Clayton 155d70a6e71SEugene Zelenko // It is ok if m_sc.symbol is nullptr here 15695897c6aSGreg Clayton scope = m_sc.symbol; 15759e8fc1cSGreg Clayton } 15895897c6aSGreg Clayton // Set the symbol context scope (the accessor will set the 15995897c6aSGreg Clayton // RESOLVED_FRAME_ID_SYMBOL_SCOPE bit in m_flags). 16095897c6aSGreg Clayton SetSymbolContextScope(scope); 16159e8fc1cSGreg Clayton } 16259e8fc1cSGreg Clayton } 16330fdc8d8SChris Lattner return m_id; 16430fdc8d8SChris Lattner } 16530fdc8d8SChris Lattner 166*b9c1b51eSKate Stone uint32_t StackFrame::GetFrameIndex() const { 167513c6bb8SJim Ingham ThreadSP thread_sp = GetThread(); 168513c6bb8SJim Ingham if (thread_sp) 169*b9c1b51eSKate Stone return thread_sp->GetStackFrameList()->GetVisibleStackFrameIndex( 170*b9c1b51eSKate Stone m_frame_index); 171513c6bb8SJim Ingham else 172513c6bb8SJim Ingham return m_frame_index; 173513c6bb8SJim Ingham } 174513c6bb8SJim Ingham 175*b9c1b51eSKate Stone void StackFrame::SetSymbolContextScope(SymbolContextScope *symbol_scope) { 176bb19a13cSSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex); 17759e8fc1cSGreg Clayton m_flags.Set(RESOLVED_FRAME_ID_SYMBOL_SCOPE); 17859e8fc1cSGreg Clayton m_id.SetSymbolContextScope(symbol_scope); 17959e8fc1cSGreg Clayton } 18059e8fc1cSGreg Clayton 181*b9c1b51eSKate Stone const Address &StackFrame::GetFrameCodeAddress() { 182bb19a13cSSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex); 183*b9c1b51eSKate Stone if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) && 184*b9c1b51eSKate Stone !m_frame_code_addr.IsSectionOffset()) { 18559e8fc1cSGreg Clayton m_flags.Set(RESOLVED_FRAME_CODE_ADDR); 18630fdc8d8SChris Lattner 18730fdc8d8SChris Lattner // Resolve the PC into a temporary address because if ResolveLoadAddress 18830fdc8d8SChris Lattner // fails to resolve the address, it will clear the address object... 189d9e416c0SGreg Clayton ThreadSP thread_sp(GetThread()); 190*b9c1b51eSKate Stone if (thread_sp) { 191d9e416c0SGreg Clayton TargetSP target_sp(thread_sp->CalculateTarget()); 192*b9c1b51eSKate Stone if (target_sp) { 193*b9c1b51eSKate Stone if (m_frame_code_addr.SetOpcodeLoadAddress( 194*b9c1b51eSKate Stone m_frame_code_addr.GetOffset(), target_sp.get(), 195*b9c1b51eSKate Stone eAddressClassCode)) { 196e72dfb32SGreg Clayton ModuleSP module_sp(m_frame_code_addr.GetModule()); 197*b9c1b51eSKate Stone if (module_sp) { 198e72dfb32SGreg Clayton m_sc.module_sp = module_sp; 19930fdc8d8SChris Lattner m_flags.Set(eSymbolContextModule); 20030fdc8d8SChris Lattner } 20130fdc8d8SChris Lattner } 20230fdc8d8SChris Lattner } 20330fdc8d8SChris Lattner } 204d9e416c0SGreg Clayton } 20512fc3e0fSGreg Clayton return m_frame_code_addr; 20630fdc8d8SChris Lattner } 20730fdc8d8SChris Lattner 208*b9c1b51eSKate Stone bool StackFrame::ChangePC(addr_t pc) { 209bb19a13cSSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex); 21099618476SJason Molenda // We can't change the pc value of a history stack frame - it is immutable. 21199618476SJason Molenda if (m_is_history_frame) 21299618476SJason Molenda return false; 213e72dfb32SGreg Clayton m_frame_code_addr.SetRawAddress(pc); 21472310355SGreg Clayton m_sc.Clear(false); 21573b472d4SGreg Clayton m_flags.Reset(0); 216d9e416c0SGreg Clayton ThreadSP thread_sp(GetThread()); 217d9e416c0SGreg Clayton if (thread_sp) 218d9e416c0SGreg Clayton thread_sp->ClearStackFrames(); 21999618476SJason Molenda return true; 22030fdc8d8SChris Lattner } 22130fdc8d8SChris Lattner 222*b9c1b51eSKate Stone const char *StackFrame::Disassemble() { 223bb19a13cSSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex); 224*b9c1b51eSKate Stone if (m_disassembly.GetSize() == 0) { 225d9e416c0SGreg Clayton ExecutionContext exe_ctx(shared_from_this()); 226d9e416c0SGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 227*b9c1b51eSKate Stone if (target) { 228d70a6e71SEugene Zelenko const char *plugin_name = nullptr; 229d70a6e71SEugene Zelenko const char *flavor = nullptr; 230d9e416c0SGreg Clayton Disassembler::Disassemble(target->GetDebugger(), 231*b9c1b51eSKate Stone target->GetArchitecture(), plugin_name, flavor, 232*b9c1b51eSKate Stone exe_ctx, 0, 0, 0, m_disassembly); 233d9e416c0SGreg Clayton } 23430fdc8d8SChris Lattner if (m_disassembly.GetSize() == 0) 235d70a6e71SEugene Zelenko return nullptr; 23630fdc8d8SChris Lattner } 23730fdc8d8SChris Lattner return m_disassembly.GetData(); 23830fdc8d8SChris Lattner } 23930fdc8d8SChris Lattner 240*b9c1b51eSKate Stone Block *StackFrame::GetFrameBlock() { 241d70a6e71SEugene Zelenko if (m_sc.block == nullptr && m_flags.IsClear(eSymbolContextBlock)) 24295897c6aSGreg Clayton GetSymbolContext(eSymbolContextBlock); 24395897c6aSGreg Clayton 244*b9c1b51eSKate Stone if (m_sc.block) { 24595897c6aSGreg Clayton Block *inline_block = m_sc.block->GetContainingInlinedBlock(); 246*b9c1b51eSKate Stone if (inline_block) { 24795897c6aSGreg Clayton // Use the block with the inlined function info 24895897c6aSGreg Clayton // as the frame block we want this frame to have only the variables 24995897c6aSGreg Clayton // for the inlined function and its non-inlined block child blocks. 25095897c6aSGreg Clayton return inline_block; 251*b9c1b51eSKate Stone } else { 25275500e72SEd Maste // This block is not contained within any inlined function blocks 25395897c6aSGreg Clayton // with so we want to use the top most function block. 25495897c6aSGreg Clayton return &m_sc.function->GetBlock(false); 25595897c6aSGreg Clayton } 25695897c6aSGreg Clayton } 257d70a6e71SEugene Zelenko return nullptr; 25895897c6aSGreg Clayton } 25995897c6aSGreg Clayton 26030fdc8d8SChris Lattner //---------------------------------------------------------------------- 26130fdc8d8SChris Lattner // Get the symbol context if we already haven't done so by resolving the 26230fdc8d8SChris Lattner // PC address as much as possible. This way when we pass around a 26330fdc8d8SChris Lattner // StackFrame object, everyone will have as much information as 26430fdc8d8SChris Lattner // possible and no one will ever have to look things up manually. 26530fdc8d8SChris Lattner //---------------------------------------------------------------------- 266*b9c1b51eSKate Stone const SymbolContext &StackFrame::GetSymbolContext(uint32_t resolve_scope) { 267bb19a13cSSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex); 26830fdc8d8SChris Lattner // Copy our internal symbol context into "sc". 269*b9c1b51eSKate Stone if ((m_flags.Get() & resolve_scope) != resolve_scope) { 27075a0333bSGreg Clayton uint32_t resolved = 0; 27175a0333bSGreg Clayton 27275a0333bSGreg Clayton // If the target was requested add that: 273*b9c1b51eSKate Stone if (!m_sc.target_sp) { 27475a0333bSGreg Clayton m_sc.target_sp = CalculateTarget(); 27575a0333bSGreg Clayton if (m_sc.target_sp) 27675a0333bSGreg Clayton resolved |= eSymbolContextTarget; 27775a0333bSGreg Clayton } 27875a0333bSGreg Clayton 279aaa0ba31SBruce Mitchener // Resolve our PC to section offset if we haven't already done so 28030fdc8d8SChris Lattner // and if we don't have a module. The resolved address section will 28130fdc8d8SChris Lattner // contain the module to which it belongs 28259e8fc1cSGreg Clayton if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR)) 2839da7bd07SGreg Clayton GetFrameCodeAddress(); 28430fdc8d8SChris Lattner 28530fdc8d8SChris Lattner // If this is not frame zero, then we need to subtract 1 from the PC 28630fdc8d8SChris Lattner // value when doing address lookups since the PC will be on the 28730fdc8d8SChris Lattner // instruction following the function call instruction... 28830fdc8d8SChris Lattner 2899da7bd07SGreg Clayton Address lookup_addr(GetFrameCodeAddress()); 290*b9c1b51eSKate Stone if (m_frame_index > 0 && lookup_addr.IsValid()) { 29130fdc8d8SChris Lattner addr_t offset = lookup_addr.GetOffset(); 292*b9c1b51eSKate Stone if (offset > 0) { 29330fdc8d8SChris Lattner lookup_addr.SetOffset(offset - 1); 294cf29675dSJason Molenda 295*b9c1b51eSKate Stone } else { 296cf29675dSJason Molenda // lookup_addr is the start of a section. We need 297cf29675dSJason Molenda // do the math on the actual load address and re-compute 298cf29675dSJason Molenda // the section. We're working with a 'noreturn' function 299cf29675dSJason Molenda // at the end of a section. 300cf29675dSJason Molenda ThreadSP thread_sp(GetThread()); 301*b9c1b51eSKate Stone if (thread_sp) { 302cf29675dSJason Molenda TargetSP target_sp(thread_sp->CalculateTarget()); 303*b9c1b51eSKate Stone if (target_sp) { 304*b9c1b51eSKate Stone addr_t addr_minus_one = 305*b9c1b51eSKate Stone lookup_addr.GetLoadAddress(target_sp.get()) - 1; 306cf29675dSJason Molenda lookup_addr.SetLoadAddress(addr_minus_one, target_sp.get()); 307*b9c1b51eSKate Stone } else { 308cf29675dSJason Molenda lookup_addr.SetOffset(offset - 1); 309cf29675dSJason Molenda } 310cf29675dSJason Molenda } 311cf29675dSJason Molenda } 31230fdc8d8SChris Lattner } 31330fdc8d8SChris Lattner 314*b9c1b51eSKate Stone if (m_sc.module_sp) { 31530fdc8d8SChris Lattner // We have something in our stack frame symbol context, lets check 31630fdc8d8SChris Lattner // if we haven't already tried to lookup one of those things. If we 31730fdc8d8SChris Lattner // haven't then we will do the query. 3181b72fcb7SGreg Clayton 3191b72fcb7SGreg Clayton uint32_t actual_resolve_scope = 0; 3201b72fcb7SGreg Clayton 321*b9c1b51eSKate Stone if (resolve_scope & eSymbolContextCompUnit) { 322*b9c1b51eSKate Stone if (m_flags.IsClear(eSymbolContextCompUnit)) { 3231b72fcb7SGreg Clayton if (m_sc.comp_unit) 3249da7bd07SGreg Clayton resolved |= eSymbolContextCompUnit; 3251b72fcb7SGreg Clayton else 3261b72fcb7SGreg Clayton actual_resolve_scope |= eSymbolContextCompUnit; 3271b72fcb7SGreg Clayton } 3281b72fcb7SGreg Clayton } 3291b72fcb7SGreg Clayton 330*b9c1b51eSKate Stone if (resolve_scope & eSymbolContextFunction) { 331*b9c1b51eSKate Stone if (m_flags.IsClear(eSymbolContextFunction)) { 3321b72fcb7SGreg Clayton if (m_sc.function) 3339da7bd07SGreg Clayton resolved |= eSymbolContextFunction; 3341b72fcb7SGreg Clayton else 3351b72fcb7SGreg Clayton actual_resolve_scope |= eSymbolContextFunction; 3361b72fcb7SGreg Clayton } 3371b72fcb7SGreg Clayton } 3381b72fcb7SGreg Clayton 339*b9c1b51eSKate Stone if (resolve_scope & eSymbolContextBlock) { 340*b9c1b51eSKate Stone if (m_flags.IsClear(eSymbolContextBlock)) { 3411b72fcb7SGreg Clayton if (m_sc.block) 3429da7bd07SGreg Clayton resolved |= eSymbolContextBlock; 3431b72fcb7SGreg Clayton else 3441b72fcb7SGreg Clayton actual_resolve_scope |= eSymbolContextBlock; 3451b72fcb7SGreg Clayton } 3461b72fcb7SGreg Clayton } 3471b72fcb7SGreg Clayton 348*b9c1b51eSKate Stone if (resolve_scope & eSymbolContextSymbol) { 349*b9c1b51eSKate Stone if (m_flags.IsClear(eSymbolContextSymbol)) { 3501b72fcb7SGreg Clayton if (m_sc.symbol) 3519da7bd07SGreg Clayton resolved |= eSymbolContextSymbol; 3521b72fcb7SGreg Clayton else 3531b72fcb7SGreg Clayton actual_resolve_scope |= eSymbolContextSymbol; 3541b72fcb7SGreg Clayton } 3551b72fcb7SGreg Clayton } 3561b72fcb7SGreg Clayton 357*b9c1b51eSKate Stone if (resolve_scope & eSymbolContextLineEntry) { 358*b9c1b51eSKate Stone if (m_flags.IsClear(eSymbolContextLineEntry)) { 3591b72fcb7SGreg Clayton if (m_sc.line_entry.IsValid()) 3609da7bd07SGreg Clayton resolved |= eSymbolContextLineEntry; 3611b72fcb7SGreg Clayton else 3621b72fcb7SGreg Clayton actual_resolve_scope |= eSymbolContextLineEntry; 3631b72fcb7SGreg Clayton } 3641b72fcb7SGreg Clayton } 3651b72fcb7SGreg Clayton 366*b9c1b51eSKate Stone if (actual_resolve_scope) { 36730fdc8d8SChris Lattner // We might be resolving less information than what is already 36830fdc8d8SChris Lattner // in our current symbol context so resolve into a temporary 36930fdc8d8SChris Lattner // symbol context "sc" so we don't clear out data we have 37030fdc8d8SChris Lattner // already found in "m_sc" 37130fdc8d8SChris Lattner SymbolContext sc; 37230fdc8d8SChris Lattner // Set flags that indicate what we have tried to resolve 373*b9c1b51eSKate Stone resolved |= m_sc.module_sp->ResolveSymbolContextForAddress( 374*b9c1b51eSKate Stone lookup_addr, actual_resolve_scope, sc); 3751b72fcb7SGreg Clayton // Only replace what we didn't already have as we may have 3761b72fcb7SGreg Clayton // information for an inlined function scope that won't match 3771b72fcb7SGreg Clayton // what a standard lookup by address would match 378d70a6e71SEugene Zelenko if ((resolved & eSymbolContextCompUnit) && m_sc.comp_unit == nullptr) 3799da7bd07SGreg Clayton m_sc.comp_unit = sc.comp_unit; 380d70a6e71SEugene Zelenko if ((resolved & eSymbolContextFunction) && m_sc.function == nullptr) 3819da7bd07SGreg Clayton m_sc.function = sc.function; 382d70a6e71SEugene Zelenko if ((resolved & eSymbolContextBlock) && m_sc.block == nullptr) 3839da7bd07SGreg Clayton m_sc.block = sc.block; 384d70a6e71SEugene Zelenko if ((resolved & eSymbolContextSymbol) && m_sc.symbol == nullptr) 3859da7bd07SGreg Clayton m_sc.symbol = sc.symbol; 386*b9c1b51eSKate Stone if ((resolved & eSymbolContextLineEntry) && 387*b9c1b51eSKate Stone !m_sc.line_entry.IsValid()) { 3889da7bd07SGreg Clayton m_sc.line_entry = sc.line_entry; 389911d5784STed Woodward m_sc.line_entry.ApplyFileMappings(m_sc.target_sp); 39075a0333bSGreg Clayton } 39130fdc8d8SChris Lattner } 392*b9c1b51eSKate Stone } else { 39330fdc8d8SChris Lattner // If we don't have a module, then we can't have the compile unit, 39430fdc8d8SChris Lattner // function, block, line entry or symbol, so we can safely call 39530fdc8d8SChris Lattner // ResolveSymbolContextForAddress with our symbol context member m_sc. 396*b9c1b51eSKate Stone if (m_sc.target_sp) { 397*b9c1b51eSKate Stone resolved |= m_sc.target_sp->GetImages().ResolveSymbolContextForAddress( 398*b9c1b51eSKate Stone lookup_addr, resolve_scope, m_sc); 399f4be227dSSean Callanan } 4009da7bd07SGreg Clayton } 40130fdc8d8SChris Lattner 40230fdc8d8SChris Lattner // Update our internal flags so we remember what we have tried to locate so 40330fdc8d8SChris Lattner // we don't have to keep trying when more calls to this function are made. 4049da7bd07SGreg Clayton // We might have dug up more information that was requested (for example 4059da7bd07SGreg Clayton // if we were asked to only get the block, we will have gotten the 4069da7bd07SGreg Clayton // compile unit, and function) so set any additional bits that we resolved 4079da7bd07SGreg Clayton m_flags.Set(resolve_scope | resolved); 40830fdc8d8SChris Lattner } 40930fdc8d8SChris Lattner 41030fdc8d8SChris Lattner // Return the symbol context with everything that was possible to resolve 41130fdc8d8SChris Lattner // resolved. 41230fdc8d8SChris Lattner return m_sc; 41330fdc8d8SChris Lattner } 41430fdc8d8SChris Lattner 415*b9c1b51eSKate Stone VariableList *StackFrame::GetVariableList(bool get_file_globals) { 416bb19a13cSSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex); 417*b9c1b51eSKate Stone if (m_flags.IsClear(RESOLVED_VARIABLES)) { 41830fdc8d8SChris Lattner m_flags.Set(RESOLVED_VARIABLES); 41930fdc8d8SChris Lattner 42095897c6aSGreg Clayton Block *frame_block = GetFrameBlock(); 421288bdf9cSGreg Clayton 422*b9c1b51eSKate Stone if (frame_block) { 42395897c6aSGreg Clayton const bool get_child_variables = true; 42495897c6aSGreg Clayton const bool can_create = true; 425c662ec8bSGreg Clayton const bool stop_if_child_block_is_inlined_function = true; 426c662ec8bSGreg Clayton m_variable_list_sp.reset(new VariableList()); 427*b9c1b51eSKate Stone frame_block->AppendBlockVariables(can_create, get_child_variables, 42872ac8a84STamas Berghammer stop_if_child_block_is_inlined_function, 429a32532bfSGreg Clayton [this](Variable *v) { return true; }, 43072ac8a84STamas Berghammer m_variable_list_sp.get()); 43130fdc8d8SChris Lattner } 4327c0962dcSSean Callanan } 433288bdf9cSGreg Clayton 434*b9c1b51eSKate Stone if (m_flags.IsClear(RESOLVED_GLOBAL_VARIABLES) && get_file_globals) { 4357c0962dcSSean Callanan m_flags.Set(RESOLVED_GLOBAL_VARIABLES); 4367c0962dcSSean Callanan 43795897c6aSGreg Clayton if (m_flags.IsClear(eSymbolContextCompUnit)) 43895897c6aSGreg Clayton GetSymbolContext(eSymbolContextCompUnit); 43995897c6aSGreg Clayton 440*b9c1b51eSKate Stone if (m_sc.comp_unit) { 441*b9c1b51eSKate Stone VariableListSP global_variable_list_sp( 442*b9c1b51eSKate Stone m_sc.comp_unit->GetVariableList(true)); 443288bdf9cSGreg Clayton if (m_variable_list_sp) 444288bdf9cSGreg Clayton m_variable_list_sp->AddVariables(global_variable_list_sp.get()); 445288bdf9cSGreg Clayton else 446288bdf9cSGreg Clayton m_variable_list_sp = global_variable_list_sp; 447288bdf9cSGreg Clayton } 44830fdc8d8SChris Lattner } 4497c0962dcSSean Callanan 45030fdc8d8SChris Lattner return m_variable_list_sp.get(); 45130fdc8d8SChris Lattner } 45230fdc8d8SChris Lattner 453d41f032aSGreg Clayton VariableListSP 454*b9c1b51eSKate Stone StackFrame::GetInScopeVariableList(bool get_file_globals, 455*b9c1b51eSKate Stone bool must_have_valid_location) { 456bb19a13cSSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex); 45799618476SJason Molenda // We can't fetch variable information for a history stack frame. 45899618476SJason Molenda if (m_is_history_frame) 45999618476SJason Molenda return VariableListSP(); 46099618476SJason Molenda 461d41f032aSGreg Clayton VariableListSP var_list_sp(new VariableList); 462d41f032aSGreg Clayton GetSymbolContext(eSymbolContextCompUnit | eSymbolContextBlock); 463d41f032aSGreg Clayton 464*b9c1b51eSKate Stone if (m_sc.block) { 465d41f032aSGreg Clayton const bool can_create = true; 466d41f032aSGreg Clayton const bool get_parent_variables = true; 467d41f032aSGreg Clayton const bool stop_if_block_is_inlined_function = true; 468*b9c1b51eSKate Stone m_sc.block->AppendVariables( 469*b9c1b51eSKate Stone can_create, get_parent_variables, stop_if_block_is_inlined_function, 470*b9c1b51eSKate Stone [this, must_have_valid_location](Variable *v) { 471*b9c1b51eSKate Stone return v->IsInScope(this) && (!must_have_valid_location || 472*b9c1b51eSKate Stone v->LocationIsValidForFrame(this)); 473cef46177SJim Ingham }, 474d41f032aSGreg Clayton var_list_sp.get()); 475d41f032aSGreg Clayton } 476d41f032aSGreg Clayton 477*b9c1b51eSKate Stone if (m_sc.comp_unit && get_file_globals) { 478*b9c1b51eSKate Stone VariableListSP global_variable_list_sp( 479*b9c1b51eSKate Stone m_sc.comp_unit->GetVariableList(true)); 480d41f032aSGreg Clayton if (global_variable_list_sp) 481d41f032aSGreg Clayton var_list_sp->AddVariables(global_variable_list_sp.get()); 482d41f032aSGreg Clayton } 483d41f032aSGreg Clayton 484d41f032aSGreg Clayton return var_list_sp; 485d41f032aSGreg Clayton } 486d41f032aSGreg Clayton 487*b9c1b51eSKate Stone ValueObjectSP StackFrame::GetValueForVariableExpressionPath( 488*b9c1b51eSKate Stone const char *var_expr_cstr, DynamicValueType use_dynamic, uint32_t options, 489*b9c1b51eSKate Stone VariableSP &var_sp, Error &error) { 49099618476SJason Molenda // We can't fetch variable information for a history stack frame. 49199618476SJason Molenda if (m_is_history_frame) 49299618476SJason Molenda return ValueObjectSP(); 49354979cddSGreg Clayton 494*b9c1b51eSKate Stone if (var_expr_cstr && var_expr_cstr[0]) { 495*b9c1b51eSKate Stone const bool check_ptr_vs_member = 496*b9c1b51eSKate Stone (options & eExpressionPathOptionCheckPtrVsMember) != 0; 497*b9c1b51eSKate Stone const bool no_fragile_ivar = 498*b9c1b51eSKate Stone (options & eExpressionPathOptionsNoFragileObjcIvar) != 0; 499*b9c1b51eSKate Stone const bool no_synth_child = 500*b9c1b51eSKate Stone (options & eExpressionPathOptionsNoSyntheticChildren) != 0; 501*b9c1b51eSKate Stone // const bool no_synth_array = (options & 502*b9c1b51eSKate Stone // eExpressionPathOptionsNoSyntheticArrayRange) != 0; 50354979cddSGreg Clayton error.Clear(); 5048b2fe6dcSGreg Clayton bool deref = false; 5058b2fe6dcSGreg Clayton bool address_of = false; 5068b2fe6dcSGreg Clayton ValueObjectSP valobj_sp; 5078b2fe6dcSGreg Clayton const bool get_file_globals = true; 508d41f032aSGreg Clayton // When looking up a variable for an expression, we need only consider the 509d41f032aSGreg Clayton // variables that are in scope. 510d41f032aSGreg Clayton VariableListSP var_list_sp(GetInScopeVariableList(get_file_globals)); 511d41f032aSGreg Clayton VariableList *variable_list = var_list_sp.get(); 5128b2fe6dcSGreg Clayton 513*b9c1b51eSKate Stone if (variable_list) { 5148b2fe6dcSGreg Clayton // If first character is a '*', then show pointer contents 51554979cddSGreg Clayton const char *var_expr = var_expr_cstr; 516*b9c1b51eSKate Stone if (var_expr[0] == '*') { 5178b2fe6dcSGreg Clayton deref = true; 5188b2fe6dcSGreg Clayton var_expr++; // Skip the '*' 519*b9c1b51eSKate Stone } else if (var_expr[0] == '&') { 5208b2fe6dcSGreg Clayton address_of = true; 5218b2fe6dcSGreg Clayton var_expr++; // Skip the '&' 5228b2fe6dcSGreg Clayton } 5238b2fe6dcSGreg Clayton 5248b2fe6dcSGreg Clayton std::string var_path(var_expr); 52554979cddSGreg Clayton size_t separator_idx = var_path.find_first_of(".-[=+~|&^%#@!/?,<>{}"); 52654979cddSGreg Clayton StreamString var_expr_path_strm; 5278b2fe6dcSGreg Clayton 5288b2fe6dcSGreg Clayton ConstString name_const_string; 5298b2fe6dcSGreg Clayton if (separator_idx == std::string::npos) 5308b2fe6dcSGreg Clayton name_const_string.SetCString(var_path.c_str()); 5318b2fe6dcSGreg Clayton else 5328b2fe6dcSGreg Clayton name_const_string.SetCStringWithLength(var_path.c_str(), separator_idx); 5338b2fe6dcSGreg Clayton 53410bc1a4eSPaul Herman var_sp = variable_list->FindVariable(name_const_string, false); 535685c88c5SGreg Clayton 536685c88c5SGreg Clayton bool synthetically_added_instance_object = false; 537685c88c5SGreg Clayton 538*b9c1b51eSKate Stone if (var_sp) { 539685c88c5SGreg Clayton var_path.erase(0, name_const_string.GetLength()); 540685c88c5SGreg Clayton } 54146252398SEnrico Granata 542*b9c1b51eSKate Stone if (!var_sp && (options & eExpressionPathOptionsAllowDirectIVarAccess)) { 543685c88c5SGreg Clayton // Check for direct ivars access which helps us with implicit 544685c88c5SGreg Clayton // access to ivars with the "this->" or "self->" 545685c88c5SGreg Clayton GetSymbolContext(eSymbolContextFunction | eSymbolContextBlock); 546685c88c5SGreg Clayton lldb::LanguageType method_language = eLanguageTypeUnknown; 547685c88c5SGreg Clayton bool is_instance_method = false; 548685c88c5SGreg Clayton ConstString method_object_name; 549*b9c1b51eSKate Stone if (m_sc.GetFunctionMethodInfo(method_language, is_instance_method, 550*b9c1b51eSKate Stone method_object_name)) { 551*b9c1b51eSKate Stone if (is_instance_method && method_object_name) { 552685c88c5SGreg Clayton var_sp = variable_list->FindVariable(method_object_name); 553*b9c1b51eSKate Stone if (var_sp) { 554685c88c5SGreg Clayton separator_idx = 0; 555685c88c5SGreg Clayton var_path.insert(0, "->"); 556685c88c5SGreg Clayton synthetically_added_instance_object = true; 557685c88c5SGreg Clayton } 558685c88c5SGreg Clayton } 559685c88c5SGreg Clayton } 560685c88c5SGreg Clayton } 561685c88c5SGreg Clayton 562*b9c1b51eSKate Stone if (!var_sp && (options & eExpressionPathOptionsInspectAnonymousUnions)) { 563*b9c1b51eSKate Stone // Check if any anonymous unions are there which contain a variable with 564*b9c1b51eSKate Stone // the name we need 565*b9c1b51eSKate Stone for (size_t i = 0; i < variable_list->GetSize(); i++) { 566*b9c1b51eSKate Stone if (VariableSP variable_sp = variable_list->GetVariableAtIndex(i)) { 567*b9c1b51eSKate Stone if (variable_sp->GetName().IsEmpty()) { 568*b9c1b51eSKate Stone if (Type *var_type = variable_sp->GetType()) { 569*b9c1b51eSKate Stone if (var_type->GetForwardCompilerType().IsAnonymousType()) { 570*b9c1b51eSKate Stone valobj_sp = 571*b9c1b51eSKate Stone GetValueObjectForFrameVariable(variable_sp, use_dynamic); 57246252398SEnrico Granata if (!valobj_sp) 57346252398SEnrico Granata return valobj_sp; 574*b9c1b51eSKate Stone valobj_sp = valobj_sp->GetChildMemberWithName( 575*b9c1b51eSKate Stone name_const_string, true); 57646252398SEnrico Granata if (valobj_sp) 57746252398SEnrico Granata break; 57846252398SEnrico Granata } 57946252398SEnrico Granata } 58046252398SEnrico Granata } 58146252398SEnrico Granata } 58246252398SEnrico Granata } 58346252398SEnrico Granata } 58446252398SEnrico Granata 585*b9c1b51eSKate Stone if (var_sp && !valobj_sp) { 5862837b766SJim Ingham valobj_sp = GetValueObjectForFrameVariable(var_sp, use_dynamic); 58778a685aaSJim Ingham if (!valobj_sp) 58878a685aaSJim Ingham return valobj_sp; 58946252398SEnrico Granata } 590*b9c1b51eSKate Stone if (valobj_sp) { 5918b2fe6dcSGreg Clayton // We are dumping at least one child 592*b9c1b51eSKate Stone while (separator_idx != std::string::npos) { 5938b2fe6dcSGreg Clayton // Calculate the next separator index ahead of time 5948b2fe6dcSGreg Clayton ValueObjectSP child_valobj_sp; 5958b2fe6dcSGreg Clayton const char separator_type = var_path[0]; 596*b9c1b51eSKate Stone switch (separator_type) { 5978b2fe6dcSGreg Clayton case '-': 5988b2fe6dcSGreg Clayton if (var_path.size() >= 2 && var_path[1] != '>') 5998b2fe6dcSGreg Clayton return ValueObjectSP(); 6008b2fe6dcSGreg Clayton 601*b9c1b51eSKate Stone if (no_fragile_ivar) { 6026d5e68eaSGreg Clayton // Make sure we aren't trying to deref an objective 6036d5e68eaSGreg Clayton // C ivar if this is not allowed 604*b9c1b51eSKate Stone const uint32_t pointer_type_flags = 605*b9c1b51eSKate Stone valobj_sp->GetCompilerType().GetTypeInfo(nullptr); 606622be238SEnrico Granata if ((pointer_type_flags & eTypeIsObjC) && 607*b9c1b51eSKate Stone (pointer_type_flags & eTypeIsPointer)) { 6086d5e68eaSGreg Clayton // This was an objective C object pointer and 6096d5e68eaSGreg Clayton // it was requested we skip any fragile ivars 6106d5e68eaSGreg Clayton // so return nothing here 6116d5e68eaSGreg Clayton return ValueObjectSP(); 6126d5e68eaSGreg Clayton } 6136d5e68eaSGreg Clayton } 6148b2fe6dcSGreg Clayton var_path.erase(0, 1); // Remove the '-' 61562e0681aSJason Molenda LLVM_FALLTHROUGH; 616*b9c1b51eSKate Stone case '.': { 61754979cddSGreg Clayton const bool expr_is_ptr = var_path[0] == '>'; 6188b2fe6dcSGreg Clayton 6198b2fe6dcSGreg Clayton var_path.erase(0, 1); // Remove the '.' or '>' 6208b2fe6dcSGreg Clayton separator_idx = var_path.find_first_of(".-["); 6218b2fe6dcSGreg Clayton ConstString child_name; 6228b2fe6dcSGreg Clayton if (separator_idx == std::string::npos) 6238b2fe6dcSGreg Clayton child_name.SetCString(var_path.c_str()); 6248b2fe6dcSGreg Clayton else 6258b2fe6dcSGreg Clayton child_name.SetCStringWithLength(var_path.c_str(), separator_idx); 6268b2fe6dcSGreg Clayton 627*b9c1b51eSKate Stone if (check_ptr_vs_member) { 62854979cddSGreg Clayton // We either have a pointer type and need to verify 62954979cddSGreg Clayton // valobj_sp is a pointer, or we have a member of a 63054979cddSGreg Clayton // class/union/struct being accessed with the . syntax 63154979cddSGreg Clayton // and need to verify we don't have a pointer. 63254979cddSGreg Clayton const bool actual_is_ptr = valobj_sp->IsPointerType(); 63354979cddSGreg Clayton 634*b9c1b51eSKate Stone if (actual_is_ptr != expr_is_ptr) { 63554979cddSGreg Clayton // Incorrect use of "." with a pointer, or "->" with 63654979cddSGreg Clayton // a class/union/struct instance or reference. 6376beaaa68SGreg Clayton valobj_sp->GetExpressionPath(var_expr_path_strm, false); 63854979cddSGreg Clayton if (actual_is_ptr) 639*b9c1b51eSKate Stone error.SetErrorStringWithFormat( 640*b9c1b51eSKate Stone "\"%s\" is a pointer and . was used to attempt to access " 641*b9c1b51eSKate Stone "\"%s\". Did you mean \"%s->%s\"?", 64254979cddSGreg Clayton var_expr_path_strm.GetString().c_str(), 64354979cddSGreg Clayton child_name.GetCString(), 644*b9c1b51eSKate Stone var_expr_path_strm.GetString().c_str(), var_path.c_str()); 64554979cddSGreg Clayton else 646*b9c1b51eSKate Stone error.SetErrorStringWithFormat( 647*b9c1b51eSKate Stone "\"%s\" is not a pointer and -> was used to attempt to " 648*b9c1b51eSKate Stone "access \"%s\". Did you mean \"%s.%s\"?", 64954979cddSGreg Clayton var_expr_path_strm.GetString().c_str(), 65054979cddSGreg Clayton child_name.GetCString(), 651*b9c1b51eSKate Stone var_expr_path_strm.GetString().c_str(), var_path.c_str()); 65254979cddSGreg Clayton return ValueObjectSP(); 65354979cddSGreg Clayton } 65454979cddSGreg Clayton } 655*b9c1b51eSKate Stone child_valobj_sp = 656*b9c1b51eSKate Stone valobj_sp->GetChildMemberWithName(child_name, true); 657*b9c1b51eSKate Stone if (!child_valobj_sp) { 658*b9c1b51eSKate Stone if (!no_synth_child) { 65986cc9829SEnrico Granata child_valobj_sp = valobj_sp->GetSyntheticValue(); 66086cc9829SEnrico Granata if (child_valobj_sp) 661*b9c1b51eSKate Stone child_valobj_sp = 662*b9c1b51eSKate Stone child_valobj_sp->GetChildMemberWithName(child_name, true); 66386cc9829SEnrico Granata } 6648c9d3560SEnrico Granata 665*b9c1b51eSKate Stone if (no_synth_child || !child_valobj_sp) { 6668b2fe6dcSGreg Clayton // No child member with name "child_name" 667*b9c1b51eSKate Stone if (synthetically_added_instance_object) { 668*b9c1b51eSKate Stone // We added a "this->" or "self->" to the beginning of the 669*b9c1b51eSKate Stone // expression 670*b9c1b51eSKate Stone // and this is the first pointer ivar access, so just return 671*b9c1b51eSKate Stone // the normal 672685c88c5SGreg Clayton // error 673*b9c1b51eSKate Stone error.SetErrorStringWithFormat( 674*b9c1b51eSKate Stone "no variable or instance variable named '%s' found in " 675*b9c1b51eSKate Stone "this frame", 676685c88c5SGreg Clayton name_const_string.GetCString()); 677*b9c1b51eSKate Stone } else { 6786beaaa68SGreg Clayton valobj_sp->GetExpressionPath(var_expr_path_strm, false); 679*b9c1b51eSKate Stone if (child_name) { 680*b9c1b51eSKate Stone error.SetErrorStringWithFormat( 681*b9c1b51eSKate Stone "\"%s\" is not a member of \"(%s) %s\"", 68254979cddSGreg Clayton child_name.GetCString(), 68354979cddSGreg Clayton valobj_sp->GetTypeName().AsCString("<invalid type>"), 68454979cddSGreg Clayton var_expr_path_strm.GetString().c_str()); 685*b9c1b51eSKate Stone } else { 686*b9c1b51eSKate Stone error.SetErrorStringWithFormat( 687*b9c1b51eSKate Stone "incomplete expression path after \"%s\" in \"%s\"", 688*b9c1b51eSKate Stone var_expr_path_strm.GetString().c_str(), var_expr_cstr); 68954979cddSGreg Clayton } 690685c88c5SGreg Clayton } 6918b2fe6dcSGreg Clayton return ValueObjectSP(); 6928b2fe6dcSGreg Clayton } 6938c9d3560SEnrico Granata } 694685c88c5SGreg Clayton synthetically_added_instance_object = false; 6958b2fe6dcSGreg Clayton // Remove the child name from the path 6968b2fe6dcSGreg Clayton var_path.erase(0, child_name.GetLength()); 697*b9c1b51eSKate Stone if (use_dynamic != eNoDynamicValues) { 698*b9c1b51eSKate Stone ValueObjectSP dynamic_value_sp( 699*b9c1b51eSKate Stone child_valobj_sp->GetDynamicValue(use_dynamic)); 70078a685aaSJim Ingham if (dynamic_value_sp) 70178a685aaSJim Ingham child_valobj_sp = dynamic_value_sp; 70278a685aaSJim Ingham } 703*b9c1b51eSKate Stone } break; 7048b2fe6dcSGreg Clayton 7058b2fe6dcSGreg Clayton case '[': 7068b2fe6dcSGreg Clayton // Array member access, or treating pointer as an array 7078b2fe6dcSGreg Clayton if (var_path.size() > 2) // Need at least two brackets and a number 7088b2fe6dcSGreg Clayton { 709d70a6e71SEugene Zelenko char *end = nullptr; 7101a65ae11SGreg Clayton long child_index = ::strtol(&var_path[1], &end, 0); 711*b9c1b51eSKate Stone if (end && *end == ']' && 712*b9c1b51eSKate Stone *(end - 1) != '[') // this code forces an error in the case of 713*b9c1b51eSKate Stone // arr[]. as bitfield[] is not a good 714*b9c1b51eSKate Stone // syntax we're good to go 7158b2fe6dcSGreg Clayton { 716*b9c1b51eSKate Stone if (valobj_sp->GetCompilerType().IsPointerToScalarType() && 717*b9c1b51eSKate Stone deref) { 718*b9c1b51eSKate Stone // what we have is *ptr[low]. the most similar C++ syntax is 719*b9c1b51eSKate Stone // to deref ptr 7209fc1944eSEnrico Granata // and extract bit low out of it. reading array item low 7219fc1944eSEnrico Granata // would be done by saying ptr[low], without a deref * sign 7229fc1944eSEnrico Granata Error error; 7239fc1944eSEnrico Granata ValueObjectSP temp(valobj_sp->Dereference(error)); 724*b9c1b51eSKate Stone if (error.Fail()) { 7259fc1944eSEnrico Granata valobj_sp->GetExpressionPath(var_expr_path_strm, false); 726*b9c1b51eSKate Stone error.SetErrorStringWithFormat( 727*b9c1b51eSKate Stone "could not dereference \"(%s) %s\"", 7289fc1944eSEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 7299fc1944eSEnrico Granata var_expr_path_strm.GetString().c_str()); 7309fc1944eSEnrico Granata return ValueObjectSP(); 7319fc1944eSEnrico Granata } 7329fc1944eSEnrico Granata valobj_sp = temp; 7339fc1944eSEnrico Granata deref = false; 734*b9c1b51eSKate Stone } else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() && 735*b9c1b51eSKate Stone deref) { 736*b9c1b51eSKate Stone // what we have is *arr[low]. the most similar C++ syntax is 737*b9c1b51eSKate Stone // to get arr[0] 7389fc1944eSEnrico Granata // (an operation that is equivalent to deref-ing arr) 7399fc1944eSEnrico Granata // and extract bit low out of it. reading array item low 7409fc1944eSEnrico Granata // would be done by saying arr[low], without a deref * sign 7419fc1944eSEnrico Granata Error error; 7429fc1944eSEnrico Granata ValueObjectSP temp(valobj_sp->GetChildAtIndex(0, true)); 743*b9c1b51eSKate Stone if (error.Fail()) { 7449fc1944eSEnrico Granata valobj_sp->GetExpressionPath(var_expr_path_strm, false); 745*b9c1b51eSKate Stone error.SetErrorStringWithFormat( 746*b9c1b51eSKate Stone "could not get item 0 for \"(%s) %s\"", 7479fc1944eSEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 7489fc1944eSEnrico Granata var_expr_path_strm.GetString().c_str()); 7499fc1944eSEnrico Granata return ValueObjectSP(); 7509fc1944eSEnrico Granata } 7519fc1944eSEnrico Granata valobj_sp = temp; 7529fc1944eSEnrico Granata deref = false; 7539fc1944eSEnrico Granata } 7548b2fe6dcSGreg Clayton 7554ef877f5SGreg Clayton bool is_incomplete_array = false; 756*b9c1b51eSKate Stone if (valobj_sp->IsPointerType()) { 757226b70c1SSean Callanan bool is_objc_pointer = true; 758226b70c1SSean Callanan 759*b9c1b51eSKate Stone if (valobj_sp->GetCompilerType().GetMinimumLanguage() != 760*b9c1b51eSKate Stone eLanguageTypeObjC) 761226b70c1SSean Callanan is_objc_pointer = false; 76299558cc4SGreg Clayton else if (!valobj_sp->GetCompilerType().IsPointerType()) 763226b70c1SSean Callanan is_objc_pointer = false; 764226b70c1SSean Callanan 765*b9c1b51eSKate Stone if (no_synth_child && is_objc_pointer) { 766*b9c1b51eSKate Stone error.SetErrorStringWithFormat( 767*b9c1b51eSKate Stone "\"(%s) %s\" is an Objective-C pointer, and cannot be " 768*b9c1b51eSKate Stone "subscripted", 769226b70c1SSean Callanan valobj_sp->GetTypeName().AsCString("<invalid type>"), 770226b70c1SSean Callanan var_expr_path_strm.GetString().c_str()); 771226b70c1SSean Callanan 772226b70c1SSean Callanan return ValueObjectSP(); 773*b9c1b51eSKate Stone } else if (is_objc_pointer) { 774*b9c1b51eSKate Stone // dereferencing ObjC variables is not valid.. so let's try 775*b9c1b51eSKate Stone // and recur to synthetic children 77686cc9829SEnrico Granata ValueObjectSP synthetic = valobj_sp->GetSyntheticValue(); 777d70a6e71SEugene Zelenko if (!synthetic /* no synthetic */ 778*b9c1b51eSKate Stone || synthetic == valobj_sp) /* synthetic is the same as 779*b9c1b51eSKate Stone the original object */ 78027b625e1SEnrico Granata { 78127b625e1SEnrico Granata valobj_sp->GetExpressionPath(var_expr_path_strm, false); 782*b9c1b51eSKate Stone error.SetErrorStringWithFormat( 783*b9c1b51eSKate Stone "\"(%s) %s\" is not an array type", 78427b625e1SEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 78527b625e1SEnrico Granata var_expr_path_strm.GetString().c_str()); 786*b9c1b51eSKate Stone } else if ( 787*b9c1b51eSKate Stone static_cast<uint32_t>(child_index) >= 788*b9c1b51eSKate Stone synthetic 789*b9c1b51eSKate Stone ->GetNumChildren() /* synthetic does not have that many values */) { 79027b625e1SEnrico Granata valobj_sp->GetExpressionPath(var_expr_path_strm, false); 791*b9c1b51eSKate Stone error.SetErrorStringWithFormat( 792*b9c1b51eSKate Stone "array index %ld is not valid for \"(%s) %s\"", 79327b625e1SEnrico Granata child_index, 79427b625e1SEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 79527b625e1SEnrico Granata var_expr_path_strm.GetString().c_str()); 796*b9c1b51eSKate Stone } else { 797*b9c1b51eSKate Stone child_valobj_sp = 798*b9c1b51eSKate Stone synthetic->GetChildAtIndex(child_index, true); 799*b9c1b51eSKate Stone if (!child_valobj_sp) { 80027b625e1SEnrico Granata valobj_sp->GetExpressionPath(var_expr_path_strm, false); 801*b9c1b51eSKate Stone error.SetErrorStringWithFormat( 802*b9c1b51eSKate Stone "array index %ld is not valid for \"(%s) %s\"", 803*b9c1b51eSKate Stone child_index, valobj_sp->GetTypeName().AsCString( 804*b9c1b51eSKate Stone "<invalid type>"), 805*b9c1b51eSKate Stone var_expr_path_strm.GetString().c_str()); 806*b9c1b51eSKate Stone } 807*b9c1b51eSKate Stone } 808*b9c1b51eSKate Stone } else { 809*b9c1b51eSKate Stone child_valobj_sp = 810*b9c1b51eSKate Stone valobj_sp->GetSyntheticArrayMember(child_index, true); 811*b9c1b51eSKate Stone if (!child_valobj_sp) { 812*b9c1b51eSKate Stone valobj_sp->GetExpressionPath(var_expr_path_strm, false); 813*b9c1b51eSKate Stone error.SetErrorStringWithFormat( 814*b9c1b51eSKate Stone "failed to use pointer as array for index %ld for " 815*b9c1b51eSKate Stone "\"(%s) %s\"", 81627b625e1SEnrico Granata child_index, 81727b625e1SEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 81827b625e1SEnrico Granata var_expr_path_strm.GetString().c_str()); 81927b625e1SEnrico Granata } 82027b625e1SEnrico Granata } 821*b9c1b51eSKate Stone } else if (valobj_sp->GetCompilerType().IsArrayType( 822*b9c1b51eSKate Stone nullptr, nullptr, &is_incomplete_array)) { 823*b9c1b51eSKate Stone // Pass false to dynamic_value here so we can tell the 824*b9c1b51eSKate Stone // difference between 82578a685aaSJim Ingham // no dynamic value and no member of this type... 826*b9c1b51eSKate Stone child_valobj_sp = 827*b9c1b51eSKate Stone valobj_sp->GetChildAtIndex(child_index, true); 828*b9c1b51eSKate Stone if (!child_valobj_sp && 829*b9c1b51eSKate Stone (is_incomplete_array || !no_synth_child)) 830*b9c1b51eSKate Stone child_valobj_sp = 831*b9c1b51eSKate Stone valobj_sp->GetSyntheticArrayMember(child_index, true); 8324ef877f5SGreg Clayton 833*b9c1b51eSKate Stone if (!child_valobj_sp) { 8346beaaa68SGreg Clayton valobj_sp->GetExpressionPath(var_expr_path_strm, false); 835*b9c1b51eSKate Stone error.SetErrorStringWithFormat( 836*b9c1b51eSKate Stone "array index %ld is not valid for \"(%s) %s\"", 83754979cddSGreg Clayton child_index, 83854979cddSGreg Clayton valobj_sp->GetTypeName().AsCString("<invalid type>"), 83954979cddSGreg Clayton var_expr_path_strm.GetString().c_str()); 84054979cddSGreg Clayton } 841*b9c1b51eSKate Stone } else if (valobj_sp->GetCompilerType().IsScalarType()) { 8429fc1944eSEnrico Granata // this is a bitfield asking to display just one bit 843*b9c1b51eSKate Stone child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild( 844*b9c1b51eSKate Stone child_index, child_index, true); 845*b9c1b51eSKate Stone if (!child_valobj_sp) { 8469fc1944eSEnrico Granata valobj_sp->GetExpressionPath(var_expr_path_strm, false); 847*b9c1b51eSKate Stone error.SetErrorStringWithFormat( 848*b9c1b51eSKate Stone "bitfield range %ld-%ld is not valid for \"(%s) %s\"", 8499fc1944eSEnrico Granata child_index, child_index, 8509fc1944eSEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 8519fc1944eSEnrico Granata var_expr_path_strm.GetString().c_str()); 8529fc1944eSEnrico Granata } 853*b9c1b51eSKate Stone } else { 85486cc9829SEnrico Granata ValueObjectSP synthetic = valobj_sp->GetSyntheticValue(); 85527b625e1SEnrico Granata if (no_synth_child /* synthetic is forbidden */ || 856d70a6e71SEugene Zelenko !synthetic /* no synthetic */ 857*b9c1b51eSKate Stone || 858*b9c1b51eSKate Stone synthetic == valobj_sp) /* synthetic is the same as the 859*b9c1b51eSKate Stone original object */ 86027b625e1SEnrico Granata { 8616beaaa68SGreg Clayton valobj_sp->GetExpressionPath(var_expr_path_strm, false); 862*b9c1b51eSKate Stone error.SetErrorStringWithFormat( 863*b9c1b51eSKate Stone "\"(%s) %s\" is not an array type", 86454979cddSGreg Clayton valobj_sp->GetTypeName().AsCString("<invalid type>"), 86554979cddSGreg Clayton var_expr_path_strm.GetString().c_str()); 866*b9c1b51eSKate Stone } else if ( 867*b9c1b51eSKate Stone static_cast<uint32_t>(child_index) >= 868*b9c1b51eSKate Stone synthetic 869*b9c1b51eSKate Stone ->GetNumChildren() /* synthetic does not have that many values */) { 87027b625e1SEnrico Granata valobj_sp->GetExpressionPath(var_expr_path_strm, false); 871*b9c1b51eSKate Stone error.SetErrorStringWithFormat( 872*b9c1b51eSKate Stone "array index %ld is not valid for \"(%s) %s\"", 87327b625e1SEnrico Granata child_index, 87427b625e1SEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 87527b625e1SEnrico Granata var_expr_path_strm.GetString().c_str()); 876*b9c1b51eSKate Stone } else { 877*b9c1b51eSKate Stone child_valobj_sp = 878*b9c1b51eSKate Stone synthetic->GetChildAtIndex(child_index, true); 879*b9c1b51eSKate Stone if (!child_valobj_sp) { 88027b625e1SEnrico Granata valobj_sp->GetExpressionPath(var_expr_path_strm, false); 881*b9c1b51eSKate Stone error.SetErrorStringWithFormat( 882*b9c1b51eSKate Stone "array index %ld is not valid for \"(%s) %s\"", 88327b625e1SEnrico Granata child_index, 88427b625e1SEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 88527b625e1SEnrico Granata var_expr_path_strm.GetString().c_str()); 88627b625e1SEnrico Granata } 88727b625e1SEnrico Granata } 88827b625e1SEnrico Granata } 8898b2fe6dcSGreg Clayton 890*b9c1b51eSKate Stone if (!child_valobj_sp) { 8918b2fe6dcSGreg Clayton // Invalid array index... 8928b2fe6dcSGreg Clayton return ValueObjectSP(); 8938b2fe6dcSGreg Clayton } 8948b2fe6dcSGreg Clayton 8958b2fe6dcSGreg Clayton // Erase the array member specification '[%i]' where 8968b2fe6dcSGreg Clayton // %i is the array index 8978b2fe6dcSGreg Clayton var_path.erase(0, (end - var_path.c_str()) + 1); 8988b2fe6dcSGreg Clayton separator_idx = var_path.find_first_of(".-["); 899*b9c1b51eSKate Stone if (use_dynamic != eNoDynamicValues) { 900*b9c1b51eSKate Stone ValueObjectSP dynamic_value_sp( 901*b9c1b51eSKate Stone child_valobj_sp->GetDynamicValue(use_dynamic)); 90278a685aaSJim Ingham if (dynamic_value_sp) 90378a685aaSJim Ingham child_valobj_sp = dynamic_value_sp; 90478a685aaSJim Ingham } 9058b2fe6dcSGreg Clayton // Break out early from the switch since we were 9068b2fe6dcSGreg Clayton // able to find the child member 9078b2fe6dcSGreg Clayton break; 908*b9c1b51eSKate Stone } else if (end && *end == '-') { 9099fc1944eSEnrico Granata // this is most probably a BitField, let's take a look 910d70a6e71SEugene Zelenko char *real_end = nullptr; 9119fc1944eSEnrico Granata long final_index = ::strtol(end + 1, &real_end, 0); 912d64d0bc0SEnrico Granata bool expand_bitfield = true; 913*b9c1b51eSKate Stone if (real_end && *real_end == ']') { 9149fc1944eSEnrico Granata // if the format given is [high-low], swap range 915*b9c1b51eSKate Stone if (child_index > final_index) { 9169fc1944eSEnrico Granata long temp = child_index; 9179fc1944eSEnrico Granata child_index = final_index; 9189fc1944eSEnrico Granata final_index = temp; 9199fc1944eSEnrico Granata } 9209fc1944eSEnrico Granata 921*b9c1b51eSKate Stone if (valobj_sp->GetCompilerType().IsPointerToScalarType() && 922*b9c1b51eSKate Stone deref) { 923*b9c1b51eSKate Stone // what we have is *ptr[low-high]. the most similar C++ 924*b9c1b51eSKate Stone // syntax is to deref ptr 925*b9c1b51eSKate Stone // and extract bits low thru high out of it. reading array 926*b9c1b51eSKate Stone // items low thru high 927*b9c1b51eSKate Stone // would be done by saying ptr[low-high], without a deref * 928*b9c1b51eSKate Stone // sign 9299fc1944eSEnrico Granata Error error; 9309fc1944eSEnrico Granata ValueObjectSP temp(valobj_sp->Dereference(error)); 931*b9c1b51eSKate Stone if (error.Fail()) { 9329fc1944eSEnrico Granata valobj_sp->GetExpressionPath(var_expr_path_strm, false); 933*b9c1b51eSKate Stone error.SetErrorStringWithFormat( 934*b9c1b51eSKate Stone "could not dereference \"(%s) %s\"", 9359fc1944eSEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 9369fc1944eSEnrico Granata var_expr_path_strm.GetString().c_str()); 9379fc1944eSEnrico Granata return ValueObjectSP(); 9389fc1944eSEnrico Granata } 9399fc1944eSEnrico Granata valobj_sp = temp; 9409fc1944eSEnrico Granata deref = false; 941*b9c1b51eSKate Stone } else if (valobj_sp->GetCompilerType() 942*b9c1b51eSKate Stone .IsArrayOfScalarType() && 943*b9c1b51eSKate Stone deref) { 944*b9c1b51eSKate Stone // what we have is *arr[low-high]. the most similar C++ 945*b9c1b51eSKate Stone // syntax is to get arr[0] 9469fc1944eSEnrico Granata // (an operation that is equivalent to deref-ing arr) 947*b9c1b51eSKate Stone // and extract bits low thru high out of it. reading array 948*b9c1b51eSKate Stone // items low thru high 949*b9c1b51eSKate Stone // would be done by saying arr[low-high], without a deref * 950*b9c1b51eSKate Stone // sign 9519fc1944eSEnrico Granata Error error; 9529fc1944eSEnrico Granata ValueObjectSP temp(valobj_sp->GetChildAtIndex(0, true)); 953*b9c1b51eSKate Stone if (error.Fail()) { 9549fc1944eSEnrico Granata valobj_sp->GetExpressionPath(var_expr_path_strm, false); 955*b9c1b51eSKate Stone error.SetErrorStringWithFormat( 956*b9c1b51eSKate Stone "could not get item 0 for \"(%s) %s\"", 9579fc1944eSEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 9589fc1944eSEnrico Granata var_expr_path_strm.GetString().c_str()); 9599fc1944eSEnrico Granata return ValueObjectSP(); 9609fc1944eSEnrico Granata } 9619fc1944eSEnrico Granata valobj_sp = temp; 9629fc1944eSEnrico Granata deref = false; 9639fc1944eSEnrico Granata } 964*b9c1b51eSKate Stone /*else if (valobj_sp->IsArrayType() || 965*b9c1b51eSKate Stone valobj_sp->IsPointerType()) 966d64d0bc0SEnrico Granata { 967*b9c1b51eSKate Stone child_valobj_sp = 968*b9c1b51eSKate Stone valobj_sp->GetSyntheticArrayRangeChild(child_index, 969*b9c1b51eSKate Stone final_index, true); 970d64d0bc0SEnrico Granata expand_bitfield = false; 971d64d0bc0SEnrico Granata if (!child_valobj_sp) 972d64d0bc0SEnrico Granata { 973*b9c1b51eSKate Stone valobj_sp->GetExpressionPath (var_expr_path_strm, 974*b9c1b51eSKate Stone false); 975*b9c1b51eSKate Stone error.SetErrorStringWithFormat ("array range %i-%i is 976*b9c1b51eSKate Stone not valid for \"(%s) %s\"", 977*b9c1b51eSKate Stone child_index, 978*b9c1b51eSKate Stone final_index, 979*b9c1b51eSKate Stone valobj_sp->GetTypeName().AsCString("<invalid 980*b9c1b51eSKate Stone type>"), 981d64d0bc0SEnrico Granata var_expr_path_strm.GetString().c_str()); 982d64d0bc0SEnrico Granata } 983d64d0bc0SEnrico Granata }*/ 9849fc1944eSEnrico Granata 985*b9c1b51eSKate Stone if (expand_bitfield) { 986*b9c1b51eSKate Stone child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild( 987*b9c1b51eSKate Stone child_index, final_index, true); 988*b9c1b51eSKate Stone if (!child_valobj_sp) { 9899fc1944eSEnrico Granata valobj_sp->GetExpressionPath(var_expr_path_strm, false); 990*b9c1b51eSKate Stone error.SetErrorStringWithFormat( 991*b9c1b51eSKate Stone "bitfield range %ld-%ld is not valid for \"(%s) %s\"", 9929fc1944eSEnrico Granata child_index, final_index, 9939fc1944eSEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 9949fc1944eSEnrico Granata var_expr_path_strm.GetString().c_str()); 9959fc1944eSEnrico Granata } 9969fc1944eSEnrico Granata } 997d64d0bc0SEnrico Granata } 9989fc1944eSEnrico Granata 999*b9c1b51eSKate Stone if (!child_valobj_sp) { 10009fc1944eSEnrico Granata // Invalid bitfield range... 10019fc1944eSEnrico Granata return ValueObjectSP(); 10029fc1944eSEnrico Granata } 10039fc1944eSEnrico Granata 10049fc1944eSEnrico Granata // Erase the bitfield member specification '[%i-%i]' where 10059fc1944eSEnrico Granata // %i is the index 10069fc1944eSEnrico Granata var_path.erase(0, (real_end - var_path.c_str()) + 1); 10079fc1944eSEnrico Granata separator_idx = var_path.find_first_of(".-["); 1008*b9c1b51eSKate Stone if (use_dynamic != eNoDynamicValues) { 1009*b9c1b51eSKate Stone ValueObjectSP dynamic_value_sp( 1010*b9c1b51eSKate Stone child_valobj_sp->GetDynamicValue(use_dynamic)); 10119fc1944eSEnrico Granata if (dynamic_value_sp) 10129fc1944eSEnrico Granata child_valobj_sp = dynamic_value_sp; 10139fc1944eSEnrico Granata } 10149fc1944eSEnrico Granata // Break out early from the switch since we were 10159fc1944eSEnrico Granata // able to find the child member 10169fc1944eSEnrico Granata break; 10179fc1944eSEnrico Granata } 1018*b9c1b51eSKate Stone } else { 1019*b9c1b51eSKate Stone error.SetErrorStringWithFormat( 1020*b9c1b51eSKate Stone "invalid square bracket encountered after \"%s\" in \"%s\"", 1021*b9c1b51eSKate Stone var_expr_path_strm.GetString().c_str(), var_path.c_str()); 10228b2fe6dcSGreg Clayton } 10238b2fe6dcSGreg Clayton return ValueObjectSP(); 10248b2fe6dcSGreg Clayton 10258b2fe6dcSGreg Clayton default: 10268b2fe6dcSGreg Clayton // Failure... 102754979cddSGreg Clayton { 10286beaaa68SGreg Clayton valobj_sp->GetExpressionPath(var_expr_path_strm, false); 1029*b9c1b51eSKate Stone error.SetErrorStringWithFormat( 1030*b9c1b51eSKate Stone "unexpected char '%c' encountered after \"%s\" in \"%s\"", 1031*b9c1b51eSKate Stone separator_type, var_expr_path_strm.GetString().c_str(), 103254979cddSGreg Clayton var_path.c_str()); 103354979cddSGreg Clayton 10348b2fe6dcSGreg Clayton return ValueObjectSP(); 10358b2fe6dcSGreg Clayton } 103654979cddSGreg Clayton } 10378b2fe6dcSGreg Clayton 10388b2fe6dcSGreg Clayton if (child_valobj_sp) 10398b2fe6dcSGreg Clayton valobj_sp = child_valobj_sp; 10408b2fe6dcSGreg Clayton 10418b2fe6dcSGreg Clayton if (var_path.empty()) 10428b2fe6dcSGreg Clayton break; 10438b2fe6dcSGreg Clayton } 1044*b9c1b51eSKate Stone if (valobj_sp) { 1045*b9c1b51eSKate Stone if (deref) { 1046af67cecdSGreg Clayton ValueObjectSP deref_valobj_sp(valobj_sp->Dereference(error)); 10478b2fe6dcSGreg Clayton valobj_sp = deref_valobj_sp; 1048*b9c1b51eSKate Stone } else if (address_of) { 104954979cddSGreg Clayton ValueObjectSP address_of_valobj_sp(valobj_sp->AddressOf(error)); 10508b2fe6dcSGreg Clayton valobj_sp = address_of_valobj_sp; 10518b2fe6dcSGreg Clayton } 10528b2fe6dcSGreg Clayton } 10538b2fe6dcSGreg Clayton return valobj_sp; 1054*b9c1b51eSKate Stone } else { 1055*b9c1b51eSKate Stone error.SetErrorStringWithFormat( 1056*b9c1b51eSKate Stone "no variable named '%s' found in this frame", 10572837b766SJim Ingham name_const_string.GetCString()); 105854979cddSGreg Clayton } 105954979cddSGreg Clayton } 1060*b9c1b51eSKate Stone } else { 106154979cddSGreg Clayton error.SetErrorStringWithFormat("invalid variable path '%s'", var_expr_cstr); 10628b2fe6dcSGreg Clayton } 10638b2fe6dcSGreg Clayton return ValueObjectSP(); 10648b2fe6dcSGreg Clayton } 106530fdc8d8SChris Lattner 1066*b9c1b51eSKate Stone bool StackFrame::GetFrameBaseValue(Scalar &frame_base, Error *error_ptr) { 1067bb19a13cSSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex); 1068*b9c1b51eSKate Stone if (!m_cfa_is_valid) { 1069*b9c1b51eSKate Stone m_frame_base_error.SetErrorString( 1070*b9c1b51eSKate Stone "No frame base available for this historical stack frame."); 107199618476SJason Molenda return false; 107299618476SJason Molenda } 107399618476SJason Molenda 1074*b9c1b51eSKate Stone if (m_flags.IsClear(GOT_FRAME_BASE)) { 1075*b9c1b51eSKate Stone if (m_sc.function) { 107630fdc8d8SChris Lattner m_frame_base.Clear(); 107730fdc8d8SChris Lattner m_frame_base_error.Clear(); 107830fdc8d8SChris Lattner 107930fdc8d8SChris Lattner m_flags.Set(GOT_FRAME_BASE); 1080d9e416c0SGreg Clayton ExecutionContext exe_ctx(shared_from_this()); 108130fdc8d8SChris Lattner Value expr_value; 1082016a95ebSGreg Clayton addr_t loclist_base_addr = LLDB_INVALID_ADDRESS; 1083016a95ebSGreg Clayton if (m_sc.function->GetFrameBaseExpression().IsLocationList()) 1084*b9c1b51eSKate Stone loclist_base_addr = 1085*b9c1b51eSKate Stone m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress( 1086*b9c1b51eSKate Stone exe_ctx.GetTargetPtr()); 1087016a95ebSGreg Clayton 1088*b9c1b51eSKate Stone if (m_sc.function->GetFrameBaseExpression().Evaluate( 1089*b9c1b51eSKate Stone &exe_ctx, nullptr, nullptr, nullptr, loclist_base_addr, nullptr, 1090*b9c1b51eSKate Stone nullptr, expr_value, &m_frame_base_error) == false) { 109130fdc8d8SChris Lattner // We should really have an error if evaluate returns, but in case 109230fdc8d8SChris Lattner // we don't, lets set the error to something at least. 109330fdc8d8SChris Lattner if (m_frame_base_error.Success()) 1094*b9c1b51eSKate Stone m_frame_base_error.SetErrorString( 1095*b9c1b51eSKate Stone "Evaluation of the frame base expression failed."); 1096*b9c1b51eSKate Stone } else { 109757ee3067SGreg Clayton m_frame_base = expr_value.ResolveValue(&exe_ctx); 109830fdc8d8SChris Lattner } 1099*b9c1b51eSKate Stone } else { 110030fdc8d8SChris Lattner m_frame_base_error.SetErrorString("No function in symbol context."); 110130fdc8d8SChris Lattner } 110230fdc8d8SChris Lattner } 110330fdc8d8SChris Lattner 110430fdc8d8SChris Lattner if (m_frame_base_error.Success()) 110530fdc8d8SChris Lattner frame_base = m_frame_base; 110630fdc8d8SChris Lattner 110730fdc8d8SChris Lattner if (error_ptr) 110830fdc8d8SChris Lattner *error_ptr = m_frame_base_error; 110930fdc8d8SChris Lattner return m_frame_base_error.Success(); 111030fdc8d8SChris Lattner } 111130fdc8d8SChris Lattner 1112*b9c1b51eSKate Stone DWARFExpression *StackFrame::GetFrameBaseExpression(Error *error_ptr) { 1113*b9c1b51eSKate Stone if (!m_sc.function) { 1114*b9c1b51eSKate Stone if (error_ptr) { 11154740a734SSean Callanan error_ptr->SetErrorString("No function in symbol context."); 11164740a734SSean Callanan } 11174740a734SSean Callanan return nullptr; 11184740a734SSean Callanan } 11194740a734SSean Callanan 11204740a734SSean Callanan return &m_sc.function->GetFrameBaseExpression(); 11214740a734SSean Callanan } 11224740a734SSean Callanan 1123*b9c1b51eSKate Stone RegisterContextSP StackFrame::GetRegisterContext() { 1124bb19a13cSSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex); 1125*b9c1b51eSKate Stone if (!m_reg_context_sp) { 1126d9e416c0SGreg Clayton ThreadSP thread_sp(GetThread()); 1127d9e416c0SGreg Clayton if (thread_sp) 1128d9e416c0SGreg Clayton m_reg_context_sp = thread_sp->CreateRegisterContextForFrame(this); 1129d9e416c0SGreg Clayton } 11305ccbd294SGreg Clayton return m_reg_context_sp; 113130fdc8d8SChris Lattner } 113230fdc8d8SChris Lattner 1133*b9c1b51eSKate Stone bool StackFrame::HasDebugInformation() { 113430fdc8d8SChris Lattner GetSymbolContext(eSymbolContextLineEntry); 113530fdc8d8SChris Lattner return m_sc.line_entry.IsValid(); 113630fdc8d8SChris Lattner } 113730fdc8d8SChris Lattner 1138288bdf9cSGreg Clayton ValueObjectSP 1139*b9c1b51eSKate Stone StackFrame::GetValueObjectForFrameVariable(const VariableSP &variable_sp, 1140*b9c1b51eSKate Stone DynamicValueType use_dynamic) { 1141bb19a13cSSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex); 1142288bdf9cSGreg Clayton ValueObjectSP valobj_sp; 1143*b9c1b51eSKate Stone if (m_is_history_frame) { 114499618476SJason Molenda return valobj_sp; 114599618476SJason Molenda } 1146288bdf9cSGreg Clayton VariableList *var_list = GetVariableList(true); 1147*b9c1b51eSKate Stone if (var_list) { 1148288bdf9cSGreg Clayton // Make sure the variable is a frame variable 1149288bdf9cSGreg Clayton const uint32_t var_idx = var_list->FindIndexForVariable(variable_sp.get()); 1150288bdf9cSGreg Clayton const uint32_t num_variables = var_list->GetSize(); 1151*b9c1b51eSKate Stone if (var_idx < num_variables) { 1152288bdf9cSGreg Clayton valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex(var_idx); 1153*b9c1b51eSKate Stone if (!valobj_sp) { 1154288bdf9cSGreg Clayton if (m_variable_list_value_objects.GetSize() < num_variables) 1155288bdf9cSGreg Clayton m_variable_list_value_objects.Resize(num_variables); 115658b59f95SJim Ingham valobj_sp = ValueObjectVariable::Create(this, variable_sp); 1157288bdf9cSGreg Clayton m_variable_list_value_objects.SetValueObjectAtIndex(var_idx, valobj_sp); 1158288bdf9cSGreg Clayton } 1159288bdf9cSGreg Clayton } 1160288bdf9cSGreg Clayton } 1161*b9c1b51eSKate Stone if (use_dynamic != eNoDynamicValues && valobj_sp) { 11622837b766SJim Ingham ValueObjectSP dynamic_sp = valobj_sp->GetDynamicValue(use_dynamic); 116378a685aaSJim Ingham if (dynamic_sp) 116478a685aaSJim Ingham return dynamic_sp; 116578a685aaSJim Ingham } 1166288bdf9cSGreg Clayton return valobj_sp; 1167288bdf9cSGreg Clayton } 1168288bdf9cSGreg Clayton 1169*b9c1b51eSKate Stone ValueObjectSP StackFrame::TrackGlobalVariable(const VariableSP &variable_sp, 1170*b9c1b51eSKate Stone DynamicValueType use_dynamic) { 1171bb19a13cSSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex); 117299618476SJason Molenda if (m_is_history_frame) 117399618476SJason Molenda return ValueObjectSP(); 117499618476SJason Molenda 1175288bdf9cSGreg Clayton // Check to make sure we aren't already tracking this variable? 1176*b9c1b51eSKate Stone ValueObjectSP valobj_sp( 1177*b9c1b51eSKate Stone GetValueObjectForFrameVariable(variable_sp, use_dynamic)); 1178*b9c1b51eSKate Stone if (!valobj_sp) { 1179288bdf9cSGreg Clayton // We aren't already tracking this global 1180288bdf9cSGreg Clayton VariableList *var_list = GetVariableList(true); 1181288bdf9cSGreg Clayton // If this frame has no variables, create a new list 1182d70a6e71SEugene Zelenko if (var_list == nullptr) 1183288bdf9cSGreg Clayton m_variable_list_sp.reset(new VariableList()); 1184288bdf9cSGreg Clayton 1185288bdf9cSGreg Clayton // Add the global/static variable to this frame 1186288bdf9cSGreg Clayton m_variable_list_sp->AddVariable(variable_sp); 1187288bdf9cSGreg Clayton 1188288bdf9cSGreg Clayton // Now make a value object for it so we can track its changes 118978a685aaSJim Ingham valobj_sp = GetValueObjectForFrameVariable(variable_sp, use_dynamic); 1190288bdf9cSGreg Clayton } 1191288bdf9cSGreg Clayton return valobj_sp; 119230fdc8d8SChris Lattner } 119330fdc8d8SChris Lattner 1194*b9c1b51eSKate Stone bool StackFrame::IsInlined() { 1195d70a6e71SEugene Zelenko if (m_sc.block == nullptr) 119659e8fc1cSGreg Clayton GetSymbolContext(eSymbolContextBlock); 119759e8fc1cSGreg Clayton if (m_sc.block) 1198d70a6e71SEugene Zelenko return m_sc.block->GetContainingInlinedBlock() != nullptr; 119959e8fc1cSGreg Clayton return false; 12006b8379c4SJim Ingham } 12016b8379c4SJim Ingham 1202*b9c1b51eSKate Stone lldb::LanguageType StackFrame::GetLanguage() { 1203009d110dSDawn Perchik CompileUnit *cu = GetSymbolContext(eSymbolContextCompUnit).comp_unit; 1204009d110dSDawn Perchik if (cu) 1205009d110dSDawn Perchik return cu->GetLanguage(); 1206009d110dSDawn Perchik return lldb::eLanguageTypeUnknown; 1207009d110dSDawn Perchik } 1208009d110dSDawn Perchik 1209*b9c1b51eSKate Stone lldb::LanguageType StackFrame::GuessLanguage() { 1210592afe73SEnrico Granata LanguageType lang_type = GetLanguage(); 1211592afe73SEnrico Granata 1212*b9c1b51eSKate Stone if (lang_type == eLanguageTypeUnknown) { 1213592afe73SEnrico Granata Function *f = GetSymbolContext(eSymbolContextFunction).function; 1214*b9c1b51eSKate Stone if (f) { 1215592afe73SEnrico Granata lang_type = f->GetMangled().GuessLanguage(); 1216592afe73SEnrico Granata } 1217592afe73SEnrico Granata } 1218592afe73SEnrico Granata 1219592afe73SEnrico Granata return lang_type; 1220592afe73SEnrico Granata } 1221592afe73SEnrico Granata 1222*b9c1b51eSKate Stone namespace { 12234740a734SSean Callanan std::pair<const Instruction::Operand *, int64_t> 12244740a734SSean Callanan GetBaseExplainingValue(const Instruction::Operand &operand, 1225*b9c1b51eSKate Stone RegisterContext ®ister_context, lldb::addr_t value) { 1226*b9c1b51eSKate Stone switch (operand.m_type) { 12274740a734SSean Callanan case Instruction::Operand::Type::Dereference: 12284740a734SSean Callanan case Instruction::Operand::Type::Immediate: 12294740a734SSean Callanan case Instruction::Operand::Type::Invalid: 12304740a734SSean Callanan case Instruction::Operand::Type::Product: 12314740a734SSean Callanan // These are not currently interesting 12324740a734SSean Callanan return std::make_pair(nullptr, 0); 1233*b9c1b51eSKate Stone case Instruction::Operand::Type::Sum: { 12344740a734SSean Callanan const Instruction::Operand *immediate_child = nullptr; 12354740a734SSean Callanan const Instruction::Operand *variable_child = nullptr; 1236*b9c1b51eSKate Stone if (operand.m_children[0].m_type == Instruction::Operand::Type::Immediate) { 12374740a734SSean Callanan immediate_child = &operand.m_children[0]; 12384740a734SSean Callanan variable_child = &operand.m_children[1]; 1239*b9c1b51eSKate Stone } else if (operand.m_children[1].m_type == 1240*b9c1b51eSKate Stone Instruction::Operand::Type::Immediate) { 12414740a734SSean Callanan immediate_child = &operand.m_children[1]; 12424740a734SSean Callanan variable_child = &operand.m_children[0]; 12434740a734SSean Callanan } 1244*b9c1b51eSKate Stone if (!immediate_child) { 12454740a734SSean Callanan return std::make_pair(nullptr, 0); 12464740a734SSean Callanan } 12474740a734SSean Callanan lldb::addr_t adjusted_value = value; 1248*b9c1b51eSKate Stone if (immediate_child->m_negative) { 12494740a734SSean Callanan adjusted_value += immediate_child->m_immediate; 1250*b9c1b51eSKate Stone } else { 12514740a734SSean Callanan adjusted_value -= immediate_child->m_immediate; 12524740a734SSean Callanan } 1253*b9c1b51eSKate Stone std::pair<const Instruction::Operand *, int64_t> base_and_offset = 1254*b9c1b51eSKate Stone GetBaseExplainingValue(*variable_child, register_context, 1255*b9c1b51eSKate Stone adjusted_value); 1256*b9c1b51eSKate Stone if (!base_and_offset.first) { 12574740a734SSean Callanan return std::make_pair(nullptr, 0); 12584740a734SSean Callanan } 1259*b9c1b51eSKate Stone if (immediate_child->m_negative) { 12604740a734SSean Callanan base_and_offset.second -= immediate_child->m_immediate; 1261*b9c1b51eSKate Stone } else { 12624740a734SSean Callanan base_and_offset.second += immediate_child->m_immediate; 12634740a734SSean Callanan } 12644740a734SSean Callanan return base_and_offset; 12654740a734SSean Callanan } 1266*b9c1b51eSKate Stone case Instruction::Operand::Type::Register: { 1267*b9c1b51eSKate Stone const RegisterInfo *info = 1268*b9c1b51eSKate Stone register_context.GetRegisterInfoByName(operand.m_register.AsCString()); 1269*b9c1b51eSKate Stone if (!info) { 12704740a734SSean Callanan return std::make_pair(nullptr, 0); 12714740a734SSean Callanan } 12724740a734SSean Callanan RegisterValue reg_value; 1273*b9c1b51eSKate Stone if (!register_context.ReadRegister(info, reg_value)) { 12744740a734SSean Callanan return std::make_pair(nullptr, 0); 12754740a734SSean Callanan } 1276*b9c1b51eSKate Stone if (reg_value.GetAsUInt64() == value) { 12774740a734SSean Callanan return std::make_pair(&operand, 0); 1278*b9c1b51eSKate Stone } else { 12794740a734SSean Callanan return std::make_pair(nullptr, 0); 12804740a734SSean Callanan } 12814740a734SSean Callanan } 12824740a734SSean Callanan } 12834740a734SSean Callanan } 12844740a734SSean Callanan 12854740a734SSean Callanan std::pair<const Instruction::Operand *, int64_t> 12864740a734SSean Callanan GetBaseExplainingDereference(const Instruction::Operand &operand, 12874740a734SSean Callanan RegisterContext ®ister_context, 1288*b9c1b51eSKate Stone lldb::addr_t addr) { 1289*b9c1b51eSKate Stone if (operand.m_type == Instruction::Operand::Type::Dereference) { 1290*b9c1b51eSKate Stone return GetBaseExplainingValue(operand.m_children[0], register_context, 12914740a734SSean Callanan addr); 12924740a734SSean Callanan } 12934740a734SSean Callanan return std::make_pair(nullptr, 0); 12944740a734SSean Callanan } 12954740a734SSean Callanan }; 12964740a734SSean Callanan 1297*b9c1b51eSKate Stone lldb::ValueObjectSP StackFrame::GuessValueForAddress(lldb::addr_t addr) { 12984740a734SSean Callanan TargetSP target_sp = CalculateTarget(); 12994740a734SSean Callanan 13004740a734SSean Callanan const ArchSpec &target_arch = target_sp->GetArchitecture(); 13014740a734SSean Callanan 13024740a734SSean Callanan AddressRange pc_range; 13034740a734SSean Callanan pc_range.GetBaseAddress() = GetFrameCodeAddress(); 13044740a734SSean Callanan pc_range.SetByteSize(target_arch.GetMaximumOpcodeByteSize()); 13054740a734SSean Callanan 13064740a734SSean Callanan ExecutionContext exe_ctx(shared_from_this()); 13074740a734SSean Callanan 13084740a734SSean Callanan const char *plugin_name = nullptr; 13094740a734SSean Callanan const char *flavor = nullptr; 13104740a734SSean Callanan const bool prefer_file_cache = false; 13114740a734SSean Callanan 1312*b9c1b51eSKate Stone DisassemblerSP disassembler_sp = Disassembler::DisassembleRange( 1313*b9c1b51eSKate Stone target_arch, plugin_name, flavor, exe_ctx, pc_range, prefer_file_cache); 13144740a734SSean Callanan 1315*b9c1b51eSKate Stone if (!disassembler_sp->GetInstructionList().GetSize()) { 13164740a734SSean Callanan return ValueObjectSP(); 13174740a734SSean Callanan } 13184740a734SSean Callanan 1319*b9c1b51eSKate Stone InstructionSP instruction_sp = 1320*b9c1b51eSKate Stone disassembler_sp->GetInstructionList().GetInstructionAtIndex(0); 13214740a734SSean Callanan 13224740a734SSean Callanan llvm::SmallVector<Instruction::Operand, 3> operands; 13234740a734SSean Callanan 1324*b9c1b51eSKate Stone if (!instruction_sp->ParseOperands(operands)) { 13254740a734SSean Callanan return ValueObjectSP(); 13264740a734SSean Callanan } 13274740a734SSean Callanan 13284740a734SSean Callanan RegisterContextSP register_context_sp = GetRegisterContext(); 13294740a734SSean Callanan 1330*b9c1b51eSKate Stone if (!register_context_sp) { 13314740a734SSean Callanan return ValueObjectSP(); 13324740a734SSean Callanan } 13334740a734SSean Callanan 1334*b9c1b51eSKate Stone for (const Instruction::Operand &operand : operands) { 1335*b9c1b51eSKate Stone std::pair<const Instruction::Operand *, int64_t> base_and_offset = 1336*b9c1b51eSKate Stone GetBaseExplainingDereference(operand, *register_context_sp, addr); 13374740a734SSean Callanan 1338*b9c1b51eSKate Stone if (!base_and_offset.first) { 13394740a734SSean Callanan continue; 13404740a734SSean Callanan } 13414740a734SSean Callanan 1342*b9c1b51eSKate Stone switch (base_and_offset.first->m_type) { 1343*b9c1b51eSKate Stone case Instruction::Operand::Type::Immediate: { 13444740a734SSean Callanan lldb_private::Address addr; 1345*b9c1b51eSKate Stone if (target_sp->ResolveLoadAddress(base_and_offset.first->m_immediate + 1346*b9c1b51eSKate Stone base_and_offset.second, 1347*b9c1b51eSKate Stone addr)) { 1348*b9c1b51eSKate Stone TypeSystem *c_type_system = 1349*b9c1b51eSKate Stone target_sp->GetScratchTypeSystemForLanguage(nullptr, eLanguageTypeC); 1350*b9c1b51eSKate Stone if (!c_type_system) { 13514740a734SSean Callanan return ValueObjectSP(); 1352*b9c1b51eSKate Stone } else { 1353*b9c1b51eSKate Stone CompilerType void_ptr_type = 1354*b9c1b51eSKate Stone c_type_system 1355*b9c1b51eSKate Stone ->GetBasicTypeFromAST(lldb::BasicType::eBasicTypeChar) 1356*b9c1b51eSKate Stone .GetPointerType(); 13574740a734SSean Callanan return ValueObjectMemory::Create(this, "", addr, void_ptr_type); 13584740a734SSean Callanan } 1359*b9c1b51eSKate Stone } else { 13604740a734SSean Callanan return ValueObjectSP(); 13614740a734SSean Callanan } 13624740a734SSean Callanan break; 13634740a734SSean Callanan } 1364*b9c1b51eSKate Stone case Instruction::Operand::Type::Register: { 1365*b9c1b51eSKate Stone return GuessValueForRegisterAndOffset(base_and_offset.first->m_register, 1366*b9c1b51eSKate Stone base_and_offset.second); 13674740a734SSean Callanan } 13684740a734SSean Callanan default: 13694740a734SSean Callanan return ValueObjectSP(); 13704740a734SSean Callanan } 13714740a734SSean Callanan } 13724740a734SSean Callanan 13734740a734SSean Callanan return ValueObjectSP(); 13744740a734SSean Callanan } 13754740a734SSean Callanan 1376*b9c1b51eSKate Stone namespace { 1377*b9c1b51eSKate Stone ValueObjectSP GetValueForOffset(StackFrame &frame, ValueObjectSP &parent, 1378*b9c1b51eSKate Stone int64_t offset) { 1379*b9c1b51eSKate Stone if (offset < 0 || uint64_t(offset) >= parent->GetByteSize()) { 13804740a734SSean Callanan return ValueObjectSP(); 13814740a734SSean Callanan } 13824740a734SSean Callanan 1383*b9c1b51eSKate Stone if (parent->IsPointerOrReferenceType()) { 13844740a734SSean Callanan return parent; 13854740a734SSean Callanan } 13864740a734SSean Callanan 1387*b9c1b51eSKate Stone for (int ci = 0, ce = parent->GetNumChildren(); ci != ce; ++ci) { 13884740a734SSean Callanan const bool can_create = true; 13894740a734SSean Callanan ValueObjectSP child_sp = parent->GetChildAtIndex(ci, can_create); 13904740a734SSean Callanan 1391*b9c1b51eSKate Stone if (!child_sp) { 13924740a734SSean Callanan return ValueObjectSP(); 13934740a734SSean Callanan } 13944740a734SSean Callanan 13954740a734SSean Callanan int64_t child_offset = child_sp->GetByteOffset(); 13964740a734SSean Callanan int64_t child_size = child_sp->GetByteSize(); 13974740a734SSean Callanan 1398*b9c1b51eSKate Stone if (offset >= child_offset && offset < (child_offset + child_size)) { 13994740a734SSean Callanan return GetValueForOffset(frame, child_sp, offset - child_offset); 14004740a734SSean Callanan } 14014740a734SSean Callanan } 14024740a734SSean Callanan 1403*b9c1b51eSKate Stone if (offset == 0) { 14044740a734SSean Callanan return parent; 1405*b9c1b51eSKate Stone } else { 14064740a734SSean Callanan return ValueObjectSP(); 14074740a734SSean Callanan } 14084740a734SSean Callanan } 14094740a734SSean Callanan 1410*b9c1b51eSKate Stone ValueObjectSP GetValueForDereferincingOffset(StackFrame &frame, 1411*b9c1b51eSKate Stone ValueObjectSP &base, 1412*b9c1b51eSKate Stone int64_t offset) { 14134740a734SSean Callanan // base is a pointer to something 14144740a734SSean Callanan // offset is the thing to add to the pointer 14154740a734SSean Callanan // We return the most sensible ValueObject for the result of *(base+offset) 14164740a734SSean Callanan 1417*b9c1b51eSKate Stone if (!base->IsPointerOrReferenceType()) { 14184740a734SSean Callanan return ValueObjectSP(); 14194740a734SSean Callanan } 14204740a734SSean Callanan 14214740a734SSean Callanan Error error; 14224740a734SSean Callanan ValueObjectSP pointee = base->Dereference(error); 14234740a734SSean Callanan 1424*b9c1b51eSKate Stone if (offset >= pointee->GetByteSize()) { 14254740a734SSean Callanan int64_t index = offset / pointee->GetByteSize(); 14264740a734SSean Callanan offset = offset % pointee->GetByteSize(); 14274740a734SSean Callanan const bool can_create = true; 14284740a734SSean Callanan pointee = base->GetSyntheticArrayMember(index, can_create); 14294740a734SSean Callanan } 14304740a734SSean Callanan 1431*b9c1b51eSKate Stone if (!pointee || error.Fail()) { 14324740a734SSean Callanan return ValueObjectSP(); 14334740a734SSean Callanan } 14344740a734SSean Callanan 14354740a734SSean Callanan return GetValueForOffset(frame, pointee, offset); 14364740a734SSean Callanan } 14374740a734SSean Callanan 14384740a734SSean Callanan //------------------------------------------------------------------ 14394740a734SSean Callanan /// Attempt to reconstruct the ValueObject for the address contained in a 14404740a734SSean Callanan /// given register plus an offset. 14414740a734SSean Callanan /// 14424740a734SSean Callanan /// @params [in] frame 14434740a734SSean Callanan /// The current stack frame. 14444740a734SSean Callanan /// 14454740a734SSean Callanan /// @params [in] reg 14464740a734SSean Callanan /// The register. 14474740a734SSean Callanan /// 14484740a734SSean Callanan /// @params [in] offset 14494740a734SSean Callanan /// The offset from the register. 14504740a734SSean Callanan /// 14514740a734SSean Callanan /// @param [in] disassembler 14524740a734SSean Callanan /// A disassembler containing instructions valid up to the current PC. 14534740a734SSean Callanan /// 14544740a734SSean Callanan /// @param [in] variables 14554740a734SSean Callanan /// The variable list from the current frame, 14564740a734SSean Callanan /// 14574740a734SSean Callanan /// @param [in] pc 14584740a734SSean Callanan /// The program counter for the instruction considered the 'user'. 14594740a734SSean Callanan /// 14604740a734SSean Callanan /// @return 14614740a734SSean Callanan /// A string describing the base for the ExpressionPath. This could be a 14624740a734SSean Callanan /// variable, a register value, an argument, or a function return value. 14634740a734SSean Callanan /// The ValueObject if found. If valid, it has a valid ExpressionPath. 14644740a734SSean Callanan //------------------------------------------------------------------ 1465*b9c1b51eSKate Stone lldb::ValueObjectSP DoGuessValueAt(StackFrame &frame, ConstString reg, 1466*b9c1b51eSKate Stone int64_t offset, Disassembler &disassembler, 1467*b9c1b51eSKate Stone VariableList &variables, const Address &pc) { 14684740a734SSean Callanan // Example of operation for Intel: 14694740a734SSean Callanan // 14704740a734SSean Callanan // +14: movq -0x8(%rbp), %rdi 14714740a734SSean Callanan // +18: movq 0x8(%rdi), %rdi 14724740a734SSean Callanan // +22: addl 0x4(%rdi), %eax 14734740a734SSean Callanan // 14744740a734SSean Callanan // f, a pointer to a struct, is known to be at -0x8(%rbp). 14754740a734SSean Callanan // 1476*b9c1b51eSKate Stone // DoGuessValueAt(frame, rdi, 4, dis, vars, 0x22) finds the instruction at +18 1477*b9c1b51eSKate Stone // that assigns to rdi, and calls itself recursively for that dereference 1478*b9c1b51eSKate Stone // DoGuessValueAt(frame, rdi, 8, dis, vars, 0x18) finds the instruction at 1479*b9c1b51eSKate Stone // +14 that assigns to rdi, and calls itself recursively for that 1480*b9c1b51eSKate Stone // derefernece 1481*b9c1b51eSKate Stone // DoGuessValueAt(frame, rbp, -8, dis, vars, 0x14) finds "f" in the 1482*b9c1b51eSKate Stone // variable list. 14834740a734SSean Callanan // Returns a ValueObject for f. (That's what was stored at rbp-8 at +14) 1484*b9c1b51eSKate Stone // Returns a ValueObject for *(f+8) or f->b (That's what was stored at rdi+8 1485*b9c1b51eSKate Stone // at +18) 1486*b9c1b51eSKate Stone // Returns a ValueObject for *(f->b+4) or f->b->a (That's what was stored at 1487*b9c1b51eSKate Stone // rdi+4 at +22) 14884740a734SSean Callanan 1489*b9c1b51eSKate Stone // First, check the variable list to see if anything is at the specified 1490*b9c1b51eSKate Stone // location. 1491*b9c1b51eSKate Stone for (size_t vi = 0, ve = variables.GetSize(); vi != ve; ++vi) { 14924740a734SSean Callanan VariableSP var_sp = variables.GetVariableAtIndex(vi); 14934740a734SSean Callanan DWARFExpression &dwarf_expression = var_sp->LocationExpression(); 14944740a734SSean Callanan 14954740a734SSean Callanan const RegisterInfo *expression_reg; 14964740a734SSean Callanan int64_t expression_offset; 14974740a734SSean Callanan ExecutionContext exe_ctx; 14984740a734SSean Callanan 1499*b9c1b51eSKate Stone if (dwarf_expression.IsDereferenceOfRegister(frame, expression_reg, 1500*b9c1b51eSKate Stone expression_offset)) { 15014740a734SSean Callanan if ((reg == ConstString(expression_reg->name) || 15024740a734SSean Callanan reg == ConstString(expression_reg->alt_name)) && 1503*b9c1b51eSKate Stone expression_offset == offset) { 15044740a734SSean Callanan return frame.GetValueObjectForFrameVariable(var_sp, eNoDynamicValues); 15054740a734SSean Callanan } 15064740a734SSean Callanan } 15074740a734SSean Callanan } 15084740a734SSean Callanan 15094740a734SSean Callanan bool is_in_return_register = false; 15104740a734SSean Callanan ABISP abi_sp = frame.CalculateProcess()->GetABI(); 15114740a734SSean Callanan RegisterInfo return_register_info; 15124740a734SSean Callanan 1513*b9c1b51eSKate Stone if (abi_sp) { 15144740a734SSean Callanan const char *return_register_name; 15154740a734SSean Callanan const RegisterInfo *reg_info = nullptr; 15164740a734SSean Callanan if (abi_sp->GetPointerReturnRegister(return_register_name) && 15174740a734SSean Callanan reg == ConstString(return_register_name) && 1518*b9c1b51eSKate Stone (reg_info = frame.GetRegisterContext()->GetRegisterInfoByName( 1519*b9c1b51eSKate Stone return_register_name))) { 15204740a734SSean Callanan is_in_return_register = true; 15214740a734SSean Callanan return_register_info = *reg_info; 15224740a734SSean Callanan } 15234740a734SSean Callanan } 15244740a734SSean Callanan 1525*b9c1b51eSKate Stone const uint32_t current_inst = 1526*b9c1b51eSKate Stone disassembler.GetInstructionList().GetIndexOfInstructionAtAddress(pc); 1527*b9c1b51eSKate Stone if (current_inst == UINT32_MAX) { 15284740a734SSean Callanan return ValueObjectSP(); 15294740a734SSean Callanan } 15304740a734SSean Callanan 15314740a734SSean Callanan ValueObjectSP source_path; 15324740a734SSean Callanan 1533*b9c1b51eSKate Stone for (uint32_t ii = current_inst - 1; ii != (uint32_t)-1; --ii) { 1534*b9c1b51eSKate Stone // This is not an exact algorithm, and it sacrifices accuracy for 1535*b9c1b51eSKate Stone // generality. 15364740a734SSean Callanan // Recognizing "mov" and "ld" instructions –– and which are their source and 15374740a734SSean Callanan // destination operands -- is something the disassembler should do for us. 1538*b9c1b51eSKate Stone InstructionSP instruction_sp = 1539*b9c1b51eSKate Stone disassembler.GetInstructionList().GetInstructionAtIndex(ii); 15404740a734SSean Callanan 1541*b9c1b51eSKate Stone if (is_in_return_register && instruction_sp->IsCall()) { 15424740a734SSean Callanan llvm::SmallVector<Instruction::Operand, 1> operands; 1543*b9c1b51eSKate Stone if (!instruction_sp->ParseOperands(operands) || operands.size() != 1) { 15444740a734SSean Callanan continue; 15454740a734SSean Callanan } 15464740a734SSean Callanan 1547*b9c1b51eSKate Stone switch (operands[0].m_type) { 15484740a734SSean Callanan default: 15494740a734SSean Callanan break; 1550*b9c1b51eSKate Stone case Instruction::Operand::Type::Immediate: { 15514740a734SSean Callanan SymbolContext sc; 15524740a734SSean Callanan Address load_address; 1553*b9c1b51eSKate Stone if (!frame.CalculateTarget()->ResolveLoadAddress( 1554*b9c1b51eSKate Stone operands[0].m_immediate, load_address)) { 15554740a734SSean Callanan break; 15564740a734SSean Callanan } 1557*b9c1b51eSKate Stone frame.CalculateTarget()->GetImages().ResolveSymbolContextForAddress( 1558*b9c1b51eSKate Stone load_address, eSymbolContextFunction, sc); 1559*b9c1b51eSKate Stone if (!sc.function) { 15604740a734SSean Callanan break; 15614740a734SSean Callanan } 15624740a734SSean Callanan CompilerType function_type = sc.function->GetCompilerType(); 1563*b9c1b51eSKate Stone if (!function_type.IsFunctionType()) { 15644740a734SSean Callanan break; 15654740a734SSean Callanan } 15664740a734SSean Callanan CompilerType return_type = function_type.GetFunctionReturnType(); 15674740a734SSean Callanan RegisterValue return_value; 1568*b9c1b51eSKate Stone if (!frame.GetRegisterContext()->ReadRegister(&return_register_info, 1569*b9c1b51eSKate Stone return_value)) { 15704740a734SSean Callanan break; 15714740a734SSean Callanan } 1572*b9c1b51eSKate Stone std::string name_str( 1573*b9c1b51eSKate Stone sc.function->GetName().AsCString("<unknown function>")); 15744740a734SSean Callanan name_str.append("()"); 15754740a734SSean Callanan Address return_value_address(return_value.GetAsUInt64()); 1576*b9c1b51eSKate Stone ValueObjectSP return_value_sp = ValueObjectMemory::Create( 1577*b9c1b51eSKate Stone &frame, name_str.c_str(), return_value_address, return_type); 15784740a734SSean Callanan return GetValueForDereferincingOffset(frame, return_value_sp, offset); 15794740a734SSean Callanan } 15804740a734SSean Callanan } 15814740a734SSean Callanan 15824740a734SSean Callanan continue; 15834740a734SSean Callanan } 15844740a734SSean Callanan 15854740a734SSean Callanan llvm::SmallVector<Instruction::Operand, 2> operands; 1586*b9c1b51eSKate Stone if (!instruction_sp->ParseOperands(operands) || operands.size() != 2) { 15874740a734SSean Callanan continue; 15884740a734SSean Callanan } 15894740a734SSean Callanan 15904740a734SSean Callanan Instruction::Operand *register_operand = nullptr; 15914740a734SSean Callanan Instruction::Operand *origin_operand = nullptr; 15924740a734SSean Callanan if (operands[0].m_type == Instruction::Operand::Type::Register && 1593*b9c1b51eSKate Stone operands[0].m_clobbered == true && operands[0].m_register == reg) { 15944740a734SSean Callanan register_operand = &operands[0]; 15954740a734SSean Callanan origin_operand = &operands[1]; 1596*b9c1b51eSKate Stone } else if (operands[1].m_type == Instruction::Operand::Type::Register && 15974740a734SSean Callanan operands[1].m_clobbered == true && 1598*b9c1b51eSKate Stone operands[1].m_register == reg) { 15994740a734SSean Callanan register_operand = &operands[1]; 16004740a734SSean Callanan origin_operand = &operands[0]; 1601*b9c1b51eSKate Stone } else { 16024740a734SSean Callanan continue; 16034740a734SSean Callanan } 16044740a734SSean Callanan 16054740a734SSean Callanan // We have an origin operand. Can we track its value down? 1606*b9c1b51eSKate Stone switch (origin_operand->m_type) { 16074740a734SSean Callanan default: 16084740a734SSean Callanan break; 16094740a734SSean Callanan case Instruction::Operand::Type::Register: 1610*b9c1b51eSKate Stone source_path = 1611*b9c1b51eSKate Stone DoGuessValueAt(frame, origin_operand->m_register, 0, disassembler, 1612*b9c1b51eSKate Stone variables, instruction_sp->GetAddress()); 16134740a734SSean Callanan break; 1614*b9c1b51eSKate Stone case Instruction::Operand::Type::Dereference: { 16154740a734SSean Callanan const Instruction::Operand &pointer = origin_operand->m_children[0]; 1616*b9c1b51eSKate Stone switch (pointer.m_type) { 16174740a734SSean Callanan default: 16184740a734SSean Callanan break; 16194740a734SSean Callanan case Instruction::Operand::Type::Register: 1620*b9c1b51eSKate Stone source_path = DoGuessValueAt(frame, pointer.m_register, 0, disassembler, 1621*b9c1b51eSKate Stone variables, instruction_sp->GetAddress()); 1622*b9c1b51eSKate Stone if (source_path) { 16234740a734SSean Callanan Error err; 16244740a734SSean Callanan source_path = source_path->Dereference(err); 1625*b9c1b51eSKate Stone if (!err.Success()) { 16264740a734SSean Callanan source_path.reset(); 16274740a734SSean Callanan } 16284740a734SSean Callanan } 16294740a734SSean Callanan break; 1630*b9c1b51eSKate Stone case Instruction::Operand::Type::Sum: { 16314740a734SSean Callanan const Instruction::Operand *origin_register = nullptr; 16324740a734SSean Callanan const Instruction::Operand *origin_offset = nullptr; 1633*b9c1b51eSKate Stone if (pointer.m_children.size() != 2) { 16344740a734SSean Callanan break; 16354740a734SSean Callanan } 1636*b9c1b51eSKate Stone if (pointer.m_children[0].m_type == 1637*b9c1b51eSKate Stone Instruction::Operand::Type::Register && 1638*b9c1b51eSKate Stone pointer.m_children[1].m_type == 1639*b9c1b51eSKate Stone Instruction::Operand::Type::Immediate) { 16404740a734SSean Callanan origin_register = &pointer.m_children[0]; 16414740a734SSean Callanan origin_offset = &pointer.m_children[1]; 1642*b9c1b51eSKate Stone } else if (pointer.m_children[1].m_type == 1643*b9c1b51eSKate Stone Instruction::Operand::Type::Register && 1644*b9c1b51eSKate Stone pointer.m_children[0].m_type == 1645*b9c1b51eSKate Stone Instruction::Operand::Type::Immediate) { 16464740a734SSean Callanan origin_register = &pointer.m_children[1]; 16474740a734SSean Callanan origin_offset = &pointer.m_children[0]; 16484740a734SSean Callanan } 1649*b9c1b51eSKate Stone if (!origin_register) { 16504740a734SSean Callanan break; 16514740a734SSean Callanan } 1652*b9c1b51eSKate Stone int64_t signed_origin_offset = 1653*b9c1b51eSKate Stone origin_offset->m_negative ? -((int64_t)origin_offset->m_immediate) 1654*b9c1b51eSKate Stone : origin_offset->m_immediate; 1655*b9c1b51eSKate Stone source_path = DoGuessValueAt(frame, origin_register->m_register, 1656*b9c1b51eSKate Stone signed_origin_offset, disassembler, 1657*b9c1b51eSKate Stone variables, instruction_sp->GetAddress()); 1658*b9c1b51eSKate Stone if (!source_path) { 16594740a734SSean Callanan break; 16604740a734SSean Callanan } 1661*b9c1b51eSKate Stone source_path = 1662*b9c1b51eSKate Stone GetValueForDereferincingOffset(frame, source_path, offset); 16634740a734SSean Callanan break; 16644740a734SSean Callanan } 16654740a734SSean Callanan } 16664740a734SSean Callanan } 16674740a734SSean Callanan } 16684740a734SSean Callanan 1669*b9c1b51eSKate Stone if (source_path) { 16704740a734SSean Callanan return source_path; 16714740a734SSean Callanan } 16724740a734SSean Callanan } 16734740a734SSean Callanan 16744740a734SSean Callanan return ValueObjectSP(); 16754740a734SSean Callanan } 16764740a734SSean Callanan } 16774740a734SSean Callanan 1678*b9c1b51eSKate Stone lldb::ValueObjectSP StackFrame::GuessValueForRegisterAndOffset(ConstString reg, 1679*b9c1b51eSKate Stone int64_t offset) { 16804740a734SSean Callanan TargetSP target_sp = CalculateTarget(); 16814740a734SSean Callanan 16824740a734SSean Callanan const ArchSpec &target_arch = target_sp->GetArchitecture(); 16834740a734SSean Callanan 16844740a734SSean Callanan Block *frame_block = GetFrameBlock(); 16854740a734SSean Callanan 1686*b9c1b51eSKate Stone if (!frame_block) { 16874740a734SSean Callanan return ValueObjectSP(); 16884740a734SSean Callanan } 16894740a734SSean Callanan 16904740a734SSean Callanan Function *function = frame_block->CalculateSymbolContextFunction(); 1691*b9c1b51eSKate Stone if (!function) { 16924740a734SSean Callanan return ValueObjectSP(); 16934740a734SSean Callanan } 16944740a734SSean Callanan 16954740a734SSean Callanan AddressRange pc_range = function->GetAddressRange(); 16964740a734SSean Callanan 1697*b9c1b51eSKate Stone if (GetFrameCodeAddress().GetFileAddress() < 1698*b9c1b51eSKate Stone pc_range.GetBaseAddress().GetFileAddress() || 1699*b9c1b51eSKate Stone GetFrameCodeAddress().GetFileAddress() - 1700*b9c1b51eSKate Stone pc_range.GetBaseAddress().GetFileAddress() >= 1701*b9c1b51eSKate Stone pc_range.GetByteSize()) { 17024740a734SSean Callanan return ValueObjectSP(); 17034740a734SSean Callanan } 17044740a734SSean Callanan 17054740a734SSean Callanan ExecutionContext exe_ctx(shared_from_this()); 17064740a734SSean Callanan 17074740a734SSean Callanan const char *plugin_name = nullptr; 17084740a734SSean Callanan const char *flavor = nullptr; 17094740a734SSean Callanan const bool prefer_file_cache = false; 1710*b9c1b51eSKate Stone DisassemblerSP disassembler_sp = Disassembler::DisassembleRange( 1711*b9c1b51eSKate Stone target_arch, plugin_name, flavor, exe_ctx, pc_range, prefer_file_cache); 17124740a734SSean Callanan 1713*b9c1b51eSKate Stone if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) { 17144740a734SSean Callanan return ValueObjectSP(); 17154740a734SSean Callanan } 17164740a734SSean Callanan 17174740a734SSean Callanan const bool get_file_globals = false; 17184740a734SSean Callanan VariableList *variables = GetVariableList(get_file_globals); 17194740a734SSean Callanan 1720*b9c1b51eSKate Stone if (!variables) { 17214740a734SSean Callanan return ValueObjectSP(); 17224740a734SSean Callanan } 17234740a734SSean Callanan 1724*b9c1b51eSKate Stone return DoGuessValueAt(*this, reg, offset, *disassembler_sp, *variables, 1725*b9c1b51eSKate Stone GetFrameCodeAddress()); 17264740a734SSean Callanan } 17274740a734SSean Callanan 1728*b9c1b51eSKate Stone TargetSP StackFrame::CalculateTarget() { 1729d9e416c0SGreg Clayton TargetSP target_sp; 1730d9e416c0SGreg Clayton ThreadSP thread_sp(GetThread()); 1731*b9c1b51eSKate Stone if (thread_sp) { 1732d9e416c0SGreg Clayton ProcessSP process_sp(thread_sp->CalculateProcess()); 1733d9e416c0SGreg Clayton if (process_sp) 1734d9e416c0SGreg Clayton target_sp = process_sp->CalculateTarget(); 1735d9e416c0SGreg Clayton } 1736d9e416c0SGreg Clayton return target_sp; 173730fdc8d8SChris Lattner } 173830fdc8d8SChris Lattner 1739*b9c1b51eSKate Stone ProcessSP StackFrame::CalculateProcess() { 1740d9e416c0SGreg Clayton ProcessSP process_sp; 1741d9e416c0SGreg Clayton ThreadSP thread_sp(GetThread()); 1742d9e416c0SGreg Clayton if (thread_sp) 1743d9e416c0SGreg Clayton process_sp = thread_sp->CalculateProcess(); 1744d9e416c0SGreg Clayton return process_sp; 174530fdc8d8SChris Lattner } 174630fdc8d8SChris Lattner 1747*b9c1b51eSKate Stone ThreadSP StackFrame::CalculateThread() { return GetThread(); } 174830fdc8d8SChris Lattner 1749*b9c1b51eSKate Stone StackFrameSP StackFrame::CalculateStackFrame() { return shared_from_this(); } 175030fdc8d8SChris Lattner 1751*b9c1b51eSKate Stone void StackFrame::CalculateExecutionContext(ExecutionContext &exe_ctx) { 1752d9e416c0SGreg Clayton exe_ctx.SetContext(shared_from_this()); 175330fdc8d8SChris Lattner } 175430fdc8d8SChris Lattner 1755*b9c1b51eSKate Stone void StackFrame::DumpUsingSettingsFormat(Stream *strm, 1756*b9c1b51eSKate Stone const char *frame_marker) { 1757d70a6e71SEugene Zelenko if (strm == nullptr) 17580603aa9dSGreg Clayton return; 17590603aa9dSGreg Clayton 17600603aa9dSGreg Clayton GetSymbolContext(eSymbolContextEverything); 1761d9e416c0SGreg Clayton ExecutionContext exe_ctx(shared_from_this()); 17620603aa9dSGreg Clayton StreamString s; 17638ec10efcSJim Ingham 17648ec10efcSJim Ingham if (frame_marker) 17658ec10efcSJim Ingham s.PutCString(frame_marker); 17668ec10efcSJim Ingham 1767d70a6e71SEugene Zelenko const FormatEntity::Entry *frame_format = nullptr; 1768d9e416c0SGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 1769d9e416c0SGreg Clayton if (target) 1770d9e416c0SGreg Clayton frame_format = target->GetDebugger().GetFrameFormat(); 1771*b9c1b51eSKate Stone if (frame_format && FormatEntity::Format(*frame_format, s, &m_sc, &exe_ctx, 1772*b9c1b51eSKate Stone nullptr, nullptr, false, false)) { 17730603aa9dSGreg Clayton strm->Write(s.GetData(), s.GetSize()); 1774*b9c1b51eSKate Stone } else { 17750603aa9dSGreg Clayton Dump(strm, true, false); 17760603aa9dSGreg Clayton strm->EOL(); 17770603aa9dSGreg Clayton } 17780603aa9dSGreg Clayton } 17790603aa9dSGreg Clayton 1780*b9c1b51eSKate Stone void StackFrame::Dump(Stream *strm, bool show_frame_index, 1781*b9c1b51eSKate Stone bool show_fullpaths) { 1782d70a6e71SEugene Zelenko if (strm == nullptr) 178330fdc8d8SChris Lattner return; 178430fdc8d8SChris Lattner 178530fdc8d8SChris Lattner if (show_frame_index) 17861b72fcb7SGreg Clayton strm->Printf("frame #%u: ", m_frame_index); 1787d9e416c0SGreg Clayton ExecutionContext exe_ctx(shared_from_this()); 1788d9e416c0SGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 1789d01b2953SDaniel Malea strm->Printf("0x%0*" PRIx64 " ", 1790*b9c1b51eSKate Stone target ? (target->GetArchitecture().GetAddressByteSize() * 2) 1791*b9c1b51eSKate Stone : 16, 1792d9e416c0SGreg Clayton GetFrameCodeAddress().GetLoadAddress(target)); 17939da7bd07SGreg Clayton GetSymbolContext(eSymbolContextEverything); 17941b72fcb7SGreg Clayton const bool show_module = true; 17951b72fcb7SGreg Clayton const bool show_inline = true; 1796aff1b357SJason Molenda const bool show_function_arguments = true; 1797c980fa92SJason Molenda const bool show_function_name = true; 1798*b9c1b51eSKate Stone m_sc.DumpStopContext(strm, exe_ctx.GetBestExecutionContextScope(), 1799*b9c1b51eSKate Stone GetFrameCodeAddress(), show_fullpaths, show_module, 1800*b9c1b51eSKate Stone show_inline, show_function_arguments, 1801c980fa92SJason Molenda show_function_name); 180230fdc8d8SChris Lattner } 180330fdc8d8SChris Lattner 1804*b9c1b51eSKate Stone void StackFrame::UpdateCurrentFrameFromPreviousFrame(StackFrame &prev_frame) { 1805bb19a13cSSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex); 1806*b9c1b51eSKate Stone assert(GetStackID() == 1807*b9c1b51eSKate Stone prev_frame.GetStackID()); // TODO: remove this after some testing 1808b57e4a1bSJason Molenda m_variable_list_sp = prev_frame.m_variable_list_sp; 1809b57e4a1bSJason Molenda m_variable_list_value_objects.Swap(prev_frame.m_variable_list_value_objects); 181068275d5eSGreg Clayton if (!m_disassembly.GetString().empty()) 181168275d5eSGreg Clayton m_disassembly.GetString().swap(m_disassembly.GetString()); 18125082c5fdSGreg Clayton } 181368275d5eSGreg Clayton 1814*b9c1b51eSKate Stone void StackFrame::UpdatePreviousFrameFromCurrentFrame(StackFrame &curr_frame) { 1815bb19a13cSSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex); 1816*b9c1b51eSKate Stone assert(GetStackID() == 1817*b9c1b51eSKate Stone curr_frame.GetStackID()); // TODO: remove this after some testing 1818b57e4a1bSJason Molenda m_id.SetPC(curr_frame.m_id.GetPC()); // Update the Stack ID PC value 1819b57e4a1bSJason Molenda assert(GetThread() == curr_frame.GetThread()); 1820b57e4a1bSJason Molenda m_frame_index = curr_frame.m_frame_index; 1821b57e4a1bSJason Molenda m_concrete_frame_index = curr_frame.m_concrete_frame_index; 1822b57e4a1bSJason Molenda m_reg_context_sp = curr_frame.m_reg_context_sp; 1823b57e4a1bSJason Molenda m_frame_code_addr = curr_frame.m_frame_code_addr; 1824*b9c1b51eSKate Stone assert(!m_sc.target_sp || !curr_frame.m_sc.target_sp || 1825*b9c1b51eSKate Stone m_sc.target_sp.get() == curr_frame.m_sc.target_sp.get()); 1826*b9c1b51eSKate Stone assert(!m_sc.module_sp || !curr_frame.m_sc.module_sp || 1827*b9c1b51eSKate Stone m_sc.module_sp.get() == curr_frame.m_sc.module_sp.get()); 1828*b9c1b51eSKate Stone assert(m_sc.comp_unit == nullptr || curr_frame.m_sc.comp_unit == nullptr || 1829*b9c1b51eSKate Stone m_sc.comp_unit == curr_frame.m_sc.comp_unit); 1830*b9c1b51eSKate Stone assert(m_sc.function == nullptr || curr_frame.m_sc.function == nullptr || 1831*b9c1b51eSKate Stone m_sc.function == curr_frame.m_sc.function); 1832b57e4a1bSJason Molenda m_sc = curr_frame.m_sc; 183359e8fc1cSGreg Clayton m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything); 183459e8fc1cSGreg Clayton m_flags.Set(m_sc.GetResolvedMask()); 183559e8fc1cSGreg Clayton m_frame_base.Clear(); 183659e8fc1cSGreg Clayton m_frame_base_error.Clear(); 183759e8fc1cSGreg Clayton } 1838e4284b71SJim Ingham 1839*b9c1b51eSKate Stone bool StackFrame::HasCachedData() const { 1840d70a6e71SEugene Zelenko if (m_variable_list_sp) 1841b57e4a1bSJason Molenda return true; 1842b57e4a1bSJason Molenda if (m_variable_list_value_objects.GetSize() > 0) 1843b57e4a1bSJason Molenda return true; 1844b57e4a1bSJason Molenda if (!m_disassembly.GetString().empty()) 1845b57e4a1bSJason Molenda return true; 1846b57e4a1bSJason Molenda return false; 1847b57e4a1bSJason Molenda } 1848b57e4a1bSJason Molenda 1849*b9c1b51eSKate Stone bool StackFrame::GetStatus(Stream &strm, bool show_frame_info, bool show_source, 1850*b9c1b51eSKate Stone const char *frame_marker) { 185153eb7ad2SGreg Clayton 1852*b9c1b51eSKate Stone if (show_frame_info) { 18537260f620SGreg Clayton strm.Indent(); 18548ec10efcSJim Ingham DumpUsingSettingsFormat(&strm, frame_marker); 18557260f620SGreg Clayton } 18567260f620SGreg Clayton 1857*b9c1b51eSKate Stone if (show_source) { 1858d9e416c0SGreg Clayton ExecutionContext exe_ctx(shared_from_this()); 18598be74995SMohit K. Bhakkad bool have_source = false, have_debuginfo = false; 1860*b9c1b51eSKate Stone Debugger::StopDisassemblyType disasm_display = 1861*b9c1b51eSKate Stone Debugger::eStopDisassemblyTypeNever; 1862d9e416c0SGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 1863*b9c1b51eSKate Stone if (target) { 186453eb7ad2SGreg Clayton Debugger &debugger = target->GetDebugger(); 1865*b9c1b51eSKate Stone const uint32_t source_lines_before = 1866*b9c1b51eSKate Stone debugger.GetStopSourceLineCount(true); 1867*b9c1b51eSKate Stone const uint32_t source_lines_after = 1868*b9c1b51eSKate Stone debugger.GetStopSourceLineCount(false); 186953eb7ad2SGreg Clayton disasm_display = debugger.GetStopDisassemblyDisplay(); 187053eb7ad2SGreg Clayton 18717260f620SGreg Clayton GetSymbolContext(eSymbolContextCompUnit | eSymbolContextLineEntry); 1872*b9c1b51eSKate Stone if (m_sc.comp_unit && m_sc.line_entry.IsValid()) { 18738be74995SMohit K. Bhakkad have_debuginfo = true; 1874*b9c1b51eSKate Stone if (source_lines_before > 0 || source_lines_after > 0) { 1875*b9c1b51eSKate Stone size_t num_lines = 1876*b9c1b51eSKate Stone target->GetSourceManager().DisplaySourceLinesWithLineNumbers( 1877*b9c1b51eSKate Stone m_sc.line_entry.file, m_sc.line_entry.line, 1878*b9c1b51eSKate Stone source_lines_before, source_lines_after, "->", &strm); 18798be74995SMohit K. Bhakkad if (num_lines != 0) 18808be74995SMohit K. Bhakkad have_source = true; 18818be74995SMohit K. Bhakkad // TODO: Give here a one time warning if source file is missing. 1882e372b98dSGreg Clayton } 1883e372b98dSGreg Clayton } 1884*b9c1b51eSKate Stone switch (disasm_display) { 188567cc0636SGreg Clayton case Debugger::eStopDisassemblyTypeNever: 1886e372b98dSGreg Clayton break; 1887e372b98dSGreg Clayton 18888be74995SMohit K. Bhakkad case Debugger::eStopDisassemblyTypeNoDebugInfo: 18898be74995SMohit K. Bhakkad if (have_debuginfo) 18908be74995SMohit K. Bhakkad break; 189162e0681aSJason Molenda LLVM_FALLTHROUGH; 18928be74995SMohit K. Bhakkad 189367cc0636SGreg Clayton case Debugger::eStopDisassemblyTypeNoSource: 1894e372b98dSGreg Clayton if (have_source) 1895e372b98dSGreg Clayton break; 189662e0681aSJason Molenda LLVM_FALLTHROUGH; 18978be74995SMohit K. Bhakkad 189867cc0636SGreg Clayton case Debugger::eStopDisassemblyTypeAlways: 1899*b9c1b51eSKate Stone if (target) { 190053eb7ad2SGreg Clayton const uint32_t disasm_lines = debugger.GetDisassemblyLineCount(); 1901*b9c1b51eSKate Stone if (disasm_lines > 0) { 1902d9e416c0SGreg Clayton const ArchSpec &target_arch = target->GetArchitecture(); 1903e372b98dSGreg Clayton AddressRange pc_range; 1904e372b98dSGreg Clayton pc_range.GetBaseAddress() = GetFrameCodeAddress(); 1905*b9c1b51eSKate Stone pc_range.SetByteSize(disasm_lines * 1906*b9c1b51eSKate Stone target_arch.GetMaximumOpcodeByteSize()); 1907d70a6e71SEugene Zelenko const char *plugin_name = nullptr; 1908d70a6e71SEugene Zelenko const char *flavor = nullptr; 1909*b9c1b51eSKate Stone Disassembler::Disassemble(target->GetDebugger(), target_arch, 1910*b9c1b51eSKate Stone plugin_name, flavor, exe_ctx, pc_range, 1911*b9c1b51eSKate Stone disasm_lines, 0, 1912*b9c1b51eSKate Stone Disassembler::eOptionMarkPCAddress, strm); 1913e372b98dSGreg Clayton } 1914e372b98dSGreg Clayton } 1915e372b98dSGreg Clayton break; 19167260f620SGreg Clayton } 19177260f620SGreg Clayton } 191853eb7ad2SGreg Clayton } 19197260f620SGreg Clayton return true; 19207260f620SGreg Clayton } 1921