]>
Commit | Line | Data |
---|---|---|
b7e215a8 | 1 | /* Output BTF format from GCC. |
a945c346 | 2 | Copyright (C) 2021-2024 Free Software Foundation, Inc. |
b7e215a8 IB |
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 | |
e53b6e56 | 22 | closely resembles that of ctfout.cc, and the same CTF container objects are |
b7e215a8 IB |
23 | used. */ |
24 | ||
25 | #include "config.h" | |
26 | #include "system.h" | |
27 | #include "coretypes.h" | |
28 | #include "target.h" | |
7d510b21 | 29 | #include "memmodel.h" |
095a01cf | 30 | #include "tm_p.h" |
b7e215a8 IB |
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" | |
dfc88fb5 CM |
38 | #include "stringpool.h" /* For lookup_attribute. */ |
39 | #include "attribs.h" /* For lookup_attribute. */ | |
b7e215a8 IB |
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 | /* BTF encodes void as type id 0. */ | |
65 | ||
66 | #define BTF_VOID_TYPEID 0 | |
67 | #define BTF_INIT_TYPEID 1 | |
68 | ||
69 | #define BTF_INVALID_TYPEID 0xFFFFFFFF | |
70 | ||
71 | /* Mapping of CTF variables to the IDs they will be assigned when they are | |
72 | converted to BTF_KIND_VAR type records. Strictly accounts for the index | |
73 | from the start of the variable type entries, does not include the number | |
74 | of types emitted prior to the variable records. */ | |
d6a87d96 | 75 | static GTY (()) hash_map <ctf_dvdef_ref, unsigned> *btf_var_ids; |
b7e215a8 IB |
76 | |
77 | /* Mapping of type IDs from original CTF ID to BTF ID. Types do not map | |
78 | 1-to-1 from CTF to BTF. To avoid polluting the CTF container when updating | |
79 | type references-by-ID, we use this map instead. */ | |
80 | static ctf_id_t * btf_id_map = NULL; | |
81 | ||
82 | /* Information for creating the BTF_KIND_DATASEC records. */ | |
83 | typedef struct btf_datasec | |
84 | { | |
85 | const char *name; /* Section name, e.g. ".bss". */ | |
86 | uint32_t name_offset; /* Offset to name in string table. */ | |
87 | vec<struct btf_var_secinfo> entries; /* Variable entries in this section. */ | |
88 | } btf_datasec_t; | |
89 | ||
90 | /* One BTF_KIND_DATASEC record is created for each output data section which | |
91 | will hold at least one variable. */ | |
92 | static vec<btf_datasec_t> datasecs; | |
93 | ||
94 | /* Holes occur for types which are present in the CTF container, but are either | |
95 | non-representable or redundant in BTF. */ | |
96 | static vec<ctf_id_t> holes; | |
97 | ||
98 | /* CTF definition(s) of void. Only one definition of void should be generated. | |
99 | We should not encounter more than one definition of void, but use a vector | |
100 | to be safe. */ | |
101 | static vec<ctf_id_t> voids; | |
102 | ||
103 | /* Functions in BTF have two separate type records - one for the prototype | |
104 | (BTF_KIND_FUNC_PROTO), as well as a BTF_KIND_FUNC. CTF_K_FUNCTION types | |
105 | map closely to BTF_KIND_FUNC_PROTO, but the BTF_KIND_FUNC records must be | |
106 | created. This vector holds them. */ | |
107 | static GTY (()) vec<ctf_dtdef_ref, va_gc> *funcs; | |
108 | ||
109 | /* The number of BTF variables added to the TU CTF container. */ | |
110 | static unsigned int num_vars_added = 0; | |
111 | ||
112 | /* The number of BTF types added to the TU CTF container. */ | |
113 | static unsigned int num_types_added = 0; | |
114 | ||
115 | /* The number of types synthesized for BTF that do not correspond to | |
116 | CTF types. */ | |
117 | static unsigned int num_types_created = 0; | |
118 | ||
7aae58b0 DF |
119 | /* Name strings for BTF kinds. |
120 | Note: the indices here must match the type defines in btf.h. */ | |
121 | static const char *const btf_kind_names[] = | |
122 | { | |
123 | "UNKN", "INT", "PTR", "ARRAY", "STRUCT", "UNION", "ENUM", "FWD", | |
124 | "TYPEDEF", "VOLATILE", "CONST", "RESTRICT", "FUNC", "FUNC_PROTO", | |
125 | "VAR", "DATASEC", "FLOAT", "DECL_TAG", "TYPE_TAG", "ENUM64" | |
126 | }; | |
127 | ||
128 | /* Return a name string for the given BTF_KIND. */ | |
129 | ||
130 | static const char * | |
131 | btf_kind_name (uint32_t btf_kind) | |
132 | { | |
133 | return btf_kind_names[btf_kind]; | |
134 | } | |
135 | ||
b7e215a8 IB |
136 | /* Map a CTF type kind to the corresponding BTF type kind. */ |
137 | ||
138 | static uint32_t | |
139 | get_btf_kind (uint32_t ctf_kind) | |
140 | { | |
141 | /* N.B. the values encoding kinds are not in general the same for the | |
142 | same kind between CTF and BTF. e.g. CTF_K_CONST != BTF_KIND_CONST. */ | |
143 | switch (ctf_kind) | |
144 | { | |
145 | case CTF_K_INTEGER: return BTF_KIND_INT; | |
18d0fad7 | 146 | case CTF_K_FLOAT: return BTF_KIND_FLOAT; |
b7e215a8 IB |
147 | case CTF_K_POINTER: return BTF_KIND_PTR; |
148 | case CTF_K_ARRAY: return BTF_KIND_ARRAY; | |
149 | case CTF_K_FUNCTION: return BTF_KIND_FUNC_PROTO; | |
150 | case CTF_K_STRUCT: return BTF_KIND_STRUCT; | |
151 | case CTF_K_UNION: return BTF_KIND_UNION; | |
152 | case CTF_K_ENUM: return BTF_KIND_ENUM; | |
153 | case CTF_K_FORWARD: return BTF_KIND_FWD; | |
154 | case CTF_K_TYPEDEF: return BTF_KIND_TYPEDEF; | |
155 | case CTF_K_VOLATILE: return BTF_KIND_VOLATILE; | |
156 | case CTF_K_CONST: return BTF_KIND_CONST; | |
157 | case CTF_K_RESTRICT: return BTF_KIND_RESTRICT; | |
158 | default:; | |
159 | } | |
160 | return BTF_KIND_UNKN; | |
161 | } | |
162 | ||
9b6e2cb7 IB |
163 | /* Some BTF types, like BTF_KIND_FUNC_PROTO, are anonymous. The machinery |
164 | in btfout to emit BTF, may reset dtd_data->ctti_name, but does not update | |
165 | the name in the ctf_dtdef_ref type object (deliberate choice). This | |
166 | interface helps abstract out that state of affairs, while giving access to | |
167 | the name of the type as intended. */ | |
168 | ||
169 | static const char * | |
170 | get_btf_type_name (ctf_dtdef_ref dtd) | |
171 | { | |
172 | const char *anon = ""; | |
173 | return (dtd->dtd_data.ctti_name) ? dtd->dtd_name : anon; | |
174 | } | |
175 | ||
7aae58b0 DF |
176 | /* Helper routines to map between 'relative' and 'absolute' IDs. |
177 | ||
178 | In BTF all records (including variables) are output in one long list, and all | |
179 | inter-type references are via index into that list. But internally since we | |
180 | a) translate from CTF, which separates variable records from regular types | |
181 | and b) create some additional types after the fact, things like VAR and FUNC | |
182 | records are stored in separate vectors with their own indices. These | |
183 | functions map between the 'relative' IDs (i.e. indices in their respective | |
184 | containers) and 'absolute' IDs (i.e. indices in the final contiguous | |
185 | output list), which goes in order: | |
186 | all normal type records translated from CTF | |
187 | all BTF_KIND_VAR records | |
188 | all BTF_KIND_FUNC records (synthesized split function records) | |
189 | all BTF_KIND_DATASEC records (synthesized) | |
190 | ||
191 | The extra '+ 1's below are to account for the implicit "void" record, which | |
192 | has index 0 but isn't actually contained in the type list. */ | |
193 | ||
194 | /* Return the final BTF ID of the variable at relative index REL. */ | |
195 | ||
196 | static ctf_id_t | |
197 | btf_absolute_var_id (ctf_id_t rel) | |
198 | { | |
199 | return rel + (num_types_added + 1); | |
200 | } | |
201 | ||
202 | /* Return the relative index of the variable with final BTF ID ABS. */ | |
203 | ||
204 | static ctf_id_t | |
205 | btf_relative_var_id (ctf_id_t abs) | |
206 | { | |
207 | return abs - (num_types_added + 1); | |
208 | } | |
209 | ||
934da923 DF |
210 | /* Return the final BTF ID of the func record at relative index REL. */ |
211 | ||
212 | static ctf_id_t | |
213 | btf_absolute_func_id (ctf_id_t rel) | |
214 | { | |
215 | return rel + (num_types_added + 1) + num_vars_added; | |
216 | } | |
217 | ||
7aae58b0 DF |
218 | /* Return the relative index of the func record with final BTF ID ABS. */ |
219 | ||
220 | static ctf_id_t | |
221 | btf_relative_func_id (ctf_id_t abs) | |
222 | { | |
223 | return abs - ((num_types_added + 1) + num_vars_added); | |
224 | } | |
225 | ||
226 | /* Return the final BTF ID of the datasec record at relative index REL. */ | |
227 | ||
228 | static ctf_id_t | |
229 | btf_absolute_datasec_id (ctf_id_t rel) | |
230 | { | |
231 | return rel + (num_types_added + 1) + num_vars_added + funcs->length (); | |
232 | } | |
233 | ||
234 | ||
b7e215a8 IB |
235 | /* Allocate the btf_id_map, and initialize elements to BTF_INVALID_TYPEID. */ |
236 | ||
237 | static void | |
238 | init_btf_id_map (size_t len) | |
239 | { | |
240 | btf_id_map = XNEWVEC (ctf_id_t, len); | |
241 | ||
242 | btf_id_map[0] = BTF_VOID_TYPEID; | |
243 | for (size_t i = 1; i < len; i++) | |
244 | btf_id_map[i] = BTF_INVALID_TYPEID; | |
245 | } | |
246 | ||
247 | /* Return the BTF type ID of CTF type ID KEY, or BTF_INVALID_TYPEID if the CTF | |
248 | type with ID KEY does not map to a BTF type. */ | |
249 | ||
0a2bd52f | 250 | ctf_id_t |
b7e215a8 IB |
251 | get_btf_id (ctf_id_t key) |
252 | { | |
253 | return btf_id_map[key]; | |
254 | } | |
255 | ||
256 | /* Set the CTF type ID KEY to map to BTF type ID VAL. */ | |
257 | ||
258 | static inline void | |
259 | set_btf_id (ctf_id_t key, ctf_id_t val) | |
260 | { | |
261 | btf_id_map[key] = val; | |
262 | } | |
263 | ||
264 | /* Return TRUE iff the given CTF type ID maps to a BTF type which will | |
265 | be emitted. */ | |
266 | static inline bool | |
267 | btf_emit_id_p (ctf_id_t id) | |
268 | { | |
269 | return ((btf_id_map[id] != BTF_VOID_TYPEID) | |
270 | && (btf_id_map[id] <= BTF_MAX_TYPE)); | |
271 | } | |
272 | ||
1502d724 DF |
273 | /* Return true if DTD is a forward-declared enum. The BTF representation |
274 | of forward declared enums is not formally defined. */ | |
275 | ||
276 | static bool | |
277 | btf_fwd_to_enum_p (ctf_dtdef_ref dtd) | |
278 | { | |
279 | uint32_t btf_kind = get_btf_kind (CTF_V2_INFO_KIND (dtd->dtd_data.ctti_info)); | |
280 | ||
281 | return (btf_kind == BTF_KIND_FWD && dtd->dtd_data.ctti_type == CTF_K_ENUM); | |
282 | } | |
283 | ||
b7e215a8 IB |
284 | /* Each BTF type can be followed additional, variable-length information |
285 | completing the description of the type. Calculate the number of bytes | |
286 | of variable information required to encode a given type. */ | |
287 | ||
288 | static uint64_t | |
289 | btf_calc_num_vbytes (ctf_dtdef_ref dtd) | |
290 | { | |
291 | uint64_t vlen_bytes = 0; | |
292 | ||
293 | uint32_t kind = get_btf_kind (CTF_V2_INFO_KIND (dtd->dtd_data.ctti_info)); | |
294 | uint32_t vlen = CTF_V2_INFO_VLEN (dtd->dtd_data.ctti_info); | |
295 | ||
296 | switch (kind) | |
297 | { | |
298 | case BTF_KIND_UNKN: | |
299 | case BTF_KIND_PTR: | |
300 | case BTF_KIND_FWD: | |
301 | case BTF_KIND_TYPEDEF: | |
302 | case BTF_KIND_VOLATILE: | |
303 | case BTF_KIND_CONST: | |
304 | case BTF_KIND_RESTRICT: | |
305 | case BTF_KIND_FUNC: | |
306 | /* These kinds have no vlen data. */ | |
307 | break; | |
308 | ||
309 | case BTF_KIND_INT: | |
310 | /* Size 0 integers represent redundant definitions of void that will | |
311 | not be emitted. Don't allocate space for them. */ | |
312 | if (dtd->dtd_data.ctti_size == 0) | |
313 | break; | |
314 | ||
315 | vlen_bytes += sizeof (uint32_t); | |
316 | break; | |
317 | ||
318 | case BTF_KIND_ARRAY: | |
319 | vlen_bytes += sizeof (struct btf_array); | |
320 | break; | |
321 | ||
322 | case BTF_KIND_STRUCT: | |
323 | case BTF_KIND_UNION: | |
324 | vlen_bytes += vlen * sizeof (struct btf_member); | |
325 | break; | |
326 | ||
327 | case BTF_KIND_ENUM: | |
099b15e2 | 328 | vlen_bytes += (dtd->dtd_data.ctti_size > 4) |
8422861b GM |
329 | ? vlen * sizeof (struct btf_enum64) |
330 | : vlen * sizeof (struct btf_enum); | |
b7e215a8 IB |
331 | break; |
332 | ||
333 | case BTF_KIND_FUNC_PROTO: | |
334 | vlen_bytes += vlen * sizeof (struct btf_param); | |
335 | break; | |
336 | ||
337 | case BTF_KIND_VAR: | |
338 | vlen_bytes += sizeof (struct btf_var); | |
339 | break; | |
340 | ||
341 | case BTF_KIND_DATASEC: | |
342 | vlen_bytes += vlen * sizeof (struct btf_var_secinfo); | |
343 | break; | |
344 | ||
345 | default: | |
346 | break; | |
347 | } | |
348 | return vlen_bytes; | |
349 | } | |
350 | ||
351 | /* Initialize BTF section (.BTF) for output. */ | |
352 | ||
353 | void | |
354 | init_btf_sections (void) | |
355 | { | |
356 | btf_info_section = get_section (BTF_INFO_SECTION_NAME, BTF_INFO_SECTION_FLAGS, | |
357 | NULL); | |
358 | ||
359 | ASM_GENERATE_INTERNAL_LABEL (btf_info_section_label, | |
360 | BTF_INFO_SECTION_LABEL, btf_label_num++); | |
361 | } | |
362 | ||
363 | /* Push a BTF datasec variable entry INFO into the datasec named SECNAME, | |
364 | creating the datasec if it does not already exist. */ | |
365 | ||
366 | static void | |
367 | btf_datasec_push_entry (ctf_container_ref ctfc, const char *secname, | |
368 | struct btf_var_secinfo info) | |
369 | { | |
370 | if (secname == NULL) | |
371 | return; | |
372 | ||
373 | for (size_t i = 0; i < datasecs.length (); i++) | |
374 | if (strcmp (datasecs[i].name, secname) == 0) | |
375 | { | |
376 | datasecs[i].entries.safe_push (info); | |
377 | return; | |
378 | } | |
379 | ||
380 | /* If we don't already have a datasec record for secname, make one. */ | |
381 | ||
382 | uint32_t str_off; | |
383 | ctf_add_string (ctfc, secname, &str_off, CTF_AUX_STRTAB); | |
384 | if (strcmp (secname, "")) | |
385 | ctfc->ctfc_aux_strlen += strlen (secname) + 1; | |
386 | ||
387 | btf_datasec_t ds; | |
388 | ds.name = secname; | |
389 | ds.name_offset = str_off; | |
390 | ||
391 | ds.entries.create (0); | |
392 | ds.entries.safe_push (info); | |
393 | ||
394 | datasecs.safe_push (ds); | |
70b30304 DF |
395 | } |
396 | ||
397 | ||
398 | /* Return the section name, as of interest to btf_collect_datasec, for the | |
399 | given symtab node. Note that this deliberately returns NULL for objects | |
400 | which do not go in a section btf_collect_datasec cares about. */ | |
401 | static const char * | |
402 | get_section_name (symtab_node *node) | |
403 | { | |
404 | const char *section_name = node->get_section (); | |
405 | ||
406 | if (section_name == NULL) | |
407 | { | |
408 | switch (categorize_decl_for_section (node->decl, 0)) | |
409 | { | |
410 | case SECCAT_BSS: | |
411 | section_name = ".bss"; | |
412 | break; | |
413 | case SECCAT_DATA: | |
414 | section_name = ".data"; | |
415 | break; | |
416 | case SECCAT_RODATA: | |
417 | section_name = ".rodata"; | |
418 | break; | |
419 | default:; | |
420 | } | |
421 | } | |
422 | ||
423 | return section_name; | |
b7e215a8 IB |
424 | } |
425 | ||
426 | /* Construct all BTF_KIND_DATASEC records for CTFC. One such record is created | |
427 | for each non-empty data-containing section in the output. Each record is | |
428 | followed by a variable number of entries describing the variables stored | |
429 | in that section. */ | |
430 | ||
431 | static void | |
432 | btf_collect_datasec (ctf_container_ref ctfc) | |
433 | { | |
70b30304 DF |
434 | cgraph_node *func; |
435 | FOR_EACH_FUNCTION (func) | |
436 | { | |
437 | dw_die_ref die = lookup_decl_die (func->decl); | |
438 | if (die == NULL) | |
439 | continue; | |
440 | ||
441 | ctf_dtdef_ref dtd = ctf_dtd_lookup (ctfc, die); | |
442 | if (dtd == NULL) | |
443 | continue; | |
444 | ||
dfc88fb5 CM |
445 | if (DECL_EXTERNAL (func->decl) |
446 | && (lookup_attribute ("kernel_helper", | |
447 | DECL_ATTRIBUTES (func->decl))) != NULL_TREE) | |
448 | continue; | |
449 | ||
70b30304 DF |
450 | /* Functions actually get two types: a BTF_KIND_FUNC_PROTO, and |
451 | also a BTF_KIND_FUNC. But the CTF container only allocates one | |
452 | type per function, which matches closely with BTF_KIND_FUNC_PROTO. | |
453 | For each such function, also allocate a BTF_KIND_FUNC entry. | |
454 | These will be output later. */ | |
455 | ctf_dtdef_ref func_dtd = ggc_cleared_alloc<ctf_dtdef_t> (); | |
456 | func_dtd->dtd_data = dtd->dtd_data; | |
457 | func_dtd->dtd_data.ctti_type = dtd->dtd_type; | |
458 | func_dtd->linkage = dtd->linkage; | |
9b6e2cb7 | 459 | func_dtd->dtd_name = dtd->dtd_name; |
0198cade CM |
460 | /* +1 for the sentinel type not in the types map. */ |
461 | func_dtd->dtd_type = num_types_added + num_types_created + 1; | |
70b30304 DF |
462 | |
463 | /* Only the BTF_KIND_FUNC type actually references the name. The | |
464 | BTF_KIND_FUNC_PROTO is always anonymous. */ | |
465 | dtd->dtd_data.ctti_name = 0; | |
466 | ||
467 | vec_safe_push (funcs, func_dtd); | |
468 | num_types_created++; | |
469 | ||
470 | /* Mark any 'extern' funcs and add DATASEC entries for them. */ | |
471 | if (DECL_EXTERNAL (func->decl)) | |
472 | { | |
473 | func_dtd->linkage = BTF_FUNC_EXTERN; | |
474 | ||
475 | const char *section_name = get_section_name (func); | |
476 | /* Note: get_section_name () returns NULL for functions in text | |
477 | section. This is intentional, since we do not want to generate | |
478 | DATASEC entries for them. */ | |
479 | if (section_name == NULL) | |
480 | continue; | |
481 | ||
482 | struct btf_var_secinfo info; | |
483 | ||
0198cade | 484 | info.type = func_dtd->dtd_type; |
70b30304 DF |
485 | |
486 | /* Both zero at compile time. */ | |
487 | info.size = 0; | |
488 | info.offset = 0; | |
489 | ||
490 | btf_datasec_push_entry (ctfc, section_name, info); | |
491 | } | |
492 | } | |
493 | ||
b7e215a8 IB |
494 | varpool_node *node; |
495 | FOR_EACH_VARIABLE (node) | |
496 | { | |
497 | dw_die_ref die = lookup_decl_die (node->decl); | |
498 | if (die == NULL) | |
499 | continue; | |
500 | ||
501 | ctf_dvdef_ref dvd = ctf_dvd_lookup (ctfc, die); | |
502 | if (dvd == NULL) | |
503 | continue; | |
504 | ||
2bce22e8 DF |
505 | /* Mark extern variables. */ |
506 | if (DECL_EXTERNAL (node->decl)) | |
b8cf266f DF |
507 | { |
508 | dvd->dvd_visibility = BTF_VAR_GLOBAL_EXTERN; | |
509 | ||
510 | /* PR112849: avoid assuming a section for extern decls without | |
511 | an explicit section, which would result in incorrectly | |
512 | emitting a BTF_KIND_DATASEC entry for them. */ | |
513 | if (node->get_section () == NULL) | |
514 | continue; | |
515 | } | |
b7e215a8 | 516 | |
70b30304 | 517 | const char *section_name = get_section_name (node); |
b7e215a8 | 518 | if (section_name == NULL) |
70b30304 | 519 | continue; |
b7e215a8 IB |
520 | |
521 | struct btf_var_secinfo info; | |
522 | ||
523 | info.type = 0; | |
524 | unsigned int *var_id = btf_var_ids->get (dvd); | |
525 | if (var_id) | |
7aae58b0 | 526 | info.type = btf_absolute_var_id (*var_id); |
b7e215a8 IB |
527 | else |
528 | continue; | |
529 | ||
530 | info.size = 0; | |
531 | tree size = DECL_SIZE_UNIT (node->decl); | |
532 | if (tree_fits_uhwi_p (size)) | |
533 | info.size = tree_to_uhwi (size); | |
4f7aa145 DF |
534 | else if (VOID_TYPE_P (TREE_TYPE (node->decl))) |
535 | info.size = 1; | |
b7e215a8 IB |
536 | |
537 | /* Offset is left as 0 at compile time, to be filled in by loaders such | |
538 | as libbpf. */ | |
539 | info.offset = 0; | |
540 | ||
541 | btf_datasec_push_entry (ctfc, section_name, info); | |
542 | } | |
70b30304 DF |
543 | |
544 | num_types_created += datasecs.length (); | |
b7e215a8 IB |
545 | } |
546 | ||
547 | /* Return true if the type ID is that of a type which will not be emitted (for | |
548 | example, if it is not representable in BTF). */ | |
549 | ||
550 | static bool | |
551 | btf_removed_type_p (ctf_id_t id) | |
552 | { | |
553 | return holes.contains (id); | |
554 | } | |
555 | ||
556 | /* Adjust the given type ID to account for holes and duplicate definitions of | |
557 | void. */ | |
558 | ||
559 | static ctf_id_t | |
560 | btf_adjust_type_id (ctf_id_t id) | |
561 | { | |
562 | size_t n; | |
563 | ctf_id_t i = 0; | |
564 | ||
565 | /* Do not adjust invalid type markers. */ | |
566 | if (id == BTF_INVALID_TYPEID) | |
567 | return id; | |
568 | ||
569 | for (n = 0; n < voids.length (); n++) | |
570 | if (id == voids[n]) | |
571 | return BTF_VOID_TYPEID; | |
572 | ||
573 | for (n = 0; n < holes.length (); n++) | |
574 | { | |
575 | if (holes[n] < id) | |
576 | i++; | |
577 | else if (holes[n] == id) | |
578 | return BTF_VOID_TYPEID; | |
579 | } | |
580 | ||
581 | return id - i; | |
582 | } | |
583 | ||
584 | /* Postprocessing callback routine for types. */ | |
585 | ||
586 | int | |
587 | btf_dtd_postprocess_cb (ctf_dtdef_ref *slot, ctf_container_ref arg_ctfc) | |
588 | { | |
589 | ctf_dtdef_ref ctftype = (ctf_dtdef_ref) * slot; | |
590 | ||
591 | size_t index = ctftype->dtd_type; | |
592 | gcc_assert (index <= arg_ctfc->ctfc_types->elements ()); | |
593 | ||
594 | uint32_t ctf_kind, btf_kind; | |
595 | ||
596 | ctf_kind = CTF_V2_INFO_KIND (ctftype->dtd_data.ctti_info); | |
597 | btf_kind = get_btf_kind (ctf_kind); | |
598 | ||
599 | if (btf_kind == BTF_KIND_UNKN) | |
600 | /* This type is not representable in BTF. Create a hole. */ | |
601 | holes.safe_push (ctftype->dtd_type); | |
602 | ||
603 | else if (btf_kind == BTF_KIND_INT && ctftype->dtd_data.ctti_size == 0) | |
604 | { | |
605 | /* This is a (redundant) definition of void. */ | |
606 | voids.safe_push (ctftype->dtd_type); | |
607 | holes.safe_push (ctftype->dtd_type); | |
608 | } | |
609 | ||
610 | arg_ctfc->ctfc_types_list[index] = ctftype; | |
611 | ||
612 | return 1; | |
613 | } | |
614 | ||
615 | /* Preprocessing callback routine for variables. */ | |
616 | ||
617 | int | |
618 | btf_dvd_emit_preprocess_cb (ctf_dvdef_ref *slot, ctf_container_ref arg_ctfc) | |
619 | { | |
620 | ctf_dvdef_ref var = (ctf_dvdef_ref) * slot; | |
621 | ||
2bce22e8 DF |
622 | /* If this is an extern variable declaration with a defining declaration |
623 | later, skip it so that only the defining declaration is emitted. | |
624 | This is the same case, fix and reasoning as in CTF; see PR105089. */ | |
625 | if (ctf_dvd_ignore_lookup (arg_ctfc, var->dvd_key)) | |
626 | return 1; | |
627 | ||
b7e215a8 | 628 | /* Do not add variables which refer to unsupported types. */ |
4f7aa145 | 629 | if (!voids.contains (var->dvd_type) && btf_removed_type_p (var->dvd_type)) |
b7e215a8 IB |
630 | return 1; |
631 | ||
632 | arg_ctfc->ctfc_vars_list[num_vars_added] = var; | |
633 | btf_var_ids->put (var, num_vars_added); | |
634 | ||
635 | num_vars_added++; | |
636 | num_types_created++; | |
637 | ||
638 | return 1; | |
639 | } | |
640 | ||
641 | /* Preprocessing callback routine for types. */ | |
642 | ||
643 | static void | |
644 | btf_dtd_emit_preprocess_cb (ctf_container_ref ctfc, ctf_dtdef_ref dtd) | |
645 | { | |
646 | if (!btf_emit_id_p (dtd->dtd_type)) | |
647 | return; | |
648 | ||
b7e215a8 IB |
649 | ctfc->ctfc_num_vlen_bytes += btf_calc_num_vbytes (dtd); |
650 | } | |
651 | ||
652 | /* Preprocess the CTF information to prepare for BTF output. BTF is almost a | |
653 | subset of CTF, with many small differences in encoding, and lacking support | |
654 | for some types (notably floating point formats). | |
655 | ||
656 | During the preprocessing pass: | |
657 | - Ascertain that the sorted list of types has been prepared. For the BTF | |
658 | generation process, this is taken care of by the btf_init_postprocess (). | |
659 | ||
660 | - BTF_KIND_FUNC and BTF_KIND_DATASEC records are constructed. These types do | |
661 | not have analogues in CTF (the analogous type to CTF_K_FUNCTION is | |
662 | BTF_KIND_FUNC_PROTO), but can be relatively easily deduced from CTF | |
663 | information. | |
664 | ||
665 | - Construct BTF_KIND_VAR records, representing variables. | |
666 | ||
667 | - Calculate the total size in bytes of variable-length information following | |
668 | BTF type records. This is used for outputting the BTF header. | |
669 | ||
670 | After preprocessing, all BTF information is ready to be output: | |
671 | - ctfc->ctfc_types_list holdstypes converted from CTF types. This does not | |
672 | include KIND_VAR, KIND_FUNC, nor KIND_DATASEC types. These types have been | |
673 | re-encoded to the appropriate representation in BTF. | |
674 | - ctfc->ctfc_vars_list holds all variables which should be output. | |
675 | Variables of unsupported types are not present in this list. | |
676 | - Vector 'funcs' holds all BTF_KIND_FUNC types, one to match each | |
677 | BTF_KIND_FUNC_PROTO. | |
678 | - Vector 'datasecs' holds all BTF_KIND_DATASEC types. */ | |
679 | ||
680 | static void | |
681 | btf_emit_preprocess (ctf_container_ref ctfc) | |
682 | { | |
683 | size_t num_ctf_types = ctfc->ctfc_types->elements (); | |
684 | size_t num_ctf_vars = ctfc->ctfc_vars->elements (); | |
685 | size_t i; | |
686 | ||
687 | if (num_ctf_types) | |
688 | { | |
689 | gcc_assert (ctfc->ctfc_types_list); | |
690 | /* Preprocess the types. */ | |
691 | for (i = 1; i <= num_ctf_types; i++) | |
692 | btf_dtd_emit_preprocess_cb (ctfc, ctfc->ctfc_types_list[i]); | |
693 | } | |
694 | ||
695 | btf_var_ids = hash_map<ctf_dvdef_ref, unsigned int>::create_ggc (100); | |
696 | ||
697 | if (num_ctf_vars) | |
698 | { | |
699 | /* Allocate and construct the list of variables. While BTF variables are | |
700 | not distinct from types (in that variables are simply types with | |
701 | BTF_KIND_VAR), it is simpler to maintain a separate list of variables | |
702 | and append them to the types list during output. */ | |
703 | ctfc->ctfc_vars_list = ggc_vec_alloc<ctf_dvdef_ref>(num_ctf_vars); | |
704 | ctfc->ctfc_vars->traverse<ctf_container_ref, btf_dvd_emit_preprocess_cb> | |
705 | (ctfc); | |
706 | ||
707 | ctfc->ctfc_num_vlen_bytes += (num_vars_added * sizeof (struct btf_var)); | |
708 | } | |
709 | ||
710 | btf_collect_datasec (ctfc); | |
711 | } | |
712 | ||
713 | /* Return true iff DMD is a member description of a bit-field which can be | |
714 | validly represented in BTF. */ | |
715 | ||
716 | static bool | |
717 | btf_dmd_representable_bitfield_p (ctf_container_ref ctfc, ctf_dmdef_t *dmd) | |
718 | { | |
719 | ctf_dtdef_ref ref_type = ctfc->ctfc_types_list[dmd->dmd_type]; | |
720 | ||
721 | if (CTF_V2_INFO_KIND (ref_type->dtd_data.ctti_info) == CTF_K_SLICE) | |
722 | { | |
723 | unsigned short word_offset = ref_type->dtd_u.dtu_slice.cts_offset; | |
724 | unsigned short bits = ref_type->dtd_u.dtu_slice.cts_bits; | |
725 | uint64_t sou_offset = dmd->dmd_offset; | |
726 | ||
727 | if ((bits > 0xff) || ((sou_offset + word_offset) > 0xffffff)) | |
728 | return false; | |
729 | ||
730 | return true; | |
731 | } | |
732 | ||
733 | return false; | |
734 | } | |
735 | ||
736 | /* BTF asm helper routines. */ | |
737 | ||
7aae58b0 DF |
738 | /* Asm'out a reference to another BTF type. */ |
739 | ||
740 | static void | |
9b8bc020 | 741 | btf_asm_type_ref (const char *prefix, ctf_container_ref ctfc, ctf_id_t ctf_id) |
7aae58b0 | 742 | { |
9b8bc020 DF |
743 | ctf_id_t btf_id = get_btf_id (ctf_id); |
744 | if (btf_id == BTF_VOID_TYPEID || btf_id == BTF_INVALID_TYPEID) | |
7aae58b0 DF |
745 | { |
746 | /* There is no explicit void type. | |
747 | Also handle any invalid refs that made it this far, just in case. */ | |
9b8bc020 | 748 | dw2_asm_output_data (4, btf_id, "%s: void", prefix); |
7aae58b0 DF |
749 | } |
750 | else | |
751 | { | |
9b8bc020 DF |
752 | gcc_assert (btf_id <= num_types_added); |
753 | ||
754 | /* Ref to a standard type in the types list. Note: take care that we | |
755 | must index the type list by the original CTF id, not the BTF id. */ | |
756 | ctf_dtdef_ref ref_type = ctfc->ctfc_types_list[ctf_id]; | |
7aae58b0 DF |
757 | uint32_t ref_kind |
758 | = get_btf_kind (CTF_V2_INFO_KIND (ref_type->dtd_data.ctti_info)); | |
759 | ||
1502d724 DF |
760 | const char *kind_name = btf_fwd_to_enum_p (ref_type) |
761 | ? btf_kind_name (BTF_KIND_ENUM) | |
762 | : btf_kind_name (ref_kind); | |
763 | ||
9b8bc020 | 764 | dw2_asm_output_data (4, btf_id, "%s: (BTF_KIND_%s '%s')", |
1502d724 | 765 | prefix, kind_name, |
9b6e2cb7 | 766 | get_btf_type_name (ref_type)); |
7aae58b0 DF |
767 | } |
768 | } | |
769 | ||
9b8bc020 DF |
770 | /* Asm'out a reference to a BTF_KIND_VAR or BTF_KIND_FUNC type. These type |
771 | kinds are BTF-specific, and should only be referred to by entries in | |
772 | BTF_KIND_DATASEC records. */ | |
773 | ||
774 | static void | |
775 | btf_asm_datasec_type_ref (const char *prefix, ctf_container_ref ctfc, | |
776 | ctf_id_t btf_id) | |
777 | { | |
778 | if (btf_id >= num_types_added + 1 | |
779 | && btf_id < num_types_added + num_vars_added + 1) | |
780 | { | |
781 | /* Ref to a variable. Should only appear in DATASEC entries. */ | |
782 | ctf_id_t var_id = btf_relative_var_id (btf_id); | |
783 | ctf_dvdef_ref dvd = ctfc->ctfc_vars_list[var_id]; | |
784 | dw2_asm_output_data (4, btf_id, "%s: (BTF_KIND_VAR '%s')", | |
785 | prefix, dvd->dvd_name); | |
786 | ||
787 | } | |
788 | else if (btf_id >= num_types_added + num_vars_added + 1) | |
789 | { | |
790 | /* Ref to a FUNC record. */ | |
791 | size_t func_id = btf_relative_func_id (btf_id); | |
792 | ctf_dtdef_ref ref_type = (*funcs)[func_id]; | |
793 | dw2_asm_output_data (4, btf_id, "%s: (BTF_KIND_FUNC '%s')", | |
794 | prefix, get_btf_type_name (ref_type)); | |
795 | } | |
796 | else | |
797 | /* The caller should not be calling this. */ | |
798 | gcc_unreachable (); | |
799 | } | |
800 | ||
b7e215a8 IB |
801 | /* Asm'out a BTF type. This routine is responsible for the bulk of the task |
802 | of converting CTF types to their BTF representation. */ | |
803 | ||
804 | static void | |
805 | btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd) | |
806 | { | |
1502d724 | 807 | uint32_t btf_kind, btf_kflag, btf_vlen, btf_size; |
b7e215a8 IB |
808 | uint32_t ctf_info = dtd->dtd_data.ctti_info; |
809 | ||
810 | btf_kind = get_btf_kind (CTF_V2_INFO_KIND (ctf_info)); | |
1502d724 | 811 | btf_size = dtd->dtd_data.ctti_size; |
b7e215a8 IB |
812 | btf_vlen = CTF_V2_INFO_VLEN (ctf_info); |
813 | ||
814 | /* By now any unrepresentable types have been removed. */ | |
815 | gcc_assert (btf_kind != BTF_KIND_UNKN); | |
816 | ||
817 | /* Size 0 integers are redundant definitions of void. None should remain | |
818 | in the types list by this point. */ | |
1502d724 | 819 | gcc_assert (btf_kind != BTF_KIND_INT || btf_size >= 1); |
b7e215a8 IB |
820 | |
821 | /* Re-encode the ctti_info to BTF. */ | |
822 | /* kflag is 1 for structs/unions with a bitfield member. | |
823 | kflag is 1 for forwards to unions. | |
824 | kflag is 0 in all other cases. */ | |
825 | btf_kflag = 0; | |
826 | ||
827 | if (btf_kind == BTF_KIND_STRUCT || btf_kind == BTF_KIND_UNION) | |
828 | { | |
829 | /* If a struct/union has ANY bitfield members, set kflag=1. | |
830 | Note that we must also change the encoding of every member to encode | |
831 | both member bitfield size (stealing most-significant 8 bits) and bit | |
832 | offset (LS 24 bits). This is done during preprocessing. */ | |
833 | ctf_dmdef_t *dmd; | |
834 | for (dmd = dtd->dtd_u.dtu_members; | |
835 | dmd != NULL; dmd = (ctf_dmdef_t *) ctf_dmd_list_next (dmd)) | |
836 | { | |
837 | /* Set kflag if this member is a representable bitfield. */ | |
838 | if (btf_dmd_representable_bitfield_p (ctfc, dmd)) | |
839 | btf_kflag = 1; | |
b7e215a8 IB |
840 | } |
841 | } | |
842 | ||
843 | /* BTF forwards make use of KIND_FLAG to distinguish between forwards to | |
844 | structs and forwards to unions. The dwarf2ctf conversion process stores | |
845 | the kind of the forward in ctti_type, but for BTF this must be 0 for | |
846 | forwards, with only the KIND_FLAG to distinguish. | |
1502d724 DF |
847 | Forwards to enum types are special-cased below. */ |
848 | else if (btf_kind == BTF_KIND_FWD) | |
b7e215a8 IB |
849 | { |
850 | if (dtd->dtd_data.ctti_type == CTF_K_UNION) | |
851 | btf_kflag = 1; | |
852 | ||
1502d724 DF |
853 | /* PR debug/111735. Encode foward-declared enums as BTF_KIND_ENUM |
854 | with vlen=0. A representation for these is not formally defined; | |
855 | this is the de-facto standard used by other tools like clang | |
856 | and pahole. */ | |
857 | else if (dtd->dtd_data.ctti_type == CTF_K_ENUM) | |
858 | { | |
859 | btf_kind = BTF_KIND_ENUM; | |
860 | btf_vlen = 0; | |
861 | } | |
862 | ||
863 | btf_size = 0; | |
b7e215a8 IB |
864 | } |
865 | ||
1502d724 | 866 | else if (btf_kind == BTF_KIND_ENUM) |
8422861b GM |
867 | { |
868 | btf_kflag = dtd->dtd_enum_unsigned | |
869 | ? BTF_KF_ENUM_UNSIGNED | |
870 | : BTF_KF_ENUM_SIGNED; | |
871 | if (dtd->dtd_data.ctti_size == 0x8) | |
872 | btf_kind = BTF_KIND_ENUM64; | |
873 | } | |
874 | ||
b6abc5db | 875 | /* PR debug/112656. BTF_KIND_FUNC_PROTO is always anonymous. */ |
1502d724 | 876 | else if (btf_kind == BTF_KIND_FUNC_PROTO) |
b6abc5db IB |
877 | dtd->dtd_data.ctti_name = 0; |
878 | ||
7aae58b0 | 879 | dw2_asm_output_data (4, dtd->dtd_data.ctti_name, |
f2e60a00 | 880 | "TYPE %" PRIu64 " BTF_KIND_%s '%s'", |
7aae58b0 | 881 | get_btf_id (dtd->dtd_type), btf_kind_name (btf_kind), |
9b6e2cb7 | 882 | get_btf_type_name (dtd)); |
b7e215a8 IB |
883 | dw2_asm_output_data (4, BTF_TYPE_INFO (btf_kind, btf_kflag, btf_vlen), |
884 | "btt_info: kind=%u, kflag=%u, vlen=%u", | |
885 | btf_kind, btf_kflag, btf_vlen); | |
886 | switch (btf_kind) | |
887 | { | |
888 | case BTF_KIND_INT: | |
18d0fad7 | 889 | case BTF_KIND_FLOAT: |
b7e215a8 IB |
890 | case BTF_KIND_STRUCT: |
891 | case BTF_KIND_UNION: | |
892 | case BTF_KIND_ENUM: | |
893 | case BTF_KIND_DATASEC: | |
8422861b | 894 | case BTF_KIND_ENUM64: |
1502d724 | 895 | dw2_asm_output_data (4, btf_size, "btt_size: %uB", btf_size); |
b7e215a8 | 896 | return; |
00887865 DF |
897 | case BTF_KIND_ARRAY: |
898 | case BTF_KIND_FWD: | |
899 | /* These types do not encode any information in the size/type field | |
900 | and should write 0. */ | |
901 | dw2_asm_output_data (4, 0, "(unused)"); | |
902 | return; | |
b7e215a8 IB |
903 | default: |
904 | break; | |
905 | } | |
906 | ||
9b8bc020 | 907 | ctf_id_t ref_id = dtd->dtd_data.ctti_type; |
7aae58b0 | 908 | btf_asm_type_ref ("btt_type", ctfc, ref_id); |
b7e215a8 IB |
909 | } |
910 | ||
911 | /* Asm'out the variable information following a BTF_KIND_ARRAY. */ | |
912 | ||
913 | static void | |
7aae58b0 | 914 | btf_asm_array (ctf_container_ref ctfc, ctf_arinfo_t arr) |
b7e215a8 | 915 | { |
9b8bc020 DF |
916 | btf_asm_type_ref ("bta_elem_type", ctfc, arr.ctr_contents); |
917 | btf_asm_type_ref ("bta_index_type", ctfc, arr.ctr_index); | |
7aae58b0 | 918 | dw2_asm_output_data (4, arr.ctr_nelems, "bta_nelems"); |
b7e215a8 IB |
919 | } |
920 | ||
921 | /* Asm'out a BTF_KIND_VAR. */ | |
922 | ||
923 | static void | |
7aae58b0 | 924 | btf_asm_varent (ctf_container_ref ctfc, ctf_dvdef_ref var) |
b7e215a8 | 925 | { |
7aae58b0 DF |
926 | dw2_asm_output_data (4, var->dvd_name_offset, "TYPE %u BTF_KIND_VAR '%s'", |
927 | (*(btf_var_ids->get (var)) + num_types_added + 1), | |
928 | var->dvd_name); | |
b7e215a8 | 929 | dw2_asm_output_data (4, BTF_TYPE_INFO (BTF_KIND_VAR, 0, 0), "btv_info"); |
9b8bc020 | 930 | btf_asm_type_ref ("btv_type", ctfc, var->dvd_type); |
2bce22e8 | 931 | dw2_asm_output_data (4, var->dvd_visibility, "btv_linkage"); |
b7e215a8 IB |
932 | } |
933 | ||
934 | /* Asm'out a member description following a BTF_KIND_STRUCT or | |
935 | BTF_KIND_UNION. */ | |
936 | ||
937 | static void | |
7aae58b0 | 938 | btf_asm_sou_member (ctf_container_ref ctfc, ctf_dmdef_t * dmd, unsigned int idx) |
b7e215a8 IB |
939 | { |
940 | ctf_dtdef_ref ref_type = ctfc->ctfc_types_list[dmd->dmd_type]; | |
9b8bc020 | 941 | ctf_id_t base_type = dmd->dmd_type; |
f079d69d DF |
942 | uint64_t sou_offset = dmd->dmd_offset; |
943 | ||
944 | dw2_asm_output_data (4, dmd->dmd_name_offset, | |
945 | "MEMBER '%s' idx=%u", | |
946 | dmd->dmd_name, idx); | |
b7e215a8 IB |
947 | |
948 | /* Re-encode bitfields to BTF representation. */ | |
949 | if (CTF_V2_INFO_KIND (ref_type->dtd_data.ctti_info) == CTF_K_SLICE) | |
950 | { | |
f079d69d DF |
951 | if (btf_dmd_representable_bitfield_p (ctfc, dmd)) |
952 | { | |
953 | unsigned short word_offset = ref_type->dtd_u.dtu_slice.cts_offset; | |
954 | unsigned short bits = ref_type->dtd_u.dtu_slice.cts_bits; | |
b7e215a8 | 955 | |
f079d69d DF |
956 | /* Pack the bit offset and bitfield size together. */ |
957 | sou_offset += word_offset; | |
958 | sou_offset &= 0x00ffffff; | |
959 | sou_offset |= ((bits & 0xff) << 24); | |
b7e215a8 | 960 | |
f079d69d | 961 | /* Refer to the base type of the slice. */ |
9b8bc020 | 962 | base_type = ref_type->dtd_u.dtu_slice.cts_type; |
f079d69d DF |
963 | } |
964 | else | |
965 | { | |
966 | /* Bitfield cannot be represented in BTF. Emit the member as having | |
967 | 'void' type. */ | |
968 | base_type = BTF_VOID_TYPEID; | |
969 | } | |
b7e215a8 | 970 | } |
f079d69d DF |
971 | |
972 | btf_asm_type_ref ("btm_type", ctfc, base_type); | |
973 | dw2_asm_output_data (4, sou_offset, "btm_offset"); | |
b7e215a8 IB |
974 | } |
975 | ||
8422861b | 976 | /* Asm'out an enum constant following a BTF_KIND_ENUM{,64}. */ |
b7e215a8 IB |
977 | |
978 | static void | |
7aae58b0 | 979 | btf_asm_enum_const (unsigned int size, ctf_dmdef_t * dmd, unsigned int idx) |
b7e215a8 | 980 | { |
7aae58b0 DF |
981 | dw2_asm_output_data (4, dmd->dmd_name_offset, "ENUM_CONST '%s' idx=%u", |
982 | dmd->dmd_name, idx); | |
099b15e2 CM |
983 | if (size <= 4) |
984 | dw2_asm_output_data (size < 4 ? 4 : size, dmd->dmd_value, "bte_value"); | |
8422861b GM |
985 | else |
986 | { | |
987 | dw2_asm_output_data (4, dmd->dmd_value & 0xffffffff, "bte_value_lo32"); | |
988 | dw2_asm_output_data (4, (dmd->dmd_value >> 32) & 0xffffffff, "bte_value_hi32"); | |
989 | } | |
b7e215a8 IB |
990 | } |
991 | ||
992 | /* Asm'out a function parameter description following a BTF_KIND_FUNC_PROTO. */ | |
993 | ||
994 | static void | |
7aae58b0 DF |
995 | btf_asm_func_arg (ctf_container_ref ctfc, ctf_func_arg_t * farg, |
996 | size_t stroffset) | |
b7e215a8 IB |
997 | { |
998 | /* If the function arg does not have a name, refer to the null string at | |
999 | the start of the string table. This ensures correct encoding for varargs | |
1000 | '...' arguments. */ | |
1001 | if ((farg->farg_name != NULL) && strcmp (farg->farg_name, "")) | |
1002 | dw2_asm_output_data (4, farg->farg_name_offset + stroffset, "farg_name"); | |
1003 | else | |
1004 | dw2_asm_output_data (4, 0, "farg_name"); | |
1005 | ||
7aae58b0 DF |
1006 | btf_asm_type_ref ("farg_type", ctfc, (btf_removed_type_p (farg->farg_type) |
1007 | ? BTF_VOID_TYPEID | |
9b8bc020 | 1008 | : farg->farg_type)); |
b7e215a8 IB |
1009 | } |
1010 | ||
1011 | /* Asm'out a BTF_KIND_FUNC type. */ | |
1012 | ||
1013 | static void | |
934da923 | 1014 | btf_asm_func_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd, ctf_id_t id) |
b7e215a8 | 1015 | { |
7aae58b0 DF |
1016 | ctf_id_t ref_id = dtd->dtd_data.ctti_type; |
1017 | dw2_asm_output_data (4, dtd->dtd_data.ctti_name, | |
934da923 | 1018 | "TYPE %" PRIu64 " BTF_KIND_FUNC '%s'", |
9b6e2cb7 | 1019 | btf_absolute_func_id (id), get_btf_type_name (dtd)); |
7aae58b0 DF |
1020 | dw2_asm_output_data (4, BTF_TYPE_INFO (BTF_KIND_FUNC, 0, dtd->linkage), |
1021 | "btt_info: kind=%u, kflag=%u, linkage=%u", | |
1022 | BTF_KIND_FUNC, 0, dtd->linkage); | |
9b8bc020 | 1023 | btf_asm_type_ref ("btt_type", ctfc, ref_id); |
b7e215a8 IB |
1024 | } |
1025 | ||
fa60ac54 CM |
1026 | /* Collect the name for the DATASEC reference required to be output as a |
1027 | symbol. */ | |
1028 | ||
1029 | static const char * | |
1030 | get_name_for_datasec_entry (ctf_container_ref ctfc, ctf_id_t ref_id) | |
1031 | { | |
1032 | if (ref_id >= num_types_added + 1 | |
1033 | && ref_id < num_types_added + num_vars_added + 1) | |
1034 | { | |
1035 | /* Ref to a variable. Should only appear in DATASEC entries. */ | |
1036 | ctf_id_t var_id = btf_relative_var_id (ref_id); | |
1037 | ctf_dvdef_ref dvd = ctfc->ctfc_vars_list[var_id]; | |
1038 | return dvd->dvd_name; | |
1039 | } | |
1040 | else if (ref_id >= num_types_added + num_vars_added + 1) | |
1041 | { | |
1042 | /* Ref to a FUNC record. */ | |
1043 | size_t func_id = btf_relative_func_id (ref_id); | |
1044 | ctf_dtdef_ref ref_type = (*funcs)[func_id]; | |
1045 | return get_btf_type_name (ref_type); | |
1046 | } | |
1047 | return NULL; | |
1048 | } | |
1049 | ||
b7e215a8 IB |
1050 | /* Asm'out a variable entry following a BTF_KIND_DATASEC. */ |
1051 | ||
1052 | static void | |
7aae58b0 | 1053 | btf_asm_datasec_entry (ctf_container_ref ctfc, struct btf_var_secinfo info) |
b7e215a8 | 1054 | { |
fa60ac54 | 1055 | const char *symbol_name = get_name_for_datasec_entry (ctfc, info.type); |
9b8bc020 | 1056 | btf_asm_datasec_type_ref ("bts_type", ctfc, info.type); |
8075477f | 1057 | if (!btf_with_core_debuginfo_p () || symbol_name == NULL) |
fa60ac54 CM |
1058 | dw2_asm_output_data (4, info.offset, "bts_offset"); |
1059 | else | |
1060 | dw2_asm_output_offset (4, symbol_name, NULL, "bts_offset"); | |
b7e215a8 IB |
1061 | dw2_asm_output_data (4, info.size, "bts_size"); |
1062 | } | |
1063 | ||
1064 | /* Asm'out a whole BTF_KIND_DATASEC, including its variable entries. */ | |
1065 | ||
1066 | static void | |
7aae58b0 DF |
1067 | btf_asm_datasec_type (ctf_container_ref ctfc, btf_datasec_t ds, ctf_id_t id, |
1068 | size_t stroffset) | |
b7e215a8 | 1069 | { |
7aae58b0 | 1070 | dw2_asm_output_data (4, ds.name_offset + stroffset, |
f2e60a00 | 1071 | "TYPE %" PRIu64 " BTF_KIND_DATASEC '%s'", |
7aae58b0 | 1072 | btf_absolute_datasec_id (id), ds.name); |
b7e215a8 IB |
1073 | dw2_asm_output_data (4, BTF_TYPE_INFO (BTF_KIND_DATASEC, 0, |
1074 | ds.entries.length ()), | |
7aae58b0 | 1075 | "btt_info: n_entries=%u", ds.entries.length ()); |
b7e215a8 IB |
1076 | /* Note: the "total section size in bytes" is emitted as 0 and patched by |
1077 | loaders such as libbpf. */ | |
1078 | dw2_asm_output_data (4, 0, "btt_size"); | |
1079 | for (size_t i = 0; i < ds.entries.length (); i++) | |
7aae58b0 | 1080 | btf_asm_datasec_entry (ctfc, ds.entries[i]); |
b7e215a8 IB |
1081 | } |
1082 | ||
1083 | /* Compute and output the header information for a .BTF section. */ | |
1084 | ||
1085 | static void | |
1086 | output_btf_header (ctf_container_ref ctfc) | |
1087 | { | |
1088 | switch_to_section (btf_info_section); | |
1089 | ASM_OUTPUT_LABEL (asm_out_file, btf_info_section_label); | |
1090 | ||
1091 | /* BTF magic number, version, flags, and header length. */ | |
1092 | dw2_asm_output_data (2, BTF_MAGIC, "btf_magic"); | |
1093 | dw2_asm_output_data (1, BTF_VERSION, "btf_version"); | |
1094 | dw2_asm_output_data (1, 0, "btf_flags"); | |
1095 | dw2_asm_output_data (4, sizeof (struct btf_header), "btf_hdr_len"); | |
1096 | ||
1097 | uint32_t type_off = 0, type_len = 0; | |
1098 | uint32_t str_off = 0, str_len = 0; | |
1099 | uint32_t datasec_vlen_bytes = 0; | |
1100 | ||
1101 | if (!ctfc_is_empty_container (ctfc)) | |
1102 | { | |
1103 | for (size_t i = 0; i < datasecs.length (); i++) | |
1104 | { | |
1105 | datasec_vlen_bytes += ((datasecs[i].entries.length ()) | |
1106 | * sizeof (struct btf_var_secinfo)); | |
1107 | } | |
1108 | ||
1109 | /* Total length (bytes) of the types section. */ | |
1110 | type_len = (num_types_added * sizeof (struct btf_type)) | |
1111 | + (num_types_created * sizeof (struct btf_type)) | |
1112 | + datasec_vlen_bytes | |
1113 | + ctfc->ctfc_num_vlen_bytes; | |
1114 | ||
1115 | str_off = type_off + type_len; | |
1116 | ||
1117 | str_len = ctfc->ctfc_strtable.ctstab_len | |
1118 | + ctfc->ctfc_aux_strtable.ctstab_len; | |
1119 | } | |
1120 | ||
1121 | /* Offset of type section. */ | |
1122 | dw2_asm_output_data (4, type_off, "type_off"); | |
1123 | /* Length of type section in bytes. */ | |
1124 | dw2_asm_output_data (4, type_len, "type_len"); | |
1125 | /* Offset of string section. */ | |
1126 | dw2_asm_output_data (4, str_off, "str_off"); | |
1127 | /* Length of string section in bytes. */ | |
1128 | dw2_asm_output_data (4, str_len, "str_len"); | |
1129 | } | |
1130 | ||
1131 | /* Output all BTF_KIND_VARs in CTFC. */ | |
1132 | ||
1133 | static void | |
1134 | output_btf_vars (ctf_container_ref ctfc) | |
1135 | { | |
1136 | size_t i; | |
1137 | size_t num_ctf_vars = num_vars_added; | |
1138 | if (num_ctf_vars) | |
1139 | { | |
1140 | for (i = 0; i < num_ctf_vars; i++) | |
7aae58b0 | 1141 | btf_asm_varent (ctfc, ctfc->ctfc_vars_list[i]); |
b7e215a8 IB |
1142 | } |
1143 | } | |
1144 | ||
1145 | /* Output BTF string records. The BTF strings section is a concatenation | |
1146 | of the standard and auxilliary string tables in the ctf container. */ | |
1147 | ||
1148 | static void | |
1149 | output_btf_strs (ctf_container_ref ctfc) | |
1150 | { | |
1151 | ctf_string_t * ctf_string = ctfc->ctfc_strtable.ctstab_head; | |
4a5bb8bc | 1152 | static int str_pos = 0; |
b7e215a8 IB |
1153 | |
1154 | while (ctf_string) | |
1155 | { | |
4a5bb8bc CM |
1156 | dw2_asm_output_nstring (ctf_string->cts_str, -1, "btf_string, str_pos = 0x%x", str_pos); |
1157 | str_pos += strlen(ctf_string->cts_str) + 1; | |
b7e215a8 IB |
1158 | ctf_string = ctf_string->cts_next; |
1159 | } | |
1160 | ||
1161 | ctf_string = ctfc->ctfc_aux_strtable.ctstab_head; | |
1162 | while (ctf_string) | |
1163 | { | |
4a5bb8bc CM |
1164 | dw2_asm_output_nstring (ctf_string->cts_str, -1, "btf_aux_string, str_pos = 0x%x", str_pos); |
1165 | str_pos += strlen(ctf_string->cts_str) + 1; | |
b7e215a8 IB |
1166 | ctf_string = ctf_string->cts_next; |
1167 | } | |
1168 | } | |
1169 | ||
1170 | /* Output all (representable) members of a BTF_KIND_STRUCT or | |
1171 | BTF_KIND_UNION type. */ | |
1172 | ||
1173 | static void | |
1174 | output_asm_btf_sou_fields (ctf_container_ref ctfc, ctf_dtdef_ref dtd) | |
1175 | { | |
1176 | ctf_dmdef_t * dmd; | |
1177 | ||
7aae58b0 | 1178 | unsigned idx = 0; |
b7e215a8 IB |
1179 | for (dmd = dtd->dtd_u.dtu_members; |
1180 | dmd != NULL; dmd = (ctf_dmdef_t *) ctf_dmd_list_next (dmd)) | |
7aae58b0 DF |
1181 | { |
1182 | btf_asm_sou_member (ctfc, dmd, idx); | |
1183 | idx++; | |
1184 | } | |
b7e215a8 IB |
1185 | } |
1186 | ||
8422861b | 1187 | /* Output all enumerator constants following a BTF_KIND_ENUM{,64}. */ |
b7e215a8 IB |
1188 | |
1189 | static void | |
1190 | output_asm_btf_enum_list (ctf_container_ref ARG_UNUSED (ctfc), | |
1191 | ctf_dtdef_ref dtd) | |
1192 | { | |
1193 | ctf_dmdef_t * dmd; | |
1194 | ||
7aae58b0 | 1195 | unsigned idx = 0; |
b7e215a8 IB |
1196 | for (dmd = dtd->dtd_u.dtu_members; |
1197 | dmd != NULL; dmd = (ctf_dmdef_t *) ctf_dmd_list_next (dmd)) | |
7aae58b0 DF |
1198 | { |
1199 | btf_asm_enum_const (dtd->dtd_data.ctti_size, dmd, idx); | |
1200 | idx++; | |
1201 | } | |
b7e215a8 IB |
1202 | } |
1203 | ||
1204 | /* Output all function arguments following a BTF_KIND_FUNC_PROTO. */ | |
1205 | ||
1206 | static void | |
1207 | output_asm_btf_func_args_list (ctf_container_ref ctfc, | |
1208 | ctf_dtdef_ref dtd) | |
1209 | { | |
1210 | size_t farg_name_offset = ctfc_get_strtab_len (ctfc, CTF_STRTAB); | |
1211 | ctf_func_arg_t * farg; | |
1212 | for (farg = dtd->dtd_u.dtu_argv; | |
1213 | farg != NULL; farg = (ctf_func_arg_t *) ctf_farg_list_next (farg)) | |
7aae58b0 | 1214 | btf_asm_func_arg (ctfc, farg, farg_name_offset); |
b7e215a8 IB |
1215 | } |
1216 | ||
1217 | /* Output the variable portion of a BTF type record. The information depends | |
1218 | on the kind of the type. */ | |
1219 | ||
1220 | static void | |
1221 | output_asm_btf_vlen_bytes (ctf_container_ref ctfc, ctf_dtdef_ref dtd) | |
1222 | { | |
1223 | uint32_t btf_kind, encoding; | |
1224 | ||
1225 | btf_kind = get_btf_kind (CTF_V2_INFO_KIND (dtd->dtd_data.ctti_info)); | |
1226 | ||
1227 | if (btf_kind == BTF_KIND_UNKN) | |
1228 | return; | |
1229 | ||
1230 | switch (btf_kind) | |
1231 | { | |
1232 | case BTF_KIND_INT: | |
1233 | /* Redundant definitions of void may still be hanging around in the type | |
1234 | list as size 0 integers. Skip emitting them. */ | |
1235 | if (dtd->dtd_data.ctti_size < 1) | |
1236 | break; | |
1237 | ||
5df04a7a JM |
1238 | /* In BTF the CHAR `encoding' seems to not be used, so clear it |
1239 | here. */ | |
1240 | dtd->dtd_u.dtu_enc.cte_format &= ~BTF_INT_CHAR; | |
1241 | ||
b7e215a8 IB |
1242 | encoding = BTF_INT_DATA (dtd->dtd_u.dtu_enc.cte_format, |
1243 | dtd->dtd_u.dtu_enc.cte_offset, | |
1244 | dtd->dtd_u.dtu_enc.cte_bits); | |
1245 | ||
1246 | dw2_asm_output_data (4, encoding, "bti_encoding"); | |
1247 | break; | |
1248 | ||
1249 | case BTF_KIND_ARRAY: | |
7aae58b0 | 1250 | btf_asm_array (ctfc, dtd->dtd_u.dtu_arr); |
b7e215a8 IB |
1251 | break; |
1252 | ||
1253 | case BTF_KIND_STRUCT: | |
1254 | case BTF_KIND_UNION: | |
1255 | output_asm_btf_sou_fields (ctfc, dtd); | |
1256 | break; | |
1257 | ||
1258 | case BTF_KIND_ENUM: | |
1259 | output_asm_btf_enum_list (ctfc, dtd); | |
1260 | break; | |
1261 | ||
1262 | case BTF_KIND_FUNC_PROTO: | |
1263 | output_asm_btf_func_args_list (ctfc, dtd); | |
1264 | break; | |
1265 | ||
1266 | case BTF_KIND_VAR: | |
1267 | /* BTF Variables are handled by output_btf_vars and btf_asm_varent. | |
1268 | There should be no BTF_KIND_VAR types at this point. */ | |
1269 | gcc_unreachable (); | |
1270 | ||
1271 | case BTF_KIND_DATASEC: | |
1272 | /* The BTF_KIND_DATASEC records are handled by output_btf_datasec_types | |
1273 | and btf_asm_datasec_type. There should be no BTF_KIND_DATASEC types | |
1274 | at this point. */ | |
1275 | gcc_unreachable (); | |
1276 | ||
1277 | default: | |
1278 | /* All other BTF type kinds have no variable length data. */ | |
1279 | break; | |
1280 | } | |
1281 | } | |
1282 | ||
1283 | /* Output a whole BTF type record for TYPE, including the fixed and variable | |
1284 | data portions. */ | |
1285 | ||
1286 | static void | |
1287 | output_asm_btf_type (ctf_container_ref ctfc, ctf_dtdef_ref type) | |
1288 | { | |
1289 | if (btf_emit_id_p (type->dtd_type)) | |
1290 | { | |
1291 | btf_asm_type (ctfc, type); | |
1292 | output_asm_btf_vlen_bytes (ctfc, type); | |
1293 | } | |
1294 | } | |
1295 | ||
1296 | /* Output all BTF types in the container. This does not include synthesized | |
1297 | types: BTF_KIND_VAR, BTF_KIND_FUNC, nor BTF_KIND_DATASEC. */ | |
1298 | ||
1299 | static void | |
1300 | output_btf_types (ctf_container_ref ctfc) | |
1301 | { | |
1302 | size_t i; | |
1303 | size_t num_types = ctfc->ctfc_types->elements (); | |
1304 | if (num_types) | |
1305 | { | |
1306 | for (i = 1; i <= num_types; i++) | |
1307 | output_asm_btf_type (ctfc, ctfc->ctfc_types_list[i]); | |
1308 | } | |
1309 | } | |
1310 | ||
1311 | /* Output all BTF_KIND_FUNC type records. */ | |
1312 | ||
1313 | static void | |
7aae58b0 | 1314 | output_btf_func_types (ctf_container_ref ctfc) |
b7e215a8 | 1315 | { |
69a3ce49 CM |
1316 | ctf_dtdef_ref ref; |
1317 | unsigned i; | |
1318 | FOR_EACH_VEC_ELT (*funcs, i, ref) | |
1319 | btf_asm_func_type (ctfc, ref, i); | |
b7e215a8 IB |
1320 | } |
1321 | ||
1322 | /* Output all BTF_KIND_DATASEC records. */ | |
1323 | ||
1324 | static void | |
1325 | output_btf_datasec_types (ctf_container_ref ctfc) | |
1326 | { | |
1327 | size_t name_offset = ctfc_get_strtab_len (ctfc, CTF_STRTAB); | |
1328 | ||
1329 | for (size_t i = 0; i < datasecs.length(); i++) | |
7aae58b0 | 1330 | btf_asm_datasec_type (ctfc, datasecs[i], i, name_offset); |
b7e215a8 IB |
1331 | } |
1332 | ||
1333 | /* Postprocess the CTF debug data post initialization. | |
1334 | ||
1335 | During the postprocess pass: | |
1336 | ||
1337 | - Prepare the sorted list of BTF types. | |
1338 | ||
1339 | The sorted list of BTF types is, firstly, used for lookup (during the BTF | |
1340 | generation process) of CTF/BTF types given a typeID. | |
1341 | ||
1342 | Secondly, in the emitted BTF section, BTF Types need to be in the sorted | |
1343 | order of their type IDs. The BTF types section is viewed as an array, | |
1344 | with type IDs used to index into that array. It is essential that every | |
1345 | type be placed at the exact index corresponding to its ID, or else | |
1346 | references to that type from other types will no longer be correct. | |
1347 | ||
1348 | - References to void types are converted to reference BTF_VOID_TYPEID. In | |
1349 | CTF, a distinct type is used to encode void. | |
1350 | ||
1351 | - Bitfield struct/union members are converted to BTF encoding. CTF uses | |
1352 | slices to encode bitfields, but BTF does not have slices and encodes | |
1353 | bitfield information directly in the variable-length btf_member | |
1354 | descriptions following the struct or union type. | |
1355 | ||
1356 | - Unrepresentable types are removed. We cannot have any invalid BTF types | |
1357 | appearing in the output so they must be removed, and type ids of other | |
1358 | types and references adjust accordingly. This also involves ensuring that | |
1359 | BTF descriptions of struct members referring to unrepresentable types are | |
1360 | not emitted, as they would be nonsensical. | |
1361 | ||
1362 | - Adjust inner- and inter-type references-by-ID to account for removed | |
1363 | types, and construct the types list. */ | |
1364 | ||
1365 | void | |
1366 | btf_init_postprocess (void) | |
1367 | { | |
1368 | ctf_container_ref tu_ctfc = ctf_get_tu_ctfc (); | |
1369 | ||
b7e215a8 IB |
1370 | holes.create (0); |
1371 | voids.create (0); | |
1372 | ||
1373 | num_types_added = 0; | |
1374 | num_types_created = 0; | |
1375 | ||
4f7aa145 DF |
1376 | /* Workaround for 'const void' variables. These variables are sometimes used |
1377 | in eBPF programs to address kernel symbols. DWARF does not generate const | |
1378 | qualifier on void type, so we would incorrectly emit these variables | |
1379 | without the const qualifier. | |
1380 | Unfortunately we need the TREE node to know it was const, and we need | |
1381 | to create the const modifier type (if needed) now, before making the types | |
1382 | list. So we can't avoid iterating with FOR_EACH_VARIABLE here, and then | |
1383 | again when creating the DATASEC entries. */ | |
1384 | ctf_id_t constvoid_id = CTF_NULL_TYPEID; | |
1385 | varpool_node *var; | |
1386 | FOR_EACH_VARIABLE (var) | |
1387 | { | |
1388 | if (!var->decl) | |
1389 | continue; | |
1390 | ||
1391 | tree type = TREE_TYPE (var->decl); | |
1392 | if (type && VOID_TYPE_P (type) && TYPE_READONLY (type)) | |
1393 | { | |
1394 | dw_die_ref die = lookup_decl_die (var->decl); | |
1395 | if (die == NULL) | |
1396 | continue; | |
1397 | ||
1398 | ctf_dvdef_ref dvd = ctf_dvd_lookup (tu_ctfc, die); | |
1399 | if (dvd == NULL) | |
1400 | continue; | |
1401 | ||
1402 | /* Create the 'const' modifier type for void. */ | |
1403 | if (constvoid_id == CTF_NULL_TYPEID) | |
1404 | constvoid_id = ctf_add_reftype (tu_ctfc, CTF_ADD_ROOT, | |
1405 | dvd->dvd_type, CTF_K_CONST, NULL); | |
1406 | dvd->dvd_type = constvoid_id; | |
1407 | } | |
1408 | } | |
1409 | ||
1410 | size_t i; | |
1411 | size_t num_ctf_types = tu_ctfc->ctfc_types->elements (); | |
1412 | ||
b7e215a8 IB |
1413 | if (num_ctf_types) |
1414 | { | |
1415 | init_btf_id_map (num_ctf_types + 1); | |
1416 | ||
1417 | /* Allocate the types list and traverse all types, placing each type | |
1418 | at the index according to its ID. Add 1 because type ID 0 always | |
1419 | represents VOID. */ | |
1420 | tu_ctfc->ctfc_types_list | |
1421 | = ggc_vec_alloc<ctf_dtdef_ref>(num_ctf_types + 1); | |
1422 | tu_ctfc->ctfc_types->traverse<ctf_container_ref, btf_dtd_postprocess_cb> | |
1423 | (tu_ctfc); | |
1424 | ||
1425 | /* Build mapping of CTF type ID -> BTF type ID, and count total number | |
1426 | of valid BTF types added. */ | |
1427 | for (i = 1; i <= num_ctf_types; i++) | |
1428 | { | |
1429 | ctf_dtdef_ref dtd = tu_ctfc->ctfc_types_list[i]; | |
1430 | ctf_id_t btfid = btf_adjust_type_id (dtd->dtd_type); | |
1431 | set_btf_id (dtd->dtd_type, btfid); | |
1432 | if (btfid < BTF_MAX_TYPE && (btfid != BTF_VOID_TYPEID)) | |
1433 | num_types_added ++; | |
1434 | } | |
1435 | } | |
1436 | } | |
1437 | ||
1438 | /* Process and output all BTF data. Entry point of btfout. */ | |
1439 | ||
1440 | void | |
1441 | btf_output (const char * filename) | |
1442 | { | |
1443 | ctf_container_ref tu_ctfc = ctf_get_tu_ctfc (); | |
1444 | ||
1445 | init_btf_sections (); | |
1446 | ||
1447 | datasecs.create (0); | |
1448 | vec_alloc (funcs, 16); | |
1449 | ||
1450 | ctf_add_cuname (tu_ctfc, filename); | |
1451 | ||
1452 | btf_emit_preprocess (tu_ctfc); | |
1453 | ||
1454 | output_btf_header (tu_ctfc); | |
1455 | output_btf_types (tu_ctfc); | |
1456 | output_btf_vars (tu_ctfc); | |
7aae58b0 | 1457 | output_btf_func_types (tu_ctfc); |
b7e215a8 IB |
1458 | output_btf_datasec_types (tu_ctfc); |
1459 | output_btf_strs (tu_ctfc); | |
1460 | } | |
1461 | ||
1462 | /* Reset all state for BTF generation so that we can rerun the compiler within | |
1463 | the same process. */ | |
1464 | ||
1465 | void | |
1466 | btf_finalize (void) | |
1467 | { | |
1468 | btf_info_section = NULL; | |
1469 | ||
1470 | /* Clear preprocessing state. */ | |
1471 | num_vars_added = 0; | |
1472 | num_types_added = 0; | |
1473 | num_types_created = 0; | |
1474 | ||
1475 | holes.release (); | |
1476 | voids.release (); | |
1477 | for (size_t i = 0; i < datasecs.length (); i++) | |
1478 | datasecs[i].entries.release (); | |
1479 | datasecs.release (); | |
1480 | ||
1481 | funcs = NULL; | |
1482 | ||
d6a87d96 IB |
1483 | btf_var_ids->empty (); |
1484 | btf_var_ids = NULL; | |
1485 | ||
b7e215a8 IB |
1486 | free (btf_id_map); |
1487 | btf_id_map = NULL; | |
1488 | ||
b7e215a8 IB |
1489 | ctf_container_ref tu_ctfc = ctf_get_tu_ctfc (); |
1490 | ctfc_delete_container (tu_ctfc); | |
1491 | tu_ctfc = NULL; | |
1492 | } | |
1493 | ||
69a3ce49 CM |
1494 | /* Traversal function for all BTF_KIND_FUNC type records. */ |
1495 | ||
1496 | bool | |
1497 | traverse_btf_func_types (funcs_traverse_callback callback, void *data) | |
1498 | { | |
1499 | ctf_dtdef_ref ref; | |
1500 | unsigned i; | |
1501 | FOR_EACH_VEC_ELT (*funcs, i, ref) | |
1502 | { | |
1503 | bool stop = callback (ref, data); | |
1504 | if (stop == true) | |
1505 | return true; | |
1506 | } | |
1507 | return false; | |
1508 | } | |
1509 | ||
b7e215a8 | 1510 | #include "gt-btfout.h" |