xref: /haiku/src/kits/debugger/value/value_nodes/AddressValueNode.cpp (revision cbe0a0c436162d78cc3f92a305b64918c839d079)
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