csu: Implement _start using as to satisfy unwinders on aarch64

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.

Reviewed by:
Differential Revision:	https://reviews.freebsd.org/D40623
This commit is contained in:
Dmitry Chagin 2023-07-07 19:56:02 +03:00
parent 1a2aa2ffb5
commit bae6bb0698
3 changed files with 25 additions and 17 deletions

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

@ -32,19 +32,4 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "libc_private.h"
#include "csu_common.h"
void __start(int, char **, char **, void (*)(void)) __dead2;
/* The entry function. */
void
__start(int argc, char *argv[], char *env[], void (*cleanup)(void))
{
#ifdef GCRT
__libc_start1_gcrt(argc, argv, env, cleanup, main, &eprol, &etext);
__asm__("eprol:");
#else
__libc_start1(argc, argv, env, cleanup, main);
#endif
}

View file

@ -32,13 +32,35 @@
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
/*
* The program entry point
* void _start(char **ap, void (*cleanup)(void)) __dead2
*/
ENTRY(_start)
.cfi_undefined x30
mov x3, x2 /* cleanup */
add x1, x0, #8 /* load argv */
ldr x0, [x0] /* load argc */
add x2, x1, x0, lsl #3 /* env is after argv */
add x2, x2, #8 /* argv is null terminated */
b __start
#ifdef PIC
adrp x4, main
add x4, x4, :lo12:main
#else
ldr x4, =main
#endif
#ifdef GCRT
ldr x5, =eprol
ldr x6, =etext
/*
* __libc_start1_gcrt(argc, argv, env, cleanup, main, &eprol, &etext)
*/
bl __libc_start1_gcrt
eprol:
#else
/* __libc_start1(argc, argv, env, cleanup, main) */
bl __libc_start1
#endif
END(_start)
.section .note.GNU-stack,"",@progbits