Message ID | 20240410182511.1528093-2-indu.bhagat@oracle.com |
---|---|
State | New |
Headers | show |
Series | Fix PR debug/112878 and a BTF issue | expand |
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 --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;