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