diff options
author | kib <kib@FreeBSD.org> | 2009-12-02 16:34:20 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2009-12-02 16:34:20 +0000 |
commit | 0d2524b06305d5ae66fdcefc0a0d0321167718d9 (patch) | |
tree | f29596ca72fd7a0e77c68583e1ad685e3fb2d947 | |
parent | 2f0aea3d4ef3af824fdfcd7443c1d5a1bd3a1cbb (diff) | |
download | FreeBSD-src-0d2524b06305d5ae66fdcefc0a0d0321167718d9.zip FreeBSD-src-0d2524b06305d5ae66fdcefc0a0d0321167718d9.tar.gz |
Properly support -fPIE by linking PIE binaries with specially-built
Scrt1.o instead of crt1.o, since the later is built as non-PIC.
Separate i386-elf crt1.c into the pure assembler part and C code,
supplying all data extracted by assembler stub as explicit parameters [1].
Hide and localize _start1 symbol used as an interface between asm and
C code.
In collaboration with: kan
Inspired by: PR i386/127387 [1]
Prodded and tested by: rdivacky [1]
MFC after: 3 weeks
-rw-r--r-- | contrib/gcc/config/freebsd-spec.h | 8 | ||||
-rw-r--r-- | lib/csu/amd64/Makefile | 5 | ||||
-rw-r--r-- | lib/csu/arm/Makefile | 5 | ||||
-rw-r--r-- | lib/csu/i386-elf/Makefile | 24 | ||||
-rw-r--r-- | lib/csu/i386-elf/crt1_c.c (renamed from lib/csu/i386-elf/crt1.c) | 30 | ||||
-rw-r--r-- | lib/csu/i386-elf/crt1_s.S | 44 | ||||
-rw-r--r-- | lib/csu/ia64/Makefile | 5 | ||||
-rw-r--r-- | lib/csu/mips/Makefile | 5 | ||||
-rw-r--r-- | lib/csu/powerpc/Makefile | 5 | ||||
-rw-r--r-- | lib/csu/sparc64/Makefile | 5 |
10 files changed, 97 insertions, 39 deletions
diff --git a/contrib/gcc/config/freebsd-spec.h b/contrib/gcc/config/freebsd-spec.h index 06735c8..5cd57b0 100644 --- a/contrib/gcc/config/freebsd-spec.h +++ b/contrib/gcc/config/freebsd-spec.h @@ -103,9 +103,10 @@ Boston, MA 02110-1301, USA. */ %{p:gcrt1.o%s} \ %{!p: \ %{profile:gcrt1.o%s} \ - %{!profile:crt1.o%s}}}} \ + %{!profile: \ + %{pie: Scrt1.o%s;:crt1.o%s}}}}} \ crti.o%s \ - %{static:crtbeginT.o%s;shared:crtbeginS.o%s;:crtbegin.o%s}" + %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}" /* Provide an ENDFILE_SPEC appropriate for FreeBSD/i386. Here we tack on our own magical crtend.o file (see crtstuff.c) which provides part of @@ -113,8 +114,7 @@ Boston, MA 02110-1301, USA. */ entering `main', followed by the normal "finalizer" file, `crtn.o'. */ #define FBSD_ENDFILE_SPEC "\ - %{!shared:crtend.o%s} \ - %{shared:crtendS.o%s} \ + %{shared|pie:crtendS.o%s;:crtend.o%s} \ crtn.o%s " /* Provide a LIB_SPEC appropriate for FreeBSD as configured and as diff --git a/lib/csu/amd64/Makefile b/lib/csu/amd64/Makefile index 71ccd67..1a74efc 100644 --- a/lib/csu/amd64/Makefile +++ b/lib/csu/amd64/Makefile @@ -4,7 +4,7 @@ SRCS= crt1.c crti.S crtn.S OBJS= ${SRCS:N*.h:R:S/$/.o/g} -OBJS+= gcrt1.o +OBJS+= Scrt1.o gcrt1.o CFLAGS+= -I${.CURDIR}/../common \ -I${.CURDIR}/../../libc/include CFLAGS+= -fno-omit-frame-pointer @@ -16,6 +16,9 @@ CLEANFILES= ${OBJS} gcrt1.o: crt1.c ${CC} ${CFLAGS} -DGCRT -c -o gcrt1.o ${.CURDIR}/crt1.c +Scrt1.o: crt1.c + ${CC} ${CFLAGS} -fPIC -DPIC -c -o Scrt1.o ${.CURDIR}/crt1.c + realinstall: ${INSTALL} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \ ${OBJS} ${DESTDIR}${LIBDIR} diff --git a/lib/csu/arm/Makefile b/lib/csu/arm/Makefile index 23954e8..097f82d 100644 --- a/lib/csu/arm/Makefile +++ b/lib/csu/arm/Makefile @@ -4,7 +4,7 @@ SRCS= crt1.c crti.S crtn.S OBJS= ${SRCS:N*.h:R:S/$/.o/g} -OBJS+= gcrt1.o +OBJS+= Scrt1.o gcrt1.o CFLAGS+= -Wall -Wno-unused \ -I${.CURDIR}/../common \ -I${.CURDIR}/../../libc/include @@ -16,6 +16,9 @@ CLEANFILES= ${OBJS} gcrt1.o: crt1.c ${CC} ${CFLAGS} -DGCRT -c -o gcrt1.o ${.ALLSRC} +Scrt1.o: crt1.c + ${CC} ${CFLAGS} -fPIC -DPIC -c -o Scrt1.o ${.ALLSRC} + realinstall: ${INSTALL} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \ ${OBJS} ${DESTDIR}${LIBDIR} diff --git a/lib/csu/i386-elf/Makefile b/lib/csu/i386-elf/Makefile index 8598ce8..c2af118 100644 --- a/lib/csu/i386-elf/Makefile +++ b/lib/csu/i386-elf/Makefile @@ -2,8 +2,8 @@ .PATH: ${.CURDIR}/../common -SRCS= crt1.c crti.S crtn.S -FILES= ${SRCS:N*.h:R:S/$/.o/g} gcrt1.o +SRCS= crti.S crtn.S +FILES= ${SRCS:N*.h:R:S/$/.o/g} gcrt1.o crt1.o Scrt1.o FILESOWN= ${LIBOWN} FILESGRP= ${LIBGRP} FILESMODE= ${LIBMODE} @@ -11,9 +11,23 @@ FILESDIR= ${LIBDIR} WARNS?= 6 CFLAGS+= -I${.CURDIR}/../common \ -I${.CURDIR}/../../libc/include -CLEANFILES= ${FILES} +CLEANFILES= ${FILES} crt1_c.o crt1_s.o gcrt1_c.o Scrt1_c.o -gcrt1.o: crt1.c - ${CC} ${CFLAGS} -DGCRT -c -o gcrt1.o ${.CURDIR}/crt1.c +gcrt1_c.o: crt1_c.c + ${CC} ${CFLAGS} -DGCRT -c -o gcrt1_c.o ${.CURDIR}/crt1_c.c + +gcrt1.o: gcrt1_c.o crt1_s.o + ${LD} ${LDFLAGS} -o gcrt1.o -r crt1_s.o gcrt1_c.o + +crt1.o: crt1_c.o crt1_s.o + ${LD} ${LDFLAGS} -o crt1.o -r crt1_s.o crt1_c.o + objcopy --localize-symbol _start1 crt1.o + +Scrt1_c.o: crt1_c.c + ${CC} ${CFLAGS} -DGCRT -fPIC -DPIC -c -o Scrt1_c.o ${.CURDIR}/crt1_c.c + +Scrt1.o: Scrt1_c.o crt1_s.o + ${LD} ${LDFLAGS} -o Scrt1.o -r crt1_s.o Scrt1_c.o + objcopy --localize-symbol _start1 Scrt1.o .include <bsd.prog.mk> diff --git a/lib/csu/i386-elf/crt1.c b/lib/csu/i386-elf/crt1_c.c index 0934333..c38f267 100644 --- a/lib/csu/i386-elf/crt1.c +++ b/lib/csu/i386-elf/crt1_c.c @@ -22,6 +22,8 @@ * 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. + * + * $FreeBSD$ */ #ifndef lint @@ -55,35 +57,15 @@ extern int etext; char **environ; const char *__progname = ""; -static __inline fptr -get_rtld_cleanup(void) -{ - fptr retval; - -#ifdef __GNUC__ - __asm__("movl %%edx,%0" : "=rm"(retval)); -#else - retval = (fptr)0; /* XXXX Fix this for other compilers */ -#endif - return(retval); -} +void _start1(fptr, int, char *[]) __dead2; -/* The entry function. */ +/* The entry function, C part. */ void -_start(char *ap, ...) +_start1(fptr cleanup, int argc, char *argv[]) { - fptr cleanup; - int argc; - char **argv; char **env; const char *s; -#ifdef __GNUC__ - __asm__("and $0xfffffff0,%esp"); -#endif - cleanup = get_rtld_cleanup(); - argv = ≈ - argc = *(long *)(void *)(argv - 1); env = argv + argc + 1; environ = env; if (argc > 0 && argv[0] != NULL) { @@ -110,4 +92,4 @@ __asm__("eprol:"); exit( main(argc, argv, env) ); } -__asm__(".ident\t\"$FreeBSD$\""); +__asm(".hidden _start1"); diff --git a/lib/csu/i386-elf/crt1_s.S b/lib/csu/i386-elf/crt1_s.S new file mode 100644 index 0000000..2af8a1b --- /dev/null +++ b/lib/csu/i386-elf/crt1_s.S @@ -0,0 +1,44 @@ +/*- + * Copyright 2009 Konstantin Belousov. + * All rights reserved. + * + * 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 ``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. + * + * $FreeBSD$ + */ + + + .text + .align 4 + .globl _start + .type _start, @function +_start: xorl %ebp,%ebp + pushl %ebp + movl %esp,%ebp + andl $0xfffffff0,%esp # align stack + leal 8(%ebp),%eax + pushl %eax # argv + pushl 4(%ebp) # argc + pushl %edx # rtld cleanup + call _start1 + .size _start, . - _start + + .ident "$FreeBSD$" diff --git a/lib/csu/ia64/Makefile b/lib/csu/ia64/Makefile index c906c09..d795103 100644 --- a/lib/csu/ia64/Makefile +++ b/lib/csu/ia64/Makefile @@ -4,7 +4,7 @@ SRCS= crt1.S crti.S crtn.S OBJS= ${SRCS:N*.h:R:S/$/.o/g} -OBJS+= gcrt1.o +OBJS+= Scrt1.o gcrt1.o CFLAGS+= -Wall -Wno-unused \ -I${.CURDIR}/../common \ -I${.CURDIR}/../../libc/include @@ -16,6 +16,9 @@ CLEANFILES= ${OBJS} gcrt1.o: crt1.S ${CC} ${CFLAGS} -DGCRT -c -o gcrt1.o ${.ALLSRC} +Scrt1.o: crt1.S + ${CC} ${CFLAGS} -fPIC -DPIC -c -o Scrt1.o ${.ALLSRC} + realinstall: ${INSTALL} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \ ${OBJS} ${DESTDIR}${LIBDIR} diff --git a/lib/csu/mips/Makefile b/lib/csu/mips/Makefile index 23954e8..097f82d 100644 --- a/lib/csu/mips/Makefile +++ b/lib/csu/mips/Makefile @@ -4,7 +4,7 @@ SRCS= crt1.c crti.S crtn.S OBJS= ${SRCS:N*.h:R:S/$/.o/g} -OBJS+= gcrt1.o +OBJS+= Scrt1.o gcrt1.o CFLAGS+= -Wall -Wno-unused \ -I${.CURDIR}/../common \ -I${.CURDIR}/../../libc/include @@ -16,6 +16,9 @@ CLEANFILES= ${OBJS} gcrt1.o: crt1.c ${CC} ${CFLAGS} -DGCRT -c -o gcrt1.o ${.ALLSRC} +Scrt1.o: crt1.c + ${CC} ${CFLAGS} -fPIC -DPIC -c -o Scrt1.o ${.ALLSRC} + realinstall: ${INSTALL} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \ ${OBJS} ${DESTDIR}${LIBDIR} diff --git a/lib/csu/powerpc/Makefile b/lib/csu/powerpc/Makefile index 23954e8..097f82d 100644 --- a/lib/csu/powerpc/Makefile +++ b/lib/csu/powerpc/Makefile @@ -4,7 +4,7 @@ SRCS= crt1.c crti.S crtn.S OBJS= ${SRCS:N*.h:R:S/$/.o/g} -OBJS+= gcrt1.o +OBJS+= Scrt1.o gcrt1.o CFLAGS+= -Wall -Wno-unused \ -I${.CURDIR}/../common \ -I${.CURDIR}/../../libc/include @@ -16,6 +16,9 @@ CLEANFILES= ${OBJS} gcrt1.o: crt1.c ${CC} ${CFLAGS} -DGCRT -c -o gcrt1.o ${.ALLSRC} +Scrt1.o: crt1.c + ${CC} ${CFLAGS} -fPIC -DPIC -c -o Scrt1.o ${.ALLSRC} + realinstall: ${INSTALL} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \ ${OBJS} ${DESTDIR}${LIBDIR} diff --git a/lib/csu/sparc64/Makefile b/lib/csu/sparc64/Makefile index 2e1d03f..7f8dd7a 100644 --- a/lib/csu/sparc64/Makefile +++ b/lib/csu/sparc64/Makefile @@ -4,7 +4,7 @@ SRCS= crt1.c crti.S crtn.S OBJS= ${SRCS:N*.h:R:S/$/.o/g} -OBJS+= gcrt1.o +OBJS+= Scrt1.o gcrt1.o CFLAGS+= -I${.CURDIR}/../common -I${.CURDIR}/../../libc/include all: ${OBJS} @@ -14,6 +14,9 @@ CLEANFILES= ${OBJS} gcrt1.o: crt1.c ${CC} ${CFLAGS} -DGCRT -c -o gcrt1.o ${.ALLSRC} +Scrt1.o: crt1.c + ${CC} ${CFLAGS} -fPIC -DPIC -c -o Scrt1.o ${.ALLSRC} + realinstall: ${INSTALL} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \ ${OBJS} ${DESTDIR}${LIBDIR} |