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 : 731 : ctf_varent_compare (const void * entry1, const void * entry2)
79 : : {
80 : 731 : int result;
81 : 731 : const ctf_dvdef_t * e1 = *(const ctf_dvdef_t * const*) entry1;
82 : 731 : const ctf_dvdef_t * e2 = *(const ctf_dvdef_t * const*) entry2;
83 : :
84 : 731 : result = strcmp (e1->dvd_name, e2->dvd_name);
85 : :
86 : 731 : 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 : 1105 : ctf_calc_num_vbytes (ctf_dtdef_ref ctftype)
98 : : {
99 : 1105 : uint32_t size;
100 : 1105 : uint64_t vlen_bytes = 0;
101 : :
102 : 1105 : uint32_t kind = CTF_V2_INFO_KIND (ctftype->dtd_data.ctti_info);
103 : 1105 : uint32_t vlen = CTF_V2_INFO_VLEN (ctftype->dtd_data.ctti_info);
104 : :
105 : 1105 : ctf_dmdef_t * dmd;
106 : 1105 : ctf_func_arg_t * farg;
107 : 1105 : uint32_t size_per_member = 0;
108 : 1105 : unsigned int num_members = 0;
109 : 1105 : unsigned int num_fargs = 0;
110 : :
111 : 1105 : 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 : 436 : case CTF_K_INTEGER:
124 : 436 : case CTF_K_FLOAT:
125 : : /* 4 bytes to represent encoding CTF_INT_DATA, CTF_FP_DATA. */
126 : 436 : vlen_bytes += sizeof (uint32_t);
127 : 436 : break;
128 : 309 : case CTF_K_FUNCTION:
129 : : /* Sanity check - number of function args must be the same as
130 : : vlen. */
131 : 309 : for (farg = ctftype->dtd_u.dtu_argv;
132 : 419 : farg != NULL; farg = (ctf_func_arg_t *) ctf_farg_list_next (farg))
133 : 110 : num_fargs++;
134 : 309 : gcc_assert (vlen == num_fargs);
135 : :
136 : : /* FIXME - CTF_PADDING_FOR_ALIGNMENT. */
137 : 309 : vlen_bytes += (vlen + (vlen & 1)) * sizeof (uint32_t);
138 : 309 : 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 : 1105 : 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 : 260 : 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 : 260 : ctf_info_section = get_section (CTF_INFO_SECTION_NAME, CTF_INFO_SECTION_FLAGS,
190 : : NULL);
191 : :
192 : 260 : ASM_GENERATE_INTERNAL_LABEL (ctf_info_section_label,
193 : : CTF_INFO_SECTION_LABEL, ctf_label_num++);
194 : 260 : }
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 : 1105 : ctf_dtd_preprocess_cb (ctf_dtdef_ref * slot, void * arg)
235 : : {
236 : 1105 : uint32_t kind;
237 : :
238 : 1105 : ctf_dtdef_ref ctftype = (ctf_dtdef_ref) *slot;
239 : 1105 : ctf_dtd_preprocess_arg_t * dtd_arg = (ctf_dtd_preprocess_arg_t *)arg;
240 : 1105 : ctf_container_ref arg_ctfc = dtd_arg->dtd_arg_ctfc;
241 : :
242 : 1105 : size_t index = ctftype->dtd_type;
243 : 1105 : 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 : 1105 : 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 : 1105 : kind = CTF_V2_INFO_KIND (ctftype->dtd_data.ctti_info);
253 : 1105 : if (kind == CTF_K_FUNCTION && ctftype->from_global_func)
254 : : {
255 : 299 : arg_ctfc->ctfc_gfuncs_list[dtd_arg->dtd_global_func_idx] = ctftype;
256 : 299 : dtd_arg->dtd_global_func_idx++;
257 : : }
258 : :
259 : : /* Calculate the vlen bytes. */
260 : 1105 : arg_ctfc->ctfc_num_vlen_bytes += ctf_calc_num_vbytes (ctftype);
261 : :
262 : 1105 : 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 : 260 : ctf_preprocess (ctf_container_ref ctfc)
284 : : {
285 : 260 : size_t num_ctf_types = ctfc->ctfc_types->elements ();
286 : 260 : 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 : 260 : size_t num_global_objts = num_ctf_vars;
291 : 260 : 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 : 78 : 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 : 260 : size_t num_global_funcs = ctfc->ctfc_num_global_funcs;
319 : 260 : if (num_global_funcs)
320 : : {
321 : 206 : ctfc->ctfc_gfuncs_list = ggc_vec_alloc<ctf_dtdef_t*>(num_global_funcs);
322 : 206 : gcc_assert (num_ctf_types);
323 : : }
324 : :
325 : 54 : if (num_ctf_types)
326 : : {
327 : 260 : ctf_dtd_preprocess_arg_t dtd_arg;
328 : 260 : dtd_arg.dtd_global_func_idx = 0;
329 : 260 : 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 : 260 : ctfc->ctfc_types_list = ggc_vec_alloc<ctf_dtdef_ref>(num_ctf_types + 1);
334 : : /* Pre-process CTF types. */
335 : 260 : ctfc->ctfc_types->traverse<void *, ctf_dtd_preprocess_cb> (&dtd_arg);
336 : :
337 : 260 : gcc_assert (dtd_arg.dtd_global_func_idx == num_global_funcs);
338 : : }
339 : 260 : }
340 : :
341 : : /* CTF asm helper routines. */
342 : :
343 : : /* Asm'out the CTF preamble. */
344 : :
345 : : static void
346 : 260 : ctf_asm_preamble (ctf_container_ref ctfc)
347 : : {
348 : 260 : dw2_asm_output_data (2, ctfc->ctfc_magic,
349 : : "CTF preamble magic number");
350 : 260 : dw2_asm_output_data (1, ctfc->ctfc_version, "CTF preamble version");
351 : 260 : dw2_asm_output_data (1, ctfc->ctfc_flags, "CTF preamble flags");
352 : 260 : }
353 : :
354 : : /* Asm'out a CTF type which is represented by ctf_stype_t. */
355 : :
356 : : static void
357 : 1105 : ctf_asm_stype (ctf_dtdef_ref type)
358 : : {
359 : 1105 : dw2_asm_output_data (4, type->dtd_data.ctti_name, "ctt_name");
360 : 1105 : dw2_asm_output_data (4, type->dtd_data.ctti_info, "ctt_info");
361 : : /* union. */
362 : 1105 : dw2_asm_output_data (4, type->dtd_data.ctti_size, "ctt_size or ctt_type");
363 : 1105 : }
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, type->dtd_u.dtu_slice.cts_type, "cts_type");
384 : 13 : dw2_asm_output_data (2, type->dtd_u.dtu_slice.cts_offset, "cts_offset");
385 : 13 : dw2_asm_output_data (2, type->dtd_u.dtu_slice.cts_bits, "cts_bits");
386 : 13 : }
387 : :
388 : : /* Asm'out a CTF type of kind CTF_K_ARRAY. */
389 : :
390 : : static void
391 : 67 : ctf_asm_array (ctf_dtdef_ref dtd)
392 : : {
393 : 67 : dw2_asm_output_data (4, dtd->dtd_u.dtu_arr.ctr_contents, "cta_contents");
394 : 67 : dw2_asm_output_data (4, dtd->dtd_u.dtu_arr.ctr_index, "cta_index");
395 : 67 : dw2_asm_output_data (4, dtd->dtd_u.dtu_arr.ctr_nelems, "cta_nelems");
396 : 67 : }
397 : :
398 : : /* Asm'out a CTF variable. */
399 : :
400 : : static void
401 : 163 : ctf_asm_varent (ctf_dvdef_ref var)
402 : : {
403 : : /* Output the reference to the name in the string table. */
404 : 163 : dw2_asm_output_data (4, var->dvd_name_offset, "ctv_name");
405 : : /* Output the type index. */
406 : 163 : dw2_asm_output_data (4, var->dvd_type, "ctv_typeidx");
407 : 163 : }
408 : :
409 : : /* Asm'out a member of CTF struct or union, represented by ctf_lmember_t. */
410 : :
411 : : static void
412 : 0 : ctf_asm_sou_lmember (ctf_dmdef_t * dmd)
413 : : {
414 : 0 : dw2_asm_output_data (4, dmd->dmd_name_offset, "ctlm_name");
415 : 0 : dw2_asm_output_data (4, CTF_OFFSET_TO_LMEMHI (dmd->dmd_offset),
416 : : "ctlm_offsethi");
417 : 0 : dw2_asm_output_data (4, dmd->dmd_type, "ctlm_type");
418 : 0 : dw2_asm_output_data (4, CTF_OFFSET_TO_LMEMLO (dmd->dmd_offset),
419 : : "ctlm_offsetlo");
420 : 0 : }
421 : :
422 : : /* Asm'out a member of a CTF sruct or union, represented by ctf_member_t. */
423 : :
424 : : static void
425 : 145 : ctf_asm_sou_member (ctf_dmdef_t * dmd)
426 : : {
427 : 145 : dw2_asm_output_data (4, dmd->dmd_name_offset, "ctm_name");
428 : 145 : dw2_asm_output_data (4, dmd->dmd_offset, "ctm_offset");
429 : 145 : dw2_asm_output_data (4, dmd->dmd_type, "ctm_type");
430 : 145 : }
431 : :
432 : : /* Asm'out an enumerator constant. */
433 : :
434 : : static void
435 : 18 : ctf_asm_enum_const (ctf_dmdef_t * dmd)
436 : : {
437 : 18 : dw2_asm_output_data (4, dmd->dmd_name_offset, "cte_name");
438 : 18 : dw2_asm_output_data (4, dmd->dmd_value, "cte_value");
439 : 18 : }
440 : :
441 : : /* Asm'out a function argument. */
442 : :
443 : : static void
444 : 110 : ctf_asm_func_arg (ctf_func_arg_t * farg)
445 : : {
446 : 0 : dw2_asm_output_data (4, farg->farg_type, "dtu_argv");
447 : 0 : }
448 : :
449 : : /* CTF writeout to asm file. */
450 : :
451 : : static void
452 : 260 : output_ctf_header (ctf_container_ref ctfc)
453 : : {
454 : 260 : switch_to_section (ctf_info_section);
455 : 260 : ASM_OUTPUT_LABEL (asm_out_file, ctf_info_section_label);
456 : :
457 : 260 : ctf_asm_preamble (ctfc);
458 : :
459 : : /* For a single compilation unit, the parent container's name and label are
460 : : NULL. */
461 : 260 : dw2_asm_output_data (4, 0, "cth_parlabel");
462 : 260 : dw2_asm_output_data (4, 0, "cth_parname");
463 : 260 : dw2_asm_output_data (4, ctfc->ctfc_cuname_offset, "cth_cuname");
464 : :
465 : 260 : int typeslen = 0;
466 : : /* Initialize the offsets. The offsets are from after the CTF header. */
467 : 260 : uint32_t lbloff = 0;
468 : 260 : uint32_t objtoff = 0;
469 : 260 : uint32_t funcoff = 0;
470 : 260 : uint32_t objtidxoff = 0;
471 : 260 : uint32_t funcidxoff = 0;
472 : 260 : uint32_t varoff = 0;
473 : 260 : uint32_t typeoff = 0;
474 : 260 : uint32_t stroff = 0;
475 : :
476 : 260 : if (!ctfc_is_empty_container (ctfc))
477 : : {
478 : 260 : gcc_assert (ctfc_get_num_ctf_types (ctfc)
479 : : == (ctfc->ctfc_num_types + ctfc->ctfc_num_stypes));
480 : :
481 : 260 : funcoff = objtoff + ctfc->ctfc_num_global_objts * sizeof (uint32_t);
482 : : /* Object index appears after function info. */
483 : 260 : objtidxoff = funcoff + ctfc->ctfc_num_global_funcs * sizeof (uint32_t);
484 : : /* Funxtion index goes next. */
485 : 260 : funcidxoff = objtidxoff + ctfc->ctfc_num_global_objts * sizeof (uint32_t);
486 : : /* Vars appear after function index. */
487 : 260 : varoff = funcidxoff + ctfc->ctfc_num_global_funcs * sizeof (uint32_t);
488 : : /* CTF types appear after vars. */
489 : 260 : typeoff = varoff + (ctfc->ctfc_vars_list_count) * sizeof (ctf_varent_t);
490 : : /* The total number of bytes for CTF types is the sum of the number of
491 : : times struct ctf_type_t, struct ctf_stype_t are written, plus the
492 : : amount of variable length data after each one of these. */
493 : 520 : typeslen = ctfc->ctfc_num_types * sizeof (ctf_type_t)
494 : 260 : + ctfc->ctfc_num_stypes * (sizeof (ctf_stype_t))
495 : 260 : + ctfc_get_num_vlen_bytes (ctfc);
496 : :
497 : : /* Strings appear after types. */
498 : 260 : stroff = typeoff + typeslen;
499 : : }
500 : :
501 : : /* Offset of label section. */
502 : 260 : dw2_asm_output_data (4, lbloff, "cth_lbloff");
503 : : /* Offset of object section. */
504 : 260 : dw2_asm_output_data (4, objtoff, "cth_objtoff");
505 : : /* Offset of function section. */
506 : 260 : dw2_asm_output_data (4, funcoff, "cth_funcoff");
507 : : /* Offset of object index section. */
508 : 260 : dw2_asm_output_data (4, objtidxoff, "cth_objtidxoff");
509 : : /* Offset of function index section. */
510 : 260 : dw2_asm_output_data (4, funcidxoff, "cth_funcidxoff");
511 : :
512 : : /* Offset of variable section. */
513 : 260 : dw2_asm_output_data (4, varoff, "cth_varoff");
514 : : /* Offset of type section. */
515 : 260 : dw2_asm_output_data (4, typeoff, "cth_typeoff");
516 : : /* Offset of string section. */
517 : 260 : dw2_asm_output_data (4, stroff, "cth_stroff");
518 : : /* Length of string section in bytes. */
519 : 260 : dw2_asm_output_data (4, ctfc->ctfc_strlen, "cth_strlen");
520 : 260 : }
521 : :
522 : : /* Output the CTF object info section. */
523 : :
524 : : static void
525 : 260 : output_ctf_obj_info (ctf_container_ref ctfc)
526 : : {
527 : 260 : uint64_t i;
528 : 260 : ctf_dvdef_ref var;
529 : :
530 : 260 : if (!ctfc->ctfc_num_global_objts) return;
531 : :
532 : : /* Compiler spits out the objts (at global scope) in the CTF obj info section.
533 : : In no specific order. In an object file, the CTF object index section is
534 : : used to associate the objts to their corresponding names. */
535 : 241 : for (i = 0; i < ctfc->ctfc_num_global_objts; i++)
536 : : {
537 : 163 : var = ctfc->ctfc_gobjts_list[i];
538 : :
539 : : /* CTF type ID corresponding to the type of the variable. */
540 : 163 : dw2_asm_output_data (4, var->dvd_type, "objtinfo_var_type");
541 : : }
542 : :
543 : : }
544 : :
545 : : /* Output the CTF function info section. */
546 : :
547 : : static void
548 : 260 : output_ctf_func_info (ctf_container_ref ctfc)
549 : : {
550 : 260 : uint64_t i;
551 : 260 : ctf_dtdef_ref ctftype;
552 : :
553 : 260 : if (!ctfc->ctfc_num_global_funcs) return;
554 : :
555 : : /* The CTF funcinfo section is simply an array of CTF_K_FUNCTION type IDs in
556 : : the type section. In an object file, the CTF function index section is
557 : : used to associate functions to their corresponding names. */
558 : 505 : for (i = 0; i < ctfc->ctfc_num_global_funcs; i++)
559 : : {
560 : 299 : ctftype = ctfc->ctfc_gfuncs_list[i];
561 : 299 : dw2_asm_output_data (4, ctftype->dtd_type, "funcinfo_func_type");
562 : : }
563 : : }
564 : :
565 : : /* Output the CTF object index section. */
566 : :
567 : : static void
568 : 260 : output_ctf_objtidx (ctf_container_ref ctfc)
569 : : {
570 : 260 : uint64_t i;
571 : 260 : ctf_dvdef_ref var;
572 : :
573 : 260 : if (!ctfc->ctfc_num_global_objts) return;
574 : :
575 : 241 : for (i = 0; i < ctfc->ctfc_num_global_objts; i++)
576 : : {
577 : 163 : var = ctfc->ctfc_gobjts_list[i];
578 : : /* Offset to the name in CTF string table. */
579 : 163 : dw2_asm_output_data (4, var->dvd_name_offset, "objtinfo_name");
580 : : }
581 : : }
582 : :
583 : : /* Output the CTF function index section. */
584 : :
585 : : static void
586 : 260 : output_ctf_funcidx (ctf_container_ref ctfc)
587 : : {
588 : 260 : uint64_t i;
589 : 260 : ctf_dtdef_ref ctftype;
590 : :
591 : 260 : if (!ctfc->ctfc_num_global_funcs) return;
592 : :
593 : 505 : for (i = 0; i < ctfc->ctfc_num_global_funcs; i++)
594 : : {
595 : 299 : ctftype = ctfc->ctfc_gfuncs_list[i];
596 : : /* Offset to the name in CTF string table. */
597 : 299 : dw2_asm_output_data (4, ctftype->dtd_data.ctti_name, "funcinfo_name");
598 : : }
599 : : }
600 : :
601 : : /* Output the CTF variables. Variables appear in the sorted ASCIIbetical
602 : : order of their names. This permits binary searching in the CTF reader. */
603 : :
604 : : static void
605 : 260 : output_ctf_vars (ctf_container_ref ctfc)
606 : : {
607 : 260 : size_t i;
608 : 260 : unsigned int num_ctf_vars = ctfc->ctfc_vars_list_count;
609 : 260 : if (num_ctf_vars)
610 : : {
611 : : /* Iterate over the list of sorted vars and output the asm. */
612 : 241 : for (i = 0; i < num_ctf_vars; i++)
613 : : {
614 : 163 : ctf_asm_varent (ctfc->ctfc_vars_list[i]);
615 : : /* The type of variable must be a valid one. */
616 : 163 : gcc_assert (ctfc->ctfc_vars_list[i]->dvd_type != CTF_NULL_TYPEID);
617 : : }
618 : : }
619 : 260 : }
620 : :
621 : : /* Output the CTF string records. */
622 : :
623 : : static void
624 : 260 : output_ctf_strs (ctf_container_ref ctfc)
625 : : {
626 : 260 : ctf_string_t * ctf_string = ctfc->ctfc_strtable.ctstab_head;
627 : :
628 : 1963 : while (ctf_string)
629 : : {
630 : 1703 : dw2_asm_output_nstring (ctf_string->cts_str, -1, "ctf_string");
631 : 1703 : ctf_string = ctf_string->cts_next;
632 : : }
633 : 260 : }
634 : :
635 : : /* Output the members of the CTF struct or union. */
636 : :
637 : : static void
638 : 72 : output_asm_ctf_sou_fields (ctf_container_ref ARG_UNUSED (ctfc),
639 : : ctf_dtdef_ref dtd)
640 : : {
641 : 72 : ctf_dmdef_t * dmd;
642 : :
643 : : /* Function pointer to dump struct/union members. */
644 : 72 : void (*ctf_asm_sou_field_func) (ctf_dmdef_t *);
645 : :
646 : 72 : uint32_t size = dtd->dtd_data.ctti_size;
647 : :
648 : : /* The variable length data struct/union CTF types is an array of
649 : : ctf_member or ctf_lmember, depending on size of the member. */
650 : 72 : if (size >= CTF_LSTRUCT_THRESH)
651 : : ctf_asm_sou_field_func = ctf_asm_sou_lmember;
652 : : else
653 : 72 : ctf_asm_sou_field_func = ctf_asm_sou_member;
654 : :
655 : 72 : for (dmd = dtd->dtd_u.dtu_members;
656 : 217 : dmd != NULL; dmd = (ctf_dmdef_t *) ctf_dmd_list_next (dmd))
657 : : {
658 : 145 : ctf_asm_sou_field_func (dmd);
659 : : /* Sanity Check - Unrepresented types appear as explicit types. */
660 : 145 : gcc_assert (dmd->dmd_type != CTF_NULL_TYPEID);
661 : : }
662 : 72 : }
663 : :
664 : : /* Output the list of enumerator constants of the CTF enum type. */
665 : :
666 : : static void
667 : 6 : output_asm_ctf_enum_list (ctf_container_ref ARG_UNUSED (ctfc),
668 : : ctf_dtdef_ref dtd)
669 : : {
670 : 6 : ctf_dmdef_t * dmd;
671 : :
672 : 0 : for (dmd = dtd->dtd_u.dtu_members;
673 : 24 : dmd != NULL; dmd = (ctf_dmdef_t *) ctf_dmd_list_next (dmd))
674 : 18 : ctf_asm_enum_const (dmd);
675 : 0 : }
676 : :
677 : : /* Output the list of function arguments of the CTF function type. */
678 : :
679 : : static void
680 : 309 : output_asm_func_args_list (ctf_container_ref ARG_UNUSED (ctfc),
681 : : ctf_dtdef_ref dtd)
682 : : {
683 : 309 : ctf_func_arg_t * farg;
684 : :
685 : 309 : for (farg = dtd->dtd_u.dtu_argv;
686 : 419 : farg != NULL; farg = (ctf_func_arg_t *) ctf_farg_list_next (farg))
687 : 110 : ctf_asm_func_arg (farg);
688 : 309 : }
689 : :
690 : : /* Output the variable length portion of the CTF type record. */
691 : :
692 : : static void
693 : 1105 : output_asm_ctf_vlen_bytes (ctf_container_ref ctfc, ctf_dtdef_ref ctftype)
694 : : {
695 : 1105 : uint32_t encoding;
696 : 1105 : uint32_t kind = CTF_V2_INFO_KIND (ctftype->dtd_data.ctti_info);
697 : 1105 : uint32_t vlen = CTF_V2_INFO_VLEN (ctftype->dtd_data.ctti_info);
698 : :
699 : 1105 : switch (kind)
700 : : {
701 : 436 : case CTF_K_INTEGER:
702 : 436 : case CTF_K_FLOAT:
703 : 436 : if (kind == CTF_K_INTEGER)
704 : : {
705 : 408 : encoding = CTF_INT_DATA (ctftype->dtd_u.dtu_enc.cte_format,
706 : : ctftype->dtd_u.dtu_enc.cte_offset,
707 : : ctftype->dtd_u.dtu_enc.cte_bits);
708 : : }
709 : : else
710 : : {
711 : 28 : encoding = CTF_FP_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 : 436 : dw2_asm_output_data (4, encoding, "ctf_encoding_data");
716 : 436 : break;
717 : 309 : case CTF_K_FUNCTION:
718 : 309 : {
719 : 309 : output_asm_func_args_list (ctfc, ctftype);
720 : : /* FIXME - CTF_PADDING_FOR_ALIGNMENT.
721 : : libctf expects this padding for alignment reasons. Expected to
722 : : be redundant in CTF_VERSION_4. */
723 : 309 : if (vlen & 1)
724 : 50 : dw2_asm_output_data (4, 0, "dtu_argv_padding");
725 : :
726 : : break;
727 : : }
728 : 67 : case CTF_K_ARRAY:
729 : 67 : ctf_asm_array (ctftype);
730 : 67 : break;
731 : 13 : case CTF_K_SLICE:
732 : 13 : {
733 : 13 : ctf_asm_slice (ctftype);
734 : : /* Type of the slice must be a valid CTF type. */
735 : 13 : gcc_assert (ctftype->dtd_u.dtu_slice.cts_type != CTF_NULL_TYPEID);
736 : : break;
737 : : }
738 : 72 : case CTF_K_STRUCT:
739 : 72 : case CTF_K_UNION:
740 : 72 : output_asm_ctf_sou_fields (ctfc, ctftype);
741 : 72 : break;
742 : 6 : case CTF_K_ENUM:
743 : 6 : output_asm_ctf_enum_list (ctfc, ctftype);
744 : : break;
745 : :
746 : : default:
747 : : /* CTF types of kind CTF_K_VOLATILE, CTF_K_CONST, CTF_K_RESTRICT,
748 : : etc have no vlen data to write. */
749 : : break;
750 : : }
751 : 1105 : }
752 : :
753 : : /* Output a CTF Type. */
754 : :
755 : : static void
756 : 1105 : output_asm_ctf_type (ctf_container_ref ctfc, ctf_dtdef_ref type)
757 : : {
758 : 1105 : if (type->dtd_data.ctti_size <= CTF_MAX_SIZE)
759 : 1105 : ctf_asm_stype (type);
760 : : else
761 : 0 : ctf_asm_type (type);
762 : : /* Now comes the variable-length portion for defining types completely.
763 : : E.g., encoding follows CTF_INT_DATA, CTF_FP_DATA types,
764 : : struct ctf_array_t follows CTF_K_ARRAY types, or a bunch of
765 : : struct ctf_member / ctf_lmember ctf_enum sit in there for CTF_K_STRUCT or
766 : : CTF_K_UNION. */
767 : 1105 : output_asm_ctf_vlen_bytes (ctfc, type);
768 : :
769 : 1105 : uint32_t kind = CTF_V2_INFO_KIND (type->dtd_data.ctti_info);
770 : : /* The underlying type must be a valid CTF type. */
771 : 1105 : if (kind == CTF_K_POINTER || kind == CTF_K_TYPEDEF
772 : 961 : || kind == CTF_K_VOLATILE || kind == CTF_K_CONST
773 : 919 : || kind == CTF_K_RESTRICT)
774 : 188 : gcc_assert (type->dtd_data.ctti_type != CTF_NULL_TYPEID);
775 : 1105 : }
776 : :
777 : : /* Output all CTF type records. */
778 : :
779 : : static void
780 : 260 : output_ctf_types (ctf_container_ref ctfc)
781 : : {
782 : 260 : size_t i;
783 : 260 : size_t num_ctf_types = ctfc->ctfc_types->elements ();
784 : 260 : if (num_ctf_types)
785 : : {
786 : : /* Type ID = 0 is used as sentinel value; not a valid type. */
787 : 1365 : for (i = 1; i <= num_ctf_types; i++)
788 : 1105 : output_asm_ctf_type (ctfc, ctfc->ctfc_types_list[i]);
789 : : }
790 : 260 : }
791 : :
792 : : /* CTF routines interfacing to the compiler. */
793 : :
794 : : /* Prepare and output the CTF section. */
795 : :
796 : : void
797 : 260 : ctf_output (const char * filename)
798 : : {
799 : 260 : if (ctf_debug_info_level == CTFINFO_LEVEL_NONE)
800 : : return;
801 : :
802 : : /* Get the CTF container for the current translation unit. */
803 : 260 : ctf_container_ref tu_ctfc = ctf_get_tu_ctfc ();
804 : :
805 : 260 : init_ctf_sections ();
806 : :
807 : 260 : ctf_add_cuname (tu_ctfc, filename);
808 : :
809 : : /* Pre-process CTF before generating assembly. */
810 : 260 : ctf_preprocess (tu_ctfc);
811 : 260 : output_ctf_header (tu_ctfc);
812 : 260 : output_ctf_obj_info (tu_ctfc);
813 : 260 : output_ctf_func_info (tu_ctfc);
814 : 260 : output_ctf_objtidx (tu_ctfc);
815 : 260 : output_ctf_funcidx (tu_ctfc);
816 : 260 : output_ctf_vars (tu_ctfc);
817 : 260 : output_ctf_types (tu_ctfc);
818 : 260 : output_ctf_strs (tu_ctfc);
819 : :
820 : : /* The total number of string bytes must be equal to those processed out to
821 : : the str subsection. */
822 : 260 : gcc_assert (tu_ctfc->ctfc_strlen
823 : : == ctfc_get_strtab_len (tu_ctfc, CTF_STRTAB));
824 : :
825 : : }
826 : :
827 : : /* Reset all state for CTF generation so that we can rerun the compiler within
828 : : the same process. */
829 : :
830 : : void
831 : 260 : ctf_finalize (void)
832 : : {
833 : 260 : ctf_info_section = NULL;
834 : :
835 : 260 : ctf_container_ref tu_ctfc = ctf_get_tu_ctfc ();
836 : 260 : ctfc_delete_container (tu_ctfc);
837 : 260 : tu_ctfc = NULL;
838 : 260 : }
839 : :
840 : : #include "gt-ctfout.h"
|