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