diff mbox series

[2/2] btf: do not skip members of data type with type id BTF_VOID_TYPEID

Message ID 20240410182511.1528093-3-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
Testing the previous fix in gen_ctf_sou_type () reveals an issue in BTF
generation, however: BTF emission was currently decrementing the vlen
(indicating the number of members) to skip members of type CTF_K_UNKNOWN
altogether, but still emitting the BTF for the corresponding member (in
output_asm_btf_sou_fields ()).

One can see malformed BTF by executing the newly added CTF testcase
(gcc.dg/debug/ctf/ctf-bitfields-5.c) with -gbtf instead or even existing
btf-struct-2.c without this patch.

To fix the issue, it makes sense to rather _not_ skip members of data
type of type id BTF_VOID_TYPEID.

gcc/ChangeLog:
	* btfout.cc (btf_asm_type): Do not skip emitting members of
	unknown type.

gcc/testsuite/ChangeLog:
	* btf-bitfields-4.c: Update the vlen check.
	* btf-struct-2.c: Check that member named 'f' with void data
	type is emitted.
---
 gcc/btfout.cc                                    | 5 -----
 gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c | 6 +++---
 gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c    | 9 +++++----
 3 files changed, 8 insertions(+), 12 deletions(-)

Comments

David Faust April 10, 2024, 7:18 p.m. UTC | #1
Hi Indu,

On 4/10/24 11:25, Indu Bhagat wrote:
> Testing the previous fix in gen_ctf_sou_type () reveals an issue in BTF
> generation, however: BTF emission was currently decrementing the vlen
> (indicating the number of members) to skip members of type CTF_K_UNKNOWN
> altogether, but still emitting the BTF for the corresponding member (in
> output_asm_btf_sou_fields ()).
> 
> One can see malformed BTF by executing the newly added CTF testcase
> (gcc.dg/debug/ctf/ctf-bitfields-5.c) with -gbtf instead or even existing
> btf-struct-2.c without this patch.
> 
> To fix the issue, it makes sense to rather _not_ skip members of data
> type of type id BTF_VOID_TYPEID.

Thank you for catching and fixing this.

FWIW, what to do in such cases for a struct with a member that has no
representation is undefined behavior in BTF.  I certainly agree it's
better not to emit something malformed, and using 'void' is a good
choice.  Better to know there was a member there that could not be
represented than to skip it altogether, and the total struct size
shall still be correct.

OK.
Thanks!

> 
> gcc/ChangeLog:
> 	* btfout.cc (btf_asm_type): Do not skip emitting members of
> 	unknown type.
> 
> gcc/testsuite/ChangeLog:
> 	* btf-bitfields-4.c: Update the vlen check.
> 	* btf-struct-2.c: Check that member named 'f' with void data
> 	type is emitted.
> ---
>  gcc/btfout.cc                                    | 5 -----
>  gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c | 6 +++---
>  gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c    | 9 +++++----
>  3 files changed, 8 insertions(+), 12 deletions(-)
> 
> diff --git a/gcc/btfout.cc b/gcc/btfout.cc
> index 4a8ec4d1ff0..ab491f0297f 100644
> --- a/gcc/btfout.cc
> +++ b/gcc/btfout.cc
> @@ -820,11 +820,6 @@ btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd)
>  	  /* 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;
>  	}
>      }
>  
> diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c
> index c00c8b3d87f..d4a6ef6a1eb 100644
> --- a/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c
> +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c
> @@ -6,14 +6,14 @@
>     In this test, we construct a structure such that the bitfield will have
>     an offset so large as to be unrepresentable in BTF. We expect that the
>     resulting BTF will describe the rest of the structure, ignoring the
> -   non-representable bitfield.  */
> +   non-representable bitfield by simply using void data type for the same.  */
>  
>  /* { dg-do compile } */
>  /* { dg-options "-O0 -gbtf -dA" } */
>  /* { dg-require-effective-target size32plus } */
>  
> -/* Struct with 3 members and no bitfield (kind_flag not set).  */
> -/* { dg-final { scan-assembler-times "\[\t \]0x4000003\[\t \]+\[^\n\]*btt_info" 1 } } */
> +/* Struct with 4 members and no bitfield (kind_flag not set).  */
> +/* { dg-final { scan-assembler-times "\[\t \]0x4000004\[\t \]+\[^\n\]*btt_info" 1 } } */
>  
>  struct bigly
>  {
> diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c b/gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c
> index e9ff06883db..fa7231be75c 100644
> --- a/gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c
> +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c
> @@ -2,14 +2,15 @@
>     unsupported type.
>  
>     BTF does not support vector types (among other things). When
> -   generating BTF for a struct (or union) type, members which refer to
> -   unsupported types should be skipped.  */
> +   generating BTF for a struct (or union) type.  Members which refer to
> +   unsupported types should not be skipped, however.  */
>  
>  /* { dg-do compile } */
>  /* { dg-options "-O0 -gbtf -dA" } */
>  
> -/* Expect a struct with only 2 members - 'f' should not be present.  */
> -/* { dg-final { scan-assembler-times "\[\t \]0x4000002\[\t \]+\[^\n\]*btt_info" 1 } } */
> +/* Expect a struct with 3 members - 'f' is present but is of data type void.  */
> +/* { dg-final { scan-assembler-times "\[\t \]0x4000003\[\t \]+\[^\n\]*btt_info" 1 } } */
> +/* { dg-final { scan-assembler-times " MEMBER 'f' idx=1\[\\r\\n\]+\[^\\r\\n\]*0\[\t \]+\[^\n\]*btm_type: void" 1 } } */
>  
>  struct with_float
>  {
diff mbox series

Patch

diff --git a/gcc/btfout.cc b/gcc/btfout.cc
index 4a8ec4d1ff0..ab491f0297f 100644
--- a/gcc/btfout.cc
+++ b/gcc/btfout.cc
@@ -820,11 +820,6 @@  btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd)
 	  /* 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;
 	}
     }
 
diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c
index c00c8b3d87f..d4a6ef6a1eb 100644
--- a/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c
+++ b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c
@@ -6,14 +6,14 @@ 
    In this test, we construct a structure such that the bitfield will have
    an offset so large as to be unrepresentable in BTF. We expect that the
    resulting BTF will describe the rest of the structure, ignoring the
-   non-representable bitfield.  */
+   non-representable bitfield by simply using void data type for the same.  */
 
 /* { dg-do compile } */
 /* { dg-options "-O0 -gbtf -dA" } */
 /* { dg-require-effective-target size32plus } */
 
-/* Struct with 3 members and no bitfield (kind_flag not set).  */
-/* { dg-final { scan-assembler-times "\[\t \]0x4000003\[\t \]+\[^\n\]*btt_info" 1 } } */
+/* Struct with 4 members and no bitfield (kind_flag not set).  */
+/* { dg-final { scan-assembler-times "\[\t \]0x4000004\[\t \]+\[^\n\]*btt_info" 1 } } */
 
 struct bigly
 {
diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c b/gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c
index e9ff06883db..fa7231be75c 100644
--- a/gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c
+++ b/gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c
@@ -2,14 +2,15 @@ 
    unsupported type.
 
    BTF does not support vector types (among other things). When
-   generating BTF for a struct (or union) type, members which refer to
-   unsupported types should be skipped.  */
+   generating BTF for a struct (or union) type.  Members which refer to
+   unsupported types should not be skipped, however.  */
 
 /* { dg-do compile } */
 /* { dg-options "-O0 -gbtf -dA" } */
 
-/* Expect a struct with only 2 members - 'f' should not be present.  */
-/* { dg-final { scan-assembler-times "\[\t \]0x4000002\[\t \]+\[^\n\]*btt_info" 1 } } */
+/* Expect a struct with 3 members - 'f' is present but is of data type void.  */
+/* { dg-final { scan-assembler-times "\[\t \]0x4000003\[\t \]+\[^\n\]*btt_info" 1 } } */
+/* { dg-final { scan-assembler-times " MEMBER 'f' idx=1\[\\r\\n\]+\[^\\r\\n\]*0\[\t \]+\[^\n\]*btm_type: void" 1 } } */
 
 struct with_float
 {