diff --git a/lib/csu/Makefile.inc b/lib/csu/Makefile.inc --- a/lib/csu/Makefile.inc +++ b/lib/csu/Makefile.inc @@ -20,7 +20,6 @@ ACFLAGS+= -DLOCORE CFLAGS+= -DSTRIP_FBSDID -CFLAGS+= -fno-asynchronous-unwind-tables CFLAGS+= -fno-omit-frame-pointer CFLAGS+= -I${.CURDIR:H}/common \ -I${SRCTOP}/lib/libc/include @@ -35,25 +34,28 @@ # These FILES qualify as libraries for the purpose of LIBRARIES_ONLY. .undef LIBRARIES_ONLY +CRT1SRC?= crt1_c.c +CRT1OBJ?= + CLEANFILES+= ${OBJS} ${CRT1OBJS} crt1_c.o gcrt1_c.o Scrt1_c.o -CLEANFILES+= crti_s.o +CLEANFILES+= crti_s.o ${CRT1SRC:C/.[S|c]$/.o/} -crt1.o: crt1_c.o ${CRT1OBJS} +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: crt1_c.c - ${CC} ${CFLAGS} -DGCRT -c -o ${.TARGET} ${.CURDIR}/crt1_c.c +gcrt1_c.o: ${CRT1SRC} + ${CC} ${CFLAGS} -DGCRT -c -o ${.TARGET} ${.CURDIR}/${CRT1SRC} -gcrt1.o: gcrt1_c.o ${CRT1OBJS} +gcrt1.o: gcrt1_c.o ${CRT1OBJS} ${CRT1OBJ} ${LD} ${_LDFLAGS} -o ${.TARGET} -r ${.ALLSRC:M*.o} -Scrt1_c.o: crt1_c.c - ${CC} ${CFLAGS} -fPIC -DPIC -c -o ${.TARGET} ${.CURDIR}/crt1_c.c +Scrt1_c.o: ${CRT1SRC} + ${CC} ${CFLAGS} -fPIC -DPIC -c -o ${.TARGET} ${.CURDIR}/${CRT1SRC} -Scrt1.o: Scrt1_c.o ${CRT1OBJS} +Scrt1.o: Scrt1_c.o ${CRT1OBJS} ${CRT1OBJ} ${LD} ${_LDFLAGS} -o ${.TARGET} -r ${.ALLSRC:M*.o} .if ${MACHINE_ARCH} == "i386" ${OBJCOPY} --localize-symbol _start1 ${.TARGET} diff --git a/lib/csu/amd64/Makefile b/lib/csu/amd64/Makefile --- a/lib/csu/amd64/Makefile +++ b/lib/csu/amd64/Makefile @@ -5,4 +5,7 @@ CFLAGS+= -I${.CURDIR} CFLAGS+= -fno-omit-frame-pointer +CRT1SRC= crt1_s.S +CRT1OBJ= crt1_c.o + .include diff --git a/lib/csu/amd64/crt1_c.c b/lib/csu/amd64/crt1_c.c --- a/lib/csu/amd64/crt1_c.c +++ b/lib/csu/amd64/crt1_c.c @@ -29,26 +29,4 @@ #include __FBSDID("$FreeBSD$"); -#include "libc_private.h" #include "csu_common.h" - -void _start(char **, void (*)(void)) __dead2; - -/* The entry function. */ -void -_start(char **ap, void (*cleanup)(void)) -{ - int argc; - char **argv; - char **env; - - argc = *(long *)(void *)ap; - argv = ap + 1; - env = ap + 2 + argc; -#ifdef GCRT - __libc_start1_gcrt(argc, argv, env, cleanup, main, &eprol, &etext); -__asm__("eprol:"); -#else - __libc_start1(argc, argv, env, cleanup, main); -#endif -} diff --git a/lib/csu/amd64/crt1_s.S b/lib/csu/amd64/crt1_s.S new file mode 100644 --- /dev/null +++ b/lib/csu/amd64/crt1_s.S @@ -0,0 +1,88 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (C) 2023 Dmitry Chagin + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + + + .text + .align 8 + + /* + * The program entry point + * %rdi %rsi + * void _start(char **ap, void (*cleanup)(void)) __dead2 + */ + .globl _start + .type _start, @function +_start: + .cfi_startproc + .cfi_undefined %rip /* Terminate call chain. */ + pushq %rbp /* Align stack, terminate call chain. */ + .cfi_def_cfa_offset 8 + movq %rsp, %rbp + .cfi_offset %rbp, -16 + .cfi_def_cfa_register %rbp +#ifdef GCRT + subq $16, %rsp +#endif + movq %rsi, %rcx + movq %rdi, %rsi /* argv = ap */ + addq $8, %rsi /* argv += 1 */ + movq %rdi, %rdx /* env = ap */ + addq $16, %rdx /* env += 2 */ + movslq (%rdi), %rax + movl %eax, %edi /* argc = *(long *)(void *)ap */ + shlq $3, %rax + addq %rax, %rdx /* env += argc */ +#ifdef PIC + /* + * XXX. %rip relative addressing does not intended to use in the + * large memory model due to offset from %rip is limited to 32 bits. + */ + leaq main(%rip), %r8 +#else + movabsq $main, %r8 +#endif +#ifdef GCRT + movabsq $eprol, %r9 + movabsq $etext, %rax + movq %rax, (%rsp) + /* + * %edi %rsi %rdx %rcx %r8 %r9 (%rsp) + * __libc_start1_gcrt(argc, argv, env, cleanup, main, &eprol, &etext) + */ + callq __libc_start1_gcrt +eprol: +#else + /* __libc_start1(argc, argv, env, cleanup, main) */ + callq __libc_start1 +#endif + int3 + .cfi_endproc + .size _start, . - _start + + .section .note.GNU-stack,"",%progbits