diff --git a/lib/csu/aarch64/Makefile b/lib/csu/aarch64/Makefile --- a/lib/csu/aarch64/Makefile +++ b/lib/csu/aarch64/Makefile @@ -3,7 +3,6 @@ .PATH: ${.CURDIR:H}/common CFLAGS+= -I${.CURDIR} -CFLAGS+= -DCRT_IRELOC_RELA CRT1OBJS+= crt1_s.o diff --git a/lib/csu/aarch64/crt1_c.c b/lib/csu/aarch64/crt1_c.c --- a/lib/csu/aarch64/crt1_c.c +++ b/lib/csu/aarch64/crt1_c.c @@ -32,42 +32,19 @@ #include __FBSDID("$FreeBSD$"); -#include - #include "libc_private.h" -#include "ignore_init.c" - -#ifdef GCRT -extern void _mcleanup(void); -extern void monstartup(void *, void *); -extern int eprol; -extern int etext; -#endif - -extern long * _end; +#include "csu_common.h" -void __start(int, char **, char **, void (*)(void)); +void __start(int, char **, char **, void (*)(void)) __dead2; /* The entry function. */ void __start(int argc, char *argv[], char *env[], void (*cleanup)(void)) { - - handle_argv(argc, argv, env); - - if (&_DYNAMIC != NULL) - atexit(cleanup); - else { - process_irelocs(); - _init_tls(); - } - #ifdef GCRT - atexit(_mcleanup); - monstartup(&eprol, &etext); + __libc_start1_gcrt(argc, argv, env, cleanup, main, &eprol, &etext); __asm__("eprol:"); +#else + __libc_start1(argc, argv, env, cleanup, main); #endif - - handle_static_init(argc, argv, env); - exit(main(argc, argv, env)); } diff --git a/lib/csu/amd64/Makefile b/lib/csu/amd64/Makefile --- a/lib/csu/amd64/Makefile +++ b/lib/csu/amd64/Makefile @@ -3,6 +3,6 @@ .PATH: ${.CURDIR:H}/common CFLAGS+= -I${.CURDIR} -CFLAGS+= -fno-omit-frame-pointer -DCRT_IRELOC_RELA +CFLAGS+= -fno-omit-frame-pointer .include diff --git a/lib/csu/amd64/crt1_c.c b/lib/csu/amd64/crt1_c.c --- a/lib/csu/amd64/crt1_c.c +++ b/lib/csu/amd64/crt1_c.c @@ -29,19 +29,10 @@ #include __FBSDID("$FreeBSD$"); -#include - #include "libc_private.h" -#include "ignore_init.c" - -#ifdef GCRT -extern void _mcleanup(void); -extern void monstartup(void *, void *); -extern int eprol; -extern int etext; -#endif +#include "csu_common.h" -void _start(char **, void (*)(void)); +void _start(char **, void (*)(void)) __dead2; /* The entry function. */ void @@ -54,21 +45,10 @@ argc = *(long *)(void *)ap; argv = ap + 1; env = ap + 2 + argc; - handle_argv(argc, argv, env); - - if (&_DYNAMIC != NULL) { - atexit(cleanup); - } else { - process_irelocs(); - _init_tls(); - } - #ifdef GCRT - atexit(_mcleanup); - monstartup(&eprol, &etext); + __libc_start1_gcrt(argc, argv, env, cleanup, main, &eprol, &etext); __asm__("eprol:"); +#else + __libc_start1(argc, argv, env, cleanup, main); #endif - - handle_static_init(argc, argv, env); - exit(main(argc, argv, env)); } diff --git a/lib/csu/arm/Makefile b/lib/csu/arm/Makefile --- a/lib/csu/arm/Makefile +++ b/lib/csu/arm/Makefile @@ -2,8 +2,6 @@ .PATH: ${.CURDIR:H}/common -CFLAGS+= -DCRT_IRELOC_SUPPRESS - CRT1OBJS+= crt1_s.o .include diff --git a/lib/csu/arm/crt1_c.c b/lib/csu/arm/crt1_c.c --- a/lib/csu/arm/crt1_c.c +++ b/lib/csu/arm/crt1_c.c @@ -46,50 +46,33 @@ #include #include -#include #include "libc_private.h" -#include "ignore_init.c" +#include "csu_common.h" struct Struct_Obj_Entry; struct ps_strings; -extern void _start(int, char **, char **, const struct Struct_Obj_Entry *, - void (*)(void), struct ps_strings *); - -#ifdef GCRT -extern void _mcleanup(void); -extern void monstartup(void *, void *); -extern int eprol; -extern int etext; -#endif +void _start(int, char **, char **, const struct Struct_Obj_Entry *, + void (*)(void), struct ps_strings *) __dead2; struct ps_strings *__ps_strings; void __start(int, char **, char **, struct ps_strings *, - const struct Struct_Obj_Entry *, void (*)(void)); + const struct Struct_Obj_Entry *, void (*)(void)) __dead2; -/* ARGSUSED */ void __start(int argc, char **argv, char **env, struct ps_strings *ps_strings, const struct Struct_Obj_Entry *obj __unused, void (*cleanup)(void)) { - - handle_argv(argc, argv, env); - if (ps_strings != (struct ps_strings *)0) __ps_strings = ps_strings; - if (&_DYNAMIC != NULL) - atexit(cleanup); - else - _init_tls(); #ifdef GCRT - atexit(_mcleanup); - monstartup(&eprol, &etext); + __libc_start1_gcrt(argc, argv, env, cleanup, main, &eprol, &etext); +#else + __libc_start1(argc, argv, env, cleanup, main); #endif - handle_static_init(argc, argv, env); - exit(main(argc, argv, env)); } #ifdef GCRT diff --git a/lib/csu/amd64/crt1_c.c b/lib/csu/common/csu_common.h copy from lib/csu/amd64/crt1_c.c copy to lib/csu/common/csu_common.h --- a/lib/csu/amd64/crt1_c.c +++ b/lib/csu/common/csu_common.h @@ -1,4 +1,3 @@ -/* LINTLIBRARY */ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * @@ -26,49 +25,26 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -__FBSDID("$FreeBSD$"); +#ifdef _CSU_COMMON_H_ -#include +/* + * This file includes both definitions and declarations, it can be + * included only into one compilation unit for csu objects. We cannot + * practically check this, but at least guard against + * double-inclusion. + */ +#error "Include this file only once" +#else +#define _CSU_COMMON_H_ -#include "libc_private.h" -#include "ignore_init.c" +char **environ; +const char *__progname = ""; #ifdef GCRT -extern void _mcleanup(void); -extern void monstartup(void *, void *); extern int eprol; extern int etext; #endif -void _start(char **, void (*)(void)); - -/* The entry function. */ -void -_start(char **ap, void (*cleanup)(void)) -{ - int argc; - char **argv; - char **env; - - argc = *(long *)(void *)ap; - argv = ap + 1; - env = ap + 2 + argc; - handle_argv(argc, argv, env); - - if (&_DYNAMIC != NULL) { - atexit(cleanup); - } else { - process_irelocs(); - _init_tls(); - } - -#ifdef GCRT - atexit(_mcleanup); - monstartup(&eprol, &etext); -__asm__("eprol:"); -#endif +int main(int, char **, char **); - handle_static_init(argc, argv, env); - exit(main(argc, argv, env)); -} +#endif /* _CSU_COMMON_H_ */ diff --git a/lib/csu/i386/Makefile b/lib/csu/i386/Makefile --- a/lib/csu/i386/Makefile +++ b/lib/csu/i386/Makefile @@ -3,7 +3,6 @@ .PATH: ${.CURDIR:H}/common CFLAGS+= -I${.CURDIR} -CFLAGS+= -DCRT_IRELOC_REL CRT1OBJS+= crt1_s.o diff --git a/lib/csu/i386/crt1_c.c b/lib/csu/i386/crt1_c.c --- a/lib/csu/i386/crt1_c.c +++ b/lib/csu/i386/crt1_c.c @@ -29,20 +29,10 @@ #include __FBSDID("$FreeBSD$"); -#include - #include "libc_private.h" -#include "ignore_init.c" - -extern void _start(char *, ...); - -#ifdef GCRT -extern void _mcleanup(void); -extern void monstartup(void *, void *); -extern int eprol; -extern int etext; -#endif +#include "csu_common.h" +void _start(char *, ...); void _start1(void (*)(void), int, char *[]) __dead2; /* The entry function, C part. */ @@ -52,22 +42,12 @@ char **env; env = argv + argc + 1; - handle_argv(argc, argv, env); - if (&_DYNAMIC != NULL) { - atexit(cleanup); - } else { - process_irelocs(); - _init_tls(); - } - #ifdef GCRT - atexit(_mcleanup); - monstartup(&eprol, &etext); + __libc_start1_gcrt(argc, argv, env, cleanup, main, &eprol, &etext); __asm__("eprol:"); +#else + __libc_start1(argc, argv, env, cleanup, main); #endif - - handle_static_init(argc, argv, env); - exit(main(argc, argv, env)); } __asm(".hidden _start1"); diff --git a/lib/csu/powerpc/Makefile b/lib/csu/powerpc/Makefile --- a/lib/csu/powerpc/Makefile +++ b/lib/csu/powerpc/Makefile @@ -3,6 +3,5 @@ .PATH: ${.CURDIR:H}/common OBJS+= crtsavres.o -CFLAGS+= -DCRT_IRELOC_SUPPRESS .include diff --git a/lib/csu/powerpc/crt1_c.c b/lib/csu/powerpc/crt1_c.c --- a/lib/csu/powerpc/crt1_c.c +++ b/lib/csu/powerpc/crt1_c.c @@ -47,22 +47,15 @@ #include #include "libc_private.h" -#include "ignore_init.c" +#include "csu_common.h" struct Struct_Obj_Entry; struct ps_strings; -#ifdef GCRT -extern void _mcleanup(void); -extern void monstartup(void *, void *); -extern int eprol; -extern int etext; -#endif - struct ps_strings *__ps_strings; void _start(int, char **, char **, const struct Struct_Obj_Entry *, - void (*)(void), struct ps_strings *); + void (*)(void), struct ps_strings *) __dead2; /* The entry function. */ /* @@ -75,25 +68,14 @@ const struct Struct_Obj_Entry *obj __unused, void (*cleanup)(void), struct ps_strings *ps_strings) { - - - handle_argv(argc, argv, env); - if (ps_strings != (struct ps_strings *)0) __ps_strings = ps_strings; - if (&_DYNAMIC != NULL) - atexit(cleanup); - else - _init_tls(); - #ifdef GCRT - atexit(_mcleanup); - monstartup(&eprol, &etext); + __libc_start1_gcrt(argc, argv, env, cleanup, main, &eprol, &etext); +#else + __libc_start1(argc, argv, env, cleanup, main); #endif - - handle_static_init(argc, argv, env); - exit(main(argc, argv, env)); } #ifdef GCRT diff --git a/lib/csu/powerpc64/Makefile b/lib/csu/powerpc64/Makefile --- a/lib/csu/powerpc64/Makefile +++ b/lib/csu/powerpc64/Makefile @@ -4,7 +4,7 @@ OBJS+= crtsavres.o CFLAGS+= -I${.CURDIR} \ - -mlongcall -DCRT_IRELOC_RELA + -mlongcall CLEANFILES+= crtsavres.S diff --git a/lib/csu/powerpc64/crt1_c.c b/lib/csu/powerpc64/crt1_c.c --- a/lib/csu/powerpc64/crt1_c.c +++ b/lib/csu/powerpc64/crt1_c.c @@ -44,87 +44,38 @@ #include __FBSDID("$FreeBSD$"); -#include #include #include -static uint32_t cpu_features; -static uint32_t cpu_features2; - #include "libc_private.h" -#include "ignore_init.c" +#include "csu_common.h" struct Struct_Obj_Entry; struct ps_strings; -extern void _start(int, char **, char **, const struct Struct_Obj_Entry *, - void (*)(void), struct ps_strings *); - -#ifdef GCRT -extern void _mcleanup(void); -extern void monstartup(void *, void *); -extern int eprol; -extern int etext; -#endif +void _start(int, char **, char **, const struct Struct_Obj_Entry *, + void (*)(void), struct ps_strings *) __dead2; struct ps_strings *__ps_strings; -static void -init_cpu_features(char **env) -{ - const Elf_Auxinfo *aux; - - /* Find the auxiliary vector on the stack. */ - while (*env++ != 0) /* Skip over environment, and NULL terminator */ - ; - aux = (const Elf_Auxinfo *)env; - - /* Digest the auxiliary vector. */ - for (; aux->a_type != AT_NULL; aux++) { - switch (aux->a_type) { - case AT_HWCAP: - cpu_features = (uint32_t)aux->a_un.a_val; - break; - case AT_HWCAP2: - cpu_features2 = (uint32_t)aux->a_un.a_val; - break; - } - } -} - - /* The entry function. */ /* * First 5 arguments are specified by the PowerPC SVR4 ABI. * The last argument, ps_strings, is a BSD extension. */ -/* ARGSUSED */ void _start(int argc, char **argv, char **env, const struct Struct_Obj_Entry *obj __unused, void (*cleanup)(void), struct ps_strings *ps_strings) { - - handle_argv(argc, argv, env); - if (ps_strings != (struct ps_strings *)0) __ps_strings = ps_strings; - if (&_DYNAMIC != NULL) - atexit(cleanup); - else { - init_cpu_features(env); - process_irelocs(); - _init_tls(); - } - #ifdef GCRT - atexit(_mcleanup); - monstartup(&eprol, &etext); + __libc_start1_gcrt(argc, argv, env, cleanup, main, &eprol, &etext); +#else + __libc_start1(argc, argv, env, cleanup, main); #endif - - handle_static_init(argc, argv, env); - exit(main(argc, argv, env)); } #ifdef GCRT diff --git a/lib/csu/riscv/Makefile b/lib/csu/riscv/Makefile --- a/lib/csu/riscv/Makefile +++ b/lib/csu/riscv/Makefile @@ -2,8 +2,6 @@ .PATH: ${.CURDIR:H}/common -CFLAGS+= -DCRT_IRELOC_SUPPRESS - CRT1OBJS+= crt1_s.o .include diff --git a/lib/csu/riscv/crt1_c.c b/lib/csu/riscv/crt1_c.c --- a/lib/csu/riscv/crt1_c.c +++ b/lib/csu/riscv/crt1_c.c @@ -36,37 +36,18 @@ #include __FBSDID("$FreeBSD$"); -#include - #include "libc_private.h" -#include "ignore_init.c" - -#ifdef GCRT -extern void _mcleanup(void); -extern void monstartup(void *, void *); -extern int eprol; -extern int etext; -#endif +#include "csu_common.h" -void __start(int argc, char **argv, char **env, void (*cleanup)(void)); +void __start(int argc, char **argv, char **env, void (*cleanup)(void)) __dead2; void __start(int argc, char **argv, char **env, void (*cleanup)(void)) { - - handle_argv(argc, argv, env); - - if (&_DYNAMIC != NULL) - atexit(cleanup); - else - _init_tls(); - #ifdef GCRT - atexit(_mcleanup); - monstartup(&eprol, &etext); + __libc_start1_gcrt(argc, argv, env, cleanup, main, &eprol, &etext); __asm__("eprol:"); +#else + __libc_start1(argc, argv, env, cleanup, main); #endif - - handle_static_init(argc, argv, env); - exit(main(argc, argv, env)); } diff --git a/lib/libc/Makefile b/lib/libc/Makefile --- a/lib/libc/Makefile +++ b/lib/libc/Makefile @@ -93,6 +93,7 @@ NOASM= .include "${LIBC_SRCTOP}/${LIBC_ARCH}/Makefile.inc" +.include "${LIBC_SRCTOP}/csu/Makefile.inc" .include "${LIBC_SRCTOP}/db/Makefile.inc" .include "${LIBC_SRCTOP}/compat-43/Makefile.inc" .include "${LIBC_SRCTOP}/gdtoa/Makefile.inc" diff --git a/lib/libc/csu/Makefile.inc b/lib/libc/csu/Makefile.inc new file mode 100644 --- /dev/null +++ b/lib/libc/csu/Makefile.inc @@ -0,0 +1,10 @@ +# + +.PATH: ${LIBC_SRCTOP}/csu +.include "${LIBC_SRCTOP}/csu/${LIBC_ARCH}/Makefile.inc" + +SRCS+= \ + ignore_init.c + +CFLAGS+= -I${LIBC_SRCTOP}/csu/${LIBC_ARCH} +SYM_MAPS+=${LIBC_SRCTOP}/csu/Symbol.map diff --git a/lib/libc/csu/Symbol.map b/lib/libc/csu/Symbol.map new file mode 100644 --- /dev/null +++ b/lib/libc/csu/Symbol.map @@ -0,0 +1,4 @@ +FBSD_1.7 { + __libc_start1; + __libc_start1_gcrt; +}; diff --git a/lib/libc/csu/aarch64/Makefile.inc b/lib/libc/csu/aarch64/Makefile.inc new file mode 100644 --- /dev/null +++ b/lib/libc/csu/aarch64/Makefile.inc @@ -0,0 +1,4 @@ +# + +CFLAGS+= -DCRT_IRELOC_RELA \ + -DINIT_IRELOCS="" diff --git a/lib/csu/aarch64/reloc.c b/lib/libc/csu/aarch64/reloc.c rename from lib/csu/aarch64/reloc.c rename to lib/libc/csu/aarch64/reloc.c diff --git a/lib/libc/csu/amd64/Makefile.inc b/lib/libc/csu/amd64/Makefile.inc new file mode 100644 --- /dev/null +++ b/lib/libc/csu/amd64/Makefile.inc @@ -0,0 +1,4 @@ +# + +CFLAGS+= -DCRT_IRELOC_RELA \ + -DINIT_IRELOCS="" diff --git a/lib/csu/amd64/reloc.c b/lib/libc/csu/amd64/reloc.c rename from lib/csu/amd64/reloc.c rename to lib/libc/csu/amd64/reloc.c diff --git a/lib/libc/csu/arm/Makefile.inc b/lib/libc/csu/arm/Makefile.inc new file mode 100644 --- /dev/null +++ b/lib/libc/csu/arm/Makefile.inc @@ -0,0 +1,4 @@ +# + +CFLAGS+= -DCRT_IRELOC_SUPPRESS \ + -DINIT_IRELOCS="" diff --git a/lib/libc/csu/i386/Makefile.inc b/lib/libc/csu/i386/Makefile.inc new file mode 100644 --- /dev/null +++ b/lib/libc/csu/i386/Makefile.inc @@ -0,0 +1,4 @@ +# + +CFLAGS+= -DCRT_IRELOC_REL \ + -DINIT_IRELOCS="" diff --git a/lib/csu/i386/reloc.c b/lib/libc/csu/i386/reloc.c rename from lib/csu/i386/reloc.c rename to lib/libc/csu/i386/reloc.c diff --git a/lib/csu/common/ignore_init.c b/lib/libc/csu/ignore_init.c rename from lib/csu/common/ignore_init.c rename to lib/libc/csu/ignore_init.c --- a/lib/csu/common/ignore_init.c +++ b/lib/libc/csu/ignore_init.c @@ -2,7 +2,7 @@ * SPDX-License-Identifier: BSD-1-Clause * * Copyright 2012 Konstantin Belousov - * Copyright (c) 2018 The FreeBSD Foundation + * Copyright (c) 2018, 2023 The FreeBSD Foundation * * Parts of this software was developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. @@ -25,14 +25,11 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -__FBSDID("$FreeBSD$"); - #include #include #include - -extern int main(int, char **, char **); +#include +#include "libc_private.h" extern void (*__preinit_array_start[])(int, char **, char **) __hidden; extern void (*__preinit_array_end[])(int, char **, char **) __hidden; @@ -79,9 +76,6 @@ #error "Define platform reloc type" #endif -char **environ; -const char *__progname = ""; - static void finalizer(void) { @@ -97,7 +91,7 @@ _fini(); } -static inline void +static void handle_static_init(int argc, char **argv, char **env) { void (*fn)(int, char **, char **); @@ -123,7 +117,9 @@ } } -static inline void +extern char **environ; + +static void handle_argv(int argc, char *argv[], char **env) { const char *s; @@ -138,3 +134,51 @@ } } } + +void +__libc_start1(int argc, char *argv[], char *env[], void (*cleanup)(void), + int (*mainX)(int, char *[], char *[])) +{ + handle_argv(argc, argv, env); + + if (&_DYNAMIC != NULL) { + atexit(cleanup); + } else { +#ifndef CRT_IRELOC_SUPPRESS + INIT_IRELOCS; + process_irelocs(); +#endif + _init_tls(); + } + + handle_static_init(argc, argv, env); + exit(mainX(argc, argv, env)); +} + +/* XXXKIB _mcleanup and monstartup defs */ +extern void _mcleanup(void); +extern void monstartup(void *, void *); + +void +__libc_start1_gcrt(int argc, char *argv[], char *env[], + void (*cleanup)(void), int (*mainX)(int, char *[], char *[]), + int *eprolp, int *etextp) +{ + handle_argv(argc, argv, env); + + if (&_DYNAMIC != NULL) { + atexit(cleanup); + } else { +#ifndef CRT_IRELOC_SUPPRESS + INIT_IRELOCS; + process_irelocs(); +#endif + _init_tls(); + } + + atexit(_mcleanup); + monstartup(eprolp, etextp); + + handle_static_init(argc, argv, env); + exit(mainX(argc, argv, env)); +} diff --git a/lib/libc/csu/powerpc/Makefile.inc b/lib/libc/csu/powerpc/Makefile.inc new file mode 100644 --- /dev/null +++ b/lib/libc/csu/powerpc/Makefile.inc @@ -0,0 +1,4 @@ +# + +CFLAGS+= -DCRT_IRELOC_SUPPRESS \ + -DINIT_IRELOCS="" diff --git a/lib/libc/csu/powerpc64/Makefile.inc b/lib/libc/csu/powerpc64/Makefile.inc new file mode 100644 --- /dev/null +++ b/lib/libc/csu/powerpc64/Makefile.inc @@ -0,0 +1,4 @@ +# + +CFLAGS+= -DCRT_IRELOC_RELA \ + -DINIT_IRELOCS="init_cpu_features(env)" diff --git a/lib/csu/powerpc64/reloc.c b/lib/libc/csu/powerpc64/reloc.c rename from lib/csu/powerpc64/reloc.c rename to lib/libc/csu/powerpc64/reloc.c --- a/lib/csu/powerpc64/reloc.c +++ b/lib/libc/csu/powerpc64/reloc.c @@ -23,6 +23,32 @@ #include __FBSDID("$FreeBSD$"); +static uint32_t cpu_features; +static uint32_t cpu_features2; + +static void +init_cpu_features(char **env) +{ + const Elf_Auxinfo *aux; + + /* Find the auxiliary vector on the stack. */ + while (*env++ != 0) /* Skip over environment, and NULL terminator */ + ; + aux = (const Elf_Auxinfo *)env; + + /* Digest the auxiliary vector. */ + for (; aux->a_type != AT_NULL; aux++) { + switch (aux->a_type) { + case AT_HWCAP: + cpu_features = (uint32_t)aux->a_un.a_val; + break; + case AT_HWCAP2: + cpu_features2 = (uint32_t)aux->a_un.a_val; + break; + } + } +} + static void crt1_handle_rela(const Elf_Rela *r) { diff --git a/lib/libc/csu/riscv/Makefile.inc b/lib/libc/csu/riscv/Makefile.inc new file mode 100644 --- /dev/null +++ b/lib/libc/csu/riscv/Makefile.inc @@ -0,0 +1,4 @@ +# + +CFLAGS+= -DCRT_IRELOC_SUPPRESS \ + -DINIT_IRELOCS="" diff --git a/lib/libc/include/libc_private.h b/lib/libc/include/libc_private.h --- a/lib/libc/include/libc_private.h +++ b/lib/libc/include/libc_private.h @@ -255,6 +255,12 @@ int _yp_check(char **); #endif +void __libc_start1(int, char *[], char *[], + void (*)(void), int (*)(int, char *[], char *[])) __dead2; +void __libc_start1_gcrt(int, char *[], char *[], + void (*)(void), int (*)(int, char *[], char *[]), + int *, int *) __dead2; + /* * Initialise TLS for static programs */