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
This commit is contained in:
Konstantin Belousov 2009-12-02 16:34:20 +00:00
parent 6b5ba0bba3
commit c09ba32715
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=200038
10 changed files with 97 additions and 39 deletions

View File

@ -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

View File

@ -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}

View File

@ -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}

View File

@ -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>

View File

@ -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;
void _start1(fptr, int, char *[]) __dead2;
#ifdef __GNUC__
__asm__("movl %%edx,%0" : "=rm"(retval));
#else
retval = (fptr)0; /* XXXX Fix this for other compilers */
#endif
return(retval);
}
/* 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 = &ap;
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");

44
lib/csu/i386-elf/crt1_s.S Normal file
View File

@ -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$"

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -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}