From: John Marino Date: Sat, 9 Apr 2011 13:14:25 +0000 (+0200) Subject: gcc44, crtstuff: Provide -fPIE support X-Git-Tag: v2.11.0~67 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/e101389cdfc0ee127faf5259925a47b42b692580 gcc44, crtstuff: Provide -fPIE support Properly support Position Independent Executables (PIE) generation by linking PIE binaries with specially-built Scrt1.o instead of crt1.o. The latter is built without the -fPIC flag. For the i386 version, gcc-2 code was first purged, and then the new assembly was placed in a separate file. All data extracted by the assembler stub as explicit parameters. The hidden _start1 symbol is used as an interface between the assembly and C code. The CFLAGS -fkeep-inline-functions was removed as it was legacy FreeBSD code that has been long since removed. The CFLAGS -elf was removed as all DragonFly targets are elf. The LDFLAGS -elf was removed because it was getting interpreted as "-entry=lf" by ld. LDFLAGS weren't even used before this commit so it's always been completely extraneous. For x86_64, the no-omit-frame-pointer flag was added during the build of crt1.o. For the builtin gcc function __builtin_frame_address to work, all call frames need to save the frame pointer. In particular, this is important for the upper frame that should terminate the chain. --- diff --git a/contrib/gcc-4.4/gcc/config/dragonfly.h b/contrib/gcc-4.4/gcc/config/dragonfly.h index 6efe734ed5..bd051b3451 100644 --- a/contrib/gcc-4.4/gcc/config/dragonfly.h +++ b/contrib/gcc-4.4/gcc/config/dragonfly.h @@ -76,14 +76,19 @@ along with GCC; see the file COPYING3. If not see #undef STARTFILE_SPEC #define STARTFILE_SPEC \ "%{!shared: \ - %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} \ - %{!p:%{profile:gcrt1.o%s} \ - %{!profile:crt1.o%s}}}} \ - crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}" + %{pg:gcrt1.o%s} \ + %{!pg: \ + %{p:gcrt1.o%s} \ + %{!p: \ + %{profile: gcrt1.o%s} \ + %{!profile: \ + %{pie: Scrt1.o%s;:crt1.o%s}}}}} \ + crti.o%s \ + %{shared|pie:crtbeginS.o%s;:crtbegin.o%s}" #undef ENDFILE_SPEC #define ENDFILE_SPEC \ - "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s" + "%{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s" #undef LIB_SPEC #define LIB_SPEC \ diff --git a/lib/csu/i386/Makefile.csu b/lib/csu/i386/Makefile.csu index 74047f73ef..44a12484aa 100644 --- a/lib/csu/i386/Makefile.csu +++ b/lib/csu/i386/Makefile.csu @@ -1,16 +1,29 @@ # $FreeBSD: src/lib/csu/i386-elf/Makefile,v 1.6.2.5 2002/11/23 17:44:29 ru Exp $ -SRCS+= crt1.c crti.S crtn.S -OBJS+= gcrt1.o -INSTALLOBJS+= crt1.o crti.o crtn.o gcrt1.o -CLEANFILES+= crt1.o crti.o crtn.o gcrt1.o +SRCS+= crti.S crtn.S +OBJS+= gcrt1.o crt1.o Scrt1.o +INSTALLOBJS+= crt1.o crti.o crtn.o gcrt1.o Scrt1.o +CLEANFILES+= crt1.o crti.o crtn.o gcrt1.o Scrt1.o \ + crt1_c.o crt1_s.o gcrtl_c.o Scrt1_c.o WARNS?= 2 -CFLAGS+= -elf -fkeep-inline-functions \ - -I${CSUDIR}/../common -LDFLAGS+= -elf +CFLAGS+= -I${CSUDIR}/../common .PATH: ${CSUDIR} ${CSUDIR}/../common -gcrt1.o: crt1.c - ${CC} ${CFLAGS} -DGCRT -c -o gcrt1.o ${CSUDIR}/crt1.c +gcrt1_c.o: crt1_c.c + ${CC} ${CFLAGS} -DGCRT -c -o gcrt1_c.o ${CSUDIR}/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 ${CSUDIR}/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 diff --git a/lib/csu/i386/crt1.c b/lib/csu/i386/crt1_c.c similarity index 59% rename from lib/csu/i386/crt1.c rename to lib/csu/i386/crt1_c.c index 3b67125451..f2462d73f1 100644 --- a/lib/csu/i386/crt1.c +++ b/lib/csu/i386/crt1_c.c @@ -22,8 +22,7 @@ * (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: src/lib/csu/i386-elf/crt1.c,v 1.4.2.2 2002/11/18 04:57:13 bde Exp $ - * $DragonFly: src/lib/csu/i386/crt1.c,v 1.3 2005/05/11 19:46:51 dillon Exp $ + * $FreeBSD: src/lib/csu/i386-elf/crt1.c, svn 200038 2009/12/02 kib $ */ #ifndef __GNUC__ @@ -51,29 +50,15 @@ extern int etext; extern int _DYNAMIC; #pragma weak _DYNAMIC -#ifdef __i386__ -#define get_rtld_cleanup() \ - ({ fptr __value; \ - __asm__("movl %%edx,%0" : "=rm"(__value)); \ - __value; }) -#else -#error "This file only supports the i386 architecture" -#endif - char **environ; char *__progname = ""; +void _start1(fptr, int, char *[]) __dead2; void -_start(char *arguments, ...) +_start1(fptr cleanup, int argc, char *argv[]) { - fptr rtld_cleanup; - int argc; - char **argv; char **env; - rtld_cleanup = get_rtld_cleanup(); - argv = &arguments; - argc = * (int *) (argv - 1); env = argv + argc + 1; environ = env; if(argc > 0 && argv[0] != NULL) { @@ -88,13 +73,13 @@ _start(char *arguments, ...) * Setup the initial TLS space. The RTLD does not set up our TLS * (it can't, it doesn't know how our errno is declared). It simply * does all the groundwork required so that we can call - * _rtld_allocate_tls(). + * _rtld_allocate_tls(). */ _init_tls(); _rtld_call_init(); if(&_DYNAMIC != NULL) - atexit(rtld_cleanup); + atexit(cleanup); #ifdef GCRT atexit(_mcleanup); @@ -102,46 +87,10 @@ _start(char *arguments, ...) atexit(_fini); #ifdef GCRT monstartup(&eprol, &etext); +__asm__("eprol:"); #endif _init(); -#ifndef __GNUC__ exit( main(argc, argv, env) ); -#else - /* - * Some versions of gcc-2 expect the stack frame to be aligned as - * follows after it is set up in main(): - * - * +--------------+ <--- aligned by PREFERRED_STACK_BOUNDARY - * +%ebp (if any) + - * +--------------+ - * |return address| - * +--------------+ - * | arguments | - * | : | - * | : | - * +--------------+ - * - * We implement the above to fix just the usual case in FreeBSD-4. - * Alignment for main() is too compiler-dependent to handle correctly - * in all cases here (or in the kernel). E.g., a different alignment - * is required for at least gcc-2.95.4 even for the small variation - * of compiling main() with -fomit-frame-pointer. - */ - __asm__("\n" - "andl $~0xf, %%esp # align stack to 16-byte boundary\n" - "subl $12+12, %%esp # space for args and padding\n" - "movl %0, 0(%%esp)\n" - "movl %1, 4(%%esp)\n" - "movl %2, 8(%%esp)\n" - "call main\n" - "movl %%eax, 0(%%esp)\n" - "call exit\n" - : : "r" (argc), "r" (argv), "r" (env) : "ax", "cx", "dx", "memory"); -#endif } -#ifdef GCRT -__asm__(".text"); -__asm__("eprol:"); -__asm__(".previous"); -#endif +__asm(".hidden _start1"); diff --git a/lib/csu/i386/crt1_s.S b/lib/csu/i386/crt1_s.S new file mode 100644 index 0000000000..9b029ec94b --- /dev/null +++ b/lib/csu/i386/crt1_s.S @@ -0,0 +1,49 @@ +/*- + * 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: src/lib/csi/i386-elf/crt1_s.S, svn 217383 2011/01/19 kib $ + */ + + .text + .align 4 + .globl _start + .type _start, @function +_start: + .cfi_startproc + xorl %ebp,%ebp + pushl %ebp + .cfi_def_cfa_offset 4 + movl %esp,%ebp + .cfi_offset %ebp,-8 + .cfi_def_cfa_register %ebp + andl $0xfffffff0,%esp # align stack + leal 8(%ebp),%eax + subl $4,%esp + pushl %eax # argv + pushl 4(%ebp) # argc + pushl %edx # rtld cleanup + call _start1 + int3 + .cfi_endproc + .size _start, . - _start diff --git a/lib/csu/x86_64/Makefile.csu b/lib/csu/x86_64/Makefile.csu index 29e9883e3b..c0ea976a0e 100644 --- a/lib/csu/x86_64/Makefile.csu +++ b/lib/csu/x86_64/Makefile.csu @@ -1,15 +1,19 @@ # $FreeBSD: src/lib/csu/amd64/Makefile,v 1.18 2003/06/30 12:53:39 ru Exp $ SRCS+= crt1.c crti.S crtn.S -OBJS+= gcrt1.o +OBJS+= Scrt1.o gcrt1.o INSTALLOBJS+= crt1.o crti.o crtn.o gcrt1.o CLEANFILES+= crt1.o crti.o crtn.o gcrt1.o WARNS?= 2 CFLAGS+= -I${CSUDIR}/../common \ -I${CSUDIR}/../../libc/include +CFLAGS+= -fno-omit-frame-pointer .PATH: ${CSUDIR} ${CSUDIR}/../common gcrt1.o: crt1.c ${CC} ${CFLAGS} -DGCRT -c -o gcrt1.o ${CSUDIR}/crt1.c + +Scrt1.o: crt1.c + ${CC} ${CFLAGS} -fPIC -DPIC -c -o Scrt1.o ${CSUDIR}/crt1.c