1 | /* Generate CTF types and objects from the GCC DWARF. |
2 | Copyright (C) 2021-2024 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 | /* Recursively generate CTF for array dimensions starting at DIE C (of type |
353 | DW_TAG_subrange_type) until DIE LAST (of type DW_TAG_subrange_type) is |
354 | reached. ARRAY_ELEMS_TYPE_ID is base type for the array. */ |
355 | |
356 | static ctf_id_t |
357 | gen_ctf_subrange_type (ctf_container_ref ctfc, ctf_id_t array_elems_type_id, |
358 | dw_die_ref c, dw_die_ref last) |
359 | { |
360 | ctf_arinfo_t arinfo; |
361 | ctf_id_t array_node_type_id = CTF_NULL_TYPEID; |
362 | |
363 | dw_attr_node *upper_bound_at; |
364 | dw_die_ref array_index_type; |
365 | uint32_t array_num_elements; |
366 | |
367 | if (dw_get_die_tag (c) == DW_TAG_subrange_type) |
368 | { |
369 | /* When DW_AT_upper_bound is used to specify the size of an |
370 | array in DWARF, it is usually an unsigned constant |
371 | specifying the upper bound index of the array. However, |
372 | for unsized arrays, such as foo[] or bar[0], |
373 | DW_AT_upper_bound is a signed integer constant |
374 | instead. */ |
375 | |
376 | upper_bound_at = get_AT (c, DW_AT_upper_bound); |
377 | if (upper_bound_at |
378 | && AT_class (upper_bound_at) == dw_val_class_unsigned_const) |
379 | /* This is the upper bound index. */ |
380 | array_num_elements = get_AT_unsigned (c, DW_AT_upper_bound) + 1; |
381 | else if (get_AT (c, DW_AT_count)) |
382 | array_num_elements = get_AT_unsigned (c, DW_AT_count); |
383 | else |
384 | { |
385 | /* This is a VLA of some kind. */ |
386 | array_num_elements = 0; |
387 | } |
388 | } |
389 | else |
390 | gcc_unreachable (); |
391 | |
392 | /* Ok, mount and register the array type. Note how the array |
393 | type we register here is the type of the elements in |
394 | subsequent "dimensions", if there are any. */ |
395 | arinfo.ctr_nelems = array_num_elements; |
396 | |
397 | array_index_type = ctf_get_AT_type (die: c); |
398 | arinfo.ctr_index = gen_ctf_type (ctfc, array_index_type); |
399 | |
400 | if (c == last) |
401 | arinfo.ctr_contents = array_elems_type_id; |
402 | else |
403 | arinfo.ctr_contents = gen_ctf_subrange_type (ctfc, array_elems_type_id, |
404 | c: dw_get_die_sib (c), last); |
405 | |
406 | if (!ctf_type_exists (ctfc, c, &array_node_type_id)) |
407 | array_node_type_id = ctf_add_array (ctfc, CTF_ADD_ROOT, &arinfo, c); |
408 | |
409 | return array_node_type_id; |
410 | } |
411 | |
412 | /* Generate CTF for an ARRAY_TYPE. */ |
413 | |
414 | static ctf_id_t |
415 | gen_ctf_array_type (ctf_container_ref ctfc, |
416 | dw_die_ref array_type) |
417 | { |
418 | dw_die_ref first, last, array_elems_type; |
419 | ctf_id_t array_elems_type_id = CTF_NULL_TYPEID; |
420 | ctf_id_t array_type_id = CTF_NULL_TYPEID; |
421 | |
422 | int vector_type_p = get_AT_flag (array_type, DW_AT_GNU_vector); |
423 | if (vector_type_p) |
424 | return array_elems_type_id; |
425 | |
426 | /* Find the first and last array dimension DIEs. */ |
427 | last = dw_get_die_child (array_type); |
428 | first = dw_get_die_sib (last); |
429 | |
430 | /* Type de-duplication. |
431 | Consult the ctfc_types before adding CTF type for the first dimension. */ |
432 | if (!ctf_type_exists (ctfc, first, &array_type_id)) |
433 | { |
434 | array_elems_type = ctf_get_AT_type (die: array_type); |
435 | /* First, register the type of the array elements if needed. */ |
436 | array_elems_type_id = gen_ctf_type (ctfc, array_elems_type); |
437 | |
438 | array_type_id = gen_ctf_subrange_type (ctfc, array_elems_type_id, c: first, |
439 | last); |
440 | } |
441 | |
442 | return array_type_id; |
443 | } |
444 | |
445 | /* Generate CTF for a typedef. */ |
446 | |
447 | static ctf_id_t |
448 | gen_ctf_typedef (ctf_container_ref ctfc, dw_die_ref tdef) |
449 | { |
450 | ctf_id_t tdef_type_id, tid; |
451 | const char *tdef_name = get_AT_string (tdef, DW_AT_name); |
452 | dw_die_ref tdef_type = ctf_get_AT_type (die: tdef); |
453 | |
454 | tid = gen_ctf_type (ctfc, tdef_type); |
455 | |
456 | /* Type de-duplication. |
457 | This is necessary because the ctf for the typedef may have been already |
458 | added due to the gen_ctf_type call above. */ |
459 | if (!ctf_type_exists (ctfc, tdef, &tdef_type_id)) |
460 | { |
461 | tdef_type_id = ctf_add_typedef (ctfc, CTF_ADD_ROOT, |
462 | tdef_name, |
463 | tid, |
464 | tdef); |
465 | } |
466 | return tdef_type_id; |
467 | } |
468 | |
469 | /* Generate CTF for a type modifier. |
470 | |
471 | If the given DIE contains a valid C modifier (like _Atomic), which is not |
472 | supported by CTF, then this function skips the modifier die and continues |
473 | with the underlying type. |
474 | |
475 | For all other cases, this function returns a CTF_NULL_TYPEID; |
476 | */ |
477 | |
478 | static ctf_id_t |
479 | gen_ctf_modifier_type (ctf_container_ref ctfc, dw_die_ref modifier) |
480 | { |
481 | uint32_t kind = CTF_K_MAX; |
482 | ctf_id_t modifier_type_id, qual_type_id; |
483 | dw_die_ref qual_type = ctf_get_AT_type (die: modifier); |
484 | |
485 | switch (dw_get_die_tag (modifier)) |
486 | { |
487 | case DW_TAG_const_type: kind = CTF_K_CONST; break; |
488 | case DW_TAG_volatile_type: kind = CTF_K_VOLATILE; break; |
489 | case DW_TAG_restrict_type: kind = CTF_K_RESTRICT; break; |
490 | case DW_TAG_atomic_type: break; |
491 | default: |
492 | return CTF_NULL_TYPEID; |
493 | } |
494 | |
495 | /* Register the type for which this modifier applies. */ |
496 | qual_type_id = gen_ctf_type (ctfc, qual_type); |
497 | |
498 | /* Skip generating a CTF modifier record for _Atomic as there is no |
499 | representation for it. */ |
500 | if (dw_get_die_tag (modifier) == DW_TAG_atomic_type) |
501 | return qual_type_id; |
502 | |
503 | gcc_assert (kind != CTF_K_MAX); |
504 | /* Now register the modifier itself. */ |
505 | if (!ctf_type_exists (ctfc, modifier, &modifier_type_id)) |
506 | modifier_type_id = ctf_add_reftype (ctfc, CTF_ADD_ROOT, |
507 | qual_type_id, kind, |
508 | modifier); |
509 | |
510 | return modifier_type_id; |
511 | } |
512 | |
513 | /* Generate CTF for a struct type. */ |
514 | |
515 | static ctf_id_t |
516 | gen_ctf_sou_type (ctf_container_ref ctfc, dw_die_ref sou, uint32_t kind) |
517 | { |
518 | uint32_t bit_size = ctf_die_bitsize (die: sou); |
519 | int declaration_p = get_AT_flag (sou, DW_AT_declaration); |
520 | const char *sou_name = get_AT_string (sou, DW_AT_name); |
521 | |
522 | ctf_id_t sou_type_id; |
523 | |
524 | /* An incomplete structure or union type is represented in DWARF by |
525 | a structure or union DIE that does not have a size attribute and |
526 | that has a DW_AT_declaration attribute. This corresponds to a |
527 | CTF forward type with kind CTF_K_STRUCT. */ |
528 | if (bit_size == 0 && declaration_p) |
529 | return ctf_add_forward (ctfc, CTF_ADD_ROOT, |
530 | sou_name, kind, sou); |
531 | |
532 | /* This is a complete struct or union type. Generate a CTF type for |
533 | it if it doesn't exist already. */ |
534 | if (!ctf_type_exists (ctfc, sou, &sou_type_id)) |
535 | sou_type_id = ctf_add_sou (ctfc, CTF_ADD_ROOT, |
536 | sou_name, kind, bit_size / 8, |
537 | sou); |
538 | |
539 | /* Now process the struct members. */ |
540 | { |
541 | dw_die_ref c; |
542 | |
543 | c = dw_get_die_child (sou); |
544 | if (c) |
545 | do |
546 | { |
547 | const char *field_name; |
548 | dw_die_ref field_type; |
549 | HOST_WIDE_INT field_location; |
550 | ctf_id_t field_type_id; |
551 | |
552 | c = dw_get_die_sib (c); |
553 | |
554 | field_name = get_AT_string (c, DW_AT_name); |
555 | field_type = ctf_get_AT_type (die: c); |
556 | field_location = ctf_get_AT_data_member_location (die: c); |
557 | |
558 | /* Generate the field type. */ |
559 | field_type_id = gen_ctf_type (ctfc, field_type); |
560 | |
561 | /* If this is a bit-field, then wrap the field type |
562 | generated above with a CTF slice. */ |
563 | if (get_AT (c, DW_AT_bit_offset) |
564 | || get_AT (c, DW_AT_data_bit_offset)) |
565 | { |
566 | dw_attr_node *attr; |
567 | HOST_WIDE_INT bitpos = 0; |
568 | HOST_WIDE_INT bitsize = ctf_die_bitsize (die: c); |
569 | HOST_WIDE_INT bit_offset; |
570 | |
571 | /* The bit offset is given in bits and it may be |
572 | negative. */ |
573 | attr = get_AT (c, DW_AT_bit_offset); |
574 | if (attr) |
575 | { |
576 | if (AT_class (attr) == dw_val_class_unsigned_const) |
577 | bit_offset = AT_unsigned (attr); |
578 | else |
579 | bit_offset = AT_int (attr); |
580 | |
581 | if (BYTES_BIG_ENDIAN) |
582 | bitpos = field_location + bit_offset; |
583 | else |
584 | { |
585 | HOST_WIDE_INT bit_size; |
586 | |
587 | attr = get_AT (c, DW_AT_byte_size); |
588 | if (attr) |
589 | /* Explicit size given in bytes. */ |
590 | bit_size = AT_unsigned (attr) * 8; |
591 | else |
592 | /* Infer the size from the member type. */ |
593 | bit_size = ctf_die_bitsize (die: field_type); |
594 | |
595 | bitpos = (field_location |
596 | + bit_size |
597 | - bit_offset |
598 | - bitsize); |
599 | } |
600 | } |
601 | |
602 | /* In DWARF5 a data_bit_offset attribute is given with |
603 | the offset of the data from the beginning of the |
604 | struct. Acknowledge it if present. */ |
605 | attr = get_AT (c, DW_AT_data_bit_offset); |
606 | if (attr) |
607 | bitpos += AT_unsigned (attr); |
608 | |
609 | /* This is not precisely a TBD_CTF_REPRESENTATION_LIMIT, but |
610 | surely something to look at for the next format version bump |
611 | for CTF. */ |
612 | if (bitsize <= 255 && (bitpos - field_location) <= 255) |
613 | field_type_id = ctf_add_slice (ctfc, CTF_ADD_NONROOT, |
614 | field_type_id, |
615 | bitpos - field_location, |
616 | bitsize, c); |
617 | else |
618 | field_type_id = gen_ctf_unknown_type (ctfc); |
619 | } |
620 | |
621 | /* Add the field type to the struct or union type. */ |
622 | ctf_add_member_offset (ctfc, sou, |
623 | field_name, |
624 | field_type_id, |
625 | field_location); |
626 | } |
627 | while (c != dw_get_die_child (sou)); |
628 | } |
629 | |
630 | return sou_type_id; |
631 | } |
632 | |
633 | /* Generate CTF for a function type. */ |
634 | |
635 | static ctf_id_t |
636 | gen_ctf_function_type (ctf_container_ref ctfc, dw_die_ref function, |
637 | bool from_global_func) |
638 | { |
639 | const char *function_name = get_AT_string (function, DW_AT_name); |
640 | dw_die_ref return_type = ctf_get_AT_type (die: function); |
641 | |
642 | ctf_funcinfo_t func_info; |
643 | uint32_t num_args = 0; |
644 | int linkage = get_AT_flag (function, DW_AT_external); |
645 | |
646 | ctf_id_t return_type_id; |
647 | ctf_id_t function_type_id; |
648 | |
649 | /* First, add the return type. */ |
650 | return_type_id = gen_ctf_type (ctfc, return_type); |
651 | func_info.ctc_return = return_type_id; |
652 | |
653 | /* Type de-duplication. |
654 | Consult the ctfc_types hash before adding the CTF function type. */ |
655 | if (ctf_type_exists (ctfc, function, &function_type_id)) |
656 | return function_type_id; |
657 | |
658 | /* Do a first pass on the formals to determine the number of |
659 | arguments, and whether the function type gets a varargs. */ |
660 | { |
661 | dw_die_ref c; |
662 | |
663 | c = dw_get_die_child (function); |
664 | if (c) |
665 | do |
666 | { |
667 | c = dw_get_die_sib (c); |
668 | |
669 | if (dw_get_die_tag (c) == DW_TAG_formal_parameter) |
670 | num_args += 1; |
671 | else if (dw_get_die_tag (c) == DW_TAG_unspecified_parameters) |
672 | { |
673 | func_info.ctc_flags |= CTF_FUNC_VARARG; |
674 | num_args += 1; |
675 | } |
676 | } |
677 | while (c != dw_get_die_child (function)); |
678 | } |
679 | |
680 | /* Note the number of typed arguments _includes_ the vararg. */ |
681 | func_info.ctc_argc = num_args; |
682 | |
683 | /* Type de-duplication has already been performed by now. */ |
684 | function_type_id = ctf_add_function (ctfc, CTF_ADD_ROOT, |
685 | function_name, |
686 | (const ctf_funcinfo_t *)&func_info, |
687 | function, |
688 | from_global_func, |
689 | linkage); |
690 | |
691 | /* Second pass on formals: generate the CTF types corresponding to |
692 | them and add them as CTF function args. */ |
693 | { |
694 | dw_die_ref c; |
695 | unsigned int i = 0; |
696 | const char *arg_name; |
697 | ctf_id_t arg_type; |
698 | |
699 | c = dw_get_die_child (function); |
700 | if (c) |
701 | do |
702 | { |
703 | c = dw_get_die_sib (c); |
704 | |
705 | if (dw_get_die_tag (c) == DW_TAG_unspecified_parameters) |
706 | { |
707 | gcc_assert (i == num_args - 1); |
708 | /* Add an argument with type 0 and no name. */ |
709 | ctf_add_function_arg (ctfc, function, "" , 0); |
710 | } |
711 | else if (dw_get_die_tag (c) == DW_TAG_formal_parameter) |
712 | { |
713 | i++; |
714 | arg_name = get_AT_string (c, DW_AT_name); |
715 | arg_type = gen_ctf_type (ctfc, ctf_get_AT_type (die: c)); |
716 | /* Add the argument to the existing CTF function type. */ |
717 | ctf_add_function_arg (ctfc, function, arg_name, arg_type); |
718 | } |
719 | else |
720 | /* This is a local variable. Ignore. */ |
721 | continue; |
722 | } |
723 | while (c != dw_get_die_child (function)); |
724 | } |
725 | |
726 | return function_type_id; |
727 | } |
728 | |
729 | /* Generate CTF for an enumeration type. */ |
730 | |
731 | static ctf_id_t |
732 | gen_ctf_enumeration_type (ctf_container_ref ctfc, dw_die_ref enumeration) |
733 | { |
734 | const char *enum_name = get_AT_string (enumeration, DW_AT_name); |
735 | unsigned int bit_size = ctf_die_bitsize (die: enumeration); |
736 | unsigned int signedness = get_AT_unsigned (enumeration, DW_AT_encoding); |
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 (die: enumeration); |
755 | bit_size = ctf_die_bitsize (die: 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, |
761 | (signedness == DW_ATE_unsigned), |
762 | enumeration); |
763 | |
764 | /* Process the enumerators. */ |
765 | { |
766 | dw_die_ref c; |
767 | |
768 | c = dw_get_die_child (enumeration); |
769 | if (c) |
770 | do |
771 | { |
772 | const char *enumerator_name; |
773 | dw_attr_node *enumerator_value; |
774 | HOST_WIDE_INT value_wide_int; |
775 | |
776 | c = dw_get_die_sib (c); |
777 | |
778 | enumerator_name = get_AT_string (c, DW_AT_name); |
779 | enumerator_value = get_AT (c, DW_AT_const_value); |
780 | |
781 | /* enumerator_value can be either a signed or an unsigned |
782 | constant value. */ |
783 | if (AT_class (enumerator_value) == dw_val_class_unsigned_const |
784 | || (AT_class (enumerator_value) |
785 | == dw_val_class_unsigned_const_implicit)) |
786 | value_wide_int = AT_unsigned (enumerator_value); |
787 | else |
788 | value_wide_int = AT_int (enumerator_value); |
789 | |
790 | ctf_add_enumerator (ctfc, enumeration_type_id, |
791 | enumerator_name, value_wide_int, enumeration); |
792 | } |
793 | while (c != dw_get_die_child (enumeration)); |
794 | } |
795 | |
796 | return enumeration_type_id; |
797 | } |
798 | |
799 | /* Add a CTF variable record for the given input DWARF DIE. */ |
800 | |
801 | static void |
802 | gen_ctf_variable (ctf_container_ref ctfc, dw_die_ref die) |
803 | { |
804 | const char *var_name = get_AT_string (die, DW_AT_name); |
805 | dw_die_ref var_type = ctf_get_AT_type (die); |
806 | unsigned int external_vis = get_AT_flag (die, DW_AT_external); |
807 | ctf_id_t var_type_id; |
808 | |
809 | /* Avoid duplicates. */ |
810 | if (ctf_dvd_lookup (ctfc, die)) |
811 | return; |
812 | |
813 | /* Do not generate CTF variable records for non-defining incomplete |
814 | declarations. Such declarations can be known via the DWARF |
815 | DW_AT_specification attribute. */ |
816 | if (ctf_dvd_ignore_lookup (ctfc, die)) |
817 | return; |
818 | |
819 | /* The value of the DW_AT_specification attribute, if present, is a |
820 | reference to the debugging information entry representing the |
821 | non-defining declaration. */ |
822 | dw_die_ref decl = get_AT_ref (die, DW_AT_specification); |
823 | |
824 | /* Add the type of the variable. */ |
825 | var_type_id = gen_ctf_type (ctfc, var_type); |
826 | |
827 | /* Generate the new CTF variable and update global counter. */ |
828 | (void) ctf_add_variable (ctfc, var_name, var_type_id, die, external_vis, |
829 | decl); |
830 | /* Skip updating the number of global objects at this time. This is updated |
831 | later after pre-processing as some CTF variable records although |
832 | generated now, will not be emitted later. [PR105089]. */ |
833 | } |
834 | |
835 | /* Add a CTF function record for the given input DWARF DIE. */ |
836 | |
837 | static void |
838 | gen_ctf_function (ctf_container_ref ctfc, dw_die_ref die) |
839 | { |
840 | ctf_id_t function_type_id; |
841 | /* Type de-duplication. |
842 | Consult the ctfc_types hash before adding the CTF function type. */ |
843 | if (ctf_type_exists (ctfc, die, &function_type_id)) |
844 | return; |
845 | |
846 | /* Add the type of the function and update the global functions |
847 | counter. Note that DWARF encodes function types in both |
848 | DW_TAG_subroutine_type and DW_TAG_subprogram in exactly the same |
849 | way. */ |
850 | (void) gen_ctf_function_type (ctfc, function: die, from_global_func: true /* from_global_func */); |
851 | ctfc->ctfc_num_global_funcs += 1; |
852 | } |
853 | |
854 | /* Add CTF type record(s) for the given input DWARF DIE and return its type id. |
855 | |
856 | If there is already a CTF type corresponding to the given DIE, then |
857 | this function returns the type id of the existing type. |
858 | |
859 | If the given DIE is not recognized as a type, then this function |
860 | returns CTF_NULL_TYPEID. */ |
861 | |
862 | static ctf_id_t |
863 | gen_ctf_type (ctf_container_ref ctfc, dw_die_ref die) |
864 | { |
865 | ctf_id_t type_id; |
866 | int unrecog_die = false; |
867 | |
868 | if (ctf_type_exists (ctfc, die, &type_id)) |
869 | return type_id; |
870 | |
871 | switch (dw_get_die_tag (die)) |
872 | { |
873 | case DW_TAG_base_type: |
874 | type_id = gen_ctf_base_type (ctfc, type: die); |
875 | break; |
876 | case DW_TAG_pointer_type: |
877 | type_id = gen_ctf_pointer_type (ctfc, ptr_type: die); |
878 | break; |
879 | case DW_TAG_typedef: |
880 | type_id = gen_ctf_typedef (ctfc, tdef: die); |
881 | break; |
882 | case DW_TAG_array_type: |
883 | type_id = gen_ctf_array_type (ctfc, array_type: die); |
884 | break; |
885 | case DW_TAG_structure_type: |
886 | type_id = gen_ctf_sou_type (ctfc, sou: die, CTF_K_STRUCT); |
887 | break; |
888 | case DW_TAG_union_type: |
889 | type_id = gen_ctf_sou_type (ctfc, sou: die, CTF_K_UNION); |
890 | break; |
891 | case DW_TAG_subroutine_type: |
892 | type_id = gen_ctf_function_type (ctfc, function: die, |
893 | from_global_func: false /* from_global_func */); |
894 | break; |
895 | case DW_TAG_enumeration_type: |
896 | type_id = gen_ctf_enumeration_type (ctfc, enumeration: die); |
897 | break; |
898 | case DW_TAG_atomic_type: |
899 | /* FALLTHROUGH */ |
900 | case DW_TAG_const_type: |
901 | /* FALLTHROUGH */ |
902 | case DW_TAG_restrict_type: |
903 | /* FALLTHROUGH */ |
904 | case DW_TAG_volatile_type: |
905 | type_id = gen_ctf_modifier_type (ctfc, modifier: die); |
906 | break; |
907 | case DW_TAG_unspecified_type: |
908 | { |
909 | const char *name = get_AT_string (die, DW_AT_name); |
910 | |
911 | if (name && strcmp (s1: name, s2: "void" ) == 0) |
912 | type_id = gen_ctf_void_type (ctfc); |
913 | else |
914 | type_id = CTF_NULL_TYPEID; |
915 | |
916 | break; |
917 | } |
918 | case DW_TAG_reference_type: |
919 | type_id = CTF_NULL_TYPEID; |
920 | break; |
921 | default: |
922 | /* Unrecognized DIE. */ |
923 | unrecog_die = true; |
924 | type_id = CTF_NULL_TYPEID; |
925 | break; |
926 | } |
927 | |
928 | /* For all types unrepresented in CTF, use an explicit CTF type of kind |
929 | CTF_K_UNKNOWN. */ |
930 | if ((type_id == CTF_NULL_TYPEID) && (!unrecog_die)) |
931 | type_id = gen_ctf_unknown_type (ctfc); |
932 | |
933 | return type_id; |
934 | } |
935 | |
936 | /* Prepare for output and write out the CTF debug information. */ |
937 | |
938 | static void |
939 | ctf_debug_finalize (const char *filename, bool btf) |
940 | { |
941 | if (btf) |
942 | { |
943 | btf_output (filename); |
944 | /* btf_finalize when compiling BPF applciations gets deallocated by the |
945 | BPF target in bpf_file_end. */ |
946 | if (btf_debuginfo_p () && !btf_with_core_debuginfo_p ()) |
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_debuginfo_p () && btf_with_core_debuginfo_p ()) |
1031 | ctf_debug_finalize (filename, btf: btf_debuginfo_p ()); |
1032 | } |
1033 | |
1034 | #include "gt-dwarf2ctf.h" |
1035 | |