diff mbox series

[1/2] ctf: fix PR debug/112878

Message ID 20240410182511.1528093-2-indu.bhagat@oracle.com
State New
Headers show
Series Fix PR debug/112878 and a BTF issue | expand

Commit Message

Indu Bhagat April 10, 2024, 6:25 p.m. UTC
PR debug/112878: ICE: in ctf_add_slice, at ctfc.cc:499 with _BitInt > 255 in a struct and -gctf1

The CTF generation in GCC does not have a mechanism to roll-back an
already added type.  In this testcase presented in the PR, we hit a
representation limit in CTF slices (for a member of a struct) and ICE,
after the type for struct (CTF_K_STRUCT) has already been added to the
container.

To exit gracefully instead, we now check for both the offset and size of
the bitfield to be explicitly <= 255.  If the check fails, we emit the
member with type CTF_K_UNKNOWN.  Note that, the value 255 stems from the
existing binutils libctf checks which were motivated to guard against
malformed inputs.

Although it is not accurate to say that this is a CTF representation
limit, mark the code with TBD_CTF_REPRESENTATION_LIMIT for now so that
this can be taken care of with the next format version bump, when
libctf's checks for the slice data can be lifted as well.

gcc/ChangeLog:
	PR debug/112878
	* dwarf2ctf.cc (gen_ctf_sou_type): Check for conditions before
	call to ctf_add_slice.  Use CTF_K_UNKNOWN type if fail.

gcc/testsuite/ChangeLog:
	PR debug/112878
	* gcc.dg/debug/ctf/ctf-bitfields-5.c: New test.
---
 gcc/dwarf2ctf.cc                                | 15 ++++++++++-----
 .../gcc.dg/debug/ctf/ctf-bitfields-5.c          | 17 +++++++++++++++++
 2 files changed, 27 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-5.c

Comments

David Faust April 10, 2024, 7:06 p.m. UTC | #1
On 4/10/24 11:25, Indu Bhagat wrote:
> PR debug/112878: ICE: in ctf_add_slice, at ctfc.cc:499 with _BitInt > 255 in a struct and -gctf1
> 
> The CTF generation in GCC does not have a mechanism to roll-back an
> already added type.  In this testcase presented in the PR, we hit a
> representation limit in CTF slices (for a member of a struct) and ICE,
> after the type for struct (CTF_K_STRUCT) has already been added to the
> container.
> 
> To exit gracefully instead, we now check for both the offset and size of
> the bitfield to be explicitly <= 255.  If the check fails, we emit the
> member with type CTF_K_UNKNOWN.  Note that, the value 255 stems from the
> existing binutils libctf checks which were motivated to guard against
> malformed inputs.
> 
> Although it is not accurate to say that this is a CTF representation
> limit, mark the code with TBD_CTF_REPRESENTATION_LIMIT for now so that
> this can be taken care of with the next format version bump, when
> libctf's checks for the slice data can be lifted as well.

OK.

> 
> gcc/ChangeLog:
> 	PR debug/112878
> 	* dwarf2ctf.cc (gen_ctf_sou_type): Check for conditions before
> 	call to ctf_add_slice.  Use CTF_K_UNKNOWN type if fail.
> 
> gcc/testsuite/ChangeLog:
> 	PR debug/112878
> 	* gcc.dg/debug/ctf/ctf-bitfields-5.c: New test.
> ---
>  gcc/dwarf2ctf.cc                                | 15 ++++++++++-----
>  .../gcc.dg/debug/ctf/ctf-bitfields-5.c          | 17 +++++++++++++++++
>  2 files changed, 27 insertions(+), 5 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-5.c
> 
> diff --git a/gcc/dwarf2ctf.cc b/gcc/dwarf2ctf.cc
> index 77d6bf89689..dc59569fe56 100644
> --- a/gcc/dwarf2ctf.cc
> +++ b/gcc/dwarf2ctf.cc
> @@ -606,11 +606,16 @@ gen_ctf_sou_type (ctf_container_ref ctfc, dw_die_ref sou, uint32_t kind)
>  	      if (attr)
>  		bitpos += AT_unsigned (attr);
>  
> -	      field_type_id = ctf_add_slice (ctfc, CTF_ADD_NONROOT,
> -					     field_type_id,
> -					     bitpos - field_location,
> -					     bitsize,
> -					     c);
> +	      /* This is not precisely a TBD_CTF_REPRESENTATION_LIMIT, but
> +		 surely something to look at for the next format version bump
> +		 for CTF.  */
> +	      if (bitsize <= 255 && (bitpos - field_location) <= 255)
> +		field_type_id = ctf_add_slice (ctfc, CTF_ADD_NONROOT,
> +					       field_type_id,
> +					       bitpos - field_location,
> +					       bitsize, c);
> +	      else
> +		field_type_id = gen_ctf_unknown_type (ctfc);
>  	    }
>  
>  	  /* Add the field type to the struct or union type.  */
> diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-5.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-5.c
> new file mode 100644
> index 00000000000..fee8228647c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-5.c
> @@ -0,0 +1,17 @@
> +/* Bitfield where the bit offset is > 255 is not allowed in CTF.
> +
> +   PR debug/112878.
> +   This testcase is to ensure graceful handling. No slices are expected.  */
> +
> +/* { dg-do compile { target bitint } } */
> +/* { dg-options "-O0 -gctf -dA" } */
> +
> +/* No slices are expected, but a struct with one member is expected.
> +   CTF_K_UNKNOWN is also expected.  */
> +/* { dg-final { scan-assembler-times "cts_type" 0 } } */
> +/* { dg-final { scan-assembler-times "\[\t \]0x1a000001\[\t \]+\[^\n\]*ctt_info" 1 } } */
> +/* { dg-final { scan-assembler-times "ascii \"unknown.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */
> +
> +struct {
> +  _BitInt(282) a : 280;
> +} b;
diff mbox series

Patch

diff --git a/gcc/dwarf2ctf.cc b/gcc/dwarf2ctf.cc
index 77d6bf89689..dc59569fe56 100644
--- a/gcc/dwarf2ctf.cc
+++ b/gcc/dwarf2ctf.cc
@@ -606,11 +606,16 @@  gen_ctf_sou_type (ctf_container_ref ctfc, dw_die_ref sou, uint32_t kind)
 	      if (attr)
 		bitpos += AT_unsigned (attr);
 
-	      field_type_id = ctf_add_slice (ctfc, CTF_ADD_NONROOT,
-					     field_type_id,
-					     bitpos - field_location,
-					     bitsize,
-					     c);
+	      /* This is not precisely a TBD_CTF_REPRESENTATION_LIMIT, but
+		 surely something to look at for the next format version bump
+		 for CTF.  */
+	      if (bitsize <= 255 && (bitpos - field_location) <= 255)
+		field_type_id = ctf_add_slice (ctfc, CTF_ADD_NONROOT,
+					       field_type_id,
+					       bitpos - field_location,
+					       bitsize, c);
+	      else
+		field_type_id = gen_ctf_unknown_type (ctfc);
 	    }
 
 	  /* Add the field type to the struct or union type.  */
diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-5.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-5.c
new file mode 100644
index 00000000000..fee8228647c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-5.c
@@ -0,0 +1,17 @@ 
+/* Bitfield where the bit offset is > 255 is not allowed in CTF.
+
+   PR debug/112878.
+   This testcase is to ensure graceful handling. No slices are expected.  */
+
+/* { dg-do compile { target bitint } } */
+/* { dg-options "-O0 -gctf -dA" } */
+
+/* No slices are expected, but a struct with one member is expected.
+   CTF_K_UNKNOWN is also expected.  */
+/* { dg-final { scan-assembler-times "cts_type" 0 } } */
+/* { dg-final { scan-assembler-times "\[\t \]0x1a000001\[\t \]+\[^\n\]*ctt_info" 1 } } */
+/* { dg-final { scan-assembler-times "ascii \"unknown.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */
+
+struct {
+  _BitInt(282) a : 280;
+} b;