1/*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2013-2014, Rene Gollent, rene@gollent.com.
4 * Distributed under the terms of the MIT License.
5 */
6
7#include "DebugInfoEntries.h"
8
9#include <new>
10
11#include "AttributeValue.h"
12#include "Dwarf.h"
13
14
15#define DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(name)				\
16	status_t													\
17	DebugInfoEntry::AddAttribute_##name(uint16 attributeName,	\
18		const AttributeValue& value)							\
19	{															\
20		return ATTRIBUTE_NOT_HANDLED;											\
21	}
22
23
24DebugInfoEntry::DebugInfoEntry()
25	:
26	fParent(NULL)
27{
28}
29
30
31DebugInfoEntry::~DebugInfoEntry()
32{
33}
34
35
36status_t
37DebugInfoEntry::InitAfterHierarchy(DebugInfoEntryInitInfo& info)
38{
39	return B_OK;
40}
41
42
43status_t
44DebugInfoEntry::InitAfterAttributes(DebugInfoEntryInitInfo& info)
45{
46	return B_OK;
47}
48
49
50void
51DebugInfoEntry::SetParent(DebugInfoEntry* parent)
52{
53	fParent = parent;
54}
55
56
57bool
58DebugInfoEntry::IsType() const
59{
60	return false;
61}
62
63
64bool
65DebugInfoEntry::IsNamespace() const
66{
67	return false;
68}
69
70
71const char*
72DebugInfoEntry::Name() const
73{
74	return NULL;
75}
76
77const char*
78DebugInfoEntry::Description() const
79{
80	return NULL;
81}
82
83
84DebugInfoEntry*
85DebugInfoEntry::Specification() const
86{
87	return NULL;
88}
89
90
91DebugInfoEntry*
92DebugInfoEntry::AbstractOrigin() const
93{
94	return NULL;
95}
96
97
98DebugInfoEntry*
99DebugInfoEntry::SignatureType() const
100{
101	return NULL;
102}
103
104
105LocationDescription*
106DebugInfoEntry::GetLocationDescription()
107{
108	return NULL;
109}
110
111
112bool
113DebugInfoEntry::GetDeclarationFile(uint32& _file) const
114{
115	DeclarationLocation* location = const_cast<DebugInfoEntry*>(this)
116		->GetDeclarationLocation();
117	if (location == NULL || !location->IsFileSet())
118		return false;
119
120	_file = location->file;
121	return true;
122}
123
124
125bool
126DebugInfoEntry::GetDeclarationLine(uint32& _line) const
127{
128	DeclarationLocation* location = const_cast<DebugInfoEntry*>(this)
129		->GetDeclarationLocation();
130	if (location == NULL || !location->IsLineSet())
131		return false;
132
133	_line = location->line;
134	return true;
135}
136
137
138bool
139DebugInfoEntry::GetDeclarationColumn(uint32& _column) const
140{
141	DeclarationLocation* location = const_cast<DebugInfoEntry*>(this)
142		->GetDeclarationLocation();
143	if (location == NULL || !location->IsColumnSet())
144		return false;
145
146	_column = location->column;
147	return true;
148}
149
150
151status_t
152DebugInfoEntry::AddChild(DebugInfoEntry* child)
153{
154	// ignore children where we don't expect them
155	return ENTRY_NOT_HANDLED;
156}
157
158
159status_t
160DebugInfoEntry::AddAttribute_decl_file(uint16 attributeName,
161	const AttributeValue& value)
162{
163	if (DeclarationLocation* location = GetDeclarationLocation()) {
164		location->SetFile(value.constant);
165		return B_OK;
166	}
167
168	return ATTRIBUTE_NOT_HANDLED;
169}
170
171
172status_t
173DebugInfoEntry::AddAttribute_decl_line(uint16 attributeName,
174	const AttributeValue& value)
175{
176	if (DeclarationLocation* location = GetDeclarationLocation()) {
177		location->SetLine(value.constant);
178		return B_OK;
179	}
180
181	return ATTRIBUTE_NOT_HANDLED;
182}
183
184
185status_t
186DebugInfoEntry::AddAttribute_decl_column(uint16 attributeName,
187	const AttributeValue& value)
188{
189	if (DeclarationLocation* location = GetDeclarationLocation()) {
190		location->SetColumn(value.constant);
191		return B_OK;
192	}
193
194	return ATTRIBUTE_NOT_HANDLED;
195}
196
197
198status_t
199DebugInfoEntry::AddAttribute_location(uint16 attributeName,
200	const AttributeValue& value)
201{
202	if (LocationDescription* location = GetLocationDescription()) {
203		if (value.attributeClass == ATTRIBUTE_CLASS_LOCLISTPTR) {
204			location->SetToLocationList(value.pointer);
205			return B_OK;
206		}
207
208		if (value.attributeClass == ATTRIBUTE_CLASS_BLOCK) {
209			location->SetToExpression(value.block.data, value.block.length);
210			return B_OK;
211		}
212		return B_BAD_DATA;
213	}
214
215	return ATTRIBUTE_NOT_HANDLED;
216}
217
218
219status_t
220DebugInfoEntry::AddAttribute_sibling(uint16 attributeName,
221	const AttributeValue& value)
222{
223	// This attribute is only intended to help the debug info consumer. We don't
224	// need it.
225	return B_OK;
226}
227
228
229DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(name)
230DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(ordering)
231DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(byte_size)
232DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(bit_offset)
233DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(bit_size)
234DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(stmt_list)
235DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(low_pc)
236DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(high_pc)
237DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(language)
238DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(discr)
239DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(discr_value)
240DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(visibility)
241DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(import)
242DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(string_length)
243DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(common_reference)
244DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(comp_dir)
245DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(const_value)
246DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(containing_type)
247DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(default_value)
248DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(inline)
249DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(is_optional)
250DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(lower_bound)
251DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(producer)
252DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(prototyped)
253DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(return_addr)
254DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(start_scope)
255DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(bit_stride)
256DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(upper_bound)
257DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(abstract_origin)
258DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(accessibility)
259DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(address_class)
260DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(artificial)
261DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(base_types)
262DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(calling_convention)
263DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(count)
264DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(data_member_location)
265DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(declaration)
266DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(discr_list)
267DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(encoding)
268DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(external)
269DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(frame_base)
270DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(friend)
271DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(identifier_case)
272DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(macro_info)
273DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(namelist_item)
274DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(priority)
275DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(segment)
276DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(specification)
277DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(static_link)
278DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(type)
279DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(use_location)
280DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(variable_parameter)
281DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(virtuality)
282DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(vtable_elem_location)
283DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(allocated)
284DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(associated)
285DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(data_location)
286DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(byte_stride)
287DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(entry_pc)
288DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(use_UTF8)
289DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(extension)
290DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(ranges)
291DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(trampoline)
292DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(call_column)
293DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(call_file)
294DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(call_line)
295DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(description)
296DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(binary_scale)
297DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(decimal_scale)
298DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(small)
299DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(decimal_sign)
300DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(digit_count)
301DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(picture_string)
302DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(mutable)
303DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(threads_scaled)
304DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(explicit)
305DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(object_pointer)
306DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(endianity)
307DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(elemental)
308DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(pure)
309DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(recursive)
310DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(signature)
311DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(main_subprogram)
312DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(data_bit_offset)
313DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(const_expr)
314DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(enum_class)
315DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(linkage_name)
316DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(call_site_value)
317DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(call_site_data_value)
318DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(call_site_target)
319DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(call_site_target_clobbered)
320DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(tail_call)
321DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(all_tail_call_sites)
322DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(all_call_sites)
323DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(all_source_call_sites)
324
325
326DeclarationLocation*
327DebugInfoEntry::GetDeclarationLocation()
328{
329	return NULL;
330}
331
332
333status_t
334DebugInfoEntry::SetDynamicAttributeValue(DynamicAttributeValue& toSet,
335	const AttributeValue& value)
336{
337	switch (value.attributeClass) {
338		case ATTRIBUTE_CLASS_CONSTANT:
339			toSet.SetTo(value.constant);
340			return B_OK;
341		case ATTRIBUTE_CLASS_REFERENCE:
342			toSet.SetTo(value.reference);
343			return B_OK;
344		case ATTRIBUTE_CLASS_BLOCK:
345			toSet.SetTo(value.block.data, value.block.length);
346			return B_OK;
347		default:
348			return B_BAD_DATA;
349	}
350}
351
352
353status_t
354DebugInfoEntry::SetConstantAttributeValue(ConstantAttributeValue& toSet,
355	const AttributeValue& value)
356{
357	switch (value.attributeClass) {
358		case ATTRIBUTE_CLASS_CONSTANT:
359			toSet.SetTo(value.constant);
360			return B_OK;
361		case ATTRIBUTE_CLASS_STRING:
362			toSet.SetTo(value.string);
363			return B_OK;
364		case ATTRIBUTE_CLASS_BLOCK:
365			toSet.SetTo(value.block.data, value.block.length);
366			return B_OK;
367		default:
368			return B_BAD_DATA;
369	}
370}
371
372
373status_t
374DebugInfoEntry::SetMemberLocation(MemberLocation& toSet,
375	const AttributeValue& value)
376{
377	switch (value.attributeClass) {
378		case ATTRIBUTE_CLASS_CONSTANT:
379			toSet.SetToConstant(value.constant);
380			return B_OK;
381		case ATTRIBUTE_CLASS_BLOCK:
382			toSet.SetToExpression(value.block.data, value.block.length);
383			return B_OK;
384		case ATTRIBUTE_CLASS_LOCLISTPTR:
385			toSet.SetToLocationList(value.pointer);
386			return B_OK;
387		default:
388			return B_BAD_DATA;
389	}
390}
391