Branch data Line data Source code
1 : : /* Output CTF format from GCC.
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 "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 : 727 : ctf_varent_compare (const void * entry1, const void * entry2)
79 : : {
80 : 727 : int result;
81 : 727 : const ctf_dvdef_t * e1 = *(const ctf_dvdef_t * const*) entry1;
82 : 727 : const ctf_dvdef_t * e2 = *(const ctf_dvdef_t * const*) entry2;
83 : :
84 : 727 : result = strcmp (e1->dvd_name, e2->dvd_name);
85 : :
86 : 727 : 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 : 1249 : ctf_calc_num_vbytes (ctf_dtdef_ref ctftype)
98 : : {
99 : 1249 : uint32_t size;
100 : 1249 : uint64_t vlen_bytes = 0;
101 : :
102 : 1249 : uint32_t kind = CTF_V2_INFO_KIND (ctftype->dtd_data.ctti_info);
103 : 1249 : uint32_t vlen = CTF_V2_INFO_VLEN (ctftype->dtd_data.ctti_info);
104 : :
105 : 1249 : ctf_dmdef_t * dmd;
106 : 1249 : ctf_func_arg_t * farg;
107 : 1249 : uint32_t size_per_member = 0;
108 : 1249 : unsigned int num_members = 0;
109 : 1249 : unsigned int num_fargs = 0;
110 : :
111 : 1249 : 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 : 508 : case CTF_K_INTEGER:
124 : 508 : case CTF_K_FLOAT:
125 : : /* 4 bytes to represent encoding CTF_INT_DATA, CTF_FP_DATA. */
126 : 508 : vlen_bytes += sizeof (uint32_t);
127 : 508 : break;
128 : 381 : case CTF_K_FUNCTION:
129 : : /* Sanity check - number of function args must be the same as
130 : : vlen. */
131 : 381 : for (farg = ctftype->dtd_u.dtu_argv;
132 : 489 : farg != NULL; farg = (ctf_func_arg_t *) ctf_farg_list_next (farg))
133 : 108 : num_fargs++;
134 : 381 : gcc_assert (vlen == num_fargs);
135 : :
136 : : /* FIXME - CTF_PADDING_FOR_ALIGNMENT. */
137 : 381 : vlen_bytes += (vlen + (vlen & 1)) * sizeof (uint32_t);
138 : 381 : break;
139 : 67 : case CTF_K_ARRAY:
140 : : /* This has a single ctf_array_t. */
141 : 67 : vlen_bytes += sizeof (ctf_array_t);
142 : 67 : break;
143 : 13 : case CTF_K_SLICE:
144 : 13 : vlen_bytes += sizeof (ctf_slice_t);
145 : 13 : break;
146 : 72 : case CTF_K_STRUCT:
147 : 72 : case CTF_K_UNION:
148 : : /* Count the number and type of members. */
149 : 72 : size = ctftype->dtd_data.ctti_size;
150 : 72 : 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 : 72 : for (dmd = ctftype->dtd_u.dtu_members;
156 : 217 : dmd != NULL; dmd = (ctf_dmdef_t *) ctf_dmd_list_next (dmd))
157 : 145 : num_members++;
158 : 72 : gcc_assert (vlen == num_members);
159 : :
160 : 72 : vlen_bytes += (num_members * size_per_member);
161 : 72 : 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 : 1249 : return vlen_bytes;
169 : : }
170 : :
171 : : /* Add a CTF variable to the end of the list. */
172 : :
173 : : static void
174 : 163 : ctf_list_add_ctf_vars (ctf_container_ref ctfc, ctf_dvdef_ref var)
175 : : {
176 : 163 : 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 : 332 : 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 : 332 : ctf_info_section = get_section (CTF_INFO_SECTION_NAME, CTF_INFO_SECTION_FLAGS,
190 : : NULL);
191 : :
192 : 332 : ASM_GENERATE_INTERNAL_LABEL (ctf_info_section_label,
193 : : CTF_INFO_SECTION_LABEL, ctf_label_num++);
194 : 332 : }
195 : :
196 : : /* Routines for CTF pre-processing. */
197 : :
198 : : static void
199 : 163 : 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 : 163 : ctf_list_add_ctf_vars (ctfc, var);
204 : 0 : }
205 : :
206 : : /* CTF preprocess callback routine for CTF variables. */
207 : :
208 : : int
209 : 164 : ctf_dvd_preprocess_cb (ctf_dvdef_ref * slot, void * arg)
210 : : {
211 : 164 : ctf_dvd_preprocess_arg_t * dvd_arg = (ctf_dvd_preprocess_arg_t *)arg;
212 : 164 : ctf_dvdef_ref var = (ctf_dvdef_ref) *slot;
213 : 164 : 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 : 164 : if (ctf_dvd_ignore_lookup (arg_ctfc, var->dvd_key))
220 : : return 1;
221 : :
222 : 163 : ctf_preprocess_var (arg_ctfc, var);
223 : :
224 : : /* Keep track of global objts. */
225 : 163 : arg_ctfc->ctfc_gobjts_list[dvd_arg->dvd_global_obj_idx] = var;
226 : 163 : dvd_arg->dvd_global_obj_idx++;
227 : :
228 : 163 : return 1;
229 : : }
230 : :
231 : : /* CTF preprocess callback routine for CTF types. */
232 : :
233 : : int
234 : 1249 : ctf_dtd_preprocess_cb (ctf_dtdef_ref * slot, void * arg)
235 : : {
236 : 1249 : uint32_t kind;
237 : :
238 : 1249 : ctf_dtdef_ref ctftype = (ctf_dtdef_ref) *slot;
239 : 1249 : ctf_dtd_preprocess_arg_t * dtd_arg = (ctf_dtd_preprocess_arg_t *)arg;
240 : 1249 : ctf_container_ref arg_ctfc = dtd_arg->dtd_arg_ctfc;
241 : :
242 : 1249 : size_t index = ctftype->dtd_type;
243 : 1249 : 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 : 1249 : 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 : 1249 : kind = CTF_V2_INFO_KIND (ctftype->dtd_data.ctti_info);
253 : 1249 : if (kind == CTF_K_FUNCTION && ctftype->from_global_func)
254 : : {
255 : 371 : arg_ctfc->ctfc_gfuncs_list[dtd_arg->dtd_global_func_idx] = ctftype;
256 : 371 : dtd_arg->dtd_global_func_idx++;
257 : : }
258 : :
259 : : /* Calculate the vlen bytes. */
260 : 1249 : arg_ctfc->ctfc_num_vlen_bytes += ctf_calc_num_vbytes (ctftype);
261 : :
262 : 1249 : 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 : 332 : ctf_preprocess (ctf_container_ref ctfc)
284 : : {
285 : 332 : size_t num_ctf_types = ctfc->ctfc_types->elements ();
286 : 332 : 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 : 332 : size_t num_global_objts = num_ctf_vars;
291 : 332 : if (num_global_objts)
292 : : {
293 : 78 : ctfc->ctfc_gobjts_list = ggc_vec_alloc<ctf_dvdef_t*>(num_global_objts);
294 : : }
295 : :
296 : 78 : if (num_ctf_vars)
297 : : {
298 : 78 : ctf_dvd_preprocess_arg_t dvd_arg;
299 : 78 : dvd_arg.dvd_global_obj_idx = 0;
300 : 78 : dvd_arg.dvd_arg_ctfc = ctfc;
301 : :
302 : : /* Allocate CTF var list. */
303 : 78 : 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 : 242 : ctfc->ctfc_vars->traverse<void *, ctf_dvd_preprocess_cb> (&dvd_arg);
308 : : /* Sort the list. */
309 : 78 : 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 : 78 : 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 : 332 : size_t num_global_funcs = ctfc->ctfc_num_global_funcs;
319 : 332 : if (num_global_funcs)
320 : : {
321 : 278 : ctfc->ctfc_gfuncs_list = ggc_vec_alloc<ctf_dtdef_t*>(num_global_funcs);
322 : 278 : gcc_assert (num_ctf_types);
323 : : }
324 : :
325 : 54 : if (num_ctf_types)
326 : : {
327 : 332 : ctf_dtd_preprocess_arg_t dtd_arg;
328 : 332 : dtd_arg.dtd_global_func_idx = 0;
329 : 332 : 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 : 332 : ctfc->ctfc_types_list = ggc_vec_alloc<ctf_dtdef_ref>(num_ctf_types + 1);
334 : : /* Pre-process CTF types. */
335 : 1581 : ctfc->ctfc_types->traverse<void *, ctf_dtd_preprocess_cb> (&dtd_arg);
336 : :
337 : 332 : gcc_assert (dtd_arg.dtd_global_func_idx == num_global_funcs);
338 : : }
339 : 332 : }
340 : :
341 : : /* CTF asm helper routines. */
342 : :
343 : : /* Asm'out the CTF preamble. */
344 : :
345 : : static void
346 : 332 : ctf_asm_preamble (ctf_container_ref ctfc)
347 : : {
348 : 332 : dw2_asm_output_data (2, ctfc->ctfc_magic,
349 : : "CTF preamble magic number");
350 : 332 : dw2_asm_output_data (1, ctfc->ctfc_version, "CTF preamble version");
351 : 332 : dw2_asm_output_data (1, ctfc->ctfc_flags, "CTF preamble flags");
352 : 332 : }
353 : :
354 : : /* Asm'out a CTF type which is represented by ctf_stype_t. */
355 : :
356 : : static void
357 : 1249 : ctf_asm_stype (ctf_dtdef_ref type)
358 : : {
359 : 1249 : dw2_asm_output_data (4, type->dtd_data.ctti_name, "ctt_name");
360 : 1249 : dw2_asm_output_data (4, type->dtd_data.ctti_info, "ctt_info");
361 : : /* union. */
362 : 1249 : dw2_asm_output_data (4, type->dtd_data.ctti_size, "ctt_size or ctt_type");
363 : 1249 : }
364 : :
365 : : /* Asm'out a CTF type which is represented by ctf_type_t. */
366 : :
367 : : static void
368 : 0 : ctf_asm_type (ctf_dtdef_ref type)
369 : : {
370 : 0 : dw2_asm_output_data (4, type->dtd_data.ctti_name, "ctt_name");
371 : 0 : dw2_asm_output_data (4, type->dtd_data.ctti_info, "ctt_info");
372 : : /* union. */
373 : 0 : dw2_asm_output_data (4, type->dtd_data.ctti_size, "ctt_size");
374 : 0 : dw2_asm_output_data (4, type->dtd_data.ctti_lsizehi, "ctt_lsizehi");
375 : 0 : dw2_asm_output_data (4, type->dtd_data.ctti_lsizelo, "ctt_lsizelo");
376 : 0 : }
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 : 67 : ctf_asm_array (ctf_dtdef_ref dtd)
393 : : {
394 : 67 : dw2_asm_output_data (4, ctf_type_id (dtd->dtd_u.dtu_arr.ctr_contents),
395 : : "cta_contents");
396 : 67 : dw2_asm_output_data (4, ctf_type_id (dtd->dtd_u.dtu_arr.ctr_index),
397 : : "cta_index");
398 : 67 : dw2_asm_output_data (4, dtd->dtd_u.dtu_arr.ctr_nelems, "cta_nelems");
399 : 67 : }
400 : :
401 : : /* Asm'out a CTF variable. */
402 : :
403 : : static void
404 : 163 : ctf_asm_varent (ctf_dvdef_ref var)
405 : : {
406 : : /* Output the reference to the name in the string table. */
407 : 163 : dw2_asm_output_data (4, var->dvd_name_offset, "ctv_name");
408 : : /* Output the type index. */
409 : 163 : dw2_asm_output_data (4, ctf_type_id (var->dvd_type), "ctv_typeidx");
410 : 163 : }
411 : :
412 : : /* Asm'out a member of CTF struct or union, represented by ctf_lmember_t. */
413 : :
414 : : static void
415 : 0 : ctf_asm_sou_lmember (ctf_dmdef_t * dmd)
416 : : {
417 : 0 : dw2_asm_output_data (4, dmd->dmd_name_offset, "ctlm_name");
418 : 0 : dw2_asm_output_data (4, CTF_OFFSET_TO_LMEMHI (dmd->dmd_offset),
419 : : "ctlm_offsethi");
420 : 0 : dw2_asm_output_data (4, ctf_type_id (dmd->dmd_type), "ctlm_type");
421 : 0 : dw2_asm_output_data (4, CTF_OFFSET_TO_LMEMLO (dmd->dmd_offset),
422 : : "ctlm_offsetlo");
423 : 0 : }
424 : :
425 : : /* Asm'out a member of a CTF sruct or union, represented by ctf_member_t. */
426 : :
427 : : static void
428 : 145 : ctf_asm_sou_member (ctf_dmdef_t * dmd)
429 : : {
430 : 145 : dw2_asm_output_data (4, dmd->dmd_name_offset, "ctm_name");
431 : 145 : dw2_asm_output_data (4, dmd->dmd_offset, "ctm_offset");
432 : 145 : dw2_asm_output_data (4, ctf_type_id (dmd->dmd_type), "ctm_type");
433 : 145 : }
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 : 108 : ctf_asm_func_arg (ctf_func_arg_t * farg)
448 : : {
449 : : /* farg_type may be NULL, indicating varargs. */
450 : 215 : dw2_asm_output_data (4, farg->farg_type
451 : 107 : ? ctf_type_id (farg->farg_type)
452 : : : 0, "dtu_argv");
453 : 108 : }
454 : :
455 : : /* CTF writeout to asm file. */
456 : :
457 : : static void
458 : 332 : output_ctf_header (ctf_container_ref ctfc)
459 : : {
460 : 332 : switch_to_section (ctf_info_section);
461 : 332 : ASM_OUTPUT_LABEL (asm_out_file, ctf_info_section_label);
462 : :
463 : 332 : ctf_asm_preamble (ctfc);
464 : :
465 : : /* For a single compilation unit, the parent container's name and label are
466 : : NULL. */
467 : 332 : dw2_asm_output_data (4, 0, "cth_parlabel");
468 : 332 : dw2_asm_output_data (4, 0, "cth_parname");
469 : 332 : dw2_asm_output_data (4, ctfc->ctfc_cuname_offset, "cth_cuname");
470 : :
471 : 332 : int typeslen = 0;
472 : : /* Initialize the offsets. The offsets are from after the CTF header. */
473 : 332 : uint32_t lbloff = 0;
474 : 332 : uint32_t objtoff = 0;
475 : 332 : uint32_t funcoff = 0;
476 : 332 : uint32_t objtidxoff = 0;
477 : 332 : uint32_t funcidxoff = 0;
478 : 332 : uint32_t varoff = 0;
479 : 332 : uint32_t typeoff = 0;
480 : 332 : uint32_t stroff = 0;
481 : :
482 : 332 : if (!ctfc_is_empty_container (ctfc))
483 : : {
484 : 332 : gcc_assert (ctfc_get_num_ctf_types (ctfc)
485 : : == (ctfc->ctfc_num_types + ctfc->ctfc_num_stypes));
486 : :
487 : 332 : funcoff = objtoff + ctfc->ctfc_num_global_objts * sizeof (uint32_t);
488 : : /* Object index appears after function info. */
489 : 332 : objtidxoff = funcoff + ctfc->ctfc_num_global_funcs * sizeof (uint32_t);
490 : : /* Funxtion index goes next. */
491 : 332 : funcidxoff = objtidxoff + ctfc->ctfc_num_global_objts * sizeof (uint32_t);
492 : : /* Vars appear after function index. */
493 : 332 : varoff = funcidxoff + ctfc->ctfc_num_global_funcs * sizeof (uint32_t);
494 : : /* CTF types appear after vars. */
495 : 332 : 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 : 664 : typeslen = ctfc->ctfc_num_types * sizeof (ctf_type_t)
500 : 332 : + ctfc->ctfc_num_stypes * (sizeof (ctf_stype_t))
501 : 332 : + ctfc_get_num_vlen_bytes (ctfc);
502 : :
503 : : /* Strings appear after types. */
504 : 332 : stroff = typeoff + typeslen;
505 : : }
506 : :
507 : : /* Offset of label section. */
508 : 332 : dw2_asm_output_data (4, lbloff, "cth_lbloff");
509 : : /* Offset of object section. */
510 : 332 : dw2_asm_output_data (4, objtoff, "cth_objtoff");
511 : : /* Offset of function section. */
512 : 332 : dw2_asm_output_data (4, funcoff, "cth_funcoff");
513 : : /* Offset of object index section. */
514 : 332 : dw2_asm_output_data (4, objtidxoff, "cth_objtidxoff");
515 : : /* Offset of function index section. */
516 : 332 : dw2_asm_output_data (4, funcidxoff, "cth_funcidxoff");
517 : :
518 : : /* Offset of variable section. */
519 : 332 : dw2_asm_output_data (4, varoff, "cth_varoff");
520 : : /* Offset of type section. */
521 : 332 : dw2_asm_output_data (4, typeoff, "cth_typeoff");
522 : : /* Offset of string section. */
523 : 332 : dw2_asm_output_data (4, stroff, "cth_stroff");
524 : : /* Length of string section in bytes. */
525 : 332 : dw2_asm_output_data (4, ctfc->ctfc_strlen, "cth_strlen");
526 : 332 : }
527 : :
528 : : /* Output the CTF object info section. */
529 : :
530 : : static void
531 : 332 : output_ctf_obj_info (ctf_container_ref ctfc)
532 : : {
533 : 332 : uint64_t i;
534 : 332 : ctf_dvdef_ref var;
535 : :
536 : 332 : 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 : 241 : for (i = 0; i < ctfc->ctfc_num_global_objts; i++)
542 : : {
543 : 163 : var = ctfc->ctfc_gobjts_list[i];
544 : :
545 : : /* CTF type ID corresponding to the type of the variable. */
546 : 163 : 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 : 332 : output_ctf_func_info (ctf_container_ref ctfc)
555 : : {
556 : 332 : uint64_t i;
557 : 332 : ctf_dtdef_ref ctftype;
558 : :
559 : 332 : 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 : 649 : for (i = 0; i < ctfc->ctfc_num_global_funcs; i++)
565 : : {
566 : 371 : ctftype = ctfc->ctfc_gfuncs_list[i];
567 : 371 : 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 : 332 : output_ctf_objtidx (ctf_container_ref ctfc)
575 : : {
576 : 332 : uint64_t i;
577 : 332 : ctf_dvdef_ref var;
578 : :
579 : 332 : if (!ctfc->ctfc_num_global_objts) return;
580 : :
581 : 241 : for (i = 0; i < ctfc->ctfc_num_global_objts; i++)
582 : : {
583 : 163 : var = ctfc->ctfc_gobjts_list[i];
584 : : /* Offset to the name in CTF string table. */
585 : 163 : 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 : 332 : output_ctf_funcidx (ctf_container_ref ctfc)
593 : : {
594 : 332 : uint64_t i;
595 : 332 : ctf_dtdef_ref ctftype;
596 : :
597 : 332 : if (!ctfc->ctfc_num_global_funcs) return;
598 : :
599 : 649 : for (i = 0; i < ctfc->ctfc_num_global_funcs; i++)
600 : : {
601 : 371 : ctftype = ctfc->ctfc_gfuncs_list[i];
602 : : /* Offset to the name in CTF string table. */
603 : 371 : 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 : 332 : output_ctf_vars (ctf_container_ref ctfc)
612 : : {
613 : 332 : size_t i;
614 : 332 : unsigned int num_ctf_vars = ctfc->ctfc_vars_list_count;
615 : 332 : if (num_ctf_vars)
616 : : {
617 : : /* Iterate over the list of sorted vars and output the asm. */
618 : 241 : for (i = 0; i < num_ctf_vars; i++)
619 : : {
620 : 163 : ctf_asm_varent (ctfc->ctfc_vars_list[i]);
621 : : /* The type of variable must be a valid one. */
622 : 163 : gcc_assert (ctfc->ctfc_vars_list[i]->dvd_type != CTF_NULL_TYPEID);
623 : : }
624 : : }
625 : 332 : }
626 : :
627 : : /* Output the CTF string records. */
628 : :
629 : : static void
630 : 332 : output_ctf_strs (ctf_container_ref ctfc)
631 : : {
632 : 332 : ctf_string_t * ctf_string = ctfc->ctfc_strtable.ctstab_head;
633 : :
634 : 2323 : while (ctf_string)
635 : : {
636 : 1991 : dw2_asm_output_nstring (ctf_string->cts_str, -1, "ctf_string");
637 : 1991 : ctf_string = ctf_string->cts_next;
638 : : }
639 : 332 : }
640 : :
641 : : /* Output the members of the CTF struct or union. */
642 : :
643 : : static void
644 : 72 : output_asm_ctf_sou_fields (ctf_container_ref ARG_UNUSED (ctfc),
645 : : ctf_dtdef_ref dtd)
646 : : {
647 : 72 : ctf_dmdef_t * dmd;
648 : :
649 : : /* Function pointer to dump struct/union members. */
650 : 72 : void (*ctf_asm_sou_field_func) (ctf_dmdef_t *);
651 : :
652 : 72 : 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 : 72 : if (size >= CTF_LSTRUCT_THRESH)
657 : : ctf_asm_sou_field_func = ctf_asm_sou_lmember;
658 : : else
659 : 72 : ctf_asm_sou_field_func = ctf_asm_sou_member;
660 : :
661 : 72 : for (dmd = dtd->dtd_u.dtu_members;
662 : 217 : dmd != NULL; dmd = (ctf_dmdef_t *) ctf_dmd_list_next (dmd))
663 : : {
664 : 145 : ctf_asm_sou_field_func (dmd);
665 : : /* Sanity Check - Unrepresented types appear as explicit types. */
666 : 145 : gcc_assert (dmd->dmd_type != CTF_NULL_TYPEID);
667 : : }
668 : 72 : }
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 : 381 : output_asm_func_args_list (ctf_container_ref ARG_UNUSED (ctfc),
687 : : ctf_dtdef_ref dtd)
688 : : {
689 : 381 : ctf_func_arg_t * farg;
690 : :
691 : 0 : for (farg = dtd->dtd_u.dtu_argv;
692 : 489 : farg != NULL; farg = (ctf_func_arg_t *) ctf_farg_list_next (farg))
693 : 108 : ctf_asm_func_arg (farg);
694 : 0 : }
695 : :
696 : : /* Output the variable length portion of the CTF type record. */
697 : :
698 : : static void
699 : 1249 : output_asm_ctf_vlen_bytes (ctf_container_ref ctfc, ctf_dtdef_ref ctftype)
700 : : {
701 : 1249 : uint32_t encoding;
702 : 1249 : uint32_t kind = CTF_V2_INFO_KIND (ctftype->dtd_data.ctti_info);
703 : 1249 : uint32_t vlen = CTF_V2_INFO_VLEN (ctftype->dtd_data.ctti_info);
704 : :
705 : 1249 : switch (kind)
706 : : {
707 : 508 : case CTF_K_INTEGER:
708 : 508 : case CTF_K_FLOAT:
709 : 508 : if (kind == CTF_K_INTEGER)
710 : : {
711 : 480 : 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 : 508 : dw2_asm_output_data (4, encoding, "ctf_encoding_data");
722 : 508 : break;
723 : 381 : case CTF_K_FUNCTION:
724 : 381 : {
725 : 381 : 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 : 381 : if (vlen & 1)
730 : 48 : dw2_asm_output_data (4, 0, "dtu_argv_padding");
731 : :
732 : : break;
733 : : }
734 : 67 : case CTF_K_ARRAY:
735 : 67 : ctf_asm_array (ctftype);
736 : 67 : 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 : 72 : case CTF_K_STRUCT:
745 : 72 : case CTF_K_UNION:
746 : 72 : output_asm_ctf_sou_fields (ctfc, ctftype);
747 : 72 : 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 : 1249 : }
758 : :
759 : : /* Output a CTF Type. */
760 : :
761 : : static void
762 : 1249 : output_asm_ctf_type (ctf_container_ref ctfc, ctf_dtdef_ref type)
763 : : {
764 : 1249 : if (type->dtd_data.ctti_size <= CTF_MAX_SIZE)
765 : 1249 : ctf_asm_stype (type);
766 : : else
767 : 0 : 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 : 1249 : output_asm_ctf_vlen_bytes (ctfc, type);
774 : :
775 : 1249 : uint32_t kind = CTF_V2_INFO_KIND (type->dtd_data.ctti_info);
776 : : /* The underlying type must be a valid CTF type. */
777 : 1249 : if (kind == CTF_K_POINTER || kind == CTF_K_TYPEDEF
778 : 1105 : || kind == CTF_K_VOLATILE || kind == CTF_K_CONST
779 : 1063 : || kind == CTF_K_RESTRICT)
780 : 188 : gcc_assert (type->dtd_data.ctti_type != CTF_NULL_TYPEID);
781 : 1249 : }
782 : :
783 : : /* Output all CTF type records. */
784 : :
785 : : static void
786 : 332 : output_ctf_types (ctf_container_ref ctfc)
787 : : {
788 : 332 : size_t i;
789 : 332 : size_t num_ctf_types = ctfc->ctfc_types->elements ();
790 : 332 : if (num_ctf_types)
791 : : {
792 : : /* Type ID = 0 is used as sentinel value; not a valid type. */
793 : 1581 : for (i = 1; i <= num_ctf_types; i++)
794 : 1249 : output_asm_ctf_type (ctfc, ctfc->ctfc_types_list[i]);
795 : : }
796 : 332 : }
797 : :
798 : : /* CTF routines interfacing to the compiler. */
799 : :
800 : : /* Prepare and output the CTF section. */
801 : :
802 : : void
803 : 332 : ctf_output (const char * filename)
804 : : {
805 : 332 : if (ctf_debug_info_level == CTFINFO_LEVEL_NONE)
806 : : return;
807 : :
808 : : /* Get the CTF container for the current translation unit. */
809 : 332 : ctf_container_ref tu_ctfc = ctf_get_tu_ctfc ();
810 : :
811 : 332 : init_ctf_sections ();
812 : :
813 : 332 : ctf_add_cuname (tu_ctfc, filename);
814 : :
815 : : /* Pre-process CTF before generating assembly. */
816 : 332 : ctf_preprocess (tu_ctfc);
817 : 332 : output_ctf_header (tu_ctfc);
818 : 332 : output_ctf_obj_info (tu_ctfc);
819 : 332 : output_ctf_func_info (tu_ctfc);
820 : 332 : output_ctf_objtidx (tu_ctfc);
821 : 332 : output_ctf_funcidx (tu_ctfc);
822 : 332 : output_ctf_vars (tu_ctfc);
823 : 332 : output_ctf_types (tu_ctfc);
824 : 332 : 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 : 332 : 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 : 332 : ctf_finalize (void)
838 : : {
839 : 332 : ctf_info_section = NULL;
840 : :
841 : 332 : ctf_container_ref tu_ctfc = ctf_get_tu_ctfc ();
842 : 332 : ctfc_delete_container (tu_ctfc);
843 : 332 : tu_ctfc = NULL;
844 : 332 : }
845 : :
846 : : #include "gt-ctfout.h"
|