Line data Source code
1 : /* Output CTF format from GCC.
2 : Copyright (C) 2019-2026 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 "memmodel.h"
25 : #include "tm_p.h"
26 : #include "output.h"
27 : #include "dwarf2asm.h"
28 : #include "debug.h"
29 : #include "ctfc.h"
30 : #include "diagnostic-core.h"
31 :
32 : static int ctf_label_num;
33 :
34 : /* Pointers to various CTF sections. */
35 :
36 : static GTY (()) section * ctf_info_section;
37 :
38 : /* Section names used to hold CTF debugging information. */
39 :
40 : /* CTF debug info section. */
41 :
42 : #ifndef CTF_INFO_SECTION_NAME
43 : #define CTF_INFO_SECTION_NAME ".ctf"
44 : #endif
45 :
46 : /* Section flags for the CTF debug info section. */
47 :
48 : #define CTF_INFO_SECTION_FLAGS (SECTION_DEBUG)
49 :
50 : /* Maximum size (in bytes) of an artificially generated CTF label. */
51 :
52 : #define MAX_CTF_LABEL_BYTES 40
53 :
54 : static char ctf_info_section_label[MAX_CTF_LABEL_BYTES];
55 :
56 : #ifndef CTF_INFO_SECTION_LABEL
57 : #define CTF_INFO_SECTION_LABEL "Lctf"
58 : #endif
59 :
60 : /* CTF preprocess callback arguments. */
61 :
62 : typedef struct ctf_dtd_preprocess_arg
63 : {
64 : uint64_t dtd_global_func_idx;
65 : ctf_container_ref dtd_arg_ctfc;
66 : } ctf_dtd_preprocess_arg_t;
67 :
68 : typedef struct ctf_dvd_preprocess_arg
69 : {
70 : uint64_t dvd_global_obj_idx;
71 : ctf_container_ref dvd_arg_ctfc;
72 : } ctf_dvd_preprocess_arg_t;
73 :
74 : /* Compare two CTF variable definition entries. Currently used for sorting
75 : by name. */
76 :
77 : static int
78 749 : ctf_varent_compare (const void * entry1, const void * entry2)
79 : {
80 749 : int result;
81 749 : const ctf_dvdef_t * e1 = *(const ctf_dvdef_t * const*) entry1;
82 749 : const ctf_dvdef_t * e2 = *(const ctf_dvdef_t * const*) entry2;
83 :
84 749 : result = strcmp (e1->dvd_name, e2->dvd_name);
85 :
86 749 : return result;
87 : }
88 :
89 : /* A CTF type record may be followed by variable-length of bytes to encode the
90 : CTF type completely. This routine calculates the number of bytes, in the
91 : final binary CTF format, which are used to encode information about the type
92 : completely.
93 :
94 : This function must always be in sync with the CTF header. */
95 :
96 : static uint64_t
97 1035 : ctf_calc_num_vbytes (ctf_dtdef_ref ctftype)
98 : {
99 1035 : uint32_t size;
100 1035 : uint64_t vlen_bytes = 0;
101 :
102 1035 : uint32_t kind = CTF_V2_INFO_KIND (ctftype->dtd_data.ctti_info);
103 1035 : uint32_t vlen = CTF_V2_INFO_VLEN (ctftype->dtd_data.ctti_info);
104 :
105 1035 : ctf_dmdef_t * dmd;
106 1035 : ctf_func_arg_t * farg;
107 1035 : uint32_t size_per_member = 0;
108 1035 : unsigned int num_members = 0;
109 1035 : unsigned int num_fargs = 0;
110 :
111 1035 : switch (kind)
112 : {
113 : case CTF_K_FORWARD:
114 : case CTF_K_UNKNOWN:
115 : case CTF_K_POINTER:
116 : case CTF_K_TYPEDEF:
117 : case CTF_K_VOLATILE:
118 : case CTF_K_CONST:
119 : case CTF_K_RESTRICT:
120 : /* These types have no vlen data. */
121 : break;
122 :
123 400 : case CTF_K_INTEGER:
124 400 : case CTF_K_FLOAT:
125 : /* 4 bytes to represent encoding CTF_INT_DATA, CTF_FP_DATA. */
126 400 : vlen_bytes += sizeof (uint32_t);
127 400 : break;
128 265 : case CTF_K_FUNCTION:
129 : /* Sanity check - number of function args must be the same as
130 : vlen. */
131 265 : for (farg = ctftype->dtd_u.dtu_argv;
132 375 : farg != NULL; farg = (ctf_func_arg_t *) ctf_farg_list_next (farg))
133 110 : num_fargs++;
134 265 : gcc_assert (vlen == num_fargs);
135 :
136 : /* FIXME - CTF_PADDING_FOR_ALIGNMENT. */
137 265 : vlen_bytes += (vlen + (vlen & 1)) * sizeof (uint32_t);
138 265 : break;
139 70 : case CTF_K_ARRAY:
140 : /* This has a single ctf_array_t. */
141 70 : vlen_bytes += sizeof (ctf_array_t);
142 70 : break;
143 13 : case CTF_K_SLICE:
144 13 : vlen_bytes += sizeof (ctf_slice_t);
145 13 : break;
146 74 : case CTF_K_STRUCT:
147 74 : case CTF_K_UNION:
148 : /* Count the number and type of members. */
149 74 : size = ctftype->dtd_data.ctti_size;
150 74 : size_per_member = size >= CTF_LSTRUCT_THRESH
151 : ? sizeof (ctf_lmember_t) : sizeof (ctf_member_t);
152 :
153 : /* Sanity check - number of members of struct must be the same as
154 : vlen. */
155 74 : for (dmd = ctftype->dtd_u.dtu_members;
156 227 : dmd != NULL; dmd = (ctf_dmdef_t *) ctf_dmd_list_next (dmd))
157 153 : num_members++;
158 74 : gcc_assert (vlen == num_members);
159 :
160 74 : vlen_bytes += (num_members * size_per_member);
161 74 : break;
162 6 : case CTF_K_ENUM:
163 6 : vlen_bytes += vlen * sizeof (ctf_enum_t);
164 6 : break;
165 : default :
166 : break;
167 : }
168 1035 : return vlen_bytes;
169 : }
170 :
171 : /* Add a CTF variable to the end of the list. */
172 :
173 : static void
174 171 : ctf_list_add_ctf_vars (ctf_container_ref ctfc, ctf_dvdef_ref var)
175 : {
176 171 : ctfc->ctfc_vars_list[ctfc->ctfc_vars_list_count++] = var;
177 0 : }
178 :
179 : /* Initialize the various sections and labels for CTF output. */
180 :
181 : void
182 219 : init_ctf_sections (void)
183 : {
184 : /* Note : Even in case of LTO, the compiler continues to generate a single
185 : CTF section for each compilation unit "early". Unlike other debug
186 : sections, CTF sections are non-LTO sections, and do not take the
187 : .gnu.debuglto_ prefix. The linker will de-duplicate the types in the CTF
188 : sections, in case of LTO or otherwise. */
189 219 : ctf_info_section = get_section (CTF_INFO_SECTION_NAME, CTF_INFO_SECTION_FLAGS,
190 : NULL);
191 :
192 219 : ASM_GENERATE_INTERNAL_LABEL (ctf_info_section_label,
193 : CTF_INFO_SECTION_LABEL, ctf_label_num++);
194 219 : }
195 :
196 : /* Routines for CTF pre-processing. */
197 :
198 : static void
199 171 : ctf_preprocess_var (ctf_container_ref ctfc, ctf_dvdef_ref var)
200 : {
201 : /* Add it to the list of types. This array of types will be sorted before
202 : assembling into output. */
203 171 : ctf_list_add_ctf_vars (ctfc, var);
204 0 : }
205 :
206 : /* CTF preprocess callback routine for CTF variables. */
207 :
208 : int
209 172 : ctf_dvd_preprocess_cb (ctf_dvdef_ref * slot, void * arg)
210 : {
211 172 : ctf_dvd_preprocess_arg_t * dvd_arg = (ctf_dvd_preprocess_arg_t *)arg;
212 172 : ctf_dvdef_ref var = (ctf_dvdef_ref) *slot;
213 172 : ctf_container_ref arg_ctfc = dvd_arg->dvd_arg_ctfc;
214 :
215 : /* If the CTF variable corresponds to an extern variable declaration with
216 : a defining declaration later on, skip it. Only CTF variable
217 : corresponding to the defining declaration for the extern variable is
218 : desirable. */
219 172 : if (ctf_dvd_ignore_lookup (arg_ctfc, var->dvd_key))
220 : return 1;
221 :
222 171 : ctf_preprocess_var (arg_ctfc, var);
223 :
224 : /* Keep track of global objts. */
225 171 : arg_ctfc->ctfc_gobjts_list[dvd_arg->dvd_global_obj_idx] = var;
226 171 : dvd_arg->dvd_global_obj_idx++;
227 :
228 171 : return 1;
229 : }
230 :
231 : /* CTF preprocess callback routine for CTF types. */
232 :
233 : int
234 1035 : ctf_dtd_preprocess_cb (ctf_dtdef_ref * slot, void * arg)
235 : {
236 1035 : uint32_t kind;
237 :
238 1035 : ctf_dtdef_ref ctftype = (ctf_dtdef_ref) *slot;
239 1035 : ctf_dtd_preprocess_arg_t * dtd_arg = (ctf_dtd_preprocess_arg_t *)arg;
240 1035 : ctf_container_ref arg_ctfc = dtd_arg->dtd_arg_ctfc;
241 :
242 1035 : size_t index = ctftype->dtd_type;
243 1035 : gcc_assert (index <= arg_ctfc->ctfc_types->elements ());
244 :
245 : /* CTF types need to be output in the order of their type IDs. In other
246 : words, if type A is used to define type B, type ID of type A must
247 : appear before type ID of type B. */
248 1035 : arg_ctfc->ctfc_types_list[index] = ctftype;
249 :
250 : /* Keep track of the CTF type if it's a function type and the type
251 : was generated from a function object. */
252 1035 : kind = CTF_V2_INFO_KIND (ctftype->dtd_data.ctti_info);
253 1035 : if (kind == CTF_K_FUNCTION && ctftype->from_global_func)
254 : {
255 255 : arg_ctfc->ctfc_gfuncs_list[dtd_arg->dtd_global_func_idx] = ctftype;
256 255 : dtd_arg->dtd_global_func_idx++;
257 : }
258 :
259 : /* Calculate the vlen bytes. */
260 1035 : arg_ctfc->ctfc_num_vlen_bytes += ctf_calc_num_vbytes (ctftype);
261 :
262 1035 : return 1;
263 : }
264 :
265 : /* CTF preprocessing.
266 : After the CTF types for the compilation unit have been generated fully, the
267 : compiler writes out the asm for the CTF types.
268 :
269 : CTF writeout in the compiler requires two passes over the CTF types. In the
270 : first pass, the CTF preprocess pass:
271 : 1. CTF types are sorted in the order of their type IDs.
272 : 2. The variable number of bytes after each CTF type record are calculated.
273 : This is used to calculate the offsets in the ctf_header_t.
274 : 3. If the CTF type is of CTF_K_FUNCTION, the number of bytes in the
275 : funcinfo sub-section are calculated. This is used to calculate the
276 : offsets in the ctf_header_t.
277 : 4. Keep the list of CTF variables in ASCIIbetical order of their names.
278 :
279 : In the second pass, the CTF writeout pass, asm tags are written out using
280 : the compiler's afore-generated internal pre-processed CTF types. */
281 :
282 : static void
283 219 : ctf_preprocess (ctf_container_ref ctfc)
284 : {
285 219 : size_t num_ctf_types = ctfc->ctfc_types->elements ();
286 219 : size_t num_ctf_vars = ctfc_get_num_ctf_vars (ctfc);
287 :
288 : /* Initialize an array to keep track of the CTF variables at global
289 : scope. At this time, size it conservatively. */
290 219 : size_t num_global_objts = num_ctf_vars;
291 219 : if (num_global_objts)
292 : {
293 82 : ctfc->ctfc_gobjts_list = ggc_vec_alloc<ctf_dvdef_t*>(num_global_objts);
294 : }
295 :
296 82 : if (num_ctf_vars)
297 : {
298 82 : ctf_dvd_preprocess_arg_t dvd_arg;
299 82 : dvd_arg.dvd_global_obj_idx = 0;
300 82 : dvd_arg.dvd_arg_ctfc = ctfc;
301 :
302 : /* Allocate CTF var list. */
303 82 : ctfc->ctfc_vars_list = ggc_vec_alloc<ctf_dvdef_ref>(num_ctf_vars);
304 : /* Variables appear in the sort ASCIIbetical order of their names. This
305 : permits binary searching in the CTF reader. Add the variables to a
306 : list for sorting. */
307 254 : ctfc->ctfc_vars->traverse<void *, ctf_dvd_preprocess_cb> (&dvd_arg);
308 : /* Sort the list. */
309 82 : qsort (ctfc->ctfc_vars_list, ctfc->ctfc_vars_list_count,
310 : sizeof (ctf_dvdef_ref), ctf_varent_compare);
311 : /* Update the actual number of the generated CTF variables at global
312 : scope. */
313 82 : ctfc->ctfc_num_global_objts = dvd_arg.dvd_global_obj_idx;
314 : }
315 :
316 : /* Initialize an array to keep track of the CTF functions types for global
317 : functions in the CTF data section. */
318 219 : size_t num_global_funcs = ctfc->ctfc_num_global_funcs;
319 219 : if (num_global_funcs)
320 : {
321 162 : ctfc->ctfc_gfuncs_list = ggc_vec_alloc<ctf_dtdef_t*>(num_global_funcs);
322 162 : gcc_assert (num_ctf_types);
323 : }
324 :
325 57 : if (num_ctf_types)
326 : {
327 219 : ctf_dtd_preprocess_arg_t dtd_arg;
328 219 : dtd_arg.dtd_global_func_idx = 0;
329 219 : dtd_arg.dtd_arg_ctfc = ctfc;
330 : /* Allocate the CTF types list. Add 1 because type ID 0 is never a valid
331 : CTF type ID. No CTF type record should appear at that offset, this
332 : eases debugging and readability. */
333 219 : ctfc->ctfc_types_list = ggc_vec_alloc<ctf_dtdef_ref>(num_ctf_types + 1);
334 : /* Pre-process CTF types. */
335 1254 : ctfc->ctfc_types->traverse<void *, ctf_dtd_preprocess_cb> (&dtd_arg);
336 :
337 219 : gcc_assert (dtd_arg.dtd_global_func_idx == num_global_funcs);
338 : }
339 219 : }
340 :
341 : /* CTF asm helper routines. */
342 :
343 : /* Asm'out the CTF preamble. */
344 :
345 : static void
346 219 : ctf_asm_preamble (ctf_container_ref ctfc)
347 : {
348 219 : dw2_asm_output_data (2, ctfc->ctfc_magic,
349 : "CTF preamble magic number");
350 219 : dw2_asm_output_data (1, ctfc->ctfc_version, "CTF preamble version");
351 219 : dw2_asm_output_data (1, ctfc->ctfc_flags, "CTF preamble flags");
352 219 : }
353 :
354 : /* Asm'out a CTF type which is represented by ctf_stype_t. */
355 :
356 : static void
357 1034 : ctf_asm_stype (ctf_dtdef_ref type)
358 : {
359 1034 : dw2_asm_output_data (4, type->dtd_data.ctti_name, "ctt_name");
360 1034 : dw2_asm_output_data (4, type->dtd_data.ctti_info, "ctt_info");
361 : /* union. */
362 1034 : dw2_asm_output_data (4, type->dtd_data.ctti_size, "ctt_size or ctt_type");
363 1034 : }
364 :
365 : /* Asm'out a CTF type which is represented by ctf_type_t. */
366 :
367 : static void
368 1 : ctf_asm_type (ctf_dtdef_ref type)
369 : {
370 1 : dw2_asm_output_data (4, type->dtd_data.ctti_name, "ctt_name");
371 1 : dw2_asm_output_data (4, type->dtd_data.ctti_info, "ctt_info");
372 : /* union. */
373 1 : dw2_asm_output_data (4, type->dtd_data.ctti_size, "ctt_size");
374 1 : dw2_asm_output_data (4, type->dtd_data.ctti_lsizehi, "ctt_lsizehi");
375 1 : dw2_asm_output_data (4, type->dtd_data.ctti_lsizelo, "ctt_lsizelo");
376 1 : }
377 :
378 : /* Asm'out a CTF type of kind CTF_K_SLICE. */
379 :
380 : static void
381 13 : ctf_asm_slice (ctf_dtdef_ref type)
382 : {
383 13 : dw2_asm_output_data (4, ctf_type_id (type->dtd_u.dtu_slice.cts_type),
384 : "cts_type");
385 13 : dw2_asm_output_data (2, type->dtd_u.dtu_slice.cts_offset, "cts_offset");
386 13 : dw2_asm_output_data (2, type->dtd_u.dtu_slice.cts_bits, "cts_bits");
387 13 : }
388 :
389 : /* Asm'out a CTF type of kind CTF_K_ARRAY. */
390 :
391 : static void
392 70 : ctf_asm_array (ctf_dtdef_ref dtd)
393 : {
394 70 : dw2_asm_output_data (4, ctf_type_id (dtd->dtd_u.dtu_arr.ctr_contents),
395 : "cta_contents");
396 70 : dw2_asm_output_data (4, ctf_type_id (dtd->dtd_u.dtu_arr.ctr_index),
397 : "cta_index");
398 70 : dw2_asm_output_data (4, dtd->dtd_u.dtu_arr.ctr_nelems, "cta_nelems");
399 70 : }
400 :
401 : /* Asm'out a CTF variable. */
402 :
403 : static void
404 171 : ctf_asm_varent (ctf_dvdef_ref var)
405 : {
406 : /* Output the reference to the name in the string table. */
407 171 : dw2_asm_output_data (4, var->dvd_name_offset, "ctv_name");
408 : /* Output the type index. */
409 171 : dw2_asm_output_data (4, ctf_type_id (var->dvd_type), "ctv_typeidx");
410 171 : }
411 :
412 : /* Asm'out a member of CTF struct or union, represented by ctf_lmember_t. */
413 :
414 : static void
415 5 : ctf_asm_sou_lmember (ctf_dmdef_t * dmd)
416 : {
417 5 : dw2_asm_output_data (4, dmd->dmd_name_offset, "ctlm_name");
418 5 : dw2_asm_output_data (4, CTF_OFFSET_TO_LMEMHI (dmd->dmd_offset),
419 : "ctlm_offsethi");
420 5 : dw2_asm_output_data (4, ctf_type_id (dmd->dmd_type), "ctlm_type");
421 5 : dw2_asm_output_data (4, CTF_OFFSET_TO_LMEMLO (dmd->dmd_offset),
422 : "ctlm_offsetlo");
423 5 : }
424 :
425 : /* Asm'out a member of a CTF sruct or union, represented by ctf_member_t. */
426 :
427 : static void
428 148 : ctf_asm_sou_member (ctf_dmdef_t * dmd)
429 : {
430 148 : dw2_asm_output_data (4, dmd->dmd_name_offset, "ctm_name");
431 148 : dw2_asm_output_data (4, dmd->dmd_offset, "ctm_offset");
432 148 : dw2_asm_output_data (4, ctf_type_id (dmd->dmd_type), "ctm_type");
433 148 : }
434 :
435 : /* Asm'out an enumerator constant. */
436 :
437 : static void
438 18 : ctf_asm_enum_const (ctf_dmdef_t * dmd)
439 : {
440 18 : dw2_asm_output_data (4, dmd->dmd_name_offset, "cte_name");
441 18 : dw2_asm_output_data (4, dmd->dmd_value, "cte_value");
442 18 : }
443 :
444 : /* Asm'out a function argument. */
445 :
446 : static void
447 110 : ctf_asm_func_arg (ctf_func_arg_t * farg)
448 : {
449 : /* farg_type may be NULL, indicating varargs. */
450 219 : dw2_asm_output_data (4, farg->farg_type
451 109 : ? ctf_type_id (farg->farg_type)
452 : : 0, "dtu_argv");
453 110 : }
454 :
455 : /* CTF writeout to asm file. */
456 :
457 : static void
458 219 : output_ctf_header (ctf_container_ref ctfc)
459 : {
460 219 : switch_to_section (ctf_info_section);
461 219 : ASM_OUTPUT_LABEL (asm_out_file, ctf_info_section_label);
462 :
463 219 : ctf_asm_preamble (ctfc);
464 :
465 : /* For a single compilation unit, the parent container's name and label are
466 : NULL. */
467 219 : dw2_asm_output_data (4, 0, "cth_parlabel");
468 219 : dw2_asm_output_data (4, 0, "cth_parname");
469 219 : dw2_asm_output_data (4, ctfc->ctfc_cuname_offset, "cth_cuname");
470 :
471 219 : int typeslen = 0;
472 : /* Initialize the offsets. The offsets are from after the CTF header. */
473 219 : uint32_t lbloff = 0;
474 219 : uint32_t objtoff = 0;
475 219 : uint32_t funcoff = 0;
476 219 : uint32_t objtidxoff = 0;
477 219 : uint32_t funcidxoff = 0;
478 219 : uint32_t varoff = 0;
479 219 : uint32_t typeoff = 0;
480 219 : uint32_t stroff = 0;
481 :
482 219 : if (!ctfc_is_empty_container (ctfc))
483 : {
484 219 : gcc_assert (ctfc_get_num_ctf_types (ctfc)
485 : == (ctfc->ctfc_num_types + ctfc->ctfc_num_stypes));
486 :
487 219 : funcoff = objtoff + ctfc->ctfc_num_global_objts * sizeof (uint32_t);
488 : /* Object index appears after function info. */
489 219 : objtidxoff = funcoff + ctfc->ctfc_num_global_funcs * sizeof (uint32_t);
490 : /* Funxtion index goes next. */
491 219 : funcidxoff = objtidxoff + ctfc->ctfc_num_global_objts * sizeof (uint32_t);
492 : /* Vars appear after function index. */
493 219 : varoff = funcidxoff + ctfc->ctfc_num_global_funcs * sizeof (uint32_t);
494 : /* CTF types appear after vars. */
495 219 : typeoff = varoff + (ctfc->ctfc_vars_list_count) * sizeof (ctf_varent_t);
496 : /* The total number of bytes for CTF types is the sum of the number of
497 : times struct ctf_type_t, struct ctf_stype_t are written, plus the
498 : amount of variable length data after each one of these. */
499 438 : typeslen = ctfc->ctfc_num_types * sizeof (ctf_type_t)
500 219 : + ctfc->ctfc_num_stypes * (sizeof (ctf_stype_t))
501 219 : + ctfc_get_num_vlen_bytes (ctfc);
502 :
503 : /* Strings appear after types. */
504 219 : stroff = typeoff + typeslen;
505 : }
506 :
507 : /* Offset of label section. */
508 219 : dw2_asm_output_data (4, lbloff, "cth_lbloff");
509 : /* Offset of object section. */
510 219 : dw2_asm_output_data (4, objtoff, "cth_objtoff");
511 : /* Offset of function section. */
512 219 : dw2_asm_output_data (4, funcoff, "cth_funcoff");
513 : /* Offset of object index section. */
514 219 : dw2_asm_output_data (4, objtidxoff, "cth_objtidxoff");
515 : /* Offset of function index section. */
516 219 : dw2_asm_output_data (4, funcidxoff, "cth_funcidxoff");
517 :
518 : /* Offset of variable section. */
519 219 : dw2_asm_output_data (4, varoff, "cth_varoff");
520 : /* Offset of type section. */
521 219 : dw2_asm_output_data (4, typeoff, "cth_typeoff");
522 : /* Offset of string section. */
523 219 : dw2_asm_output_data (4, stroff, "cth_stroff");
524 : /* Length of string section in bytes. */
525 219 : dw2_asm_output_data (4, ctfc->ctfc_strlen, "cth_strlen");
526 219 : }
527 :
528 : /* Output the CTF object info section. */
529 :
530 : static void
531 219 : output_ctf_obj_info (ctf_container_ref ctfc)
532 : {
533 219 : uint64_t i;
534 219 : ctf_dvdef_ref var;
535 :
536 219 : if (!ctfc->ctfc_num_global_objts) return;
537 :
538 : /* Compiler spits out the objts (at global scope) in the CTF obj info section.
539 : In no specific order. In an object file, the CTF object index section is
540 : used to associate the objts to their corresponding names. */
541 253 : for (i = 0; i < ctfc->ctfc_num_global_objts; i++)
542 : {
543 171 : var = ctfc->ctfc_gobjts_list[i];
544 :
545 : /* CTF type ID corresponding to the type of the variable. */
546 171 : dw2_asm_output_data (4, ctf_type_id (var->dvd_type), "objtinfo_var_type");
547 : }
548 :
549 : }
550 :
551 : /* Output the CTF function info section. */
552 :
553 : static void
554 219 : output_ctf_func_info (ctf_container_ref ctfc)
555 : {
556 219 : uint64_t i;
557 219 : ctf_dtdef_ref ctftype;
558 :
559 219 : if (!ctfc->ctfc_num_global_funcs) return;
560 :
561 : /* The CTF funcinfo section is simply an array of CTF_K_FUNCTION type IDs in
562 : the type section. In an object file, the CTF function index section is
563 : used to associate functions to their corresponding names. */
564 417 : for (i = 0; i < ctfc->ctfc_num_global_funcs; i++)
565 : {
566 255 : ctftype = ctfc->ctfc_gfuncs_list[i];
567 255 : dw2_asm_output_data (4, ctftype->dtd_type, "funcinfo_func_type");
568 : }
569 : }
570 :
571 : /* Output the CTF object index section. */
572 :
573 : static void
574 219 : output_ctf_objtidx (ctf_container_ref ctfc)
575 : {
576 219 : uint64_t i;
577 219 : ctf_dvdef_ref var;
578 :
579 219 : if (!ctfc->ctfc_num_global_objts) return;
580 :
581 253 : for (i = 0; i < ctfc->ctfc_num_global_objts; i++)
582 : {
583 171 : var = ctfc->ctfc_gobjts_list[i];
584 : /* Offset to the name in CTF string table. */
585 171 : dw2_asm_output_data (4, var->dvd_name_offset, "objtinfo_name");
586 : }
587 : }
588 :
589 : /* Output the CTF function index section. */
590 :
591 : static void
592 219 : output_ctf_funcidx (ctf_container_ref ctfc)
593 : {
594 219 : uint64_t i;
595 219 : ctf_dtdef_ref ctftype;
596 :
597 219 : if (!ctfc->ctfc_num_global_funcs) return;
598 :
599 417 : for (i = 0; i < ctfc->ctfc_num_global_funcs; i++)
600 : {
601 255 : ctftype = ctfc->ctfc_gfuncs_list[i];
602 : /* Offset to the name in CTF string table. */
603 255 : dw2_asm_output_data (4, ctftype->dtd_data.ctti_name, "funcinfo_name");
604 : }
605 : }
606 :
607 : /* Output the CTF variables. Variables appear in the sorted ASCIIbetical
608 : order of their names. This permits binary searching in the CTF reader. */
609 :
610 : static void
611 219 : output_ctf_vars (ctf_container_ref ctfc)
612 : {
613 219 : size_t i;
614 219 : unsigned int num_ctf_vars = ctfc->ctfc_vars_list_count;
615 219 : if (num_ctf_vars)
616 : {
617 : /* Iterate over the list of sorted vars and output the asm. */
618 253 : for (i = 0; i < num_ctf_vars; i++)
619 : {
620 171 : ctf_asm_varent (ctfc->ctfc_vars_list[i]);
621 : /* The type of variable must be a valid one. */
622 171 : gcc_assert (ctfc->ctfc_vars_list[i]->dvd_type != CTF_NULL_TYPEID);
623 : }
624 : }
625 219 : }
626 :
627 : /* Output the CTF string records. */
628 :
629 : static void
630 219 : output_ctf_strs (ctf_container_ref ctfc)
631 : {
632 219 : ctf_string_t * ctf_string = ctfc->ctfc_strtable.ctstab_head;
633 :
634 1780 : while (ctf_string)
635 : {
636 1561 : dw2_asm_output_nstring (ctf_string->cts_str, -1, "ctf_string");
637 1561 : ctf_string = ctf_string->cts_next;
638 : }
639 219 : }
640 :
641 : /* Output the members of the CTF struct or union. */
642 :
643 : static void
644 74 : output_asm_ctf_sou_fields (ctf_container_ref ARG_UNUSED (ctfc),
645 : ctf_dtdef_ref dtd)
646 : {
647 74 : ctf_dmdef_t * dmd;
648 :
649 : /* Function pointer to dump struct/union members. */
650 74 : void (*ctf_asm_sou_field_func) (ctf_dmdef_t *);
651 :
652 74 : uint32_t size = dtd->dtd_data.ctti_size;
653 :
654 : /* The variable length data struct/union CTF types is an array of
655 : ctf_member or ctf_lmember, depending on size of the member. */
656 74 : if (size >= CTF_LSTRUCT_THRESH)
657 : ctf_asm_sou_field_func = ctf_asm_sou_lmember;
658 : else
659 73 : ctf_asm_sou_field_func = ctf_asm_sou_member;
660 :
661 74 : for (dmd = dtd->dtd_u.dtu_members;
662 227 : dmd != NULL; dmd = (ctf_dmdef_t *) ctf_dmd_list_next (dmd))
663 : {
664 153 : ctf_asm_sou_field_func (dmd);
665 : /* Sanity Check - Unrepresented types appear as explicit types. */
666 153 : gcc_assert (dmd->dmd_type != CTF_NULL_TYPEID);
667 : }
668 74 : }
669 :
670 : /* Output the list of enumerator constants of the CTF enum type. */
671 :
672 : static void
673 6 : output_asm_ctf_enum_list (ctf_container_ref ARG_UNUSED (ctfc),
674 : ctf_dtdef_ref dtd)
675 : {
676 6 : ctf_dmdef_t * dmd;
677 :
678 0 : for (dmd = dtd->dtd_u.dtu_members;
679 24 : dmd != NULL; dmd = (ctf_dmdef_t *) ctf_dmd_list_next (dmd))
680 18 : ctf_asm_enum_const (dmd);
681 0 : }
682 :
683 : /* Output the list of function arguments of the CTF function type. */
684 :
685 : static void
686 265 : output_asm_func_args_list (ctf_container_ref ARG_UNUSED (ctfc),
687 : ctf_dtdef_ref dtd)
688 : {
689 265 : ctf_func_arg_t * farg;
690 :
691 0 : for (farg = dtd->dtd_u.dtu_argv;
692 375 : farg != NULL; farg = (ctf_func_arg_t *) ctf_farg_list_next (farg))
693 110 : ctf_asm_func_arg (farg);
694 0 : }
695 :
696 : /* Output the variable length portion of the CTF type record. */
697 :
698 : static void
699 1035 : output_asm_ctf_vlen_bytes (ctf_container_ref ctfc, ctf_dtdef_ref ctftype)
700 : {
701 1035 : uint32_t encoding;
702 1035 : uint32_t kind = CTF_V2_INFO_KIND (ctftype->dtd_data.ctti_info);
703 1035 : uint32_t vlen = CTF_V2_INFO_VLEN (ctftype->dtd_data.ctti_info);
704 :
705 1035 : switch (kind)
706 : {
707 400 : case CTF_K_INTEGER:
708 400 : case CTF_K_FLOAT:
709 400 : if (kind == CTF_K_INTEGER)
710 : {
711 372 : encoding = CTF_INT_DATA (ctftype->dtd_u.dtu_enc.cte_format,
712 : ctftype->dtd_u.dtu_enc.cte_offset,
713 : ctftype->dtd_u.dtu_enc.cte_bits);
714 : }
715 : else
716 : {
717 28 : encoding = CTF_FP_DATA (ctftype->dtd_u.dtu_enc.cte_format,
718 : ctftype->dtd_u.dtu_enc.cte_offset,
719 : ctftype->dtd_u.dtu_enc.cte_bits);
720 : }
721 400 : dw2_asm_output_data (4, encoding, "ctf_encoding_data");
722 400 : break;
723 265 : case CTF_K_FUNCTION:
724 265 : {
725 265 : output_asm_func_args_list (ctfc, ctftype);
726 : /* FIXME - CTF_PADDING_FOR_ALIGNMENT.
727 : libctf expects this padding for alignment reasons. Expected to
728 : be redundant in CTF_VERSION_4. */
729 265 : if (vlen & 1)
730 48 : dw2_asm_output_data (4, 0, "dtu_argv_padding");
731 :
732 : break;
733 : }
734 70 : case CTF_K_ARRAY:
735 70 : ctf_asm_array (ctftype);
736 70 : break;
737 13 : case CTF_K_SLICE:
738 13 : {
739 13 : ctf_asm_slice (ctftype);
740 : /* Type of the slice must be a valid CTF type. */
741 13 : gcc_assert (ctftype->dtd_u.dtu_slice.cts_type != CTF_NULL_TYPEID);
742 : break;
743 : }
744 74 : case CTF_K_STRUCT:
745 74 : case CTF_K_UNION:
746 74 : output_asm_ctf_sou_fields (ctfc, ctftype);
747 74 : break;
748 6 : case CTF_K_ENUM:
749 6 : output_asm_ctf_enum_list (ctfc, ctftype);
750 : break;
751 :
752 : default:
753 : /* CTF types of kind CTF_K_VOLATILE, CTF_K_CONST, CTF_K_RESTRICT,
754 : etc have no vlen data to write. */
755 : break;
756 : }
757 1035 : }
758 :
759 : /* Output a CTF Type. */
760 :
761 : static void
762 1035 : output_asm_ctf_type (ctf_container_ref ctfc, ctf_dtdef_ref type)
763 : {
764 1035 : if (type->dtd_data.ctti_size <= CTF_MAX_SIZE)
765 1034 : ctf_asm_stype (type);
766 : else
767 1 : ctf_asm_type (type);
768 : /* Now comes the variable-length portion for defining types completely.
769 : E.g., encoding follows CTF_INT_DATA, CTF_FP_DATA types,
770 : struct ctf_array_t follows CTF_K_ARRAY types, or a bunch of
771 : struct ctf_member / ctf_lmember ctf_enum sit in there for CTF_K_STRUCT or
772 : CTF_K_UNION. */
773 1035 : output_asm_ctf_vlen_bytes (ctfc, type);
774 :
775 1035 : uint32_t kind = CTF_V2_INFO_KIND (type->dtd_data.ctti_info);
776 : /* The underlying type must be a valid CTF type. */
777 1035 : if (kind == CTF_K_POINTER || kind == CTF_K_TYPEDEF
778 888 : || kind == CTF_K_VOLATILE || kind == CTF_K_CONST
779 845 : || kind == CTF_K_RESTRICT)
780 192 : gcc_assert (type->dtd_data.ctti_type != CTF_NULL_TYPEID);
781 1035 : }
782 :
783 : /* Output all CTF type records. */
784 :
785 : static void
786 219 : output_ctf_types (ctf_container_ref ctfc)
787 : {
788 219 : size_t i;
789 219 : size_t num_ctf_types = ctfc->ctfc_types->elements ();
790 219 : if (num_ctf_types)
791 : {
792 : /* Type ID = 0 is used as sentinel value; not a valid type. */
793 1254 : for (i = 1; i <= num_ctf_types; i++)
794 1035 : output_asm_ctf_type (ctfc, ctfc->ctfc_types_list[i]);
795 : }
796 219 : }
797 :
798 : /* CTF routines interfacing to the compiler. */
799 :
800 : /* Prepare and output the CTF section. */
801 :
802 : void
803 219 : ctf_output (const char * filename)
804 : {
805 219 : if (ctf_debug_info_level == CTFINFO_LEVEL_NONE)
806 : return;
807 :
808 : /* Get the CTF container for the current translation unit. */
809 219 : ctf_container_ref tu_ctfc = ctf_get_tu_ctfc ();
810 :
811 219 : init_ctf_sections ();
812 :
813 219 : ctf_add_cuname (tu_ctfc, filename);
814 :
815 : /* Pre-process CTF before generating assembly. */
816 219 : ctf_preprocess (tu_ctfc);
817 219 : output_ctf_header (tu_ctfc);
818 219 : output_ctf_obj_info (tu_ctfc);
819 219 : output_ctf_func_info (tu_ctfc);
820 219 : output_ctf_objtidx (tu_ctfc);
821 219 : output_ctf_funcidx (tu_ctfc);
822 219 : output_ctf_vars (tu_ctfc);
823 219 : output_ctf_types (tu_ctfc);
824 219 : output_ctf_strs (tu_ctfc);
825 :
826 : /* The total number of string bytes must be equal to those processed out to
827 : the str subsection. */
828 219 : gcc_assert (tu_ctfc->ctfc_strlen
829 : == ctfc_get_strtab_len (tu_ctfc, CTF_STRTAB));
830 :
831 : }
832 :
833 : /* Reset all state for CTF generation so that we can rerun the compiler within
834 : the same process. */
835 :
836 : void
837 219 : ctf_finalize (void)
838 : {
839 219 : ctf_info_section = NULL;
840 :
841 219 : ctf_container_ref tu_ctfc = ctf_get_tu_ctfc ();
842 219 : ctfc_delete_container (tu_ctfc);
843 219 : tu_ctfc = NULL;
844 219 : }
845 :
846 : #include "gt-ctfout.h"
|