1*78a685aaSJim Ingham //===-- ValueObjectMemory.cpp ---------------------------------*- C++ -*-===// 2*78a685aaSJim Ingham // 3*78a685aaSJim Ingham // The LLVM Compiler Infrastructure 4*78a685aaSJim Ingham // 5*78a685aaSJim Ingham // This file is distributed under the University of Illinois Open Source 6*78a685aaSJim Ingham // License. See LICENSE.TXT for details. 7*78a685aaSJim Ingham // 8*78a685aaSJim Ingham //===----------------------------------------------------------------------===// 9*78a685aaSJim Ingham 10*78a685aaSJim Ingham 11*78a685aaSJim Ingham #include "lldb/Core/ValueObjectMemory.h" 12*78a685aaSJim Ingham 13*78a685aaSJim Ingham // C Includes 14*78a685aaSJim Ingham // C++ Includes 15*78a685aaSJim Ingham // Other libraries and framework includes 16*78a685aaSJim Ingham // Project includes 17*78a685aaSJim Ingham #include "lldb/Core/Module.h" 18*78a685aaSJim Ingham #include "lldb/Core/ValueObjectList.h" 19*78a685aaSJim Ingham #include "lldb/Core/Value.h" 20*78a685aaSJim Ingham #include "lldb/Core/ValueObject.h" 21*78a685aaSJim Ingham 22*78a685aaSJim Ingham #include "lldb/Symbol/ObjectFile.h" 23*78a685aaSJim Ingham #include "lldb/Symbol/SymbolContext.h" 24*78a685aaSJim Ingham #include "lldb/Symbol/Type.h" 25*78a685aaSJim Ingham #include "lldb/Symbol/Variable.h" 26*78a685aaSJim Ingham 27*78a685aaSJim Ingham #include "lldb/Target/ExecutionContext.h" 28*78a685aaSJim Ingham #include "lldb/Target/Process.h" 29*78a685aaSJim Ingham #include "lldb/Target/RegisterContext.h" 30*78a685aaSJim Ingham #include "lldb/Target/Target.h" 31*78a685aaSJim Ingham #include "lldb/Target/Thread.h" 32*78a685aaSJim Ingham 33*78a685aaSJim Ingham 34*78a685aaSJim Ingham using namespace lldb_private; 35*78a685aaSJim Ingham 36*78a685aaSJim Ingham ValueObjectMemory::ValueObjectMemory (ExecutionContextScope *exe_scope, 37*78a685aaSJim Ingham const char *name, 38*78a685aaSJim Ingham const Address &address, 39*78a685aaSJim Ingham lldb::TypeSP &type_sp) : 40*78a685aaSJim Ingham ValueObject(exe_scope), 41*78a685aaSJim Ingham m_address (address), 42*78a685aaSJim Ingham m_type_sp(type_sp) 43*78a685aaSJim Ingham { 44*78a685aaSJim Ingham // Do not attempt to construct one of these objects with no variable! 45*78a685aaSJim Ingham assert (m_type_sp.get() != NULL); 46*78a685aaSJim Ingham SetName (name); 47*78a685aaSJim Ingham m_value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get()); 48*78a685aaSJim Ingham lldb::addr_t load_address = m_address.GetLoadAddress(m_update_point.GetTarget()); 49*78a685aaSJim Ingham if (load_address != LLDB_INVALID_ADDRESS) 50*78a685aaSJim Ingham { 51*78a685aaSJim Ingham m_value.SetValueType(Value::eValueTypeLoadAddress); 52*78a685aaSJim Ingham m_value.GetScalar() = load_address; 53*78a685aaSJim Ingham } 54*78a685aaSJim Ingham else 55*78a685aaSJim Ingham { 56*78a685aaSJim Ingham lldb::addr_t file_address = m_address.GetFileAddress(); 57*78a685aaSJim Ingham if (file_address != LLDB_INVALID_ADDRESS) 58*78a685aaSJim Ingham { 59*78a685aaSJim Ingham m_value.SetValueType(Value::eValueTypeFileAddress); 60*78a685aaSJim Ingham m_value.GetScalar() = file_address; 61*78a685aaSJim Ingham } 62*78a685aaSJim Ingham else 63*78a685aaSJim Ingham { 64*78a685aaSJim Ingham m_value.GetScalar() = m_address.GetOffset(); 65*78a685aaSJim Ingham m_value.SetValueType (Value::eValueTypeScalar); 66*78a685aaSJim Ingham } 67*78a685aaSJim Ingham } 68*78a685aaSJim Ingham } 69*78a685aaSJim Ingham 70*78a685aaSJim Ingham ValueObjectMemory::~ValueObjectMemory() 71*78a685aaSJim Ingham { 72*78a685aaSJim Ingham } 73*78a685aaSJim Ingham 74*78a685aaSJim Ingham lldb::clang_type_t 75*78a685aaSJim Ingham ValueObjectMemory::GetClangType () 76*78a685aaSJim Ingham { 77*78a685aaSJim Ingham return m_type_sp->GetClangForwardType(); 78*78a685aaSJim Ingham } 79*78a685aaSJim Ingham 80*78a685aaSJim Ingham ConstString 81*78a685aaSJim Ingham ValueObjectMemory::GetTypeName() 82*78a685aaSJim Ingham { 83*78a685aaSJim Ingham return m_type_sp->GetName(); 84*78a685aaSJim Ingham } 85*78a685aaSJim Ingham 86*78a685aaSJim Ingham uint32_t 87*78a685aaSJim Ingham ValueObjectMemory::CalculateNumChildren() 88*78a685aaSJim Ingham { 89*78a685aaSJim Ingham return m_type_sp->GetNumChildren(true); 90*78a685aaSJim Ingham } 91*78a685aaSJim Ingham 92*78a685aaSJim Ingham clang::ASTContext * 93*78a685aaSJim Ingham ValueObjectMemory::GetClangAST () 94*78a685aaSJim Ingham { 95*78a685aaSJim Ingham return m_type_sp->GetClangAST(); 96*78a685aaSJim Ingham } 97*78a685aaSJim Ingham 98*78a685aaSJim Ingham size_t 99*78a685aaSJim Ingham ValueObjectMemory::GetByteSize() 100*78a685aaSJim Ingham { 101*78a685aaSJim Ingham return m_type_sp->GetByteSize(); 102*78a685aaSJim Ingham } 103*78a685aaSJim Ingham 104*78a685aaSJim Ingham lldb::ValueType 105*78a685aaSJim Ingham ValueObjectMemory::GetValueType() const 106*78a685aaSJim Ingham { 107*78a685aaSJim Ingham // RETHINK: Should this be inherited from somewhere? 108*78a685aaSJim Ingham return lldb::eValueTypeVariableGlobal; 109*78a685aaSJim Ingham } 110*78a685aaSJim Ingham 111*78a685aaSJim Ingham bool 112*78a685aaSJim Ingham ValueObjectMemory::UpdateValue () 113*78a685aaSJim Ingham { 114*78a685aaSJim Ingham SetValueIsValid (false); 115*78a685aaSJim Ingham m_error.Clear(); 116*78a685aaSJim Ingham 117*78a685aaSJim Ingham ExecutionContext exe_ctx (GetExecutionContextScope()); 118*78a685aaSJim Ingham 119*78a685aaSJim Ingham if (exe_ctx.target) 120*78a685aaSJim Ingham { 121*78a685aaSJim Ingham m_data.SetByteOrder(exe_ctx.target->GetArchitecture().GetByteOrder()); 122*78a685aaSJim Ingham m_data.SetAddressByteSize(exe_ctx.target->GetArchitecture().GetAddressByteSize()); 123*78a685aaSJim Ingham } 124*78a685aaSJim Ingham 125*78a685aaSJim Ingham Value old_value(m_value); 126*78a685aaSJim Ingham if (m_address.IsValid()) 127*78a685aaSJim Ingham { 128*78a685aaSJim Ingham Value::ValueType value_type = m_value.GetValueType(); 129*78a685aaSJim Ingham 130*78a685aaSJim Ingham switch (value_type) 131*78a685aaSJim Ingham { 132*78a685aaSJim Ingham default: 133*78a685aaSJim Ingham assert(!"Unhandled expression result value kind..."); 134*78a685aaSJim Ingham break; 135*78a685aaSJim Ingham 136*78a685aaSJim Ingham case Value::eValueTypeScalar: 137*78a685aaSJim Ingham // The variable value is in the Scalar value inside the m_value. 138*78a685aaSJim Ingham // We can point our m_data right to it. 139*78a685aaSJim Ingham m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0); 140*78a685aaSJim Ingham break; 141*78a685aaSJim Ingham 142*78a685aaSJim Ingham case Value::eValueTypeFileAddress: 143*78a685aaSJim Ingham case Value::eValueTypeLoadAddress: 144*78a685aaSJim Ingham case Value::eValueTypeHostAddress: 145*78a685aaSJim Ingham // The DWARF expression result was an address in the inferior 146*78a685aaSJim Ingham // process. If this variable is an aggregate type, we just need 147*78a685aaSJim Ingham // the address as the main value as all child variable objects 148*78a685aaSJim Ingham // will rely upon this location and add an offset and then read 149*78a685aaSJim Ingham // their own values as needed. If this variable is a simple 150*78a685aaSJim Ingham // type, we read all data for it into m_data. 151*78a685aaSJim Ingham // Make sure this type has a value before we try and read it 152*78a685aaSJim Ingham 153*78a685aaSJim Ingham // If we have a file address, convert it to a load address if we can. 154*78a685aaSJim Ingham if (value_type == Value::eValueTypeFileAddress && exe_ctx.process) 155*78a685aaSJim Ingham { 156*78a685aaSJim Ingham lldb::addr_t load_addr = m_address.GetLoadAddress(exe_ctx.target); 157*78a685aaSJim Ingham if (load_addr != LLDB_INVALID_ADDRESS) 158*78a685aaSJim Ingham { 159*78a685aaSJim Ingham m_value.SetValueType(Value::eValueTypeLoadAddress); 160*78a685aaSJim Ingham m_value.GetScalar() = load_addr; 161*78a685aaSJim Ingham } 162*78a685aaSJim Ingham } 163*78a685aaSJim Ingham 164*78a685aaSJim Ingham if (ClangASTContext::IsAggregateType (GetClangType())) 165*78a685aaSJim Ingham { 166*78a685aaSJim Ingham // this value object represents an aggregate type whose 167*78a685aaSJim Ingham // children have values, but this object does not. So we 168*78a685aaSJim Ingham // say we are changed if our location has changed. 169*78a685aaSJim Ingham SetValueDidChange (value_type != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar()); 170*78a685aaSJim Ingham } 171*78a685aaSJim Ingham else 172*78a685aaSJim Ingham { 173*78a685aaSJim Ingham // Copy the Value and set the context to use our Variable 174*78a685aaSJim Ingham // so it can extract read its value into m_data appropriately 175*78a685aaSJim Ingham Value value(m_value); 176*78a685aaSJim Ingham value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get()); 177*78a685aaSJim Ingham m_error = value.GetValueAsData(&exe_ctx, GetClangAST(), m_data, 0); 178*78a685aaSJim Ingham } 179*78a685aaSJim Ingham break; 180*78a685aaSJim Ingham } 181*78a685aaSJim Ingham 182*78a685aaSJim Ingham SetValueIsValid (m_error.Success()); 183*78a685aaSJim Ingham } 184*78a685aaSJim Ingham return m_error.Success(); 185*78a685aaSJim Ingham } 186*78a685aaSJim Ingham 187*78a685aaSJim Ingham 188*78a685aaSJim Ingham 189*78a685aaSJim Ingham bool 190*78a685aaSJim Ingham ValueObjectMemory::IsInScope () 191*78a685aaSJim Ingham { 192*78a685aaSJim Ingham // FIXME: Maybe try to read the memory address, and if that works, then 193*78a685aaSJim Ingham // we are in scope? 194*78a685aaSJim Ingham return true; 195*78a685aaSJim Ingham } 196*78a685aaSJim Ingham 197