gcc44, crtstuff: Provide -fPIE support
authorJohn Marino <draco@marino.st>
Sat, 9 Apr 2011 13:14:25 +0000 (15:14 +0200)
committerJohn Marino <draco@marino.st>
Sat, 9 Apr 2011 22:51:29 +0000 (00:51 +0200)
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.

contrib/gcc-4.4/gcc/config/dragonfly.h
lib/csu/i386/Makefile.csu
lib/csu/i386/crt1_c.c [moved from lib/csu/i386/crt1.c with 59% similarity]
lib/csu/i386/crt1_s.S [new file with mode: 0644]
lib/csu/x86_64/Makefile.csu

index 6efe734..bd051b3 100644 (file)
@@ -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 \
index 74047f7..44a1248 100644 (file)
@@ -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
similarity index 59%
rename from lib/csu/i386/crt1.c
rename to lib/csu/i386/crt1_c.c
index 3b67125..f2462d7 100644 (file)
@@ -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 (file)
index 0000000..9b029ec
--- /dev/null
@@ -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
index 29e9883..c0ea976 100644 (file)
@@ -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