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