Date: Sat, 13 Oct 2018 23:52:55 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r339351 - in head/lib/csu: aarch64 amd64 arm common i386 mips powerpc powerpc64 riscv sparc64 Message-ID: <201810132352.w9DNqtQu098344@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Sat Oct 13 23:52:55 2018 New Revision: 339351 URL: https://svnweb.freebsd.org/changeset/base/339351 Log: Process irelocs for statically linked binaries from crt1 on x86. This makes statically linked binaries with ifuncs operational. Reported and tested by: mjg Reviewed by: emaste, markj Sponsored by: The FreeBSD Foundation Approved by: re (rgrimes) Differential revision: https://reviews.freebsd.org/D17363 Added: head/lib/csu/amd64/reloc.c (contents, props changed) head/lib/csu/i386/reloc.c (contents, props changed) Modified: head/lib/csu/aarch64/Makefile head/lib/csu/amd64/Makefile head/lib/csu/amd64/crt1.c head/lib/csu/arm/Makefile head/lib/csu/common/ignore_init.c head/lib/csu/i386/Makefile head/lib/csu/i386/crt1_c.c head/lib/csu/mips/Makefile head/lib/csu/powerpc/Makefile head/lib/csu/powerpc64/Makefile head/lib/csu/riscv/Makefile head/lib/csu/sparc64/Makefile Modified: head/lib/csu/aarch64/Makefile ============================================================================== --- head/lib/csu/aarch64/Makefile Sat Oct 13 21:26:07 2018 (r339350) +++ head/lib/csu/aarch64/Makefile Sat Oct 13 23:52:55 2018 (r339351) @@ -7,6 +7,7 @@ OBJS= ${SRCS:N*.h:R:S/$/.o/g} OBJS+= Scrt1.o gcrt1.o CFLAGS+= -I${.CURDIR:H}/common \ -I${SRCTOP}/lib/libc/include +CFLAGS+= -DCRT_IRELOC_SUPPRESS FILES= ${OBJS} FILESMODE= ${LIBMODE} Modified: head/lib/csu/amd64/Makefile ============================================================================== --- head/lib/csu/amd64/Makefile Sat Oct 13 21:26:07 2018 (r339350) +++ head/lib/csu/amd64/Makefile Sat Oct 13 23:52:55 2018 (r339351) @@ -5,9 +5,9 @@ SRCS= crt1.c crti.S crtn.S OBJS= ${SRCS:N*.h:R:S/$/.o/g} OBJS+= Scrt1.o gcrt1.o -CFLAGS+= -I${.CURDIR:H}/common \ +CFLAGS+= -I${.CURDIR} -I${.CURDIR:H}/common \ -I${SRCTOP}/lib/libc/include -CFLAGS+= -fno-omit-frame-pointer +CFLAGS+= -fno-omit-frame-pointer -DCRT_IRELOC_RELA FILES= ${OBJS} FILESMODE= ${LIBMODE} Modified: head/lib/csu/amd64/crt1.c ============================================================================== --- head/lib/csu/amd64/crt1.c Sat Oct 13 21:26:07 2018 (r339350) +++ head/lib/csu/amd64/crt1.c Sat Oct 13 23:52:55 2018 (r339351) @@ -59,10 +59,12 @@ _start(char **ap, void (*cleanup)(void)) env = ap + 2 + argc; handle_argv(argc, argv, env); - if (&_DYNAMIC != NULL) + if (&_DYNAMIC != NULL) { atexit(cleanup); - else + } else { + process_irelocs(); _init_tls(); + } #ifdef GCRT atexit(_mcleanup); Added: head/lib/csu/amd64/reloc.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/lib/csu/amd64/reloc.c Sat Oct 13 23:52:55 2018 (r339351) @@ -0,0 +1,66 @@ +/*- + * Copyright (c) 2018 The FreeBSD Foundation + * + * This software was developed by Konstantin Belousov <kib@FreeBSD.org> + * 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. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 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 <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <machine/specialreg.h> +#include <machine/cpufunc.h> + +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; + } +} Modified: head/lib/csu/arm/Makefile ============================================================================== --- head/lib/csu/arm/Makefile Sat Oct 13 21:26:07 2018 (r339350) +++ head/lib/csu/arm/Makefile Sat Oct 13 23:52:55 2018 (r339351) @@ -7,6 +7,7 @@ OBJS= ${SRCS:N*.h:R:S/$/.o/g} OBJS+= Scrt1.o gcrt1.o CFLAGS+= -I${.CURDIR:H}/common \ -I${SRCTOP}/lib/libc/include +CFLAGS+= -DCRT_IRELOC_SUPPRESS STATIC_CFLAGS+= -mlong-calls FILES= ${OBJS} Modified: head/lib/csu/common/ignore_init.c ============================================================================== --- head/lib/csu/common/ignore_init.c Sat Oct 13 21:26:07 2018 (r339350) +++ head/lib/csu/common/ignore_init.c Sat Oct 13 23:52:55 2018 (r339351) @@ -2,8 +2,11 @@ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright 2012 Konstantin Belousov <kib@FreeBSD.org> - * All rights reserved. + * Copyright (c) 2018 The FreeBSD Foundation * + * Parts of this software was developed by Konstantin Belousov + * <kib@FreeBSD.org> 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: @@ -29,7 +32,9 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> +#include <sys/elf.h> #include <sys/elf_common.h> + #include "notes.h" extern int main(int, char **, char **); @@ -45,6 +50,39 @@ 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 char **environ; const char *__progname = ""; Modified: head/lib/csu/i386/Makefile ============================================================================== --- head/lib/csu/i386/Makefile Sat Oct 13 21:26:07 2018 (r339350) +++ head/lib/csu/i386/Makefile Sat Oct 13 23:52:55 2018 (r339351) @@ -5,8 +5,9 @@ SRCS= crti.S crtn.S OBJS= ${SRCS:N*.h:R:S/$/.o/g} OBJS+= gcrt1.o crt1.o Scrt1.o -CFLAGS+= -I${.CURDIR:H}/common \ +CFLAGS+= -I${.CURDIR} -I${.CURDIR:H}/common \ -I${SRCTOP}/lib/libc/include +CFLAGS+= -DCRT_IRELOC_REL FILES= ${OBJS} FILESMODE= ${LIBMODE} Modified: head/lib/csu/i386/crt1_c.c ============================================================================== --- head/lib/csu/i386/crt1_c.c Sat Oct 13 21:26:07 2018 (r339350) +++ head/lib/csu/i386/crt1_c.c Sat Oct 13 23:52:55 2018 (r339351) @@ -56,10 +56,12 @@ _start1(fptr cleanup, int argc, char *argv[]) env = argv + argc + 1; handle_argv(argc, argv, env); - if (&_DYNAMIC != NULL) + if (&_DYNAMIC != NULL) { atexit(cleanup); - else + } else { + process_irelocs(); _init_tls(); + } #ifdef GCRT atexit(_mcleanup); Added: head/lib/csu/i386/reloc.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/lib/csu/i386/reloc.c Sat Oct 13 23:52:55 2018 (r339351) @@ -0,0 +1,88 @@ +/*- + * Copyright (c) 2018 The FreeBSD Foundation + * + * This software was developed by Konstantin Belousov <kib@FreeBSD.org> + * 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. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 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 <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <machine/specialreg.h> +#include <machine/cpufunc.h> + +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; + } +} Modified: head/lib/csu/mips/Makefile ============================================================================== --- head/lib/csu/mips/Makefile Sat Oct 13 21:26:07 2018 (r339350) +++ head/lib/csu/mips/Makefile Sat Oct 13 23:52:55 2018 (r339351) @@ -7,6 +7,7 @@ OBJS= ${SRCS:N*.h:R:S/$/.o/g} OBJS+= Scrt1.o gcrt1.o CFLAGS+= -I${.CURDIR:H}/common \ -I${SRCTOP}/lib/libc/include +CFLAGS+= -DCRT_IRELOC_SUPPRESS FILES= ${OBJS} FILESMODE= ${LIBMODE} Modified: head/lib/csu/powerpc/Makefile ============================================================================== --- head/lib/csu/powerpc/Makefile Sat Oct 13 21:26:07 2018 (r339350) +++ head/lib/csu/powerpc/Makefile Sat Oct 13 23:52:55 2018 (r339351) @@ -7,6 +7,7 @@ OBJS= ${SRCS:N*.h:R:S/$/.o/g} OBJS+= Scrt1.o gcrt1.o CFLAGS+= -I${.CURDIR:H}/common \ -I${SRCTOP}/lib/libc/include +CFLAGS+= -DCRT_IRELOC_SUPPRESS FILES= ${OBJS} FILESMODE= ${LIBMODE} Modified: head/lib/csu/powerpc64/Makefile ============================================================================== --- head/lib/csu/powerpc64/Makefile Sat Oct 13 21:26:07 2018 (r339350) +++ head/lib/csu/powerpc64/Makefile Sat Oct 13 23:52:55 2018 (r339351) @@ -7,7 +7,7 @@ OBJS= ${SRCS:N*.h:R:S/$/.o/g} OBJS+= Scrt1.o gcrt1.o CFLAGS+= -I${.CURDIR:H}/common \ -I${SRCTOP}/lib/libc/include \ - -mlongcall + -mlongcall -DCRT_IRELOC_SUPPRESS FILES= ${OBJS} FILESMODE= ${LIBMODE} Modified: head/lib/csu/riscv/Makefile ============================================================================== --- head/lib/csu/riscv/Makefile Sat Oct 13 21:26:07 2018 (r339350) +++ head/lib/csu/riscv/Makefile Sat Oct 13 23:52:55 2018 (r339351) @@ -7,6 +7,7 @@ OBJS= ${SRCS:N*.h:R:S/$/.o/g} OBJS+= Scrt1.o gcrt1.o CFLAGS+= -I${.CURDIR:H}/common \ -I${SRCTOP}/lib/libc/include +CFLAGS+= -DCRT_IRELOC_SUPPRESS FILES= ${OBJS} FILESMODE= ${LIBMODE} Modified: head/lib/csu/sparc64/Makefile ============================================================================== --- head/lib/csu/sparc64/Makefile Sat Oct 13 21:26:07 2018 (r339350) +++ head/lib/csu/sparc64/Makefile Sat Oct 13 23:52:55 2018 (r339351) @@ -7,6 +7,7 @@ OBJS= ${SRCS:N*.h:R:S/$/.o/g} OBJS+= Scrt1.o gcrt1.o CFLAGS+= -I${.CURDIR:H}/common \ -I${SRCTOP}/lib/libc/include +CFLAGS+= -DCRT_IRELOC_SUPPRESS FILES= ${OBJS} FILESMODE= ${LIBMODE}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201810132352.w9DNqtQu098344>