public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] btf: Add support to BTF_KIND_ENUM64 type
@ 2022-08-29 21:11 Guillermo E. Martinez
  2022-09-20 19:32 ` Guillermo E. Martinez
                   ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Guillermo E. Martinez @ 2022-08-29 21:11 UTC (permalink / raw)
  To: gcc-patches; +Cc: Guillermo E. Martinez

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
-- 
2.35.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2022-10-31 18:26 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-29 21:11 [PATCH] btf: Add support to BTF_KIND_ENUM64 type Guillermo E. Martinez
2022-09-20 19:32 ` Guillermo E. Martinez
2022-09-28 18:45 ` David Faust
2022-09-28 21:07   ` Guillermo E. Martinez
2022-09-28 21:15 ` [PATCH v2] " Guillermo E. Martinez
2022-09-29 22:35   ` Indu Bhagat
2022-10-03 14:39     ` Guillermo E. Martinez
2022-10-11 18:55       ` Indu Bhagat
2022-10-15  3:45         ` Guillermo E. Martinez
2022-10-15  3:55   ` [PATCH v3] " Guillermo E. Martinez
2022-10-18 21:40     ` Indu Bhagat
2022-10-18 21:48       ` Guillermo E. Martinez
2022-10-20  2:05     ` [PATCH v4] " Guillermo E. Martinez
2022-10-21  9:28       ` Indu Bhagat
2022-10-31 18:26         ` Indu Bhagat

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).