aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Faust <david.faust@oracle.com>2025-08-06 09:24:40 -0700
committerDavid Faust <david.faust@oracle.com>2025-08-25 12:01:17 -0700
commitc77d79785d32b30502c8bcd6aa53b63d715bb124 (patch)
treeffa6af52322261fcfdf5ef9ac22d46ff76b6808b
parent490948d95194b2ae8056fc838c977c977404b97a (diff)
downloadgcc-c77d79785d32b30502c8bcd6aa53b63d715bb124.zip
gcc-c77d79785d32b30502c8bcd6aa53b63d715bb124.tar.gz
gcc-c77d79785d32b30502c8bcd6aa53b63d715bb124.tar.bz2
ctf: avoid overflow for array num elements [PR121411]
CTF array encoding uses uint32 for number of elements. This means there is a hard upper limit on array types which the format can represent. GCC internally was also using a uint32_t for this, which would overflow when translating from DWARF for arrays with more than UINT32_MAX elements. Use an unsigned HOST_WIDE_INT instead to fetch the array bound, and fall back to CTF_K_UNKNOWN if the array cannot be represented in CTF. PR debug/121411 gcc/ * dwarf2ctf.cc (gen_ctf_subrange_type): Use unsigned HWI for array_num_elements. Fallback to CTF_K_UNKNOWN if the array type has too many elements for CTF to represent. gcc/testsuite/ * gcc.dg/debug/ctf/ctf-array-7.c: New test.
-rw-r--r--gcc/dwarf2ctf.cc12
-rw-r--r--gcc/testsuite/gcc.dg/debug/ctf/ctf-array-7.c23
2 files changed, 32 insertions, 3 deletions
diff --git a/gcc/dwarf2ctf.cc b/gcc/dwarf2ctf.cc
index 7de3696..f8b305b 100644
--- a/gcc/dwarf2ctf.cc
+++ b/gcc/dwarf2ctf.cc
@@ -361,7 +361,7 @@ gen_ctf_subrange_type (ctf_container_ref ctfc, ctf_dtdef_ref array_elems_type,
dw_attr_node *upper_bound_at;
dw_die_ref array_index_type;
- uint32_t array_num_elements;
+ unsigned HOST_WIDE_INT array_num_elements;
if (dw_get_die_tag (c) == DW_TAG_subrange_type)
{
@@ -376,9 +376,9 @@ gen_ctf_subrange_type (ctf_container_ref ctfc, ctf_dtdef_ref array_elems_type,
if (upper_bound_at
&& AT_class (upper_bound_at) == dw_val_class_unsigned_const)
/* This is the upper bound index. */
- array_num_elements = get_AT_unsigned (c, DW_AT_upper_bound) + 1;
+ array_num_elements = AT_unsigned (get_AT (c, DW_AT_upper_bound)) + 1;
else if (get_AT (c, DW_AT_count))
- array_num_elements = get_AT_unsigned (c, DW_AT_count);
+ array_num_elements = AT_unsigned (get_AT (c, DW_AT_count));
else
{
/* This is a VLA of some kind. */
@@ -388,6 +388,12 @@ gen_ctf_subrange_type (ctf_container_ref ctfc, ctf_dtdef_ref array_elems_type,
else
gcc_unreachable ();
+ if (array_num_elements > UINT32_MAX)
+ {
+ /* The array cannot be encoded in CTF. TBD_CTF_REPRESENTATION_LIMIT. */
+ return gen_ctf_unknown_type (ctfc);
+ }
+
/* Ok, mount and register the array type. Note how the array
type we register here is the type of the elements in
subsequent "dimensions", if there are any. */
diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-7.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-7.c
new file mode 100644
index 0000000..01accc7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-7.c
@@ -0,0 +1,23 @@
+/* CTF generation for array which cannot be encoded in CTF.
+
+ CTF encoding uses a uint32 for number of elements in an array which
+ means there is a hard upper limit on sizes of arrays which can be
+ represented. Arrays with too many elements are encoded with
+ CTF_K_UNKNOWN to indicate that they cannot be represented. */
+
+/* { dg-do compile } */
+/* { dg-options "-O0 -gctf -dA" } */
+
+int rep[0xffffffff];
+int unrep[0x100000000];
+
+/* One dimension can be represented, other cannot.
+ Result is a (representable) array with unknown element type. */
+int unrepdim [0xab][0x100000007];
+
+/* Two CTF_K_ARRAY, one (shared) CTF_K_UNKNOWN. */
+/* { dg-final { scan-assembler-times "0x12000000\[\t \]+\[^\n\]*ctt_info" 2 } } */
+/* { dg-final { scan-assembler-times "0x2000000\[\t \]+\[^\n\]*ctt_info" 1 } } */
+
+/* { dg-final { scan-assembler-times "\[\t \]+0xffffffff\[\t \]+\[^\n\]*cta_nelems" 1 } } */
+/* { dg-final { scan-assembler-times "\[\t \]+0xab\[\t \]+\[^\n\]*cta_nelems" 1 } } */