[PATCH] toolchain: gcc: MIPS: fix emitted .size for VLAs
David 'equinox' Lamparter
equinox at diac24.net
Wed Jan 28 08:05:49 PST 2026
>From the patch files:
GCC was emitting the size of the constant part of VLA structures, e.g.
something like:
struct foo {
int a, b[];
} bar = { 1, { 2, 3, 4 } };
Would get a .size 4 (for a), rather than 16 (a, and 3 items in b). This
doesn't immediately break things, but one case where it matters is when
the object is in a shared library and the linker creates a copy
relocation - it'll only copy the first part of whatever we're looking
at.
Use the size of the decl (which will include the variable part) rather
than the type (which has no idea what is about to be set up in terms of
content) - same as all the other architectures. The "new" code in fact
comes from gcc/config/elfos.h.
References: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102298
Signed-off-by: David 'equinox' Lamparter <equinox at diac24.net>
---
(dup of https://github.com/openwrt/openwrt/pull/21753)
Tested on 25.12 on an TP-Link EAP-615-Wall; fixes the FRR problem and
doesn't seem to cause any ill effect.
---
...tted-size-for-variably-sized-objects.patch | 64 +++++++++++++++++++
...tted-size-for-variably-sized-objects.patch | 64 +++++++++++++++++++
...tted-size-for-variably-sized-objects.patch | 64 +++++++++++++++++++
...tted-size-for-variably-sized-objects.patch | 64 +++++++++++++++++++
4 files changed, 256 insertions(+)
create mode 100644 toolchain/gcc/patches-12.x/150-MIPS-fix-emitted-size-for-variably-sized-objects.patch
create mode 100644 toolchain/gcc/patches-13.x/150-MIPS-fix-emitted-size-for-variably-sized-objects.patch
create mode 100644 toolchain/gcc/patches-14.x/150-MIPS-fix-emitted-size-for-variably-sized-objects.patch
create mode 100644 toolchain/gcc/patches-15.x/150-MIPS-fix-emitted-size-for-variably-sized-objects.patch
diff --git a/toolchain/gcc/patches-12.x/150-MIPS-fix-emitted-size-for-variably-sized-objects.patch b/toolchain/gcc/patches-12.x/150-MIPS-fix-emitted-size-for-variably-sized-objects.patch
new file mode 100644
index 000000000000..2371f4f044cd
--- /dev/null
+++ b/toolchain/gcc/patches-12.x/150-MIPS-fix-emitted-size-for-variably-sized-objects.patch
@@ -0,0 +1,64 @@
+From 3cbfc5374bc48494db3308eb1d0ef293f9f7b5e8 Mon Sep 17 00:00:00 2001
+From: David Lamparter <equinox at diac24.net>
+Date: Wed, 28 Jan 2026 16:29:06 +0100
+Subject: [PATCH] MIPS: fix emitted .size for variably sized objects
+
+GCC was emitting the size of the constant part of VLA structures, e.g.
+something like:
+
+ struct foo {
+ int a, b[];
+ } bar = { 1, { 2, 3, 4 } };
+
+Would get a .size 4 (for a), rather than 16 (a, and 3 items in b). This
+doesn't immediately break things, but one case where it matters is when
+the object is in a shared library and the linker creates a copy
+relocation - it'll only copy the first part of whatever we're looking
+at.
+
+Use the size of the decl (which will include the variable part) rather
+than the type (which has no idea what is about to be set up in terms of
+content) - same as all the other architectures. The "new" code in fact
+comes from gcc/config/elfos.h.
+
+References: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102298
+Cc: Andrew Pinski <andrew.pinski at oss.qualcomm.com>
+Signed-off-by: David Lamparter <equinox at diac24.net>
+---
+ gcc/config/mips/mips.cc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
+index d26630b20cef..163cc30c6f10 100644
+--- a/gcc/config/mips/mips.cc
++++ b/gcc/config/mips/mips.cc
+@@ -9581,7 +9581,7 @@ mips_output_external (FILE *file, tree decl, const char *name)
+ fputs ("\t.extern\t", file);
+ assemble_name (file, name);
+ fprintf (file, ", " HOST_WIDE_INT_PRINT_DEC "\n",
+- int_size_in_bytes (TREE_TYPE (decl)));
++ tree_to_uhwi (DECL_SIZE_UNIT (decl)));
+ }
+ }
+ }
+@@ -9895,7 +9895,7 @@ mips_declare_object_name (FILE *stream, const char *name,
+ HOST_WIDE_INT size;
+
+ size_directive_output = 1;
+- size = int_size_in_bytes (TREE_TYPE (decl));
++ size = tree_to_uhwi (DECL_SIZE_UNIT (decl));
+ ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
+ }
+
+@@ -9920,7 +9920,7 @@ mips_finish_declare_object (FILE *stream, tree decl, int top_level, int at_end)
+ HOST_WIDE_INT size;
+
+ size_directive_output = 1;
+- size = int_size_in_bytes (TREE_TYPE (decl));
++ size = tree_to_uhwi (DECL_SIZE_UNIT (decl));
+ ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
+ }
+ }
+--
+2.52.0
+
diff --git a/toolchain/gcc/patches-13.x/150-MIPS-fix-emitted-size-for-variably-sized-objects.patch b/toolchain/gcc/patches-13.x/150-MIPS-fix-emitted-size-for-variably-sized-objects.patch
new file mode 100644
index 000000000000..2bff4d21badc
--- /dev/null
+++ b/toolchain/gcc/patches-13.x/150-MIPS-fix-emitted-size-for-variably-sized-objects.patch
@@ -0,0 +1,64 @@
+From e49eff5fc806e255028510de55d8d8ccac1dc99b Mon Sep 17 00:00:00 2001
+From: David Lamparter <equinox at diac24.net>
+Date: Wed, 28 Jan 2026 16:29:06 +0100
+Subject: [PATCH] MIPS: fix emitted .size for variably sized objects
+
+GCC was emitting the size of the constant part of VLA structures, e.g.
+something like:
+
+ struct foo {
+ int a, b[];
+ } bar = { 1, { 2, 3, 4 } };
+
+Would get a .size 4 (for a), rather than 16 (a, and 3 items in b). This
+doesn't immediately break things, but one case where it matters is when
+the object is in a shared library and the linker creates a copy
+relocation - it'll only copy the first part of whatever we're looking
+at.
+
+Use the size of the decl (which will include the variable part) rather
+than the type (which has no idea what is about to be set up in terms of
+content) - same as all the other architectures. The "new" code in fact
+comes from gcc/config/elfos.h.
+
+References: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102298
+Cc: Andrew Pinski <andrew.pinski at oss.qualcomm.com>
+Signed-off-by: David Lamparter <equinox at diac24.net>
+---
+ gcc/config/mips/mips.cc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
+index 9bc73b2e77db..de0c50904baa 100644
+--- a/gcc/config/mips/mips.cc
++++ b/gcc/config/mips/mips.cc
+@@ -9588,7 +9588,7 @@ mips_output_external (FILE *file, tree decl, const char *name)
+ fputs ("\t.extern\t", file);
+ assemble_name (file, name);
+ fprintf (file, ", " HOST_WIDE_INT_PRINT_DEC "\n",
+- int_size_in_bytes (TREE_TYPE (decl)));
++ tree_to_uhwi (DECL_SIZE_UNIT (decl)));
+ }
+ }
+ }
+@@ -9898,7 +9898,7 @@ mips_declare_object_name (FILE *stream, const char *name,
+ HOST_WIDE_INT size;
+
+ size_directive_output = 1;
+- size = int_size_in_bytes (TREE_TYPE (decl));
++ size = tree_to_uhwi (DECL_SIZE_UNIT (decl));
+ ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
+ }
+
+@@ -9923,7 +9923,7 @@ mips_finish_declare_object (FILE *stream, tree decl, int top_level, int at_end)
+ HOST_WIDE_INT size;
+
+ size_directive_output = 1;
+- size = int_size_in_bytes (TREE_TYPE (decl));
++ size = tree_to_uhwi (DECL_SIZE_UNIT (decl));
+ ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
+ }
+ }
+--
+2.52.0
+
diff --git a/toolchain/gcc/patches-14.x/150-MIPS-fix-emitted-size-for-variably-sized-objects.patch b/toolchain/gcc/patches-14.x/150-MIPS-fix-emitted-size-for-variably-sized-objects.patch
new file mode 100644
index 000000000000..13d8a7700a8c
--- /dev/null
+++ b/toolchain/gcc/patches-14.x/150-MIPS-fix-emitted-size-for-variably-sized-objects.patch
@@ -0,0 +1,64 @@
+From 8217b98353ec987db36f54d1852664db0748f15f Mon Sep 17 00:00:00 2001
+From: David Lamparter <equinox at diac24.net>
+Date: Wed, 28 Jan 2026 16:29:06 +0100
+Subject: [PATCH] MIPS: fix emitted .size for variably sized objects
+
+GCC was emitting the size of the constant part of VLA structures, e.g.
+something like:
+
+ struct foo {
+ int a, b[];
+ } bar = { 1, { 2, 3, 4 } };
+
+Would get a .size 4 (for a), rather than 16 (a, and 3 items in b). This
+doesn't immediately break things, but one case where it matters is when
+the object is in a shared library and the linker creates a copy
+relocation - it'll only copy the first part of whatever we're looking
+at.
+
+Use the size of the decl (which will include the variable part) rather
+than the type (which has no idea what is about to be set up in terms of
+content) - same as all the other architectures. The "new" code in fact
+comes from gcc/config/elfos.h.
+
+References: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102298
+Cc: Andrew Pinski <andrew.pinski at oss.qualcomm.com>
+Signed-off-by: David Lamparter <equinox at diac24.net>
+---
+ gcc/config/mips/mips.cc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
+index 1156d212c1f9..ff27234c2c1b 100644
+--- a/gcc/config/mips/mips.cc
++++ b/gcc/config/mips/mips.cc
+@@ -9755,7 +9755,7 @@ mips_output_external (FILE *file, tree decl, const char *name)
+ fputs ("\t.extern\t", file);
+ assemble_name (file, name);
+ fprintf (file, ", " HOST_WIDE_INT_PRINT_DEC "\n",
+- int_size_in_bytes (TREE_TYPE (decl)));
++ tree_to_uhwi (DECL_SIZE_UNIT (decl)));
+ }
+ }
+ }
+@@ -10065,7 +10065,7 @@ mips_declare_object_name (FILE *stream, const char *name,
+ HOST_WIDE_INT size;
+
+ size_directive_output = 1;
+- size = int_size_in_bytes (TREE_TYPE (decl));
++ size = tree_to_uhwi (DECL_SIZE_UNIT (decl));
+ ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
+ }
+
+@@ -10090,7 +10090,7 @@ mips_finish_declare_object (FILE *stream, tree decl, int top_level, int at_end)
+ HOST_WIDE_INT size;
+
+ size_directive_output = 1;
+- size = int_size_in_bytes (TREE_TYPE (decl));
++ size = tree_to_uhwi (DECL_SIZE_UNIT (decl));
+ ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
+ }
+ }
+--
+2.52.0
+
diff --git a/toolchain/gcc/patches-15.x/150-MIPS-fix-emitted-size-for-variably-sized-objects.patch b/toolchain/gcc/patches-15.x/150-MIPS-fix-emitted-size-for-variably-sized-objects.patch
new file mode 100644
index 000000000000..eea9563a70b9
--- /dev/null
+++ b/toolchain/gcc/patches-15.x/150-MIPS-fix-emitted-size-for-variably-sized-objects.patch
@@ -0,0 +1,64 @@
+From 56e3fdaf4d493673a97ce89121fb70a0afd9f1ed Mon Sep 17 00:00:00 2001
+From: David Lamparter <equinox at diac24.net>
+Date: Wed, 28 Jan 2026 16:29:06 +0100
+Subject: [PATCH] MIPS: fix emitted .size for variably sized objects
+
+GCC was emitting the size of the constant part of VLA structures, e.g.
+something like:
+
+ struct foo {
+ int a, b[];
+ } bar = { 1, { 2, 3, 4 } };
+
+Would get a .size 4 (for a), rather than 16 (a, and 3 items in b). This
+doesn't immediately break things, but one case where it matters is when
+the object is in a shared library and the linker creates a copy
+relocation - it'll only copy the first part of whatever we're looking
+at.
+
+Use the size of the decl (which will include the variable part) rather
+than the type (which has no idea what is about to be set up in terms of
+content) - same as all the other architectures. The "new" code in fact
+comes from gcc/config/elfos.h.
+
+References: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102298
+Cc: Andrew Pinski <andrew.pinski at oss.qualcomm.com>
+Signed-off-by: David Lamparter <equinox at diac24.net>
+---
+ gcc/config/mips/mips.cc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
+index 24a28dcf817f..5e5f0fe02eba 100644
+--- a/gcc/config/mips/mips.cc
++++ b/gcc/config/mips/mips.cc
+@@ -9885,7 +9885,7 @@ mips_output_external (FILE *file, tree decl, const char *name)
+ fputs ("\t.extern\t", file);
+ assemble_name (file, name);
+ fprintf (file, ", " HOST_WIDE_INT_PRINT_DEC "\n",
+- int_size_in_bytes (TREE_TYPE (decl)));
++ tree_to_uhwi (DECL_SIZE_UNIT (decl)));
+ }
+ }
+ }
+@@ -10195,7 +10195,7 @@ mips_declare_object_name (FILE *stream, const char *name,
+ HOST_WIDE_INT size;
+
+ size_directive_output = 1;
+- size = int_size_in_bytes (TREE_TYPE (decl));
++ size = tree_to_uhwi (DECL_SIZE_UNIT (decl));
+ ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
+ }
+
+@@ -10220,7 +10220,7 @@ mips_finish_declare_object (FILE *stream, tree decl, int top_level, int at_end)
+ HOST_WIDE_INT size;
+
+ size_directive_output = 1;
+- size = int_size_in_bytes (TREE_TYPE (decl));
++ size = tree_to_uhwi (DECL_SIZE_UNIT (decl));
+ ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
+ }
+ }
+--
+2.52.0
+
--
2.52.0
More information about the openwrt-devel
mailing list