]>
Commit | Line | Data |
---|---|---|
b7e215a8 IB |
1 | /* Generate CTF types and objects from the GCC DWARF. |
2 | Copyright (C) 2021 Free Software Foundation, Inc. | |
3 | ||
4 | This file is part of GCC. | |
5 | ||
6 | GCC is free software; you can redistribute it and/or modify it under | |
7 | the terms of the GNU General Public License as published by the Free | |
8 | Software Foundation; either version 3, or (at your option) any later | |
9 | version. | |
10 | ||
11 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
12 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
13 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
14 | for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
17 | along with GCC; see the file COPYING3. If not see | |
18 | <http://www.gnu.org/licenses/>. */ | |
19 | ||
20 | #include "config.h" | |
21 | #include "system.h" | |
22 | #include "coretypes.h" | |
23 | #include "target.h" | |
24 | #include "dwarf2out.h" | |
25 | #include "dwarf2out.h" | |
26 | ||
27 | #include "dwarf2ctf.h" | |
28 | #include "ctfc.h" | |
29 | ||
30 | /* Forward declarations for some routines defined in this file. */ | |
31 | ||
32 | static ctf_id_t | |
33 | gen_ctf_type (ctf_container_ref, dw_die_ref); | |
34 | ||
35 | /* All the DIE structures we handle come from the DWARF information | |
78fff8a4 | 36 | generated by GCC. However, there are three situations where we need |
b7e215a8 IB |
37 | to create our own created DIE structures because GCC doesn't |
38 | provide them. | |
39 | ||
40 | The DWARF spec suggests using a DIE with DW_TAG_unspecified_type | |
41 | and name "void" in order to denote the void type. But GCC doesn't | |
42 | follow this advice. Still we need a DIE to act as a key for void | |
43 | types, we use ctf_void_die. | |
44 | ||
45 | Also, if a subrange type corresponding to an array index does not | |
46 | specify a type then we assume it is `int'. | |
47 | ||
48 | Finally, for types unrepresentable in CTF, we need a DIE to anchor | |
49 | them to a CTF type of kind unknown. | |
50 | ||
51 | The variables below are initialized in ctf_debug_init and hold | |
52 | references to the proper DIEs. */ | |
53 | ||
54 | static GTY (()) dw_die_ref ctf_void_die; | |
55 | static GTY (()) dw_die_ref ctf_array_index_die; | |
56 | static GTY (()) dw_die_ref ctf_unknown_die; | |
57 | ||
58 | /* Some DIEs have a type description attribute, stored in a DW_AT_type | |
59 | attribute. However, GCC generates no attribute to signify a `void' | |
60 | type. | |
61 | ||
62 | This can happen in many contexts (return type of a function, | |
63 | pointed or qualified type, etc) so we use the `ctf_get_AT_type' | |
64 | function below abstracts this. */ | |
65 | ||
66 | static dw_die_ref | |
67 | ctf_get_AT_type (dw_die_ref die) | |
68 | { | |
69 | dw_die_ref type_die = get_AT_ref (die, DW_AT_type); | |
70 | return (type_die ? type_die : ctf_void_die); | |
71 | } | |
72 | ||
73 | /* Some data member DIEs have location specified as a DWARF expression | |
74 | (specifically in DWARF2). Luckily, the expression is a simple | |
75 | DW_OP_plus_uconst with one operand set to zero. | |
76 | ||
77 | Sometimes the data member location may also be negative. In yet some other | |
78 | cases (specifically union data members), the data member location is | |
79 | non-existent. Handle all these scenarios here to abstract this. */ | |
80 | ||
81 | static HOST_WIDE_INT | |
82 | ctf_get_AT_data_member_location (dw_die_ref die) | |
83 | { | |
84 | HOST_WIDE_INT field_location = 0; | |
85 | dw_attr_node * attr; | |
86 | ||
87 | /* The field location (in bits) can be determined from | |
88 | either a DW_AT_data_member_location attribute or a | |
89 | DW_AT_data_bit_offset attribute. */ | |
90 | if (get_AT (die, DW_AT_data_bit_offset)) | |
91 | field_location = get_AT_unsigned (die, DW_AT_data_bit_offset); | |
92 | else | |
93 | { | |
94 | attr = get_AT (die, DW_AT_data_member_location); | |
95 | if (attr && AT_class (attr) == dw_val_class_loc) | |
96 | { | |
97 | dw_loc_descr_ref descr = AT_loc (attr); | |
98 | /* Operand 2 must be zero; the structure is assumed to be on the | |
99 | stack in DWARF2. */ | |
100 | gcc_assert (!descr->dw_loc_oprnd2.v.val_unsigned); | |
101 | gcc_assert (descr->dw_loc_oprnd2.val_class | |
102 | == dw_val_class_unsigned_const); | |
151b423a | 103 | field_location = descr->dw_loc_oprnd1.v.val_unsigned * 8; |
b7e215a8 IB |
104 | } |
105 | else | |
106 | { | |
107 | attr = get_AT (die, DW_AT_data_member_location); | |
108 | if (attr && AT_class (attr) == dw_val_class_const) | |
151b423a | 109 | field_location = AT_int (attr) * 8; |
b7e215a8 IB |
110 | else |
111 | field_location = (get_AT_unsigned (die, | |
112 | DW_AT_data_member_location) | |
113 | * 8); | |
114 | } | |
115 | } | |
116 | ||
117 | return field_location; | |
118 | } | |
119 | ||
120 | /* CTF Types' and CTF Variables' Location Information. CTF section does not | |
121 | emit location information, this is provided for BTF CO-RE use-cases. These | |
122 | functions fetch information from DWARF Die directly, as such the location | |
123 | information is not buffered in the CTF container. */ | |
124 | ||
125 | const char * | |
126 | ctf_get_die_loc_file (dw_die_ref die) | |
127 | { | |
128 | if (!die) | |
129 | return NULL; | |
130 | ||
131 | struct dwarf_file_data * file; | |
132 | file = get_AT_file (die, DW_AT_decl_file); | |
133 | if (!file) | |
134 | return NULL; | |
135 | ||
136 | return file->filename; | |
137 | } | |
138 | ||
139 | unsigned int | |
140 | ctf_get_die_loc_line (dw_die_ref die) | |
141 | { | |
142 | if (!die) | |
143 | return 0; | |
144 | ||
145 | return get_AT_unsigned (die, DW_AT_decl_line); | |
146 | } | |
147 | ||
148 | unsigned int | |
149 | ctf_get_die_loc_col (dw_die_ref die) | |
150 | { | |
151 | if (!die) | |
152 | return 0; | |
153 | ||
154 | return get_AT_unsigned (die, DW_AT_decl_column); | |
155 | } | |
156 | ||
157 | /* Generate CTF for the void type. */ | |
158 | ||
159 | static ctf_id_t | |
160 | gen_ctf_void_type (ctf_container_ref ctfc) | |
161 | { | |
162 | ctf_encoding_t ctf_encoding = {0, 0, 0}; | |
163 | ||
164 | /* In CTF the void type is encoded as a 0-byte signed integer | |
165 | type. */ | |
166 | ||
167 | ctf_encoding.cte_bits = 0; | |
168 | ctf_encoding.cte_format = CTF_INT_SIGNED; | |
169 | ||
170 | gcc_assert (ctf_void_die != NULL); | |
171 | return ctf_add_integer (ctfc, CTF_ADD_ROOT, "void", | |
172 | &ctf_encoding, ctf_void_die); | |
173 | } | |
174 | ||
175 | /* Generate CTF type of unknown kind. */ | |
176 | ||
177 | static ctf_id_t | |
178 | gen_ctf_unknown_type (ctf_container_ref ctfc) | |
179 | { | |
180 | ctf_id_t unknown_type_id; | |
181 | ||
182 | /* In CTF, the unknown type is encoded as a 0 byte sized type with kind | |
183 | CTF_K_UNKNOWN. Create an encoding object merely to reuse the underlying | |
184 | ctf_add_encoded interface; the CTF encoding object is not 'used' any more | |
185 | than just the generation of size from. */ | |
186 | ctf_encoding_t ctf_encoding = {0, 0, 0}; | |
187 | ||
188 | gcc_assert (ctf_unknown_die != NULL); | |
189 | /* Type de-duplication. */ | |
190 | if (!ctf_type_exists (ctfc, ctf_unknown_die, &unknown_type_id)) | |
191 | unknown_type_id = ctf_add_unknown (ctfc, CTF_ADD_ROOT, "unknown", | |
192 | &ctf_encoding, ctf_unknown_die); | |
193 | ||
194 | return unknown_type_id; | |
195 | } | |
196 | ||
197 | /* Sizes of entities can be given in bytes or bits. This function | |
198 | abstracts this by returning the size in bits of the given entity. | |
199 | If no DW_AT_byte_size nor DW_AT_bit_size are defined, this function | |
200 | returns 0. */ | |
201 | ||
202 | static uint32_t | |
203 | ctf_die_bitsize (dw_die_ref die) | |
204 | { | |
205 | dw_attr_node *attr_byte_size = get_AT (die, DW_AT_byte_size); | |
206 | dw_attr_node *attr_bit_size = get_AT (die, DW_AT_bit_size); | |
207 | ||
208 | if (attr_bit_size) | |
209 | return AT_unsigned (attr_bit_size); | |
210 | else if (attr_byte_size) | |
211 | return (AT_unsigned (attr_byte_size) * 8); | |
212 | else | |
213 | return 0; | |
214 | } | |
215 | ||
216 | /* Generate CTF for base type (integer, boolean, real, fixed point and complex). | |
217 | Important: the caller of this API must make sure that duplicate types are | |
218 | not added. */ | |
219 | ||
220 | static ctf_id_t | |
221 | gen_ctf_base_type (ctf_container_ref ctfc, dw_die_ref type) | |
222 | { | |
223 | ctf_id_t type_id = CTF_NULL_TYPEID; | |
224 | ||
225 | ctf_encoding_t ctf_encoding = {0, 0, 0}; | |
226 | ||
227 | unsigned int encoding = get_AT_unsigned (type, DW_AT_encoding); | |
228 | unsigned int bit_size = ctf_die_bitsize (type); | |
229 | const char * name_string = get_AT_string (type, DW_AT_name); | |
230 | ||
231 | switch (encoding) | |
232 | { | |
233 | case DW_ATE_void: | |
234 | ||
235 | ctf_encoding.cte_format = CTF_INT_SIGNED; | |
236 | ctf_encoding.cte_bits = 0; | |
237 | ||
238 | gcc_assert (name_string); | |
239 | type_id = ctf_add_integer (ctfc, CTF_ADD_ROOT, name_string, | |
240 | &ctf_encoding, type); | |
241 | ||
242 | break; | |
243 | case DW_ATE_boolean: | |
244 | ||
245 | ctf_encoding.cte_format = CTF_INT_BOOL; | |
246 | ctf_encoding.cte_bits = bit_size; | |
247 | ||
248 | gcc_assert (name_string); | |
249 | type_id = ctf_add_integer (ctfc, CTF_ADD_ROOT, name_string, | |
250 | &ctf_encoding, type); | |
251 | break; | |
252 | case DW_ATE_float: | |
253 | { | |
254 | unsigned int float_bit_size | |
255 | = tree_to_uhwi (TYPE_SIZE (float_type_node)); | |
256 | unsigned int double_bit_size | |
257 | = tree_to_uhwi (TYPE_SIZE (double_type_node)); | |
258 | unsigned int long_double_bit_size | |
259 | = tree_to_uhwi (TYPE_SIZE (long_double_type_node)); | |
260 | ||
261 | if (bit_size == float_bit_size) | |
262 | ctf_encoding.cte_format = CTF_FP_SINGLE; | |
263 | else if (bit_size == double_bit_size) | |
264 | ctf_encoding.cte_format = CTF_FP_DOUBLE; | |
265 | else if (bit_size == long_double_bit_size) | |
266 | ctf_encoding.cte_format = CTF_FP_LDOUBLE; | |
267 | else | |
268 | /* CTF does not have representation for other types. Skip them. */ | |
269 | break; | |
270 | ||
271 | ctf_encoding.cte_bits = bit_size; | |
272 | type_id = ctf_add_float (ctfc, CTF_ADD_ROOT, name_string, | |
273 | &ctf_encoding, type); | |
274 | ||
275 | break; | |
276 | } | |
277 | case DW_ATE_signed_char: | |
278 | /* FALLTHROUGH */ | |
279 | case DW_ATE_unsigned_char: | |
280 | /* FALLTHROUGH */ | |
281 | case DW_ATE_signed: | |
282 | /* FALLTHROUGH */ | |
283 | case DW_ATE_unsigned: | |
284 | ||
285 | if (encoding == DW_ATE_signed_char | |
286 | || encoding == DW_ATE_unsigned_char) | |
287 | ctf_encoding.cte_format |= CTF_INT_CHAR; | |
288 | ||
289 | if (encoding == DW_ATE_signed | |
290 | || encoding == DW_ATE_signed_char) | |
291 | ctf_encoding.cte_format |= CTF_INT_SIGNED; | |
292 | ||
293 | ctf_encoding.cte_bits = bit_size; | |
294 | type_id = ctf_add_integer (ctfc, CTF_ADD_ROOT, name_string, | |
295 | &ctf_encoding, type); | |
296 | break; | |
297 | ||
298 | case DW_ATE_complex_float: | |
299 | { | |
300 | unsigned int float_bit_size | |
301 | = tree_to_uhwi (TYPE_SIZE (float_type_node)); | |
302 | unsigned int double_bit_size | |
303 | = tree_to_uhwi (TYPE_SIZE (double_type_node)); | |
304 | unsigned int long_double_bit_size | |
305 | = tree_to_uhwi (TYPE_SIZE (long_double_type_node)); | |
306 | ||
307 | if (bit_size == float_bit_size * 2) | |
308 | ctf_encoding.cte_format = CTF_FP_CPLX; | |
309 | else if (bit_size == double_bit_size * 2) | |
310 | ctf_encoding.cte_format = CTF_FP_DCPLX; | |
311 | else if (bit_size == long_double_bit_size * 2) | |
312 | ctf_encoding.cte_format = CTF_FP_LDCPLX; | |
313 | else | |
314 | /* CTF does not have representation for other types. Skip them. */ | |
315 | break; | |
316 | ||
317 | ctf_encoding.cte_bits = bit_size; | |
318 | type_id = ctf_add_float (ctfc, CTF_ADD_ROOT, name_string, | |
319 | &ctf_encoding, type); | |
320 | break; | |
321 | } | |
322 | default: | |
323 | /* Ignore. */ | |
324 | break; | |
325 | } | |
326 | ||
327 | return type_id; | |
328 | } | |
329 | ||
330 | /* Generate CTF for a pointer type. */ | |
331 | ||
332 | static ctf_id_t | |
333 | gen_ctf_pointer_type (ctf_container_ref ctfc, dw_die_ref ptr_type) | |
334 | { | |
335 | ctf_id_t type_id = CTF_NULL_TYPEID; | |
336 | ctf_id_t ptr_type_id = CTF_NULL_TYPEID; | |
337 | dw_die_ref pointed_type_die = ctf_get_AT_type (ptr_type); | |
338 | ||
339 | type_id = gen_ctf_type (ctfc, pointed_type_die); | |
340 | ||
341 | /* Type de-duplication. | |
342 | Consult the ctfc_types hash again before adding the CTF pointer type | |
343 | because there can be cases where a pointer type may have been added by | |
344 | the gen_ctf_type call above. */ | |
345 | if (ctf_type_exists (ctfc, ptr_type, &ptr_type_id)) | |
346 | return ptr_type_id; | |
347 | ||
348 | ptr_type_id = ctf_add_pointer (ctfc, CTF_ADD_ROOT, type_id, ptr_type); | |
349 | return ptr_type_id; | |
350 | } | |
351 | ||
352 | /* Generate CTF for an array type. */ | |
353 | ||
354 | static ctf_id_t | |
355 | gen_ctf_array_type (ctf_container_ref ctfc, dw_die_ref array_type) | |
356 | { | |
357 | dw_die_ref c; | |
358 | ctf_id_t array_elems_type_id = CTF_NULL_TYPEID; | |
359 | ||
360 | int vector_type_p = get_AT_flag (array_type, DW_AT_GNU_vector); | |
361 | if (vector_type_p) | |
362 | return array_elems_type_id; | |
363 | ||
364 | dw_die_ref array_elems_type = ctf_get_AT_type (array_type); | |
365 | ||
366 | /* First, register the type of the array elements if needed. */ | |
367 | array_elems_type_id = gen_ctf_type (ctfc, array_elems_type); | |
368 | ||
369 | /* DWARF array types pretend C supports multi-dimensional arrays. | |
370 | So for the type int[N][M], the array type DIE contains two | |
371 | subrange_type children, the first iwth upper bound N-1 and the | |
372 | second with upper bound M-1. | |
373 | ||
374 | CTF, on the other hand, just encodes each array type in its own | |
375 | array type CTF struct. Therefore we have to iterate on the | |
376 | children and create all the needed types. */ | |
377 | ||
378 | c = dw_get_die_child (array_type); | |
379 | gcc_assert (c); | |
380 | do | |
381 | { | |
382 | ctf_arinfo_t arinfo; | |
383 | dw_die_ref array_index_type; | |
384 | uint32_t array_num_elements; | |
385 | ||
386 | c = dw_get_die_sib (c); | |
387 | ||
388 | if (dw_get_die_tag (c) == DW_TAG_subrange_type) | |
389 | { | |
390 | dw_attr_node *upper_bound_at; | |
391 | ||
392 | array_index_type = ctf_get_AT_type (c); | |
393 | ||
394 | /* When DW_AT_upper_bound is used to specify the size of an | |
395 | array in DWARF, it is usually an unsigned constant | |
396 | specifying the upper bound index of the array. However, | |
397 | for unsized arrays, such as foo[] or bar[0], | |
398 | DW_AT_upper_bound is a signed integer constant | |
399 | instead. */ | |
400 | ||
401 | upper_bound_at = get_AT (c, DW_AT_upper_bound); | |
402 | if (upper_bound_at | |
403 | && AT_class (upper_bound_at) == dw_val_class_unsigned_const) | |
404 | /* This is the upper bound index. */ | |
405 | array_num_elements = get_AT_unsigned (c, DW_AT_upper_bound) + 1; | |
406 | else if (get_AT (c, DW_AT_count)) | |
407 | array_num_elements = get_AT_unsigned (c, DW_AT_count); | |
408 | else | |
409 | { | |
410 | /* This is a VLA of some kind. */ | |
411 | array_num_elements = 0; | |
412 | } | |
413 | } | |
414 | else if (dw_get_die_tag (c) == DW_TAG_enumeration_type) | |
415 | { | |
416 | array_index_type = 0; | |
417 | array_num_elements = 0; | |
418 | /* XXX writeme. */ | |
419 | gcc_assert (1); | |
420 | } | |
421 | else | |
422 | gcc_unreachable (); | |
423 | ||
424 | /* Ok, mount and register the array type. Note how the array | |
425 | type we register here is the type of the elements in | |
426 | subsequent "dimensions", if there are any. */ | |
427 | ||
428 | arinfo.ctr_nelems = array_num_elements; | |
429 | if (array_index_type) | |
430 | arinfo.ctr_index = gen_ctf_type (ctfc, array_index_type); | |
431 | else | |
432 | arinfo.ctr_index = gen_ctf_type (ctfc, ctf_array_index_die); | |
433 | ||
434 | arinfo.ctr_contents = array_elems_type_id; | |
435 | if (!ctf_type_exists (ctfc, c, &array_elems_type_id)) | |
436 | array_elems_type_id = ctf_add_array (ctfc, CTF_ADD_ROOT, &arinfo, | |
437 | c); | |
438 | } | |
439 | while (c != dw_get_die_child (array_type)); | |
440 | ||
441 | #if 0 | |
442 | /* Type de-duplication. | |
443 | Consult the ctfc_types hash again before adding the CTF array type because | |
444 | there can be cases where an array_type type may have been added by the | |
445 | gen_ctf_type call above. */ | |
446 | if (!ctf_type_exists (ctfc, array_type, &type_id)) | |
447 | type_id = ctf_add_array (ctfc, CTF_ADD_ROOT, &arinfo, array_type); | |
448 | #endif | |
449 | ||
450 | return array_elems_type_id; | |
451 | } | |
452 | ||
453 | /* Generate CTF for a typedef. */ | |
454 | ||
455 | static ctf_id_t | |
456 | gen_ctf_typedef (ctf_container_ref ctfc, dw_die_ref tdef) | |
457 | { | |
458 | ctf_id_t tdef_type_id, tid; | |
459 | const char *tdef_name = get_AT_string (tdef, DW_AT_name); | |
460 | dw_die_ref tdef_type = ctf_get_AT_type (tdef); | |
461 | ||
462 | tid = gen_ctf_type (ctfc, tdef_type); | |
463 | ||
464 | /* Type de-duplication. | |
465 | This is necessary because the ctf for the typedef may have been already | |
466 | added due to the gen_ctf_type call above. */ | |
467 | if (!ctf_type_exists (ctfc, tdef, &tdef_type_id)) | |
468 | { | |
469 | tdef_type_id = ctf_add_typedef (ctfc, CTF_ADD_ROOT, | |
470 | tdef_name, | |
471 | tid, | |
472 | tdef); | |
473 | } | |
474 | return tdef_type_id; | |
475 | } | |
476 | ||
477 | /* Generate CTF for a type modifier. | |
478 | ||
479 | If the given DIE contains a valid C modifier (like _Atomic), which is not | |
480 | supported by CTF, then this function skips the modifier die and continues | |
481 | with the underlying type. | |
482 | ||
483 | For all other cases, this function returns a CTF_NULL_TYPEID; | |
484 | */ | |
485 | ||
486 | static ctf_id_t | |
487 | gen_ctf_modifier_type (ctf_container_ref ctfc, dw_die_ref modifier) | |
488 | { | |
489 | uint32_t kind = CTF_K_MAX; | |
490 | ctf_id_t modifier_type_id, qual_type_id; | |
491 | dw_die_ref qual_type = ctf_get_AT_type (modifier); | |
492 | ||
493 | switch (dw_get_die_tag (modifier)) | |
494 | { | |
495 | case DW_TAG_const_type: kind = CTF_K_CONST; break; | |
496 | case DW_TAG_volatile_type: kind = CTF_K_VOLATILE; break; | |
497 | case DW_TAG_restrict_type: kind = CTF_K_RESTRICT; break; | |
498 | case DW_TAG_atomic_type: break; | |
499 | default: | |
500 | return CTF_NULL_TYPEID; | |
501 | } | |
502 | ||
503 | /* Register the type for which this modifier applies. */ | |
504 | qual_type_id = gen_ctf_type (ctfc, qual_type); | |
505 | ||
506 | /* Skip generating a CTF modifier record for _Atomic as there is no | |
507 | representation for it. */ | |
508 | if (dw_get_die_tag (modifier) == DW_TAG_atomic_type) | |
509 | return qual_type_id; | |
510 | ||
511 | gcc_assert (kind != CTF_K_MAX); | |
512 | /* Now register the modifier itself. */ | |
513 | if (!ctf_type_exists (ctfc, modifier, &modifier_type_id)) | |
514 | modifier_type_id = ctf_add_reftype (ctfc, CTF_ADD_ROOT, | |
515 | qual_type_id, kind, | |
516 | modifier); | |
517 | ||
518 | return modifier_type_id; | |
519 | } | |
520 | ||
521 | /* Generate CTF for a struct type. */ | |
522 | ||
523 | static ctf_id_t | |
524 | gen_ctf_sou_type (ctf_container_ref ctfc, dw_die_ref sou, uint32_t kind) | |
525 | { | |
526 | uint32_t bit_size = ctf_die_bitsize (sou); | |
527 | int declaration_p = get_AT_flag (sou, DW_AT_declaration); | |
528 | const char *sou_name = get_AT_string (sou, DW_AT_name); | |
529 | ||
530 | ctf_id_t sou_type_id; | |
531 | ||
532 | /* An incomplete structure or union type is represented in DWARF by | |
533 | a structure or union DIE that does not have a size attribute and | |
534 | that has a DW_AT_declaration attribute. This corresponds to a | |
535 | CTF forward type with kind CTF_K_STRUCT. */ | |
536 | if (bit_size == 0 && declaration_p) | |
537 | return ctf_add_forward (ctfc, CTF_ADD_ROOT, | |
538 | sou_name, kind, sou); | |
539 | ||
540 | /* This is a complete struct or union type. Generate a CTF type for | |
541 | it if it doesn't exist already. */ | |
542 | if (!ctf_type_exists (ctfc, sou, &sou_type_id)) | |
543 | sou_type_id = ctf_add_sou (ctfc, CTF_ADD_ROOT, | |
544 | sou_name, kind, bit_size / 8, | |
545 | sou); | |
546 | ||
547 | /* Now process the struct members. */ | |
548 | { | |
549 | dw_die_ref c; | |
550 | ||
551 | c = dw_get_die_child (sou); | |
552 | if (c) | |
553 | do | |
554 | { | |
555 | const char *field_name; | |
556 | dw_die_ref field_type; | |
557 | HOST_WIDE_INT field_location; | |
558 | ctf_id_t field_type_id; | |
559 | ||
560 | c = dw_get_die_sib (c); | |
561 | ||
562 | field_name = get_AT_string (c, DW_AT_name); | |
563 | field_type = ctf_get_AT_type (c); | |
564 | field_location = ctf_get_AT_data_member_location (c); | |
565 | ||
566 | /* Generate the field type. */ | |
567 | field_type_id = gen_ctf_type (ctfc, field_type); | |
568 | ||
569 | /* If this is a bit-field, then wrap the field type | |
570 | generated above with a CTF slice. */ | |
571 | if (get_AT (c, DW_AT_bit_offset) | |
572 | || get_AT (c, DW_AT_data_bit_offset)) | |
573 | { | |
574 | dw_attr_node *attr; | |
575 | HOST_WIDE_INT bitpos = 0; | |
576 | HOST_WIDE_INT bitsize = ctf_die_bitsize (c); | |
577 | HOST_WIDE_INT bit_offset; | |
578 | ||
579 | /* The bit offset is given in bits and it may be | |
580 | negative. */ | |
581 | attr = get_AT (c, DW_AT_bit_offset); | |
582 | if (attr) | |
583 | { | |
584 | if (AT_class (attr) == dw_val_class_unsigned_const) | |
585 | bit_offset = AT_unsigned (attr); | |
586 | else | |
587 | bit_offset = AT_int (attr); | |
588 | ||
589 | if (BYTES_BIG_ENDIAN) | |
590 | bitpos = field_location + bit_offset; | |
591 | else | |
592 | { | |
593 | HOST_WIDE_INT bit_size; | |
594 | ||
595 | attr = get_AT (c, DW_AT_byte_size); | |
596 | if (attr) | |
597 | /* Explicit size given in bytes. */ | |
598 | bit_size = AT_unsigned (attr) * 8; | |
599 | else | |
600 | /* Infer the size from the member type. */ | |
601 | bit_size = ctf_die_bitsize (field_type); | |
602 | ||
603 | bitpos = (field_location | |
604 | + bit_size | |
605 | - bit_offset | |
606 | - bitsize); | |
607 | } | |
608 | } | |
609 | ||
610 | /* In DWARF5 a data_bit_offset attribute is given with | |
611 | the offset of the data from the beginning of the | |
612 | struct. Acknowledge it if present. */ | |
613 | attr = get_AT (c, DW_AT_data_bit_offset); | |
614 | if (attr) | |
615 | bitpos += AT_unsigned (attr); | |
616 | ||
617 | field_type_id = ctf_add_slice (ctfc, CTF_ADD_NONROOT, | |
618 | field_type_id, | |
619 | bitpos - field_location, | |
620 | bitsize, | |
621 | c); | |
622 | } | |
623 | ||
624 | /* Add the field type to the struct or union type. */ | |
625 | ctf_add_member_offset (ctfc, sou, | |
626 | field_name, | |
627 | field_type_id, | |
628 | field_location); | |
629 | } | |
630 | while (c != dw_get_die_child (sou)); | |
631 | } | |
632 | ||
633 | return sou_type_id; | |
634 | } | |
635 | ||
636 | /* Generate CTF for a function type. */ | |
637 | ||
638 | static ctf_id_t | |
639 | gen_ctf_function_type (ctf_container_ref ctfc, dw_die_ref function, | |
640 | bool from_global_func) | |
641 | { | |
642 | const char *function_name = get_AT_string (function, DW_AT_name); | |
643 | dw_die_ref return_type = ctf_get_AT_type (function); | |
644 | ||
645 | ctf_funcinfo_t func_info; | |
646 | uint32_t num_args = 0; | |
647 | ||
648 | ctf_id_t return_type_id; | |
649 | ctf_id_t function_type_id; | |
650 | ||
651 | /* First, add the return type. */ | |
652 | return_type_id = gen_ctf_type (ctfc, return_type); | |
653 | func_info.ctc_return = return_type_id; | |
654 | ||
655 | /* Type de-duplication. | |
656 | Consult the ctfc_types hash before adding the CTF function type. */ | |
657 | if (ctf_type_exists (ctfc, function, &function_type_id)) | |
658 | return function_type_id; | |
659 | ||
660 | /* Do a first pass on the formals to determine the number of | |
661 | arguments, and whether the function type gets a varargs. */ | |
662 | { | |
663 | dw_die_ref c; | |
664 | ||
665 | c = dw_get_die_child (function); | |
666 | if (c) | |
667 | do | |
668 | { | |
669 | c = dw_get_die_sib (c); | |
670 | ||
671 | if (dw_get_die_tag (c) == DW_TAG_formal_parameter) | |
672 | num_args += 1; | |
673 | else if (dw_get_die_tag (c) == DW_TAG_unspecified_parameters) | |
674 | { | |
675 | func_info.ctc_flags |= CTF_FUNC_VARARG; | |
676 | num_args += 1; | |
677 | } | |
678 | } | |
679 | while (c != dw_get_die_child (function)); | |
680 | } | |
681 | ||
682 | /* Note the number of typed arguments _includes_ the vararg. */ | |
683 | func_info.ctc_argc = num_args; | |
684 | ||
685 | /* Type de-duplication has already been performed by now. */ | |
686 | function_type_id = ctf_add_function (ctfc, CTF_ADD_ROOT, | |
687 | function_name, | |
688 | (const ctf_funcinfo_t *)&func_info, | |
689 | function, | |
690 | from_global_func); | |
691 | ||
692 | /* Second pass on formals: generate the CTF types corresponding to | |
693 | them and add them as CTF function args. */ | |
694 | { | |
695 | dw_die_ref c; | |
696 | unsigned int i = 0; | |
697 | const char *arg_name; | |
698 | ctf_id_t arg_type; | |
699 | ||
700 | c = dw_get_die_child (function); | |
701 | if (c) | |
702 | do | |
703 | { | |
704 | c = dw_get_die_sib (c); | |
705 | ||
706 | if (dw_get_die_tag (c) == DW_TAG_unspecified_parameters) | |
707 | { | |
708 | gcc_assert (i == num_args - 1); | |
709 | /* Add an argument with type 0 and no name. */ | |
710 | ctf_add_function_arg (ctfc, function, "", 0); | |
711 | } | |
712 | else if (dw_get_die_tag (c) == DW_TAG_formal_parameter) | |
713 | { | |
714 | i++; | |
715 | arg_name = get_AT_string (c, DW_AT_name); | |
716 | arg_type = gen_ctf_type (ctfc, ctf_get_AT_type (c)); | |
717 | /* Add the argument to the existing CTF function type. */ | |
718 | ctf_add_function_arg (ctfc, function, arg_name, arg_type); | |
719 | } | |
720 | else | |
721 | /* This is a local variable. Ignore. */ | |
722 | continue; | |
723 | } | |
724 | while (c != dw_get_die_child (function)); | |
725 | } | |
726 | ||
727 | return function_type_id; | |
728 | } | |
729 | ||
730 | /* Generate CTF for an enumeration type. */ | |
731 | ||
732 | static ctf_id_t | |
733 | gen_ctf_enumeration_type (ctf_container_ref ctfc, dw_die_ref enumeration) | |
734 | { | |
735 | const char *enum_name = get_AT_string (enumeration, DW_AT_name); | |
736 | unsigned int bit_size = ctf_die_bitsize (enumeration); | |
737 | int declaration_p = get_AT_flag (enumeration, DW_AT_declaration); | |
738 | ||
739 | ctf_id_t enumeration_type_id; | |
740 | ||
741 | /* If this is an incomplete enum, generate a CTF forward for it and | |
742 | be done. */ | |
743 | if (declaration_p) | |
744 | { | |
745 | gcc_assert (enum_name); | |
746 | return ctf_add_forward (ctfc, CTF_ADD_ROOT, enum_name, | |
747 | CTF_K_ENUM, enumeration); | |
748 | } | |
749 | ||
750 | /* If the size the enumerators is not specified then use the size of | |
751 | the underlying type, which must be a base type. */ | |
752 | if (bit_size == 0) | |
753 | { | |
754 | dw_die_ref type = ctf_get_AT_type (enumeration); | |
755 | bit_size = ctf_die_bitsize (type); | |
756 | } | |
757 | ||
758 | /* Generate a CTF type for the enumeration. */ | |
759 | enumeration_type_id = ctf_add_enum (ctfc, CTF_ADD_ROOT, | |
760 | enum_name, bit_size / 8, enumeration); | |
761 | ||
762 | /* Process the enumerators. */ | |
763 | { | |
764 | dw_die_ref c; | |
765 | ||
766 | c = dw_get_die_child (enumeration); | |
767 | if (c) | |
768 | do | |
769 | { | |
770 | const char *enumerator_name; | |
771 | dw_attr_node *enumerator_value; | |
772 | HOST_WIDE_INT value_wide_int; | |
773 | ||
774 | c = dw_get_die_sib (c); | |
775 | ||
776 | enumerator_name = get_AT_string (c, DW_AT_name); | |
777 | enumerator_value = get_AT (c, DW_AT_const_value); | |
778 | ||
779 | /* enumerator_value can be either a signed or an unsigned | |
780 | constant value. */ | |
781 | if (AT_class (enumerator_value) == dw_val_class_unsigned_const | |
782 | || (AT_class (enumerator_value) | |
783 | == dw_val_class_unsigned_const_implicit)) | |
784 | value_wide_int = AT_unsigned (enumerator_value); | |
785 | else | |
786 | value_wide_int = AT_int (enumerator_value); | |
787 | ||
788 | ctf_add_enumerator (ctfc, enumeration_type_id, | |
789 | enumerator_name, value_wide_int, enumeration); | |
790 | } | |
791 | while (c != dw_get_die_child (enumeration)); | |
792 | } | |
793 | ||
794 | return enumeration_type_id; | |
795 | } | |
796 | ||
797 | /* Add a CTF variable record for the given input DWARF DIE. */ | |
798 | ||
799 | static void | |
800 | gen_ctf_variable (ctf_container_ref ctfc, dw_die_ref die) | |
801 | { | |
802 | const char *var_name = get_AT_string (die, DW_AT_name); | |
803 | dw_die_ref var_type = ctf_get_AT_type (die); | |
804 | unsigned int external_vis = get_AT_flag (die, DW_AT_external); | |
805 | ctf_id_t var_type_id; | |
806 | ||
807 | /* Avoid duplicates. */ | |
808 | if (ctf_dvd_lookup (ctfc, die)) | |
809 | return; | |
810 | ||
811 | /* Add the type of the variable. */ | |
812 | var_type_id = gen_ctf_type (ctfc, var_type); | |
813 | ||
814 | /* Generate the new CTF variable and update global counter. */ | |
815 | (void) ctf_add_variable (ctfc, var_name, var_type_id, die, external_vis); | |
816 | ctfc->ctfc_num_global_objts += 1; | |
817 | } | |
818 | ||
819 | /* Add a CTF function record for the given input DWARF DIE. */ | |
820 | ||
821 | static void | |
822 | gen_ctf_function (ctf_container_ref ctfc, dw_die_ref die) | |
823 | { | |
824 | ctf_id_t function_type_id; | |
825 | /* Type de-duplication. | |
826 | Consult the ctfc_types hash before adding the CTF function type. */ | |
827 | if (ctf_type_exists (ctfc, die, &function_type_id)) | |
828 | return; | |
829 | ||
830 | /* Add the type of the function and update the global functions | |
831 | counter. Note that DWARF encodes function types in both | |
832 | DW_TAG_subroutine_type and DW_TAG_subprogram in exactly the same | |
833 | way. */ | |
834 | (void) gen_ctf_function_type (ctfc, die, true /* from_global_func */); | |
835 | ctfc->ctfc_num_global_funcs += 1; | |
836 | } | |
837 | ||
838 | /* Add CTF type record(s) for the given input DWARF DIE and return its type id. | |
839 | ||
840 | If there is already a CTF type corresponding to the given DIE, then | |
841 | this function returns the type id of the existing type. | |
842 | ||
843 | If the given DIE is not recognized as a type, then this function | |
844 | returns CTF_NULL_TYPEID. */ | |
845 | ||
846 | static ctf_id_t | |
847 | gen_ctf_type (ctf_container_ref ctfc, dw_die_ref die) | |
848 | { | |
849 | ctf_id_t type_id; | |
850 | int unrecog_die = false; | |
851 | ||
852 | if (ctf_type_exists (ctfc, die, &type_id)) | |
853 | return type_id; | |
854 | ||
855 | switch (dw_get_die_tag (die)) | |
856 | { | |
857 | case DW_TAG_base_type: | |
858 | type_id = gen_ctf_base_type (ctfc, die); | |
859 | break; | |
860 | case DW_TAG_pointer_type: | |
861 | type_id = gen_ctf_pointer_type (ctfc, die); | |
862 | break; | |
863 | case DW_TAG_typedef: | |
864 | type_id = gen_ctf_typedef (ctfc, die); | |
865 | break; | |
866 | case DW_TAG_array_type: | |
867 | type_id = gen_ctf_array_type (ctfc, die); | |
868 | break; | |
869 | case DW_TAG_structure_type: | |
870 | type_id = gen_ctf_sou_type (ctfc, die, CTF_K_STRUCT); | |
871 | break; | |
872 | case DW_TAG_union_type: | |
873 | type_id = gen_ctf_sou_type (ctfc, die, CTF_K_UNION); | |
874 | break; | |
875 | case DW_TAG_subroutine_type: | |
876 | type_id = gen_ctf_function_type (ctfc, die, | |
877 | false /* from_global_func */); | |
878 | break; | |
879 | case DW_TAG_enumeration_type: | |
880 | type_id = gen_ctf_enumeration_type (ctfc, die); | |
881 | break; | |
882 | case DW_TAG_atomic_type: | |
883 | /* FALLTHROUGH */ | |
884 | case DW_TAG_const_type: | |
885 | /* FALLTHROUGH */ | |
886 | case DW_TAG_restrict_type: | |
887 | /* FALLTHROUGH */ | |
888 | case DW_TAG_volatile_type: | |
889 | type_id = gen_ctf_modifier_type (ctfc, die); | |
890 | break; | |
891 | case DW_TAG_unspecified_type: | |
892 | { | |
893 | const char *name = get_AT_string (die, DW_AT_name); | |
894 | ||
895 | if (name && strcmp (name, "void") == 0) | |
896 | type_id = gen_ctf_void_type (ctfc); | |
897 | else | |
898 | type_id = CTF_NULL_TYPEID; | |
899 | ||
900 | break; | |
901 | } | |
902 | case DW_TAG_reference_type: | |
903 | type_id = CTF_NULL_TYPEID; | |
904 | break; | |
905 | default: | |
906 | /* Unrecognized DIE. */ | |
907 | unrecog_die = true; | |
908 | type_id = CTF_NULL_TYPEID; | |
909 | break; | |
910 | } | |
911 | ||
912 | /* For all types unrepresented in CTF, use an explicit CTF type of kind | |
913 | CTF_K_UNKNOWN. */ | |
914 | if ((type_id == CTF_NULL_TYPEID) && (!unrecog_die)) | |
915 | type_id = gen_ctf_unknown_type (ctfc); | |
916 | ||
917 | return type_id; | |
918 | } | |
919 | ||
849d5f59 IB |
920 | /* Prepare for output and write out the CTF debug information. */ |
921 | ||
922 | static void | |
923 | ctf_debug_finalize (const char *filename, bool btf) | |
924 | { | |
925 | if (btf) | |
926 | { | |
927 | btf_output (filename); | |
928 | btf_finalize (); | |
929 | } | |
930 | ||
931 | else | |
932 | { | |
933 | /* Emit the collected CTF information. */ | |
934 | ctf_output (filename); | |
935 | ||
936 | /* Reset the CTF state. */ | |
937 | ctf_finalize (); | |
938 | } | |
939 | } | |
940 | ||
b7e215a8 IB |
941 | bool |
942 | ctf_do_die (dw_die_ref die) | |
943 | { | |
944 | ctf_container_ref tu_ctfc = ctf_get_tu_ctfc (); | |
945 | ||
946 | /* Note how we tell the caller to continue traversing children DIEs | |
947 | if this DIE didn't result in CTF records being added. */ | |
948 | if (dw_get_die_tag (die) == DW_TAG_variable) | |
949 | { | |
950 | gen_ctf_variable (tu_ctfc, die); | |
951 | return false; | |
952 | } | |
953 | else if (dw_get_die_tag (die) == DW_TAG_subprogram) | |
954 | { | |
955 | gen_ctf_function (tu_ctfc, die); | |
956 | return false; | |
957 | } | |
958 | else | |
959 | return gen_ctf_type (tu_ctfc, die) == CTF_NULL_TYPEID; | |
960 | } | |
961 | ||
962 | /* Initialize CTF subsystem for CTF debug info generation. */ | |
963 | ||
964 | void | |
965 | ctf_debug_init (void) | |
966 | { | |
967 | /* First, initialize the CTF subsystem. */ | |
968 | ctf_init (); | |
969 | ||
970 | /* Create a couple of DIE structures that we may need. */ | |
971 | ctf_void_die = new_die_raw (DW_TAG_unspecified_type); | |
972 | add_name_attribute (ctf_void_die, "void"); | |
973 | ctf_array_index_die | |
974 | = base_type_die (integer_type_node, 0 /* reverse */); | |
975 | add_name_attribute (ctf_array_index_die, "int"); | |
976 | ctf_unknown_die = new_die_raw (DW_TAG_unspecified_type); | |
977 | add_name_attribute (ctf_unknown_die, "unknown"); | |
978 | } | |
979 | ||
980 | /* Preprocess the CTF debug information after initialization. */ | |
981 | ||
982 | void | |
983 | ctf_debug_init_postprocess (bool btf) | |
984 | { | |
985 | /* Only BTF requires postprocessing right after init. */ | |
986 | if (btf) | |
987 | btf_init_postprocess (); | |
988 | } | |
989 | ||
849d5f59 | 990 | /* Early finish CTF/BTF debug info. */ |
b7e215a8 IB |
991 | |
992 | void | |
849d5f59 | 993 | ctf_debug_early_finish (const char * filename) |
b7e215a8 | 994 | { |
849d5f59 IB |
995 | /* Emit CTF debug info early always. */ |
996 | if (ctf_debug_info_level > CTFINFO_LEVEL_NONE | |
997 | /* Emit BTF debug info early if CO-RE relocations are not | |
998 | required. */ | |
999 | || (btf_debuginfo_p () && !btf_with_core_debuginfo_p ())) | |
1000 | ctf_debug_finalize (filename, btf_debuginfo_p ()); | |
1001 | } | |
b7e215a8 | 1002 | |
849d5f59 | 1003 | /* Finish CTF/BTF debug info emission. */ |
b7e215a8 | 1004 | |
849d5f59 IB |
1005 | void |
1006 | ctf_debug_finish (const char * filename) | |
1007 | { | |
1008 | /* Emit BTF debug info here when CO-RE relocations need to be generated. | |
1009 | BTF with CO-RE relocations needs to be generated when CO-RE is in effect | |
1010 | for the BPF target. */ | |
1011 | if (btf_with_core_debuginfo_p ()) | |
1012 | { | |
1013 | gcc_assert (btf_debuginfo_p ()); | |
1014 | ctf_debug_finalize (filename, btf_debuginfo_p ()); | |
b7e215a8 IB |
1015 | } |
1016 | } | |
1017 | ||
1018 | #include "gt-dwarf2ctf.h" |