xref: /haiku/src/kits/debugger/dwarf/AttributeClasses.cpp (revision f7c507c3a6fbf3a44c59500543926a9088724968)
1 /*
2  * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Copyright 2013-2018, Rene Gollent, rene@gollent.com.
4  * Distributed under the terms of the MIT License.
5  */
6 
7 #include "AttributeClasses.h"
8 #include "Dwarf.h"
9 
10 
11 enum {
12 	AC_ADDRESS		= 1 << (ATTRIBUTE_CLASS_ADDRESS - 1),
13 	AC_BLOCK		= 1 << (ATTRIBUTE_CLASS_BLOCK - 1),
14 	AC_CONSTANT		= 1 << (ATTRIBUTE_CLASS_CONSTANT - 1),
15 	AC_FLAG			= 1 << (ATTRIBUTE_CLASS_FLAG - 1),
16 	AC_LINEPTR		= 1 << (ATTRIBUTE_CLASS_LINEPTR - 1),
17 	AC_LOCLISTPTR	= 1 << (ATTRIBUTE_CLASS_LOCLISTPTR - 1),
18 	AC_MACPTR		= 1 << (ATTRIBUTE_CLASS_MACPTR - 1),
19 	AC_RANGELISTPTR	= 1 << (ATTRIBUTE_CLASS_RANGELISTPTR - 1),
20 	AC_REFERENCE	= 1 << (ATTRIBUTE_CLASS_REFERENCE - 1),
21 	AC_STRING		= 1 << (ATTRIBUTE_CLASS_STRING - 1)
22 };
23 
24 
25 struct attribute_info_entry {
26 	const char*	name;
27 	uint16		value;
28 	uint16		classes;
29 };
30 
31 struct attribute_name_info_entry {
32 	const char*				name;
33 	DebugInfoEntrySetter	setter;
34 	uint16					value;
35 	uint16					classes;
36 };
37 
38 
39 #undef ENTRY
40 #define ENTRY(name)	"DW_AT_" #name, &DebugInfoEntry::AddAttribute_##name, \
41 	DW_AT_##name
42 
43 static const attribute_name_info_entry kAttributeNameInfos[] = {
44 	{ ENTRY(sibling),				AC_REFERENCE },
45 	{ ENTRY(location),				AC_BLOCK | AC_LOCLISTPTR },
46 	{ ENTRY(name),					AC_STRING },
47 	{ ENTRY(ordering),				AC_CONSTANT },
48 	{ ENTRY(byte_size),				AC_BLOCK | AC_CONSTANT | AC_REFERENCE },
49 	{ ENTRY(bit_offset),			AC_BLOCK | AC_CONSTANT | AC_REFERENCE },
50 	{ ENTRY(bit_size),				AC_BLOCK | AC_CONSTANT | AC_REFERENCE },
51 	{ ENTRY(stmt_list),				AC_LINEPTR },
52 	{ ENTRY(low_pc),				AC_ADDRESS | AC_CONSTANT | AC_REFERENCE },
53 	{ ENTRY(high_pc),				AC_ADDRESS | AC_CONSTANT | AC_REFERENCE },
54 	{ ENTRY(language),				AC_CONSTANT },
55 	{ ENTRY(discr),					AC_REFERENCE },
56 	{ ENTRY(discr_value),			AC_CONSTANT },
57 	{ ENTRY(visibility),			AC_CONSTANT },
58 	{ ENTRY(import),				AC_REFERENCE },
59 	{ ENTRY(string_length),			AC_BLOCK | AC_LOCLISTPTR },
60 	{ ENTRY(common_reference),		AC_REFERENCE },
61 	{ ENTRY(comp_dir),				AC_STRING },
62 	{ ENTRY(const_value),			AC_BLOCK | AC_CONSTANT | AC_STRING },
63 	{ ENTRY(containing_type),		AC_REFERENCE },
64 	{ ENTRY(default_value),			AC_REFERENCE | AC_CONSTANT | AC_FLAG },
65 	{ ENTRY(inline),				AC_CONSTANT },
66 	{ ENTRY(is_optional),			AC_FLAG },
67 	{ ENTRY(lower_bound),			AC_BLOCK | AC_CONSTANT | AC_REFERENCE },
68 	{ ENTRY(producer),				AC_STRING },
69 	{ ENTRY(prototyped),			AC_FLAG },
70 	{ ENTRY(return_addr),			AC_BLOCK | AC_LOCLISTPTR },
71 	{ ENTRY(start_scope),			AC_CONSTANT },
72 	{ ENTRY(bit_stride),			AC_BLOCK | AC_CONSTANT | AC_REFERENCE },
73 	{ ENTRY(upper_bound),			AC_BLOCK | AC_CONSTANT | AC_REFERENCE },
74 	{ ENTRY(abstract_origin),		AC_REFERENCE },
75 	{ ENTRY(accessibility),			AC_CONSTANT },
76 	{ ENTRY(address_class),			AC_CONSTANT },
77 	{ ENTRY(artificial),			AC_FLAG },
78 	{ ENTRY(base_types),			AC_REFERENCE },
79 	{ ENTRY(calling_convention),	AC_CONSTANT },
80 	{ ENTRY(count),					AC_BLOCK | AC_CONSTANT | AC_REFERENCE },
81 	{ ENTRY(data_member_location),	AC_BLOCK | AC_CONSTANT | AC_LOCLISTPTR },
82 	{ ENTRY(decl_column),			AC_CONSTANT },
83 	{ ENTRY(decl_file),				AC_CONSTANT },
84 	{ ENTRY(decl_line),				AC_CONSTANT },
85 	{ ENTRY(declaration),			AC_FLAG },
86 	{ ENTRY(discr_list),			AC_BLOCK },
87 	{ ENTRY(encoding),				AC_CONSTANT },
88 	{ ENTRY(external),				AC_FLAG },
89 	{ ENTRY(frame_base),			AC_BLOCK | AC_LOCLISTPTR },
90 	{ ENTRY(friend),				AC_REFERENCE },
91 	{ ENTRY(identifier_case),		AC_CONSTANT },
92 	{ ENTRY(macro_info),			AC_MACPTR },
93 	{ ENTRY(namelist_item),			AC_BLOCK | AC_REFERENCE },
94 	{ ENTRY(priority),				AC_REFERENCE },
95 	{ ENTRY(segment),				AC_BLOCK | AC_LOCLISTPTR },
96 	{ ENTRY(specification),			AC_REFERENCE },
97 	{ ENTRY(static_link),			AC_BLOCK | AC_LOCLISTPTR },
98 	{ ENTRY(type),					AC_REFERENCE },
99 	{ ENTRY(use_location),			AC_BLOCK | AC_LOCLISTPTR },
100 	{ ENTRY(variable_parameter),	AC_FLAG },
101 	{ ENTRY(virtuality),			AC_CONSTANT },
102 	{ ENTRY(vtable_elem_location),	AC_BLOCK | AC_LOCLISTPTR },
103 	{ ENTRY(allocated),				AC_BLOCK | AC_CONSTANT | AC_REFERENCE },
104 	{ ENTRY(associated),			AC_BLOCK | AC_CONSTANT | AC_REFERENCE },
105 	{ ENTRY(data_location),			AC_BLOCK },
106 	{ ENTRY(byte_stride),			AC_BLOCK | AC_CONSTANT | AC_REFERENCE },
107 	{ ENTRY(entry_pc),				AC_ADDRESS },
108 	{ ENTRY(use_UTF8),				AC_FLAG },
109 	{ ENTRY(extension),				AC_REFERENCE },
110 	{ ENTRY(ranges),				AC_RANGELISTPTR },
111 	{ ENTRY(trampoline),			AC_ADDRESS | AC_FLAG | AC_REFERENCE
112 										| AC_STRING },
113 	{ ENTRY(call_column),			AC_CONSTANT },
114 	{ ENTRY(call_file),				AC_CONSTANT },
115 	{ ENTRY(call_line),				AC_CONSTANT },
116 	{ ENTRY(description),			AC_STRING },
117 	{ ENTRY(binary_scale),			AC_CONSTANT },
118 	{ ENTRY(decimal_scale),			AC_CONSTANT },
119 	{ ENTRY(small),					AC_REFERENCE },
120 	{ ENTRY(decimal_sign),			AC_CONSTANT },
121 	{ ENTRY(digit_count),			AC_CONSTANT },
122 	{ ENTRY(picture_string),		AC_STRING },
123 	{ ENTRY(mutable),				AC_FLAG },
124 	{ ENTRY(threads_scaled),		AC_FLAG },
125 	{ ENTRY(explicit),				AC_FLAG },
126 	{ ENTRY(object_pointer),		AC_REFERENCE },
127 	{ ENTRY(endianity),				AC_CONSTANT },
128 	{ ENTRY(elemental),				AC_FLAG },
129 	{ ENTRY(pure),					AC_FLAG },
130 	{ ENTRY(recursive),				AC_FLAG },
131 	{ ENTRY(signature),				AC_REFERENCE },
132 	{ ENTRY(main_subprogram),		AC_FLAG },
133 	{ ENTRY(data_bit_offset),		AC_CONSTANT },
134 	{ ENTRY(const_expr),			AC_FLAG },
135 	{ ENTRY(enum_class),			AC_FLAG },
136 	{ ENTRY(linkage_name),			AC_STRING },
137 	{ ENTRY(call_site_value),		AC_BLOCK },
138 	{ ENTRY(call_site_data_value),	AC_BLOCK },
139 	{ ENTRY(call_site_target),		AC_BLOCK },
140 	{ ENTRY(call_site_target_clobbered),
141 									AC_BLOCK },
142 	{ ENTRY(tail_call),				AC_FLAG },
143 	{ ENTRY(all_tail_call_sites),	AC_FLAG },
144 	{ ENTRY(all_call_sites),		AC_FLAG },
145 	{ ENTRY(all_source_call_sites),	AC_FLAG },
146 
147 	{}
148 };
149 
150 static const uint32 kAttributeNameInfoCount = DW_AT_linkage_name + 9;
151 static attribute_name_info_entry sAttributeNameInfos[kAttributeNameInfoCount];
152 
153 
154 #undef ENTRY
155 #define ENTRY(name)	"DW_FORM_" #name, DW_FORM_##name
156 
157 static const attribute_info_entry kAttributeFormInfos[] = {
158 	{ ENTRY(addr),			AC_ADDRESS },
159 	{ ENTRY(block2),		AC_BLOCK },
160 	{ ENTRY(block4),		AC_BLOCK },
161 	{ ENTRY(data2),			AC_CONSTANT },
162 	{ ENTRY(data4),			AC_CONSTANT | AC_LINEPTR | AC_LOCLISTPTR
163 								| AC_MACPTR | AC_RANGELISTPTR },
164 	{ ENTRY(data8),			AC_CONSTANT | AC_LINEPTR | AC_LOCLISTPTR
165 								| AC_MACPTR | AC_RANGELISTPTR },
166 	{ ENTRY(string),		AC_STRING },
167 	{ ENTRY(block),			AC_BLOCK },
168 	{ ENTRY(block1),		AC_BLOCK },
169 	{ ENTRY(data1),			AC_CONSTANT },
170 	{ ENTRY(flag),			AC_FLAG },
171 	{ ENTRY(sdata),			AC_CONSTANT },
172 	{ ENTRY(strp),			AC_STRING },
173 	{ ENTRY(udata),			AC_CONSTANT },
174 	{ ENTRY(ref_addr),		AC_REFERENCE },
175 	{ ENTRY(ref1),			AC_REFERENCE },
176 	{ ENTRY(ref2),			AC_REFERENCE },
177 	{ ENTRY(ref4),			AC_REFERENCE },
178 	{ ENTRY(ref8),			AC_REFERENCE },
179 	{ ENTRY(ref_udata),		AC_REFERENCE },
180 	{ ENTRY(indirect),		AC_REFERENCE },
181 	{ ENTRY(sec_offset),	AC_LINEPTR | AC_LOCLISTPTR | AC_MACPTR
182 								| AC_RANGELISTPTR },
183 	{ ENTRY(exprloc),		AC_BLOCK },
184 	{ ENTRY(flag_present),	AC_FLAG },
185 	{ ENTRY(ref_sig8),		AC_REFERENCE },
186 	{}
187 };
188 
189 static const uint32 kAttributeFormInfoCount = DW_FORM_ref_sig8 + 1;
190 static attribute_info_entry sAttributeFormInfos[kAttributeFormInfoCount];
191 
192 static struct InitAttributeInfos {
193 	InitAttributeInfos()
194 	{
195 		for (uint32 i = 0; kAttributeNameInfos[i].name != NULL; i++) {
196 			const attribute_name_info_entry& entry = kAttributeNameInfos[i];
197 			if (entry.value <= DW_AT_linkage_name)
198 				sAttributeNameInfos[entry.value] = entry;
199 			else {
200 				sAttributeNameInfos[DW_AT_linkage_name + 1
201 					+ (entry.value - DW_AT_call_site_value)] = entry;
202 			}
203 		}
204 
205 		for (uint32 i = 0; kAttributeFormInfos[i].name != NULL; i++) {
206 			const attribute_info_entry& entry = kAttributeFormInfos[i];
207 			sAttributeFormInfos[entry.value] = entry;
208 		}
209 	}
210 } sInitAttributeInfos;
211 
212 
213 uint16
214 get_attribute_name_classes(uint32 name)
215 {
216 	if (name <= DW_AT_linkage_name)
217 		return sAttributeNameInfos[name].classes;
218 	else if (name >= DW_AT_call_site_value
219 		&& name <= DW_AT_all_source_call_sites) {
220 		return sAttributeNameInfos[DW_AT_linkage_name + 1
221 			+ (name - DW_AT_call_site_value)].classes;
222 	}
223 
224 	return 0;
225 }
226 
227 
228 uint16
229 get_attribute_form_classes(uint32 form)
230 {
231 	return form < kAttributeFormInfoCount
232 		? sAttributeFormInfos[form].classes : 0;
233 }
234 
235 
236 uint8
237 get_attribute_class(uint32 name, uint32 form)
238 {
239 	uint16 classes = get_attribute_name_classes(name)
240 		& get_attribute_form_classes(form);
241 
242 	int clazz = 0;
243 	while (classes != 0) {
244 		classes >>= 1;
245 		clazz++;
246 	}
247 
248 	return clazz;
249 }
250 
251 
252 const char*
253 get_attribute_name_name(uint32 name)
254 {
255 	if (name <= DW_AT_linkage_name)
256 		return sAttributeNameInfos[name].name;
257 	else if (name >= DW_AT_call_site_value
258 		&& name <= DW_AT_all_source_call_sites) {
259 		return sAttributeNameInfos[DW_AT_linkage_name + 1 +
260 				(name - DW_AT_call_site_value)].name;
261 	}
262 
263 	return NULL;
264 }
265 
266 
267 const char*
268 get_attribute_form_name(uint32 form)
269 {
270 	return form < kAttributeFormInfoCount
271 		? sAttributeFormInfos[form].name : NULL;
272 }
273 
274 
275 DebugInfoEntrySetter
276 get_attribute_name_setter(uint32 name)
277 {
278 	return (name < kAttributeNameInfoCount)
279 		? sAttributeNameInfos[name].setter : NULL;
280 }
281