Skip to content

Commit

Permalink
csu: Implement _start using as to satisfy unwinders on i386
Browse files Browse the repository at this point in the history
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
  • Loading branch information
lemul committed Jul 11, 2023
1 parent d7e2580 commit d744a37
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 34 deletions.
6 changes: 0 additions & 6 deletions lib/csu/Makefile.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand All @@ -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
Expand Down
3 changes: 2 additions & 1 deletion lib/csu/i386/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

CFLAGS+= -I${.CURDIR}

CRT1OBJS+= crt1_s.o
CRT1SRC= crt1_s.S
CRT1OBJ= crt1_c.o

.include <bsd.lib.mk>
21 changes: 1 addition & 20 deletions lib/csu/i386/crt1_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
58 changes: 51 additions & 7 deletions lib/csu/i386/crt1_s.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit d744a37

Please sign in to comment.