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
This commit is contained in:
Dmitry Chagin 2023-07-11 15:12:01 +03:00
parent d7e2580a14
commit d744a37a3a
4 changed files with 54 additions and 34 deletions

View file

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

View file

@ -4,6 +4,7 @@
CFLAGS+= -I${.CURDIR}
CRT1OBJS+= crt1_s.o
CRT1SRC= crt1_s.S
CRT1OBJ= crt1_c.o
.include <bsd.lib.mk>

View file

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

View file

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