diff options
Diffstat (limited to 'lib/libc/csu')
-rw-r--r-- | lib/libc/csu/aarch64/Makefile.inc | 3 | ||||
-rw-r--r-- | lib/libc/csu/aarch64/reloc.c | 6 | ||||
-rw-r--r-- | lib/libc/csu/amd64/Makefile.inc | 3 | ||||
-rw-r--r-- | lib/libc/csu/amd64/reloc.c | 3 | ||||
-rw-r--r-- | lib/libc/csu/arm/Makefile.inc | 3 | ||||
-rw-r--r-- | lib/libc/csu/i386/Makefile.inc | 3 | ||||
-rw-r--r-- | lib/libc/csu/i386/reloc.c | 3 | ||||
-rw-r--r-- | lib/libc/csu/libc_start1.c | 37 | ||||
-rw-r--r-- | lib/libc/csu/powerpc/Makefile.inc | 3 | ||||
-rw-r--r-- | lib/libc/csu/powerpc64/Makefile.inc | 3 | ||||
-rw-r--r-- | lib/libc/csu/powerpc64/reloc.c | 10 | ||||
-rw-r--r-- | lib/libc/csu/powerpcspe/Makefile.inc | 3 | ||||
-rw-r--r-- | lib/libc/csu/riscv/Makefile.inc | 3 | ||||
-rw-r--r-- | lib/libc/csu/riscv/reloc.c | 56 |
14 files changed, 104 insertions, 35 deletions
diff --git a/lib/libc/csu/aarch64/Makefile.inc b/lib/libc/csu/aarch64/Makefile.inc index b3420a638164..6c315c5e2624 100644 --- a/lib/libc/csu/aarch64/Makefile.inc +++ b/lib/libc/csu/aarch64/Makefile.inc @@ -1,4 +1,3 @@ # -CFLAGS+= -DCRT_IRELOC_RELA \ - -DINIT_IRELOCS="" +CFLAGS+= -DCRT_IRELOC_RELA diff --git a/lib/libc/csu/aarch64/reloc.c b/lib/libc/csu/aarch64/reloc.c index 7f5dff497fe2..4ba7920bcb07 100644 --- a/lib/libc/csu/aarch64/reloc.c +++ b/lib/libc/csu/aarch64/reloc.c @@ -25,6 +25,12 @@ */ #include <sys/cdefs.h> + +static void +ifunc_init(const Elf_Auxinfo *aux __unused) +{ +} + static void crt1_handle_rela(const Elf_Rela *r) { diff --git a/lib/libc/csu/amd64/Makefile.inc b/lib/libc/csu/amd64/Makefile.inc index f14033217580..6c315c5e2624 100644 --- a/lib/libc/csu/amd64/Makefile.inc +++ b/lib/libc/csu/amd64/Makefile.inc @@ -1,4 +1,3 @@ # -CFLAGS+= -DCRT_IRELOC_RELA \ - -DINIT_IRELOCS="init_cpu_features()" +CFLAGS+= -DCRT_IRELOC_RELA diff --git a/lib/libc/csu/amd64/reloc.c b/lib/libc/csu/amd64/reloc.c index 654958819271..f1f83db9a391 100644 --- a/lib/libc/csu/amd64/reloc.c +++ b/lib/libc/csu/amd64/reloc.c @@ -24,6 +24,7 @@ */ #include <sys/cdefs.h> + #include <machine/specialreg.h> #include <machine/cpufunc.h> @@ -31,7 +32,7 @@ static uint32_t cpu_feature, cpu_feature2; static uint32_t cpu_stdext_feature, cpu_stdext_feature2; static void -init_cpu_features(void) +ifunc_init(const Elf_Auxinfo *aux __unused) { u_int p[4]; diff --git a/lib/libc/csu/arm/Makefile.inc b/lib/libc/csu/arm/Makefile.inc index 2534e6579f38..ddead75f874d 100644 --- a/lib/libc/csu/arm/Makefile.inc +++ b/lib/libc/csu/arm/Makefile.inc @@ -1,4 +1,3 @@ # -CFLAGS+= -DCRT_IRELOC_SUPPRESS \ - -DINIT_IRELOCS="" +CFLAGS+= -DCRT_IRELOC_SUPPRESS diff --git a/lib/libc/csu/i386/Makefile.inc b/lib/libc/csu/i386/Makefile.inc index f3f8c2b176ce..32018000e1f2 100644 --- a/lib/libc/csu/i386/Makefile.inc +++ b/lib/libc/csu/i386/Makefile.inc @@ -1,4 +1,3 @@ # -CFLAGS+= -DCRT_IRELOC_REL \ - -DINIT_IRELOCS="init_cpu_features()" +CFLAGS+= -DCRT_IRELOC_REL diff --git a/lib/libc/csu/i386/reloc.c b/lib/libc/csu/i386/reloc.c index d617f35dc665..7097f58d8f26 100644 --- a/lib/libc/csu/i386/reloc.c +++ b/lib/libc/csu/i386/reloc.c @@ -24,6 +24,7 @@ */ #include <sys/cdefs.h> + #include <machine/specialreg.h> #include <machine/cpufunc.h> @@ -31,7 +32,7 @@ static uint32_t cpu_feature, cpu_feature2; static uint32_t cpu_stdext_feature, cpu_stdext_feature2; static void -init_cpu_features(void) +ifunc_init(const Elf_Auxinfo *aux __unused) { u_int cpuid_supported, p[4]; diff --git a/lib/libc/csu/libc_start1.c b/lib/libc/csu/libc_start1.c index f0e708e405ce..5b08ba03ba8c 100644 --- a/lib/libc/csu/libc_start1.c +++ b/lib/libc/csu/libc_start1.c @@ -28,6 +28,7 @@ #include <sys/param.h> #include <sys/elf.h> #include <sys/elf_common.h> +#include <errno.h> #include <stdlib.h> #include "libc_private.h" @@ -137,6 +138,24 @@ handle_argv(int argc, char *argv[], char **env) } } +static void +handle_irelocs(char *env[]) +{ +#ifndef CRT_IRELOC_SUPPRESS + 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; + + ifunc_init(aux); + process_irelocs(); +#else + (void)env; +#endif +} + void __libc_start1(int argc, char *argv[], char *env[], void (*cleanup)(void), int (*mainX)(int, char *[], char *[])) @@ -146,14 +165,18 @@ __libc_start1(int argc, char *argv[], char *env[], void (*cleanup)(void), if (&_DYNAMIC != NULL) { atexit(cleanup); } else { -#ifndef CRT_IRELOC_SUPPRESS - INIT_IRELOCS; - process_irelocs(); -#endif + handle_irelocs(env); _init_tls(); } handle_static_init(argc, argv, env); + + /* + * C17 4.3 paragraph 3: + * The value of errno in the initial thread is zero at program + * startup. + */ + errno = 0; exit(mainX(argc, argv, env)); } @@ -171,10 +194,7 @@ __libc_start1_gcrt(int argc, char *argv[], char *env[], if (&_DYNAMIC != NULL) { atexit(cleanup); } else { -#ifndef CRT_IRELOC_SUPPRESS - INIT_IRELOCS; - process_irelocs(); -#endif + handle_irelocs(env); _init_tls(); } @@ -182,5 +202,6 @@ __libc_start1_gcrt(int argc, char *argv[], char *env[], monstartup(eprolp, etextp); handle_static_init(argc, argv, env); + errno = 0; exit(mainX(argc, argv, env)); } diff --git a/lib/libc/csu/powerpc/Makefile.inc b/lib/libc/csu/powerpc/Makefile.inc index 2534e6579f38..ddead75f874d 100644 --- a/lib/libc/csu/powerpc/Makefile.inc +++ b/lib/libc/csu/powerpc/Makefile.inc @@ -1,4 +1,3 @@ # -CFLAGS+= -DCRT_IRELOC_SUPPRESS \ - -DINIT_IRELOCS="" +CFLAGS+= -DCRT_IRELOC_SUPPRESS diff --git a/lib/libc/csu/powerpc64/Makefile.inc b/lib/libc/csu/powerpc64/Makefile.inc index 5d59d40eb393..6c315c5e2624 100644 --- a/lib/libc/csu/powerpc64/Makefile.inc +++ b/lib/libc/csu/powerpc64/Makefile.inc @@ -1,4 +1,3 @@ # -CFLAGS+= -DCRT_IRELOC_RELA \ - -DINIT_IRELOCS="init_cpu_features(env)" +CFLAGS+= -DCRT_IRELOC_RELA diff --git a/lib/libc/csu/powerpc64/reloc.c b/lib/libc/csu/powerpc64/reloc.c index 6201ba0f1fb5..5637e6534197 100644 --- a/lib/libc/csu/powerpc64/reloc.c +++ b/lib/libc/csu/powerpc64/reloc.c @@ -20,20 +20,12 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> static uint32_t cpu_features; static uint32_t cpu_features2; static void -init_cpu_features(char **env) +ifunc_init(const Elf_Auxinfo *aux) { - 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) { diff --git a/lib/libc/csu/powerpcspe/Makefile.inc b/lib/libc/csu/powerpcspe/Makefile.inc index 2534e6579f38..ddead75f874d 100644 --- a/lib/libc/csu/powerpcspe/Makefile.inc +++ b/lib/libc/csu/powerpcspe/Makefile.inc @@ -1,4 +1,3 @@ # -CFLAGS+= -DCRT_IRELOC_SUPPRESS \ - -DINIT_IRELOCS="" +CFLAGS+= -DCRT_IRELOC_SUPPRESS diff --git a/lib/libc/csu/riscv/Makefile.inc b/lib/libc/csu/riscv/Makefile.inc index 2534e6579f38..6c315c5e2624 100644 --- a/lib/libc/csu/riscv/Makefile.inc +++ b/lib/libc/csu/riscv/Makefile.inc @@ -1,4 +1,3 @@ # -CFLAGS+= -DCRT_IRELOC_SUPPRESS \ - -DINIT_IRELOCS="" +CFLAGS+= -DCRT_IRELOC_RELA diff --git a/lib/libc/csu/riscv/reloc.c b/lib/libc/csu/riscv/reloc.c new file mode 100644 index 000000000000..6ae85085089b --- /dev/null +++ b/lib/libc/csu/riscv/reloc.c @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 2019 Leandro Lupori + * Copyright (c) 2024 Jessica Clarke <jrtc27@FreeBSD.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +static unsigned long elf_hwcap; + +static void +ifunc_init(const Elf_Auxinfo *aux) +{ + /* Digest the auxiliary vector. */ + for (; aux->a_type != AT_NULL; aux++) { + switch (aux->a_type) { + case AT_HWCAP: + elf_hwcap = (uint32_t)aux->a_un.a_val; + break; + } + } +} + +static void +crt1_handle_rela(const Elf_Rela *r) +{ + typedef Elf_Addr (*ifunc_resolver_t)( + unsigned long, unsigned long, unsigned long, unsigned long, + unsigned long, unsigned long, unsigned long, unsigned long); + Elf_Addr *ptr, *where, target; + + switch (ELF_R_TYPE(r->r_info)) { + case R_RISCV_IRELATIVE: + ptr = (Elf_Addr *)r->r_addend; + where = (Elf_Addr *)r->r_offset; + target = ((ifunc_resolver_t)ptr)(elf_hwcap, + 0, 0, 0, 0, 0, 0, 0); + *where = target; + break; + } +} |