1254721Semaste//===-- ValueObjectMemory.cpp ---------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste 11254721Semaste#include "lldb/Core/ValueObjectMemory.h" 12254721Semaste 13254721Semaste// C Includes 14254721Semaste// C++ Includes 15254721Semaste// Other libraries and framework includes 16254721Semaste// Project includes 17254721Semaste#include "lldb/Core/Module.h" 18254721Semaste#include "lldb/Core/ValueObjectList.h" 19254721Semaste#include "lldb/Core/Value.h" 20254721Semaste#include "lldb/Core/ValueObject.h" 21254721Semaste 22254721Semaste#include "lldb/Symbol/ObjectFile.h" 23254721Semaste#include "lldb/Symbol/SymbolContext.h" 24254721Semaste#include "lldb/Symbol/Type.h" 25254721Semaste#include "lldb/Symbol/Variable.h" 26254721Semaste 27254721Semaste#include "lldb/Target/ExecutionContext.h" 28254721Semaste#include "lldb/Target/Process.h" 29254721Semaste#include "lldb/Target/RegisterContext.h" 30254721Semaste#include "lldb/Target/Target.h" 31254721Semaste#include "lldb/Target/Thread.h" 32254721Semaste 33254721Semasteusing namespace lldb; 34254721Semasteusing namespace lldb_private; 35254721Semaste 36254721SemasteValueObjectSP 37254721SemasteValueObjectMemory::Create (ExecutionContextScope *exe_scope, 38254721Semaste const char *name, 39254721Semaste const Address &address, 40254721Semaste lldb::TypeSP &type_sp) 41254721Semaste{ 42254721Semaste return (new ValueObjectMemory (exe_scope, name, address, type_sp))->GetSP(); 43254721Semaste} 44254721Semaste 45254721SemasteValueObjectSP 46254721SemasteValueObjectMemory::Create (ExecutionContextScope *exe_scope, 47254721Semaste const char *name, 48254721Semaste const Address &address, 49254721Semaste const ClangASTType &ast_type) 50254721Semaste{ 51254721Semaste return (new ValueObjectMemory (exe_scope, name, address, ast_type))->GetSP(); 52254721Semaste} 53254721Semaste 54254721SemasteValueObjectMemory::ValueObjectMemory (ExecutionContextScope *exe_scope, 55254721Semaste const char *name, 56254721Semaste const Address &address, 57254721Semaste lldb::TypeSP &type_sp) : 58254721Semaste ValueObject(exe_scope), 59254721Semaste m_address (address), 60254721Semaste m_type_sp(type_sp), 61254721Semaste m_clang_type() 62254721Semaste{ 63254721Semaste // Do not attempt to construct one of these objects with no variable! 64254721Semaste assert (m_type_sp.get() != NULL); 65254721Semaste SetName (ConstString(name)); 66254721Semaste m_value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get()); 67254721Semaste TargetSP target_sp (GetTargetSP()); 68254721Semaste lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get()); 69254721Semaste if (load_address != LLDB_INVALID_ADDRESS) 70254721Semaste { 71254721Semaste m_value.SetValueType(Value::eValueTypeLoadAddress); 72254721Semaste m_value.GetScalar() = load_address; 73254721Semaste } 74254721Semaste else 75254721Semaste { 76254721Semaste lldb::addr_t file_address = m_address.GetFileAddress(); 77254721Semaste if (file_address != LLDB_INVALID_ADDRESS) 78254721Semaste { 79254721Semaste m_value.SetValueType(Value::eValueTypeFileAddress); 80254721Semaste m_value.GetScalar() = file_address; 81254721Semaste } 82254721Semaste else 83254721Semaste { 84254721Semaste m_value.GetScalar() = m_address.GetOffset(); 85254721Semaste m_value.SetValueType (Value::eValueTypeScalar); 86254721Semaste } 87254721Semaste } 88254721Semaste} 89254721Semaste 90254721SemasteValueObjectMemory::ValueObjectMemory (ExecutionContextScope *exe_scope, 91254721Semaste const char *name, 92254721Semaste const Address &address, 93254721Semaste const ClangASTType &ast_type) : 94254721Semaste ValueObject(exe_scope), 95254721Semaste m_address (address), 96254721Semaste m_type_sp(), 97254721Semaste m_clang_type(ast_type) 98254721Semaste{ 99254721Semaste // Do not attempt to construct one of these objects with no variable! 100254721Semaste assert (m_clang_type.GetASTContext()); 101254721Semaste assert (m_clang_type.GetOpaqueQualType()); 102254721Semaste 103254721Semaste TargetSP target_sp (GetTargetSP()); 104254721Semaste 105254721Semaste SetName (ConstString(name)); 106254721Semaste// m_value.SetContext(Value::eContextTypeClangType, m_clang_type.GetOpaqueQualType()); 107254721Semaste m_value.SetClangType(m_clang_type); 108254721Semaste lldb::addr_t load_address = m_address.GetLoadAddress (target_sp.get()); 109254721Semaste if (load_address != LLDB_INVALID_ADDRESS) 110254721Semaste { 111254721Semaste m_value.SetValueType(Value::eValueTypeLoadAddress); 112254721Semaste m_value.GetScalar() = load_address; 113254721Semaste } 114254721Semaste else 115254721Semaste { 116254721Semaste lldb::addr_t file_address = m_address.GetFileAddress(); 117254721Semaste if (file_address != LLDB_INVALID_ADDRESS) 118254721Semaste { 119254721Semaste m_value.SetValueType(Value::eValueTypeFileAddress); 120254721Semaste m_value.GetScalar() = file_address; 121254721Semaste } 122254721Semaste else 123254721Semaste { 124254721Semaste m_value.GetScalar() = m_address.GetOffset(); 125254721Semaste m_value.SetValueType (Value::eValueTypeScalar); 126254721Semaste } 127254721Semaste } 128254721Semaste} 129254721Semaste 130254721SemasteValueObjectMemory::~ValueObjectMemory() 131254721Semaste{ 132254721Semaste} 133254721Semaste 134254721SemasteClangASTType 135254721SemasteValueObjectMemory::GetClangTypeImpl () 136254721Semaste{ 137254721Semaste if (m_type_sp) 138254721Semaste return m_type_sp->GetClangForwardType(); 139254721Semaste return m_clang_type; 140254721Semaste} 141254721Semaste 142254721SemasteConstString 143254721SemasteValueObjectMemory::GetTypeName() 144254721Semaste{ 145254721Semaste if (m_type_sp) 146254721Semaste return m_type_sp->GetName(); 147254721Semaste return m_clang_type.GetConstTypeName(); 148254721Semaste} 149254721Semaste 150254721Semastesize_t 151254721SemasteValueObjectMemory::CalculateNumChildren() 152254721Semaste{ 153254721Semaste if (m_type_sp) 154254721Semaste return m_type_sp->GetNumChildren(true); 155254721Semaste const bool omit_empty_base_classes = true; 156254721Semaste return m_clang_type.GetNumChildren (omit_empty_base_classes); 157254721Semaste} 158254721Semaste 159254721Semasteuint64_t 160254721SemasteValueObjectMemory::GetByteSize() 161254721Semaste{ 162254721Semaste if (m_type_sp) 163254721Semaste return m_type_sp->GetByteSize(); 164254721Semaste return m_clang_type.GetByteSize (); 165254721Semaste} 166254721Semaste 167254721Semastelldb::ValueType 168254721SemasteValueObjectMemory::GetValueType() const 169254721Semaste{ 170254721Semaste // RETHINK: Should this be inherited from somewhere? 171254721Semaste return lldb::eValueTypeVariableGlobal; 172254721Semaste} 173254721Semaste 174254721Semastebool 175254721SemasteValueObjectMemory::UpdateValue () 176254721Semaste{ 177254721Semaste SetValueIsValid (false); 178254721Semaste m_error.Clear(); 179254721Semaste 180254721Semaste ExecutionContext exe_ctx (GetExecutionContextRef()); 181254721Semaste 182254721Semaste Target *target = exe_ctx.GetTargetPtr(); 183254721Semaste if (target) 184254721Semaste { 185254721Semaste m_data.SetByteOrder(target->GetArchitecture().GetByteOrder()); 186254721Semaste m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize()); 187254721Semaste } 188254721Semaste 189254721Semaste Value old_value(m_value); 190254721Semaste if (m_address.IsValid()) 191254721Semaste { 192254721Semaste Value::ValueType value_type = m_value.GetValueType(); 193254721Semaste 194254721Semaste switch (value_type) 195254721Semaste { 196254721Semaste default: 197254721Semaste assert(!"Unhandled expression result value kind..."); 198254721Semaste break; 199254721Semaste 200254721Semaste case Value::eValueTypeScalar: 201254721Semaste // The variable value is in the Scalar value inside the m_value. 202254721Semaste // We can point our m_data right to it. 203254721Semaste m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get()); 204254721Semaste break; 205254721Semaste 206254721Semaste case Value::eValueTypeFileAddress: 207254721Semaste case Value::eValueTypeLoadAddress: 208254721Semaste case Value::eValueTypeHostAddress: 209254721Semaste // The DWARF expression result was an address in the inferior 210254721Semaste // process. If this variable is an aggregate type, we just need 211254721Semaste // the address as the main value as all child variable objects 212254721Semaste // will rely upon this location and add an offset and then read 213254721Semaste // their own values as needed. If this variable is a simple 214254721Semaste // type, we read all data for it into m_data. 215254721Semaste // Make sure this type has a value before we try and read it 216254721Semaste 217254721Semaste // If we have a file address, convert it to a load address if we can. 218254721Semaste if (value_type == Value::eValueTypeFileAddress && exe_ctx.GetProcessPtr()) 219254721Semaste { 220254721Semaste lldb::addr_t load_addr = m_address.GetLoadAddress(target); 221254721Semaste if (load_addr != LLDB_INVALID_ADDRESS) 222254721Semaste { 223254721Semaste m_value.SetValueType(Value::eValueTypeLoadAddress); 224254721Semaste m_value.GetScalar() = load_addr; 225254721Semaste } 226254721Semaste } 227254721Semaste 228254721Semaste if (GetClangType().IsAggregateType()) 229254721Semaste { 230254721Semaste // this value object represents an aggregate type whose 231254721Semaste // children have values, but this object does not. So we 232254721Semaste // say we are changed if our location has changed. 233254721Semaste SetValueDidChange (value_type != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar()); 234254721Semaste } 235254721Semaste else 236254721Semaste { 237254721Semaste // Copy the Value and set the context to use our Variable 238254721Semaste // so it can extract read its value into m_data appropriately 239254721Semaste Value value(m_value); 240254721Semaste if (m_type_sp) 241254721Semaste value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get()); 242254721Semaste else 243254721Semaste { 244254721Semaste //value.SetContext(Value::eContextTypeClangType, m_clang_type.GetOpaqueQualType()); 245254721Semaste value.SetClangType(m_clang_type); 246254721Semaste } 247254721Semaste 248254721Semaste m_error = value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get()); 249254721Semaste } 250254721Semaste break; 251254721Semaste } 252254721Semaste 253254721Semaste SetValueIsValid (m_error.Success()); 254254721Semaste } 255254721Semaste return m_error.Success(); 256254721Semaste} 257254721Semaste 258254721Semaste 259254721Semaste 260254721Semastebool 261254721SemasteValueObjectMemory::IsInScope () 262254721Semaste{ 263254721Semaste // FIXME: Maybe try to read the memory address, and if that works, then 264254721Semaste // we are in scope? 265254721Semaste return true; 266254721Semaste} 267254721Semaste 268254721Semaste 269254721Semastelldb::ModuleSP 270254721SemasteValueObjectMemory::GetModule() 271254721Semaste{ 272254721Semaste return m_address.GetModule(); 273254721Semaste} 274254721Semaste 275254721Semaste 276