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