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 24AddressValueNode::AddressValueNode(ValueNodeChild* nodeChild, 25 AddressType* type) 26 : 27 ValueNode(nodeChild), 28 fType(type), 29 fChild(NULL) 30{ 31 fType->AcquireReference(); 32} 33 34 35AddressValueNode::~AddressValueNode() 36{ 37 if (fChild != NULL) 38 fChild->ReleaseReference(); 39 fType->ReleaseReference(); 40} 41 42 43Type* 44AddressValueNode::GetType() const 45{ 46 return fType; 47} 48 49 50status_t 51AddressValueNode::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 90status_t 91AddressValueNode::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 126int32 127AddressValueNode::CountChildren() const 128{ 129 return fChild != NULL ? 1 : 0; 130} 131 132 133ValueNodeChild* 134AddressValueNode::ChildAt(int32 index) const 135{ 136 return index == 0 ? fChild : NULL; 137} 138 139 140// #pragma mark - AddressValueNodeChild 141 142 143AddressValueNodeChild::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 154AddressValueNodeChild::~AddressValueNodeChild() 155{ 156 fType->ReleaseReference(); 157} 158 159 160const BString& 161AddressValueNodeChild::Name() const 162{ 163 return fName; 164} 165 166 167Type* 168AddressValueNodeChild::GetType() const 169{ 170 return fType; 171} 172 173 174ValueNode* 175AddressValueNodeChild::Parent() const 176{ 177 return fParent; 178} 179 180 181status_t 182AddressValueNodeChild::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