1 | /* Generate CTF. |
2 | Copyright (C) 2019-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 "toplev.h" |
25 | #include "ctfc.h" |
26 | #include "diagnostic-core.h" |
27 | |
28 | /* A CTF container object - one per translation unit. */ |
29 | |
30 | ctf_container_ref tu_ctfc; |
31 | |
32 | ctf_container_ref |
33 | ctf_get_tu_ctfc (void) |
34 | { |
35 | return tu_ctfc; |
36 | } |
37 | |
38 | /* If the next ctf type id is still set to the init value, no ctf records to |
39 | report. */ |
40 | bool |
41 | ctfc_is_empty_container (ctf_container_ref ctfc) |
42 | { |
43 | return ((ctfc)->ctfc_nextid == CTF_INIT_TYPEID); |
44 | } |
45 | |
46 | /* Get the total number of CTF types in the container. */ |
47 | |
48 | unsigned int |
49 | ctfc_get_num_ctf_types (ctf_container_ref ctfc) |
50 | { |
51 | return ctfc->ctfc_types->elements (); |
52 | } |
53 | |
54 | /* Get the total number of CTF variables in the container. */ |
55 | |
56 | unsigned int ctfc_get_num_ctf_vars (ctf_container_ref ctfc) |
57 | { |
58 | return ctfc->ctfc_vars->elements (); |
59 | } |
60 | |
61 | /* Get reference to the CTF string table or the CTF auxilliary |
62 | string table. */ |
63 | |
64 | ctf_strtable_t * |
65 | ctfc_get_strtab (ctf_container_ref ctfc, int aux) |
66 | { |
67 | return aux ? &(ctfc)->ctfc_aux_strtable : &(ctfc->ctfc_strtable); |
68 | } |
69 | |
70 | /* Get the length of the specified string table of the CTF container. */ |
71 | |
72 | size_t |
73 | ctfc_get_strtab_len (ctf_container_ref ctfc, int aux) |
74 | { |
75 | ctf_strtable_t * strtab = ctfc_get_strtab (ctfc, aux); |
76 | return strtab->ctstab_len; |
77 | } |
78 | |
79 | /* Get the number of bytes to represent the variable length portion of all CTF |
80 | types in the CTF container. */ |
81 | |
82 | size_t ctfc_get_num_vlen_bytes (ctf_container_ref ctfc) |
83 | { |
84 | return ctfc->ctfc_num_vlen_bytes; |
85 | } |
86 | |
87 | /* Return which member of the union is used in CTFTYPE. Used for garbage |
88 | collection. */ |
89 | |
90 | enum ctf_dtu_d_union_enum |
91 | ctf_dtu_d_union_selector (ctf_dtdef_ref ctftype) |
92 | { |
93 | uint32_t kind = CTF_V2_INFO_KIND (ctftype->dtd_data.ctti_info); |
94 | switch (kind) |
95 | { |
96 | case CTF_K_UNKNOWN: |
97 | case CTF_K_INTEGER: |
98 | case CTF_K_FLOAT: |
99 | return CTF_DTU_D_ENCODING; |
100 | case CTF_K_STRUCT: |
101 | case CTF_K_UNION: |
102 | case CTF_K_ENUM: |
103 | return CTF_DTU_D_MEMBERS; |
104 | case CTF_K_ARRAY: |
105 | return CTF_DTU_D_ARRAY; |
106 | case CTF_K_FUNCTION: |
107 | return CTF_DTU_D_ARGUMENTS; |
108 | case CTF_K_SLICE: |
109 | return CTF_DTU_D_SLICE; |
110 | default: |
111 | /* The largest member as default. */ |
112 | return CTF_DTU_D_ARRAY; |
113 | } |
114 | } |
115 | |
116 | /* Insert CTF type into the CTF container. */ |
117 | |
118 | static void |
119 | ctf_dtd_insert (ctf_container_ref ctfc, ctf_dtdef_ref dtd) |
120 | { |
121 | bool existed = false; |
122 | ctf_dtdef_ref entry = dtd; |
123 | |
124 | ctf_dtdef_ref * item = ctfc->ctfc_types->find_slot (value: entry, insert: INSERT); |
125 | if (*item == NULL) |
126 | *item = dtd; |
127 | else |
128 | existed = true; |
129 | /* Duplicate CTF type records not expected to be inserted. */ |
130 | gcc_assert (!existed); |
131 | } |
132 | |
133 | /* Lookup CTF type given a DWARF die for the type. */ |
134 | |
135 | ctf_dtdef_ref |
136 | ctf_dtd_lookup (const ctf_container_ref ctfc, const dw_die_ref type) |
137 | { |
138 | ctf_dtdef_t entry; |
139 | entry.dtd_key = type; |
140 | |
141 | ctf_dtdef_ref * slot = ctfc->ctfc_types->find_slot (value: &entry, insert: NO_INSERT); |
142 | |
143 | if (slot) |
144 | return (ctf_dtdef_ref)*slot; |
145 | |
146 | return NULL; |
147 | } |
148 | |
149 | /* Insert CTF variable into the CTF container. */ |
150 | |
151 | static void |
152 | ctf_dvd_insert (ctf_container_ref ctfc, ctf_dvdef_ref dvd) |
153 | { |
154 | bool existed = false; |
155 | ctf_dvdef_ref entry = dvd; |
156 | |
157 | ctf_dvdef_ref * item = ctfc->ctfc_vars->find_slot (value: entry, insert: INSERT); |
158 | if (*item == NULL) |
159 | *item = dvd; |
160 | else |
161 | existed = true; |
162 | /* Duplicate variable records not expected to be inserted. */ |
163 | gcc_assert (!existed); |
164 | } |
165 | |
166 | /* Lookup CTF variable given a DWARF die for the decl. */ |
167 | |
168 | ctf_dvdef_ref |
169 | ctf_dvd_lookup (const ctf_container_ref ctfc, dw_die_ref die) |
170 | { |
171 | ctf_dvdef_t entry; |
172 | entry.dvd_key = die; |
173 | |
174 | ctf_dvdef_ref * slot = ctfc->ctfc_vars->find_slot (value: &entry, insert: NO_INSERT); |
175 | |
176 | if (slot) |
177 | return (ctf_dvdef_ref)*slot; |
178 | |
179 | return NULL; |
180 | } |
181 | |
182 | /* Insert a dummy CTF variable into the list of variables to be ignored. */ |
183 | |
184 | static void |
185 | ctf_dvd_ignore_insert (ctf_container_ref ctfc, ctf_dvdef_ref dvd) |
186 | { |
187 | bool existed = false; |
188 | ctf_dvdef_ref entry = dvd; |
189 | |
190 | ctf_dvdef_ref * item = ctfc->ctfc_ignore_vars->find_slot (value: entry, insert: INSERT); |
191 | if (*item == NULL) |
192 | *item = dvd; |
193 | else |
194 | existed = true; |
195 | /* Duplicate variable records not expected to be inserted. */ |
196 | gcc_assert (!existed); |
197 | } |
198 | |
199 | /* Lookup the dummy CTF variable given the DWARF die for the non-defining |
200 | decl to be ignored. */ |
201 | |
202 | bool |
203 | ctf_dvd_ignore_lookup (const ctf_container_ref ctfc, dw_die_ref die) |
204 | { |
205 | ctf_dvdef_t entry; |
206 | entry.dvd_key = die; |
207 | |
208 | ctf_dvdef_ref * slot = ctfc->ctfc_ignore_vars->find_slot (value: &entry, insert: NO_INSERT); |
209 | |
210 | if (slot) |
211 | return true; |
212 | |
213 | return false; |
214 | } |
215 | |
216 | /* Append member definition to the list. Member list is a singly-linked list |
217 | with list start pointing to the head. */ |
218 | |
219 | static void |
220 | ctf_dmd_list_append (ctf_dmdef_t ** dmd, ctf_dmdef_t * elem) |
221 | { |
222 | ctf_dmdef_t * tail = (dmd && *dmd) ? *dmd : NULL; |
223 | if (tail) |
224 | { |
225 | while (tail->dmd_next) |
226 | tail = tail->dmd_next; |
227 | |
228 | tail->dmd_next = elem; |
229 | } |
230 | else |
231 | *dmd = elem; |
232 | |
233 | elem->dmd_next = NULL; |
234 | } |
235 | |
236 | /* Append function argument to the list. Member list is a singly-linked list |
237 | with list start pointing to the head. */ |
238 | |
239 | static void |
240 | ctf_farg_list_append (ctf_func_arg_t ** farg, ctf_func_arg_t * elem) |
241 | { |
242 | ctf_func_arg_t * tail = (farg && *farg) ? *farg : NULL; |
243 | if (tail) |
244 | { |
245 | while (tail->farg_next) |
246 | tail = tail->farg_next; |
247 | |
248 | tail->farg_next = elem; |
249 | } |
250 | else |
251 | *farg = elem; |
252 | |
253 | elem->farg_next = NULL; |
254 | } |
255 | |
256 | /* Append str to the CTF string table. */ |
257 | |
258 | static void |
259 | ctfc_strtable_append_str (ctf_strtable_t * str_table, const char * str) |
260 | { |
261 | ctf_string_t * ctf_string = ggc_cleared_alloc<ctf_string_t> (); |
262 | /* Keep a reference to the input STR. */ |
263 | ctf_string->cts_str = str; |
264 | ctf_string->cts_next = NULL; |
265 | |
266 | if (!str_table->ctstab_head) |
267 | str_table->ctstab_head = ctf_string; |
268 | |
269 | /* Append to the end of the list. */ |
270 | if (str_table->ctstab_tail) |
271 | str_table->ctstab_tail->cts_next = ctf_string; |
272 | |
273 | str_table->ctstab_tail = ctf_string; |
274 | } |
275 | |
276 | /* Wrapper function to add str to the CTF string table. No de-duplication of |
277 | CTF strings is done by the compiler. */ |
278 | |
279 | static const char * |
280 | ctfc_strtable_add_str (ctf_strtable_t * str_table, const char * name, |
281 | uint32_t * name_offset) |
282 | { |
283 | size_t len; |
284 | char * ctf_string; |
285 | /* Return value is the offset to the string in the string table. */ |
286 | uint32_t str_offset = str_table->ctstab_len; |
287 | |
288 | /* Add empty string only once at the beginning of the string table. Also, do |
289 | not add null strings, return the offset to the empty string for them. */ |
290 | if ((!name || (name != NULL && !strcmp (s1: name, s2: "" ))) && str_offset) |
291 | { |
292 | ctf_string = CONST_CAST (char *, str_table->ctstab_estr); |
293 | str_offset = 0; |
294 | } |
295 | else |
296 | { |
297 | gcc_assert (name); |
298 | /* Add null-terminated strings to the string table. */ |
299 | len = strlen (s: name) + 1; |
300 | ctf_string = CONST_CAST (char *, ggc_strdup (name)); |
301 | |
302 | ctfc_strtable_append_str (str_table, str: ctf_string); |
303 | /* Add string to the string table. Keep number of strings updated. */ |
304 | str_table->ctstab_num++; |
305 | /* Keep the number of bytes contained in the string table updated. */ |
306 | str_table->ctstab_len += len; |
307 | } |
308 | |
309 | *name_offset = str_offset; |
310 | |
311 | return (const char *) ctf_string; |
312 | |
313 | } |
314 | |
315 | /* Add string to the appropriate string table in the CTF container. */ |
316 | |
317 | const char * |
318 | ctf_add_string (ctf_container_ref ctfc, const char * name, |
319 | uint32_t * name_offset, int aux_str = CTF_STRTAB) |
320 | { |
321 | /* Get the CTF string table or the CTF auxilliary string table, |
322 | as applicable. */ |
323 | ctf_strtable_t *str_table = ctfc_get_strtab (ctfc, aux: aux_str); |
324 | return ctfc_strtable_add_str (str_table, name, name_offset); |
325 | } |
326 | |
327 | /* Add the compilation unit (CU) name string to the CTF string table. The |
328 | CU name has a prepended pwd string if it is a relative path. Also set the |
329 | CU name offset in the CTF container. */ |
330 | |
331 | void |
332 | ctf_add_cuname (ctf_container_ref ctfc, const char * filename) |
333 | { |
334 | char * cuname = NULL; |
335 | |
336 | /* (filename at this point of compilation cannot be null). */ |
337 | |
338 | if (!IS_DIR_SEPARATOR (filename[0])) |
339 | { |
340 | /* Filename is a relative path. */ |
341 | const char * cu_pwd = get_src_pwd (); |
342 | const int cu_pwd_len = strlen (s: cu_pwd); |
343 | |
344 | /* Add a DIR_SEPARATOR char before the filename. */ |
345 | const int len = cu_pwd_len + 2 + strlen (s: filename); |
346 | |
347 | cuname = (char *) ggc_alloc_atomic (s: len); |
348 | memset (s: cuname, c: 0, n: len); |
349 | |
350 | strcpy (dest: cuname, src: cu_pwd); |
351 | cuname[cu_pwd_len] = DIR_SEPARATOR; |
352 | cuname[cu_pwd_len+1] = 0; |
353 | strcat (dest: cuname, src: filename); |
354 | } |
355 | else |
356 | /* Filename is an absolute path. */ |
357 | cuname = CONST_CAST (char *, ggc_strdup (filename)); |
358 | |
359 | ctf_add_string (ctfc, name: cuname, name_offset: &(ctfc->ctfc_cuname_offset)); |
360 | /* Add 1 as CTF strings in the CTF string table are null-terminated |
361 | strings. */ |
362 | ctfc->ctfc_strlen += strlen (s: cuname) + 1; |
363 | |
364 | /* Mark cuname for garbage collection. */ |
365 | cuname = NULL; |
366 | } |
367 | |
368 | /* Functions to create CTF types. |
369 | |
370 | These functions perform the task of adding CTF types to the CTF container. |
371 | No de-duplication is done by them; the onus is on the calling function to do |
372 | so. The caller must first do a lookup via ctf_dtd_lookup or |
373 | ctf_dvd_lookup, as applicable, to ascertain that the CTF type or the CTF |
374 | variable respectively does not already exist, and then add it. */ |
375 | |
376 | static ctf_id_t |
377 | ctf_add_generic (ctf_container_ref ctfc, uint32_t flag, const char * name, |
378 | ctf_dtdef_ref * rp, dw_die_ref die) |
379 | { |
380 | ctf_dtdef_ref dtd; |
381 | ctf_id_t type; |
382 | |
383 | gcc_assert (flag == CTF_ADD_NONROOT || flag == CTF_ADD_ROOT); |
384 | |
385 | dtd = ggc_cleared_alloc<ctf_dtdef_t> (); |
386 | |
387 | type = ctfc->ctfc_nextid++; |
388 | gcc_assert (type < CTF_MAX_TYPE); /* CTF type ID overflow. */ |
389 | |
390 | /* Buffer the strings in the CTF string table. */ |
391 | dtd->dtd_name = ctf_add_string (ctfc, name, name_offset: &(dtd->dtd_data.ctti_name)); |
392 | dtd->dtd_type = type; |
393 | dtd->dtd_key = die; |
394 | |
395 | if ((name != NULL) && strcmp (s1: name, s2: "" )) |
396 | ctfc->ctfc_strlen += strlen (s: name) + 1; |
397 | |
398 | ctf_dtd_insert (ctfc, dtd); |
399 | |
400 | *rp = dtd; |
401 | return type; |
402 | } |
403 | |
404 | static ctf_id_t |
405 | ctf_add_encoded (ctf_container_ref ctfc, uint32_t flag, const char * name, |
406 | const ctf_encoding_t * ep, uint32_t kind, dw_die_ref die) |
407 | { |
408 | ctf_dtdef_ref dtd; |
409 | ctf_id_t type; |
410 | |
411 | type = ctf_add_generic (ctfc, flag, name, rp: &dtd, die); |
412 | |
413 | dtd->dtd_data.ctti_info = CTF_TYPE_INFO (kind, flag, 0); |
414 | |
415 | uint32_t roundup_nbytes = (ROUND_UP (ep->cte_bits, BITS_PER_UNIT) |
416 | / BITS_PER_UNIT); |
417 | |
418 | /* FIXME, stay close to what libctf does. But by getting next power of two, |
419 | aren't we conveying less precise information. E.g. floating point mode |
420 | XF has a size of 12 bytes. */ |
421 | dtd->dtd_data.ctti_size = roundup_nbytes ? (1 << ceil_log2 (x: roundup_nbytes)) |
422 | : roundup_nbytes; |
423 | dtd->dtd_u.dtu_enc = *ep; |
424 | |
425 | ctfc->ctfc_num_stypes++; |
426 | |
427 | return type; |
428 | } |
429 | |
430 | ctf_id_t |
431 | ctf_add_reftype (ctf_container_ref ctfc, uint32_t flag, ctf_id_t ref, |
432 | uint32_t kind, dw_die_ref die) |
433 | { |
434 | ctf_dtdef_ref dtd; |
435 | ctf_id_t type; |
436 | |
437 | gcc_assert (ref <= CTF_MAX_TYPE); |
438 | |
439 | type = ctf_add_generic (ctfc, flag, NULL, rp: &dtd, die); |
440 | dtd->dtd_data.ctti_info = CTF_TYPE_INFO (kind, flag, 0); |
441 | /* Caller of this API must guarantee that a CTF type with id = ref already |
442 | exists. This will also be validated for us at link-time. */ |
443 | dtd->dtd_data.ctti_type = (uint32_t) ref; |
444 | |
445 | ctfc->ctfc_num_stypes++; |
446 | |
447 | return type; |
448 | } |
449 | |
450 | ctf_id_t |
451 | ctf_add_forward (ctf_container_ref ctfc, uint32_t flag, const char * name, |
452 | uint32_t kind, dw_die_ref die) |
453 | { |
454 | ctf_dtdef_ref dtd; |
455 | ctf_id_t type = 0; |
456 | |
457 | type = ctf_add_generic (ctfc, flag, name, rp: &dtd, die); |
458 | |
459 | dtd->dtd_data.ctti_info = CTF_TYPE_INFO (CTF_K_FORWARD, flag, 0); |
460 | dtd->dtd_data.ctti_type = kind; |
461 | |
462 | ctfc->ctfc_num_stypes++; |
463 | |
464 | return type; |
465 | } |
466 | |
467 | ctf_id_t |
468 | ctf_add_typedef (ctf_container_ref ctfc, uint32_t flag, const char * name, |
469 | ctf_id_t ref, dw_die_ref die) |
470 | { |
471 | ctf_dtdef_ref dtd; |
472 | ctf_id_t type; |
473 | |
474 | gcc_assert (ref <= CTF_MAX_TYPE); |
475 | /* Nameless Typedefs are not expected. */ |
476 | gcc_assert ((name != NULL) && strcmp (name, "" )); |
477 | |
478 | type = ctf_add_generic (ctfc, flag, name, rp: &dtd, die); |
479 | dtd->dtd_data.ctti_info = CTF_TYPE_INFO (CTF_K_TYPEDEF, flag, 0); |
480 | /* Caller of this API must guarantee that a CTF type with id = ref already |
481 | exists. This will also be validated for us at link-time. */ |
482 | dtd->dtd_data.ctti_type = (uint32_t) ref; |
483 | |
484 | gcc_assert (dtd->dtd_type != dtd->dtd_data.ctti_type); |
485 | |
486 | ctfc->ctfc_num_stypes++; |
487 | |
488 | return type; |
489 | } |
490 | |
491 | ctf_id_t |
492 | ctf_add_slice (ctf_container_ref ctfc, uint32_t flag, ctf_id_t ref, |
493 | uint32_t bit_offset, uint32_t bit_size, dw_die_ref die) |
494 | { |
495 | ctf_dtdef_ref dtd; |
496 | ctf_id_t type; |
497 | uint32_t roundup_nbytes; |
498 | |
499 | gcc_assert ((bit_size <= 255) && (bit_offset <= 255)); |
500 | |
501 | gcc_assert (ref <= CTF_MAX_TYPE); |
502 | |
503 | type = ctf_add_generic (ctfc, flag, NULL, rp: &dtd, die); |
504 | |
505 | dtd->dtd_data.ctti_info = CTF_TYPE_INFO (CTF_K_SLICE, flag, 0); |
506 | |
507 | roundup_nbytes = (ROUND_UP (bit_size, BITS_PER_UNIT) / BITS_PER_UNIT); |
508 | /* FIXME, stay close to what libctf does. But by getting next power of two, |
509 | aren't we conveying less precise information, especially for bitfields. |
510 | For example, cte_bits = 33, roundup_nbytes = 5, ctti_size = 8 in the |
511 | implementation below. */ |
512 | dtd->dtd_data.ctti_size = roundup_nbytes ? (1 << ceil_log2 (x: roundup_nbytes)) |
513 | : 0; |
514 | |
515 | /* Caller of this API must guarantee that a CTF type with id = ref already |
516 | exists. This will also be validated for us at link-time. */ |
517 | dtd->dtd_u.dtu_slice.cts_type = (uint32_t) ref; |
518 | dtd->dtd_u.dtu_slice.cts_bits = bit_size; |
519 | dtd->dtd_u.dtu_slice.cts_offset = bit_offset; |
520 | |
521 | ctfc->ctfc_num_stypes++; |
522 | |
523 | return type; |
524 | } |
525 | |
526 | ctf_id_t |
527 | ctf_add_float (ctf_container_ref ctfc, uint32_t flag, |
528 | const char * name, const ctf_encoding_t * ep, dw_die_ref die) |
529 | { |
530 | return (ctf_add_encoded (ctfc, flag, name, ep, CTF_K_FLOAT, die)); |
531 | } |
532 | |
533 | ctf_id_t |
534 | ctf_add_integer (ctf_container_ref ctfc, uint32_t flag, |
535 | const char * name, const ctf_encoding_t * ep, dw_die_ref die) |
536 | { |
537 | return (ctf_add_encoded (ctfc, flag, name, ep, CTF_K_INTEGER, die)); |
538 | } |
539 | |
540 | ctf_id_t |
541 | ctf_add_unknown (ctf_container_ref ctfc, uint32_t flag, |
542 | const char * name, const ctf_encoding_t * ep, dw_die_ref die) |
543 | { |
544 | return (ctf_add_encoded (ctfc, flag, name, ep, CTF_K_UNKNOWN, die)); |
545 | } |
546 | |
547 | ctf_id_t |
548 | ctf_add_pointer (ctf_container_ref ctfc, uint32_t flag, ctf_id_t ref, |
549 | dw_die_ref die) |
550 | { |
551 | return (ctf_add_reftype (ctfc, flag, ref, CTF_K_POINTER, die)); |
552 | } |
553 | |
554 | ctf_id_t |
555 | ctf_add_array (ctf_container_ref ctfc, uint32_t flag, const ctf_arinfo_t * arp, |
556 | dw_die_ref die) |
557 | { |
558 | ctf_dtdef_ref dtd; |
559 | ctf_id_t type; |
560 | |
561 | gcc_assert (arp); |
562 | |
563 | /* Caller of this API must make sure CTF type for arp->ctr_contents and |
564 | arp->ctr_index are already added. This will also be validated for us at |
565 | link-time. */ |
566 | |
567 | type = ctf_add_generic (ctfc, flag, NULL, rp: &dtd, die); |
568 | |
569 | dtd->dtd_data.ctti_info = CTF_TYPE_INFO (CTF_K_ARRAY, flag, 0); |
570 | dtd->dtd_data.ctti_size = 0; |
571 | dtd->dtd_u.dtu_arr = *arp; |
572 | |
573 | ctfc->ctfc_num_stypes++; |
574 | |
575 | return type; |
576 | } |
577 | |
578 | ctf_id_t |
579 | ctf_add_enum (ctf_container_ref ctfc, uint32_t flag, const char * name, |
580 | HOST_WIDE_INT size, bool eunsigned, dw_die_ref die) |
581 | { |
582 | ctf_dtdef_ref dtd; |
583 | ctf_id_t type; |
584 | |
585 | /* In the compiler, no need to handle the case of promoting forwards to |
586 | enums. This comment is simply to note a divergence from libctf. */ |
587 | |
588 | /* The compiler does, however, update any previously existing forward types |
589 | to non-root. CTF does not allow existence of two root types with the same |
590 | name. */ |
591 | ctf_dtdef_ref enum_fwd_type = ctf_dtd_lookup (ctfc, type: die); |
592 | if (enum_fwd_type) |
593 | { |
594 | enum_fwd_type->dtd_data.ctti_info |
595 | = CTF_TYPE_INFO (CTF_K_FORWARD, CTF_ADD_NONROOT, 0); |
596 | } |
597 | |
598 | type = ctf_add_generic (ctfc, flag, name, rp: &dtd, die); |
599 | |
600 | dtd->dtd_data.ctti_info = CTF_TYPE_INFO (CTF_K_ENUM, flag, 0); |
601 | |
602 | /* Size in bytes should always fit, of course. |
603 | TBD WARN - warn instead? */ |
604 | gcc_assert (size <= CTF_MAX_SIZE); |
605 | |
606 | dtd->dtd_data.ctti_size = size; |
607 | dtd->dtd_enum_unsigned = eunsigned; |
608 | |
609 | ctfc->ctfc_num_stypes++; |
610 | |
611 | return type; |
612 | } |
613 | |
614 | int |
615 | ctf_add_enumerator (ctf_container_ref ctfc, ctf_id_t enid, const char * name, |
616 | HOST_WIDE_INT value, dw_die_ref die) |
617 | { |
618 | ctf_dmdef_t * dmd; |
619 | uint32_t kind, vlen, root; |
620 | |
621 | /* Callers of this API must make sure that CTF_K_ENUM with enid has been |
622 | addded. This will also be validated for us at link-time. */ |
623 | ctf_dtdef_ref dtd = ctf_dtd_lookup (ctfc, type: die); |
624 | gcc_assert (dtd); |
625 | gcc_assert (dtd->dtd_type == enid); |
626 | gcc_assert (name); |
627 | |
628 | kind = CTF_V2_INFO_KIND (dtd->dtd_data.ctti_info); |
629 | root = CTF_V2_INFO_ISROOT (dtd->dtd_data.ctti_info); |
630 | vlen = CTF_V2_INFO_VLEN (dtd->dtd_data.ctti_info); |
631 | |
632 | gcc_assert (kind == CTF_K_ENUM && vlen < CTF_MAX_VLEN); |
633 | |
634 | /* Enum value is of type HOST_WIDE_INT in the compiler, CTF enumerators |
635 | values in ctf_enum_t is limited to int32_t, BTF supports signed and |
636 | unsigned enumerators values of 32 and 64 bits, for both debug formats |
637 | we use ctf_dmdef_t.dmd_value entry of HOST_WIDE_INT type. So check |
638 | CTF bounds and skip adding this enum value if out of bounds. */ |
639 | if (!btf_debuginfo_p() && ((value > INT_MAX) || (value < INT_MIN))) |
640 | { |
641 | /* FIXME - Note this TBD_CTF_REPRESENTATION_LIMIT. */ |
642 | return (1); |
643 | } |
644 | |
645 | dmd = ggc_cleared_alloc<ctf_dmdef_t> (); |
646 | |
647 | /* Buffer the strings in the CTF string table. */ |
648 | dmd->dmd_name = ctf_add_string (ctfc, name, name_offset: &(dmd->dmd_name_offset)); |
649 | dmd->dmd_type = CTF_NULL_TYPEID; |
650 | dmd->dmd_offset = 0; |
651 | |
652 | dmd->dmd_value = value; |
653 | |
654 | dtd->dtd_data.ctti_info = CTF_TYPE_INFO (kind, root, vlen + 1); |
655 | ctf_dmd_list_append (dmd: &dtd->dtd_u.dtu_members, elem: dmd); |
656 | |
657 | if ((name != NULL) && strcmp (s1: name, s2: "" )) |
658 | ctfc->ctfc_strlen += strlen (s: name) + 1; |
659 | |
660 | return (0); |
661 | } |
662 | |
663 | int |
664 | ctf_add_member_offset (ctf_container_ref ctfc, dw_die_ref sou, |
665 | const char * name, ctf_id_t type, |
666 | uint64_t bit_offset) |
667 | { |
668 | ctf_dtdef_ref dtd = ctf_dtd_lookup (ctfc, type: sou); |
669 | ctf_dmdef_t * dmd; |
670 | |
671 | uint32_t kind, vlen, root; |
672 | |
673 | /* The type of the member being added must already exist. */ |
674 | gcc_assert (dtd); |
675 | |
676 | kind = CTF_V2_INFO_KIND (dtd->dtd_data.ctti_info); |
677 | root = CTF_V2_INFO_ISROOT (dtd->dtd_data.ctti_info); |
678 | vlen = CTF_V2_INFO_VLEN (dtd->dtd_data.ctti_info); |
679 | |
680 | gcc_assert (kind == CTF_K_STRUCT || kind == CTF_K_UNION); |
681 | gcc_assert (vlen < CTF_MAX_VLEN); |
682 | |
683 | dmd = ggc_cleared_alloc<ctf_dmdef_t> (); |
684 | |
685 | /* Buffer the strings in the CTF string table. */ |
686 | dmd->dmd_name = ctf_add_string (ctfc, name, name_offset: &(dmd->dmd_name_offset)); |
687 | dmd->dmd_type = type; |
688 | dmd->dmd_value = -1; |
689 | |
690 | if (kind == CTF_K_STRUCT && vlen != 0) |
691 | dmd->dmd_offset = bit_offset; |
692 | else |
693 | dmd->dmd_offset = 0; |
694 | |
695 | dtd->dtd_data.ctti_info = CTF_TYPE_INFO (kind, root, vlen + 1); |
696 | ctf_dmd_list_append (dmd: &dtd->dtd_u.dtu_members, elem: dmd); |
697 | |
698 | if ((name != NULL) && strcmp (s1: name, s2: "" )) |
699 | ctfc->ctfc_strlen += strlen (s: name) + 1; |
700 | |
701 | return 0; |
702 | } |
703 | |
704 | int |
705 | ctf_add_variable (ctf_container_ref ctfc, const char * name, ctf_id_t ref, |
706 | dw_die_ref die, unsigned int external_vis, |
707 | dw_die_ref die_var_decl) |
708 | { |
709 | ctf_dvdef_ref dvd, dvd_ignore; |
710 | |
711 | gcc_assert (name); |
712 | |
713 | if (name != NULL) |
714 | { |
715 | dvd = ggc_cleared_alloc<ctf_dvdef_t> (); |
716 | dvd->dvd_key = die; |
717 | /* Buffer the strings in the CTF string table. */ |
718 | dvd->dvd_name = ctf_add_string (ctfc, name, name_offset: &(dvd->dvd_name_offset)); |
719 | dvd->dvd_visibility = external_vis; |
720 | dvd->dvd_type = ref; |
721 | |
722 | /* If DW_AT_specification attribute exists, keep track of it as this is |
723 | the non-defining declaration corresponding to the variable. We will |
724 | skip emitting CTF variable for such incomplete, non-defining |
725 | declarations. |
726 | There could be some non-defining declarations, however, for which a |
727 | defining declaration does not show up in the same CU. For such |
728 | cases, the compiler continues to emit CTF variable record as |
729 | usual. */ |
730 | if (die_var_decl) |
731 | { |
732 | dvd_ignore = ggc_cleared_alloc<ctf_dvdef_t> (); |
733 | dvd_ignore->dvd_key = die_var_decl; |
734 | /* It's alright to leave other fields as zero. No valid CTF |
735 | variable will be added for these DW_TAG_variable DIEs. */ |
736 | ctf_dvd_ignore_insert (ctfc, dvd: dvd_ignore); |
737 | } |
738 | |
739 | ctf_dvd_insert (ctfc, dvd); |
740 | |
741 | if (strcmp (s1: name, s2: "" )) |
742 | ctfc->ctfc_strlen += strlen (s: name) + 1; |
743 | } |
744 | |
745 | return 0; |
746 | } |
747 | |
748 | int |
749 | ctf_add_function_arg (ctf_container_ref ctfc, dw_die_ref func, |
750 | const char * name, ctf_id_t type) |
751 | { |
752 | ctf_dtdef_ref dtd = ctf_dtd_lookup (ctfc, type: func); |
753 | ctf_func_arg_t * farg; |
754 | uint32_t vlen; |
755 | |
756 | /* The function to which argument is being added must already exist. */ |
757 | gcc_assert (dtd); |
758 | /* The number of args must have been non-zero. */ |
759 | vlen = CTF_V2_INFO_VLEN (dtd->dtd_data.ctti_info); |
760 | gcc_assert (vlen); |
761 | |
762 | farg = ggc_cleared_alloc<ctf_func_arg_t> (); |
763 | |
764 | /* Buffer the strings in the auxilliary string table. CTF V3 format does not |
765 | require function argument names. Use auxilliary string table to keep |
766 | these strings to avoid unnecessary bloat in CTF section in CTF V3. */ |
767 | farg->farg_name = ctf_add_string (ctfc, name, name_offset: &(farg->farg_name_offset), |
768 | CTF_AUX_STRTAB); |
769 | farg->farg_type = type; |
770 | |
771 | ctf_farg_list_append (farg: &dtd->dtd_u.dtu_argv, elem: farg); |
772 | |
773 | /* For aux_str, keep ctfc_aux_strlen updated for debugging. */ |
774 | if ((name != NULL) && strcmp (s1: name, s2: "" )) |
775 | ctfc->ctfc_aux_strlen += strlen (s: name) + 1; |
776 | |
777 | return 0; |
778 | } |
779 | |
780 | ctf_id_t |
781 | ctf_add_function (ctf_container_ref ctfc, uint32_t flag, const char * name, |
782 | const ctf_funcinfo_t * ctc, dw_die_ref die, |
783 | bool from_global_func, int linkage) |
784 | { |
785 | ctf_dtdef_ref dtd; |
786 | ctf_id_t type; |
787 | uint32_t vlen; |
788 | |
789 | gcc_assert (ctc); |
790 | |
791 | vlen = ctc->ctc_argc; |
792 | gcc_assert (vlen <= CTF_MAX_VLEN); |
793 | |
794 | type = ctf_add_generic (ctfc, flag, name, rp: &dtd, die); |
795 | |
796 | dtd->from_global_func = from_global_func; |
797 | dtd->linkage = linkage; |
798 | dtd->dtd_data.ctti_info = CTF_TYPE_INFO (CTF_K_FUNCTION, flag, vlen); |
799 | /* Caller must make sure CTF types for ctc->ctc_return are already added. */ |
800 | dtd->dtd_data.ctti_type = (uint32_t) ctc->ctc_return; |
801 | /* Caller must make sure CTF types for function arguments are already added |
802 | via ctf_add_function_arg () API. */ |
803 | |
804 | ctfc->ctfc_num_stypes++; |
805 | |
806 | return type; |
807 | } |
808 | |
809 | ctf_id_t |
810 | ctf_add_sou (ctf_container_ref ctfc, uint32_t flag, const char * name, |
811 | uint32_t kind, size_t size, dw_die_ref die) |
812 | { |
813 | ctf_dtdef_ref dtd; |
814 | ctf_id_t type = 0; |
815 | |
816 | gcc_assert ((kind == CTF_K_STRUCT) || (kind == CTF_K_UNION)); |
817 | |
818 | /* In the compiler, no need to handle the case of promoting forwards to |
819 | structs. This comment is simply to note a divergence from libctf. */ |
820 | |
821 | /* The compiler does, however, update any previously existing forward types |
822 | to non-root. CTF does not allow existence of two root types with the same |
823 | name. */ |
824 | ctf_dtdef_ref sou_fwd_type = ctf_dtd_lookup (ctfc, type: die); |
825 | if (sou_fwd_type) |
826 | { |
827 | sou_fwd_type->dtd_data.ctti_info |
828 | = CTF_TYPE_INFO (CTF_K_FORWARD, CTF_ADD_NONROOT, 0); |
829 | } |
830 | |
831 | type = ctf_add_generic (ctfc, flag, name, rp: &dtd, die); |
832 | |
833 | dtd->dtd_data.ctti_info = CTF_TYPE_INFO (kind, flag, 0); |
834 | |
835 | if (size > CTF_MAX_SIZE) |
836 | { |
837 | dtd->dtd_data.ctti_size = CTF_LSIZE_SENT; |
838 | dtd->dtd_data.ctti_lsizehi = CTF_SIZE_TO_LSIZE_HI (size); |
839 | dtd->dtd_data.ctti_lsizelo = CTF_SIZE_TO_LSIZE_LO (size); |
840 | ctfc->ctfc_num_types++; |
841 | } |
842 | else |
843 | { |
844 | dtd->dtd_data.ctti_size = (uint32_t) size; |
845 | ctfc->ctfc_num_stypes++; |
846 | } |
847 | |
848 | return type; |
849 | } |
850 | |
851 | /* Given a TREE_TYPE node, return the CTF type ID for that type. */ |
852 | |
853 | ctf_id_t |
854 | ctf_lookup_tree_type (ctf_container_ref ctfc, const tree type) |
855 | { |
856 | dw_die_ref die = lookup_type_die (type); |
857 | if (die == NULL) |
858 | return CTF_NULL_TYPEID; |
859 | |
860 | ctf_dtdef_ref dtd = ctf_dtd_lookup (ctfc, type: die); |
861 | if (dtd == NULL) |
862 | return CTF_NULL_TYPEID; |
863 | |
864 | return dtd->dtd_type; |
865 | } |
866 | |
867 | /* Check if CTF for TYPE has already been generated. Mainstay for |
868 | de-duplication. If CTF type already exists, returns TRUE and updates |
869 | the TYPE_ID for the caller. */ |
870 | |
871 | bool |
872 | ctf_type_exists (ctf_container_ref ctfc, dw_die_ref type, |
873 | ctf_id_t * type_id) |
874 | { |
875 | bool exists = false; |
876 | ctf_dtdef_ref ctf_type_seen = ctf_dtd_lookup (ctfc, type); |
877 | |
878 | if (ctf_type_seen) |
879 | { |
880 | exists = true; |
881 | /* CTF type for this type exists. */ |
882 | *type_id = ctf_type_seen->dtd_type; |
883 | } |
884 | |
885 | return exists; |
886 | } |
887 | |
888 | /* Location information for CTF Types and CTF Variables. CTF section does not |
889 | emit location information; at this time, location information is needed for |
890 | BTF CO-RE use-cases. */ |
891 | |
892 | int |
893 | ctfc_get_dtd_srcloc (ctf_dtdef_ref dtd, ctf_srcloc_ref loc) |
894 | { |
895 | loc->ctsloc_file = ctf_get_die_loc_file (dtd->dtd_key); |
896 | loc->ctsloc_line = ctf_get_die_loc_line (dtd->dtd_key); |
897 | loc->ctsloc_col = ctf_get_die_loc_col (dtd->dtd_key); |
898 | |
899 | if (loc->ctsloc_file == NULL) |
900 | return 1; |
901 | |
902 | return 0; |
903 | } |
904 | |
905 | int |
906 | ctfc_get_dvd_srcloc (ctf_dvdef_ref dvd, ctf_srcloc_ref loc) |
907 | { |
908 | loc->ctsloc_file = ctf_get_die_loc_file (dvd->dvd_key); |
909 | loc->ctsloc_line = ctf_get_die_loc_line (dvd->dvd_key); |
910 | loc->ctsloc_col = ctf_get_die_loc_col (dvd->dvd_key); |
911 | |
912 | if (loc->ctsloc_file == NULL) |
913 | return 1; |
914 | |
915 | return 0; |
916 | } |
917 | |
918 | /* CTF container setup and teardown routines. */ |
919 | |
920 | /* Initialize the CTF string table. |
921 | The first entry in the CTF string table (empty string) is added. */ |
922 | |
923 | static void |
924 | init_ctf_strtable (ctf_strtable_t * strtab) |
925 | { |
926 | strtab->ctstab_head = NULL; |
927 | strtab->ctstab_tail = NULL; |
928 | strtab->ctstab_num = 0; |
929 | strtab->ctstab_len = 0; |
930 | |
931 | /* The first entry in the CTF string table is an empty string. E.g., CTF |
932 | type records with no name (like CTF_K_CONST, CTF_K_VOLATILE etc) point to |
933 | this string. */ |
934 | uint32_t estr_offset = 0; |
935 | strtab->ctstab_estr = ctfc_strtable_add_str (str_table: strtab, name: "" , name_offset: &estr_offset); |
936 | } |
937 | |
938 | /* Initialize the string tables in the CTF container. */ |
939 | |
940 | static void |
941 | init_ctf_string_table (ctf_container_ref ctfc) |
942 | { |
943 | init_ctf_strtable (strtab: &ctfc->ctfc_strtable); |
944 | ctfc->ctfc_strlen++; |
945 | |
946 | init_ctf_strtable (strtab: &ctfc->ctfc_aux_strtable); |
947 | ctfc->ctfc_aux_strlen++; |
948 | } |
949 | |
950 | /* Allocate a new CTF container with the desired flags. */ |
951 | |
952 | static inline ctf_container_ref |
953 | new_ctf_container (void) |
954 | { |
955 | tu_ctfc = ggc_cleared_alloc<ctf_container_t> (); |
956 | tu_ctfc->ctfc_types |
957 | = hash_table<ctfc_dtd_hasher>::create_ggc (n: 100); |
958 | tu_ctfc->ctfc_vars |
959 | = hash_table<ctfc_dvd_hasher>::create_ggc (n: 100); |
960 | tu_ctfc->ctfc_ignore_vars |
961 | = hash_table<ctfc_dvd_hasher>::create_ggc (n: 10); |
962 | |
963 | return tu_ctfc; |
964 | } |
965 | |
966 | /* Initialize a CTF container per translation unit. */ |
967 | |
968 | static void |
969 | init_ctf_container (void) |
970 | { |
971 | tu_ctfc = new_ctf_container (); |
972 | |
973 | tu_ctfc->ctfc_magic = CTF_MAGIC; |
974 | tu_ctfc->ctfc_version = CTF_VERSION; |
975 | tu_ctfc->ctfc_flags = CTF_F_NEWFUNCINFO; |
976 | tu_ctfc->ctfc_nextid = CTF_INIT_TYPEID; |
977 | |
978 | init_ctf_string_table (ctfc: tu_ctfc); |
979 | } |
980 | |
981 | void |
982 | ctfc_delete_strtab (ctf_strtable_t * strtab) |
983 | { |
984 | ctf_string_t * str = NULL; |
985 | ctf_string_t * next_str = NULL; |
986 | |
987 | str = strtab->ctstab_head; |
988 | next_str = str; |
989 | while (next_str != NULL) |
990 | { |
991 | next_str = str->cts_next; |
992 | ggc_free (str); |
993 | str = next_str; |
994 | } |
995 | |
996 | strtab->ctstab_head = NULL; |
997 | strtab->ctstab_tail = NULL; |
998 | strtab->ctstab_estr = NULL; |
999 | } |
1000 | |
1001 | /* Delete the CTF container's resources. */ |
1002 | |
1003 | void |
1004 | ctfc_delete_container (ctf_container_ref ctfc) |
1005 | { |
1006 | if (ctfc) |
1007 | { |
1008 | ctfc->ctfc_types->empty (); |
1009 | ctfc->ctfc_types = NULL; |
1010 | |
1011 | ctfc->ctfc_vars->empty (); |
1012 | ctfc->ctfc_types = NULL; |
1013 | |
1014 | ctfc->ctfc_ignore_vars->empty (); |
1015 | ctfc->ctfc_ignore_vars = NULL; |
1016 | |
1017 | ctfc_delete_strtab (strtab: &ctfc->ctfc_strtable); |
1018 | ctfc_delete_strtab (strtab: &ctfc->ctfc_aux_strtable); |
1019 | if (ctfc->ctfc_vars_list) |
1020 | { |
1021 | ggc_free (ctfc->ctfc_vars_list); |
1022 | ctfc->ctfc_vars_list = NULL; |
1023 | } |
1024 | if (ctfc->ctfc_types_list) |
1025 | { |
1026 | ggc_free (ctfc->ctfc_types_list); |
1027 | ctfc->ctfc_types_list = NULL; |
1028 | } |
1029 | if (ctfc->ctfc_gfuncs_list) |
1030 | { |
1031 | ggc_free (ctfc->ctfc_gfuncs_list); |
1032 | ctfc->ctfc_gfuncs_list = NULL; |
1033 | } |
1034 | if (ctfc->ctfc_gobjts_list) |
1035 | { |
1036 | ggc_free (ctfc->ctfc_gobjts_list); |
1037 | ctfc->ctfc_gobjts_list = NULL; |
1038 | } |
1039 | |
1040 | ctfc= NULL; |
1041 | } |
1042 | } |
1043 | |
1044 | /* CTF routines interfacing to the compiler. */ |
1045 | |
1046 | void |
1047 | ctf_init (void) |
1048 | { |
1049 | init_ctf_container (); |
1050 | } |
1051 | |