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