Branch data Line data Source code
1 : : /* Output BTF format from GCC.
2 : : Copyright (C) 2021-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 : : /* This file contains routines to output the BPF Type Format (BTF). The BTF
21 : : debug format is very similar to CTF; as a result, the structure of this file
22 : : closely resembles that of ctfout.cc, and the same CTF container objects are
23 : : used. */
24 : :
25 : : #include "config.h"
26 : : #include "system.h"
27 : : #include "coretypes.h"
28 : : #include "target.h"
29 : : #include "memmodel.h"
30 : : #include "tm_p.h"
31 : : #include "output.h"
32 : : #include "dwarf2asm.h"
33 : : #include "debug.h"
34 : : #include "ctfc.h"
35 : : #include "diagnostic-core.h"
36 : : #include "cgraph.h"
37 : : #include "varasm.h"
38 : : #include "stringpool.h" /* For lookup_attribute. */
39 : : #include "attribs.h" /* For lookup_attribute. */
40 : : #include "dwarf2out.h" /* For lookup_decl_die. */
41 : :
42 : : static int btf_label_num;
43 : :
44 : : static GTY (()) section * btf_info_section;
45 : :
46 : : /* BTF debug info section. */
47 : :
48 : : #ifndef BTF_INFO_SECTION_NAME
49 : : #define BTF_INFO_SECTION_NAME ".BTF"
50 : : #endif
51 : :
52 : : #define BTF_INFO_SECTION_FLAGS (SECTION_DEBUG)
53 : :
54 : : /* Maximum size (in bytes) for an artifically generated BTF label. */
55 : :
56 : : #define MAX_BTF_LABEL_BYTES 40
57 : :
58 : : static char btf_info_section_label[MAX_BTF_LABEL_BYTES];
59 : :
60 : : #ifndef BTF_INFO_SECTION_LABEL
61 : : #define BTF_INFO_SECTION_LABEL "Lbtf"
62 : : #endif
63 : :
64 : : #define BTF_INVALID_TYPEID 0xFFFFFFFF
65 : :
66 : : /* Internal representation of an entry in a BTF_KIND_DATASEC record. */
67 : : struct btf_datasec_entry
68 : : {
69 : : union {
70 : : ctf_dvdef_ref dvd; /* Reference to the underlying variable represented. */
71 : : ctf_dtdef_ref dtd; /* Reference to the underlying type represented. */
72 : : };
73 : : bool is_var; /* True iff this entry represents a variable. */
74 : : uint32_t size; /* Size of variable or function, in bytes.
75 : : For functions, always zero at compile time. */
76 : : };
77 : :
78 : : /* Internal representation of a BTF_KIND_DATASEC record. */
79 : : typedef struct btf_datasec
80 : : {
81 : : ctf_id_t id; /* BTF type ID of this record. */
82 : : const char *name; /* Section name, e.g. ".bss". */
83 : : uint32_t name_offset; /* Offset to name in string table. */
84 : : vec<struct btf_datasec_entry> entries; /* Entries in this section. */
85 : : } btf_datasec_t;
86 : :
87 : : /* One BTF_KIND_DATASEC record is created for each output data section which
88 : : will hold at least one variable. */
89 : : static vec<btf_datasec_t> datasecs;
90 : :
91 : : /* Functions in BTF have two separate type records - one for the prototype
92 : : (BTF_KIND_FUNC_PROTO), as well as a BTF_KIND_FUNC. CTF_K_FUNCTION types
93 : : map closely to BTF_KIND_FUNC_PROTO, but the BTF_KIND_FUNC records must be
94 : : created. This vector holds them. */
95 : : static GTY (()) vec<ctf_dtdef_ref, va_gc> *funcs;
96 : :
97 : : /* Maps BTF_KIND_FUNC_PROTO to the BTF_KIND_FUNC record for it. Used when
98 : : creating DATASEC entries. */
99 : : static GTY (()) hash_map<ctf_dtdef_ref, ctf_dtdef_ref> *func_map;
100 : :
101 : : /* Highest BTF ID assigned to any regular type translated from CTF.
102 : : Does not include BTF_KIND_{VAR,FUNC,DATASEC} types. */
103 : : static ctf_id_t max_translated_id = 0;
104 : :
105 : : /* Name strings for BTF kinds.
106 : : Note: the indices here must match the type defines in btf.h. */
107 : : static const char *const btf_kind_names[] =
108 : : {
109 : : "UNKN", "INT", "PTR", "ARRAY", "STRUCT", "UNION", "ENUM", "FWD",
110 : : "TYPEDEF", "VOLATILE", "CONST", "RESTRICT", "FUNC", "FUNC_PROTO",
111 : : "VAR", "DATASEC", "FLOAT", "DECL_TAG", "TYPE_TAG", "ENUM64"
112 : : };
113 : :
114 : : /* Return a name string for the given BTF_KIND. */
115 : :
116 : : static const char *
117 : 821 : btf_kind_name (uint32_t btf_kind)
118 : : {
119 : 821 : return btf_kind_names[btf_kind];
120 : : }
121 : :
122 : : /* Map a CTF type kind to the corresponding BTF type kind. */
123 : :
124 : : static uint32_t
125 : 3353 : get_btf_kind (uint32_t ctf_kind)
126 : : {
127 : : /* N.B. the values encoding kinds are not in general the same for the
128 : : same kind between CTF and BTF. e.g. CTF_K_CONST != BTF_KIND_CONST. */
129 : 0 : switch (ctf_kind)
130 : : {
131 : : case CTF_K_INTEGER: return BTF_KIND_INT;
132 : : case CTF_K_FLOAT: return BTF_KIND_FLOAT;
133 : : case CTF_K_POINTER: return BTF_KIND_PTR;
134 : : case CTF_K_ARRAY: return BTF_KIND_ARRAY;
135 : : case CTF_K_FUNCTION: return BTF_KIND_FUNC_PROTO;
136 : : case CTF_K_STRUCT: return BTF_KIND_STRUCT;
137 : : case CTF_K_UNION: return BTF_KIND_UNION;
138 : : case CTF_K_ENUM: return BTF_KIND_ENUM;
139 : : case CTF_K_FORWARD: return BTF_KIND_FWD;
140 : : case CTF_K_TYPEDEF: return BTF_KIND_TYPEDEF;
141 : : case CTF_K_VOLATILE: return BTF_KIND_VOLATILE;
142 : : case CTF_K_CONST: return BTF_KIND_CONST;
143 : : case CTF_K_RESTRICT: return BTF_KIND_RESTRICT;
144 : : default:;
145 : : }
146 : : return BTF_KIND_UNKN;
147 : : }
148 : :
149 : : /* Convenience wrapper around get_btf_kind for the common case. */
150 : :
151 : : static uint32_t
152 : 3299 : btf_dtd_kind (ctf_dtdef_ref dtd)
153 : : {
154 : 0 : if (!dtd)
155 : : return BTF_KIND_UNKN;
156 : 2478 : return get_btf_kind (CTF_V2_INFO_KIND (dtd->dtd_data.ctti_info));
157 : : }
158 : :
159 : : /* Some BTF types, like BTF_KIND_FUNC_PROTO, are anonymous. The machinery
160 : : in btfout to emit BTF, may reset dtd_data->ctti_name, but does not update
161 : : the name in the ctf_dtdef_ref type object (deliberate choice). This
162 : : interface helps abstract out that state of affairs, while giving access to
163 : : the name of the type as intended. */
164 : :
165 : : static const char *
166 : 906 : get_btf_type_name (ctf_dtdef_ref dtd)
167 : : {
168 : 906 : const char *anon = "";
169 : 567 : return (dtd->dtd_data.ctti_name) ? dtd->dtd_name : anon;
170 : : }
171 : :
172 : : static bool
173 : 1283 : btf_emit_type_p (ctf_dtdef_ref dtd)
174 : : {
175 : 1283 : uint32_t kind = btf_dtd_kind (dtd);
176 : :
177 : 1256 : if (kind == BTF_KIND_UNKN)
178 : : /* This type is not representable in BTF. */
179 : : return false;
180 : :
181 : 1256 : if (kind == BTF_KIND_INT && dtd->dtd_data.ctti_size == 0)
182 : : /* This is a (redundant) definition of void. */
183 : 19 : return false;
184 : :
185 : : return true;
186 : : }
187 : :
188 : : /* Return true if DTD is a forward-declared enum. The BTF representation
189 : : of forward declared enums is not formally defined. */
190 : :
191 : : static bool
192 : 455 : btf_fwd_to_enum_p (ctf_dtdef_ref dtd)
193 : : {
194 : 909 : uint32_t kind = btf_dtd_kind (dtd);
195 : 455 : return (kind == BTF_KIND_FWD && dtd->dtd_data.ctti_type == CTF_K_ENUM);
196 : : }
197 : :
198 : : /* Each BTF type can be followed additional, variable-length information
199 : : completing the description of the type. Calculate the number of bytes
200 : : of variable information required to encode a given type. */
201 : :
202 : : static uint64_t
203 : 366 : btf_calc_num_vbytes (ctf_dtdef_ref dtd)
204 : : {
205 : 366 : uint64_t vlen_bytes = 0;
206 : :
207 : 366 : uint32_t kind = btf_dtd_kind (dtd);
208 : 366 : uint32_t vlen = CTF_V2_INFO_VLEN (dtd->dtd_data.ctti_info);
209 : :
210 : 366 : switch (kind)
211 : : {
212 : : case BTF_KIND_UNKN:
213 : : case BTF_KIND_PTR:
214 : : case BTF_KIND_FWD:
215 : : case BTF_KIND_TYPEDEF:
216 : : case BTF_KIND_VOLATILE:
217 : : case BTF_KIND_CONST:
218 : : case BTF_KIND_RESTRICT:
219 : : case BTF_KIND_FUNC:
220 : : /* These kinds have no vlen data. */
221 : : break;
222 : :
223 : 148 : case BTF_KIND_INT:
224 : : /* Size 0 integers represent redundant definitions of void that will
225 : : not be emitted. Don't allocate space for them. */
226 : 148 : if (dtd->dtd_data.ctti_size == 0)
227 : : break;
228 : :
229 : 366 : vlen_bytes += sizeof (uint32_t);
230 : : break;
231 : :
232 : : case BTF_KIND_ARRAY:
233 : 366 : vlen_bytes += sizeof (struct btf_array);
234 : : break;
235 : :
236 : 32 : case BTF_KIND_STRUCT:
237 : 32 : case BTF_KIND_UNION:
238 : 32 : vlen_bytes += vlen * sizeof (struct btf_member);
239 : 32 : break;
240 : :
241 : 8 : case BTF_KIND_ENUM:
242 : 8 : vlen_bytes += (dtd->dtd_data.ctti_size > 4)
243 : 8 : ? vlen * sizeof (struct btf_enum64)
244 : 5 : : vlen * sizeof (struct btf_enum);
245 : : break;
246 : :
247 : 87 : case BTF_KIND_FUNC_PROTO:
248 : 87 : vlen_bytes += vlen * sizeof (struct btf_param);
249 : 87 : break;
250 : :
251 : 0 : case BTF_KIND_VAR:
252 : 0 : vlen_bytes += sizeof (struct btf_var);
253 : 0 : break;
254 : :
255 : 0 : case BTF_KIND_DATASEC:
256 : 0 : vlen_bytes += vlen * sizeof (struct btf_var_secinfo);
257 : 0 : break;
258 : :
259 : : default:
260 : : break;
261 : : }
262 : 366 : return vlen_bytes;
263 : : }
264 : :
265 : : /* Initialize BTF section (.BTF) for output. */
266 : :
267 : : void
268 : 107 : init_btf_sections (void)
269 : : {
270 : 107 : btf_info_section = get_section (BTF_INFO_SECTION_NAME, BTF_INFO_SECTION_FLAGS,
271 : : NULL);
272 : :
273 : 107 : ASM_GENERATE_INTERNAL_LABEL (btf_info_section_label,
274 : : BTF_INFO_SECTION_LABEL, btf_label_num++);
275 : 107 : }
276 : :
277 : : /* Return the section name, as of interest to btf_collect_datasec, for the
278 : : given symtab node. Note that this deliberately returns NULL for objects
279 : : which do not go in a section btf_collect_datasec cares about. */
280 : : static const char *
281 : 91 : get_section_name (symtab_node *node)
282 : : {
283 : 91 : const char *section_name = node->get_section ();
284 : :
285 : 8 : if (section_name == NULL)
286 : : {
287 : 83 : switch (categorize_decl_for_section (node->decl, 0))
288 : : {
289 : 52 : case SECCAT_BSS:
290 : 52 : section_name = ".bss";
291 : 52 : break;
292 : 22 : case SECCAT_DATA:
293 : 22 : section_name = ".data";
294 : 22 : break;
295 : 8 : case SECCAT_RODATA:
296 : 8 : section_name = ".rodata";
297 : 8 : break;
298 : : default:;
299 : : }
300 : : }
301 : :
302 : 91 : return section_name;
303 : : }
304 : :
305 : : /* Return true iff DMD is a member description of a bit-field which can be
306 : : validly represented in BTF. */
307 : :
308 : : static bool
309 : 78 : btf_dmd_representable_bitfield_p (ctf_dmdef_t *dmd)
310 : : {
311 : 78 : ctf_dtdef_ref ref_type = dmd->dmd_type;
312 : 78 : if (!ref_type)
313 : : return false;
314 : :
315 : 78 : if (CTF_V2_INFO_KIND (ref_type->dtd_data.ctti_info) == CTF_K_SLICE)
316 : : {
317 : 14 : unsigned short word_offset = ref_type->dtd_u.dtu_slice.cts_offset;
318 : 14 : unsigned short bits = ref_type->dtd_u.dtu_slice.cts_bits;
319 : 14 : uint64_t sou_offset = dmd->dmd_offset;
320 : :
321 : 14 : if ((bits > 0xff) || ((sou_offset + word_offset) > 0xffffff))
322 : : return false;
323 : :
324 : 12 : return true;
325 : : }
326 : :
327 : : return false;
328 : : }
329 : :
330 : : /* BTF asm helper routines. */
331 : :
332 : : /* Asm'out a reference to another BTF type. */
333 : :
334 : : static void
335 : 467 : btf_asm_type_ref (const char *prefix, ctf_dtdef_ref dtd)
336 : : {
337 : 467 : if (!dtd || !btf_emit_type_p (dtd))
338 : 12 : dw2_asm_output_data (4, BTF_VOID_TYPEID, "%s: void", prefix);
339 : : else
340 : : {
341 : 455 : uint32_t kind = btf_dtd_kind (dtd);
342 : 455 : if (btf_fwd_to_enum_p (dtd))
343 : : kind = BTF_KIND_ENUM;
344 : 454 : else if (kind == BTF_KIND_FUNC_PROTO && dtd->dtd_type > max_translated_id)
345 : 3 : kind = BTF_KIND_FUNC;
346 : :
347 : 735 : dw2_asm_output_data (4, dtd->dtd_type, "%s: (BTF_KIND_%s '%s')",
348 : : prefix, btf_kind_name (kind),
349 : : get_btf_type_name (dtd));
350 : : }
351 : 467 : }
352 : :
353 : : /* Asm'out a BTF type. This routine is responsible for the bulk of the task
354 : : of converting CTF types to their BTF representation. */
355 : :
356 : : static void
357 : 366 : btf_asm_type (ctf_dtdef_ref dtd)
358 : : {
359 : 366 : uint32_t btf_kind, btf_kflag, btf_vlen, btf_size;
360 : 366 : uint32_t ctf_info = dtd->dtd_data.ctti_info;
361 : :
362 : 366 : btf_kind = btf_dtd_kind (dtd);
363 : 366 : btf_size = dtd->dtd_data.ctti_size;
364 : 366 : btf_vlen = CTF_V2_INFO_VLEN (ctf_info);
365 : :
366 : : /* By now any unrepresentable types have been removed. */
367 : 366 : gcc_assert (btf_kind != BTF_KIND_UNKN);
368 : :
369 : : /* Size 0 integers are redundant definitions of void. None should remain
370 : : in the types list by this point. */
371 : 366 : gcc_assert (btf_kind != BTF_KIND_INT || btf_size >= 1);
372 : :
373 : : /* Re-encode the ctti_info to BTF. */
374 : : /* kflag is 1 for structs/unions with a bitfield member.
375 : : kflag is 1 for forwards to unions.
376 : : kflag is 0 in all other cases. */
377 : 366 : btf_kflag = 0;
378 : :
379 : 366 : if (btf_kind == BTF_KIND_STRUCT || btf_kind == BTF_KIND_UNION)
380 : : {
381 : : /* If a struct/union has ANY bitfield members, set kflag=1. */
382 : 32 : ctf_dmdef_t *dmd;
383 : 32 : for (dmd = dtd->dtd_u.dtu_members;
384 : 97 : dmd != NULL; dmd = (ctf_dmdef_t *) ctf_dmd_list_next (dmd))
385 : : {
386 : : /* Set kflag if this member is a representable bitfield. */
387 : 69 : if (btf_dmd_representable_bitfield_p (dmd))
388 : : {
389 : : btf_kflag = 1;
390 : : break;
391 : : }
392 : : }
393 : : }
394 : :
395 : : /* BTF forwards make use of KIND_FLAG to distinguish between forwards to
396 : : structs and forwards to unions. The dwarf2ctf conversion process stores
397 : : the kind of the forward in ctti_type, but for BTF this must be 0 for
398 : : forwards, with only the KIND_FLAG to distinguish.
399 : : Forwards to enum types are special-cased below. */
400 : 334 : else if (btf_kind == BTF_KIND_FWD)
401 : : {
402 : 5 : if (dtd->dtd_data.ctti_type == CTF_K_UNION)
403 : : btf_kflag = 1;
404 : :
405 : : /* PR debug/111735. Encode foward-declared enums as BTF_KIND_ENUM
406 : : with vlen=0. A representation for these is not formally defined;
407 : : this is the de-facto standard used by other tools like clang
408 : : and pahole. */
409 : 4 : else if (dtd->dtd_data.ctti_type == CTF_K_ENUM)
410 : : {
411 : 1 : btf_kind = BTF_KIND_ENUM;
412 : 1 : btf_vlen = 0;
413 : : }
414 : :
415 : : btf_size = 0;
416 : : }
417 : :
418 : 329 : else if (btf_kind == BTF_KIND_ENUM)
419 : : {
420 : 8 : btf_kflag = dtd->dtd_enum_unsigned
421 : 8 : ? BTF_KF_ENUM_UNSIGNED
422 : : : BTF_KF_ENUM_SIGNED;
423 : 8 : if (dtd->dtd_data.ctti_size == 0x8)
424 : 3 : btf_kind = BTF_KIND_ENUM64;
425 : : }
426 : :
427 : : /* PR debug/112656. BTF_KIND_FUNC_PROTO is always anonymous. */
428 : 321 : else if (btf_kind == BTF_KIND_FUNC_PROTO)
429 : 87 : dtd->dtd_data.ctti_name = 0;
430 : :
431 : 568 : dw2_asm_output_data (4, dtd->dtd_data.ctti_name,
432 : : "TYPE %" PRIu64 " BTF_KIND_%s '%s'",
433 : : dtd->dtd_type, btf_kind_name (btf_kind),
434 : : get_btf_type_name (dtd));
435 : 725 : dw2_asm_output_data (4, BTF_TYPE_INFO (btf_kind, btf_kflag, btf_vlen),
436 : : "btt_info: kind=%u, kflag=%u, vlen=%u",
437 : : btf_kind, btf_kflag, btf_vlen);
438 : 366 : switch (btf_kind)
439 : : {
440 : 195 : case BTF_KIND_INT:
441 : 195 : case BTF_KIND_FLOAT:
442 : 195 : case BTF_KIND_STRUCT:
443 : 195 : case BTF_KIND_UNION:
444 : 195 : case BTF_KIND_ENUM:
445 : 195 : case BTF_KIND_DATASEC:
446 : 195 : case BTF_KIND_ENUM64:
447 : 195 : dw2_asm_output_data (4, btf_size, "btt_size: %uB", btf_size);
448 : 195 : return;
449 : 26 : case BTF_KIND_ARRAY:
450 : 26 : case BTF_KIND_FWD:
451 : : /* These types do not encode any information in the size/type field
452 : : and should write 0. */
453 : 26 : dw2_asm_output_data (4, 0, "(unused)");
454 : 26 : return;
455 : 145 : default:
456 : 145 : break;
457 : : }
458 : :
459 : 145 : btf_asm_type_ref ("btt_type", dtd->ref_type);
460 : : }
461 : :
462 : : /* Asm'out the variable information following a BTF_KIND_ARRAY. */
463 : :
464 : : static void
465 : 22 : btf_asm_array (ctf_arinfo_t arr)
466 : : {
467 : 22 : btf_asm_type_ref ("bta_elem_type", arr.ctr_contents);
468 : 22 : btf_asm_type_ref ("bta_index_type", arr.ctr_index);
469 : 22 : dw2_asm_output_data (4, arr.ctr_nelems, "bta_nelems");
470 : 22 : }
471 : :
472 : : /* Asm'out a BTF_KIND_VAR. */
473 : :
474 : : static void
475 : 91 : btf_asm_varent (ctf_dvdef_ref var)
476 : : {
477 : 91 : dw2_asm_output_data (4, var->dvd_name_offset,
478 : : "TYPE %" PRIu64 " BTF_KIND_VAR '%s'",
479 : : var->dvd_id, var->dvd_name);
480 : 91 : dw2_asm_output_data (4, BTF_TYPE_INFO (BTF_KIND_VAR, 0, 0), "btv_info");
481 : 91 : btf_asm_type_ref ("btv_type", var->dvd_type);
482 : 91 : dw2_asm_output_data (4, var->dvd_visibility, "btv_linkage");
483 : 91 : }
484 : :
485 : : /* Asm'out a member description following a BTF_KIND_STRUCT or
486 : : BTF_KIND_UNION. */
487 : :
488 : : static void
489 : 73 : btf_asm_sou_member (ctf_dmdef_t * dmd, unsigned int idx)
490 : : {
491 : 73 : ctf_dtdef_ref base_type = dmd->dmd_type;
492 : 73 : uint64_t sou_offset = dmd->dmd_offset;
493 : :
494 : 73 : dw2_asm_output_data (4, dmd->dmd_name_offset,
495 : : "MEMBER '%s' idx=%u",
496 : : dmd->dmd_name, idx);
497 : :
498 : 73 : if (base_type
499 : 73 : && CTF_V2_INFO_KIND (base_type->dtd_data.ctti_info) == CTF_K_SLICE)
500 : : {
501 : 9 : if (btf_dmd_representable_bitfield_p (dmd))
502 : : {
503 : 8 : unsigned short word_offset = base_type->dtd_u.dtu_slice.cts_offset;
504 : 8 : unsigned short bits = base_type->dtd_u.dtu_slice.cts_bits;
505 : :
506 : : /* Pack the bit offset and bitfield size together. */
507 : 8 : sou_offset += word_offset;
508 : 8 : sou_offset &= 0x00ffffff;
509 : 8 : sou_offset |= ((bits & 0xff) << 24);
510 : :
511 : : /* Refer to the base type of the slice. */
512 : 8 : base_type = base_type->dtd_u.dtu_slice.cts_type;
513 : : }
514 : : else
515 : : {
516 : : /* Bitfield cannot be represented in BTF. Emit the member as having
517 : : 'void' type. */
518 : : base_type = NULL;
519 : : }
520 : : }
521 : :
522 : 73 : btf_asm_type_ref ("btm_type", base_type);
523 : 73 : dw2_asm_output_data (4, sou_offset, "btm_offset");
524 : 73 : }
525 : :
526 : : /* Asm'out an enum constant following a BTF_KIND_ENUM{,64}. */
527 : :
528 : : static void
529 : 25 : btf_asm_enum_const (unsigned int size, ctf_dmdef_t * dmd, unsigned int idx)
530 : : {
531 : 25 : dw2_asm_output_data (4, dmd->dmd_name_offset, "ENUM_CONST '%s' idx=%u",
532 : : dmd->dmd_name, idx);
533 : 25 : if (size <= 4)
534 : 16 : dw2_asm_output_data (size < 4 ? 4 : size, dmd->dmd_value, "bte_value");
535 : : else
536 : : {
537 : 9 : dw2_asm_output_data (4, dmd->dmd_value & 0xffffffff, "bte_value_lo32");
538 : 9 : dw2_asm_output_data (4, (dmd->dmd_value >> 32) & 0xffffffff, "bte_value_hi32");
539 : : }
540 : 25 : }
541 : :
542 : : /* Asm'out a function parameter description following a BTF_KIND_FUNC_PROTO. */
543 : :
544 : : static void
545 : 26 : btf_asm_func_arg (ctf_func_arg_t * farg, size_t stroffset)
546 : : {
547 : : /* If the function arg does not have a name, refer to the null string at
548 : : the start of the string table. This ensures correct encoding for varargs
549 : : '...' arguments. */
550 : 26 : if ((farg->farg_name != NULL) && strcmp (farg->farg_name, ""))
551 : 15 : dw2_asm_output_data (4, farg->farg_name_offset + stroffset,
552 : : "farg_name '%s'", farg->farg_name);
553 : : else
554 : 11 : dw2_asm_output_data (4, 0, "farg_name ''");
555 : :
556 : 26 : btf_asm_type_ref ("farg_type", farg->farg_type);
557 : 26 : }
558 : :
559 : : /* Asm'out a BTF_KIND_FUNC type. */
560 : :
561 : : static void
562 : 85 : btf_asm_func_type (ctf_dtdef_ref dtd)
563 : : {
564 : 170 : dw2_asm_output_data (4, dtd->dtd_data.ctti_name,
565 : : "TYPE %" PRIu64 " BTF_KIND_FUNC '%s'",
566 : : dtd->dtd_type, get_btf_type_name (dtd));
567 : 85 : dw2_asm_output_data (4, BTF_TYPE_INFO (BTF_KIND_FUNC, 0, dtd->linkage),
568 : : "btt_info: kind=%u, kflag=%u, linkage=%u",
569 : : BTF_KIND_FUNC, 0, dtd->linkage);
570 : 85 : btf_asm_type_ref ("btt_type", dtd->ref_type);
571 : 85 : }
572 : :
573 : : /* Asm'out a variable entry following a BTF_KIND_DATASEC. */
574 : :
575 : : static void
576 : 90 : btf_asm_datasec_entry (struct btf_datasec_entry entry)
577 : : {
578 : 90 : const char *symbol_name = NULL;
579 : 90 : if (entry.is_var)
580 : : {
581 : 87 : symbol_name = entry.dvd->dvd_name;
582 : 87 : dw2_asm_output_data (4, entry.dvd->dvd_id,
583 : : "bts_type: (BTF_KIND_VAR '%s')", symbol_name);
584 : : }
585 : : else
586 : : {
587 : 3 : symbol_name = entry.dtd->dtd_name;
588 : 3 : btf_asm_type_ref ("bts_type", entry.dtd);
589 : : }
590 : :
591 : 90 : if (!btf_with_core_debuginfo_p () || symbol_name == NULL)
592 : 90 : dw2_asm_output_data (4, 0, "bts_offset");
593 : : else
594 : 0 : dw2_asm_output_offset (4, symbol_name, NULL, "bts_offset");
595 : :
596 : 90 : dw2_asm_output_data (4, entry.size, "bts_size");
597 : 90 : }
598 : :
599 : : /* Asm'out a whole BTF_KIND_DATASEC, including its variable entries. */
600 : :
601 : : static void
602 : 44 : btf_asm_datasec_type (btf_datasec_t ds)
603 : : {
604 : 44 : dw2_asm_output_data (4, ds.name_offset,
605 : : "TYPE %" PRIu64 " BTF_KIND_DATASEC '%s'",
606 : : ds.id, ds.name);
607 : 88 : dw2_asm_output_data (4, BTF_TYPE_INFO (BTF_KIND_DATASEC, 0,
608 : : ds.entries.length ()),
609 : : "btt_info: n_entries=%u", ds.entries.length ());
610 : : /* Note: the "total section size in bytes" is emitted as 0 and patched by
611 : : loaders such as libbpf. */
612 : 44 : dw2_asm_output_data (4, 0, "btt_size");
613 : 134 : for (size_t i = 0; i < ds.entries.length (); i++)
614 : 90 : btf_asm_datasec_entry (ds.entries[i]);
615 : 44 : }
616 : :
617 : : /* Compute and output the header information for a .BTF section. */
618 : :
619 : : static void
620 : 107 : output_btf_header (ctf_container_ref ctfc)
621 : : {
622 : 107 : switch_to_section (btf_info_section);
623 : 107 : ASM_OUTPUT_LABEL (asm_out_file, btf_info_section_label);
624 : :
625 : : /* BTF magic number, version, flags, and header length. */
626 : 107 : dw2_asm_output_data (2, BTF_MAGIC, "btf_magic");
627 : 107 : dw2_asm_output_data (1, BTF_VERSION, "btf_version");
628 : 107 : dw2_asm_output_data (1, 0, "btf_flags");
629 : 107 : dw2_asm_output_data (4, sizeof (struct btf_header), "btf_hdr_len");
630 : :
631 : 107 : uint32_t type_off = 0, type_len = 0;
632 : 107 : uint32_t str_off = 0, str_len = 0;
633 : :
634 : 107 : if (!ctfc_is_empty_container (ctfc))
635 : : {
636 : : /* Total length (bytes) of the types section. */
637 : 107 : type_len = ctfc->ctfc_num_types * sizeof (struct btf_type)
638 : 107 : + ctfc->ctfc_num_vlen_bytes;
639 : :
640 : 107 : str_off = type_off + type_len;
641 : :
642 : 107 : str_len = ctfc->ctfc_strtable.ctstab_len
643 : 107 : + ctfc->ctfc_aux_strtable.ctstab_len;
644 : : }
645 : :
646 : : /* Offset of type section. */
647 : 107 : dw2_asm_output_data (4, type_off, "type_off");
648 : : /* Length of type section in bytes. */
649 : 107 : dw2_asm_output_data (4, type_len, "type_len: ntypes=%u, vlen=%u",
650 : 107 : (uint32_t) ctfc->ctfc_num_types,
651 : 107 : (uint32_t) ctfc->ctfc_num_vlen_bytes);
652 : : /* Offset of string section. */
653 : 107 : dw2_asm_output_data (4, str_off, "str_off");
654 : : /* Length of string section in bytes. */
655 : 107 : dw2_asm_output_data (4, str_len, "str_len");
656 : 107 : }
657 : :
658 : : /* Output all BTF_KIND_VARs in CTFC. */
659 : :
660 : : static void
661 : 107 : output_btf_vars (ctf_container_ref ctfc)
662 : : {
663 : 107 : size_t i;
664 : 107 : size_t num_ctf_vars = ctfc->ctfc_vars_list_count;
665 : 107 : if (num_ctf_vars)
666 : : {
667 : 122 : for (i = 0; i < num_ctf_vars; i++)
668 : 91 : btf_asm_varent (ctfc->ctfc_vars_list[i]);
669 : : }
670 : 107 : }
671 : :
672 : : /* Output BTF string records. The BTF strings section is a concatenation
673 : : of the standard and auxilliary string tables in the ctf container. */
674 : :
675 : : static void
676 : 107 : output_btf_strs (ctf_container_ref ctfc)
677 : : {
678 : 107 : ctf_string_t * ctf_string = ctfc->ctfc_strtable.ctstab_head;
679 : 107 : static int str_pos = 0;
680 : :
681 : 702 : while (ctf_string)
682 : : {
683 : 595 : dw2_asm_output_nstring (ctf_string->cts_str, -1,
684 : : "btf_string, str_pos = 0x%x", str_pos);
685 : 595 : str_pos += strlen(ctf_string->cts_str) + 1;
686 : 595 : ctf_string = ctf_string->cts_next;
687 : : }
688 : :
689 : 107 : ctf_string = ctfc->ctfc_aux_strtable.ctstab_head;
690 : 273 : while (ctf_string)
691 : : {
692 : 166 : dw2_asm_output_nstring (ctf_string->cts_str, -1,
693 : : "btf_aux_string, str_pos = 0x%x", str_pos);
694 : 166 : str_pos += strlen(ctf_string->cts_str) + 1;
695 : 166 : ctf_string = ctf_string->cts_next;
696 : : }
697 : 107 : }
698 : :
699 : : /* Output all (representable) members of a BTF_KIND_STRUCT or
700 : : BTF_KIND_UNION type. */
701 : :
702 : : static void
703 : 32 : output_asm_btf_sou_fields (ctf_dtdef_ref dtd)
704 : : {
705 : 32 : ctf_dmdef_t * dmd;
706 : :
707 : 32 : unsigned idx = 0;
708 : 32 : for (dmd = dtd->dtd_u.dtu_members;
709 : 105 : dmd != NULL; dmd = (ctf_dmdef_t *) ctf_dmd_list_next (dmd))
710 : : {
711 : 73 : btf_asm_sou_member (dmd, idx);
712 : 73 : idx++;
713 : : }
714 : 32 : }
715 : :
716 : : /* Output all enumerator constants following a BTF_KIND_ENUM{,64}. */
717 : :
718 : : static void
719 : 8 : output_asm_btf_enum_list (ctf_dtdef_ref dtd)
720 : : {
721 : 8 : ctf_dmdef_t * dmd;
722 : :
723 : 8 : unsigned idx = 0;
724 : 8 : for (dmd = dtd->dtd_u.dtu_members;
725 : 33 : dmd != NULL; dmd = (ctf_dmdef_t *) ctf_dmd_list_next (dmd))
726 : : {
727 : 25 : btf_asm_enum_const (dtd->dtd_data.ctti_size, dmd, idx);
728 : 25 : idx++;
729 : : }
730 : 8 : }
731 : :
732 : : /* Output all function arguments following a BTF_KIND_FUNC_PROTO. */
733 : :
734 : : static void
735 : 87 : output_asm_btf_func_args_list (ctf_container_ref ctfc,
736 : : ctf_dtdef_ref dtd)
737 : : {
738 : 87 : size_t farg_name_offset = ctfc_get_strtab_len (ctfc, CTF_STRTAB);
739 : 87 : ctf_func_arg_t * farg;
740 : 87 : for (farg = dtd->dtd_u.dtu_argv;
741 : 113 : farg != NULL; farg = (ctf_func_arg_t *) ctf_farg_list_next (farg))
742 : 26 : btf_asm_func_arg (farg, farg_name_offset);
743 : 87 : }
744 : :
745 : : /* Output the variable portion of a BTF type record. The information depends
746 : : on the kind of the type. */
747 : :
748 : : static void
749 : 366 : output_asm_btf_vlen_bytes (ctf_container_ref ctfc, ctf_dtdef_ref dtd)
750 : : {
751 : 366 : uint32_t btf_kind, encoding;
752 : :
753 : 366 : btf_kind = btf_dtd_kind (dtd);
754 : :
755 : 366 : if (btf_kind == BTF_KIND_UNKN)
756 : : return;
757 : :
758 : 366 : switch (btf_kind)
759 : : {
760 : 148 : case BTF_KIND_INT:
761 : : /* Redundant definitions of void may still be hanging around in the type
762 : : list as size 0 integers. Skip emitting them. */
763 : 148 : if (dtd->dtd_data.ctti_size < 1)
764 : : break;
765 : :
766 : : /* In BTF the CHAR `encoding' seems to not be used, so clear it here. */
767 : 148 : dtd->dtd_u.dtu_enc.cte_format &= ~BTF_INT_CHAR;
768 : :
769 : 148 : encoding = BTF_INT_DATA (dtd->dtd_u.dtu_enc.cte_format,
770 : : dtd->dtd_u.dtu_enc.cte_offset,
771 : : dtd->dtd_u.dtu_enc.cte_bits);
772 : :
773 : 148 : dw2_asm_output_data (4, encoding, "bti_encoding");
774 : 148 : break;
775 : :
776 : 22 : case BTF_KIND_ARRAY:
777 : 22 : btf_asm_array (dtd->dtd_u.dtu_arr);
778 : 22 : break;
779 : :
780 : 32 : case BTF_KIND_STRUCT:
781 : 32 : case BTF_KIND_UNION:
782 : 32 : output_asm_btf_sou_fields (dtd);
783 : 32 : break;
784 : :
785 : 8 : case BTF_KIND_ENUM:
786 : 8 : output_asm_btf_enum_list (dtd);
787 : 8 : break;
788 : :
789 : 87 : case BTF_KIND_FUNC_PROTO:
790 : 87 : output_asm_btf_func_args_list (ctfc, dtd);
791 : 87 : break;
792 : :
793 : 0 : case BTF_KIND_VAR:
794 : : /* BTF Variables are handled by output_btf_vars and btf_asm_varent.
795 : : There should be no BTF_KIND_VAR types at this point. */
796 : 0 : gcc_unreachable ();
797 : :
798 : 0 : case BTF_KIND_DATASEC:
799 : : /* The BTF_KIND_DATASEC records are handled by output_btf_datasec_types
800 : : and btf_asm_datasec_type. There should be no BTF_KIND_DATASEC types
801 : : at this point. */
802 : 0 : gcc_unreachable ();
803 : :
804 : : default:
805 : : /* All other BTF type kinds have no variable length data. */
806 : : break;
807 : : }
808 : : }
809 : :
810 : : /* Output a whole BTF type record for TYPE, including the fixed and variable
811 : : data portions. */
812 : :
813 : : static void
814 : 384 : output_asm_btf_type (ctf_container_ref ctfc, ctf_dtdef_ref type)
815 : : {
816 : 384 : if (btf_emit_type_p (type))
817 : : {
818 : 366 : btf_asm_type (type);
819 : 366 : output_asm_btf_vlen_bytes (ctfc, type);
820 : : }
821 : 384 : }
822 : :
823 : : /* Output all BTF types in the container. This does not include synthesized
824 : : types: BTF_KIND_VAR, BTF_KIND_FUNC, nor BTF_KIND_DATASEC. */
825 : :
826 : : static void
827 : 107 : output_btf_types (ctf_container_ref ctfc)
828 : : {
829 : 107 : size_t i;
830 : 107 : size_t num_types;
831 : 107 : if (debug_prune_btf)
832 : 4 : num_types = max_translated_id;
833 : : else
834 : 103 : num_types = ctfc->ctfc_types->elements ();
835 : :
836 : 107 : if (num_types)
837 : : {
838 : 491 : for (i = 1; i <= num_types; i++)
839 : 384 : output_asm_btf_type (ctfc, ctfc->ctfc_types_list[i]);
840 : : }
841 : 107 : }
842 : :
843 : : /* Output all BTF_KIND_FUNC type records. */
844 : :
845 : : static void
846 : 107 : output_btf_func_types (void)
847 : : {
848 : 107 : ctf_dtdef_ref ref;
849 : 107 : unsigned i;
850 : 192 : FOR_EACH_VEC_ELT (*funcs, i, ref)
851 : 85 : btf_asm_func_type (ref);
852 : 107 : }
853 : :
854 : : /* Output all BTF_KIND_DATASEC records. */
855 : :
856 : : static void
857 : 107 : output_btf_datasec_types (void)
858 : : {
859 : 151 : for (size_t i = 0; i < datasecs.length (); i++)
860 : 44 : btf_asm_datasec_type (datasecs[i]);
861 : 107 : }
862 : :
863 : : /* Write out all BTF debug info. */
864 : :
865 : : void
866 : 107 : btf_output (ctf_container_ref ctfc)
867 : : {
868 : 107 : output_btf_header (ctfc);
869 : 107 : output_btf_types (ctfc);
870 : 107 : output_btf_vars (ctfc);
871 : 107 : output_btf_func_types ();
872 : 107 : output_btf_datasec_types ();
873 : 107 : output_btf_strs (ctfc);
874 : 107 : }
875 : :
876 : : /* Workaround for 'const void' variables. These variables are sometimes used
877 : : in eBPF programs to address kernel symbols. DWARF does not generate const
878 : : qualifier on void type, so we would incorrectly emit these variables
879 : : without the const qualifier. Find any such variables, and update them to
880 : : refer to a new 'const' modifier type for void. */
881 : :
882 : : static void
883 : 107 : btf_add_const_void (ctf_container_ref ctfc)
884 : : {
885 : 107 : ctf_dtdef_ref constvoid_dtd = NULL;
886 : 107 : varpool_node *var;
887 : 398 : FOR_EACH_VARIABLE (var)
888 : : {
889 : 92 : if (!var->decl)
890 : 0 : continue;
891 : :
892 : 92 : tree type = TREE_TYPE (var->decl);
893 : 92 : if (type && VOID_TYPE_P (type) && TYPE_READONLY (type))
894 : : {
895 : 1 : dw_die_ref die = lookup_decl_die (var->decl);
896 : 1 : if (die == NULL)
897 : 0 : continue;
898 : :
899 : 1 : ctf_dvdef_ref dvd = ctf_dvd_lookup (ctfc, die);
900 : 1 : if (dvd == NULL)
901 : 0 : continue;
902 : :
903 : : /* Create the 'const' modifier type for void. */
904 : 1 : if (constvoid_dtd == NULL)
905 : 1 : constvoid_dtd = ctf_add_reftype (ctfc, CTF_ADD_ROOT,
906 : : dvd->dvd_type, CTF_K_CONST, NULL);
907 : 1 : dvd->dvd_type = constvoid_dtd;
908 : : }
909 : : }
910 : 107 : }
911 : :
912 : : /* Functions actually get two type records: a BTF_KIND_FUNC_PROTO, and also a
913 : : BTF_KIND_FUNC. But the CTF container only allocates one type per function,
914 : : which matches closely with BTF_KIND_FUNC_PROTO. For each such function,
915 : : construct a BTF_KIND_FUNC entry. This is done early, because we want FUNC
916 : : records even for functions which are later inlined by optimizations. */
917 : :
918 : : static void
919 : 107 : btf_add_func_records (ctf_container_ref ctfc)
920 : : {
921 : 107 : cgraph_node *func;
922 : 384 : FOR_EACH_FUNCTION (func)
923 : : {
924 : 85 : dw_die_ref die = lookup_decl_die (func->decl);
925 : 85 : if (die == NULL)
926 : 0 : continue;
927 : :
928 : 85 : ctf_dtdef_ref dtd = ctf_dtd_lookup (ctfc, die);
929 : 85 : if (dtd == NULL)
930 : 0 : continue;
931 : :
932 : : /* Do not add FUNC records for kernel helpers. */
933 : 85 : if (DECL_EXTERNAL (func->decl)
934 : 89 : && (lookup_attribute ("kernel_helper",
935 : 4 : DECL_ATTRIBUTES (func->decl))) != NULL_TREE)
936 : 0 : continue;
937 : :
938 : 85 : ctf_dtdef_ref func_dtd = ggc_cleared_alloc<ctf_dtdef_t> ();
939 : 85 : func_dtd->dtd_data = dtd->dtd_data;
940 : 85 : func_dtd->dtd_data.ctti_type = dtd->dtd_type;
941 : 85 : func_dtd->ref_type = dtd;
942 : 85 : func_dtd->linkage = dtd->linkage;
943 : 85 : func_dtd->dtd_name = dtd->dtd_name;
944 : : /* Type ID will be assigned just before output. */
945 : :
946 : : /* Only the BTF_KIND_FUNC type actually references the name.
947 : : The BTF_KIND_FUNC_PROTO is always anonymous. */
948 : 85 : dtd->dtd_data.ctti_name = 0;
949 : :
950 : : /* Mark 'extern' funcs. */
951 : 85 : if (DECL_EXTERNAL (func->decl))
952 : 4 : func_dtd->linkage = BTF_FUNC_EXTERN;
953 : :
954 : : /* Buffer newly created FUNC records. We cannot simply insert them
955 : : into the types map, because types are keyed by their DWARF DIE,
956 : : and we have no unique DIE to use as a key since the FUNC_PROTOs
957 : : are already present in the map. */
958 : 85 : vec_safe_push (funcs, func_dtd);
959 : 85 : func_map->put (dtd, func_dtd);
960 : : }
961 : 107 : }
962 : :
963 : : /* The set of types used directly in the source program, and any types manually
964 : : marked as used. This is the set of types which will be emitted when
965 : : flag_prune_btf is set. */
966 : : static GTY (()) hash_set<ctf_dtdef_ref> *btf_used_types;
967 : :
968 : : /* Fixup used to avoid unnecessary pointer chasing for types. A fixup is
969 : : created when a structure or union member is a pointer to another struct
970 : : or union type. In such cases, avoid emitting full type information for
971 : : the pointee struct or union type (which may be quite large), unless that
972 : : type is used directly elsewhere. */
973 : : struct btf_fixup
974 : : {
975 : : ctf_dtdef_ref pointer_dtd; /* Type node to which the fixup is applied. */
976 : : ctf_dtdef_ref pointee_dtd; /* Original type node referred to by pointer_dtd.
977 : : If this concrete type is not otherwise used,
978 : : then a forward is created. */
979 : : };
980 : :
981 : : /* Stores fixups while processing types. */
982 : : static vec<struct btf_fixup> fixups;
983 : :
984 : : /* For fixups where the underlying type is not used in the end, a BTF_KIND_FWD
985 : : is created and emitted. This vector stores them. */
986 : : static GTY (()) vec<ctf_dtdef_ref, va_gc> *forwards;
987 : :
988 : : /* Recursively add type DTD and any types it references to the used set.
989 : : Return a type that should be used for references to DTD - usually DTD itself,
990 : : but may be NULL if DTD corresponds to a type which will not be emitted.
991 : : CHECK_PTR is true if one of the predecessors in recursive calls is a struct
992 : : or union member. SEEN_PTR is true if CHECK_PTR is true AND one of the
993 : : predecessors was a pointer type. These two flags are used to avoid chasing
994 : : pointers to struct/union only used from pointer members. For such types, we
995 : : will emit a forward instead of the full type information, unless
996 : : CREATE_FIXUPS is false. */
997 : :
998 : : static ctf_dtdef_ref
999 : 54 : btf_add_used_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd,
1000 : : bool check_ptr, bool seen_ptr, bool create_fixups)
1001 : : {
1002 : 54 : if (dtd == NULL)
1003 : : return NULL;
1004 : :
1005 : 54 : uint32_t ctf_kind = CTF_V2_INFO_KIND (dtd->dtd_data.ctti_info);
1006 : 54 : uint32_t kind = get_btf_kind (ctf_kind);
1007 : :
1008 : : /* Check whether the type has already been added. */
1009 : 54 : if (btf_used_types->contains (dtd))
1010 : : {
1011 : : /* It's possible the type was already added as a fixup, but that we now
1012 : : have a concrete use of it. */
1013 : 13 : switch (kind)
1014 : : {
1015 : 5 : case BTF_KIND_PTR:
1016 : 5 : case BTF_KIND_TYPEDEF:
1017 : 5 : case BTF_KIND_CONST:
1018 : 5 : case BTF_KIND_VOLATILE:
1019 : 5 : case BTF_KIND_RESTRICT:
1020 : 5 : if (check_ptr)
1021 : : /* Type was previously added as a fixup, and that's OK. */
1022 : : return dtd;
1023 : : else
1024 : : {
1025 : : /* The type was previously added as a fixup, but now we have
1026 : : a concrete use of it. Remove the fixup. */
1027 : 3 : for (size_t i = 0; i < fixups.length (); i++)
1028 : 1 : if (fixups[i].pointer_dtd == dtd)
1029 : 1 : fixups.unordered_remove (i);
1030 : :
1031 : : /* Add the concrete base type. */
1032 : 2 : dtd->ref_type = btf_add_used_type (ctfc, dtd->ref_type, check_ptr,
1033 : : seen_ptr, create_fixups);
1034 : 2 : return dtd;
1035 : : }
1036 : : default:
1037 : : return dtd;
1038 : : }
1039 : : }
1040 : :
1041 : 41 : if (ctf_kind == CTF_K_SLICE)
1042 : : {
1043 : : /* Bitfield. Add the underlying type to the used set, but leave
1044 : : the reference to the bitfield. The slice type won't be emitted,
1045 : : but we need the information in it when writing out the bitfield
1046 : : encoding. */
1047 : 0 : btf_add_used_type (ctfc, dtd->dtd_u.dtu_slice.cts_type,
1048 : : check_ptr, seen_ptr, create_fixups);
1049 : 0 : return dtd;
1050 : : }
1051 : :
1052 : : /* Skip redundant definitions of void and types with no BTF encoding. */
1053 : 41 : if ((kind == BTF_KIND_INT && dtd->dtd_data.ctti_size == 0)
1054 : 40 : || (kind == BTF_KIND_UNKN))
1055 : : return NULL;
1056 : :
1057 : : /* Add the type itself, and assign its id.
1058 : : Do this before recursing to handle things like linked list structures. */
1059 : 40 : gcc_assert (ctfc->ctfc_nextid <= BTF_MAX_TYPE);
1060 : 40 : dtd->dtd_type = ctfc->ctfc_nextid++;
1061 : 40 : btf_used_types->add (dtd);
1062 : 40 : ctf_add_string (ctfc, dtd->dtd_name, &(dtd->dtd_data.ctti_name), CTF_STRTAB);
1063 : 40 : ctfc->ctfc_num_types++;
1064 : 40 : ctfc->ctfc_num_vlen_bytes += btf_calc_num_vbytes (dtd);
1065 : :
1066 : : /* Recursively add types referenced by this type. */
1067 : 40 : switch (kind)
1068 : : {
1069 : : case BTF_KIND_INT:
1070 : : case BTF_KIND_FLOAT:
1071 : : case BTF_KIND_FWD:
1072 : : /* Leaf kinds which do not refer to any other types. */
1073 : : break;
1074 : :
1075 : 0 : case BTF_KIND_FUNC:
1076 : 0 : case BTF_KIND_VAR:
1077 : : /* Root kinds; no type we are visiting may refer to these. */
1078 : 0 : gcc_unreachable ();
1079 : :
1080 : 15 : case BTF_KIND_PTR:
1081 : 15 : case BTF_KIND_TYPEDEF:
1082 : 15 : case BTF_KIND_CONST:
1083 : 15 : case BTF_KIND_VOLATILE:
1084 : 15 : case BTF_KIND_RESTRICT:
1085 : 15 : {
1086 : : /* These type kinds refer to exactly one other type. */
1087 : 15 : if (check_ptr && !seen_ptr)
1088 : 5 : seen_ptr = (kind == BTF_KIND_PTR);
1089 : :
1090 : : /* Try to avoid chasing pointers to struct/union types if the
1091 : : underlying type isn't used. */
1092 : 15 : if (check_ptr && seen_ptr && create_fixups)
1093 : : {
1094 : 6 : ctf_dtdef_ref ref = dtd->ref_type;
1095 : 10 : uint32_t ref_kind = btf_dtd_kind (ref);
1096 : :
1097 : 6 : if ((ref_kind == BTF_KIND_STRUCT || ref_kind == BTF_KIND_UNION)
1098 : 6 : && !btf_used_types->contains (ref))
1099 : : {
1100 : 2 : struct btf_fixup fixup;
1101 : 2 : fixup.pointer_dtd = dtd;
1102 : 2 : fixup.pointee_dtd = ref;
1103 : 2 : fixups.safe_push (fixup);
1104 : 2 : break;
1105 : : }
1106 : : }
1107 : :
1108 : : /* Add the type to which this type refers. */
1109 : 13 : dtd->ref_type = btf_add_used_type (ctfc, dtd->ref_type, check_ptr,
1110 : : seen_ptr, create_fixups);
1111 : 13 : break;
1112 : : }
1113 : 2 : case BTF_KIND_ARRAY:
1114 : 2 : {
1115 : : /* Add element and index types. */
1116 : 2 : ctf_arinfo_t *arr = &(dtd->dtd_u.dtu_arr);
1117 : 2 : arr->ctr_contents = btf_add_used_type (ctfc, arr->ctr_contents, false,
1118 : : false, create_fixups);
1119 : 2 : arr->ctr_index = btf_add_used_type (ctfc, arr->ctr_index, false, false,
1120 : : create_fixups);
1121 : 2 : break;
1122 : : }
1123 : 7 : case BTF_KIND_STRUCT:
1124 : 7 : case BTF_KIND_UNION:
1125 : 7 : case BTF_KIND_ENUM:
1126 : 7 : case BTF_KIND_ENUM64:
1127 : 7 : {
1128 : : /* Add members. */
1129 : 7 : ctf_dmdef_t *dmd;
1130 : 7 : for (dmd = dtd->dtd_u.dtu_members;
1131 : 23 : dmd != NULL; dmd = (ctf_dmdef_t *) ctf_dmd_list_next (dmd))
1132 : : {
1133 : : /* Add member type for struct/union members. For enums, only the
1134 : : enumerator names are needed. */
1135 : 16 : if (kind == BTF_KIND_STRUCT || kind == BTF_KIND_UNION)
1136 : 16 : dmd->dmd_type = btf_add_used_type (ctfc, dmd->dmd_type, true,
1137 : : false, create_fixups);
1138 : 16 : ctf_add_string (ctfc, dmd->dmd_name, &(dmd->dmd_name_offset),
1139 : : CTF_STRTAB);
1140 : : }
1141 : : break;
1142 : : }
1143 : 4 : case BTF_KIND_FUNC_PROTO:
1144 : 4 : {
1145 : : /* Add return type. */
1146 : 4 : dtd->ref_type = btf_add_used_type (ctfc, dtd->ref_type, false, false,
1147 : : create_fixups);
1148 : :
1149 : : /* Add arg types. */
1150 : 4 : ctf_func_arg_t * farg;
1151 : 4 : for (farg = dtd->dtd_u.dtu_argv;
1152 : 13 : farg != NULL; farg = (ctf_func_arg_t *) ctf_farg_list_next (farg))
1153 : : {
1154 : 9 : farg->farg_type = btf_add_used_type (ctfc, farg->farg_type, false,
1155 : : false, create_fixups);
1156 : : /* Note: argument names are stored in the auxilliary string table,
1157 : : since CTF does not include arg names. That table has not been
1158 : : cleared, so no need to re-add argument names here. */
1159 : : }
1160 : : break;
1161 : : }
1162 : : default:
1163 : : return NULL;
1164 : : }
1165 : :
1166 : : return dtd;
1167 : : }
1168 : :
1169 : : /* Initial entry point of BTF generation, called at early_finish () after
1170 : : CTF information has possibly been output. Translate all CTF information
1171 : : to BTF, and do any processing that must be done early, such as creating
1172 : : BTF_KIND_FUNC records. */
1173 : :
1174 : : void
1175 : 107 : btf_early_finish (void)
1176 : : {
1177 : 107 : ctf_container_ref tu_ctfc = ctf_get_tu_ctfc ();
1178 : :
1179 : 107 : vec_alloc (funcs, 16);
1180 : 107 : func_map = hash_map<ctf_dtdef_ref, ctf_dtdef_ref>::create_ggc (16);
1181 : :
1182 : : /* Note: from this point on, destructive changes are made to the TU CTFC to
1183 : : translate CTF to BTF. If CTF debug info has also been requested, it must
1184 : : be emitted before starting the translation to BTF. */
1185 : 107 : btf_add_const_void (tu_ctfc);
1186 : 107 : btf_add_func_records (tu_ctfc);
1187 : :
1188 : : /* These fields are reset to count BTF types etc. */
1189 : 107 : tu_ctfc->ctfc_num_types = 0;
1190 : 107 : tu_ctfc->ctfc_num_vlen_bytes = 0;
1191 : 107 : tu_ctfc->ctfc_vars_list_count = 0;
1192 : :
1193 : 107 : if (debug_prune_btf)
1194 : : {
1195 : 4 : btf_used_types
1196 : 4 : = hash_set<ctf_dtdef_ref>::create_ggc (tu_ctfc->ctfc_types->elements ());
1197 : 4 : tu_ctfc->ctfc_nextid = 1;
1198 : 4 : fixups.create (1);
1199 : :
1200 : : /* Empty the string table, which was already populated with strings for
1201 : : all types translated from DWARF. We may only need a very small subset
1202 : : of these strings; those will be re-added below. */
1203 : 4 : ctfc_delete_strtab (&tu_ctfc->ctfc_strtable);
1204 : 4 : init_ctf_strtable (&tu_ctfc->ctfc_strtable);
1205 : 4 : tu_ctfc->ctfc_strlen++;
1206 : : }
1207 : 107 : }
1208 : :
1209 : : /* Push a BTF datasec entry ENTRY into the datasec named SECNAME,
1210 : : creating the datasec record if it does not already exist. */
1211 : :
1212 : : static void
1213 : 90 : btf_datasec_push_entry (ctf_container_ref ctfc, const char *secname,
1214 : : struct btf_datasec_entry entry)
1215 : : {
1216 : 90 : if (secname == NULL)
1217 : 46 : return;
1218 : :
1219 : : /* If we already have a datasec record for the appropriate section,
1220 : : append the new entry to it. */
1221 : 113 : for (size_t i = 0; i < datasecs.length (); i++)
1222 : 69 : if (strcmp (datasecs[i].name, secname) == 0)
1223 : : {
1224 : 46 : datasecs[i].entries.safe_push (entry);
1225 : 46 : return;
1226 : : }
1227 : :
1228 : : /* If we don't already have a datasec record for secname, make one. */
1229 : 44 : uint32_t str_off;
1230 : 44 : ctf_add_string (ctfc, secname, &str_off, CTF_AUX_STRTAB);
1231 : 44 : if (strcmp (secname, ""))
1232 : 44 : ctfc->ctfc_aux_strlen += strlen (secname) + 1;
1233 : :
1234 : : /* Note: ID will be assigned just before output. */
1235 : 44 : btf_datasec_t ds;
1236 : 44 : ds.name = secname;
1237 : 44 : ds.name_offset = str_off;
1238 : :
1239 : : /* Insert the entry into the new datasec record. */
1240 : 44 : ds.entries.create (1);
1241 : 44 : ds.entries.quick_push (entry);
1242 : :
1243 : : /* Insert the datasec record itself. */
1244 : 44 : datasecs.safe_push (ds);
1245 : : }
1246 : :
1247 : : /* Create a datasec entry for a function, and insert it into the datasec
1248 : : record for the appropriate section. Create the record if it does not
1249 : : yet exist. */
1250 : :
1251 : : static void
1252 : 4 : btf_datasec_add_func (ctf_container_ref ctfc, cgraph_node *func,
1253 : : ctf_dtdef_ref func_dtd)
1254 : : {
1255 : 4 : const char *section_name = get_section_name (func);
1256 : :
1257 : : /* Note: get_section_name () returns NULL for functions in text
1258 : : section. This is intentional, since we do not want to generate
1259 : : DATASEC entries for them. */
1260 : 4 : if (section_name == NULL)
1261 : 1 : return;
1262 : :
1263 : 3 : struct btf_datasec_entry entry;
1264 : 3 : gcc_assert (func_dtd);
1265 : 3 : entry.dtd = func_dtd;
1266 : 3 : entry.is_var = false;
1267 : :
1268 : : /* Size is left as zero at compile time, to be filled in by loaders
1269 : : such as libbpf. */
1270 : 3 : entry.size = 0;
1271 : :
1272 : 3 : btf_datasec_push_entry (ctfc, section_name, entry);
1273 : : }
1274 : :
1275 : : /* Create a datasec entry for a variable, and insert it into the datasec
1276 : : record for the appropriate section. Create the record if it does not
1277 : : yet exist. */
1278 : :
1279 : : static void
1280 : 91 : btf_datasec_add_var (ctf_container_ref ctfc, varpool_node *var,
1281 : : ctf_dvdef_ref dvd)
1282 : : {
1283 : : /* PR112849: avoid assuming a section for extern decls without
1284 : : an explicit section, which would result in incorrectly
1285 : : emitting a BTF_KIND_DATASEC entry for them. */
1286 : 91 : if (DECL_EXTERNAL (var->decl) && var->get_section () == NULL)
1287 : 4 : return;
1288 : :
1289 : 87 : const char *section_name = get_section_name (var);
1290 : 87 : if (section_name == NULL)
1291 : : return;
1292 : :
1293 : 87 : gcc_assert (dvd);
1294 : 87 : struct btf_datasec_entry entry;
1295 : 87 : entry.dvd = dvd;
1296 : 87 : entry.is_var = true;
1297 : 87 : entry.size = 0;
1298 : :
1299 : 87 : tree size = DECL_SIZE_UNIT (var->decl);
1300 : 87 : if (tree_fits_uhwi_p (size))
1301 : 86 : entry.size = tree_to_uhwi (size);
1302 : 1 : else if (VOID_TYPE_P (TREE_TYPE (var->decl)))
1303 : 1 : entry.size = 1;
1304 : :
1305 : 87 : btf_datasec_push_entry (ctfc, section_name, entry);
1306 : : }
1307 : :
1308 : : /* Add datasec entries for functions to CTFC. */
1309 : :
1310 : : static void
1311 : 107 : btf_add_func_datasec_entries (ctf_container_ref ctfc)
1312 : : {
1313 : : /* We need to create FUNC records at early_finish, so that we have them
1314 : : even for functions which are later inlined by optimization passes.
1315 : : But on the other hand, we do not want datasec entries for such functions,
1316 : : so only create the datasec entries for them late. This loop will not
1317 : : hit functions which have already been inlined. */
1318 : 107 : cgraph_node *func;
1319 : 382 : FOR_EACH_FUNCTION (func)
1320 : : {
1321 : 84 : dw_die_ref die = lookup_decl_die (func->decl);
1322 : 84 : if (die == NULL)
1323 : 0 : continue;
1324 : :
1325 : 84 : ctf_dtdef_ref dtd = ctf_dtd_lookup (ctfc, die);
1326 : 84 : if (dtd == NULL)
1327 : 0 : continue;
1328 : :
1329 : 84 : ctf_dtdef_ref *pdtd = func_map->get (dtd);
1330 : 84 : if (pdtd && DECL_EXTERNAL (func->decl))
1331 : 4 : btf_datasec_add_func (ctfc, func, *pdtd);
1332 : : }
1333 : 107 : }
1334 : :
1335 : : /* Helper function used to determine whether or not a BTF_KIND_VAR record
1336 : : for the variable VAR shall be emitted. */
1337 : :
1338 : : static bool
1339 : 92 : btf_emit_variable_p (ctf_container_ref ctfc, varpool_node *var,
1340 : : ctf_dvdef_ref *pdvd)
1341 : : {
1342 : 92 : dw_die_ref die = lookup_decl_die (var->decl);
1343 : 92 : if (die == NULL)
1344 : : return false;
1345 : :
1346 : 92 : ctf_dvdef_ref dvd = ctf_dvd_lookup (ctfc, die);
1347 : 92 : if (dvd == NULL)
1348 : : return false;
1349 : :
1350 : : /* If this is an extern variable declaration with a defining declaration
1351 : : later, skip it so that only the defining declaration is emitted.
1352 : : This is the same case, fix and reasoning as in CTF; see PR105089. */
1353 : 92 : if (ctf_dvd_ignore_lookup (ctfc, dvd->dvd_key))
1354 : : return false;
1355 : :
1356 : : /* Skip variables with unrepresentable types. */
1357 : 92 : if (!btf_emit_type_p (dvd->dvd_type))
1358 : : return false;
1359 : :
1360 : 91 : *pdvd = dvd;
1361 : 91 : return true;
1362 : : }
1363 : :
1364 : : /* Add BTF_KIND_VAR records for variables. */
1365 : :
1366 : : static void
1367 : 107 : btf_add_vars (ctf_container_ref ctfc)
1368 : : {
1369 : 107 : size_t num_ctf_vars = ctfc->ctfc_vars->elements ();
1370 : :
1371 : 107 : ctfc->ctfc_vars_list = ggc_vec_alloc<ctf_dvdef_ref>(num_ctf_vars);
1372 : :
1373 : 107 : varpool_node *var;
1374 : 107 : ctf_dvdef_ref dvd;
1375 : 306 : FOR_EACH_VARIABLE (var)
1376 : : {
1377 : 92 : if (!btf_emit_variable_p (ctfc, var, &dvd))
1378 : 1 : continue;
1379 : :
1380 : : /* Mark 'extern' variables. */
1381 : 91 : if (DECL_EXTERNAL (var->decl))
1382 : 6 : dvd->dvd_visibility = BTF_VAR_GLOBAL_EXTERN;
1383 : :
1384 : : /* Add the variable to the vars list. */
1385 : 91 : ctfc->ctfc_vars_list[ctfc->ctfc_vars_list_count++] = dvd;
1386 : :
1387 : : /* Add a BTF_KIND_DATASEC entry for the variable. */
1388 : 91 : btf_datasec_add_var (ctfc, var, dvd);
1389 : :
1390 : 91 : const char *section = var->get_section ();
1391 : 5 : if (section && (strcmp (section, ".maps") == 0) && debug_prune_btf)
1392 : : {
1393 : : /* The .maps section has special meaning in BTF: it is used for BPF
1394 : : map definitions. These definitions should be structs. We must
1395 : : collect pointee types used in map members as though they are used
1396 : : directly, effectively ignoring (from the pruning perspective) that
1397 : : they are struct members. */
1398 : 1 : ctf_dtdef_ref dtd = dvd->dvd_type;
1399 : 93 : uint32_t kind = btf_dtd_kind (dvd->dvd_type);
1400 : 1 : if (kind == BTF_KIND_STRUCT)
1401 : : {
1402 : 1 : ctf_dmdef_t *dmd;
1403 : 1 : for (dmd = dtd->dtd_u.dtu_members;
1404 : 3 : dmd != NULL; dmd = (ctf_dmdef_t *) ctf_dmd_list_next (dmd))
1405 : 2 : btf_add_used_type (ctfc, dmd->dmd_type, false, false, true);
1406 : : }
1407 : : }
1408 : : }
1409 : 107 : }
1410 : :
1411 : : /* Callback used by btf_assign_type_ids to insert types into their initial
1412 : : positions in the type list. */
1413 : :
1414 : : static int
1415 : 343 : btf_type_list_cb (ctf_dtdef_ref *slot, ctf_container_ref ctfc)
1416 : : {
1417 : 343 : ctf_dtdef_ref dtd = *slot;
1418 : 343 : ctfc->ctfc_types_list[dtd->dtd_type] = dtd;
1419 : 343 : return 1;
1420 : : }
1421 : :
1422 : : /* Construct the initial type list and assign BTF IDs for all types translated
1423 : : from CTF. */
1424 : :
1425 : : static void
1426 : 103 : btf_collect_translated_types (ctf_container_ref ctfc)
1427 : : {
1428 : 103 : size_t num_ctf_types = ctfc->ctfc_types->elements ();
1429 : :
1430 : : /* First, place each type at its CTF-assigned index in the list.
1431 : : The '+1' here and below is to account for the implicit void type with
1432 : : ID 0. There is no real type at index 0 in the list. */
1433 : 103 : ctfc->ctfc_types_list = ggc_vec_alloc<ctf_dtdef_ref>(num_ctf_types + 1);
1434 : 343 : ctfc->ctfc_types->traverse<ctf_container_ref, btf_type_list_cb> (ctfc);
1435 : :
1436 : : /* Now, pass through the list and adjust IDs to account for types which will
1437 : : not be emitted. This results in each type that will be emitted in BTF
1438 : : being assigned an appropriate ID. Note that types which will not be
1439 : : emitted remain in the list; they are skipped at output time. */
1440 : 103 : unsigned int skip = 0;
1441 : 446 : for (size_t i = 1; i <= num_ctf_types; i++)
1442 : : {
1443 : 343 : ctf_dtdef_ref dtd = ctfc->ctfc_types_list[i];
1444 : 343 : if (!btf_emit_type_p (dtd))
1445 : : {
1446 : 18 : dtd->dtd_type = BTF_INVALID_TYPEID;
1447 : 18 : skip += 1;
1448 : 18 : continue;
1449 : : }
1450 : :
1451 : 325 : dtd->dtd_type -= skip;
1452 : 325 : ctfc->ctfc_num_types++;
1453 : 325 : ctfc->ctfc_num_vlen_bytes += btf_calc_num_vbytes (dtd);
1454 : : }
1455 : :
1456 : 103 : max_translated_id = ctfc->ctfc_num_types;
1457 : 103 : ctfc->ctfc_nextid = ctfc->ctfc_num_types + 1;
1458 : 103 : }
1459 : :
1460 : : /* Assign BTF IDs for FUNC records and account for their size. */
1461 : :
1462 : : static void
1463 : 107 : btf_assign_func_ids (ctf_container_ref ctfc)
1464 : : {
1465 : 107 : ctf_dtdef_ref dtd;
1466 : 107 : unsigned int i;
1467 : 192 : FOR_EACH_VEC_ELT (*funcs, i, dtd)
1468 : : {
1469 : 85 : dtd->dtd_type = ctfc->ctfc_nextid++;
1470 : 85 : ctfc->ctfc_num_types++;
1471 : : }
1472 : 107 : }
1473 : :
1474 : : /* Assign BTF IDs for variables and account for their size. */
1475 : :
1476 : : static void
1477 : 107 : btf_assign_var_ids (ctf_container_ref ctfc)
1478 : : {
1479 : 198 : for (size_t i = 0; i < ctfc->ctfc_vars_list_count; i++)
1480 : : {
1481 : 91 : ctf_dvdef_ref dvd = ctfc->ctfc_vars_list[i];
1482 : 91 : ctf_id_t id = ctfc->ctfc_nextid++;
1483 : 91 : gcc_assert (id <= BTF_MAX_TYPE);
1484 : 91 : dvd->dvd_id = id;
1485 : :
1486 : 91 : ctfc->ctfc_num_types++;
1487 : 91 : ctfc->ctfc_num_vlen_bytes += sizeof (struct btf_var);
1488 : : }
1489 : 107 : }
1490 : :
1491 : : /* Assign BTF IDs for datasec records and account for their size. */
1492 : :
1493 : : static void
1494 : 107 : btf_assign_datasec_ids (ctf_container_ref ctfc)
1495 : : {
1496 : 151 : for (size_t i = 0; i < datasecs.length (); i++)
1497 : : {
1498 : 44 : datasecs[i].id = ctfc->ctfc_nextid++;
1499 : 44 : datasecs[i].name_offset += ctfc_get_strtab_len (ctfc, CTF_STRTAB);
1500 : 44 : ctfc->ctfc_num_types++;
1501 : 44 : ctfc->ctfc_num_vlen_bytes += (datasecs[i].entries.length ()
1502 : 44 : * sizeof (struct btf_var_secinfo));
1503 : : }
1504 : 107 : }
1505 : :
1506 : :
1507 : : /* Manually mark that type T is used to ensure it will not be pruned.
1508 : : Used by the BPF backend when generating BPF CO-RE to mark types used
1509 : : in CO-RE relocations. */
1510 : :
1511 : : void
1512 : 0 : btf_mark_type_used (tree t)
1513 : : {
1514 : : /* If we are not going to prune anyway, this is a no-op. */
1515 : 0 : if (!debug_prune_btf)
1516 : : return;
1517 : :
1518 : 0 : gcc_assert (TYPE_P (t));
1519 : 0 : ctf_container_ref ctfc = ctf_get_tu_ctfc ();
1520 : 0 : ctf_dtdef_ref dtd = ctf_lookup_tree_type (ctfc, t);
1521 : :
1522 : 0 : if (!dtd)
1523 : : return;
1524 : :
1525 : 0 : btf_add_used_type (ctfc, dtd, false, false, true);
1526 : : }
1527 : :
1528 : : /* Callback used for assembling the only-used-types list. Note that this is
1529 : : the same as btf_type_list_cb above, but the hash_set traverse requires a
1530 : : different function signature. */
1531 : :
1532 : : static bool
1533 : 40 : btf_used_type_list_cb (const ctf_dtdef_ref& dtd, ctf_container_ref ctfc)
1534 : : {
1535 : 40 : ctfc->ctfc_types_list[dtd->dtd_type] = dtd;
1536 : 40 : return true;
1537 : : }
1538 : :
1539 : : /* Collect the set of types reachable from global variables and functions.
1540 : : This is the minimal set of types, used when generating pruned BTF. */
1541 : :
1542 : : static void
1543 : 4 : btf_collect_pruned_types (ctf_container_ref ctfc)
1544 : : {
1545 : 4 : vec_alloc (forwards, 1);
1546 : :
1547 : : /* Add types used from functions. */
1548 : 4 : ctf_dtdef_ref dtd;
1549 : 4 : size_t i;
1550 : 10 : FOR_EACH_VEC_ELT (*funcs, i, dtd)
1551 : : {
1552 : 2 : btf_add_used_type (ctfc, dtd->ref_type, false, false, true);
1553 : 2 : ctf_add_string (ctfc, dtd->dtd_name, &(dtd->dtd_data.ctti_name),
1554 : : CTF_STRTAB);
1555 : : }
1556 : :
1557 : : /* Add types used from global variables. */
1558 : 6 : for (i = 0; i < ctfc->ctfc_vars_list_count; i++)
1559 : : {
1560 : 2 : ctf_dvdef_ref dvd = ctfc->ctfc_vars_list[i];
1561 : 2 : btf_add_used_type (ctfc, dvd->dvd_type, false, false, true);
1562 : 2 : ctf_add_string (ctfc, dvd->dvd_name, &(dvd->dvd_name_offset), CTF_STRTAB);
1563 : : }
1564 : :
1565 : : /* Process fixups. If the base type was never added, create a forward for it
1566 : : and adjust the reference to point to that. If it was added, then nothing
1567 : : needs to change. */
1568 : 5 : for (i = 0; i < fixups.length (); i++)
1569 : : {
1570 : 1 : struct btf_fixup *fx = &fixups[i];
1571 : 1 : if (!btf_used_types->contains (fx->pointee_dtd))
1572 : : {
1573 : : /* The underlying type is not used. Create a forward. */
1574 : 1 : ctf_dtdef_ref fwd = ggc_cleared_alloc<ctf_dtdef_t> ();
1575 : 1 : ctf_id_t id = ctfc->ctfc_nextid++;
1576 : 1 : gcc_assert (id <= BTF_MAX_TYPE);
1577 : :
1578 : 1 : bool union_p = (btf_dtd_kind (fx->pointee_dtd) == BTF_KIND_UNION);
1579 : :
1580 : 1 : fwd->dtd_name = fx->pointee_dtd->dtd_name;
1581 : 1 : fwd->dtd_data.ctti_info = CTF_TYPE_INFO (CTF_K_FORWARD, union_p, 0);
1582 : 1 : fwd->dtd_type = id;
1583 : 1 : ctfc->ctfc_num_types++;
1584 : 1 : ctfc->ctfc_num_vlen_bytes += btf_calc_num_vbytes (fwd);
1585 : 1 : ctf_add_string (ctfc, fwd->dtd_name, &(fwd->dtd_data.ctti_name),
1586 : : CTF_STRTAB);
1587 : :
1588 : : /* Update the pointer to point to the forward. */
1589 : 1 : fx->pointer_dtd->ref_type = fwd;
1590 : 1 : vec_safe_push (forwards, fwd);
1591 : : }
1592 : : }
1593 : :
1594 : : /* Construct the resulting pruned type list. */
1595 : 4 : ctfc->ctfc_types_list
1596 : 4 : = ggc_vec_alloc<ctf_dtdef_ref> (btf_used_types->elements () + 1
1597 : 8 : + vec_safe_length (forwards));
1598 : :
1599 : 40 : btf_used_types->traverse<ctf_container_ref, btf_used_type_list_cb> (ctfc);
1600 : :
1601 : : /* Insert the newly created forwards into the regular types list too. */
1602 : 9 : FOR_EACH_VEC_ELT (*forwards, i, dtd)
1603 : 1 : ctfc->ctfc_types_list[dtd->dtd_type] = dtd;
1604 : :
1605 : 4 : max_translated_id = btf_used_types->elements () + vec_safe_length (forwards);
1606 : 4 : }
1607 : :
1608 : : /* Late entry point for BTF generation, called from dwarf2out_finish ().
1609 : : Complete and emit BTF information. */
1610 : :
1611 : : void
1612 : 107 : btf_finish (void)
1613 : : {
1614 : 107 : ctf_container_ref tu_ctfc = ctf_get_tu_ctfc ();
1615 : 107 : init_btf_sections ();
1616 : :
1617 : 107 : datasecs.create (0);
1618 : :
1619 : 107 : btf_add_vars (tu_ctfc);
1620 : 107 : if (debug_prune_btf)
1621 : : {
1622 : : /* Collect pruned set of BTF types and prepare for emission.
1623 : : This includes only types directly used in file-scope variables and
1624 : : function return/argument types. */
1625 : 4 : btf_collect_pruned_types (tu_ctfc);
1626 : : }
1627 : : else
1628 : : {
1629 : : /* Collect all BTF types and prepare for emission.
1630 : : This includes all types translated from DWARF. */
1631 : 103 : btf_collect_translated_types (tu_ctfc);
1632 : : }
1633 : 107 : btf_add_func_datasec_entries (tu_ctfc);
1634 : :
1635 : 107 : btf_assign_var_ids (tu_ctfc);
1636 : 107 : btf_assign_func_ids (tu_ctfc);
1637 : 107 : btf_assign_datasec_ids (tu_ctfc);
1638 : :
1639 : : /* Finally, write out the complete .BTF section. */
1640 : 107 : btf_output (tu_ctfc);
1641 : :
1642 : : /* If compiling for BPF with CO-RE info, we cannot deallocate until after the
1643 : : contents of the .BTF.ext section are finalized, which happens very late in
1644 : : BPF backend. Therefore, the deallocation (i.e. btf_finalize ()) is delayed
1645 : : until TARGET_ASM_FILE_END for BPF CO-RE. */
1646 : 107 : if (!btf_with_core_debuginfo_p ())
1647 : 107 : btf_finalize ();
1648 : 107 : }
1649 : :
1650 : : /* Reset all state for BTF generation so that we can rerun the compiler within
1651 : : the same process. */
1652 : :
1653 : : void
1654 : 107 : btf_finalize (void)
1655 : : {
1656 : 107 : btf_info_section = NULL;
1657 : 107 : max_translated_id = 0;
1658 : :
1659 : 151 : for (size_t i = 0; i < datasecs.length (); i++)
1660 : 44 : datasecs[i].entries.release ();
1661 : 107 : datasecs.release ();
1662 : :
1663 : 107 : funcs = NULL;
1664 : 107 : if (func_map)
1665 : : {
1666 : 107 : func_map->empty ();
1667 : 107 : func_map = NULL;
1668 : : }
1669 : :
1670 : 107 : if (debug_prune_btf)
1671 : : {
1672 : 4 : if (btf_used_types)
1673 : : {
1674 : 4 : btf_used_types->empty ();
1675 : 4 : btf_used_types = NULL;
1676 : : }
1677 : :
1678 : 4 : fixups.release ();
1679 : 4 : forwards = NULL;
1680 : : }
1681 : :
1682 : 107 : ctf_container_ref tu_ctfc = ctf_get_tu_ctfc ();
1683 : 107 : ctfc_delete_container (tu_ctfc);
1684 : 107 : tu_ctfc = NULL;
1685 : 107 : }
1686 : :
1687 : : /* Traversal function for all BTF_KIND_FUNC type records. */
1688 : :
1689 : : bool
1690 : 0 : traverse_btf_func_types (funcs_traverse_callback callback, void *data)
1691 : : {
1692 : 0 : ctf_dtdef_ref ref;
1693 : 0 : unsigned i;
1694 : 0 : FOR_EACH_VEC_ELT (*funcs, i, ref)
1695 : : {
1696 : 0 : bool stop = callback (ref, data);
1697 : 0 : if (stop == true)
1698 : : return true;
1699 : : }
1700 : : return false;
1701 : : }
1702 : :
1703 : : #include "gt-btfout.h"
|