1 | /* Generate CTF types and objects from the GCC DWARF. |
2 | Copyright (C) 2021-2023 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 |
36 | generated by GCC. However, there are three situations where we need |
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); |
103 | field_location = descr->dw_loc_oprnd1.v.val_unsigned * 8; |
104 | } |
105 | else |
106 | { |
107 | attr = get_AT (die, DW_AT_data_member_location); |
108 | if (attr && AT_class (attr) == dw_val_class_const) |
109 | field_location = AT_int (attr) * 8; |
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 = {.cte_format: 0, .cte_offset: 0, .cte_bits: 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 = {.cte_format: 0, .cte_offset: 0, .cte_bits: 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 = {.cte_format: 0, .cte_offset: 0, .cte_bits: 0}; |
226 | |
227 | unsigned int encoding = get_AT_unsigned (type, DW_AT_encoding); |
228 | unsigned int bit_size = ctf_die_bitsize (die: 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 (die: 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 (die: 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 with 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 (die: 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 (die: 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 (die: 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 (die: 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 (die: c); |
564 | field_location = ctf_get_AT_data_member_location (die: 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 (die: 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 (die: 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 (die: function); |
644 | |
645 | ctf_funcinfo_t func_info; |
646 | uint32_t num_args = 0; |
647 | int linkage = get_AT_flag (function, DW_AT_external); |
648 | |
649 | ctf_id_t return_type_id; |
650 | ctf_id_t function_type_id; |
651 | |
652 | /* First, add the return type. */ |
653 | return_type_id = gen_ctf_type (ctfc, return_type); |
654 | func_info.ctc_return = return_type_id; |
655 | |
656 | /* Type de-duplication. |
657 | Consult the ctfc_types hash before adding the CTF function type. */ |
658 | if (ctf_type_exists (ctfc, function, &function_type_id)) |
659 | return function_type_id; |
660 | |
661 | /* Do a first pass on the formals to determine the number of |
662 | arguments, and whether the function type gets a varargs. */ |
663 | { |
664 | dw_die_ref c; |
665 | |
666 | c = dw_get_die_child (function); |
667 | if (c) |
668 | do |
669 | { |
670 | c = dw_get_die_sib (c); |
671 | |
672 | if (dw_get_die_tag (c) == DW_TAG_formal_parameter) |
673 | num_args += 1; |
674 | else if (dw_get_die_tag (c) == DW_TAG_unspecified_parameters) |
675 | { |
676 | func_info.ctc_flags |= CTF_FUNC_VARARG; |
677 | num_args += 1; |
678 | } |
679 | } |
680 | while (c != dw_get_die_child (function)); |
681 | } |
682 | |
683 | /* Note the number of typed arguments _includes_ the vararg. */ |
684 | func_info.ctc_argc = num_args; |
685 | |
686 | /* Type de-duplication has already been performed by now. */ |
687 | function_type_id = ctf_add_function (ctfc, CTF_ADD_ROOT, |
688 | function_name, |
689 | (const ctf_funcinfo_t *)&func_info, |
690 | function, |
691 | from_global_func, |
692 | linkage); |
693 | |
694 | /* Second pass on formals: generate the CTF types corresponding to |
695 | them and add them as CTF function args. */ |
696 | { |
697 | dw_die_ref c; |
698 | unsigned int i = 0; |
699 | const char *arg_name; |
700 | ctf_id_t arg_type; |
701 | |
702 | c = dw_get_die_child (function); |
703 | if (c) |
704 | do |
705 | { |
706 | c = dw_get_die_sib (c); |
707 | |
708 | if (dw_get_die_tag (c) == DW_TAG_unspecified_parameters) |
709 | { |
710 | gcc_assert (i == num_args - 1); |
711 | /* Add an argument with type 0 and no name. */ |
712 | ctf_add_function_arg (ctfc, function, "" , 0); |
713 | } |
714 | else if (dw_get_die_tag (c) == DW_TAG_formal_parameter) |
715 | { |
716 | i++; |
717 | arg_name = get_AT_string (c, DW_AT_name); |
718 | arg_type = gen_ctf_type (ctfc, ctf_get_AT_type (die: c)); |
719 | /* Add the argument to the existing CTF function type. */ |
720 | ctf_add_function_arg (ctfc, function, arg_name, arg_type); |
721 | } |
722 | else |
723 | /* This is a local variable. Ignore. */ |
724 | continue; |
725 | } |
726 | while (c != dw_get_die_child (function)); |
727 | } |
728 | |
729 | return function_type_id; |
730 | } |
731 | |
732 | /* Generate CTF for an enumeration type. */ |
733 | |
734 | static ctf_id_t |
735 | gen_ctf_enumeration_type (ctf_container_ref ctfc, dw_die_ref enumeration) |
736 | { |
737 | const char *enum_name = get_AT_string (enumeration, DW_AT_name); |
738 | unsigned int bit_size = ctf_die_bitsize (die: enumeration); |
739 | unsigned int signedness = get_AT_unsigned (enumeration, DW_AT_encoding); |
740 | int declaration_p = get_AT_flag (enumeration, DW_AT_declaration); |
741 | |
742 | ctf_id_t enumeration_type_id; |
743 | |
744 | /* If this is an incomplete enum, generate a CTF forward for it and |
745 | be done. */ |
746 | if (declaration_p) |
747 | { |
748 | gcc_assert (enum_name); |
749 | return ctf_add_forward (ctfc, CTF_ADD_ROOT, enum_name, |
750 | CTF_K_ENUM, enumeration); |
751 | } |
752 | |
753 | /* If the size the enumerators is not specified then use the size of |
754 | the underlying type, which must be a base type. */ |
755 | if (bit_size == 0) |
756 | { |
757 | dw_die_ref type = ctf_get_AT_type (die: enumeration); |
758 | bit_size = ctf_die_bitsize (die: type); |
759 | } |
760 | |
761 | /* Generate a CTF type for the enumeration. */ |
762 | enumeration_type_id = ctf_add_enum (ctfc, CTF_ADD_ROOT, |
763 | enum_name, bit_size / 8, |
764 | (signedness == DW_ATE_unsigned), |
765 | enumeration); |
766 | |
767 | /* Process the enumerators. */ |
768 | { |
769 | dw_die_ref c; |
770 | |
771 | c = dw_get_die_child (enumeration); |
772 | if (c) |
773 | do |
774 | { |
775 | const char *enumerator_name; |
776 | dw_attr_node *enumerator_value; |
777 | HOST_WIDE_INT value_wide_int; |
778 | |
779 | c = dw_get_die_sib (c); |
780 | |
781 | enumerator_name = get_AT_string (c, DW_AT_name); |
782 | enumerator_value = get_AT (c, DW_AT_const_value); |
783 | |
784 | /* enumerator_value can be either a signed or an unsigned |
785 | constant value. */ |
786 | if (AT_class (enumerator_value) == dw_val_class_unsigned_const |
787 | || (AT_class (enumerator_value) |
788 | == dw_val_class_unsigned_const_implicit)) |
789 | value_wide_int = AT_unsigned (enumerator_value); |
790 | else |
791 | value_wide_int = AT_int (enumerator_value); |
792 | |
793 | ctf_add_enumerator (ctfc, enumeration_type_id, |
794 | enumerator_name, value_wide_int, enumeration); |
795 | } |
796 | while (c != dw_get_die_child (enumeration)); |
797 | } |
798 | |
799 | return enumeration_type_id; |
800 | } |
801 | |
802 | /* Add a CTF variable record for the given input DWARF DIE. */ |
803 | |
804 | static void |
805 | gen_ctf_variable (ctf_container_ref ctfc, dw_die_ref die) |
806 | { |
807 | const char *var_name = get_AT_string (die, DW_AT_name); |
808 | dw_die_ref var_type = ctf_get_AT_type (die); |
809 | unsigned int external_vis = get_AT_flag (die, DW_AT_external); |
810 | ctf_id_t var_type_id; |
811 | |
812 | /* Avoid duplicates. */ |
813 | if (ctf_dvd_lookup (ctfc, die)) |
814 | return; |
815 | |
816 | /* Do not generate CTF variable records for non-defining incomplete |
817 | declarations. Such declarations can be known via the DWARF |
818 | DW_AT_specification attribute. */ |
819 | if (ctf_dvd_ignore_lookup (ctfc, die)) |
820 | return; |
821 | |
822 | /* The value of the DW_AT_specification attribute, if present, is a |
823 | reference to the debugging information entry representing the |
824 | non-defining declaration. */ |
825 | dw_die_ref decl = get_AT_ref (die, DW_AT_specification); |
826 | |
827 | /* Add the type of the variable. */ |
828 | var_type_id = gen_ctf_type (ctfc, var_type); |
829 | |
830 | /* Generate the new CTF variable and update global counter. */ |
831 | (void) ctf_add_variable (ctfc, var_name, var_type_id, die, external_vis, |
832 | decl); |
833 | /* Skip updating the number of global objects at this time. This is updated |
834 | later after pre-processing as some CTF variable records although |
835 | generated now, will not be emitted later. [PR105089]. */ |
836 | } |
837 | |
838 | /* Add a CTF function record for the given input DWARF DIE. */ |
839 | |
840 | static void |
841 | gen_ctf_function (ctf_container_ref ctfc, dw_die_ref die) |
842 | { |
843 | ctf_id_t function_type_id; |
844 | /* Type de-duplication. |
845 | Consult the ctfc_types hash before adding the CTF function type. */ |
846 | if (ctf_type_exists (ctfc, die, &function_type_id)) |
847 | return; |
848 | |
849 | /* Add the type of the function and update the global functions |
850 | counter. Note that DWARF encodes function types in both |
851 | DW_TAG_subroutine_type and DW_TAG_subprogram in exactly the same |
852 | way. */ |
853 | (void) gen_ctf_function_type (ctfc, function: die, from_global_func: true /* from_global_func */); |
854 | ctfc->ctfc_num_global_funcs += 1; |
855 | } |
856 | |
857 | /* Add CTF type record(s) for the given input DWARF DIE and return its type id. |
858 | |
859 | If there is already a CTF type corresponding to the given DIE, then |
860 | this function returns the type id of the existing type. |
861 | |
862 | If the given DIE is not recognized as a type, then this function |
863 | returns CTF_NULL_TYPEID. */ |
864 | |
865 | static ctf_id_t |
866 | gen_ctf_type (ctf_container_ref ctfc, dw_die_ref die) |
867 | { |
868 | ctf_id_t type_id; |
869 | int unrecog_die = false; |
870 | |
871 | if (ctf_type_exists (ctfc, die, &type_id)) |
872 | return type_id; |
873 | |
874 | switch (dw_get_die_tag (die)) |
875 | { |
876 | case DW_TAG_base_type: |
877 | type_id = gen_ctf_base_type (ctfc, type: die); |
878 | break; |
879 | case DW_TAG_pointer_type: |
880 | type_id = gen_ctf_pointer_type (ctfc, ptr_type: die); |
881 | break; |
882 | case DW_TAG_typedef: |
883 | type_id = gen_ctf_typedef (ctfc, tdef: die); |
884 | break; |
885 | case DW_TAG_array_type: |
886 | type_id = gen_ctf_array_type (ctfc, array_type: die); |
887 | break; |
888 | case DW_TAG_structure_type: |
889 | type_id = gen_ctf_sou_type (ctfc, sou: die, CTF_K_STRUCT); |
890 | break; |
891 | case DW_TAG_union_type: |
892 | type_id = gen_ctf_sou_type (ctfc, sou: die, CTF_K_UNION); |
893 | break; |
894 | case DW_TAG_subroutine_type: |
895 | type_id = gen_ctf_function_type (ctfc, function: die, |
896 | from_global_func: false /* from_global_func */); |
897 | break; |
898 | case DW_TAG_enumeration_type: |
899 | type_id = gen_ctf_enumeration_type (ctfc, enumeration: die); |
900 | break; |
901 | case DW_TAG_atomic_type: |
902 | /* FALLTHROUGH */ |
903 | case DW_TAG_const_type: |
904 | /* FALLTHROUGH */ |
905 | case DW_TAG_restrict_type: |
906 | /* FALLTHROUGH */ |
907 | case DW_TAG_volatile_type: |
908 | type_id = gen_ctf_modifier_type (ctfc, modifier: die); |
909 | break; |
910 | case DW_TAG_unspecified_type: |
911 | { |
912 | const char *name = get_AT_string (die, DW_AT_name); |
913 | |
914 | if (name && strcmp (s1: name, s2: "void" ) == 0) |
915 | type_id = gen_ctf_void_type (ctfc); |
916 | else |
917 | type_id = CTF_NULL_TYPEID; |
918 | |
919 | break; |
920 | } |
921 | case DW_TAG_reference_type: |
922 | type_id = CTF_NULL_TYPEID; |
923 | break; |
924 | default: |
925 | /* Unrecognized DIE. */ |
926 | unrecog_die = true; |
927 | type_id = CTF_NULL_TYPEID; |
928 | break; |
929 | } |
930 | |
931 | /* For all types unrepresented in CTF, use an explicit CTF type of kind |
932 | CTF_K_UNKNOWN. */ |
933 | if ((type_id == CTF_NULL_TYPEID) && (!unrecog_die)) |
934 | type_id = gen_ctf_unknown_type (ctfc); |
935 | |
936 | return type_id; |
937 | } |
938 | |
939 | /* Prepare for output and write out the CTF debug information. */ |
940 | |
941 | static void |
942 | ctf_debug_finalize (const char *filename, bool btf) |
943 | { |
944 | if (btf) |
945 | { |
946 | btf_output (filename); |
947 | btf_finalize (); |
948 | } |
949 | |
950 | else |
951 | { |
952 | /* Emit the collected CTF information. */ |
953 | ctf_output (filename); |
954 | |
955 | /* Reset the CTF state. */ |
956 | ctf_finalize (); |
957 | } |
958 | } |
959 | |
960 | bool |
961 | ctf_do_die (dw_die_ref die) |
962 | { |
963 | ctf_container_ref tu_ctfc = ctf_get_tu_ctfc (); |
964 | |
965 | /* Note how we tell the caller to continue traversing children DIEs |
966 | if this DIE didn't result in CTF records being added. */ |
967 | if (dw_get_die_tag (die) == DW_TAG_variable) |
968 | { |
969 | gen_ctf_variable (ctfc: tu_ctfc, die); |
970 | return false; |
971 | } |
972 | else if (dw_get_die_tag (die) == DW_TAG_subprogram) |
973 | { |
974 | gen_ctf_function (ctfc: tu_ctfc, die); |
975 | return false; |
976 | } |
977 | else |
978 | return gen_ctf_type (ctfc: tu_ctfc, die) == CTF_NULL_TYPEID; |
979 | } |
980 | |
981 | /* Initialize CTF subsystem for CTF debug info generation. */ |
982 | |
983 | void |
984 | ctf_debug_init (void) |
985 | { |
986 | /* First, initialize the CTF subsystem. */ |
987 | ctf_init (); |
988 | |
989 | /* Create a couple of DIE structures that we may need. */ |
990 | ctf_void_die = new_die_raw (DW_TAG_unspecified_type); |
991 | add_name_attribute (ctf_void_die, "void" ); |
992 | ctf_array_index_die |
993 | = base_type_die (integer_type_node, 0 /* reverse */); |
994 | add_name_attribute (ctf_array_index_die, "int" ); |
995 | ctf_unknown_die = new_die_raw (DW_TAG_unspecified_type); |
996 | add_name_attribute (ctf_unknown_die, "unknown" ); |
997 | } |
998 | |
999 | /* Preprocess the CTF debug information after initialization. */ |
1000 | |
1001 | void |
1002 | ctf_debug_init_postprocess (bool btf) |
1003 | { |
1004 | /* Only BTF requires postprocessing right after init. */ |
1005 | if (btf) |
1006 | btf_init_postprocess (); |
1007 | } |
1008 | |
1009 | /* Early finish CTF/BTF debug info. */ |
1010 | |
1011 | void |
1012 | ctf_debug_early_finish (const char * filename) |
1013 | { |
1014 | /* Emit CTF debug info early always. */ |
1015 | if (ctf_debug_info_level > CTFINFO_LEVEL_NONE |
1016 | /* Emit BTF debug info early if CO-RE relocations are not |
1017 | required. */ |
1018 | || (btf_debuginfo_p () && !btf_with_core_debuginfo_p ())) |
1019 | ctf_debug_finalize (filename, btf: btf_debuginfo_p ()); |
1020 | } |
1021 | |
1022 | /* Finish CTF/BTF debug info emission. */ |
1023 | |
1024 | void |
1025 | ctf_debug_finish (const char * filename) |
1026 | { |
1027 | /* Emit BTF debug info here when CO-RE relocations need to be generated. |
1028 | BTF with CO-RE relocations needs to be generated when CO-RE is in effect |
1029 | for the BPF target. */ |
1030 | if (btf_with_core_debuginfo_p ()) |
1031 | { |
1032 | gcc_assert (btf_debuginfo_p ()); |
1033 | ctf_debug_finalize (filename, btf: btf_debuginfo_p ()); |
1034 | } |
1035 | } |
1036 | |
1037 | #include "gt-dwarf2ctf.h" |
1038 | |