Browse Source

* adjusted startup code so it guarantees 16 byte stack alignment on program
startup for Linux/i386 (since the code generator won't keep the 16 byte
alignment (yet?) for that platform, it won't make much difference in
practice)

git-svn-id: trunk@22383 -

Jonas Maebe 13 years ago
parent
commit
0ad1a26c61

+ 4 - 5
rtl/linux/i386/cprt21.as

@@ -39,21 +39,20 @@ _start:
         /* First locate the start of the environment variables */
         /* First locate the start of the environment variables */
 
 
         popl    %esi
         popl    %esi
-        movl    %eax,%edi
 
 
         movl    %esp,%ebx               /* Points to the arguments */
         movl    %esp,%ebx               /* Points to the arguments */
         movl    %esi,%eax
         movl    %esi,%eax
         incl    %eax
         incl    %eax
         shll    $2,%eax
         shll    $2,%eax
         addl    %esp,%eax
         addl    %esp,%eax
-        andl    $0xfffffff8,%esp        /* Align stack */
+        andl    $0xfffffff0,%esp        /* Align stack to 16 bytes */
 
 
         movl    %eax,operatingsystem_parameter_envp    /* Move the environment pointer */
         movl    %eax,operatingsystem_parameter_envp    /* Move the environment pointer */
         movl    %esi,operatingsystem_parameter_argc    /* Move the argument counter    */
         movl    %esi,operatingsystem_parameter_argc    /* Move the argument counter    */
         movl    %ebx,operatingsystem_parameter_argv    /* Move the argument pointer    */
         movl    %ebx,operatingsystem_parameter_argv    /* Move the argument pointer    */
 
 
         xorl    %ebp,%ebp
         xorl    %ebp,%ebp
-        pushl   %edi
+        pushl   %edi  /* __libc_start_main takes 7 arguments -> push 1 extra to keep 16 byte stack alignment */
         pushl   %esp
         pushl   %esp
         pushl   %edx
         pushl   %edx
         pushl   $_fini_dummy
         pushl   $_fini_dummy
@@ -78,8 +77,8 @@ main:
 
 
         /* start the program */
         /* start the program */
         xorl    %ebp,%ebp
         xorl    %ebp,%ebp
-        call    PASCALMAIN
-        hlt
+        /* jmp to keep stack alignment */
+        jmp     PASCALMAIN
 
 
         .globl _haltproc
         .globl _haltproc
         .type _haltproc,@function
         .type _haltproc,@function

+ 2 - 0
rtl/linux/i386/dllprt0.as

@@ -24,6 +24,7 @@ _startlib:
 FPC_SHARED_LIB_START:
 FPC_SHARED_LIB_START:
         pushl   %ebp
         pushl   %ebp
         movl    %esp,%ebp
         movl    %esp,%ebp
+        subl    $8, %esp         /* align back to 16 bytes if it was before the call */
 
 
         movl    8(%ebp),%eax
         movl    8(%ebp),%eax
         movl    12(%ebp),%ecx
         movl    12(%ebp),%ecx
@@ -50,6 +51,7 @@ _haltproc2:             # GAS <= 2.15 bug: generates larger jump if a label is e
         .globl  FPC_SHARED_LIB_EXIT
         .globl  FPC_SHARED_LIB_EXIT
         .type   FPC_SHARED_LIB_EXIT,@function
         .type   FPC_SHARED_LIB_EXIT,@function
 FPC_SHARED_LIB_EXIT:
 FPC_SHARED_LIB_EXIT:
+        subl    $12, %esp               /* align back to 16 bytes if it was before the call */
 	call	lib_exit
 	call	lib_exit
         xorl    %eax,%eax
         xorl    %eax,%eax
         incl    %eax                    /* eax=1, exit call */
         incl    %eax                    /* eax=1, exit call */

+ 10 - 6
rtl/linux/i386/gprt21.as

@@ -22,22 +22,20 @@
 _start:
 _start:
         /* First locate the start of the environment variables */
         /* First locate the start of the environment variables */
         popl    %esi
         popl    %esi
-        movl    %eax,%edi
 
 
         movl    %esp,%ebx               /* Points to the arguments */
         movl    %esp,%ebx               /* Points to the arguments */
         movl    %esi,%eax
         movl    %esi,%eax
         incl    %eax
         incl    %eax
         shll    $2,%eax
         shll    $2,%eax
         addl    %esp,%eax
         addl    %esp,%eax
-        andl    $0xfffffff8,%esp        /* Align stack */
+        andl    $0xfffffff0,%esp        /* Align stack to 16 bytes */
 
 
         movl    %eax,operatingsystem_parameter_envp    /* Move the environment pointer */
         movl    %eax,operatingsystem_parameter_envp    /* Move the environment pointer */
         movl    %esi,operatingsystem_parameter_argc    /* Move the argument counter    */
         movl    %esi,operatingsystem_parameter_argc    /* Move the argument counter    */
         movl    %ebx,operatingsystem_parameter_argv    /* Move the argument pointer    */
         movl    %ebx,operatingsystem_parameter_argv    /* Move the argument pointer    */
 
 
-        movl    %edi,%eax
         xorl    %ebp,%ebp
         xorl    %ebp,%ebp
-        pushl   %eax
+        pushl   %eax                    /* __libc_start_main takes 7 arguments -> push 1 extra to keep 16 byte stack alignment */
         pushl   %esp
         pushl   %esp
         pushl   %edx
         pushl   %edx
         pushl   $_fini_dummy
         pushl   $_fini_dummy
@@ -58,13 +56,19 @@ cmain:
         movl    %edi,___fpc_ret_edi
         movl    %edi,___fpc_ret_edi
         pushl   %eax
         pushl   %eax
 
 
+        /* align stack to 16 bytes before call */
+        subl    $12, %esp
+
         call    __gmon_start__
         call    __gmon_start__
 
 
+        /* restore stack */
+        addl    $12, %esp
+
         /* Save initial stackpointer */
         /* Save initial stackpointer */
         movl    %esp,__stkptr
         movl    %esp,__stkptr
 
 
-        /* start the program */
-        call    PASCALMAIN
+        /* start the program (jmp to keep stack alignment) */
+        jmp    PASCALMAIN
         hlt
         hlt
 
 
         .globl _haltproc
         .globl _haltproc

+ 1 - 1
rtl/linux/i386/prt0.as

@@ -45,7 +45,7 @@ _start:
         popl    %ecx                    /* Get argc in ecx */
         popl    %ecx                    /* Get argc in ecx */
         movl    %esp,%ebx               /* Esp now points to the arguments */
         movl    %esp,%ebx               /* Esp now points to the arguments */
         leal    4(%esp,%ecx,4),%eax     /* The start of the environment is: esp+4*eax+4 */
         leal    4(%esp,%ecx,4),%eax     /* The start of the environment is: esp+4*eax+4 */
-        andl    $0xfffffff8,%esp        /* Align stack */
+        andl    $0xfffffff0,%esp        /* Align stack to 16 bytes */
 
 
         leal    operatingsystem_parameters,%edi
         leal    operatingsystem_parameters,%edi
         stosl   /* Move the environment pointer */
         stosl   /* Move the environment pointer */

+ 1 - 1
rtl/linux/i386/si_c21.inc

@@ -61,7 +61,7 @@ asm
 
 
   movl    %esp,%ebx               { Esp now points to the arguments }
   movl    %esp,%ebx               { Esp now points to the arguments }
   leal    4(%esp,%ecx,4),%eax     { The start of the environment is: esp+4*eax+4 }
   leal    4(%esp,%ecx,4),%eax     { The start of the environment is: esp+4*eax+4 }
-  andl    $0xfffffff8,%esp        { Align stack }
+  andl    $0xfffffff0,%esp        { Align stack to 16 bytes }
 
 
   {$ifdef FPC_PIC}
   {$ifdef FPC_PIC}
         pushl %edx
         pushl %edx

+ 1 - 1
rtl/linux/i386/si_c21g.inc

@@ -122,7 +122,7 @@ asm
 
 
   movl    %esp,%ebx               { Esp now points to the arguments }
   movl    %esp,%ebx               { Esp now points to the arguments }
   leal    4(%esp,%ecx,4),%eax     { The start of the environment is: esp+4*eax+4 }
   leal    4(%esp,%ecx,4),%eax     { The start of the environment is: esp+4*eax+4 }
-  andl    $0xfffffff8,%esp        { Align stack }
+  andl    $0xfffffff0,%esp        { Align stack to 16 bytes }
 
 
   {$ifdef FPC_PIC}
   {$ifdef FPC_PIC}
         pushl %edx
         pushl %edx

+ 2 - 2
rtl/linux/i386/si_prc.inc

@@ -55,7 +55,7 @@ asm
 
 
   movl    %esp,%ebx               { Esp now points to the arguments }
   movl    %esp,%ebx               { Esp now points to the arguments }
   leal    4(%esp,%ecx,4),%eax     { The start of the environment is: esp+4*eax+4 }
   leal    4(%esp,%ecx,4),%eax     { The start of the environment is: esp+4*eax+4 }
-  andl    $0xfffffff8,%esp        { Align stack }
+  andl    $0xfffffff0,%esp        { Align stack to 16 bytes }
 
 
   {$ifdef FPC_PIC}
   {$ifdef FPC_PIC}
         pushl %ebx
         pushl %ebx
@@ -118,7 +118,7 @@ end;
 
 
 procedure _FPC_proc_haltproc; assembler; nostackframe; public name '_haltproc';
 procedure _FPC_proc_haltproc; assembler; nostackframe; public name '_haltproc';
 asm
 asm
-
+  addl  $12, %esp  { align stack back to 16 bytes }
 .Lhaltproc:
 .Lhaltproc:
   {$ifdef FPC_PIC}
   {$ifdef FPC_PIC}
         call  fpc_geteipasebxlocal
         call  fpc_geteipasebxlocal