]>
Commit | Line | Data |
---|---|---|
b7e215a8 | 1 | /* Generate CTF types and objects from the GCC DWARF. |
a945c346 | 2 | Copyright (C) 2021-2024 Free Software Foundation, Inc. |
b7e215a8 IB |
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 | ||
5d24bf3a CM |
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. */ | |
b7e215a8 IB |
355 | |
356 | static ctf_id_t | |
5d24bf3a CM |
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) | |
b7e215a8 | 359 | { |
5d24bf3a CM |
360 | ctf_arinfo_t arinfo; |
361 | ctf_id_t array_node_type_id = CTF_NULL_TYPEID; | |
b7e215a8 | 362 | |
5d24bf3a CM |
363 | dw_attr_node *upper_bound_at; |
364 | dw_die_ref array_index_type; | |
365 | uint32_t array_num_elements; | |
b7e215a8 | 366 | |
5d24bf3a CM |
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 (); | |
b7e215a8 | 391 | |
5d24bf3a CM |
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; | |
b7e215a8 | 396 | |
5d24bf3a CM |
397 | array_index_type = ctf_get_AT_type (c); |
398 | arinfo.ctr_index = gen_ctf_type (ctfc, array_index_type); | |
b7e215a8 | 399 | |
5d24bf3a CM |
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 | dw_get_die_sib (c), last); | |
b7e215a8 | 405 | |
5d24bf3a CM |
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); | |
b7e215a8 | 408 | |
5d24bf3a CM |
409 | return array_node_type_id; |
410 | } | |
b7e215a8 | 411 | |
5d24bf3a | 412 | /* Generate CTF for an ARRAY_TYPE. */ |
b7e215a8 | 413 | |
5d24bf3a CM |
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; | |
b7e215a8 | 421 | |
5d24bf3a CM |
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; | |
b7e215a8 | 425 | |
5d24bf3a CM |
426 | /* Find the first and last array dimension DIEs. */ |
427 | last = dw_get_die_child (array_type); | |
428 | first = dw_get_die_sib (last); | |
b7e215a8 | 429 | |
b7e215a8 | 430 | /* Type de-duplication. |
5d24bf3a CM |
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 (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, first, | |
439 | last); | |
440 | } | |
441 | ||
442 | return array_type_id; | |
b7e215a8 IB |
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 (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 (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 (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 (c); | |
556 | field_location = ctf_get_AT_data_member_location (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 (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 (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 | ||
5c869aa8 IB |
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); | |
b7e215a8 IB |
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 (function); | |
641 | ||
642 | ctf_funcinfo_t func_info; | |
643 | uint32_t num_args = 0; | |
32566720 | 644 | int linkage = get_AT_flag (function, DW_AT_external); |
b7e215a8 IB |
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, | |
32566720 JM |
688 | from_global_func, |
689 | linkage); | |
b7e215a8 IB |
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 (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 (enumeration); | |
8422861b | 736 | unsigned int signedness = get_AT_unsigned (enumeration, DW_AT_encoding); |
b7e215a8 IB |
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, | |
8422861b GM |
760 | enum_name, bit_size / 8, |
761 | (signedness == DW_ATE_unsigned), | |
762 | enumeration); | |
b7e215a8 IB |
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 | ||
d0b00e74 IB |
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 | ||
b7e215a8 IB |
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. */ | |
d0b00e74 IB |
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]. */ | |
b7e215a8 IB |
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, die, 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, die); | |
875 | break; | |
876 | case DW_TAG_pointer_type: | |
877 | type_id = gen_ctf_pointer_type (ctfc, die); | |
878 | break; | |
879 | case DW_TAG_typedef: | |
880 | type_id = gen_ctf_typedef (ctfc, die); | |
881 | break; | |
882 | case DW_TAG_array_type: | |
883 | type_id = gen_ctf_array_type (ctfc, die); | |
884 | break; | |
885 | case DW_TAG_structure_type: | |
886 | type_id = gen_ctf_sou_type (ctfc, die, CTF_K_STRUCT); | |
887 | break; | |
888 | case DW_TAG_union_type: | |
889 | type_id = gen_ctf_sou_type (ctfc, die, CTF_K_UNION); | |
890 | break; | |
891 | case DW_TAG_subroutine_type: | |
892 | type_id = gen_ctf_function_type (ctfc, die, | |
893 | false /* from_global_func */); | |
894 | break; | |
895 | case DW_TAG_enumeration_type: | |
896 | type_id = gen_ctf_enumeration_type (ctfc, 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, 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 (name, "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 | ||
849d5f59 IB |
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); | |
38d2eb33 CM |
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 (); | |
849d5f59 IB |
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 | ||
b7e215a8 IB |
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 (tu_ctfc, die); | |
970 | return false; | |
971 | } | |
972 | else if (dw_get_die_tag (die) == DW_TAG_subprogram) | |
973 | { | |
974 | gen_ctf_function (tu_ctfc, die); | |
975 | return false; | |
976 | } | |
977 | else | |
978 | return gen_ctf_type (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 | ||
849d5f59 | 1009 | /* Early finish CTF/BTF debug info. */ |
b7e215a8 IB |
1010 | |
1011 | void | |
849d5f59 | 1012 | ctf_debug_early_finish (const char * filename) |
b7e215a8 | 1013 | { |
849d5f59 IB |
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_debuginfo_p ()); | |
1020 | } | |
b7e215a8 | 1021 | |
849d5f59 | 1022 | /* Finish CTF/BTF debug info emission. */ |
b7e215a8 | 1023 | |
849d5f59 IB |
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. */ | |
38d2eb33 CM |
1030 | if (btf_debuginfo_p () && btf_with_core_debuginfo_p ()) |
1031 | ctf_debug_finalize (filename, btf_debuginfo_p ()); | |
b7e215a8 IB |
1032 | } |
1033 | ||
1034 | #include "gt-dwarf2ctf.h" |