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 {
InitAttributeInfosInitAttributeInfos250 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
get_attribute_name_classes(uint32 name)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
get_attribute_form_classes(uint32 form)286 get_attribute_form_classes(uint32 form)
287 {
288 return form < kAttributeFormInfoCount
289 ? sAttributeFormInfos[form].classes : 0;
290 }
291
292
293 uint8
get_attribute_class(uint32 name,uint32 form)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*
get_attribute_name_name(uint32 name)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*
get_attribute_form_name(uint32 form)325 get_attribute_form_name(uint32 form)
326 {
327 return form < kAttributeFormInfoCount
328 ? sAttributeFormInfos[form].name : NULL;
329 }
330
331
332 DebugInfoEntrySetter
get_attribute_name_setter(uint32 name)333 get_attribute_name_setter(uint32 name)
334 {
335 return (name < kAttributeNameInfoCount)
336 ? sAttributeNameInfos[name].setter : NULL;
337 }
338