From nobody Mon Jun 12 12:22:26 2023 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4QfrRQ3P2jz4d9g3; Mon, 12 Jun 2023 12:22:26 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4QfrRQ32gcz3qbM; Mon, 12 Jun 2023 12:22:26 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1686572546; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=a2FR4ZmJrImEsAT0Df/nDeMjxVWl6FZG+w4bIb1GvdQ=; b=wujQ7YRA2TnvFt3DbONH3/ncqBJzuyW74maUfjKJ3YisoRDto/2gVtz/3Mhad/BIGDnISK OWYSNdoNERt9PjvjFGMXNV6jDJzkvl62v5QYxRPbP1Kzvx1T5Z53y5mXhIAdDnMqEsewtP zxcGNWw2LmjxCoSN34XYcIwe3iUFwbqZdpMOiRkNq4hFxPVL+8/w7lZbqCCEtz9T+V28qt J/hrFo+KkAobnJcE8Sv7qCdh4D18Ya6Ih8IB+ZfnS+rvzGD6AAYl1pan/3jX88mjJhanoy 1FMA0+7njkEZ/Md1Ca+qSgiC40jD1qOjKCQ3ZravTPtmGD9Dy6ta9XsChDEbWw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1686572546; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=a2FR4ZmJrImEsAT0Df/nDeMjxVWl6FZG+w4bIb1GvdQ=; b=wPCJgWfYAb2LVqUhbjSwmG+EKk+JGZZOtsh7rzTA9NZHp4DqineqjF06fGWLnWXzkybA1r SD66tPc7rHqfnlsFqmv71WRCTEz3CUc1UgkhHcXxF1w501vKxV/2afyxn4D1KeMnz60kLf IX0cR5PzjVqwG/l83oNHBaK60bmXVj3CuMQqkLd4gFBCfaBJ/kylX21Exq7ngfeqakROP5 PxcefXsL+Qk2r0UP6aPQ0CouEjub9W3KJNEQ6s9Z/6FTEgB1l0o9G5cS9OoH5Q3EljWuCP RTzRtTxLzarHiQIjqICpd0FnWlnNgIEdYan/vI1se/N/nyBjlfq+IgoCYaoKPw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1686572546; a=rsa-sha256; cv=none; b=dYns0llwypLpPW2Y0Ke5YukFeklXsknpI+6KmpIlvxS4dKXBQ4W1HNheQAiXUOeS5RVfII qXFMWhMTAWchxVb43cLMJLhO8UdlyQC7OMvbeZVIBV1QOofoxKA4urmZbqfz0avRK2QoS+ gevHAVr97Nh55DRAdZCcMY+ZvF88AhA3Th0vuLS0kMfVnFO484AYPm26TUtJSt0RDBQWxb TMnG2QUuG+/vWVyqbovV6Se/coPBGuqoHzQsqCVpaA9maFhEfkRgPwWl3RoqwbvfsKzVUC Fm3Ztm+lgF3kzSaKUvJMEi5EoVLHjiZjUrpV4Ax01GJHJivslQb0pcztEKrMPA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4QfrRQ1tVDzfwj; Mon, 12 Jun 2023 12:22:26 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 35CCMQE0048014; Mon, 12 Jun 2023 12:22:26 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 35CCMQtw048013; Mon, 12 Jun 2023 12:22:26 GMT (envelope-from git) Date: Mon, 12 Jun 2023 12:22:26 GMT Message-Id: <202306121222.35CCMQtw048013@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Konstantin Belousov Subject: git: aea1d51e854e - stable/13 - csu: move common code to libc List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: aea1d51e854e06565b609d4fb065787d7d8328b4 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=aea1d51e854e06565b609d4fb065787d7d8328b4 commit aea1d51e854e06565b609d4fb065787d7d8328b4 Author: Konstantin Belousov AuthorDate: 2022-10-30 23:47:44 +0000 Commit: Konstantin Belousov CommitDate: 2023-06-12 12:19:38 +0000 csu: move common code to libc For MFC purposes, keep lib/csu code intact, only add lib/libc/csu bits. This allows stable/13 to run simple binaries compiled on 14. (cherry picked from commit 51015e6d0f570239b0c2088dc6cf2b018928375d) --- lib/libc/Makefile | 1 + lib/libc/csu/Makefile.inc | 10 ++ lib/libc/csu/Symbol.map | 4 + lib/libc/csu/aarch64/Makefile.inc | 4 + lib/libc/csu/aarch64/reloc.c | 46 +++++++++ lib/libc/csu/amd64/Makefile.inc | 4 + lib/libc/csu/amd64/reloc.c | 63 ++++++++++++ lib/libc/csu/arm/Makefile.inc | 4 + lib/libc/csu/i386/Makefile.inc | 4 + lib/libc/csu/i386/reloc.c | 85 +++++++++++++++++ lib/libc/csu/ignore_init.c | 184 ++++++++++++++++++++++++++++++++++++ lib/libc/csu/mips/Makefile.inc | 4 + lib/libc/csu/powerpc/Makefile.inc | 4 + lib/libc/csu/powerpc64/Makefile.inc | 4 + lib/libc/csu/powerpc64/reloc.c | 69 ++++++++++++++ lib/libc/csu/riscv/Makefile.inc | 4 + lib/libc/include/libc_private.h | 6 ++ 17 files changed, 500 insertions(+) diff --git a/lib/libc/Makefile b/lib/libc/Makefile index 6363cef8d48b..43efccba08dd 100644 --- a/lib/libc/Makefile +++ b/lib/libc/Makefile @@ -93,6 +93,7 @@ MIASM= 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 index 000000000000..453303bea608 --- /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 index 000000000000..7fc09add5e45 --- /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 index 000000000000..b3420a638164 --- /dev/null +++ b/lib/libc/csu/aarch64/Makefile.inc @@ -0,0 +1,4 @@ +# + +CFLAGS+= -DCRT_IRELOC_RELA \ + -DINIT_IRELOCS="" diff --git a/lib/libc/csu/aarch64/reloc.c b/lib/libc/csu/aarch64/reloc.c new file mode 100644 index 000000000000..f3dbf3e3b570 --- /dev/null +++ b/lib/libc/csu/aarch64/reloc.c @@ -0,0 +1,46 @@ +/*- + * Copyright (c) 2019 Leandro Lupori + * Copyright (c) 2021 The FreeBSD Foundation + * + * Portions of this software were developed by Andrew Turner + * under sponsorship from the FreeBSD Foundation. + * + * 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. + */ + +#include +__FBSDID("$FreeBSD$"); + +static void +crt1_handle_rela(const Elf_Rela *r) +{ + typedef Elf_Addr (*ifunc_resolver_t)( + uint64_t, uint64_t, uint64_t, uint64_t, + uint64_t, uint64_t, uint64_t, uint64_t); + Elf_Addr *ptr, *where, target; + + switch (ELF_R_TYPE(r->r_info)) { + case R_AARCH64_IRELATIVE: + ptr = (Elf_Addr *)r->r_addend; + where = (Elf_Addr *)r->r_offset; + target = ((ifunc_resolver_t)ptr)(0, 0, 0, 0, 0, 0, 0, 0); + *where = target; + break; + } +} diff --git a/lib/libc/csu/amd64/Makefile.inc b/lib/libc/csu/amd64/Makefile.inc new file mode 100644 index 000000000000..b3420a638164 --- /dev/null +++ b/lib/libc/csu/amd64/Makefile.inc @@ -0,0 +1,4 @@ +# + +CFLAGS+= -DCRT_IRELOC_RELA \ + -DINIT_IRELOCS="" diff --git a/lib/libc/csu/amd64/reloc.c b/lib/libc/csu/amd64/reloc.c new file mode 100644 index 000000000000..adb52e42a32c --- /dev/null +++ b/lib/libc/csu/amd64/reloc.c @@ -0,0 +1,63 @@ +/*- + * Copyright (c) 2018 The FreeBSD Foundation + * + * This software was developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * 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. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +static void +crt1_handle_rela(const Elf_Rela *r) +{ + Elf_Addr *ptr, *where, target; + u_int p[4]; + uint32_t cpu_feature, cpu_feature2; + uint32_t cpu_stdext_feature, cpu_stdext_feature2; + + do_cpuid(1, p); + cpu_feature = p[3]; + cpu_feature2 = p[2]; + do_cpuid(0, p); + if (p[0] >= 7) { + cpuid_count(7, 0, p); + cpu_stdext_feature = p[1]; + cpu_stdext_feature2 = p[2]; + } else { + cpu_stdext_feature = 0; + cpu_stdext_feature2 = 0; + } + + switch (ELF_R_TYPE(r->r_info)) { + case R_X86_64_IRELATIVE: + ptr = (Elf_Addr *)r->r_addend; + where = (Elf_Addr *)r->r_offset; + target = ((Elf_Addr (*)(uint32_t, uint32_t, uint32_t, + uint32_t))ptr)(cpu_feature, cpu_feature2, + cpu_stdext_feature, cpu_stdext_feature2); + *where = target; + break; + } +} diff --git a/lib/libc/csu/arm/Makefile.inc b/lib/libc/csu/arm/Makefile.inc new file mode 100644 index 000000000000..2534e6579f38 --- /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 index 000000000000..ac0984df2349 --- /dev/null +++ b/lib/libc/csu/i386/Makefile.inc @@ -0,0 +1,4 @@ +# + +CFLAGS+= -DCRT_IRELOC_REL \ + -DINIT_IRELOCS="" diff --git a/lib/libc/csu/i386/reloc.c b/lib/libc/csu/i386/reloc.c new file mode 100644 index 000000000000..13438035841d --- /dev/null +++ b/lib/libc/csu/i386/reloc.c @@ -0,0 +1,85 @@ +/*- + * Copyright (c) 2018 The FreeBSD Foundation + * + * This software was developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * 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. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +static void +crt1_handle_rel(const Elf_Rel *r) +{ + Elf_Addr *where, target; + u_int cpuid_supported, p[4]; + uint32_t cpu_feature, cpu_feature2; + uint32_t cpu_stdext_feature, cpu_stdext_feature2; + + __asm __volatile( + " pushfl\n" + " popl %%eax\n" + " movl %%eax,%%ecx\n" + " xorl $0x200000,%%eax\n" + " pushl %%eax\n" + " popfl\n" + " pushfl\n" + " popl %%eax\n" + " xorl %%eax,%%ecx\n" + " je 1f\n" + " movl $1,%0\n" + " jmp 2f\n" + "1: movl $0,%0\n" + "2:\n" + : "=r" (cpuid_supported) : : "eax", "ecx", "cc"); + if (cpuid_supported) { + do_cpuid(1, p); + cpu_feature = p[3]; + cpu_feature2 = p[2]; + do_cpuid(0, p); + if (p[0] >= 7) { + cpuid_count(7, 0, p); + cpu_stdext_feature = p[1]; + cpu_stdext_feature2 = p[2]; + } else { + cpu_stdext_feature = 0; + cpu_stdext_feature2 = 0; + } + } else { + cpu_feature = 0; + cpu_feature2 = 0; + cpu_stdext_feature = 0; + cpu_stdext_feature2 = 0; + } + + switch (ELF_R_TYPE(r->r_info)) { + case R_386_IRELATIVE: + where = (Elf_Addr *)r->r_offset; + target = ((Elf_Addr (*)(uint32_t, uint32_t, uint32_t, + uint32_t))*where)(cpu_feature, cpu_feature2, + cpu_stdext_feature, cpu_stdext_feature2); + *where = target; + break; + } +} diff --git a/lib/libc/csu/ignore_init.c b/lib/libc/csu/ignore_init.c new file mode 100644 index 000000000000..60c45d7e735f --- /dev/null +++ b/lib/libc/csu/ignore_init.c @@ -0,0 +1,184 @@ +/*- + * SPDX-License-Identifier: BSD-1-Clause + * + * Copyright 2012 Konstantin Belousov + * Copyright (c) 2018, 2023 The FreeBSD Foundation + * + * Parts of this software was developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * 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 ``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 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. + */ + +#include +#include +#include +#include +#include "libc_private.h" + +extern void (*__preinit_array_start[])(int, char **, char **) __hidden; +extern void (*__preinit_array_end[])(int, char **, char **) __hidden; +extern void (*__init_array_start[])(int, char **, char **) __hidden; +extern void (*__init_array_end[])(int, char **, char **) __hidden; +extern void (*__fini_array_start[])(void) __hidden; +extern void (*__fini_array_end[])(void) __hidden; +extern void _fini(void) __hidden; +extern void _init(void) __hidden; + +extern int _DYNAMIC; +#pragma weak _DYNAMIC + +#if defined(CRT_IRELOC_RELA) +extern const Elf_Rela __rela_iplt_start[] __weak_symbol __hidden; +extern const Elf_Rela __rela_iplt_end[] __weak_symbol __hidden; + +#include "reloc.c" + +static void +process_irelocs(void) +{ + const Elf_Rela *r; + + for (r = &__rela_iplt_start[0]; r < &__rela_iplt_end[0]; r++) + crt1_handle_rela(r); +} +#elif defined(CRT_IRELOC_REL) +extern const Elf_Rel __rel_iplt_start[] __weak_symbol __hidden; +extern const Elf_Rel __rel_iplt_end[] __weak_symbol __hidden; + +#include "reloc.c" + +static void +process_irelocs(void) +{ + const Elf_Rel *r; + + for (r = &__rel_iplt_start[0]; r < &__rel_iplt_end[0]; r++) + crt1_handle_rel(r); +} +#elif defined(CRT_IRELOC_SUPPRESS) +#else +#error "Define platform reloc type" +#endif + +static void +finalizer(void) +{ + void (*fn)(void); + size_t array_size, n; + + array_size = __fini_array_end - __fini_array_start; + for (n = array_size; n > 0; n--) { + fn = __fini_array_start[n - 1]; + if ((uintptr_t)fn != 0 && (uintptr_t)fn != 1) + (fn)(); + } + _fini(); +} + +static void +handle_static_init(int argc, char **argv, char **env) +{ + void (*fn)(int, char **, char **); + size_t array_size, n; + + if (&_DYNAMIC != NULL) + return; + + atexit(finalizer); + + array_size = __preinit_array_end - __preinit_array_start; + for (n = 0; n < array_size; n++) { + fn = __preinit_array_start[n]; + if ((uintptr_t)fn != 0 && (uintptr_t)fn != 1) + fn(argc, argv, env); + } + _init(); + array_size = __init_array_end - __init_array_start; + for (n = 0; n < array_size; n++) { + fn = __init_array_start[n]; + if ((uintptr_t)fn != 0 && (uintptr_t)fn != 1) + fn(argc, argv, env); + } +} + +extern char **environ; + +static void +handle_argv(int argc, char *argv[], char **env) +{ + const char *s; + + if (environ == NULL) + environ = env; + if (argc > 0 && argv[0] != NULL) { + __progname = argv[0]; + for (s = __progname; *s != '\0'; s++) { + if (*s == '/') + __progname = s + 1; + } + } +} + +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/mips/Makefile.inc b/lib/libc/csu/mips/Makefile.inc new file mode 100644 index 000000000000..2534e6579f38 --- /dev/null +++ b/lib/libc/csu/mips/Makefile.inc @@ -0,0 +1,4 @@ +# + +CFLAGS+= -DCRT_IRELOC_SUPPRESS \ + -DINIT_IRELOCS="" diff --git a/lib/libc/csu/powerpc/Makefile.inc b/lib/libc/csu/powerpc/Makefile.inc new file mode 100644 index 000000000000..2534e6579f38 --- /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 index 000000000000..5d59d40eb393 --- /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/libc/csu/powerpc64/reloc.c b/lib/libc/csu/powerpc64/reloc.c new file mode 100644 index 000000000000..5ba191d07cd9 --- /dev/null +++ b/lib/libc/csu/powerpc64/reloc.c @@ -0,0 +1,69 @@ +/*- + * Copyright (c) 2019 Leandro Lupori + * + * 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. + */ + +#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) +{ + typedef Elf_Addr (*ifunc_resolver_t)( + uint32_t, uint32_t, uint64_t, uint64_t, + uint64_t, uint64_t, uint64_t, uint64_t); + Elf_Addr *ptr, *where, target; + + switch (ELF_R_TYPE(r->r_info)) { + case R_PPC_IRELATIVE: + ptr = (Elf_Addr *)r->r_addend; + where = (Elf_Addr *)r->r_offset; + target = ((ifunc_resolver_t)ptr)(cpu_features, cpu_features2, + 0, 0, 0, 0, 0, 0); + *where = target; + break; + } +} diff --git a/lib/libc/csu/riscv/Makefile.inc b/lib/libc/csu/riscv/Makefile.inc new file mode 100644 index 000000000000..2534e6579f38 --- /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 index 78a75cc6284d..5fa7a6da1198 100644 --- a/lib/libc/include/libc_private.h +++ b/lib/libc/include/libc_private.h @@ -255,6 +255,12 @@ enum { 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 */