1 /* 2 * Copyright 2015, Rene Gollent, rene@gollent.com. 3 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. 4 * Distributed under the terms of the MIT License. 5 */ 6 7 8 #include "AddressValueNode.h" 9 10 #include <new> 11 12 #include "AddressValue.h" 13 #include "Architecture.h" 14 #include "Tracing.h" 15 #include "Type.h" 16 #include "ValueLoader.h" 17 #include "ValueLocation.h" 18 #include "ValueNodeContainer.h" 19 20 21 // #pragma mark - AddressValueNode 22 23 24 AddressValueNode::AddressValueNode(ValueNodeChild* nodeChild, 25 AddressType* type) 26 : 27 ValueNode(nodeChild), 28 fType(type), 29 fChild(NULL) 30 { 31 fType->AcquireReference(); 32 } 33 34 35 AddressValueNode::~AddressValueNode() 36 { 37 if (fChild != NULL) 38 fChild->ReleaseReference(); 39 fType->ReleaseReference(); 40 } 41 42 43 Type* 44 AddressValueNode::GetType() const 45 { 46 return fType; 47 } 48 49 50 status_t 51 AddressValueNode::ResolvedLocationAndValue(ValueLoader* valueLoader, 52 ValueLocation*& _location, Value*& _value) 53 { 54 // get the location 55 ValueLocation* location = NodeChild()->Location(); 56 if (location == NULL) 57 return B_BAD_VALUE; 58 59 TRACE_LOCALS(" TYPE_ADDRESS\n"); 60 61 // get the value type 62 type_code valueType; 63 if (valueLoader->GetArchitecture()->AddressSize() == 4) { 64 valueType = B_UINT32_TYPE; 65 TRACE_LOCALS(" -> 32 bit\n"); 66 } else { 67 valueType = B_UINT64_TYPE; 68 TRACE_LOCALS(" -> 64 bit\n"); 69 } 70 71 // load the value data 72 BVariant valueData; 73 status_t error = valueLoader->LoadValue(location, valueType, false, 74 valueData); 75 if (error != B_OK) 76 return error; 77 78 // create the type object 79 Value* value = new(std::nothrow) AddressValue(valueData); 80 if (value == NULL) 81 return B_NO_MEMORY; 82 83 location->AcquireReference(); 84 _location = location; 85 _value = value; 86 return B_OK; 87 } 88 89 90 status_t 91 AddressValueNode::CreateChildren(TeamTypeInformation* info) 92 { 93 if (fChild != NULL) 94 return B_OK; 95 96 // For function pointers, don't bother creating a child, as there 97 // currently isn't any useful information that can be presented there, 98 // and the address node's value already indicates the instruction pointer 99 // of the target function. 100 // TODO: an eventual future possibility might be for a child node to 101 // indicate the name of the function being pointed to, if target address 102 // is valid. 103 Type* baseType = fType->BaseType(); 104 if (baseType != NULL && baseType->Kind() == TYPE_FUNCTION) 105 return B_OK; 106 107 // construct name 108 BString name = "*"; 109 name << Name(); 110 111 // create the child 112 fChild = new(std::nothrow) AddressValueNodeChild(this, name, 113 baseType); 114 if (fChild == NULL) 115 return B_NO_MEMORY; 116 117 fChild->SetContainer(fContainer); 118 119 if (fContainer != NULL) 120 fContainer->NotifyValueNodeChildrenCreated(this); 121 122 return B_OK; 123 } 124 125 126 int32 127 AddressValueNode::CountChildren() const 128 { 129 return fChild != NULL ? 1 : 0; 130 } 131 132 133 ValueNodeChild* 134 AddressValueNode::ChildAt(int32 index) const 135 { 136 return index == 0 ? fChild : NULL; 137 } 138 139 140 // #pragma mark - AddressValueNodeChild 141 142 143 AddressValueNodeChild::AddressValueNodeChild(AddressValueNode* parent, 144 const BString& name, Type* type) 145 : 146 fParent(parent), 147 fName(name), 148 fType(type) 149 { 150 fType->AcquireReference(); 151 } 152 153 154 AddressValueNodeChild::~AddressValueNodeChild() 155 { 156 fType->ReleaseReference(); 157 } 158 159 160 const BString& 161 AddressValueNodeChild::Name() const 162 { 163 return fName; 164 } 165 166 167 Type* 168 AddressValueNodeChild::GetType() const 169 { 170 return fType; 171 } 172 173 174 ValueNode* 175 AddressValueNodeChild::Parent() const 176 { 177 return fParent; 178 } 179 180 181 status_t 182 AddressValueNodeChild::ResolveLocation(ValueLoader* valueLoader, 183 ValueLocation*& _location) 184 { 185 // The parent's value is an address pointing to this component. 186 AddressValue* parentValue = dynamic_cast<AddressValue*>( 187 fParent->GetValue()); 188 if (parentValue == NULL) 189 return B_BAD_VALUE; 190 191 // resolve the location 192 ValueLocation* location; 193 status_t error = fType->ResolveObjectDataLocation(parentValue->ToUInt64(), 194 location); 195 if (error != B_OK) { 196 TRACE_LOCALS("AddressValueNodeChild::ResolveLocation(): " 197 "ResolveObjectDataLocation() failed: %s\n", strerror(error)); 198 return error; 199 } 200 201 _location = location; 202 return B_OK; 203 } 204