1 //===-- ValueObjectChild.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/ValueObjectChild.h" 11 12 #include "lldb/Core/Module.h" 13 #include "lldb/Core/ValueObjectList.h" 14 15 #include "lldb/Symbol/CompilerType.h" 16 #include "lldb/Symbol/ObjectFile.h" 17 #include "lldb/Symbol/SymbolContext.h" 18 #include "lldb/Symbol/Type.h" 19 #include "lldb/Symbol/Variable.h" 20 21 #include "lldb/Target/ExecutionContext.h" 22 #include "lldb/Target/Process.h" 23 #include "lldb/Target/Target.h" 24 25 using namespace lldb_private; 26 27 ValueObjectChild::ValueObjectChild 28 ( 29 ValueObject &parent, 30 const CompilerType &compiler_type, 31 const ConstString &name, 32 uint64_t byte_size, 33 int32_t byte_offset, 34 uint32_t bitfield_bit_size, 35 uint32_t bitfield_bit_offset, 36 bool is_base_class, 37 bool is_deref_of_parent, 38 AddressType child_ptr_or_ref_addr_type 39 ) : 40 ValueObject (parent), 41 m_compiler_type (compiler_type), 42 m_byte_size (byte_size), 43 m_byte_offset (byte_offset), 44 m_bitfield_bit_size (bitfield_bit_size), 45 m_bitfield_bit_offset (bitfield_bit_offset), 46 m_is_base_class (is_base_class), 47 m_is_deref_of_parent (is_deref_of_parent), 48 m_can_update_with_invalid_exe_ctx() 49 { 50 m_name = name; 51 SetAddressTypeOfChildren(child_ptr_or_ref_addr_type); 52 } 53 54 ValueObjectChild::~ValueObjectChild() 55 { 56 } 57 58 lldb::ValueType 59 ValueObjectChild::GetValueType() const 60 { 61 return m_parent->GetValueType(); 62 } 63 64 size_t 65 ValueObjectChild::CalculateNumChildren(uint32_t max) 66 { 67 auto children_count = GetCompilerType().GetNumChildren (true); 68 return children_count <= max ? children_count : max; 69 } 70 71 static void 72 AdjustForBitfieldness(ConstString& name, 73 uint8_t bitfield_bit_size) 74 { 75 if (name && bitfield_bit_size) 76 { 77 const char *compiler_type_name = name.AsCString(); 78 if (compiler_type_name) 79 { 80 std::vector<char> bitfield_type_name (strlen(compiler_type_name) + 32, 0); 81 ::snprintf (&bitfield_type_name.front(), bitfield_type_name.size(), "%s:%u", compiler_type_name, bitfield_bit_size); 82 name.SetCString(&bitfield_type_name.front()); 83 } 84 } 85 } 86 87 ConstString 88 ValueObjectChild::GetTypeName() 89 { 90 if (m_type_name.IsEmpty()) 91 { 92 m_type_name = GetCompilerType().GetConstTypeName (); 93 AdjustForBitfieldness(m_type_name, m_bitfield_bit_size); 94 } 95 return m_type_name; 96 } 97 98 ConstString 99 ValueObjectChild::GetQualifiedTypeName() 100 { 101 ConstString qualified_name = GetCompilerType().GetConstTypeName(); 102 AdjustForBitfieldness(qualified_name, m_bitfield_bit_size); 103 return qualified_name; 104 } 105 106 ConstString 107 ValueObjectChild::GetDisplayTypeName() 108 { 109 ConstString display_name = GetCompilerType().GetDisplayTypeName(); 110 AdjustForBitfieldness(display_name, m_bitfield_bit_size); 111 return display_name; 112 } 113 114 LazyBool 115 ValueObjectChild::CanUpdateWithInvalidExecutionContext () 116 { 117 if (m_can_update_with_invalid_exe_ctx.hasValue()) 118 return m_can_update_with_invalid_exe_ctx.getValue(); 119 if (m_parent) 120 { 121 ValueObject *opinionated_parent = m_parent->FollowParentChain([] (ValueObject* valobj) -> bool { 122 return (valobj->CanUpdateWithInvalidExecutionContext() == eLazyBoolCalculate); 123 }); 124 if (opinionated_parent) 125 return (m_can_update_with_invalid_exe_ctx = opinionated_parent->CanUpdateWithInvalidExecutionContext()).getValue(); 126 } 127 return (m_can_update_with_invalid_exe_ctx = this->ValueObject::CanUpdateWithInvalidExecutionContext()).getValue(); 128 } 129 130 bool 131 ValueObjectChild::UpdateValue () 132 { 133 m_error.Clear(); 134 SetValueIsValid (false); 135 ValueObject* parent = m_parent; 136 if (parent) 137 { 138 if (parent->UpdateValueIfNeeded(false)) 139 { 140 m_value.SetCompilerType(GetCompilerType()); 141 142 // Copy the parent scalar value and the scalar value type 143 m_value.GetScalar() = parent->GetValue().GetScalar(); 144 Value::ValueType value_type = parent->GetValue().GetValueType(); 145 m_value.SetValueType (value_type); 146 147 if (parent->GetCompilerType().IsPointerOrReferenceType ()) 148 { 149 lldb::addr_t addr = parent->GetPointerValue (); 150 m_value.GetScalar() = addr; 151 152 if (addr == LLDB_INVALID_ADDRESS) 153 { 154 m_error.SetErrorString ("parent address is invalid."); 155 } 156 else if (addr == 0) 157 { 158 m_error.SetErrorString ("parent is NULL"); 159 } 160 else 161 { 162 m_value.GetScalar() += m_byte_offset; 163 AddressType addr_type = parent->GetAddressTypeOfChildren(); 164 165 switch (addr_type) 166 { 167 case eAddressTypeFile: 168 { 169 lldb::ProcessSP process_sp (GetProcessSP()); 170 if (process_sp && process_sp->IsAlive() == true) 171 m_value.SetValueType (Value::eValueTypeLoadAddress); 172 else 173 m_value.SetValueType(Value::eValueTypeFileAddress); 174 } 175 break; 176 case eAddressTypeLoad: 177 m_value.SetValueType (Value::eValueTypeLoadAddress); 178 break; 179 case eAddressTypeHost: 180 m_value.SetValueType(Value::eValueTypeHostAddress); 181 break; 182 case eAddressTypeInvalid: 183 // TODO: does this make sense? 184 m_value.SetValueType(Value::eValueTypeScalar); 185 break; 186 } 187 } 188 } 189 else 190 { 191 switch (value_type) 192 { 193 case Value::eValueTypeLoadAddress: 194 case Value::eValueTypeFileAddress: 195 case Value::eValueTypeHostAddress: 196 { 197 lldb::addr_t addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); 198 if (addr == LLDB_INVALID_ADDRESS) 199 { 200 m_error.SetErrorString ("parent address is invalid."); 201 } 202 else if (addr == 0) 203 { 204 m_error.SetErrorString ("parent is NULL"); 205 } 206 else 207 { 208 // Set this object's scalar value to the address of its 209 // value by adding its byte offset to the parent address 210 m_value.GetScalar() += GetByteOffset(); 211 } 212 } 213 break; 214 215 case Value::eValueTypeScalar: 216 // TODO: What if this is a register value? Do we try and 217 // extract the child value from within the parent data? 218 // Probably... 219 default: 220 m_error.SetErrorString ("parent has invalid value."); 221 break; 222 } 223 } 224 225 if (m_error.Success()) 226 { 227 const bool thread_and_frame_only_if_stopped = true; 228 ExecutionContext exe_ctx (GetExecutionContextRef().Lock(thread_and_frame_only_if_stopped)); 229 if (GetCompilerType().GetTypeInfo() & lldb::eTypeHasValue) 230 m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get()); 231 else 232 m_error.Clear(); // No value so nothing to read... 233 } 234 } 235 else 236 { 237 m_error.SetErrorStringWithFormat("parent failed to evaluate: %s", parent->GetError().AsCString()); 238 } 239 } 240 else 241 { 242 m_error.SetErrorString("ValueObjectChild has a NULL parent ValueObject."); 243 } 244 245 return m_error.Success(); 246 } 247 248 249 bool 250 ValueObjectChild::IsInScope () 251 { 252 ValueObject* root(GetRoot()); 253 if (root) 254 return root->IsInScope (); 255 return false; 256 } 257