H8: Add support for preinit/init/fini array

Message ID 20260712195656.744504-1-jdx@o2.pl
State New
Headers
Series H8: Add support for preinit/init/fini array |

Commit Message

Jan Dubiec July 12, 2026, 7:54 p.m. UTC
  This patch adds support for .preinit_array, .init_array, and .fini_array
for the H8 family when binutils and GCC are configured with "--enable-initfini-array".

The changes to init.c and fini.c ensure that linker-defined symbols
referenced from C code are not affected by target-specific symbol naming
conventions. For example, GCC for H8 prefixes external symbol names with
an underscore, whereas GCC for ARM does not. The asm keyword is used to
associate C identifiers with the corresponding linker-defined symbol names
in a target-independent manner.

The patch has been tested on H8 wher it enables support for the
initialization and finalization arrays and on ARM in order to verify that
the changes do not introduce any regressions.

Signed-off-by: Jan Dubiec <jdx@o2.pl>
---
 newlib/libc/misc/fini.c         |  6 ++++--
 newlib/libc/misc/init.c         | 12 ++++++++----
 newlib/libc/sys/h8300hms/crt0.S |  6 ++++++
 3 files changed, 18 insertions(+), 6 deletions(-)
  

Comments

Jeff Johnston July 14, 2026, 11:36 p.m. UTC | #1
Patch merged.

-- Jeff J.

On Sun, Jul 12, 2026 at 4:09 PM Jan Dubiec <jdx@o2.pl> wrote:

> This patch adds support for .preinit_array, .init_array, and .fini_array
> for the H8 family when binutils and GCC are configured with
> "--enable-initfini-array".
>
> The changes to init.c and fini.c ensure that linker-defined symbols
> referenced from C code are not affected by target-specific symbol naming
> conventions. For example, GCC for H8 prefixes external symbol names with
> an underscore, whereas GCC for ARM does not. The asm keyword is used to
> associate C identifiers with the corresponding linker-defined symbol names
> in a target-independent manner.
>
> The patch has been tested on H8 wher it enables support for the
> initialization and finalization arrays and on ARM in order to verify that
> the changes do not introduce any regressions.
>
> Signed-off-by: Jan Dubiec <jdx@o2.pl>
> ---
>  newlib/libc/misc/fini.c         |  6 ++++--
>  newlib/libc/misc/init.c         | 12 ++++++++----
>  newlib/libc/sys/h8300hms/crt0.S |  6 ++++++
>  3 files changed, 18 insertions(+), 6 deletions(-)
>
> diff --git a/newlib/libc/misc/fini.c b/newlib/libc/misc/fini.c
> index 5f2016070..0c3a1e0d5 100644
> --- a/newlib/libc/misc/fini.c
> +++ b/newlib/libc/misc/fini.c
> @@ -14,8 +14,10 @@
>  #include <sys/types.h>
>
>  #ifdef _HAVE_INITFINI_ARRAY
> -extern void (*__fini_array_start []) (void) __attribute__((weak));
> -extern void (*__fini_array_end []) (void) __attribute__((weak));
> +extern void (*__fini_array_start []) (void) asm("__fini_array_start")
> +       __attribute__((weak));
> +extern void (*__fini_array_end []) (void) asm("__fini_array_end")
> +       __attribute__((weak));
>
>  #ifdef _HAVE_INIT_FINI
>  extern void _fini (void);
> diff --git a/newlib/libc/misc/init.c b/newlib/libc/misc/init.c
> index 3aef7ad06..5781535f9 100644
> --- a/newlib/libc/misc/init.c
> +++ b/newlib/libc/misc/init.c
> @@ -16,10 +16,14 @@
>  #ifdef _HAVE_INITFINI_ARRAY
>
>  /* These magic symbols are provided by the linker.  */
> -extern void (*__preinit_array_start []) (void) __attribute__((weak));
> -extern void (*__preinit_array_end []) (void) __attribute__((weak));
> -extern void (*__init_array_start []) (void) __attribute__((weak));
> -extern void (*__init_array_end []) (void) __attribute__((weak));
> +extern void (*__preinit_array_start []) (void)
> asm("__preinit_array_start")
> +       __attribute__((weak));
> +extern void (*__preinit_array_end []) (void) asm("__preinit_array_end")
> +       __attribute__((weak));
> +extern void (*__init_array_start []) (void) asm("__init_array_start")
> +       __attribute__((weak));
> +extern void (*__init_array_end []) (void) asm("__init_array_end")
> +       __attribute__((weak));
>
>  #ifdef _HAVE_INIT_FINI
>  extern void _init (void);
> diff --git a/newlib/libc/sys/h8300hms/crt0.S
> b/newlib/libc/sys/h8300hms/crt0.S
> index 757fb0477..020b957d6 100644
> --- a/newlib/libc/sys/h8300hms/crt0.S
> +++ b/newlib/libc/sys/h8300hms/crt0.S
> @@ -1,6 +1,12 @@
>  ; H8/300, H8/300H, H8/300S and H8SX start up file.
>
>  #include "setarch.h"
> +#include "newlib.h"
> +
> +#ifdef _HAVE_INITFINI_ARRAY
> +#define __init ___libc_init_array
> +#define __fini ___libc_fini_array
> +#endif
>
>  #ifdef __H8300__
>
> --
> 2.54.0
>
>
  
Hans-Peter Nilsson Aug. 12, 2026, 2:53 a.m. UTC | #2
> From: Jan Dubiec <jdx@o2.pl>
> Date: Sun, 12 Jul 2026 21:54:53 +0200

> This patch adds support for .preinit_array, .init_array, and .fini_array
> for the H8 family when binutils and GCC are configured with "--enable-initfini-array".

To accomplish that, there should have been a fix to binutils, per
below.

Instead, this patch broke initfini support for targets with a
USER_LABEL_PREFIX, like cris-elf.  I was alerted to this commit when
people tried to use newlib master with cris-elf in
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126518

> The changes to init.c and fini.c ensure that linker-defined symbols
> referenced from C code are not affected by target-specific symbol naming
> conventions. For example, GCC for H8 prefixes external symbol names with
> an underscore, whereas GCC for ARM does not. The asm keyword is used to
> associate C identifiers with the corresponding linker-defined symbol names
> in a target-independent manner.
> 
> The patch has been tested on H8 wher it enables support for the
> initialization and finalization arrays and on ARM in order to verify that
> the changes do not introduce any regressions.

Since ARM isn't a USER_LABEL_PREFIX-target, your patch was neutral
there.  While testing the patch there too makes sense, that target
wasn't in the cross-hairs; it didn't change the symbols.

The parts of this patch to the generic files, should be reverted.
Instead I suggest to correct binutils for h8300 to emit the "_" as a
prefix to those linker-generated initfini-symbols in the default
linker scripts, something like:

diff --git a/ld/emulparams/h8300elf.sh b/ld/emulparams/h8300elf.sh
index 45b3458d1cea..dd007fcd0ffc 100644
--- a/ld/emulparams/h8300elf.sh
+++ b/ld/emulparams/h8300elf.sh
@@ -9,6 +9,7 @@ MAXPAGESIZE=2
 TARGET_PAGE_SIZE=128
 ARCH=h8300
 TEMPLATE_NAME=elf
+USER_LABEL_PREFIX=_
 EMBEDDED=yes
 STACK_ADDR=0xfefc
 TINY_READONLY_SECTION=".tinyrodata :

(cf. emulparams/criself.sh and ld/scripttempl/elf.sc)

That might of course have fallout for other symbols defined in those
scripts, but would align with other targets (no special defines or
asm-renames needed).

brgds, H-P
  
Jeff Johnston Aug. 12, 2026, 5:37 p.m. UTC | #3
The changes to fini.c and init.c have been reverted.

-- Jeff J.

On Tue, Aug 11, 2026 at 10:54 PM Hans-Peter Nilsson <hp@axis.com> wrote:

> > From: Jan Dubiec <jdx@o2.pl>
> > Date: Sun, 12 Jul 2026 21:54:53 +0200
>
> > This patch adds support for .preinit_array, .init_array, and .fini_array
> > for the H8 family when binutils and GCC are configured with
> "--enable-initfini-array".
>
> To accomplish that, there should have been a fix to binutils, per
> below.
>
> Instead, this patch broke initfini support for targets with a
> USER_LABEL_PREFIX, like cris-elf.  I was alerted to this commit when
> people tried to use newlib master with cris-elf in
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126518
>
> > The changes to init.c and fini.c ensure that linker-defined symbols
> > referenced from C code are not affected by target-specific symbol naming
> > conventions. For example, GCC for H8 prefixes external symbol names with
> > an underscore, whereas GCC for ARM does not. The asm keyword is used to
> > associate C identifiers with the corresponding linker-defined symbol
> names
> > in a target-independent manner.
> >
> > The patch has been tested on H8 wher it enables support for the
> > initialization and finalization arrays and on ARM in order to verify that
> > the changes do not introduce any regressions.
>
> Since ARM isn't a USER_LABEL_PREFIX-target, your patch was neutral
> there.  While testing the patch there too makes sense, that target
> wasn't in the cross-hairs; it didn't change the symbols.
>
> The parts of this patch to the generic files, should be reverted.
> Instead I suggest to correct binutils for h8300 to emit the "_" as a
> prefix to those linker-generated initfini-symbols in the default
> linker scripts, something like:
>
> diff --git a/ld/emulparams/h8300elf.sh b/ld/emulparams/h8300elf.sh
> index 45b3458d1cea..dd007fcd0ffc 100644
> --- a/ld/emulparams/h8300elf.sh
> +++ b/ld/emulparams/h8300elf.sh
> @@ -9,6 +9,7 @@ MAXPAGESIZE=2
>  TARGET_PAGE_SIZE=128
>  ARCH=h8300
>  TEMPLATE_NAME=elf
> +USER_LABEL_PREFIX=_
>  EMBEDDED=yes
>  STACK_ADDR=0xfefc
>  TINY_READONLY_SECTION=".tinyrodata :
>
> (cf. emulparams/criself.sh and ld/scripttempl/elf.sc)
>
> That might of course have fallout for other symbols defined in those
> scripts, but would align with other targets (no special defines or
> asm-renames needed).
>
> brgds, H-P
>
>
  
Jan Dubiec Aug. 15, 2026, 7:55 a.m. UTC | #4
On 12.08.2026 04:53, Hans-Peter Nilsson wrote:
[...]

> The parts of this patch to the generic files, should be reverted.
> Instead I suggest to correct binutils for h8300 to emit the "_" as a
> prefix to those linker-generated initfini-symbols in the default
> linker scripts, something like:
Thanks for pointing this out. It led to the discovery of an 
inconsistency in the H8 toolchain. I had actually considered 
USER_LABEL_PREFIX earlier, but was misled by gcc, which defines this 
macro: 
https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/config/h8300/elf.h;hb=HEAD

I have already posted a patch for binutils: 
https://sourceware.org/pipermail/binutils/2026-August/150796.html

/J.D.
  
Jan Dubiec Aug. 15, 2026, 7:59 a.m. UTC | #5
On 12.08.2026 04:53, Hans-Peter Nilsson wrote:
[...]

> The parts of this patch to the generic files, should be reverted.
> Instead I suggest to correct binutils for h8300 to emit the "_" as a
> prefix to those linker-generated initfini-symbols in the default
> linker scripts, something like:
Thanks for pointing this out. It led to the discovery of an 
inconsistency in the H8 toolchain. I had actually considered 
USER_LABEL_PREFIX earlier, but was misled by gcc, which defines this 
macro: 
https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/config/h8300/elf.h;hb=HEAD

I have already posted a patch for binutils: 
https://sourceware.org/pipermail/binutils/2026-August/150796.html

/J.D.
  

Patch

diff --git a/newlib/libc/misc/fini.c b/newlib/libc/misc/fini.c
index 5f2016070..0c3a1e0d5 100644
--- a/newlib/libc/misc/fini.c
+++ b/newlib/libc/misc/fini.c
@@ -14,8 +14,10 @@ 
 #include <sys/types.h>
 
 #ifdef _HAVE_INITFINI_ARRAY
-extern void (*__fini_array_start []) (void) __attribute__((weak));
-extern void (*__fini_array_end []) (void) __attribute__((weak));
+extern void (*__fini_array_start []) (void) asm("__fini_array_start")
+	__attribute__((weak));
+extern void (*__fini_array_end []) (void) asm("__fini_array_end")
+	__attribute__((weak));
 
 #ifdef _HAVE_INIT_FINI
 extern void _fini (void);
diff --git a/newlib/libc/misc/init.c b/newlib/libc/misc/init.c
index 3aef7ad06..5781535f9 100644
--- a/newlib/libc/misc/init.c
+++ b/newlib/libc/misc/init.c
@@ -16,10 +16,14 @@ 
 #ifdef _HAVE_INITFINI_ARRAY
 
 /* These magic symbols are provided by the linker.  */
-extern void (*__preinit_array_start []) (void) __attribute__((weak));
-extern void (*__preinit_array_end []) (void) __attribute__((weak));
-extern void (*__init_array_start []) (void) __attribute__((weak));
-extern void (*__init_array_end []) (void) __attribute__((weak));
+extern void (*__preinit_array_start []) (void) asm("__preinit_array_start")
+	__attribute__((weak));
+extern void (*__preinit_array_end []) (void) asm("__preinit_array_end")
+	__attribute__((weak));
+extern void (*__init_array_start []) (void) asm("__init_array_start")
+	__attribute__((weak));
+extern void (*__init_array_end []) (void) asm("__init_array_end")
+	__attribute__((weak));
 
 #ifdef _HAVE_INIT_FINI
 extern void _init (void);
diff --git a/newlib/libc/sys/h8300hms/crt0.S b/newlib/libc/sys/h8300hms/crt0.S
index 757fb0477..020b957d6 100644
--- a/newlib/libc/sys/h8300hms/crt0.S
+++ b/newlib/libc/sys/h8300hms/crt0.S
@@ -1,6 +1,12 @@ 
 ; H8/300, H8/300H, H8/300S and H8SX start up file.
 
 #include "setarch.h"
+#include "newlib.h"
+
+#ifdef _HAVE_INITFINI_ARRAY
+#define __init	___libc_init_array
+#define __fini	___libc_fini_array
+#endif
 
 #ifdef __H8300__