xref: /haiku/src/kits/debugger/dwarf/AttributeClasses.cpp (revision 3634f142352af2428aed187781fc9d75075e9140)
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_ADDRPTR		= 1 << (ATTRIBUTE_CLASS_ADDRPTR - 1),
14 	AC_BLOCK		= 1 << (ATTRIBUTE_CLASS_BLOCK - 1),
15 	AC_CONSTANT		= 1 << (ATTRIBUTE_CLASS_CONSTANT - 1),
16 	AC_FLAG			= 1 << (ATTRIBUTE_CLASS_FLAG - 1),
17 	AC_LINEPTR		= 1 << (ATTRIBUTE_CLASS_LINEPTR - 1),
18 	AC_LOCLIST   	= 1 << (ATTRIBUTE_CLASS_LOCLIST - 1),
19 	AC_LOCLISTPTR	= 1 << (ATTRIBUTE_CLASS_LOCLISTPTR - 1),
20 	AC_MACPTR		= 1 << (ATTRIBUTE_CLASS_MACPTR - 1),
21 	AC_RANGELIST   	= 1 << (ATTRIBUTE_CLASS_RANGELIST - 1),
22 	AC_RANGELISTPTR	= 1 << (ATTRIBUTE_CLASS_RANGELISTPTR - 1),
23 	AC_REFERENCE	= 1 << (ATTRIBUTE_CLASS_REFERENCE - 1),
24 	AC_STRING		= 1 << (ATTRIBUTE_CLASS_STRING - 1),
25 	AC_STROFFSETSPTR= 1 << (ATTRIBUTE_CLASS_STROFFSETSPTR - 1),
26 };
27 
28 
29 struct attribute_info_entry {
30 	const char*	name;
31 	uint16		value;
32 	uint16		classes;
33 };
34 
35 struct attribute_name_info_entry {
36 	const char*				name;
37 	DebugInfoEntrySetter	setter;
38 	uint16					value;
39 	uint16					classes;
40 };
41 
42 
43 #undef ENTRY
44 #define ENTRY(name)	"DW_AT_" #name, &DebugInfoEntry::AddAttribute_##name, \
45 	DW_AT_##name
46 
47 static const attribute_name_info_entry kAttributeNameInfos[] = {
48 	{ ENTRY(sibling),				AC_REFERENCE },
49 	{ ENTRY(location),				AC_BLOCK | AC_LOCLIST },
50 	{ ENTRY(name),					AC_STRING },
51 	{ ENTRY(ordering),				AC_CONSTANT },
52 	{ ENTRY(byte_size),				AC_BLOCK | AC_CONSTANT | AC_REFERENCE },
53 	{ ENTRY(bit_offset),			AC_BLOCK | AC_CONSTANT | AC_REFERENCE },
54 	{ ENTRY(bit_size),				AC_BLOCK | AC_CONSTANT | AC_REFERENCE },
55 	{ ENTRY(stmt_list),				AC_LINEPTR },
56 	{ ENTRY(low_pc),				AC_ADDRESS | AC_CONSTANT | AC_REFERENCE },
57 	{ ENTRY(high_pc),				AC_ADDRESS | AC_CONSTANT | AC_REFERENCE },
58 	{ ENTRY(language),				AC_CONSTANT },
59 	{ ENTRY(discr),					AC_REFERENCE },
60 	{ ENTRY(discr_value),			AC_CONSTANT },
61 	{ ENTRY(visibility),			AC_CONSTANT },
62 	{ ENTRY(import),				AC_REFERENCE },
63 	{ ENTRY(string_length),			AC_BLOCK | AC_LOCLIST },
64 	{ ENTRY(common_reference),		AC_REFERENCE },
65 	{ ENTRY(comp_dir),				AC_STRING },
66 	{ ENTRY(const_value),			AC_BLOCK | AC_CONSTANT | AC_STRING },
67 	{ ENTRY(containing_type),		AC_REFERENCE },
68 	{ ENTRY(default_value),			AC_REFERENCE | AC_CONSTANT | AC_FLAG },
69 	{ ENTRY(inline),				AC_CONSTANT },
70 	{ ENTRY(is_optional),			AC_FLAG },
71 	{ ENTRY(lower_bound),			AC_BLOCK | AC_CONSTANT | AC_REFERENCE },
72 	{ ENTRY(producer),				AC_STRING },
73 	{ ENTRY(prototyped),			AC_FLAG },
74 	{ ENTRY(return_addr),			AC_BLOCK | AC_LOCLIST },
75 	{ ENTRY(start_scope),			AC_CONSTANT },
76 	{ ENTRY(bit_stride),			AC_BLOCK | AC_CONSTANT | AC_REFERENCE },
77 	{ ENTRY(upper_bound),			AC_BLOCK | AC_CONSTANT | AC_REFERENCE },
78 	{ ENTRY(abstract_origin),		AC_REFERENCE },
79 	{ ENTRY(accessibility),			AC_CONSTANT },
80 	{ ENTRY(address_class),			AC_CONSTANT },
81 	{ ENTRY(artificial),			AC_FLAG },
82 	{ ENTRY(base_types),			AC_REFERENCE },
83 	{ ENTRY(calling_convention),	AC_CONSTANT },
84 	{ ENTRY(count),					AC_BLOCK | AC_CONSTANT | AC_REFERENCE },
85 	{ ENTRY(data_member_location),	AC_BLOCK | AC_CONSTANT | AC_LOCLIST },
86 	{ ENTRY(decl_column),			AC_CONSTANT },
87 	{ ENTRY(decl_file),				AC_CONSTANT },
88 	{ ENTRY(decl_line),				AC_CONSTANT },
89 	{ ENTRY(declaration),			AC_FLAG },
90 	{ ENTRY(discr_list),			AC_BLOCK },
91 	{ ENTRY(encoding),				AC_CONSTANT },
92 	{ ENTRY(external),				AC_FLAG },
93 	{ ENTRY(frame_base),			AC_BLOCK | AC_LOCLIST },
94 	{ ENTRY(friend),				AC_REFERENCE },
95 	{ ENTRY(identifier_case),		AC_CONSTANT },
96 	{ ENTRY(macro_info),			AC_MACPTR },
97 	{ ENTRY(namelist_item),			AC_BLOCK | AC_REFERENCE },
98 	{ ENTRY(priority),				AC_REFERENCE },
99 	{ ENTRY(segment),				AC_BLOCK | AC_LOCLIST },
100 	{ ENTRY(specification),			AC_REFERENCE },
101 	{ ENTRY(static_link),			AC_BLOCK | AC_LOCLIST },
102 	{ ENTRY(type),					AC_REFERENCE },
103 	{ ENTRY(use_location),			AC_BLOCK | AC_LOCLIST },
104 	{ ENTRY(variable_parameter),	AC_FLAG },
105 	{ ENTRY(virtuality),			AC_CONSTANT },
106 	{ ENTRY(vtable_elem_location),	AC_BLOCK | AC_LOCLIST },
107 	{ ENTRY(allocated),				AC_BLOCK | AC_CONSTANT | AC_REFERENCE },
108 	{ ENTRY(associated),			AC_BLOCK | AC_CONSTANT | AC_REFERENCE },
109 	{ ENTRY(data_location),			AC_BLOCK },
110 	{ ENTRY(byte_stride),			AC_BLOCK | AC_CONSTANT | AC_REFERENCE },
111 	{ ENTRY(entry_pc),				AC_ADDRESS },
112 	{ ENTRY(use_UTF8),				AC_FLAG },
113 	{ ENTRY(extension),				AC_REFERENCE },
114 	{ ENTRY(ranges),				AC_RANGELIST },
115 	{ ENTRY(trampoline),			AC_ADDRESS | AC_FLAG | AC_REFERENCE
116 										| AC_STRING },
117 	{ ENTRY(call_column),			AC_CONSTANT },
118 	{ ENTRY(call_file),				AC_CONSTANT },
119 	{ ENTRY(call_line),				AC_CONSTANT },
120 	{ ENTRY(description),			AC_STRING },
121 	{ ENTRY(binary_scale),			AC_CONSTANT },
122 	{ ENTRY(decimal_scale),			AC_CONSTANT },
123 	{ ENTRY(small),					AC_REFERENCE },
124 	{ ENTRY(decimal_sign),			AC_CONSTANT },
125 	{ ENTRY(digit_count),			AC_CONSTANT },
126 	{ ENTRY(picture_string),		AC_STRING },
127 	{ ENTRY(mutable),				AC_FLAG },
128 	{ ENTRY(threads_scaled),		AC_FLAG },
129 	{ ENTRY(explicit),				AC_FLAG },
130 	{ ENTRY(object_pointer),		AC_REFERENCE },
131 	{ ENTRY(endianity),				AC_CONSTANT },
132 	{ ENTRY(elemental),				AC_FLAG },
133 	{ ENTRY(pure),					AC_FLAG },
134 	{ ENTRY(recursive),				AC_FLAG },
135 	{ ENTRY(signature),				AC_REFERENCE },
136 	{ ENTRY(main_subprogram),		AC_FLAG },
137 	{ ENTRY(data_bit_offset),		AC_CONSTANT },
138 	{ ENTRY(const_expr),			AC_FLAG },
139 	{ ENTRY(enum_class),			AC_FLAG },
140 	{ ENTRY(linkage_name),			AC_STRING },
141 	{ ENTRY(string_length_bit_size),
142 									AC_CONSTANT },
143 	{ ENTRY(string_length_byte_size),
144 									AC_CONSTANT },
145 	{ ENTRY(rank),					AC_CONSTANT | AC_BLOCK },
146 	{ ENTRY(str_offsets_base),		AC_STROFFSETSPTR },
147 	{ ENTRY(addr_base),				AC_ADDRPTR },
148 	{ ENTRY(rnglists_base),			AC_RANGELISTPTR },
149 	{ ENTRY(dwo_name),				AC_STRING },
150 	{ ENTRY(reference),				AC_FLAG },
151 	{ ENTRY(rvalue_reference),		AC_FLAG },
152 	{ ENTRY(macros),				AC_MACPTR },
153 	{ ENTRY(call_all_calls),		AC_FLAG },
154 	{ ENTRY(call_all_source_calls),	AC_FLAG },
155 	{ ENTRY(call_all_tail_calls),	AC_FLAG },
156 	{ ENTRY(call_return_pc),		AC_ADDRESS },
157 	{ ENTRY(call_value),			AC_BLOCK },
158 	{ ENTRY(call_origin),			AC_BLOCK },
159 	{ ENTRY(call_parameter),		AC_REFERENCE },
160 	{ ENTRY(call_pc),				AC_ADDRESS },
161 	{ ENTRY(call_tail_call),		AC_FLAG },
162 	{ ENTRY(call_target),			AC_BLOCK },
163 	{ ENTRY(call_target_clobbered),	AC_BLOCK },
164 	{ ENTRY(call_data_location),	AC_BLOCK },
165 	{ ENTRY(call_data_value),		AC_BLOCK },
166 	{ ENTRY(noreturn),				AC_FLAG },
167 	{ ENTRY(alignment),				AC_CONSTANT },
168 	{ ENTRY(export_symbols),		AC_FLAG },
169 	{ ENTRY(deleted),				AC_FLAG },
170 	{ ENTRY(defaulted),				AC_CONSTANT },
171 	{ ENTRY(loclists_base),			AC_LOCLISTPTR },
172 	{ ENTRY(call_site_value),		AC_BLOCK },
173 	{ ENTRY(call_site_data_value),	AC_BLOCK },
174 	{ ENTRY(call_site_target),		AC_BLOCK },
175 	{ ENTRY(call_site_target_clobbered),
176 									AC_BLOCK },
177 	{ ENTRY(tail_call),				AC_FLAG },
178 	{ ENTRY(all_tail_call_sites),	AC_FLAG },
179 	{ ENTRY(all_call_sites),		AC_FLAG },
180 	{ ENTRY(all_source_call_sites),	AC_FLAG },
181 
182 	{}
183 };
184 
185 static const uint32 kAttributeNameInfoCount = DW_AT_loclists_base + 9;
186 static attribute_name_info_entry sAttributeNameInfos[kAttributeNameInfoCount];
187 
188 
189 #undef ENTRY
190 #define ENTRY(name)	"DW_FORM_" #name, DW_FORM_##name
191 
192 static const attribute_info_entry kAttributeFormInfos[] = {
193 	{ ENTRY(addr),			AC_ADDRESS },
194 	{ ENTRY(block2),		AC_BLOCK },
195 	{ ENTRY(block4),		AC_BLOCK },
196 	{ ENTRY(data2),			AC_CONSTANT },
197 	{ ENTRY(data4),			AC_CONSTANT | AC_LINEPTR | AC_LOCLIST
198 								| AC_MACPTR | AC_RANGELIST },
199 	{ ENTRY(data8),			AC_CONSTANT | AC_LINEPTR | AC_LOCLIST
200 								| AC_MACPTR | AC_RANGELIST },
201 	{ ENTRY(string),		AC_STRING },
202 	{ ENTRY(block),			AC_BLOCK },
203 	{ ENTRY(block1),		AC_BLOCK },
204 	{ ENTRY(data1),			AC_CONSTANT },
205 	{ ENTRY(flag),			AC_FLAG },
206 	{ ENTRY(sdata),			AC_CONSTANT },
207 	{ ENTRY(strp),			AC_STRING },
208 	{ ENTRY(udata),			AC_CONSTANT },
209 	{ ENTRY(ref_addr),		AC_REFERENCE },
210 	{ ENTRY(ref1),			AC_REFERENCE },
211 	{ ENTRY(ref2),			AC_REFERENCE },
212 	{ ENTRY(ref4),			AC_REFERENCE },
213 	{ ENTRY(ref8),			AC_REFERENCE },
214 	{ ENTRY(ref_udata),		AC_REFERENCE },
215 	{ ENTRY(indirect),		AC_REFERENCE },
216 	{ ENTRY(sec_offset),	AC_ADDRPTR | AC_LINEPTR
217 								| AC_LOCLIST | AC_LOCLISTPTR
218 								| AC_MACPTR
219 								| AC_RANGELIST | AC_RANGELISTPTR
220 								| AC_STROFFSETSPTR  },
221 	{ ENTRY(exprloc),		AC_BLOCK },
222 	{ ENTRY(flag_present),	AC_FLAG },
223 	{ ENTRY(strx),			AC_STRING },
224 	{ ENTRY(addrx),			AC_ADDRESS },
225 	{ ENTRY(ref_sup4),		AC_REFERENCE },
226 	{ ENTRY(strp_sup),		AC_STRING },
227 	{ ENTRY(data16),		AC_CONSTANT },
228 	{ ENTRY(line_strp),		AC_STRING },
229 	{ ENTRY(ref_sig8),		AC_REFERENCE },
230 	{ ENTRY(implicit_const),
231 							AC_CONSTANT },
232 	{ ENTRY(loclistx),		AC_LOCLIST },
233 	{ ENTRY(rnglistx),		AC_RANGELIST },
234 	{ ENTRY(ref_sup8),		AC_REFERENCE },
235 	{ ENTRY(strx1),			AC_STRING },
236 	{ ENTRY(strx2),			AC_STRING },
237 	{ ENTRY(strx3),			AC_STRING },
238 	{ ENTRY(strx4),			AC_STRING },
239 	{ ENTRY(addrx1),		AC_ADDRESS },
240 	{ ENTRY(addrx2),		AC_ADDRESS },
241 	{ ENTRY(addrx3),		AC_ADDRESS },
242 	{ ENTRY(addrx4),		AC_ADDRESS },
243 	{}
244 };
245 
246 static const uint32 kAttributeFormInfoCount = DW_FORM_addrx4 + 1;
247 static attribute_info_entry sAttributeFormInfos[kAttributeFormInfoCount];
248 
249 static struct InitAttributeInfos {
250 	InitAttributeInfos()
251 	{
252 		for (uint32 i = 0; kAttributeNameInfos[i].name != NULL; i++) {
253 			const attribute_name_info_entry& entry = kAttributeNameInfos[i];
254 			if (entry.value <= DW_AT_loclists_base)
255 				sAttributeNameInfos[entry.value] = entry;
256 			else {
257 				sAttributeNameInfos[DW_AT_loclists_base + 1
258 					+ (entry.value - DW_AT_call_site_value)] = entry;
259 			}
260 		}
261 
262 		for (uint32 i = 0; kAttributeFormInfos[i].name != NULL; i++) {
263 			const attribute_info_entry& entry = kAttributeFormInfos[i];
264 			sAttributeFormInfos[entry.value] = entry;
265 		}
266 	}
267 } sInitAttributeInfos;
268 
269 
270 uint16
271 get_attribute_name_classes(uint32 name)
272 {
273 	if (name <= DW_AT_loclists_base)
274 		return sAttributeNameInfos[name].classes;
275 	else if (name >= DW_AT_call_site_value
276 		&& name <= DW_AT_all_source_call_sites) {
277 		return sAttributeNameInfos[DW_AT_loclists_base + 1
278 			+ (name - DW_AT_call_site_value)].classes;
279 	}
280 
281 	return 0;
282 }
283 
284 
285 uint16
286 get_attribute_form_classes(uint32 form)
287 {
288 	return form < kAttributeFormInfoCount
289 		? sAttributeFormInfos[form].classes : 0;
290 }
291 
292 
293 uint8
294 get_attribute_class(uint32 name, uint32 form)
295 {
296 	uint16 classes = get_attribute_name_classes(name)
297 		& get_attribute_form_classes(form);
298 
299 	int clazz = 0;
300 	while (classes != 0) {
301 		classes >>= 1;
302 		clazz++;
303 	}
304 
305 	return clazz;
306 }
307 
308 
309 const char*
310 get_attribute_name_name(uint32 name)
311 {
312 	if (name <= DW_AT_loclists_base)
313 		return sAttributeNameInfos[name].name;
314 	else if (name >= DW_AT_call_site_value
315 		&& name <= DW_AT_all_source_call_sites) {
316 		return sAttributeNameInfos[DW_AT_loclists_base + 1 +
317 				(name - DW_AT_call_site_value)].name;
318 	}
319 
320 	return NULL;
321 }
322 
323 
324 const char*
325 get_attribute_form_name(uint32 form)
326 {
327 	return form < kAttributeFormInfoCount
328 		? sAttributeFormInfos[form].name : NULL;
329 }
330 
331 
332 DebugInfoEntrySetter
333 get_attribute_name_setter(uint32 name)
334 {
335 	return (name < kAttributeNameInfoCount)
336 		? sAttributeNameInfos[name].setter : NULL;
337 }
338