public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-9927] btf: emit non-representable bitfield as void
@ 2024-04-11 22:21 David Faust
  0 siblings, 0 replies; only message in thread
From: David Faust @ 2024-04-11 22:21 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:f079d69d7b1338522562516537d96e9e1285c95e

commit r14-9927-gf079d69d7b1338522562516537d96e9e1285c95e
Author: David Faust <david.faust@oracle.com>
Date:   Thu Apr 11 11:18:55 2024 -0700

    btf: emit non-representable bitfield as void
    
    This patch fixes an issue with mangled BTF that could occur when
    a struct type contains a bitfield member which cannot be represented
    in BTF.  It is undefined what should happen in such cases, but we can
    at least do something reasonable.
    
    Commit
    
      936dd627cd9 "btf: do not skip members of data type with type id
      BTF_VOID_TYPEID"
    
    made a similar change for un-representable non-bitfield members, but
    had an unintended side-effect of mangling BTF for un-representable
    bitfields: the struct (or union) would account for the offending
    bitfield in its member count but the bitfield member itself was
    not emitted, making the member count incorrect.
    
    This change ensures that non-representable bitfield members of struct
    and union types are always emitted with BTF_VOID_TYPEID.  This avoids
    corrupting the BTF information for the entire struct or union type.
    
    gcc/
            * btfout.cc (btf_asm_sou_member): Always emit non-representable
            bitfield members as having 'void' type.  Refactor slightly.
    
    gcc/testsuite/
            * gcc.dg/debug/btf/btf-bitfields-4.c: Add two new checks.

Diff:
---
 gcc/btfout.cc                                    | 54 ++++++++++++------------
 gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c |  2 +
 2 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/gcc/btfout.cc b/gcc/btfout.cc
index ab491f0297f..a1510574a93 100644
--- a/gcc/btfout.cc
+++ b/gcc/btfout.cc
@@ -922,41 +922,39 @@ static void
 btf_asm_sou_member (ctf_container_ref ctfc, ctf_dmdef_t * dmd, unsigned int idx)
 {
   ctf_dtdef_ref ref_type = ctfc->ctfc_types_list[dmd->dmd_type];
+  ctf_id_t base_type = get_btf_id (dmd->dmd_type);
+  uint64_t sou_offset = dmd->dmd_offset;
+
+  dw2_asm_output_data (4, dmd->dmd_name_offset,
+		       "MEMBER '%s' idx=%u",
+		       dmd->dmd_name, idx);
 
   /* 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;
+      if (btf_dmd_representable_bitfield_p (ctfc, dmd))
+	{
+	  unsigned short word_offset = ref_type->dtd_u.dtu_slice.cts_offset;
+	  unsigned short bits = ref_type->dtd_u.dtu_slice.cts_bits;
 
-      sou_offset &= 0x00ffffff;
-      sou_offset |= ((bits & 0xff) << 24);
+	  /* Pack the bit offset and bitfield size together.  */
+	  sou_offset += word_offset;
+	  sou_offset &= 0x00ffffff;
+	  sou_offset |= ((bits & 0xff) << 24);
 
-      dw2_asm_output_data (4, dmd->dmd_name_offset,
-			   "MEMBER '%s' idx=%u",
-			   dmd->dmd_name, idx);
-      /* Refer to the base type of the slice.  */
-      btf_asm_type_ref ("btm_type", ctfc, get_btf_id (base_type));
-      dw2_asm_output_data (4, sou_offset, "btm_offset");
-    }
-  else
-    {
-      dw2_asm_output_data (4, dmd->dmd_name_offset,
-			   "MEMBER '%s' idx=%u",
-			   dmd->dmd_name, idx);
-      btf_asm_type_ref ("btm_type", ctfc, get_btf_id (dmd->dmd_type));
-      dw2_asm_output_data (4, dmd->dmd_offset, "btm_offset");
+	  /* Refer to the base type of the slice.  */
+	  base_type = get_btf_id (ref_type->dtd_u.dtu_slice.cts_type);
+	}
+      else
+	{
+	  /* Bitfield cannot be represented in BTF.  Emit the member as having
+	     'void' type.  */
+	  base_type = BTF_VOID_TYPEID;
+	}
     }
+
+  btf_asm_type_ref ("btm_type", ctfc, base_type);
+  dw2_asm_output_data (4, sou_offset, "btm_offset");
 }
 
 /* Asm'out an enum constant following a BTF_KIND_ENUM{,64}.  */
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 d4a6ef6a1eb..20cdfaa057a 100644
--- a/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c
+++ b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c
@@ -14,6 +14,8 @@
 
 /* Struct with 4 members and no bitfield (kind_flag not set).  */
 /* { dg-final { scan-assembler-times "\[\t \]0x4000004\[\t \]+\[^\n\]*btt_info" 1 } } */
+/* { dg-final { scan-assembler-times " MEMBER" 4 } } */
+/* { dg-final { scan-assembler-times " MEMBER 'unsup' idx=2\[\\r\\n\]+\[^\\r\\n\]*0\[\t \]+\[^\n\]*btm_type: void" 1 } } */
 
 struct bigly
 {

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-04-11 22:21 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-11 22:21 [gcc r14-9927] btf: emit non-representable bitfield as void David Faust

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).