LCOV - code coverage report
Current view: top level - gcc - btfout.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 95.1 % 714 679
Test Date: 2026-02-28 14:20:25 Functions: 96.4 % 56 54
Legend: Lines:     hit not hit

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

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.