/* Output BTF format from GCC.
   Copyright (C) 2021 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

/* This file contains routines to output the BPF Type Format (BTF). The BTF
   debug format is very similar to CTF; as a result, the structure of this file
   closely resembles that of ctfout.c, and the same CTF container objects are
   used.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "target.h"
#include "memmodel.h"
#include "tm_p.h"
#include "output.h"
#include "dwarf2asm.h"
#include "debug.h"
#include "ctfc.h"
#include "diagnostic-core.h"
#include "cgraph.h"
#include "varasm.h"
#include "dwarf2out.h" /* For lookup_decl_die.  */

static int btf_label_num;

static GTY (()) section * btf_info_section;

/* BTF debug info section.  */

#ifndef BTF_INFO_SECTION_NAME
#define BTF_INFO_SECTION_NAME  ".BTF"
#endif

#define BTF_INFO_SECTION_FLAGS (SECTION_DEBUG)

/* Maximum size (in bytes) for an artifically generated BTF label.  */

#define MAX_BTF_LABEL_BYTES 40

static char btf_info_section_label[MAX_BTF_LABEL_BYTES];

#ifndef BTF_INFO_SECTION_LABEL
#define BTF_INFO_SECTION_LABEL  "Lbtf"
#endif

/* BTF encodes void as type id 0.  */

#define BTF_VOID_TYPEID 0
#define BTF_INIT_TYPEID 1

#define BTF_INVALID_TYPEID 0xFFFFFFFF

/* Mapping of CTF variables to the IDs they will be assigned when they are
   converted to BTF_KIND_VAR type records. Strictly accounts for the index
   from the start of the variable type entries, does not include the number
   of types emitted prior to the variable records.  */
static GTY (()) hash_map <ctf_dvdef_ref, unsigned> *btf_var_ids;

/* Mapping of type IDs from original CTF ID to BTF ID. Types do not map
   1-to-1 from CTF to BTF. To avoid polluting the CTF container when updating
   type references-by-ID, we use this map instead.  */
static ctf_id_t * btf_id_map = NULL;

/* Information for creating the BTF_KIND_DATASEC records.  */
typedef struct btf_datasec
{
  const char *name;                    /* Section name, e.g. ".bss".  */
  uint32_t name_offset;                /* Offset to name in string table.  */
  vec<struct btf_var_secinfo> entries; /* Variable entries in this section.  */
} btf_datasec_t;

/* One BTF_KIND_DATASEC record is created for each output data section which
   will hold at least one variable.  */
static vec<btf_datasec_t> datasecs;

/* Holes occur for types which are present in the CTF container, but are either
   non-representable or redundant in BTF.  */
static vec<ctf_id_t> holes;

/* CTF definition(s) of void. Only one definition of void should be generated.
   We should not encounter more than one definition of void, but use a vector
   to be safe.  */
static vec<ctf_id_t> voids;

/* Functions in BTF have two separate type records - one for the prototype
   (BTF_KIND_FUNC_PROTO), as well as a BTF_KIND_FUNC. CTF_K_FUNCTION types
   map closely to BTF_KIND_FUNC_PROTO, but the BTF_KIND_FUNC records must be
   created. This vector holds them.  */
static GTY (()) vec<ctf_dtdef_ref, va_gc> *funcs;

/* The number of BTF variables added to the TU CTF container.  */
static unsigned int num_vars_added = 0;

/* The number of BTF types added to the TU CTF container.  */
static unsigned int num_types_added = 0;

/* The number of types synthesized for BTF that do not correspond to
   CTF types.  */
static unsigned int num_types_created = 0;

/* Map a CTF type kind to the corresponding BTF type kind.  */

static uint32_t
get_btf_kind (uint32_t ctf_kind)
{
  /* N.B. the values encoding kinds are not in general the same for the
     same kind between CTF and BTF. e.g. CTF_K_CONST != BTF_KIND_CONST.  */
  switch (ctf_kind)
    {
    case CTF_K_INTEGER:  return BTF_KIND_INT;
    case CTF_K_FLOAT:	 return BTF_KIND_FLOAT;
    case CTF_K_POINTER:  return BTF_KIND_PTR;
    case CTF_K_ARRAY:    return BTF_KIND_ARRAY;
    case CTF_K_FUNCTION: return BTF_KIND_FUNC_PROTO;
    case CTF_K_STRUCT:   return BTF_KIND_STRUCT;
    case CTF_K_UNION:    return BTF_KIND_UNION;
    case CTF_K_ENUM:     return BTF_KIND_ENUM;
    case CTF_K_FORWARD:  return BTF_KIND_FWD;
    case CTF_K_TYPEDEF:  return BTF_KIND_TYPEDEF;
    case CTF_K_VOLATILE: return BTF_KIND_VOLATILE;
    case CTF_K_CONST:    return BTF_KIND_CONST;
    case CTF_K_RESTRICT: return BTF_KIND_RESTRICT;
    default:;
    }
  return BTF_KIND_UNKN;
}

/* Allocate the btf_id_map, and initialize elements to BTF_INVALID_TYPEID.  */

static void
init_btf_id_map (size_t len)
{
  btf_id_map = XNEWVEC (ctf_id_t, len);

  btf_id_map[0] = BTF_VOID_TYPEID;
  for (size_t i = 1; i < len; i++)
    btf_id_map[i] = BTF_INVALID_TYPEID;
}

/* Return the BTF type ID of CTF type ID KEY, or BTF_INVALID_TYPEID if the CTF
   type with ID KEY does not map to a BTF type.  */

ctf_id_t
get_btf_id (ctf_id_t key)
{
  return btf_id_map[key];
}

/* Set the CTF type ID KEY to map to BTF type ID VAL.  */

static inline void
set_btf_id (ctf_id_t key, ctf_id_t val)
{
  btf_id_map[key] = val;
}

/* Return TRUE iff the given CTF type ID maps to a BTF type which will
   be emitted.  */
static inline bool
btf_emit_id_p (ctf_id_t id)
{
  return ((btf_id_map[id] != BTF_VOID_TYPEID)
	  && (btf_id_map[id] <= BTF_MAX_TYPE));
}

/* Each BTF type can be followed additional, variable-length information
   completing the description of the type. Calculate the number of bytes
   of variable information required to encode a given type.  */

static uint64_t
btf_calc_num_vbytes (ctf_dtdef_ref dtd)
{
  uint64_t vlen_bytes = 0;

  uint32_t kind = get_btf_kind (CTF_V2_INFO_KIND (dtd->dtd_data.ctti_info));
  uint32_t vlen = CTF_V2_INFO_VLEN (dtd->dtd_data.ctti_info);

  switch (kind)
    {
    case BTF_KIND_UNKN:
    case BTF_KIND_PTR:
    case BTF_KIND_FWD:
    case BTF_KIND_TYPEDEF:
    case BTF_KIND_VOLATILE:
    case BTF_KIND_CONST:
    case BTF_KIND_RESTRICT:
    case BTF_KIND_FUNC:
    /* These kinds have no vlen data.  */
      break;

    case BTF_KIND_INT:
      /* Size 0 integers represent redundant definitions of void that will
	 not be emitted. Don't allocate space for them.  */
      if (dtd->dtd_data.ctti_size == 0)
	break;

      vlen_bytes += sizeof (uint32_t);
      break;

    case BTF_KIND_ARRAY:
      vlen_bytes += sizeof (struct btf_array);
      break;

    case BTF_KIND_STRUCT:
    case BTF_KIND_UNION:
      vlen_bytes += vlen * sizeof (struct btf_member);
      break;

    case BTF_KIND_ENUM:
      vlen_bytes += vlen * sizeof (struct btf_enum);
      break;

    case BTF_KIND_FUNC_PROTO:
      vlen_bytes += vlen * sizeof (struct btf_param);
      break;

    case BTF_KIND_VAR:
      vlen_bytes += sizeof (struct btf_var);
      break;

    case BTF_KIND_DATASEC:
      vlen_bytes += vlen * sizeof (struct btf_var_secinfo);
      break;

    default:
      break;
    }
  return vlen_bytes;
}

/* Initialize BTF section (.BTF) for output.  */

void
init_btf_sections (void)
{
  btf_info_section = get_section (BTF_INFO_SECTION_NAME, BTF_INFO_SECTION_FLAGS,
				  NULL);

  ASM_GENERATE_INTERNAL_LABEL (btf_info_section_label,
			       BTF_INFO_SECTION_LABEL, btf_label_num++);
}

/* Push a BTF datasec variable entry INFO into the datasec named SECNAME,
   creating the datasec if it does not already exist.  */

static void
btf_datasec_push_entry (ctf_container_ref ctfc, const char *secname,
			struct btf_var_secinfo info)
{
  if (secname == NULL)
    return;

  for (size_t i = 0; i < datasecs.length (); i++)
    if (strcmp (datasecs[i].name, secname) == 0)
      {
	datasecs[i].entries.safe_push (info);
	return;
      }

  /* If we don't already have a datasec record for secname, make one.  */

  uint32_t str_off;
  ctf_add_string (ctfc, secname, &str_off, CTF_AUX_STRTAB);
  if (strcmp (secname, ""))
    ctfc->ctfc_aux_strlen += strlen (secname) + 1;

  btf_datasec_t ds;
  ds.name = secname;
  ds.name_offset = str_off;

  ds.entries.create (0);
  ds.entries.safe_push (info);

  datasecs.safe_push (ds);
  num_types_created++;
}

/* Construct all BTF_KIND_DATASEC records for CTFC. One such record is created
   for each non-empty data-containing section in the output. Each record is
   followed by a variable number of entries describing the variables stored
   in that section.  */

static void
btf_collect_datasec (ctf_container_ref ctfc)
{
  /* See cgraph.h struct symtab_node, which varpool_node extends.  */
  varpool_node *node;
  FOR_EACH_VARIABLE (node)
    {
      dw_die_ref die = lookup_decl_die (node->decl);
      if (die == NULL)
	continue;

      ctf_dvdef_ref dvd = ctf_dvd_lookup (ctfc, die);
      if (dvd == NULL)
	continue;

      const char *section_name = node->get_section ();

      if (section_name == NULL)
	{
	  switch (categorize_decl_for_section (node->decl, 0))
	    {
	    case SECCAT_BSS:
	      section_name = ".bss";
	      break;
	    case SECCAT_DATA:
	      section_name = ".data";
	      break;
	    case SECCAT_RODATA:
	      section_name = ".rodata";
	      break;
	    default:
	      continue;
	    }
	}

      struct btf_var_secinfo info;

      info.type = 0;
      unsigned int *var_id = btf_var_ids->get (dvd);
      if (var_id)
	/* +1 for the sentinel type not in the types map.  */
	info.type = *var_id + num_types_added + 1;
      else
	continue;

      info.size = 0;
      tree size = DECL_SIZE_UNIT (node->decl);
      if (tree_fits_uhwi_p (size))
	info.size = tree_to_uhwi (size);

      /* Offset is left as 0 at compile time, to be filled in by loaders such
	 as libbpf.  */
      info.offset = 0;

      btf_datasec_push_entry (ctfc, section_name, info);
    }
}

/* Return true if the type ID is that of a type which will not be emitted (for
   example, if it is not representable in BTF).  */

static bool
btf_removed_type_p (ctf_id_t id)
{
  return holes.contains (id);
}

/* Adjust the given type ID to account for holes and duplicate definitions of
   void.  */

static ctf_id_t
btf_adjust_type_id (ctf_id_t id)
{
  size_t n;
  ctf_id_t i = 0;

  /* Do not adjust invalid type markers.  */
  if (id == BTF_INVALID_TYPEID)
    return id;

  for (n = 0; n < voids.length (); n++)
    if (id == voids[n])
      return BTF_VOID_TYPEID;

  for (n = 0; n < holes.length (); n++)
    {
      if (holes[n] < id)
	i++;
      else if (holes[n] == id)
	return BTF_VOID_TYPEID;
    }

  return id - i;
}

/* Postprocessing callback routine for types.  */

int
btf_dtd_postprocess_cb (ctf_dtdef_ref *slot, ctf_container_ref arg_ctfc)
{
  ctf_dtdef_ref ctftype = (ctf_dtdef_ref) * slot;

  size_t index = ctftype->dtd_type;
  gcc_assert (index <= arg_ctfc->ctfc_types->elements ());

  uint32_t ctf_kind, btf_kind;

  ctf_kind = CTF_V2_INFO_KIND (ctftype->dtd_data.ctti_info);
  btf_kind = get_btf_kind (ctf_kind);

  if (btf_kind == BTF_KIND_UNKN)
    /* This type is not representable in BTF. Create a hole.  */
    holes.safe_push (ctftype->dtd_type);

  else if (btf_kind == BTF_KIND_INT && ctftype->dtd_data.ctti_size == 0)
    {
      /* This is a (redundant) definition of void.  */
      voids.safe_push (ctftype->dtd_type);
      holes.safe_push (ctftype->dtd_type);
    }

  arg_ctfc->ctfc_types_list[index] = ctftype;

  return 1;
}

/* Preprocessing callback routine for variables.  */

int
btf_dvd_emit_preprocess_cb (ctf_dvdef_ref *slot, ctf_container_ref arg_ctfc)
{
  ctf_dvdef_ref var = (ctf_dvdef_ref) * slot;

  /* Do not add variables which refer to unsupported types.  */
  if (btf_removed_type_p (var->dvd_type))
    return 1;

  arg_ctfc->ctfc_vars_list[num_vars_added] = var;
  btf_var_ids->put (var, num_vars_added);

  num_vars_added++;
  num_types_created++;

  return 1;
}

/* Preprocessing callback routine for types.  */

static void
btf_dtd_emit_preprocess_cb (ctf_container_ref ctfc, ctf_dtdef_ref dtd)
{
  if (!btf_emit_id_p (dtd->dtd_type))
    return;

  uint32_t btf_kind
    = get_btf_kind (CTF_V2_INFO_KIND (dtd->dtd_data.ctti_info));

  if (btf_kind == BTF_KIND_FUNC_PROTO)
    {
      /* Functions actually get two types: a BTF_KIND_FUNC_PROTO, and
	 also a BTF_KIND_FUNC. But the CTF container only allocates one
	 type per function, which matches closely with BTF_KIND_FUNC_PROTO.
	 For each such function, also allocate a BTF_KIND_FUNC entry.
	 These will be output later.  */
      ctf_dtdef_ref func_dtd = ggc_cleared_alloc<ctf_dtdef_t> ();
      func_dtd->dtd_data = dtd->dtd_data;
      func_dtd->dtd_data.ctti_type = dtd->dtd_type;

      vec_safe_push (funcs, func_dtd);
      num_types_created++;

      /* Only the BTF_KIND_FUNC type actually references the name. The
	 BTF_KIND_FUNC_PROTO is always anonymous.  */
      dtd->dtd_data.ctti_name = 0;
    }

  ctfc->ctfc_num_vlen_bytes += btf_calc_num_vbytes (dtd);
}

/* Preprocess the CTF information to prepare for BTF output.  BTF is almost a
   subset of CTF, with many small differences in encoding, and lacking support
   for some types (notably floating point formats).

   During the preprocessing pass:
   - Ascertain that the sorted list of types has been prepared.  For the BTF
     generation process, this is taken care of by the btf_init_postprocess ().

   - BTF_KIND_FUNC and BTF_KIND_DATASEC records are constructed. These types do
     not have analogues in CTF (the analogous type to CTF_K_FUNCTION is
     BTF_KIND_FUNC_PROTO), but can be relatively easily deduced from CTF
     information.

   - Construct BTF_KIND_VAR records, representing variables.

   - Calculate the total size in bytes of variable-length information following
     BTF type records. This is used for outputting the BTF header.

   After preprocessing, all BTF information is ready to be output:
   - ctfc->ctfc_types_list holdstypes converted from CTF types. This does not
     include KIND_VAR, KIND_FUNC, nor KIND_DATASEC types. These types have been
     re-encoded to the appropriate representation in BTF.
   - ctfc->ctfc_vars_list holds all variables which should be output.
     Variables of unsupported types are not present in this list.
   - Vector 'funcs' holds all BTF_KIND_FUNC types, one to match each
     BTF_KIND_FUNC_PROTO.
   - Vector 'datasecs' holds all BTF_KIND_DATASEC types.  */

static void
btf_emit_preprocess (ctf_container_ref ctfc)
{
  size_t num_ctf_types = ctfc->ctfc_types->elements ();
  size_t num_ctf_vars = ctfc->ctfc_vars->elements ();
  size_t i;

  if (num_ctf_types)
    {
      gcc_assert (ctfc->ctfc_types_list);
      /* Preprocess the types.  */
      for (i = 1; i <= num_ctf_types; i++)
	btf_dtd_emit_preprocess_cb (ctfc, ctfc->ctfc_types_list[i]);
    }

  btf_var_ids = hash_map<ctf_dvdef_ref, unsigned int>::create_ggc (100);

  if (num_ctf_vars)
    {
      /* Allocate and construct the list of variables. While BTF variables are
	 not distinct from types (in that variables are simply types with
	 BTF_KIND_VAR), it is simpler to maintain a separate list of variables
	 and append them to the types list during output.  */
      ctfc->ctfc_vars_list = ggc_vec_alloc<ctf_dvdef_ref>(num_ctf_vars);
      ctfc->ctfc_vars->traverse<ctf_container_ref, btf_dvd_emit_preprocess_cb>
	(ctfc);

      ctfc->ctfc_num_vlen_bytes += (num_vars_added * sizeof (struct btf_var));
    }

  btf_collect_datasec (ctfc);
}

/* Return true iff DMD is a member description of a bit-field which can be
   validly represented in BTF.  */

static bool
btf_dmd_representable_bitfield_p (ctf_container_ref ctfc, ctf_dmdef_t *dmd)
{
  ctf_dtdef_ref ref_type = ctfc->ctfc_types_list[dmd->dmd_type];

  if (CTF_V2_INFO_KIND (ref_type->dtd_data.ctti_info) == CTF_K_SLICE)
    {
      unsigned short word_offset = ref_type->dtd_u.dtu_slice.cts_offset;
      unsigned short bits = ref_type->dtd_u.dtu_slice.cts_bits;
      uint64_t sou_offset = dmd->dmd_offset;

      if ((bits > 0xff) || ((sou_offset + word_offset) > 0xffffff))
	return false;

      return true;
    }

  return false;
}

/* BTF asm helper routines.  */

/* Asm'out a BTF type. This routine is responsible for the bulk of the task
   of converting CTF types to their BTF representation.  */

static void
btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd)
{
  uint32_t btf_kind, btf_kflag, btf_vlen, btf_size_type;
  uint32_t ctf_info = dtd->dtd_data.ctti_info;

  btf_kind = get_btf_kind (CTF_V2_INFO_KIND (ctf_info));
  btf_size_type = dtd->dtd_data.ctti_type;
  btf_vlen = CTF_V2_INFO_VLEN (ctf_info);

  /* By now any unrepresentable types have been removed.  */
  gcc_assert (btf_kind != BTF_KIND_UNKN);

  /* Size 0 integers are redundant definitions of void. None should remain
     in the types list by this point.  */
  gcc_assert (btf_kind != BTF_KIND_INT || btf_size_type >= 1);

  /* Re-encode the ctti_info to BTF.  */
  /* kflag is 1 for structs/unions with a bitfield member.
     kflag is 1 for forwards to unions.
     kflag is 0 in all other cases.  */
  btf_kflag = 0;

  if (btf_kind == BTF_KIND_STRUCT || btf_kind == BTF_KIND_UNION)
    {
      /* If a struct/union has ANY bitfield members, set kflag=1.
	 Note that we must also change the encoding of every member to encode
	 both member bitfield size (stealing most-significant 8 bits) and bit
	 offset (LS 24 bits). This is done during preprocessing.  */
      ctf_dmdef_t *dmd;
      for (dmd = dtd->dtd_u.dtu_members;
	   dmd != NULL; dmd = (ctf_dmdef_t *) ctf_dmd_list_next (dmd))
	{
	  /* Set kflag if this member is a representable bitfield.  */
	  if (btf_dmd_representable_bitfield_p (ctfc, dmd))
	    btf_kflag = 1;

	  /* Struct members that refer to unsupported types or bitfield formats
	     shall be skipped. These are marked during preprocessing.  */
	  else if (!btf_emit_id_p (dmd->dmd_type))
	    btf_vlen -= 1;
	}
    }

  /* BTF forwards make use of KIND_FLAG to distinguish between forwards to
     structs and forwards to unions. The dwarf2ctf conversion process stores
     the kind of the forward in ctti_type, but for BTF this must be 0 for
     forwards, with only the KIND_FLAG to distinguish.
     At time of writing, BTF forwards to enums are unspecified.  */
  if (btf_kind == BTF_KIND_FWD)
    {
      if (dtd->dtd_data.ctti_type == CTF_K_UNION)
	btf_kflag = 1;

      btf_size_type = 0;
    }

  dw2_asm_output_data (4, dtd->dtd_data.ctti_name, "btt_name");
  dw2_asm_output_data (4, BTF_TYPE_INFO (btf_kind, btf_kflag, btf_vlen),
		       "btt_info: kind=%u, kflag=%u, vlen=%u",
		       btf_kind, btf_kflag, btf_vlen);
  switch (btf_kind)
    {
    case BTF_KIND_INT:
    case BTF_KIND_FLOAT:
    case BTF_KIND_STRUCT:
    case BTF_KIND_UNION:
    case BTF_KIND_ENUM:
    case BTF_KIND_DATASEC:
      dw2_asm_output_data (4, dtd->dtd_data.ctti_size, "btt_size: %uB",
			   dtd->dtd_data.ctti_size);
      return;
    default:
      break;
    }

  dw2_asm_output_data (4, get_btf_id (dtd->dtd_data.ctti_type), "btt_type");
}

/* Asm'out the variable information following a BTF_KIND_ARRAY.  */

static void
btf_asm_array (ctf_dtdef_ref dtd)
{
  dw2_asm_output_data (4, get_btf_id (dtd->dtd_u.dtu_arr.ctr_contents),
		       "bta_contents");
  dw2_asm_output_data (4, get_btf_id (dtd->dtd_u.dtu_arr.ctr_index),
		       "bta_index");
  dw2_asm_output_data (4, dtd->dtd_u.dtu_arr.ctr_nelems, "bta_nelems");
}

/* Asm'out a BTF_KIND_VAR.  */

static void
btf_asm_varent (ctf_dvdef_ref var)
{
  dw2_asm_output_data (4, var->dvd_name_offset, "btv_name");
  dw2_asm_output_data (4, BTF_TYPE_INFO (BTF_KIND_VAR, 0, 0), "btv_info");
  dw2_asm_output_data (4, get_btf_id (var->dvd_type), "btv_type");
  dw2_asm_output_data (4, (var->dvd_visibility ? 1 : 0), "btv_linkage");
}

/* Asm'out a member description following a BTF_KIND_STRUCT or
   BTF_KIND_UNION.  */

static void
btf_asm_sou_member (ctf_container_ref ctfc, ctf_dmdef_t * dmd)
{
  ctf_dtdef_ref ref_type = ctfc->ctfc_types_list[dmd->dmd_type];

  /* Re-encode bitfields to BTF representation.  */
  if (CTF_V2_INFO_KIND (ref_type->dtd_data.ctti_info) == CTF_K_SLICE)
    {
      ctf_id_t base_type = ref_type->dtd_u.dtu_slice.cts_type;
      unsigned short word_offset = ref_type->dtd_u.dtu_slice.cts_offset;
      unsigned short bits = ref_type->dtd_u.dtu_slice.cts_bits;
      uint64_t sou_offset = dmd->dmd_offset;

      /* Pack the bit offset and bitfield size together.  */
      sou_offset += word_offset;

      /* If this bitfield cannot be represented, do not output anything.
	 The parent struct/union 'vlen' field has already been updated.  */
      if ((bits > 0xff) || (sou_offset > 0xffffff))
	return;

      sou_offset &= 0x00ffffff;
      sou_offset |= ((bits & 0xff) << 24);

      /* Refer to the base type of the slice.  */
      dw2_asm_output_data (4, dmd->dmd_name_offset, "btm_name_off");
      dw2_asm_output_data (4, get_btf_id (base_type), "btm_type");
      dw2_asm_output_data (4, sou_offset, "btm_offset");
    }
  else
    {
      dw2_asm_output_data (4, dmd->dmd_name_offset, "btm_name_off");
      dw2_asm_output_data (4, get_btf_id (dmd->dmd_type), "btm_type");
      dw2_asm_output_data (4, dmd->dmd_offset, "btm_offset");
    }
}

/* Asm'out an enum constant following a BTF_KIND_ENUM.  */

static void
btf_asm_enum_const (ctf_dmdef_t * dmd)
{
  dw2_asm_output_data (4, dmd->dmd_name_offset, "bte_name");
  dw2_asm_output_data (4, dmd->dmd_value, "bte_value");
}

/* Asm'out a function parameter description following a BTF_KIND_FUNC_PROTO.  */

static void
btf_asm_func_arg (ctf_func_arg_t * farg, size_t stroffset)
{
  /* If the function arg does not have a name, refer to the null string at
     the start of the string table. This ensures correct encoding for varargs
     '...' arguments.  */
  if ((farg->farg_name != NULL) && strcmp (farg->farg_name, ""))
    dw2_asm_output_data (4, farg->farg_name_offset + stroffset, "farg_name");
  else
    dw2_asm_output_data (4, 0, "farg_name");

  dw2_asm_output_data (4, (btf_removed_type_p (farg->farg_type)
			   ? BTF_VOID_TYPEID
			   : get_btf_id (farg->farg_type)),
		       "farg_type");
}

/* Asm'out a BTF_KIND_FUNC type.  */

static void
btf_asm_func_type (ctf_dtdef_ref dtd)
{
  dw2_asm_output_data (4, dtd->dtd_data.ctti_name, "btt_name");
  dw2_asm_output_data (4, BTF_TYPE_INFO (BTF_KIND_FUNC, 0, 0), "btt_info");
  dw2_asm_output_data (4, get_btf_id (dtd->dtd_data.ctti_type), "btt_type");
}

/* Asm'out a variable entry following a BTF_KIND_DATASEC.  */

static void
btf_asm_datasec_entry (struct btf_var_secinfo info)
{
  dw2_asm_output_data (4, info.type, "bts_type");
  dw2_asm_output_data (4, info.offset, "bts_offset");
  dw2_asm_output_data (4, info.size, "bts_size");
}

/* Asm'out a whole BTF_KIND_DATASEC, including its variable entries.  */

static void
btf_asm_datasec_type (btf_datasec_t ds, size_t stroffset)
{
  dw2_asm_output_data (4, ds.name_offset + stroffset, "btt_name");
  dw2_asm_output_data (4, BTF_TYPE_INFO (BTF_KIND_DATASEC, 0,
					 ds.entries.length ()),
		       "btt_info");
  /* Note: the "total section size in bytes" is emitted as 0 and patched by
     loaders such as libbpf.  */
  dw2_asm_output_data (4, 0, "btt_size");
  for (size_t i = 0; i < ds.entries.length (); i++)
    btf_asm_datasec_entry (ds.entries[i]);
}

/* Compute and output the header information for a .BTF section.  */

static void
output_btf_header (ctf_container_ref ctfc)
{
   switch_to_section (btf_info_section);
   ASM_OUTPUT_LABEL (asm_out_file, btf_info_section_label);

   /* BTF magic number, version, flags, and header length.  */
   dw2_asm_output_data (2, BTF_MAGIC, "btf_magic");
   dw2_asm_output_data (1, BTF_VERSION, "btf_version");
   dw2_asm_output_data (1, 0, "btf_flags");
   dw2_asm_output_data (4, sizeof (struct btf_header), "btf_hdr_len");

   uint32_t type_off = 0, type_len = 0;
   uint32_t str_off = 0, str_len = 0;
   uint32_t datasec_vlen_bytes = 0;

   if (!ctfc_is_empty_container (ctfc))
     {
       for (size_t i = 0; i < datasecs.length (); i++)
	 {
	   datasec_vlen_bytes += ((datasecs[i].entries.length ())
				  * sizeof (struct btf_var_secinfo));
	 }

       /* Total length (bytes) of the types section.  */
       type_len = (num_types_added * sizeof (struct btf_type))
	 + (num_types_created * sizeof (struct btf_type))
	 + datasec_vlen_bytes
	 + ctfc->ctfc_num_vlen_bytes;

       str_off = type_off + type_len;

       str_len = ctfc->ctfc_strtable.ctstab_len
	 + ctfc->ctfc_aux_strtable.ctstab_len;
     }

   /* Offset of type section.  */
   dw2_asm_output_data (4, type_off, "type_off");
   /* Length of type section in bytes.  */
   dw2_asm_output_data (4, type_len, "type_len");
    /* Offset of string section.  */
   dw2_asm_output_data (4, str_off, "str_off");
    /* Length of string section in bytes.  */
   dw2_asm_output_data (4, str_len, "str_len");
}

/* Output all BTF_KIND_VARs in CTFC.  */

static void
output_btf_vars (ctf_container_ref ctfc)
{
  size_t i;
  size_t num_ctf_vars = num_vars_added;
  if (num_ctf_vars)
    {
      for (i = 0; i < num_ctf_vars; i++)
	btf_asm_varent (ctfc->ctfc_vars_list[i]);
    }
}

/* Output BTF string records. The BTF strings section is a concatenation
   of the standard and auxilliary string tables in the ctf container.  */

static void
output_btf_strs (ctf_container_ref ctfc)
{
  ctf_string_t * ctf_string = ctfc->ctfc_strtable.ctstab_head;

  while (ctf_string)
    {
      dw2_asm_output_nstring (ctf_string->cts_str, -1, "btf_string");
      ctf_string = ctf_string->cts_next;
    }

  ctf_string = ctfc->ctfc_aux_strtable.ctstab_head;
  while (ctf_string)
    {
      dw2_asm_output_nstring (ctf_string->cts_str, -1, "btf_aux_string");
      ctf_string = ctf_string->cts_next;
    }
}

/* Output all (representable) members of a BTF_KIND_STRUCT or
   BTF_KIND_UNION type.  */

static void
output_asm_btf_sou_fields (ctf_container_ref ctfc, ctf_dtdef_ref dtd)
{
  ctf_dmdef_t * dmd;

  for (dmd = dtd->dtd_u.dtu_members;
       dmd != NULL; dmd = (ctf_dmdef_t *) ctf_dmd_list_next (dmd))
      btf_asm_sou_member (ctfc, dmd);
}

/* Output all enumerator constants following a BTF_KIND_ENUM.  */

static void
output_asm_btf_enum_list (ctf_container_ref ARG_UNUSED (ctfc),
			  ctf_dtdef_ref dtd)
{
  ctf_dmdef_t * dmd;

  for (dmd = dtd->dtd_u.dtu_members;
       dmd != NULL; dmd = (ctf_dmdef_t *) ctf_dmd_list_next (dmd))
    btf_asm_enum_const (dmd);
}

/* Output all function arguments following a BTF_KIND_FUNC_PROTO.  */

static void
output_asm_btf_func_args_list (ctf_container_ref ctfc,
			       ctf_dtdef_ref dtd)
{
  size_t farg_name_offset = ctfc_get_strtab_len (ctfc, CTF_STRTAB);
  ctf_func_arg_t * farg;
  for (farg = dtd->dtd_u.dtu_argv;
       farg != NULL; farg = (ctf_func_arg_t *) ctf_farg_list_next (farg))
    btf_asm_func_arg (farg, farg_name_offset);
}

/* Output the variable portion of a BTF type record. The information depends
   on the kind of the type.  */

static void
output_asm_btf_vlen_bytes (ctf_container_ref ctfc, ctf_dtdef_ref dtd)
{
  uint32_t btf_kind, encoding;

  btf_kind = get_btf_kind (CTF_V2_INFO_KIND (dtd->dtd_data.ctti_info));

  if (btf_kind == BTF_KIND_UNKN)
    return;

  switch (btf_kind)
    {
    case BTF_KIND_INT:
      /* Redundant definitions of void may still be hanging around in the type
	 list as size 0 integers. Skip emitting them.  */
      if (dtd->dtd_data.ctti_size < 1)
	break;

      encoding = BTF_INT_DATA (dtd->dtd_u.dtu_enc.cte_format,
			       dtd->dtd_u.dtu_enc.cte_offset,
			       dtd->dtd_u.dtu_enc.cte_bits);

      dw2_asm_output_data (4, encoding, "bti_encoding");
      break;

    case BTF_KIND_ARRAY:
      btf_asm_array (dtd);
      break;

    case BTF_KIND_STRUCT:
    case BTF_KIND_UNION:
      output_asm_btf_sou_fields (ctfc, dtd);
      break;

    case BTF_KIND_ENUM:
      output_asm_btf_enum_list (ctfc, dtd);
      break;

    case BTF_KIND_FUNC_PROTO:
      output_asm_btf_func_args_list (ctfc, dtd);
      break;

    case BTF_KIND_VAR:
      /* BTF Variables are handled by output_btf_vars and btf_asm_varent.
	 There should be no BTF_KIND_VAR types at this point.  */
      gcc_unreachable ();

    case BTF_KIND_DATASEC:
      /* The BTF_KIND_DATASEC records are handled by output_btf_datasec_types
	 and btf_asm_datasec_type. There should be no BTF_KIND_DATASEC types
	 at this point.  */
      gcc_unreachable ();

    default:
      /* All other BTF type kinds have no variable length data.  */
      break;
    }
}

/* Output a whole BTF type record for TYPE, including the fixed and variable
   data portions.  */

static void
output_asm_btf_type (ctf_container_ref ctfc, ctf_dtdef_ref type)
{
  if (btf_emit_id_p (type->dtd_type))
    {
      btf_asm_type (ctfc, type);
      output_asm_btf_vlen_bytes (ctfc, type);
    }
}

/* Output all BTF types in the container. This does not include synthesized
   types: BTF_KIND_VAR, BTF_KIND_FUNC, nor BTF_KIND_DATASEC.  */

static void
output_btf_types (ctf_container_ref ctfc)
{
  size_t i;
  size_t num_types = ctfc->ctfc_types->elements ();
  if (num_types)
    {
      for (i = 1; i <= num_types; i++)
	output_asm_btf_type (ctfc, ctfc->ctfc_types_list[i]);
    }
}

/* Output all BTF_KIND_FUNC type records.  */

static void
output_btf_func_types (void)
{
  for (size_t i = 0; i < vec_safe_length (funcs); i++)
    btf_asm_func_type ((*funcs)[i]);
}

/* Output all BTF_KIND_DATASEC records.  */

static void
output_btf_datasec_types (ctf_container_ref ctfc)
{
  size_t name_offset = ctfc_get_strtab_len (ctfc, CTF_STRTAB);

  for (size_t i = 0; i < datasecs.length(); i++)
    btf_asm_datasec_type (datasecs[i], name_offset);
}

/* Postprocess the CTF debug data post initialization.

   During the postprocess pass:

   - Prepare the sorted list of BTF types.

     The sorted list of BTF types is, firstly, used for lookup (during the BTF
     generation process) of CTF/BTF types given a typeID.

     Secondly, in the emitted BTF section, BTF Types need to be in the sorted
     order of their type IDs.  The BTF types section is viewed as an array,
     with type IDs used to index into that array.  It is essential that every
     type be placed at the exact index corresponding to its ID, or else
     references to that type from other types will no longer be correct.

   - References to void types are converted to reference BTF_VOID_TYPEID. In
     CTF, a distinct type is used to encode void.

   - Bitfield struct/union members are converted to BTF encoding. CTF uses
     slices to encode bitfields, but BTF does not have slices and encodes
     bitfield information directly in the variable-length btf_member
     descriptions following the struct or union type.

   - Unrepresentable types are removed. We cannot have any invalid BTF types
     appearing in the output so they must be removed, and type ids of other
     types and references adjust accordingly. This also involves ensuring that
     BTF descriptions of struct members referring to unrepresentable types are
     not emitted, as they would be nonsensical.

   - Adjust inner- and inter-type references-by-ID to account for removed
     types, and construct the types list.  */

void
btf_init_postprocess (void)
{
  ctf_container_ref tu_ctfc = ctf_get_tu_ctfc ();

  size_t i;
  size_t num_ctf_types = tu_ctfc->ctfc_types->elements ();

  holes.create (0);
  voids.create (0);

  num_types_added = 0;
  num_types_created = 0;

  if (num_ctf_types)
    {
      init_btf_id_map (num_ctf_types + 1);

      /* Allocate the types list and traverse all types, placing each type
	 at the index according to its ID.  Add 1 because type ID 0 always
	 represents VOID.  */
      tu_ctfc->ctfc_types_list
	= ggc_vec_alloc<ctf_dtdef_ref>(num_ctf_types + 1);
      tu_ctfc->ctfc_types->traverse<ctf_container_ref, btf_dtd_postprocess_cb>
	(tu_ctfc);

      /* Build mapping of CTF type ID -> BTF type ID, and count total number
	 of valid BTF types added.  */
      for (i = 1; i <= num_ctf_types; i++)
	{
	  ctf_dtdef_ref dtd = tu_ctfc->ctfc_types_list[i];
	  ctf_id_t btfid = btf_adjust_type_id (dtd->dtd_type);
	  set_btf_id (dtd->dtd_type, btfid);
	  if (btfid < BTF_MAX_TYPE && (btfid != BTF_VOID_TYPEID))
	    num_types_added ++;
	}
    }
}

/* Process and output all BTF data. Entry point of btfout.  */

void
btf_output (const char * filename)
{
  ctf_container_ref tu_ctfc = ctf_get_tu_ctfc ();

  init_btf_sections ();

  datasecs.create (0);
  vec_alloc (funcs, 16);

  ctf_add_cuname (tu_ctfc, filename);

  btf_emit_preprocess (tu_ctfc);

  output_btf_header (tu_ctfc);
  output_btf_types (tu_ctfc);
  output_btf_vars (tu_ctfc);
  output_btf_func_types ();
  output_btf_datasec_types (tu_ctfc);
  output_btf_strs (tu_ctfc);
}

/* Reset all state for BTF generation so that we can rerun the compiler within
   the same process.  */

void
btf_finalize (void)
{
  btf_info_section = NULL;

  /* Clear preprocessing state.  */
  num_vars_added = 0;
  num_types_added = 0;
  num_types_created = 0;

  holes.release ();
  voids.release ();
  for (size_t i = 0; i < datasecs.length (); i++)
    datasecs[i].entries.release ();
  datasecs.release ();

  funcs = NULL;

  btf_var_ids->empty ();
  btf_var_ids = NULL;

  free (btf_id_map);
  btf_id_map = NULL;

  ctf_container_ref tu_ctfc = ctf_get_tu_ctfc ();
  ctfc_delete_container (tu_ctfc);
  tu_ctfc = NULL;
}

#include "gt-btfout.h"
