diff --git a/.gitattributes b/.gitattributes index 45ac120310..ff9797fe01 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4733,6 +4733,8 @@ rtl/linux/x86_64/cprt0.as -text rtl/linux/x86_64/dllprt0.as -text rtl/linux/x86_64/gprt0.as -text rtl/linux/x86_64/prt0.as -text +rtl/linux/x86_64/si_c.inc svneol=native#text/plain +rtl/linux/x86_64/si_prc.inc svneol=native#text/plain rtl/linux/x86_64/sighnd.inc svneol=native#text/plain rtl/linux/x86_64/sighndh.inc svneol=native#text/plain rtl/linux/x86_64/stat.inc svneol=native#text/plain diff --git a/rtl/linux/x86_64/si_c.inc b/rtl/linux/x86_64/si_c.inc new file mode 100644 index 0000000000..f7d66310dd --- /dev/null +++ b/rtl/linux/x86_64/si_c.inc @@ -0,0 +1,161 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2005 by Michael Van Canneyt, Peter Vreman, + & Daniel Mantione, members of the Free Pascal development team. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + **********************************************************************} + +{ + Linux ELF startup code for Free Pascal + + + Stack layout at program start: + + nil + envn + .... + .... ENVIRONMENT VARIABLES + env1 + env0 + nil + argn + .... + .... COMMAND LINE OPTIONS + arg1 + arg0 + argc <--- esp +} + +var + libc_environ: pchar; external name '__environ'; + libc_fpu_control: word; external name '__fpu_control'; + libc_init_proc: procedure; external name '_init'; + libc_fini_proc: procedure; external name '_fini'; + + fpc_ret,fpc_ret_rbp : pointer; + +procedure libc_atexit; external name '__libc_atexit'; +procedure libc_exit; external name '__libc_exit'; +procedure libc_init; external name '__libc_init'; +procedure libc_setfpucw; external name '__setfpucw'; +procedure libc_start_main; external name '__libc_start_main'; + +procedure PASCALMAIN; external name 'PASCALMAIN'; + +procedure main_stub; assembler; nostackframe; + asm + { save return address } + popq %rax + + // stack alignment + pushq %rax + + movq %rax,fpc_ret + movq %rbp,fpc_ret_rbp + pushq %rax + + { Save initial stackpointer } + movq %rsp,__stkptr + + { start the program } + xorq %rbp,%rbp + call PASCALMAIN + hlt + end; + + +procedure ini_dummy; assembler; nostackframe + asm + ret + end; + +{****************************************************************************** + C library start/halt + ******************************************************************************} + +procedure _FPC_libc_start; assembler; nostackframe; public name '_start'; + asm + { Clear the frame pointer. The ABI suggests this be done, to mark + the outermost frame obviously. } + xorq %rbp, %rbp + + { Extract the arguments as encoded on the stack and set up + the arguments for __libc_start_main (int (*main) (int, char **, char **), + int argc, char *argv, + void (*init) (void), void (*fini) (void), + void (*rtld_fini) (void), void *stack_end). + The arguments are passed via registers and on the stack: + main: %rdi + argc: %rsi + argv: %rdx + init: %rcx + fini: %r8 + rtld_fini: %r9 + stack_end: stack. } + + movq %rdx, %r9 { Address of the shared library termination + function. } + popq %rsi { Pop the argument count. } + movq %rsp, %rdx { argv starts just at the current stack top. } + + movq %rsi,operatingsystem_parameter_argc + movq %rsp,operatingsystem_parameter_argv { argv starts just at the current stack top. } + leaq 8(,%rsi,8),%rax + addq %rsp,%rax + movq %rax,operatingsystem_parameter_envp + + { Align the stack to a 16 byte boundary to follow the ABI. } + andq $~15, %rsp + + pushq %rax { Push garbage because we push 8 more bytes. } + + { Provide the highest stack address to the user code (for stacks + which grow downwards). } + pushq %rsp + + { Pass address of our own entry points to .fini and .init. } + movq $ini_dummy, %r8 + movq $ini_dummy, %rcx + + movq $main_stub, %rdi + + { Call the user's main function, and exit with its value. + But let the libc call main. } + call libc_start_main + + hlt { Crash if somehow `exit' does return. } + + { We need this stuff to make gdb behave itself, otherwise + gdb will chokes with SIGILL when trying to debug apps. + } + .section ".note.ABI-tag", "a" + .align 4 + .long 1f - 0f + .long 3f - 2f + .long 1 +0: .asciz "GNU" +1: .align 4 +2: .long 0 + .long 2,4,0 +3: .align 4 + + .section .note.GNU-stack,"",@progbits + end; + + +procedure _FPC_libc_haltproc; assembler; nostackframe; public name '_haltproc'; + asm + movzwq operatingsystem_result,%rax { load and save exitcode } + + movq ___fpc_ret,%rdx { return to libc } + movq ___fpc_ret_rbp,%rbp + pushq %rdx + ret + end; diff --git a/rtl/linux/x86_64/si_prc.inc b/rtl/linux/x86_64/si_prc.inc new file mode 100644 index 0000000000..a1358d0f07 --- /dev/null +++ b/rtl/linux/x86_64/si_prc.inc @@ -0,0 +1,82 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2005 by Michael Van Canneyt, Peter Vreman, + & Daniel Mantione, members of the Free Pascal development team. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + **********************************************************************} + +{ + Linux ELF startup code for Free Pascal + + + %rdx Contains a function pointer to be registered with `atexit'. + This is how the dynamic linker arranges to have DT_FINI + functions called for shared libraries that have been loaded + before this code runs. + + %rsp The stack contains the arguments and environment: + 0(%rsp) argc + 8(%rsp) argv[0] + ... + (8*argc)(%rsp) NULL + (8*(argc+1))(%rsp) envp[0] + ... + NULL +} + +procedure PASCALMAIN; external name 'PASCALMAIN'; + +{****************************************************************************** + Process start/halt + ******************************************************************************} + +procedure _FPC_proc_start; assembler; nostackframe; public name '_start'; + asm + popq %rsi { Pop the argument count. } + movq %rsi,operatingsystem_parameter_argc + movq %rsp,operatingsystem_parameter_argv { argv starts just at the current stack top. } + leaq 8(,%rsi,8),%rax + addq %rsp,%rax + movq %rax,operatingsystem_parameter_envp + andq $0xfffffffffffffff0,%rsp { Align the stack to a 16 byte boundary to follow the ABI. } + + { Save initial stackpointer } + movq %rsp,__stkptr + + xorq %rbp, %rbp + call PASCALMAIN + end; + + +procedure _FPC_proc_haltproc; assembler; nostackframe; public name '_haltproc'; + asm + .Lhaltproc: + movl $231,%eax { exit_group call } + movzwl operatingsystem_result,%edi + syscall + jmp .Lhaltproc + + { We need this stuff to make gdb behave itself, otherwise + gdb will chokes with SIGILL when trying to debug apps. + } + .section ".note.ABI-tag", "a" + .align 4 + .long 1f - 0f + .long 3f - 2f + .long 1 +0: .asciz "GNU" +1: .align 4 +2: .long 0 + .long 2,4,0 +3: .align 4 + + .section .note.GNU-stack,"",@progbits + end; +