LCOV - code coverage report
Current view: top level - gcc - btfout.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 95.9 % 559 536
Test Date: 2024-04-20 14:03:02 Functions: 80.0 % 50 40
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

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

Generated by: LCOV version 2.1-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.