btf: Add support to BTF_KIND_ENUM64 type
Commit Message
Hello GCC team,
The following patch update BTF/CTF backend to support
BTF_KIND_ENUM64 type.
Comments will be welcomed and appreciated!,
Kind regards,
guillermo
--
BTF supports 64-bits enumerators with following encoding:
struct btf_type:
name_off: 0 or offset to a valid C identifier
info.kind_flag: 0 for unsigned, 1 for signed
info.kind: BTF_KIND_ENUM64
info.vlen: number of enum values
size: 1/2/4/8
The btf_type is followed by info.vlen number of:
struct btf_enum64
{
uint32_t name_off; /* Offset in string section of enumerator name. */
uint32_t val_lo32; /* lower 32-bit value for a 64-bit value Enumerator */
uint32_t val_hi32; /* high 32-bit value for a 64-bit value Enumerator */
};
So, a new btf_enum64 structure was added to represent BTF_KIND_ENUM64
and a new field in ctf_dtdef to represent specific type's properties, in
the particular case for CTF enums it helps to distinguish when its
enumerators values are signed or unsigned, later that information is
used to encode the BTF enum type.
gcc/ChangeLog:
* btfout.cc (btf_calc_num_vbytes): Compute enumeration size depending of
enumerator type btf_enum{,64}.
(btf_asm_type): Update btf_kflag according to enumerators sign,
using correct BPF type in BTF_KIND_ENUMi{,64}.
(btf_asm_enum_const): New argument to represent the size of
the BTF enum type.
* ctfc.cc (ctf_add_enum): Use and initialization of flag field to
CTF_ENUM_F_NONE.
(ctf_add_enumerator): New argument to represent CTF flags,
updating the comment and flag vaue according to enumerators
sing.
* ctfc.h (ctf_dmdef): Update dmd_value to HOST_WIDE_INT to allow
use 32/64 bits enumerators.
(ctf_dtdef): Add flags to to describe specifyc type's properties.
* dwarf2ctf.cc (gen_ctf_enumeration_type): Update flags field
depending when a signed enumerator value is found.
include/btf.h (btf_enum64): Add new definition and new symbolic
constant to BTF_KIND_ENUM64 and BTF_KF_ENUM_{UN,}SIGNED.
gcc/testsuite/ChangeLog:
gcc.dg/debug/btf/btf-enum-1.c: Update testcase, with correct
info.kflags encoding.
gcc.dg/debug/btf/btf-enum64-1.c: New testcase.
---
gcc/btfout.cc | 24 ++++++++---
gcc/ctfc.cc | 14 ++++---
gcc/ctfc.h | 9 +++-
gcc/dwarf2ctf.cc | 9 +++-
gcc/testsuite/gcc.dg/debug/btf/btf-enum-1.c | 2 +-
gcc/testsuite/gcc.dg/debug/btf/btf-enum64-1.c | 41 +++++++++++++++++++
include/btf.h | 19 +++++++--
7 files changed, 99 insertions(+), 19 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-enum64-1.c
Comments
ping
On 8/29/22 16:11, Guillermo E. Martinez wrote:
> Hello GCC team,
>
> The following patch update BTF/CTF backend to support
> BTF_KIND_ENUM64 type.
>
> Comments will be welcomed and appreciated!,
>
> Kind regards,
> guillermo
> --
>
> BTF supports 64-bits enumerators with following encoding:
>
> struct btf_type:
> name_off: 0 or offset to a valid C identifier
> info.kind_flag: 0 for unsigned, 1 for signed
> info.kind: BTF_KIND_ENUM64
> info.vlen: number of enum values
> size: 1/2/4/8
>
> The btf_type is followed by info.vlen number of:
>
> struct btf_enum64
> {
> uint32_t name_off; /* Offset in string section of enumerator name. */
> uint32_t val_lo32; /* lower 32-bit value for a 64-bit value Enumerator */
> uint32_t val_hi32; /* high 32-bit value for a 64-bit value Enumerator */
> };
>
> So, a new btf_enum64 structure was added to represent BTF_KIND_ENUM64
> and a new field in ctf_dtdef to represent specific type's properties, in
> the particular case for CTF enums it helps to distinguish when its
> enumerators values are signed or unsigned, later that information is
> used to encode the BTF enum type.
>
> gcc/ChangeLog:
>
> * btfout.cc (btf_calc_num_vbytes): Compute enumeration size depending of
> enumerator type btf_enum{,64}.
> (btf_asm_type): Update btf_kflag according to enumerators sign,
> using correct BPF type in BTF_KIND_ENUMi{,64}.
> (btf_asm_enum_const): New argument to represent the size of
> the BTF enum type.
> * ctfc.cc (ctf_add_enum): Use and initialization of flag field to
> CTF_ENUM_F_NONE.
> (ctf_add_enumerator): New argument to represent CTF flags,
> updating the comment and flag vaue according to enumerators
> sing.
> * ctfc.h (ctf_dmdef): Update dmd_value to HOST_WIDE_INT to allow
> use 32/64 bits enumerators.
> (ctf_dtdef): Add flags to to describe specifyc type's properties.
> * dwarf2ctf.cc (gen_ctf_enumeration_type): Update flags field
> depending when a signed enumerator value is found.
> include/btf.h (btf_enum64): Add new definition and new symbolic
> constant to BTF_KIND_ENUM64 and BTF_KF_ENUM_{UN,}SIGNED.
>
> gcc/testsuite/ChangeLog:
>
> gcc.dg/debug/btf/btf-enum-1.c: Update testcase, with correct
> info.kflags encoding.
> gcc.dg/debug/btf/btf-enum64-1.c: New testcase.
> ---
> gcc/btfout.cc | 24 ++++++++---
> gcc/ctfc.cc | 14 ++++---
> gcc/ctfc.h | 9 +++-
> gcc/dwarf2ctf.cc | 9 +++-
> gcc/testsuite/gcc.dg/debug/btf/btf-enum-1.c | 2 +-
> gcc/testsuite/gcc.dg/debug/btf/btf-enum64-1.c | 41 +++++++++++++++++++
> include/btf.h | 19 +++++++--
> 7 files changed, 99 insertions(+), 19 deletions(-)
> create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-enum64-1.c
>
> diff --git a/gcc/btfout.cc b/gcc/btfout.cc
> index 997a33fa089..4b11c867c23 100644
> --- a/gcc/btfout.cc
> +++ b/gcc/btfout.cc
> @@ -223,7 +223,9 @@ btf_calc_num_vbytes (ctf_dtdef_ref dtd)
> break;
>
> case BTF_KIND_ENUM:
> - vlen_bytes += vlen * sizeof (struct btf_enum);
> + vlen_bytes += (dtd->dtd_data.ctti_size == 0x8)
> + ? vlen * sizeof (struct btf_enum64)
> + : vlen * sizeof (struct btf_enum);
> break;
>
> case BTF_KIND_FUNC_PROTO:
> @@ -622,6 +624,15 @@ btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd)
> btf_size_type = 0;
> }
>
> + if (btf_kind == BTF_KIND_ENUM)
> + {
> + btf_kflag = (dtd->flags & CTF_ENUM_F_ENUMERATORS_SIGNED)
> + ? BTF_KF_ENUM_SIGNED
> + : BTF_KF_ENUM_UNSIGNED;
> + if (dtd->dtd_data.ctti_size == 0x8)
> + btf_kind = BTF_KIND_ENUM64;
> + }
> +
> 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",
> @@ -634,6 +645,7 @@ btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd)
> case BTF_KIND_UNION:
> case BTF_KIND_ENUM:
> case BTF_KIND_DATASEC:
> + case BTF_KIND_ENUM64:
> dw2_asm_output_data (4, dtd->dtd_data.ctti_size, "btt_size: %uB",
> dtd->dtd_data.ctti_size);
> return;
> @@ -707,13 +719,13 @@ btf_asm_sou_member (ctf_container_ref ctfc, ctf_dmdef_t * dmd)
> }
> }
>
> -/* Asm'out an enum constant following a BTF_KIND_ENUM. */
> +/* Asm'out an enum constant following a BTF_KIND_ENUM{,64}. */
>
> static void
> -btf_asm_enum_const (ctf_dmdef_t * dmd)
> +btf_asm_enum_const (unsigned int size, 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");
> + dw2_asm_output_data (size, dmd->dmd_value, "bte_value");
> }
>
> /* Asm'out a function parameter description following a BTF_KIND_FUNC_PROTO. */
> @@ -871,7 +883,7 @@ output_asm_btf_sou_fields (ctf_container_ref ctfc, ctf_dtdef_ref dtd)
> btf_asm_sou_member (ctfc, dmd);
> }
>
> -/* Output all enumerator constants following a BTF_KIND_ENUM. */
> +/* Output all enumerator constants following a BTF_KIND_ENUM{,64}. */
>
> static void
> output_asm_btf_enum_list (ctf_container_ref ARG_UNUSED (ctfc),
> @@ -881,7 +893,7 @@ output_asm_btf_enum_list (ctf_container_ref ARG_UNUSED (ctfc),
>
> for (dmd = dtd->dtd_u.dtu_members;
> dmd != NULL; dmd = (ctf_dmdef_t *) ctf_dmd_list_next (dmd))
> - btf_asm_enum_const (dmd);
> + btf_asm_enum_const (dtd->dtd_data.ctti_size, dmd);
> }
>
> /* Output all function arguments following a BTF_KIND_FUNC_PROTO. */
> diff --git a/gcc/ctfc.cc b/gcc/ctfc.cc
> index 9773358a475..253c36b6a0a 100644
> --- a/gcc/ctfc.cc
> +++ b/gcc/ctfc.cc
> @@ -604,6 +604,7 @@ ctf_add_enum (ctf_container_ref ctfc, uint32_t flag, const char * name,
> gcc_assert (size <= CTF_MAX_SIZE);
>
> dtd->dtd_data.ctti_size = size;
> + dtd->flags = CTF_ENUM_F_NONE;
>
> ctfc->ctfc_num_stypes++;
>
> @@ -612,7 +613,7 @@ ctf_add_enum (ctf_container_ref ctfc, uint32_t flag, const char * name,
>
> int
> ctf_add_enumerator (ctf_container_ref ctfc, ctf_id_t enid, const char * name,
> - HOST_WIDE_INT value, dw_die_ref die)
> + HOST_WIDE_INT value, uint32_t flags, dw_die_ref die)
> {
> ctf_dmdef_t * dmd;
> uint32_t kind, vlen, root;
> @@ -630,10 +631,12 @@ ctf_add_enumerator (ctf_container_ref ctfc, ctf_id_t enid, const char * name,
>
> gcc_assert (kind == CTF_K_ENUM && vlen < CTF_MAX_VLEN);
>
> - /* Enum value is of type HOST_WIDE_INT in the compiler, dmd_value is int32_t
> - on the other hand. Check bounds and skip adding this enum value if out of
> - bounds. */
> - if ((value > INT_MAX) || (value < INT_MIN))
> + /* Enum value is of type HOST_WIDE_INT in the compiler, CTF enumerators
> + values in ctf_enum_t is limited to int32_t, BTF supports signed and
> + unsigned enumerators values of 32 and 64 bits, for both debug formats
> + we use ctf_dmdef_t.dmd_value entry of HOST_WIDE_INT type. So check
> + CTF bounds and skip adding this enum value if out of bounds. */
> + if (!btf_debuginfo_p() && ((value > INT_MAX) || (value < INT_MIN)))
> {
> /* FIXME - Note this TBD_CTF_REPRESENTATION_LIMIT. */
> return (1);
> @@ -649,6 +652,7 @@ ctf_add_enumerator (ctf_container_ref ctfc, ctf_id_t enid, const char * name,
> dmd->dmd_value = value;
>
> dtd->dtd_data.ctti_info = CTF_TYPE_INFO (kind, root, vlen + 1);
> + dtd->flags |= flags;
> ctf_dmd_list_append (&dtd->dtd_u.dtu_members, dmd);
>
> if ((name != NULL) && strcmp (name, ""))
> diff --git a/gcc/ctfc.h b/gcc/ctfc.h
> index bcf3a43ae1b..a22342b2610 100644
> --- a/gcc/ctfc.h
> +++ b/gcc/ctfc.h
> @@ -125,6 +125,10 @@ typedef struct GTY (()) ctf_itype
>
> #define CTF_FUNC_VARARG 0x1
>
> +/* Enum specific flags. */
> +#define CTF_ENUM_F_NONE (0)
> +#define CTF_ENUM_F_ENUMERATORS_SIGNED (1 << 0)
> +
> /* Struct/union/enum member definition for CTF generation. */
>
> typedef struct GTY ((chain_next ("%h.dmd_next"))) ctf_dmdef
> @@ -133,7 +137,7 @@ typedef struct GTY ((chain_next ("%h.dmd_next"))) ctf_dmdef
> ctf_id_t dmd_type; /* Type of this member (for sou). */
> uint32_t dmd_name_offset; /* Offset of the name in str table. */
> uint64_t dmd_offset; /* Offset of this member in bits (for sou). */
> - int dmd_value; /* Value of this member (for enum). */
> + HOST_WIDE_INT dmd_value; /* Value of this member (for enum). */
> struct ctf_dmdef * dmd_next; /* A list node. */
> } ctf_dmdef_t;
>
> @@ -162,6 +166,7 @@ struct GTY ((for_user)) ctf_dtdef
> bool from_global_func; /* Whether this type was added from a global
> function. */
> uint32_t linkage; /* Used in function types. 0=local, 1=global. */
> + uint32_t flags; /* Flags to describe specific type's properties. */
> union GTY ((desc ("ctf_dtu_d_union_selector (&%1)")))
> {
> /* struct, union, or enum. */
> @@ -429,7 +434,7 @@ extern ctf_id_t ctf_add_sou (ctf_container_ref, uint32_t, const char *,
> uint32_t, size_t, dw_die_ref);
>
> extern int ctf_add_enumerator (ctf_container_ref, ctf_id_t, const char *,
> - HOST_WIDE_INT, dw_die_ref);
> + HOST_WIDE_INT, uint32_t, dw_die_ref);
> extern int ctf_add_member_offset (ctf_container_ref, dw_die_ref, const char *,
> ctf_id_t, uint64_t);
> extern int ctf_add_function_arg (ctf_container_ref, dw_die_ref,
> diff --git a/gcc/dwarf2ctf.cc b/gcc/dwarf2ctf.cc
> index 397100004c2..0ef96dd48fd 100644
> --- a/gcc/dwarf2ctf.cc
> +++ b/gcc/dwarf2ctf.cc
> @@ -772,6 +772,7 @@ gen_ctf_enumeration_type (ctf_container_ref ctfc, dw_die_ref enumeration)
> const char *enumerator_name;
> dw_attr_node *enumerator_value;
> HOST_WIDE_INT value_wide_int;
> + uint32_t flags = 0;
>
> c = dw_get_die_sib (c);
>
> @@ -785,10 +786,14 @@ gen_ctf_enumeration_type (ctf_container_ref ctfc, dw_die_ref enumeration)
> == dw_val_class_unsigned_const_implicit))
> value_wide_int = AT_unsigned (enumerator_value);
> else
> - value_wide_int = AT_int (enumerator_value);
> + {
> + value_wide_int = AT_int (enumerator_value);
> + flags |= CTF_ENUM_F_ENUMERATORS_SIGNED;
> + }
>
> ctf_add_enumerator (ctfc, enumeration_type_id,
> - enumerator_name, value_wide_int, enumeration);
> + enumerator_name, value_wide_int,
> + flags, enumeration);
> }
> while (c != dw_get_die_child (enumeration));
> }
> diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-enum-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-enum-1.c
> index 728493b0804..7e940529f1b 100644
> --- a/gcc/testsuite/gcc.dg/debug/btf/btf-enum-1.c
> +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-enum-1.c
> @@ -4,7 +4,7 @@
> /* { dg-options "-O0 -gbtf -dA" } */
>
> /* { dg-final { scan-assembler-times "\[\t \]0x6000004\[\t \]+\[^\n\]*btt_info" 1 } } */
> -/* { dg-final { scan-assembler-times "\[\t \]0x6000003\[\t \]+\[^\n\]*btt_info" 1 } } */
> +/* { dg-final { scan-assembler-times "\[\t \]0x86000003\[\t \]+\[^\n\]*btt_info" 1 } } */
> /* { dg-final { scan-assembler-times "ascii \"QAD.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
> /* { dg-final { scan-assembler-times "ascii \"QED.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
> /* { dg-final { scan-assembler-times "ascii \"QOD.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
> diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-enum64-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-enum64-1.c
> new file mode 100644
> index 00000000000..da103842807
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-enum64-1.c
> @@ -0,0 +1,41 @@
> +/* Test BTF generation for 64 bits enums. */
> +
> +/* { dg-do compile } */
> +/* { dg-options "-O0 -gbtf -dA" } */
> +
> +/* { dg-final { scan-assembler-times "\[\t \].size\[\t \]myenum1,\[\t \]8" 1 } } */
> +/* { dg-final { scan-assembler-times "\[\t \].size\[\t \]myenum2,\[\t \]8" 1 } } */
> +/* { dg-final { scan-assembler-times "\[\t \].size\[\t \]myenum3,\[\t \]8" 1 } } */
> +/* { dg-final { scan-assembler-times "\[\t \]0x13000003\[\t \]+\[^\n\]*btt_info" 2 } } */
> +/* { dg-final { scan-assembler-times "\[\t \]0x93000003\[\t \]+\[^\n\]*btt_info" 1 } } */
> +/* { dg-final { scan-assembler-times "ascii \"B1.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
> +/* { dg-final { scan-assembler-times "ascii \"B2.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
> +/* { dg-final { scan-assembler-times "ascii \"B3.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
> +/* { dg-final { scan-assembler-times "ascii \"C1.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
> +/* { dg-final { scan-assembler-times "ascii \"C2.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
> +/* { dg-final { scan-assembler-times "ascii \"C3.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
> +/* { dg-final { scan-assembler-times "ascii \"D1.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
> +/* { dg-final { scan-assembler-times "ascii \"D2.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
> +/* { dg-final { scan-assembler-times "ascii \"D3.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
> +/* { dg-final { scan-assembler-times "bte_value" 9 } } */
> +
> +enum default_enum
> +{
> + B1 = 0xffffffffaa,
> + B2 = 0xbbbbbbbb,
> + B3 = 0xaabbccdd,
> +} myenum1 = B1;
> +
> +enum explicit_unsigned
> +{
> + C1 = 0xffffffffbbUL,
> + C2 = 0xbbbbbbbb,
> + C3 = 0xaabbccdd,
> +} myenum2 = C1;
> +
> +enum signed64
> +{
> + D1 = 0xffffffffaa,
> + D2 = 0xbbbbbbbb,
> + D3 = -0x1,
> +} myenum3 = D1;
> diff --git a/include/btf.h b/include/btf.h
> index 78b551ced23..eba67f9d599 100644
> --- a/include/btf.h
> +++ b/include/btf.h
> @@ -109,7 +109,8 @@ struct btf_type
> #define BTF_KIND_VAR 14 /* Variable. */
> #define BTF_KIND_DATASEC 15 /* Section such as .bss or .data. */
> #define BTF_KIND_FLOAT 16 /* Floating point. */
> -#define BTF_KIND_MAX BTF_KIND_FLOAT
> +#define BTF_KIND_ENUM64 19 /* Enumeration up to 64 bits. */
> +#define BTF_KIND_MAX BTF_KIND_ENUM64
> #define NR_BTF_KINDS (BTF_KIND_MAX + 1)
>
> /* For some BTF_KINDs, struct btf_type is immediately followed by
> @@ -130,14 +131,17 @@ struct btf_type
> #define BTF_INT_BOOL (1 << 2)
>
> /* BTF_KIND_ENUM is followed by VLEN struct btf_enum entries,
> - which describe the enumerators. Note that BTF currently only
> - supports signed 32-bit enumerator values. */
> + which describe the enumerators. */
> struct btf_enum
> {
> uint32_t name_off; /* Offset in string section of enumerator name. */
> int32_t val; /* Enumerator value. */
> };
>
> +/* BTF_KF_ENUM_ holds the flags for kflags in BTF_KIND_ENUM{,64}. */
> +#define BTF_KF_ENUM_UNSIGNED (0)
> +#define BTF_KF_ENUM_SIGNED (1 << 0)
> +
> /* BTF_KIND_ARRAY is followed by a single struct btf_array. */
> struct btf_array
> {
> @@ -190,6 +194,15 @@ struct btf_var_secinfo
> uint32_t size; /* Size (in bytes) of variable. */
> };
>
> +/* BTF_KIND_ENUM64 is followed by VLEN struct btf_enum64 entries,
> + which describe the 64 bits enumerators. */
> +struct btf_enum64
> +{
> + uint32_t name_off; /* Offset in string section of enumerator name. */
> + uint32_t val_lo32; /* lower 32-bit value for a 64-bit value Enumerator */
> + uint32_t val_hi32; /* high 32-bit value for a 64-bit value Enumerator */
> +};
> +
> #ifdef __cplusplus
> }
> #endif
Hi Guillermo,
Thanks for the patch. Just a couple of small nits on the changelog
entries below but otherwise very nice, LGTM.
But, please wait a couple of days before pushing to give Indu time
to raise any objections about the changes in ctfc/dwarf2ctf.
Thanks!
David
On 8/29/22 14:11, Guillermo E. Martinez via Gcc-patches wrote:
> Hello GCC team,
>
> The following patch update BTF/CTF backend to support
> BTF_KIND_ENUM64 type.
>
> Comments will be welcomed and appreciated!,
>
> Kind regards,
> guillermo
> --
>
> BTF supports 64-bits enumerators with following encoding:
>
> struct btf_type:
> name_off: 0 or offset to a valid C identifier
> info.kind_flag: 0 for unsigned, 1 for signed
> info.kind: BTF_KIND_ENUM64
> info.vlen: number of enum values
> size: 1/2/4/8
>
> The btf_type is followed by info.vlen number of:
>
> struct btf_enum64
> {
> uint32_t name_off; /* Offset in string section of enumerator name. */
> uint32_t val_lo32; /* lower 32-bit value for a 64-bit value Enumerator */
> uint32_t val_hi32; /* high 32-bit value for a 64-bit value Enumerator */
> };
>
> So, a new btf_enum64 structure was added to represent BTF_KIND_ENUM64
> and a new field in ctf_dtdef to represent specific type's properties, in
> the particular case for CTF enums it helps to distinguish when its
> enumerators values are signed or unsigned, later that information is
> used to encode the BTF enum type.
>
> gcc/ChangeLog:
>
> * btfout.cc (btf_calc_num_vbytes): Compute enumeration size depending of
> enumerator type btf_enum{,64}.
> (btf_asm_type): Update btf_kflag according to enumerators sign,
> using correct BPF type in BTF_KIND_ENUMi{,64}.
> (btf_asm_enum_const): New argument to represent the size of
> the BTF enum type.
> * ctfc.cc (ctf_add_enum): Use and initialization of flag field to
> CTF_ENUM_F_NONE.
> (ctf_add_enumerator): New argument to represent CTF flags,
> updating the comment and flag vaue according to enumerators
> sing.
> * ctfc.h (ctf_dmdef): Update dmd_value to HOST_WIDE_INT to allow
> use 32/64 bits enumerators.
> (ctf_dtdef): Add flags to to describe specifyc type's properties.
typo: specific
> * dwarf2ctf.cc (gen_ctf_enumeration_type): Update flags field
> depending when a signed enumerator value is found.
> include/btf.h (btf_enum64): Add new definition and new symbolic
> constant to BTF_KIND_ENUM64 and BTF_KF_ENUM_{UN,}SIGNED.
Missing an * here for include/btf.h
>
> gcc/testsuite/ChangeLog:
>
> gcc.dg/debug/btf/btf-enum-1.c: Update testcase, with correct
> info.kflags encoding.
> gcc.dg/debug/btf/btf-enum64-1.c: New testcase.
Likewise for these ChangeLog entries.
You can use contrib/gcc-changelog/git_check_commit.py to check the
formatting of the entries.
> ---
> gcc/btfout.cc | 24 ++++++++---
> gcc/ctfc.cc | 14 ++++---
> gcc/ctfc.h | 9 +++-
> gcc/dwarf2ctf.cc | 9 +++-
> gcc/testsuite/gcc.dg/debug/btf/btf-enum-1.c | 2 +-
> gcc/testsuite/gcc.dg/debug/btf/btf-enum64-1.c | 41 +++++++++++++++++++
> include/btf.h | 19 +++++++--
> 7 files changed, 99 insertions(+), 19 deletions(-)
> create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-enum64-1.c
>
> diff --git a/gcc/btfout.cc b/gcc/btfout.cc
> index 997a33fa089..4b11c867c23 100644
> --- a/gcc/btfout.cc
> +++ b/gcc/btfout.cc
> @@ -223,7 +223,9 @@ btf_calc_num_vbytes (ctf_dtdef_ref dtd)
> break;
>
> case BTF_KIND_ENUM:
> - vlen_bytes += vlen * sizeof (struct btf_enum);
> + vlen_bytes += (dtd->dtd_data.ctti_size == 0x8)
> + ? vlen * sizeof (struct btf_enum64)
> + : vlen * sizeof (struct btf_enum);
> break;
>
> case BTF_KIND_FUNC_PROTO:
> @@ -622,6 +624,15 @@ btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd)
> btf_size_type = 0;
> }
>
> + if (btf_kind == BTF_KIND_ENUM)
> + {
> + btf_kflag = (dtd->flags & CTF_ENUM_F_ENUMERATORS_SIGNED)
> + ? BTF_KF_ENUM_SIGNED
> + : BTF_KF_ENUM_UNSIGNED;
> + if (dtd->dtd_data.ctti_size == 0x8)
> + btf_kind = BTF_KIND_ENUM64;
> + }
> +
> 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",
> @@ -634,6 +645,7 @@ btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd)
> case BTF_KIND_UNION:
> case BTF_KIND_ENUM:
> case BTF_KIND_DATASEC:
> + case BTF_KIND_ENUM64:
> dw2_asm_output_data (4, dtd->dtd_data.ctti_size, "btt_size: %uB",
> dtd->dtd_data.ctti_size);
> return;
> @@ -707,13 +719,13 @@ btf_asm_sou_member (ctf_container_ref ctfc, ctf_dmdef_t * dmd)
> }
> }
>
> -/* Asm'out an enum constant following a BTF_KIND_ENUM. */
> +/* Asm'out an enum constant following a BTF_KIND_ENUM{,64}. */
>
> static void
> -btf_asm_enum_const (ctf_dmdef_t * dmd)
> +btf_asm_enum_const (unsigned int size, 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");
> + dw2_asm_output_data (size, dmd->dmd_value, "bte_value");
> }
>
> /* Asm'out a function parameter description following a BTF_KIND_FUNC_PROTO. */
> @@ -871,7 +883,7 @@ output_asm_btf_sou_fields (ctf_container_ref ctfc, ctf_dtdef_ref dtd)
> btf_asm_sou_member (ctfc, dmd);
> }
>
> -/* Output all enumerator constants following a BTF_KIND_ENUM. */
> +/* Output all enumerator constants following a BTF_KIND_ENUM{,64}. */
>
> static void
> output_asm_btf_enum_list (ctf_container_ref ARG_UNUSED (ctfc),
> @@ -881,7 +893,7 @@ output_asm_btf_enum_list (ctf_container_ref ARG_UNUSED (ctfc),
>
> for (dmd = dtd->dtd_u.dtu_members;
> dmd != NULL; dmd = (ctf_dmdef_t *) ctf_dmd_list_next (dmd))
> - btf_asm_enum_const (dmd);
> + btf_asm_enum_const (dtd->dtd_data.ctti_size, dmd);
> }
>
> /* Output all function arguments following a BTF_KIND_FUNC_PROTO. */
> diff --git a/gcc/ctfc.cc b/gcc/ctfc.cc
> index 9773358a475..253c36b6a0a 100644
> --- a/gcc/ctfc.cc
> +++ b/gcc/ctfc.cc
> @@ -604,6 +604,7 @@ ctf_add_enum (ctf_container_ref ctfc, uint32_t flag, const char * name,
> gcc_assert (size <= CTF_MAX_SIZE);
>
> dtd->dtd_data.ctti_size = size;
> + dtd->flags = CTF_ENUM_F_NONE;
>
> ctfc->ctfc_num_stypes++;
>
> @@ -612,7 +613,7 @@ ctf_add_enum (ctf_container_ref ctfc, uint32_t flag, const char * name,
>
> int
> ctf_add_enumerator (ctf_container_ref ctfc, ctf_id_t enid, const char * name,
> - HOST_WIDE_INT value, dw_die_ref die)
> + HOST_WIDE_INT value, uint32_t flags, dw_die_ref die)
> {
> ctf_dmdef_t * dmd;
> uint32_t kind, vlen, root;
> @@ -630,10 +631,12 @@ ctf_add_enumerator (ctf_container_ref ctfc, ctf_id_t enid, const char * name,
>
> gcc_assert (kind == CTF_K_ENUM && vlen < CTF_MAX_VLEN);
>
> - /* Enum value is of type HOST_WIDE_INT in the compiler, dmd_value is int32_t
> - on the other hand. Check bounds and skip adding this enum value if out of
> - bounds. */
> - if ((value > INT_MAX) || (value < INT_MIN))
> + /* Enum value is of type HOST_WIDE_INT in the compiler, CTF enumerators
> + values in ctf_enum_t is limited to int32_t, BTF supports signed and
> + unsigned enumerators values of 32 and 64 bits, for both debug formats
> + we use ctf_dmdef_t.dmd_value entry of HOST_WIDE_INT type. So check
> + CTF bounds and skip adding this enum value if out of bounds. */
> + if (!btf_debuginfo_p() && ((value > INT_MAX) || (value < INT_MIN)))
> {
> /* FIXME - Note this TBD_CTF_REPRESENTATION_LIMIT. */
> return (1);
> @@ -649,6 +652,7 @@ ctf_add_enumerator (ctf_container_ref ctfc, ctf_id_t enid, const char * name,
> dmd->dmd_value = value;
>
> dtd->dtd_data.ctti_info = CTF_TYPE_INFO (kind, root, vlen + 1);
> + dtd->flags |= flags;
> ctf_dmd_list_append (&dtd->dtd_u.dtu_members, dmd);
>
> if ((name != NULL) && strcmp (name, ""))
> diff --git a/gcc/ctfc.h b/gcc/ctfc.h
> index bcf3a43ae1b..a22342b2610 100644
> --- a/gcc/ctfc.h
> +++ b/gcc/ctfc.h
> @@ -125,6 +125,10 @@ typedef struct GTY (()) ctf_itype
>
> #define CTF_FUNC_VARARG 0x1
>
> +/* Enum specific flags. */
> +#define CTF_ENUM_F_NONE (0)
> +#define CTF_ENUM_F_ENUMERATORS_SIGNED (1 << 0)
> +
> /* Struct/union/enum member definition for CTF generation. */
>
> typedef struct GTY ((chain_next ("%h.dmd_next"))) ctf_dmdef
> @@ -133,7 +137,7 @@ typedef struct GTY ((chain_next ("%h.dmd_next"))) ctf_dmdef
> ctf_id_t dmd_type; /* Type of this member (for sou). */
> uint32_t dmd_name_offset; /* Offset of the name in str table. */
> uint64_t dmd_offset; /* Offset of this member in bits (for sou). */
> - int dmd_value; /* Value of this member (for enum). */
> + HOST_WIDE_INT dmd_value; /* Value of this member (for enum). */
> struct ctf_dmdef * dmd_next; /* A list node. */
> } ctf_dmdef_t;
>
> @@ -162,6 +166,7 @@ struct GTY ((for_user)) ctf_dtdef
> bool from_global_func; /* Whether this type was added from a global
> function. */
> uint32_t linkage; /* Used in function types. 0=local, 1=global. */
> + uint32_t flags; /* Flags to describe specific type's properties. */
> union GTY ((desc ("ctf_dtu_d_union_selector (&%1)")))
> {
> /* struct, union, or enum. */
> @@ -429,7 +434,7 @@ extern ctf_id_t ctf_add_sou (ctf_container_ref, uint32_t, const char *,
> uint32_t, size_t, dw_die_ref);
>
> extern int ctf_add_enumerator (ctf_container_ref, ctf_id_t, const char *,
> - HOST_WIDE_INT, dw_die_ref);
> + HOST_WIDE_INT, uint32_t, dw_die_ref);
> extern int ctf_add_member_offset (ctf_container_ref, dw_die_ref, const char *,
> ctf_id_t, uint64_t);
> extern int ctf_add_function_arg (ctf_container_ref, dw_die_ref,
> diff --git a/gcc/dwarf2ctf.cc b/gcc/dwarf2ctf.cc
> index 397100004c2..0ef96dd48fd 100644
> --- a/gcc/dwarf2ctf.cc
> +++ b/gcc/dwarf2ctf.cc
> @@ -772,6 +772,7 @@ gen_ctf_enumeration_type (ctf_container_ref ctfc, dw_die_ref enumeration)
> const char *enumerator_name;
> dw_attr_node *enumerator_value;
> HOST_WIDE_INT value_wide_int;
> + uint32_t flags = 0;
>
> c = dw_get_die_sib (c);
>
> @@ -785,10 +786,14 @@ gen_ctf_enumeration_type (ctf_container_ref ctfc, dw_die_ref enumeration)
> == dw_val_class_unsigned_const_implicit))
> value_wide_int = AT_unsigned (enumerator_value);
> else
> - value_wide_int = AT_int (enumerator_value);
> + {
> + value_wide_int = AT_int (enumerator_value);
> + flags |= CTF_ENUM_F_ENUMERATORS_SIGNED;
> + }
>
> ctf_add_enumerator (ctfc, enumeration_type_id,
> - enumerator_name, value_wide_int, enumeration);
> + enumerator_name, value_wide_int,
> + flags, enumeration);
> }
> while (c != dw_get_die_child (enumeration));
> }
> diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-enum-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-enum-1.c
> index 728493b0804..7e940529f1b 100644
> --- a/gcc/testsuite/gcc.dg/debug/btf/btf-enum-1.c
> +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-enum-1.c
> @@ -4,7 +4,7 @@
> /* { dg-options "-O0 -gbtf -dA" } */
>
> /* { dg-final { scan-assembler-times "\[\t \]0x6000004\[\t \]+\[^\n\]*btt_info" 1 } } */
> -/* { dg-final { scan-assembler-times "\[\t \]0x6000003\[\t \]+\[^\n\]*btt_info" 1 } } */
> +/* { dg-final { scan-assembler-times "\[\t \]0x86000003\[\t \]+\[^\n\]*btt_info" 1 } } */
> /* { dg-final { scan-assembler-times "ascii \"QAD.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
> /* { dg-final { scan-assembler-times "ascii \"QED.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
> /* { dg-final { scan-assembler-times "ascii \"QOD.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
> diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-enum64-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-enum64-1.c
> new file mode 100644
> index 00000000000..da103842807
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-enum64-1.c
> @@ -0,0 +1,41 @@
> +/* Test BTF generation for 64 bits enums. */
> +
> +/* { dg-do compile } */
> +/* { dg-options "-O0 -gbtf -dA" } */
> +
> +/* { dg-final { scan-assembler-times "\[\t \].size\[\t \]myenum1,\[\t \]8" 1 } } */
> +/* { dg-final { scan-assembler-times "\[\t \].size\[\t \]myenum2,\[\t \]8" 1 } } */
> +/* { dg-final { scan-assembler-times "\[\t \].size\[\t \]myenum3,\[\t \]8" 1 } } */
> +/* { dg-final { scan-assembler-times "\[\t \]0x13000003\[\t \]+\[^\n\]*btt_info" 2 } } */
> +/* { dg-final { scan-assembler-times "\[\t \]0x93000003\[\t \]+\[^\n\]*btt_info" 1 } } */
> +/* { dg-final { scan-assembler-times "ascii \"B1.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
> +/* { dg-final { scan-assembler-times "ascii \"B2.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
> +/* { dg-final { scan-assembler-times "ascii \"B3.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
> +/* { dg-final { scan-assembler-times "ascii \"C1.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
> +/* { dg-final { scan-assembler-times "ascii \"C2.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
> +/* { dg-final { scan-assembler-times "ascii \"C3.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
> +/* { dg-final { scan-assembler-times "ascii \"D1.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
> +/* { dg-final { scan-assembler-times "ascii \"D2.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
> +/* { dg-final { scan-assembler-times "ascii \"D3.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
> +/* { dg-final { scan-assembler-times "bte_value" 9 } } */
> +
> +enum default_enum
> +{
> + B1 = 0xffffffffaa,
> + B2 = 0xbbbbbbbb,
> + B3 = 0xaabbccdd,
> +} myenum1 = B1;
> +
> +enum explicit_unsigned
> +{
> + C1 = 0xffffffffbbUL,
> + C2 = 0xbbbbbbbb,
> + C3 = 0xaabbccdd,
> +} myenum2 = C1;
> +
> +enum signed64
> +{
> + D1 = 0xffffffffaa,
> + D2 = 0xbbbbbbbb,
> + D3 = -0x1,
> +} myenum3 = D1;
> diff --git a/include/btf.h b/include/btf.h
> index 78b551ced23..eba67f9d599 100644
> --- a/include/btf.h
> +++ b/include/btf.h
> @@ -109,7 +109,8 @@ struct btf_type
> #define BTF_KIND_VAR 14 /* Variable. */
> #define BTF_KIND_DATASEC 15 /* Section such as .bss or .data. */
> #define BTF_KIND_FLOAT 16 /* Floating point. */
> -#define BTF_KIND_MAX BTF_KIND_FLOAT
> +#define BTF_KIND_ENUM64 19 /* Enumeration up to 64 bits. */
> +#define BTF_KIND_MAX BTF_KIND_ENUM64
> #define NR_BTF_KINDS (BTF_KIND_MAX + 1)
>
> /* For some BTF_KINDs, struct btf_type is immediately followed by
> @@ -130,14 +131,17 @@ struct btf_type
> #define BTF_INT_BOOL (1 << 2)
>
> /* BTF_KIND_ENUM is followed by VLEN struct btf_enum entries,
> - which describe the enumerators. Note that BTF currently only
> - supports signed 32-bit enumerator values. */
> + which describe the enumerators. */
> struct btf_enum
> {
> uint32_t name_off; /* Offset in string section of enumerator name. */
> int32_t val; /* Enumerator value. */
> };
>
> +/* BTF_KF_ENUM_ holds the flags for kflags in BTF_KIND_ENUM{,64}. */
> +#define BTF_KF_ENUM_UNSIGNED (0)
> +#define BTF_KF_ENUM_SIGNED (1 << 0)
> +
> /* BTF_KIND_ARRAY is followed by a single struct btf_array. */
> struct btf_array
> {
> @@ -190,6 +194,15 @@ struct btf_var_secinfo
> uint32_t size; /* Size (in bytes) of variable. */
> };
>
> +/* BTF_KIND_ENUM64 is followed by VLEN struct btf_enum64 entries,
> + which describe the 64 bits enumerators. */
> +struct btf_enum64
> +{
> + uint32_t name_off; /* Offset in string section of enumerator name. */
> + uint32_t val_lo32; /* lower 32-bit value for a 64-bit value Enumerator */
> + uint32_t val_hi32; /* high 32-bit value for a 64-bit value Enumerator */
> +};
> +
> #ifdef __cplusplus
> }
> #endif
On 9/28/22 13:45, David Faust wrote:
> Hi Guillermo,
>
Hi David,
> Thanks for the patch. Just a couple of small nits on the changelog
> entries below but otherwise very nice, LGTM.
>
> But, please wait a couple of days before pushing to give Indu time
> to raise any objections about the changes in ctfc/dwarf2ctf.
>
OK. Thanks for your comments!.
> Thanks!
> David
>
> On 8/29/22 14:11, Guillermo E. Martinez via Gcc-patches wrote:
>> Hello GCC team,
>>
>> The following patch update BTF/CTF backend to support
>> BTF_KIND_ENUM64 type.
>>
>> Comments will be welcomed and appreciated!,
>>
>> Kind regards,
>> guillermo
>> --
>>
>> BTF supports 64-bits enumerators with following encoding:
>>
>> struct btf_type:
>> name_off: 0 or offset to a valid C identifier
>> info.kind_flag: 0 for unsigned, 1 for signed
>> info.kind: BTF_KIND_ENUM64
>> info.vlen: number of enum values
>> size: 1/2/4/8
>>
>> The btf_type is followed by info.vlen number of:
>>
>> struct btf_enum64
>> {
>> uint32_t name_off; /* Offset in string section of enumerator name. */
>> uint32_t val_lo32; /* lower 32-bit value for a 64-bit value Enumerator */
>> uint32_t val_hi32; /* high 32-bit value for a 64-bit value Enumerator */
>> };
>>
>> So, a new btf_enum64 structure was added to represent BTF_KIND_ENUM64
>> and a new field in ctf_dtdef to represent specific type's properties, in
>> the particular case for CTF enums it helps to distinguish when its
>> enumerators values are signed or unsigned, later that information is
>> used to encode the BTF enum type.
>>
>> gcc/ChangeLog:
>>
>> * btfout.cc (btf_calc_num_vbytes): Compute enumeration size depending of
>> enumerator type btf_enum{,64}.
>> (btf_asm_type): Update btf_kflag according to enumerators sign,
>> using correct BPF type in BTF_KIND_ENUMi{,64}.
>> (btf_asm_enum_const): New argument to represent the size of
>> the BTF enum type.
>> * ctfc.cc (ctf_add_enum): Use and initialization of flag field to
>> CTF_ENUM_F_NONE.
>> (ctf_add_enumerator): New argument to represent CTF flags,
>> updating the comment and flag vaue according to enumerators
>> sing.
>> * ctfc.h (ctf_dmdef): Update dmd_value to HOST_WIDE_INT to allow
>> use 32/64 bits enumerators.
>> (ctf_dtdef): Add flags to to describe specifyc type's properties.
>
> typo: specific
>
Fixed in v2.
>> * dwarf2ctf.cc (gen_ctf_enumeration_type): Update flags field
>> depending when a signed enumerator value is found.
>> include/btf.h (btf_enum64): Add new definition and new symbolic
>> constant to BTF_KIND_ENUM64 and BTF_KF_ENUM_{UN,}SIGNED.
>
> Missing an * here for include/btf.h
>
Fixed in v2.
>>
>> gcc/testsuite/ChangeLog:
>>
>> gcc.dg/debug/btf/btf-enum-1.c: Update testcase, with correct
>> info.kflags encoding.
>> gcc.dg/debug/btf/btf-enum64-1.c: New testcase.
>
> Likewise for these ChangeLog entries.
>
Fixed in v2.
> You can use contrib/gcc-changelog/git_check_commit.py to check the
> formatting of the entries.
>
Oh. thanks for mention it, really useful.
>> ---
>> gcc/btfout.cc | 24 ++++++++---
>> gcc/ctfc.cc | 14 ++++---
>> gcc/ctfc.h | 9 +++-
>> gcc/dwarf2ctf.cc | 9 +++-
>> gcc/testsuite/gcc.dg/debug/btf/btf-enum-1.c | 2 +-
>> gcc/testsuite/gcc.dg/debug/btf/btf-enum64-1.c | 41 +++++++++++++++++++
>> include/btf.h | 19 +++++++--
>> 7 files changed, 99 insertions(+), 19 deletions(-)
>> create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-enum64-1.c
>>
>> diff --git a/gcc/btfout.cc b/gcc/btfout.cc
>> index 997a33fa089..4b11c867c23 100644
>> --- a/gcc/btfout.cc
>>[...]
Regards,
guillermo
@@ -223,7 +223,9 @@ btf_calc_num_vbytes (ctf_dtdef_ref dtd)
break;
case BTF_KIND_ENUM:
- vlen_bytes += vlen * sizeof (struct btf_enum);
+ vlen_bytes += (dtd->dtd_data.ctti_size == 0x8)
+ ? vlen * sizeof (struct btf_enum64)
+ : vlen * sizeof (struct btf_enum);
break;
case BTF_KIND_FUNC_PROTO:
@@ -622,6 +624,15 @@ btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd)
btf_size_type = 0;
}
+ if (btf_kind == BTF_KIND_ENUM)
+ {
+ btf_kflag = (dtd->flags & CTF_ENUM_F_ENUMERATORS_SIGNED)
+ ? BTF_KF_ENUM_SIGNED
+ : BTF_KF_ENUM_UNSIGNED;
+ if (dtd->dtd_data.ctti_size == 0x8)
+ btf_kind = BTF_KIND_ENUM64;
+ }
+
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",
@@ -634,6 +645,7 @@ btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd)
case BTF_KIND_UNION:
case BTF_KIND_ENUM:
case BTF_KIND_DATASEC:
+ case BTF_KIND_ENUM64:
dw2_asm_output_data (4, dtd->dtd_data.ctti_size, "btt_size: %uB",
dtd->dtd_data.ctti_size);
return;
@@ -707,13 +719,13 @@ btf_asm_sou_member (ctf_container_ref ctfc, ctf_dmdef_t * dmd)
}
}
-/* Asm'out an enum constant following a BTF_KIND_ENUM. */
+/* Asm'out an enum constant following a BTF_KIND_ENUM{,64}. */
static void
-btf_asm_enum_const (ctf_dmdef_t * dmd)
+btf_asm_enum_const (unsigned int size, 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");
+ dw2_asm_output_data (size, dmd->dmd_value, "bte_value");
}
/* Asm'out a function parameter description following a BTF_KIND_FUNC_PROTO. */
@@ -871,7 +883,7 @@ output_asm_btf_sou_fields (ctf_container_ref ctfc, ctf_dtdef_ref dtd)
btf_asm_sou_member (ctfc, dmd);
}
-/* Output all enumerator constants following a BTF_KIND_ENUM. */
+/* Output all enumerator constants following a BTF_KIND_ENUM{,64}. */
static void
output_asm_btf_enum_list (ctf_container_ref ARG_UNUSED (ctfc),
@@ -881,7 +893,7 @@ output_asm_btf_enum_list (ctf_container_ref ARG_UNUSED (ctfc),
for (dmd = dtd->dtd_u.dtu_members;
dmd != NULL; dmd = (ctf_dmdef_t *) ctf_dmd_list_next (dmd))
- btf_asm_enum_const (dmd);
+ btf_asm_enum_const (dtd->dtd_data.ctti_size, dmd);
}
/* Output all function arguments following a BTF_KIND_FUNC_PROTO. */
@@ -604,6 +604,7 @@ ctf_add_enum (ctf_container_ref ctfc, uint32_t flag, const char * name,
gcc_assert (size <= CTF_MAX_SIZE);
dtd->dtd_data.ctti_size = size;
+ dtd->flags = CTF_ENUM_F_NONE;
ctfc->ctfc_num_stypes++;
@@ -612,7 +613,7 @@ ctf_add_enum (ctf_container_ref ctfc, uint32_t flag, const char * name,
int
ctf_add_enumerator (ctf_container_ref ctfc, ctf_id_t enid, const char * name,
- HOST_WIDE_INT value, dw_die_ref die)
+ HOST_WIDE_INT value, uint32_t flags, dw_die_ref die)
{
ctf_dmdef_t * dmd;
uint32_t kind, vlen, root;
@@ -630,10 +631,12 @@ ctf_add_enumerator (ctf_container_ref ctfc, ctf_id_t enid, const char * name,
gcc_assert (kind == CTF_K_ENUM && vlen < CTF_MAX_VLEN);
- /* Enum value is of type HOST_WIDE_INT in the compiler, dmd_value is int32_t
- on the other hand. Check bounds and skip adding this enum value if out of
- bounds. */
- if ((value > INT_MAX) || (value < INT_MIN))
+ /* Enum value is of type HOST_WIDE_INT in the compiler, CTF enumerators
+ values in ctf_enum_t is limited to int32_t, BTF supports signed and
+ unsigned enumerators values of 32 and 64 bits, for both debug formats
+ we use ctf_dmdef_t.dmd_value entry of HOST_WIDE_INT type. So check
+ CTF bounds and skip adding this enum value if out of bounds. */
+ if (!btf_debuginfo_p() && ((value > INT_MAX) || (value < INT_MIN)))
{
/* FIXME - Note this TBD_CTF_REPRESENTATION_LIMIT. */
return (1);
@@ -649,6 +652,7 @@ ctf_add_enumerator (ctf_container_ref ctfc, ctf_id_t enid, const char * name,
dmd->dmd_value = value;
dtd->dtd_data.ctti_info = CTF_TYPE_INFO (kind, root, vlen + 1);
+ dtd->flags |= flags;
ctf_dmd_list_append (&dtd->dtd_u.dtu_members, dmd);
if ((name != NULL) && strcmp (name, ""))
@@ -125,6 +125,10 @@ typedef struct GTY (()) ctf_itype
#define CTF_FUNC_VARARG 0x1
+/* Enum specific flags. */
+#define CTF_ENUM_F_NONE (0)
+#define CTF_ENUM_F_ENUMERATORS_SIGNED (1 << 0)
+
/* Struct/union/enum member definition for CTF generation. */
typedef struct GTY ((chain_next ("%h.dmd_next"))) ctf_dmdef
@@ -133,7 +137,7 @@ typedef struct GTY ((chain_next ("%h.dmd_next"))) ctf_dmdef
ctf_id_t dmd_type; /* Type of this member (for sou). */
uint32_t dmd_name_offset; /* Offset of the name in str table. */
uint64_t dmd_offset; /* Offset of this member in bits (for sou). */
- int dmd_value; /* Value of this member (for enum). */
+ HOST_WIDE_INT dmd_value; /* Value of this member (for enum). */
struct ctf_dmdef * dmd_next; /* A list node. */
} ctf_dmdef_t;
@@ -162,6 +166,7 @@ struct GTY ((for_user)) ctf_dtdef
bool from_global_func; /* Whether this type was added from a global
function. */
uint32_t linkage; /* Used in function types. 0=local, 1=global. */
+ uint32_t flags; /* Flags to describe specific type's properties. */
union GTY ((desc ("ctf_dtu_d_union_selector (&%1)")))
{
/* struct, union, or enum. */
@@ -429,7 +434,7 @@ extern ctf_id_t ctf_add_sou (ctf_container_ref, uint32_t, const char *,
uint32_t, size_t, dw_die_ref);
extern int ctf_add_enumerator (ctf_container_ref, ctf_id_t, const char *,
- HOST_WIDE_INT, dw_die_ref);
+ HOST_WIDE_INT, uint32_t, dw_die_ref);
extern int ctf_add_member_offset (ctf_container_ref, dw_die_ref, const char *,
ctf_id_t, uint64_t);
extern int ctf_add_function_arg (ctf_container_ref, dw_die_ref,
@@ -772,6 +772,7 @@ gen_ctf_enumeration_type (ctf_container_ref ctfc, dw_die_ref enumeration)
const char *enumerator_name;
dw_attr_node *enumerator_value;
HOST_WIDE_INT value_wide_int;
+ uint32_t flags = 0;
c = dw_get_die_sib (c);
@@ -785,10 +786,14 @@ gen_ctf_enumeration_type (ctf_container_ref ctfc, dw_die_ref enumeration)
== dw_val_class_unsigned_const_implicit))
value_wide_int = AT_unsigned (enumerator_value);
else
- value_wide_int = AT_int (enumerator_value);
+ {
+ value_wide_int = AT_int (enumerator_value);
+ flags |= CTF_ENUM_F_ENUMERATORS_SIGNED;
+ }
ctf_add_enumerator (ctfc, enumeration_type_id,
- enumerator_name, value_wide_int, enumeration);
+ enumerator_name, value_wide_int,
+ flags, enumeration);
}
while (c != dw_get_die_child (enumeration));
}
@@ -4,7 +4,7 @@
/* { dg-options "-O0 -gbtf -dA" } */
/* { dg-final { scan-assembler-times "\[\t \]0x6000004\[\t \]+\[^\n\]*btt_info" 1 } } */
-/* { dg-final { scan-assembler-times "\[\t \]0x6000003\[\t \]+\[^\n\]*btt_info" 1 } } */
+/* { dg-final { scan-assembler-times "\[\t \]0x86000003\[\t \]+\[^\n\]*btt_info" 1 } } */
/* { dg-final { scan-assembler-times "ascii \"QAD.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
/* { dg-final { scan-assembler-times "ascii \"QED.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
/* { dg-final { scan-assembler-times "ascii \"QOD.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
new file mode 100644
@@ -0,0 +1,41 @@
+/* Test BTF generation for 64 bits enums. */
+
+/* { dg-do compile } */
+/* { dg-options "-O0 -gbtf -dA" } */
+
+/* { dg-final { scan-assembler-times "\[\t \].size\[\t \]myenum1,\[\t \]8" 1 } } */
+/* { dg-final { scan-assembler-times "\[\t \].size\[\t \]myenum2,\[\t \]8" 1 } } */
+/* { dg-final { scan-assembler-times "\[\t \].size\[\t \]myenum3,\[\t \]8" 1 } } */
+/* { dg-final { scan-assembler-times "\[\t \]0x13000003\[\t \]+\[^\n\]*btt_info" 2 } } */
+/* { dg-final { scan-assembler-times "\[\t \]0x93000003\[\t \]+\[^\n\]*btt_info" 1 } } */
+/* { dg-final { scan-assembler-times "ascii \"B1.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
+/* { dg-final { scan-assembler-times "ascii \"B2.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
+/* { dg-final { scan-assembler-times "ascii \"B3.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
+/* { dg-final { scan-assembler-times "ascii \"C1.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
+/* { dg-final { scan-assembler-times "ascii \"C2.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
+/* { dg-final { scan-assembler-times "ascii \"C3.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
+/* { dg-final { scan-assembler-times "ascii \"D1.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
+/* { dg-final { scan-assembler-times "ascii \"D2.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
+/* { dg-final { scan-assembler-times "ascii \"D3.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */
+/* { dg-final { scan-assembler-times "bte_value" 9 } } */
+
+enum default_enum
+{
+ B1 = 0xffffffffaa,
+ B2 = 0xbbbbbbbb,
+ B3 = 0xaabbccdd,
+} myenum1 = B1;
+
+enum explicit_unsigned
+{
+ C1 = 0xffffffffbbUL,
+ C2 = 0xbbbbbbbb,
+ C3 = 0xaabbccdd,
+} myenum2 = C1;
+
+enum signed64
+{
+ D1 = 0xffffffffaa,
+ D2 = 0xbbbbbbbb,
+ D3 = -0x1,
+} myenum3 = D1;
@@ -109,7 +109,8 @@ struct btf_type
#define BTF_KIND_VAR 14 /* Variable. */
#define BTF_KIND_DATASEC 15 /* Section such as .bss or .data. */
#define BTF_KIND_FLOAT 16 /* Floating point. */
-#define BTF_KIND_MAX BTF_KIND_FLOAT
+#define BTF_KIND_ENUM64 19 /* Enumeration up to 64 bits. */
+#define BTF_KIND_MAX BTF_KIND_ENUM64
#define NR_BTF_KINDS (BTF_KIND_MAX + 1)
/* For some BTF_KINDs, struct btf_type is immediately followed by
@@ -130,14 +131,17 @@ struct btf_type
#define BTF_INT_BOOL (1 << 2)
/* BTF_KIND_ENUM is followed by VLEN struct btf_enum entries,
- which describe the enumerators. Note that BTF currently only
- supports signed 32-bit enumerator values. */
+ which describe the enumerators. */
struct btf_enum
{
uint32_t name_off; /* Offset in string section of enumerator name. */
int32_t val; /* Enumerator value. */
};
+/* BTF_KF_ENUM_ holds the flags for kflags in BTF_KIND_ENUM{,64}. */
+#define BTF_KF_ENUM_UNSIGNED (0)
+#define BTF_KF_ENUM_SIGNED (1 << 0)
+
/* BTF_KIND_ARRAY is followed by a single struct btf_array. */
struct btf_array
{
@@ -190,6 +194,15 @@ struct btf_var_secinfo
uint32_t size; /* Size (in bytes) of variable. */
};
+/* BTF_KIND_ENUM64 is followed by VLEN struct btf_enum64 entries,
+ which describe the 64 bits enumerators. */
+struct btf_enum64
+{
+ uint32_t name_off; /* Offset in string section of enumerator name. */
+ uint32_t val_lo32; /* lower 32-bit value for a 64-bit value Enumerator */
+ uint32_t val_hi32; /* high 32-bit value for a 64-bit value Enumerator */
+};
+
#ifdef __cplusplus
}
#endif