The branch main has been updated by dchagin:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=d744a37a3ad4be9d1f748258195f9d654c3cb2ae

commit d744a37a3ad4be9d1f748258195f9d654c3cb2ae
Author:     Dmitry Chagin <[email protected]>
AuthorDate: 2023-07-11 12:12:01 +0000
Commit:     Dmitry Chagin <[email protected]>
CommitDate: 2023-07-11 12:12:01 +0000

    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
---
 lib/csu/Makefile.inc  |  6 ------
 lib/csu/i386/Makefile |  3 ++-
 lib/csu/i386/crt1_c.c | 21 +------------------
 lib/csu/i386/crt1_s.S | 58 ++++++++++++++++++++++++++++++++++++++++++++-------
 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

Reply via email to