aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDmitry Chagin <dchagin@FreeBSD.org>2023-07-11 12:12:01 +0000
committerDmitry Chagin <dchagin@FreeBSD.org>2023-07-11 12:12:01 +0000
commitd744a37a3ad4be9d1f748258195f9d654c3cb2ae (patch)
tree87d6171402099fd045156ab81e99493e03893c06 /lib
parentd7e2580a1494a8a05d4a97fa472612df84c1539b (diff)
downloadsrc-d744a37a3ad4be9d1f748258195f9d654c3cb2ae.tar.gz
src-d744a37a3ad4be9d1f748258195f9d654c3cb2ae.zip
csu: Implement _start using as to satisfy unwinders on i386
The right unwinding stop indicator should be CFI-undefined PC. https://dwarfstd.org/doc/Dwarf3.pdf - page 118: If a Return Address register is defined in the virtual unwind table, and its rule is undefined (for example, by DW_CFA_undefined), then there is no return address and no call address, and the virtual unwind of stack activations is complete. The hack localizing _start1 symbol removed. Reviewed by: kib Differential Revision: https://reviews.freebsd.org/D40624
Diffstat (limited to 'lib')
-rw-r--r--lib/csu/Makefile.inc6
-rw-r--r--lib/csu/i386/Makefile3
-rw-r--r--lib/csu/i386/crt1_c.c21
-rw-r--r--lib/csu/i386/crt1_s.S58
4 files changed, 54 insertions, 34 deletions
diff --git a/lib/csu/Makefile.inc b/lib/csu/Makefile.inc
index ee60c3968b87..9c3352296651 100644
--- a/lib/csu/Makefile.inc
+++ b/lib/csu/Makefile.inc
@@ -42,9 +42,6 @@ CLEANFILES+= crti_s.o ${CRT1SRC:C/.[S|c]$/.o/}
crt1.o: ${CRT1SRC:C/.[S|c]$/.o/} ${CRT1OBJS} ${CRT1OBJ}
${LD} ${_LDFLAGS} -o ${.TARGET} -r ${.ALLSRC:M*.o}
-.if ${MACHINE_ARCH} == "i386"
- ${OBJCOPY} --localize-symbol _start1 ${.TARGET}
-.endif
gcrt1_c.o: ${CRT1SRC}
${CC} ${CFLAGS} -DGCRT -c -o ${.TARGET} ${.CURDIR}/${CRT1SRC}
@@ -57,9 +54,6 @@ Scrt1_c.o: ${CRT1SRC}
Scrt1.o: Scrt1_c.o ${CRT1OBJS} ${CRT1OBJ}
${LD} ${_LDFLAGS} -o ${.TARGET} -r ${.ALLSRC:M*.o}
-.if ${MACHINE_ARCH} == "i386"
- ${OBJCOPY} --localize-symbol _start1 ${.TARGET}
-.endif
crtbegin.o: crtbegin.c
crtbeginS.o: crtbegin.c
diff --git a/lib/csu/i386/Makefile b/lib/csu/i386/Makefile
index d8d0d3fd8f99..72be8b70ef19 100644
--- a/lib/csu/i386/Makefile
+++ b/lib/csu/i386/Makefile
@@ -4,6 +4,7 @@
CFLAGS+= -I${.CURDIR}
-CRT1OBJS+= crt1_s.o
+CRT1SRC= crt1_s.S
+CRT1OBJ= crt1_c.o
.include <bsd.lib.mk>
diff --git a/lib/csu/i386/crt1_c.c b/lib/csu/i386/crt1_c.c
index d49c763749a3..7b28200cbd29 100644
--- a/lib/csu/i386/crt1_c.c
+++ b/lib/csu/i386/crt1_c.c
@@ -29,25 +29,6 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include "libc_private.h"
#include "csu_common.h"
-void _start(char *, ...);
-void _start1(void (*)(void), int, char *[]) __dead2;
-
-/* The entry function, C part. */
-void
-_start1(void (*cleanup)(void), int argc, char *argv[])
-{
- char **env;
-
- env = argv + argc + 1;
-#ifdef GCRT
- __libc_start1_gcrt(argc, argv, env, cleanup, main, &eprol, &etext);
-__asm__("eprol:");
-#else
- __libc_start1(argc, argv, env, cleanup, main);
-#endif
-}
-
-__asm(".hidden _start1");
+void _start(char *, ...) __dead2;
diff --git a/lib/csu/i386/crt1_s.S b/lib/csu/i386/crt1_s.S
index 1bd9a4283987..f6e230a1a5a7 100644
--- a/lib/csu/i386/crt1_s.S
+++ b/lib/csu/i386/crt1_s.S
@@ -31,19 +31,63 @@ __FBSDID("$FreeBSD$");
.type _start, @function
_start:
.cfi_startproc
+ .cfi_undefined %eip
+ popl %esi # Pop argc
+ .cfi_def_cfa_offset -4
+ movl %esp,%edi # argv starts at stack top
xorl %ebp,%ebp
pushl %ebp
- .cfi_def_cfa_offset 4
+ .cfi_def_cfa_offset 0
movl %esp,%ebp
- .cfi_offset %ebp,-8
+ .cfi_offset %ebp,-4
.cfi_def_cfa_register %ebp
andl $0xfffffff0,%esp # align stack
- leal 8(%ebp),%eax
- subl $4,%esp
- pushl %eax # argv
- pushl 4(%ebp) # argc
+
+#ifdef GCRT
+ subl $4,%esp # Align stack for 7 arguments
+ pushl $etext
+ pushl $eprol
+eprol:
+#else
+ subl $12,%esp # Align stack for 5 arguments
+#endif /* GCRT */
+
+#ifdef PIC
+ calll 1f
+1: popl %ebx
+ addl $_GLOBAL_OFFSET_TABLE_+[.-1b],%ebx
+ leal main@GOTOFF(%ebx),%eax
+ pushl %eax
+#else
+ pushl $main
+#endif /* PIC */
+
pushl %edx # rtld cleanup
- call _start1
+ /* env = argv + argc + 1 */
+ movl %edi,%eax # env = argv
+ movl %esi,%ecx
+ shll $2,%ecx # argc * 4
+ addl %ecx,%eax # env += argc
+ addl $4,%eax # env += 1
+ pushl %eax # env
+ pushl %edi # argv
+ pushl %esi # argc
+
+#ifdef GCRT
+ /*
+ * __libc_start1_gcrt(argc, argv, env, cleanup, main, &eprol, &etext);
+ */
+ calll __libc_start1_gcrt
+#else
+ /*
+ * __libc_start1(argc, argv, env, cleanup, main);
+ */
+#ifdef PIC
+ calll __libc_start1@PLT
+#else
+ calll __libc_start1
+#endif
+#endif /* GCRT */
int3
.cfi_endproc
.size _start, . - _start