diff options
-rw-r--r-- | compiler/systems/t_linux.pas | 18 | ||||
-rw-r--r-- | rtl/linux/arm/dllprt0.as | 27 | ||||
-rw-r--r-- | rtl/linux/arm/prt0.as | 24 | ||||
-rw-r--r-- | rtl/linux/i386/si_prc.inc | 27 | ||||
-rw-r--r-- | rtl/linux/mips/prt0.as | 10 | ||||
-rw-r--r-- | rtl/linux/mipsel/prt0.as | 15 | ||||
-rw-r--r-- | rtl/linux/powerpc/dllprt0.as | 46 | ||||
-rw-r--r-- | rtl/linux/powerpc/prt0.as | 75 | ||||
-rw-r--r-- | rtl/linux/powerpc64/dllprt0.as | 27 | ||||
-rw-r--r-- | rtl/linux/powerpc64/prt0.as | 103 | ||||
-rw-r--r-- | rtl/linux/sparc/prt0.as | 17 | ||||
-rw-r--r-- | rtl/linux/x86_64/dllprt0.as | 2 | ||||
-rw-r--r-- | rtl/linux/x86_64/prt0.as | 24 | ||||
-rw-r--r-- | rtl/linux/x86_64/si_prc.inc | 14 |
14 files changed, 321 insertions, 108 deletions
diff --git a/compiler/systems/t_linux.pas b/compiler/systems/t_linux.pas index 0712159bc9..4977a116a0 100644 --- a/compiler/systems/t_linux.pas +++ b/compiler/systems/t_linux.pas @@ -330,6 +330,7 @@ Var s,s1,s2 : TCmdStr; found1, found2 : boolean; + linksToSharedLibFiles : boolean; begin result:=False; { set special options for some targets } @@ -432,6 +433,13 @@ begin { Write sharedlibraries like -l<lib>, also add the needed dynamic linker here to be sure that it gets linked this is needed for glibc2 systems (PFV) } + if (isdll) then + begin + Add('INPUT('); + Add(info.DynamicLinker); + Add(')'); + end; + linksToSharedLibFiles := not SharedLibFiles.Empty; if not SharedLibFiles.Empty then begin @@ -497,8 +505,13 @@ begin end; end; - {Entry point.} - add('ENTRY(_start)'); + {Entry point. Only needed for executables, set on the linker command line for + shared libraries. } + if (not isdll) then + if (linksToSharedLibFiles and not linklibc) then + add('ENTRY(_dynamic_start)') + else + add('ENTRY(_start)'); {$ifdef x86_64} {$define LINKERSCRIPT_INCLUDED} @@ -641,7 +654,6 @@ begin add('OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",'); add(' "elf32-littlearm")'); add('OUTPUT_ARCH(arm)'); - add('ENTRY(_start)'); add('SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib");'); add('SECTIONS'); add('{'); diff --git a/rtl/linux/arm/dllprt0.as b/rtl/linux/arm/dllprt0.as index a054991d31..129bc0bb19 100644 --- a/rtl/linux/arm/dllprt0.as +++ b/rtl/linux/arm/dllprt0.as @@ -1,3 +1,18 @@ +/* + * This file is part of the Free Pascal run time library. + * Copyright (c) 2011 by Thomas Schatzl, + * member of the Free Pascal development team. + * + * Startup code for shared libraries, ARM version. + * + * 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. + */ + .file "dllprt0.as" .text .globl _startlib @@ -24,10 +39,6 @@ FPC_SHARED_LIB_START: ldr ip, =__stklen str sp, [ip] - ldr ip, =TC_SYSTEM_ISLIBRARY - mov a1, #1 - str a1, [ip] - /* call main and exit normally */ bl PASCALMAIN ldmdb fp, {fp, sp, pc} @@ -35,14 +46,18 @@ FPC_SHARED_LIB_START: .globl _haltproc .type _haltproc,#function _haltproc: - /* r0 contains exitcode */ + /* reload exitcode */ + ldr r0,=operatingsystem_result + ldr r0,[r0] swi 0x900001 b _haltproc .globl _haltproc_eabi .type _haltproc_eabi,#function _haltproc_eabi: - /* r0 contains exitcode */ + /* reload exitcode */ + ldr r0,=operatingsystem_result + ldr r0,[r0] mov r7,#248 swi 0x0 b _haltproc_eabi diff --git a/rtl/linux/arm/prt0.as b/rtl/linux/arm/prt0.as index b655e7ddd2..750779e19f 100644 --- a/rtl/linux/arm/prt0.as +++ b/rtl/linux/arm/prt0.as @@ -42,6 +42,14 @@ */ .text + .globl _dynamic_start + .type _dynamic_start,#function +_dynamic_start: + ldr ip,=__dl_fini + str a1,[ip] + b _start + + .text .globl _start .type _start,#function _start: @@ -81,11 +89,20 @@ _haltproc: .globl _haltproc_eabi .type _haltproc_eabi,#function _haltproc_eabi: + ldr r0,=__dl_fini + ldr r0,[r0] + cmp r0,#0 + + /* only branch if not equal zero */ + movne lr,pc + bxne r0 /* we require armv5 anyway, so use bx here */ + +.Lloop: ldr r0,=operatingsystem_result - ldrb r0,[r0] - mov r7,#248 + ldr r0,[r0] + mov r7,#248 /* exit group call */ swi 0x0 - b _haltproc_eabi + b .Lloop /* Define a symbol for the first piece of initialized data. */ .data @@ -96,6 +113,7 @@ __data_start: data_start = __data_start .bss + .comm __dl_fini,4 .comm __stkptr,4 .comm operatingsystem_parameter_envp,4 diff --git a/rtl/linux/i386/si_prc.inc b/rtl/linux/i386/si_prc.inc index 1be4506e59..fd46d7f1fb 100644 --- a/rtl/linux/i386/si_prc.inc +++ b/rtl/linux/i386/si_prc.inc @@ -41,7 +41,7 @@ procedure PASCALMAIN; external name 'PASCALMAIN'; ******************************************************************************} var - dlexitproc: pointer; + dlexitproc : pointer; {$ifdef FPC_PIC} function fpc_geteipasebxlocal : pointer; [external name 'fpc_geteipasebx']; @@ -60,12 +60,9 @@ asm {$ifdef FPC_PIC} pushl %ebx pushl %ecx - - call fpc_geteipasebxlocal - addl $_GLOBAL_OFFSET_TABLE_,%ebx - movl dlexitproc@GOT(%ebx),%ecx - movl %edx,(%ecx) + call fpc_geteipasebxlocal + addl $_GLOBAL_OFFSET_TABLE_,%ebx movl operatingsystem_parameter_envp@GOT(%ebx),%ecx movl %eax,(%ecx) @@ -78,7 +75,6 @@ asm popl %ebx movl %ebx,(%edx) {$else FPC_PIC} - movl %edx, dlexitproc movl %eax,operatingsystem_parameter_envp movl %ecx,operatingsystem_parameter_argc movl %ebx,operatingsystem_parameter_argv @@ -103,6 +99,23 @@ asm call PASCALMAIN end; +procedure _FPC_dynamic_proc_start; assembler; nostackframe; public name '_dynamic_start'; +asm + {$ifdef FPC_PIC} + pushl %ebx + call fpc_geteipasebxlocal + addl $_GLOBAL_OFFSET_TABLE_,%ebx + + movl dlexitproc@GOT(%ebx),%ebx + movl %edx,(%ebx) + popl %ebx + {$else} + movl %edx, dlexitproc + {$endif} + jmp _FPC_proc_start +end; + + procedure _FPC_proc_haltproc; assembler; nostackframe; public name '_haltproc'; asm diff --git a/rtl/linux/mips/prt0.as b/rtl/linux/mips/prt0.as index 0dfcec7702..73512fbe03 100644 --- a/rtl/linux/mips/prt0.as +++ b/rtl/linux/mips/prt0.as @@ -14,6 +14,13 @@ .section ".text" .align 4 + .global _dynamic_start + .type _dynamic_start,#function +_dynamic_start: + /* TODO: need to set __dl_fini here */ + b _start + + .align 4 .global _start .type _start,#function _start: @@ -77,6 +84,8 @@ _start: .globl _haltproc .type _haltproc,@function _haltproc: + /* TODO: need to check whether __dl_fini is non-zero and call the function pointer in case */ + li v0,4001 lui a0,0x0 lw a0,0(a0) @@ -87,6 +96,7 @@ _haltproc: .size _start, .-_start .comm __stkptr,4 + .comm __dl_fini,4 .comm operatingsystem_parameter_envp,4 .comm operatingsystem_parameter_argc,4 diff --git a/rtl/linux/mipsel/prt0.as b/rtl/linux/mipsel/prt0.as index 4477c3ea32..2d1b0ab9e6 100644 --- a/rtl/linux/mipsel/prt0.as +++ b/rtl/linux/mipsel/prt0.as @@ -14,6 +14,17 @@ .set noat .section ".text" + + .align 4 + .global _dynamic_start + .type _dynamic_start,@function +_dynamic_start: + /* TODO: check whether this code is correct */ + lui $a2,%hi(__dl_fini) + sw $v0,%lo(__dl_fini)($a2) + b _start + + .align 4 .global _start .type _start,@function @@ -29,6 +40,7 @@ sp ($29) The stack contains the arguments and environment: 0(%esp) argc 4(%esp) argv[0] + ... (4*argc)(%esp) NULL (4*(argc+1))(%esp) envp[0] @@ -75,6 +87,8 @@ _start: .globl _haltproc .type _haltproc,@function _haltproc: + /* TODO: need to check whether __dl_fini is non-zero and call the function pointer in case */ + li $v0,4001 lui $a0,0x0 lw $a0,0($a0) @@ -85,6 +99,7 @@ _haltproc: .size _start, .-_start .comm __stkptr,4 + .comm __dl_fini,4 .comm operatingsystem_parameter_envp,4 .comm operatingsystem_parameter_argc,4 diff --git a/rtl/linux/powerpc/dllprt0.as b/rtl/linux/powerpc/dllprt0.as index f4d157bc0d..54579408d1 100644 --- a/rtl/linux/powerpc/dllprt0.as +++ b/rtl/linux/powerpc/dllprt0.as @@ -20,42 +20,32 @@ .section ".text" .globl FPC_SHARED_LIB_START .type FPC_SHARED_LIB_START,@function - - .globl _start -_start: FPC_SHARED_LIB_START: - mr 26,1 - /* Set up an initial stack frame, and clear the LR. */ - clrrwi 1,1,4 - li 0,0 - stwu 1,-16(1) - mtlr 0 - stw 0,0(1) - lwz 3,0(26) /* get argc */ + mflr 0 + stw 0,4(1) + stwu 1,-32(1) + + /* store argument count (in r3)*/ lis 11,operatingsystem_parameter_argc@ha stw 3,operatingsystem_parameter_argc@l(11); - - addi 4,26,4 /* get argv */ + /* store argument vector (in r4) */ lis 11,operatingsystem_parameter_argv@ha stw 4,operatingsystem_parameter_argv@l(11); - - addi 27,3,1 /* calculate argc + 1 into r27 */ - slwi 27,27,2 /* calculate (argc + 1) * sizeof(char *) into r27 */ - add 5,4,27 /* get address of env[0] */ + /* store environment pointer (in r5) */ lis 11,operatingsystem_parameter_envp@ha stw 5,operatingsystem_parameter_envp@l(11); lis 11,__stkptr@ha stw 1,__stkptr@l(11); - /* update library flag in RTL */ - lis 11,operatingsystem_islibrary@ha - li 6, 1 - stb 6, operatingsystem_islibrary@l(11) - + /* call library initialization */ bl PASCALMAIN - b _haltproc + /* return to the caller */ + addi 1,1,32 + lwz 0,4(1) + mtlr 0 + blr .globl _haltproc .globl FPC_SHARED_LIB_EXIT @@ -63,9 +53,17 @@ FPC_SHARED_LIB_START: .type _haltproc,@function FPC_SHARED_LIB_EXIT: _haltproc: + lis 11,operatingsystem_result@ha + lwz 3,operatingsystem_result@l(3) + li 0,234 /* exit group call */ + sc + + lis 11,operatingsystem_result@ha + lwz 3,operatingsystem_result@l(3) li 0,1 /* exit call */ sc - b _haltproc + /* we should not reach here. Crash horribly */ + trap /* Define a symbol for the first piece of initialized data. */ .section ".data" diff --git a/rtl/linux/powerpc/prt0.as b/rtl/linux/powerpc/prt0.as index 003c1fdd66..e6f51ded20 100644 --- a/rtl/linux/powerpc/prt0.as +++ b/rtl/linux/powerpc/prt0.as @@ -1,22 +1,32 @@ -/* Startup code for programs linked with GNU libc. - Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. +/* + * This file is part of the Free Pascal run time library. + * Copyright (c) 2011 by Thomas Schatzl, + * member of the Free Pascal development team. + * + * Startup code for normal programs, PowerPC version. + * + * 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. + */ - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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. See the GNU - Lesser General Public License for more details. +/* + * Main program entry point for dynamic executables. + */ + .section ".text" + .globl _dynamic_start +_dynamic_start: + lis 11,__dl_fini@ha + stw 7,__dl_fini@l(11) - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + b _start +/* + * Main program entry point for static executables. + */ .section ".text" .globl _start _start: @@ -27,6 +37,7 @@ _start: stwu 1,-16(1) mtlr 0 stw 0,0(1) + lwz 3,0(26) /* get argc */ lis 11,operatingsystem_parameter_argc@ha stw 3,operatingsystem_parameter_argc@l(11); @@ -46,14 +57,36 @@ _start: bl PASCALMAIN - b _haltproc + /* we should not reach here. Crash horribly */ + trap .globl _haltproc .type _haltproc,@function _haltproc: + + lis 11,__dl_fini@ha + lwz 11,__dl_fini@l(11) + + cmpwi 11, 0 + beq .LNoDlFiniCall + + mtctr 11 + bctrl + +.LNoDlFiniCall: + + lis 11,operatingsystem_result@ha + lwz 3,operatingsystem_result@l(11) + li 0,234 /* exit group call */ + sc + + lis 11,operatingsystem_result@ha + lwz 3,operatingsystem_result@l(11) li 0,1 /* exit call */ sc - b _haltproc + /* we should not reach here. Crash horribly */ + trap + /* Define a symbol for the first piece of initialized data. */ .section ".data" @@ -63,6 +96,12 @@ data_start: .section ".bss" + .type __dl_fini, @object + .size __dl_fini, 4 + .global __dl_fini +__dl_fini: + .skip 4 + .type __stkptr, @object .size __stkptr, 4 .global __stkptr diff --git a/rtl/linux/powerpc64/dllprt0.as b/rtl/linux/powerpc64/dllprt0.as index 79907037b9..4896a1d7ae 100644 --- a/rtl/linux/powerpc64/dllprt0.as +++ b/rtl/linux/powerpc64/dllprt0.as @@ -3,7 +3,7 @@ * Copyright (c) 2005 by Thomas Schatzl, * member of the Free Pascal development team. * - * Startup code for normal programs, PowerPC64 version. + * Startup code for shared libraries, PowerPC64 version. * * See the file COPYING.FPC, included in this distribution, * for details about the copyright. @@ -56,7 +56,7 @@ std 2, 40(1) mtctr 0 ld 2, 8(11) - ld 11, 8(11) + ld 11, 16(11) bctr .long 0 .byte 0, 12, 128, 0, 0, 0, 0, 0 @@ -322,31 +322,29 @@ _restvr_31: addi r12,r0,-16 /* * Main program entry point label (function), called by the loader + * + * The document "64-bit PowerPC ELF Application Binary Interface Supplement 1.9" + * pg. 24f specifies the register contents. */ FUNCTION_PROLOG FPC_SHARED_LIB_START - mflr 0 std 0, 16(1) /* save LR */ stdu 1, -144(1) /* save back chain, make frame */ - /* store argument count (in r3?)*/ + /* store argument count (in r3)*/ LOAD_64BIT_VAL 10, operatingsystem_parameter_argc stw 3, 0(10) - /* store argument vector (in r4?) */ + /* store argument vector (in r4) */ LOAD_64BIT_VAL 10, operatingsystem_parameter_argv std 4, 0(10) - /* store environment pointer (in r5?) */ + /* store environment pointer (in r5) */ LOAD_64BIT_VAL 10, operatingsystem_parameter_envp std 5, 0(10) - /* update library flag in RTL */ - LOAD_64BIT_VAL 8, operatingsystem_islibrary - li 6, 1 - stb 6, 0(8) - LOAD_64BIT_VAL 8, __stkptr std 1,0(8) + /* call library initialization */ bl PASCALMAIN nop @@ -355,6 +353,8 @@ FUNCTION_PROLOG FPC_SHARED_LIB_START ld 0,16(1) /* prepare for method return */ mtlr 0 blr +.long 0 +.byte 0, 12, 64, 0, 0, 0, 0, 0 /* this routine is only called when the halt() routine of the RTL embedded in the shared library is called */ @@ -370,7 +370,10 @@ FUNCTION_PROLOG FPC_SHARED_LIB_EXIT lwz 3, 0(3) li 0, 1 sc - b .FPC_SHARED_LIB_EXIT + /* we should not reach here. Crash horribly */ + trap +.long 0 +.byte 0, 12, 64, 0, 0, 0, 0, 0 /* Define a symbol for the first piece of initialized data. */ .section ".data" diff --git a/rtl/linux/powerpc64/prt0.as b/rtl/linux/powerpc64/prt0.as index 9eb7796991..e2b569d211 100644 --- a/rtl/linux/powerpc64/prt0.as +++ b/rtl/linux/powerpc64/prt0.as @@ -56,7 +56,7 @@ std 2, 40(1) mtctr 0 ld 2, 8(11) - ld 11, 8(11) + ld 11, 16(11) bctr .long 0 .byte 0, 12, 128, 0, 0, 0, 0, 0 @@ -321,54 +321,97 @@ _restvr_31: addi r12,r0,-16 */ /* - * Main program entry point label (function), called by the loader + * Main program entry point for dynamic executables. + * + * r7 contains the function pointer that needs to be registered for calling at exit. */ -FUNCTION_PROLOG _start +FUNCTION_PROLOG _dynamic_start + LOAD_64BIT_VAL 11, __dl_fini + std 7,0(11) + LOAD_64BIT_VAL 11, _start + /* do not bother loading the actual function address of _start. We can directly jump to it */ + /* set up GOT pointer from original start function */ + ld 2,8(11) + /* and environment pointer */ + ld 11,16(11) + b _start +.long 0 +.byte 0, 12, 64, 0, 0, 0, 0, 0 - mr 26, 1 /* save stack pointer */ +/* + * Main program entry point for static executables + * + * The document "64-bit PowerPC ELF Application Binary Interface Supplement 1.9" + * pg. 24f specifies that argc/argv/envp are passed in registers r3/r4/r5 respectively, + * but that does not seem to be the case. + * + * However the stack layout and contents are the same as for other platforms, so + * use this. + */ +FUNCTION_PROLOG _start + mr 26,1 /* save stack pointer */ /* Set up an initial stack frame, and clear the LR */ - clrrdi 1, 1, 5 /* align r1 */ - li 0, 0 + clrrdi 1,1,5 /* align r1 */ + li 0,0 stdu 1,-128(1) mtlr 0 - std 0, 0(1) /* r1 = pointer to NULL value */ + std 0,0(1) /* r1 = pointer to NULL value */ /* store argument count (= 0(r1) )*/ - ld 3, 0(26) - LOAD_64BIT_VAL 10, operatingsystem_parameter_argc - stw 3, 0(10) + ld 3,0(26) + LOAD_64BIT_VAL 10,operatingsystem_parameter_argc + stw 3,0(10) /* calculate argument vector address and store (= 8(r1) + 8 ) */ - addi 4, 26, 8 - LOAD_64BIT_VAL 10, operatingsystem_parameter_argv - std 4, 0(10) + addi 4,26,8 + LOAD_64BIT_VAL 10,operatingsystem_parameter_argv + std 4,0(10) /* store environment pointer (= argv + (argc+1)* 8 ) */ - addi 5, 3, 1 - sldi 5, 5, 3 - add 5, 4, 5 + addi 5,3,1 + sldi 5,5,3 + add 5,4,5 LOAD_64BIT_VAL 10, operatingsystem_parameter_envp - std 5, 0(10) + std 5,0(10) - LOAD_64BIT_VAL 8, __stkptr + LOAD_64BIT_VAL 8,__stkptr std 1,0(8) bl PASCALMAIN nop - /* directly jump to exit procedure, not via the function pointer */ - b ._haltproc + /* we should not reach here. Crash horribly */ + trap FUNCTION_PROLOG _haltproc - /* exit group call */ + mflr 0 + std 0,16(1) + stdu 1,-144(1) + + LOAD_64BIT_VAL 11,__dl_fini + ld 11,0(11) + cmpdi 11,0 + beq .LNoCallDlFini + + bl .ptrgl + ld 2,40(1) + +.LNoCallDlFini: + LOAD_64BIT_VAL 3, operatingsystem_result - lwz 3, 0(3) - li 0, 234 + lwz 3,0(3) + /* exit group call */ + li 0,234 sc - /* exit call */ + LOAD_64BIT_VAL 3, operatingsystem_result - lwz 3, 0(3) - li 0, 1 + lwz 3,0(3) + /* exit call */ + li 0,1 sc - b ._haltproc + /* we should not reach here. Crash horribly */ + trap + /* do not bother cleaning up the stack frame, we should not reach here */ +.long 0 +.byte 0, 12, 64, 0, 0, 0, 0, 0 /* Define a symbol for the first piece of initialized data. */ .section ".data" @@ -384,6 +427,12 @@ data_start: __stkptr: .skip 8 + .type __dl_fini, @object + .size __dl_fini, 8 + .global __dl_fini +__dl_fini: + .skip 8 + .type operatingsystem_parameters, @object .size operatingsystem_parameters, 24 operatingsystem_parameters: diff --git a/rtl/linux/sparc/prt0.as b/rtl/linux/sparc/prt0.as index 48d4cd006a..5f441d61f1 100644 --- a/rtl/linux/sparc/prt0.as +++ b/rtl/linux/sparc/prt0.as @@ -19,6 +19,14 @@ 02111-1307 USA. */ .section ".text" + + .align 4 + .global _dynamic_start + .type _dynamic_start,#function +_dynamic_start: + /* TODO: need to set __dl_fini here */ + b _start + .align 4 .global _start .type _start,#function @@ -49,7 +57,7 @@ _start: or %o1,%lo(operatingsystem_parameter_envp),%o1 st %o2, [%o1] - /* Save initial stackpointer */ + /* Save initial stackpointer */ sethi %hi(__stkptr),%o1 or %o1,%lo(__stkptr),%o1 st %sp, [%o1] @@ -57,11 +65,15 @@ _start: /* Call the user program entry point. */ call PASCALMAIN nop + /* Die very horribly if main returns. */ + unimp .globl _haltproc .type _haltproc,@function _haltproc: - mov 188, %g1 /* "exit_group" system call */ + /* TODO: need to check whether __dl_fini is non-zero and call the function pointer in case */ + + mov 188, %g1 /* "exit_group" system call */ ta 0x10 /* dot the system call */ nop /* delay slot */ /* Die very horribly if exit returns. */ @@ -70,6 +82,7 @@ _haltproc: .size _start, .-_start .comm __stkptr,4 + .comm __dl_fini,4 .comm operatingsystem_parameter_envp,4 .comm operatingsystem_parameter_argc,4 diff --git a/rtl/linux/x86_64/dllprt0.as b/rtl/linux/x86_64/dllprt0.as index 8dcbccf7ca..477da7785b 100644 --- a/rtl/linux/x86_64/dllprt0.as +++ b/rtl/linux/x86_64/dllprt0.as @@ -44,8 +44,6 @@ FPC_SHARED_LIB_START: .globl _start .type _start,@function _startlib: -# movq %rdx,%r9 /* Address of the shared library termination -# function. */ pushq %rbx movq operatingsystem_parameter_argc@GOTPCREL(%rip),%rbx movq %rdi,(%rbx) diff --git a/rtl/linux/x86_64/prt0.as b/rtl/linux/x86_64/prt0.as index 02fbeeb75c..b8e01f409d 100644 --- a/rtl/linux/x86_64/prt0.as +++ b/rtl/linux/x86_64/prt0.as @@ -16,8 +16,10 @@ # /* This is the canonical entry point, usually the first thing in the text - segment. The SVR4/i386 ABI (pages 3-31, 3-32) says that when the entry - point runs, most registers' values are unspecified, except for: + segment. The document "System V Application Binary Interface AMD64 + Architecture Processor Supplement Version 0.99.5" pg. 30 defines that + the entry point runs, most registers' values are unspecified, except + for: %rdx Contains a function pointer to be registered with `atexit'. This is how the dynamic linker arranges to have DT_FINI @@ -35,11 +37,17 @@ */ .text + .globl _dynamic_start + .type _dynamic_start,@function +_dynamic_start: + movq __dl_fini@GOTPCREL(%rip),%rax + movq %rdx,(%rax) + jmp _start + + .text .globl _start .type _start,@function _start: -# movq %rdx,%r9 /* Address of the shared library termination -# function. */ popq %rsi /* Pop the argument count. */ movq operatingsystem_parameter_argc@GOTPCREL(%rip),%rax movq %rsi,(%rax) @@ -62,6 +70,13 @@ _start: .globl _haltproc .type _haltproc,@function _haltproc: + movq __dl_fini@GOTPCREL(%rip),%rax + movq (%rax),%rax + testq %rax,%rax + jz .LNoDlFiniCall + call *%rax +.LNoDlFiniCall: + movq operatingsystem_result@GOTPCREL(%rip),%rax movzwl (%rax),%edi movl $231,%eax /* exit_group call */ @@ -78,6 +93,7 @@ __data_start: .bss .comm __stkptr,8 + .comm __dl_fini,8 .comm operatingsystem_parameter_envp,8 .comm operatingsystem_parameter_argc,8 diff --git a/rtl/linux/x86_64/si_prc.inc b/rtl/linux/x86_64/si_prc.inc index a1358d0f07..5f0bcd3e0d 100644 --- a/rtl/linux/x86_64/si_prc.inc +++ b/rtl/linux/x86_64/si_prc.inc @@ -37,6 +37,9 @@ procedure PASCALMAIN; external name 'PASCALMAIN'; Process start/halt ******************************************************************************} +var + dlexitproc: pointer; + procedure _FPC_proc_start; assembler; nostackframe; public name '_start'; asm popq %rsi { Pop the argument count. } @@ -54,9 +57,20 @@ procedure _FPC_proc_start; assembler; nostackframe; public name '_start'; call PASCALMAIN end; +procedure _FPC_dynamic_proc_start; assembler; nostackframe; public name '_dynamic_start'; + asm + movq %rdx,dlexitproc + jmp _FPC_proc_start + end; procedure _FPC_proc_haltproc; assembler; nostackframe; public name '_haltproc'; asm + movq dlexitproc,%rdx + testq %rdx,%rdx + jz .Lhaltproc + + call *%rdx + .Lhaltproc: movl $231,%eax { exit_group call } movzwl operatingsystem_result,%edi |