Browse Source

* several fixes by Pierre Pede (parts of his patch to mantis #12492)
o fixed gprof under linux/i386
o fixed pic-compilation of the linux/i386 rtl
o initialisation of linux shared libraries is now possible with pic-code

git-svn-id: trunk@13703 -

Jonas Maebe 16 years ago
parent
commit
92ff07deaf

+ 2 - 2
compiler/systems/t_linux.pas

@@ -1074,8 +1074,8 @@ begin
 
 
  { Create some replacements }
  { Create some replacements }
  { note: linux does not use exportlib.initname/fininame due to the custom startup code }
  { note: linux does not use exportlib.initname/fininame due to the custom startup code }
-  InitStr:='-init FPC_LIB_START';
-  FiniStr:='-fini FPC_LIB_EXIT';
+  InitStr:='-init FPC_SHARED_LIB_START';
+  FiniStr:='-fini FPC_SHARED_LIB_EXIT';
   SoNameStr:='-soname '+ExtractFileName(current_module.sharedlibfilename^);
   SoNameStr:='-soname '+ExtractFileName(current_module.sharedlibfilename^);
 
 
 { Call linker }
 { Call linker }

+ 12 - 0
rtl/i386/i386.inc

@@ -94,10 +94,12 @@ function mmx_support : boolean;
        mmx_support:=false;
        mmx_support:=false;
   end;
   end;
 
 
+{$ifndef FPC_PIC}
 {$if not defined(FPC_SYSTEM_HAS_MOVE) and defined(REGCALL) }
 {$if not defined(FPC_SYSTEM_HAS_MOVE) and defined(REGCALL) }
 {$define USE_FASTMOVE}
 {$define USE_FASTMOVE}
 {$i fastmove.inc}
 {$i fastmove.inc}
 {$endif FPC_SYSTEM_HAS_MOVE}
 {$endif FPC_SYSTEM_HAS_MOVE}
+{$endif FPC_PIC}
 
 
 procedure fpc_cpuinit;
 procedure fpc_cpuinit;
   begin
   begin
@@ -1476,7 +1478,17 @@ asm
         jl      .Lj3596
         jl      .Lj3596
 .Lj3603:
 .Lj3603:
 // [104] If declocked(l^) then
 // [104] If declocked(l^) then
+  {$ifdef FPC_PIC}
+	pushl	%ebx
+        call	fpc_geteipasebx
+        addl	$_GLOBAL_OFFSET_TABLE_,%ebx
+        movl	ismultithread@GOT(%ebx),%ebx
+        movl	(%ebx),%ebx
+        cmp	$0, %ebx
+	popl    %ebx
+  {$else FPC_PIC}
         cmpl    $0,ismultithread
         cmpl    $0,ismultithread
+  {$endif FPC_PIC}
         jne     .Lj3610
         jne     .Lj3610
         decl    (%edx)
         decl    (%edx)
         je      .Lj3620
         je      .Lj3620

+ 7 - 3
rtl/linux/i386/dllprt0.as

@@ -19,9 +19,9 @@
         .globl  _startlib
         .globl  _startlib
         .type   _startlib,@function
         .type   _startlib,@function
 _startlib:
 _startlib:
-        .globl  FPC_LIB_START
-        .type   FPC_LIB_START,@function
-FPC_LIB_START:
+        .globl  FPC_SHARED_LIB_START
+        .type   FPC_SHARED_LIB_START,@function
+FPC_SHARED_LIB_START:
         pushl   %ebp
         pushl   %ebp
         movl    %esp,%ebp
         movl    %esp,%ebp
 
 
@@ -47,6 +47,10 @@ FPC_LIB_START:
         .type   _haltproc,@function
         .type   _haltproc,@function
 _haltproc:
 _haltproc:
 _haltproc2:             # GAS <= 2.15 bug: generates larger jump if a label is exported
 _haltproc2:             # GAS <= 2.15 bug: generates larger jump if a label is exported
+        .globl  FPC_SHARED_LIB_EXIT
+        .type   FPC_SHARED_LIB_EXIT,@function
+FPC_SHARED_LIB_EXIT:
+	call	lib_exit
         xorl    %eax,%eax
         xorl    %eax,%eax
         incl    %eax                    /* eax=1, exit call */
         incl    %eax                    /* eax=1, exit call */
         movzwl  operatingsystem_result,%ebx
         movzwl  operatingsystem_result,%ebx

+ 90 - 11
rtl/linux/i386/si_c.inc

@@ -46,6 +46,7 @@ procedure libc_setfpucw; external name '__setfpucw';
 procedure libc_start_main; external name '__libc_start_main';
 procedure libc_start_main; external name '__libc_start_main';
 
 
 procedure PASCALMAIN; external name 'PASCALMAIN';
 procedure PASCALMAIN; external name 'PASCALMAIN';
+Procedure fpc_geteipasebx;[external name 'fpc_geteipasebx'];
 
 
 {******************************************************************************
 {******************************************************************************
                           C library start/halt
                           C library start/halt
@@ -53,38 +54,102 @@ procedure PASCALMAIN; external name 'PASCALMAIN';
 {$asmmode ATT}
 {$asmmode ATT}
 
 
 procedure _FPC_libc_start; assembler; nostackframe; public name '_start';
 procedure _FPC_libc_start; assembler; nostackframe; public name '_start';
+var
+  _ebx: LongInt;
+  _ecx: LongInt;
+  _libc_init_proc: LongInt;
 asm
 asm
   { First locate the start of the environment variables }
   { First locate the start of the environment variables }
   popl    %ecx                    { Get argc in ecx }
   popl    %ecx                    { Get argc in ecx }
-  movl    %esp,%ebx               { Esp now points to the arguments }
+
+  {$ifdef FPC_PIC}
+        movl    %esp,_ebx               { Points to the arguments }
+        movl    %ecx,_ecx               
+  {$else FPC_PIC}
+        movl    %esp,%ebx               { Points to the arguments }
+  {$endif FPC_PIC}
+
   leal    4(%esp,%ecx,4),%eax     { The start of the environment is: esp+4*eax+8 }
   leal    4(%esp,%ecx,4),%eax     { The start of the environment is: esp+4*eax+8 }
   andl    $0xfffffff8,%esp        { Align stack }
   andl    $0xfffffff8,%esp        { Align stack }
 
 
-  movl    %eax,operatingsystem_parameter_envp    { Move the environment pointer }
-  movl    %ecx,operatingsystem_parameter_argc    { Move the argument counter    }
-  movl    %ebx,operatingsystem_parameter_argv    { Move the argument pointer    }
+  {$ifdef FPC_PIC}
+        pushl   %ecx
+        call  fpc_geteipasebx
+        addl  $_GLOBAL_OFFSET_TABLE_,%ebx
+        movl  operatingsystem_parameter_envp@GOT(%ebx),%ecx
+        movl  %eax,(%ecx)
+        movl  libc_environ@GOT(%ebx),%ecx
+        movl  %eax,(%ecx)
+
+        pushl %eax
+        movl  operatingsystem_parameter_argc@GOT(%ebx),%ecx
+        movl  _ecx,%eax
+        movl  %eax,(%ecx)
+        movl  operatingsystem_parameter_argv@GOT(%ebx),%ecx
+        movl  _ebx,%eax
+        movl  %eax,(%ecx)
+	popl  %eax
+
+        popl  %ecx
+        movl  _ebx,%ebx
+  {$else FPC_PIC}
+	movl    %eax,operatingsystem_parameter_envp    { Move the environment pointer }
+	movl    %ecx,operatingsystem_parameter_argc    { Move the argument counter    }
+	movl    %ebx,operatingsystem_parameter_argv    { Move the argument pointer    }
+  	movl    %eax,libc_environ          { libc environ }
+  {$endif FPC_PIC}
 
 
-  movl    %eax,libc_environ          { libc environ }
 
 
   pushl   %eax
   pushl   %eax
   pushl   %ebx
   pushl   %ebx
   pushl   %ecx
   pushl   %ecx
 
 
   call    libc_init             { init libc }
   call    libc_init             { init libc }
-  movzwl  libc_fpu_control,%eax
+
+  {$ifdef FPC_PIC}
+        pushl   %ecx
+  	pushl   %ebx
+        call  fpc_geteipasebx
+        addl  $_GLOBAL_OFFSET_TABLE_,%ebx
+        movl  libc_init_proc@GOT(%ebx),%ecx
+	movl  (%ecx),%ecx
+	movl  %ecx,_libc_init_proc
+  	popl    %ebx
+        popl    %ecx
+  {$else FPC_PIC}
+	movzwl  libc_fpu_control,%eax
+  {$endif FPC_PIC}
+
+
   pushl   %eax
   pushl   %eax
   call    libc_setfpucw
   call    libc_setfpucw
   popl    %eax
   popl    %eax
   pushl   $libc_fini_proc
   pushl   $libc_fini_proc
   call    libc_atexit
   call    libc_atexit
   popl    %eax
   popl    %eax
-  call    libc_init_proc
+
+  {$ifdef FPC_PIC}
+	call    _libc_init_proc
+  {$else FPC_PIC}
+	call    libc_init_proc
+  {$endif FPC_PIC}
 
 
   popl    %eax
   popl    %eax
   popl    %eax
   popl    %eax
 
 
   { Save initial stackpointer }
   { Save initial stackpointer }
-  movl    %esp,initialstkptr
+  {$ifdef FPC_PIC}
+        pushl   %ecx
+  	pushl   %ebx
+        call  fpc_geteipasebx
+        addl  $_GLOBAL_OFFSET_TABLE_,%ebx
+        movl  initialstkptr@GOT(%ebx),%ecx
+	movl  %esp,(%ecx)
+  	popl    %ebx
+        popl    %ecx
+  {$else FPC_PIC}
+	movl    %esp,initialstkptr
+  {$endif FPC_PIC}
 
 
   xorl    %ebp,%ebp
   xorl    %ebp,%ebp
   call    PASCALMAIN              { start the program }
   call    PASCALMAIN              { start the program }
@@ -93,12 +158,26 @@ end;
 procedure _FPC_libc_haltproc; assembler; nostackframe; public name '_haltproc';
 procedure _FPC_libc_haltproc; assembler; nostackframe; public name '_haltproc';
 asm
 asm
 .Lhaltproc:
 .Lhaltproc:
-{$if sizeof(ExitCode)=2}
+
+ {$ifdef FPC_PIC}
+  call    fpc_geteipasebx
+  addl    $_GLOBAL_OFFSET_TABLE_,%ebx
+  movl    ExitCode@GOT(%ebx),%ebx
+ {$if sizeof(ExitCode)=2}
+  movzwl  (%ebx),%ebx
+ {$else}
+  mov     (%ebx),%ebx
+ {$endif}
+{$else FPC_PIC}
+ {$if sizeof(ExitCode)=2}
   movzwl  ExitCode,%ebx
   movzwl  ExitCode,%ebx
-{$else}
+ {$else}
   mov     ExitCode,%ebx
   mov     ExitCode,%ebx
-{$endif}
+ {$endif}
+{$endif FPC_PIC}
+
   pushl   %ebx
   pushl   %ebx
+
   call    libc_exit
   call    libc_exit
   xorl    %eax,%eax
   xorl    %eax,%eax
   incl    %eax                    { eax=1, exit call }
   incl    %eax                    { eax=1, exit call }

+ 141 - 58
rtl/linux/i386/si_c21.inc

@@ -33,83 +33,166 @@
          argc <--- esp
          argc <--- esp
 }
 }
 
 
+{$asmmode att}
+
 var
 var
-  libc21_fpc_ret, libc21_fpc_ret_ebx, libc21_fpc_ret_ebp: ptrint; { return address to libc }
+  dlexitproc: pointer; { atexit from loader }
 
 
-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 libc_start_main; external name '__libc_start_main';
-
 procedure PASCALMAIN; external name 'PASCALMAIN';
 procedure PASCALMAIN; external name 'PASCALMAIN';
 
 
+{ Some helpers }
+
+procedure _init_fini_dummy; compilerproc; nostackframe; assembler;
+asm
+  ret
+end; 
+
 {******************************************************************************
 {******************************************************************************
-                         glibc 2.1 library start/halt
+                       glibc 2.1 lib + profiling start/halt
  ******************************************************************************}
  ******************************************************************************}
-{$asmmode ATT}
 
 
 procedure _FPC_libc21_start; assembler; nostackframe; public name '_start';
 procedure _FPC_libc21_start; assembler; nostackframe; public name '_start';
 asm
 asm
+  xorl    %ebp,%ebp
   { First locate the start of the environment variables }
   { First locate the start of the environment variables }
 
 
-  popl    %esi
-  movl    %eax,%edi
+  popl    %ecx                    { Get argc in ecx }
 
 
-  movl    %esp,%ebx               { Points to the arguments }
-  movl    %esi,%eax
-  incl    %eax
-  shll    $2,%eax
-  addl    %esp,%eax
+  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 }
   andl    $0xfffffff8,%esp        { Align stack }
   andl    $0xfffffff8,%esp        { Align stack }
 
 
-  movl    %eax,operatingsystem_parameter_envp    { Move the environment pointer }
-  movl    %esi,operatingsystem_parameter_argc    { Move the argument counter    }
-  movl    %ebx,operatingsystem_parameter_argv    { Move the argument pointer    }
-
-  xorl    %ebp,%ebp
-  pushl   %edi
-  pushl   %esp
-  pushl   %edx
-  pushl   $.Lfini_dummy
-  pushl   $.Linit_dummy
-  pushl   %ebx
-  pushl   %esi
-  pushl   $.Lmain
-  call    libc_start_main
-.Linit_dummy:
-.Lfini_dummy:
-  ret
-
-{ fake main routine which will be run from libc }
-.Lmain:
-  { save return address }
-  popl    %eax
-  movl    %eax,libc21_fpc_ret
-  movl    %ebx,libc21_fpc_ret_ebx
-  movl    %ebp,libc21_fpc_ret_ebp
-  pushl   %eax
+  {$ifdef FPC_PIC}
+        pushl %edx
+        pushl %ebx
+        pushl %ecx
+	
+	call .Lpiclab
+.Lpiclab:
+        popl  %ebx
+        addl  $_GLOBAL_OFFSET_TABLE_,%ebx
+
+	movl  dlexitproc@GOT(%ebx),%ecx
+	movl  %edx,(%ecx)
+
+	movl  operatingsystem_parameter_envp@GOT(%ebx),%ecx
+	movl  %eax,(%ecx)
+
+	movl  operatingsystem_parameter_argc@GOT(%ebx),%edx
+	popl  %ecx
+	movl  %ecx,(%edx)
+
+	movl  operatingsystem_parameter_argv@GOT(%ebx),%edx
+	popl  %ebx
+	movl  %ebx,(%edx)
+	popl  %edx
+  {$else FPC_PIC}
+  	movl  %edx, dlexitproc
+  	movl  %eax,operatingsystem_parameter_envp
+  	movl  %ecx,operatingsystem_parameter_argc
+  	movl  %ebx,operatingsystem_parameter_argv
+  {$endif FPC_PIC}
 
 
   { Save initial stackpointer }
   { Save initial stackpointer }
-  movl    %esp,initialstkptr
-
-  { start the program }
-  xorl    %ebp,%ebp
-  call    PASCALMAIN
-  hlt
+  {$ifdef FPC_PIC}
+        pushl %ebx
+        call  .Lpiclab2
+.Lpiclab2:
+        popl  %ebx
+        addl  $_GLOBAL_OFFSET_TABLE_,%ebx
+	movl  initialstkptr@GOT(%ebx),%ebx
+  	movl  %esp,(%ebx)
+	popl  %ebx
+  {$else FPC_PIC}
+  	movl    %esp,initialstkptr
+  {$endif FPC_PIC}
+
+        { int __libc_start_main(
+		int *(main) (int, char * *, char * *), 
+		int argc, 
+		char * * ubp_av, 
+		void (*init) (void), 
+		void (*fini) (void), 
+		void (*rtld_fini) (void), 
+		void (* stack_end)); } 
+
+        pushl %ebp   			{ padding }
+        pushl %esp   			{ stack_end }
+        pushl %edx   			{ function to be registered with
+                      			  atexit(), passed by loader }
+  	pushl $_init_fini_dummy
+  	pushl $_init_fini_dummy
+	pushl %ebx             		{ Push second argument: argv.  }
+	pushl %ecx             		{ Push first argument: argc.  }
+
+	pushl $PASCALMAIN
+
+  	call  libc_start_main
+	hlt
 end;
 end;
 
 
 procedure _FPC_libc21_haltproc; assembler; nostackframe; public name '_haltproc';
 procedure _FPC_libc21_haltproc; assembler; nostackframe; public name '_haltproc';
 asm
 asm
-{$if sizeof(ExitCode)=2}
-  movzwl  ExitCode,%eax
-{$else}
-  mov     ExitCode,%eax
-{$endif}
-
-  movl    libc21_fpc_ret,%edx         { return to libc }
-  movl    libc21_fpc_ret_ebp,%ebp
-  movl    libc21_fpc_ret_ebx,%ebx
-  push    %edx
-  ret
+.Lhaltproc:
+  {$ifdef FPC_PIC}
+        call  .Lpiclab
+.Lpiclab:
+        popl  %ebx
+        addl  $_GLOBAL_OFFSET_TABLE_,%ebx
+        movl  dlexitproc@GOT(%ebx),%eax
+        movl  (%eax),%eax
+  {$else FPC_PIC}
+        movl    dlexitproc,%eax
+  {$endif FPC_PIC}
+  testl   %eax,%eax
+  je      .Lnodlexitproc
+  call    *%eax
+.Lnodlexitproc:
+  movl    syscall_nr_exit_group,%eax
+
+{$ifdef FPC_PIC}
+  call    .Lpiclab2
+.Lpiclab2:
+  popl    %ebx
+  addl    $_GLOBAL_OFFSET_TABLE_,%ebx
+  movl    ExitCode@GOT(%ebx),%ebx
+ {$if sizeof(ExitCode)=2}
+  movzwl  (%ebx),%ebx
+ {$else}
+  mov     (%ebx),%ebx
+ {$endif}
+{$else FPC_PIC}
+ {$if sizeof(ExitCode)=2}
+  movzwl  ExitCode,%ebx
+ {$else}
+  mov     ExitCode,%ebx
+ {$endif}
+{$endif FPC_PIC}
+
+  int     $0x80
+  movl    syscall_nr_exit,%eax
+
+{$ifdef FPC_PIC}
+  call    .Lpiclab3
+.Lpiclab3:
+  popl    %ebx
+  addl    $_GLOBAL_OFFSET_TABLE_,%ebx
+  movl    ExitCode@GOT(%ebx),%ebx
+ {$if sizeof(ExitCode)=2}
+  movzwl  (%ebx),%ebx
+ {$else}
+  mov     (%ebx),%ebx
+ {$endif}
+{$else FPC_PIC}
+
+ {$if sizeof(ExitCode)=2}
+  movzwl  ExitCode,%ebx
+ {$else}
+  mov     ExitCode,%ebx
+ {$endif}
+{$endif FPC_PIC}
+
+  int     $0x80
+  jmp     .Lhaltproc
 end;
 end;
-

+ 197 - 89
rtl/linux/i386/si_c21g.inc

@@ -33,116 +33,224 @@
          argc <--- esp
          argc <--- esp
 }
 }
 
 
-var
-  gmon_etext: longint; external name '_etext';
-  gmon_start: longint; external name '_start';
-  gmon_mcleanup: procedure; external name '_mcleanup';
-  libc21_fpc_ret, libc21_fpc_ret_ebx: ptrint; { return address to libc }
-  libc21_fpc_ret_esi, libc21_fpc_ret_edi: ptrint;
-  gmon_monstarted: longint = 0;
+{
+    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.
 
 
-procedure gmon_monstartup; external name 'monstartup';
+    See the file COPYING.FPC, included in this distribution,
+    for details about the copyright.
 
 
-procedure libc_atexit; external name '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';
+    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
+}
+
+{$asmmode att}
 
 
+{ Some helpers }
+
+{$ifdef FPC_PIC}
+function fpc0geteipasebx : pointer; compilerproc; nostackframe; assembler; 
+asm  
+  movl (%esp),%ebx  
+  ret  
+end;
+{$endif FPC_PIC}
+
+procedure _init_fini_dummy; compilerproc; nostackframe; assembler;
+asm
+  ret
+end;
+
+procedure gmon_mcleanup; cdecl; external name '_mcleanup';
+procedure gmon_monstartup (main,etext : pointer);cdecl;external name 'monstartup';
+
+procedure libc_start_main; external name '__libc_start_main';
 procedure PASCALMAIN; external name 'PASCALMAIN';
 procedure PASCALMAIN; external name 'PASCALMAIN';
 
 
+var
+  dlexitproc: pointer; { atexit from loader }
+
+  gmon_start : record end;external name 'PASCALMAIN';
+  gmon_etext : record end;external name '_etext';
+
+  gmon_monstarted: longint = 0;
+
 {******************************************************************************
 {******************************************************************************
-                       glibc 2.1 lib + profiling start/halt
+                          Process start/halt
  ******************************************************************************}
  ******************************************************************************}
-{$asmmode ATT}
 
 
-procedure _FPC_libc21_gprof_gmon_start; assembler; nostackframe;
-asm
-  pushl   %ebp
-  movl    gmon_monstarted,%eax
-  leal    0x1(%eax),%edx
-  movl    %esp,%ebp
-  movl    %edx,gmon_monstarted
-  testl   %eax,%eax
-  jnz     .Lnomonstart
-  pushl   $gmon_start
-  pushl   $gmon_etext                  { Initialize gmon }
-  call    gmon_monstartup
-  addl    $8,%esp
-  pushl   $gmon_mcleanup
-  call    libc_atexit
-  addl    $4,%esp
-.Lnomonstart:
-  movl   %ebp,%esp
-  popl   %ebp
-  ret
+procedure _FPC_libc21_gprof_gmon_start; public name '_FPC_libc21_gprof_gmon_start';
+begin
+  if gmon_monstarted=0 then
+  begin
+    inc(gmon_monstarted);
+    gmon_monstartup(@gmon_start,@gmon_etext);
+  end;
+  PASCALMAIN;
 end;
 end;
 
 
 procedure _FPC_libc21_gprof_start; assembler; nostackframe; public name '_start';
 procedure _FPC_libc21_gprof_start; assembler; nostackframe; public name '_start';
 asm
 asm
+  xorl    %ebp,%ebp
   { First locate the start of the environment variables }
   { First locate the start of the environment variables }
-  popl    %esi
-  movl    %eax,%edi
-
-  movl    %esp,%ebx               { Points to the arguments }
-  movl    %esi,%eax
-  incl    %eax
-  shll    $2,%eax
-  addl    %esp,%eax
+
+  popl    %ecx                    { Get argc in ecx }
+
+  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 }
   andl    $0xfffffff8,%esp        { Align stack }
   andl    $0xfffffff8,%esp        { Align stack }
 
 
-  movl    %eax,operatingsystem_parameter_envp    { Move the environment pointer }
-  movl    %esi,operatingsystem_parameter_argc    { Move the argument counter    }
-  movl    %ebx,operatingsystem_parameter_argv    { Move the argument pointer    }
+  {$ifdef FPC_PIC}
+        pushl %edx
+        pushl %ebx
+        pushl %ecx
+	
+	call fpc0geteipasebx
+        addl  $_GLOBAL_OFFSET_TABLE_,%ebx
 
 
-  movl    %edi,%eax
-  xorl    %ebp,%ebp
-  pushl   %eax
-  pushl   %esp
-  pushl   %edx
-  pushl   $.Lfini_dummy
-  pushl   $.Linit_dummy
-  pushl   %ebx
-  pushl   %esi
-  pushl   $.Lcmain
-  call    libc_start_main
-.Linit_dummy:
-.Lfini_dummy:
-  ret
+	movl  dlexitproc@GOT(%ebx),%ecx
+	movl  %edx,(%ecx)
+
+	movl  operatingsystem_parameter_envp@GOT(%ebx),%ecx
+	movl  %eax,(%ecx)
 
 
-{ fake main routine which will be run from libc }
-.Lcmain:
-  { save return address }
-  popl    %eax
-  movl    %eax,libc21_fpc_ret
-  movl    %ebx,libc21_fpc_ret_ebx
-  movl    %esi,libc21_fpc_ret_esi
-  movl    %edi,libc21_fpc_ret_edi
-  pushl   %eax
+	movl  operatingsystem_parameter_argc@GOT(%ebx),%edx
+	popl  %ecx
+	movl  %ecx,(%edx)
 
 
-  call    _FPC_libc21_gprof_gmon_start
+	movl  operatingsystem_parameter_argv@GOT(%ebx),%edx
+	popl  %ebx
+	movl  %ebx,(%edx)
+	popl  %edx
+  {$else FPC_PIC}
+  	movl  %edx, dlexitproc
+  	movl  %eax,operatingsystem_parameter_envp
+  	movl  %ecx,operatingsystem_parameter_argc
+  	movl  %ebx,operatingsystem_parameter_argv
+  {$endif FPC_PIC}
 
 
   { Save initial stackpointer }
   { Save initial stackpointer }
-  movl    %esp,initialstkptr
+  {$ifdef FPC_PIC}
+        pushl %ebx
+        call  fpc0geteipasebx
+        addl  $_GLOBAL_OFFSET_TABLE_,%ebx
+	movl  initialstkptr@GOT(%ebx),%ebx
+  	movl  %esp,(%ebx)
+	popl  %ebx
+  {$else FPC_PIC}
+  	movl    %esp,initialstkptr
+  {$endif FPC_PIC}
 
 
-  { start the program }
-  call    PASCALMAIN
-  hlt
-end;
+        { int __libc_start_main(
+		int *(main) (int, char * *, char * *), 
+		int argc, 
+		char * * ubp_av, 
+		void (*init) (void), 
+		void (*fini) (void), 
+		void (*rtld_fini) (void), 
+		void (* stack_end)); } 
 
 
-procedure _FPC_libc21_gprof_haltproc; assembler; nostackframe; public name '_haltproc';
-asm
-{$if sizeof(ExitCode)=2}
-  movzwl  ExitCode,%eax
-{$else}
-  mov     ExitCode,%eax
-{$endif}
-
-  movl    libc21_fpc_ret,%edx         { return to libc }
-  movl    libc21_fpc_ret_ebx,%ebx
-  movl    libc21_fpc_ret_esi,%esi
-  movl    libc21_fpc_ret_edi,%edi
-  push    %edx
-  ret
+        pushl %ebp   			{ padding }
+        pushl %esp   			{ stack_end }
+        pushl %edx   			{ function to be registered with
+                      			  atexit(), passed by loader }
+        pushl $_init_fini_dummy
+        pushl $_init_fini_dummy
+        pushl %ebx                      { Push second argument: argv.  }
+        pushl %ecx                      { Push first argument: argc.  }
+
+        pushl $_FPC_libc21_gprof_gmon_start
+
+        call  libc_start_main
+	hlt
 end;
 end;
 
 
+procedure _FPC_libc21_gprof_haltproc(e:longint);cdecl;public name '_haltproc';
+begin
+  if gmon_monstarted=1 then
+  begin
+    dec(gmon_monstarted);
+    gmon_mcleanup;
+  end;
+  asm
+.Lhaltproc:
+  {$ifdef FPC_PIC}
+        call  fpc0geteipasebx
+        addl  $_GLOBAL_OFFSET_TABLE_,%ebx
+        movl  dlexitproc@GOT(%ebx),%eax
+        movl  (%eax),%eax
+  {$else FPC_PIC}
+        movl    dlexitproc,%eax
+  {$endif FPC_PIC}
+  testl   %eax,%eax
+  je      .Lnodlexitproc
+  call    *%eax
+.Lnodlexitproc:
+  movl    syscall_nr_exit_group,%eax
+
+{$ifdef FPC_PIC}
+  call    fpc0geteipasebx
+  addl    $_GLOBAL_OFFSET_TABLE_,%ebx
+  movl    ExitCode@GOT(%ebx),%ebx
+ {$if sizeof(ExitCode)=2}
+  movzwl  (%ebx),%ebx
+ {$else}
+  mov     (%ebx),%ebx
+ {$endif}
+{$else FPC_PIC}
+ {$if sizeof(ExitCode)=2}
+  movzwl  ExitCode,%ebx
+ {$else}
+  mov     ExitCode,%ebx
+ {$endif}
+{$endif FPC_PIC}
+
+  int     $0x80
+  movl    syscall_nr_exit,%eax
+
+{$ifdef FPC_PIC}
+  call    fpc0geteipasebx
+  addl    $_GLOBAL_OFFSET_TABLE_,%ebx
+  movl    ExitCode@GOT(%ebx),%ebx
+ {$if sizeof(ExitCode)=2}
+  movzwl  (%ebx),%ebx
+ {$else}
+  mov     (%ebx),%ebx
+ {$endif}
+{$else FPC_PIC}
+
+ {$if sizeof(ExitCode)=2}
+  movzwl  ExitCode,%ebx
+ {$else}
+  mov     ExitCode,%ebx
+ {$endif}
+{$endif FPC_PIC}
+
+  int     $0x80
+  jmp     .Lhaltproc
+ end;
+end;

+ 37 - 44
rtl/linux/i386/si_dll.inc

@@ -35,18 +35,19 @@
 
 
 procedure PASCALMAIN; external name 'PASCALMAIN';
 procedure PASCALMAIN; external name 'PASCALMAIN';
 
 
+function get1eipasebx : pointer; compilerproc; nostackframe; assembler; 
+asm  
+  movl (%esp),%ebx  
+  ret  
+end;
+
 {******************************************************************************
 {******************************************************************************
                         Shared library start/halt
                         Shared library start/halt
  ******************************************************************************}
  ******************************************************************************}
 {$asmmode ATT}
 {$asmmode ATT}
 
 
-procedure _FPC_shared_lib_start(argc : dword;argv,envp : pointer); cdecl; public name '_FPC_SHARED_LIB_START_LOCAL'; public name '_start';
+procedure _FPC_shared_lib_start(argc : dword;argv,envp : pointer); cdecl; public name 'FPC_SHARED_LIB_START'; public name '_start';
 begin
 begin
-  { we've to discuss about the use of this ;) }
-  asm
-    { Save initial stackpointer }
-    movl    %esp,initialstkptr
-  end;
 
 
   operatingsystem_parameter_argc:=argc;    { Copy the argument count      }
   operatingsystem_parameter_argc:=argc;    { Copy the argument count      }
   operatingsystem_parameter_argv:=argv;    { Copy the argument pointer    }
   operatingsystem_parameter_argv:=argv;    { Copy the argument pointer    }
@@ -54,53 +55,45 @@ begin
 
 
   IsLibrary:=true;
   IsLibrary:=true;
 
 
+  asm
+    { Save initial stackpointer }
+    {$ifdef FPC_PIC}
+        call  get1eipasebx
+        addl  $_GLOBAL_OFFSET_TABLE_,%ebx
+        movl  initialstkptr@GOT(%ebx),%ecx
+	movl  %esp,(%ecx)
+    {$else FPC_PIC}
+	movl    %esp,initialstkptr
+    {$endif FPC_PIC}
+  end;
+
   PASCALMAIN;
   PASCALMAIN;
 end;
 end;
 
 
-{$ifndef VER2_0}
-
-{ this hack is needed so we can make the reference below to _FPC_shared_lib_start }
-{ local in compiler/systems/t_linux.pas                                           }
-procedure _FPC_SHARED_LIB_START_LOCAL(argc : dword;argv,envp : pointer); cdecl; external;
-
-procedure initdummy; assembler; nostackframe;
-label
-  FPC_LIB_START;
-asm
-.init
-  .align 16
-  .globl FPC_LIB_START
-//    .type FPC_LIB_START,@function
-FPC_LIB_START:
-{$ifdef FPC_PIC}
-  jmp	_FPC_SHARED_LIB_START_LOCAL@PLT
-{$else FPC_PIC}
-  jmp	_FPC_SHARED_LIB_START_LOCAL
-{$endif FPC_PIC}
-.text
-end;
-{$endif VER_2_0}
+Procedure lib_exit; external name 'FPC_LIB_EXIT';
 
 
-procedure _FPC_shared_lib_haltproc; assembler; nostackframe; public name '_haltproc';
+procedure _FPC_shared_lib_haltproc; assembler; nostackframe; public name 'FPC_SHARED_LIB_EXIT'; public name '_haltproc';
 asm
 asm
-{$ifdef FPC_PIC}
-  call    fpc_geteipasebx
-  addl    $_GLOBAL_OFFSET_TABLE_,%ebx
-{$endif}
 .Lhaltproc:
 .Lhaltproc:
-  xorl    %eax,%eax
-  incl    %eax                    { eax=1, exit call }
-{$ifdef FPC_PIC}
-  pushl   %ebx
+  call	  lib_exit
+ {$ifdef FPC_PIC}
+  call    get1eipasebx
+  addl    $_GLOBAL_OFFSET_TABLE_,%ebx
   movl    ExitCode@GOT(%ebx),%ebx
   movl    ExitCode@GOT(%ebx),%ebx
-{$if sizeof(ExitCode)=2}
+ {$if sizeof(ExitCode)=2}
   movzwl  (%ebx),%ebx
   movzwl  (%ebx),%ebx
-{$else}
+ {$else}
   mov     (%ebx),%ebx
   mov     (%ebx),%ebx
-{$endif}
-{$endif}
+ {$endif}
+{$else FPC_PIC}
+ {$if sizeof(ExitCode)=2}
+  movzwl  ExitCode,%ebx
+ {$else}
+  mov     ExitCode,%ebx
+ {$endif}
+{$endif FPC_PIC}
+  xorl    %eax,%eax
+  incl    %eax                    { eax=1, exit call }
   int     $0x80
   int     $0x80
   jmp     .Lhaltproc
   jmp     .Lhaltproc
-  popl    %ebx
 end;
 end;
-

+ 15 - 3
rtl/linux/i386/si_g.inc

@@ -90,11 +90,23 @@ end;
 procedure _FPC_proc_gprof_haltproc; assembler; nostackframe; public name '_haltproc';
 procedure _FPC_proc_gprof_haltproc; assembler; nostackframe; public name '_haltproc';
 asm
 asm
 .Lhaltproc:
 .Lhaltproc:
-{$if sizeof(ExitCode)=2}
+ {$ifdef FPC_PIC}
+  call    fpc_geteipasebx
+  addl    $_GLOBAL_OFFSET_TABLE_,%ebx
+  movl    ExitCode@GOT(%ebx),%ebx
+ {$if sizeof(ExitCode)=2}
+  movzwl  (%ebx),%ebx
+ {$else}
+  mov     (%ebx),%ebx
+ {$endif}
+{$else FPC_PIC}
+ {$if sizeof(ExitCode)=2}
   movzwl  ExitCode,%ebx
   movzwl  ExitCode,%ebx
-{$else}
+ {$else}
   mov     ExitCode,%ebx
   mov     ExitCode,%ebx
-{$endif}
+ {$endif}
+{$endif FPC_PIC}
+
   pushl   %ebx
   pushl   %ebx
   call    libc_exit     { call libc exit, this will  write the gmon.out }
   call    libc_exit     { call libc exit, this will  write the gmon.out }
   movl    syscall_nr_exit_group,%eax
   movl    syscall_nr_exit_group,%eax

+ 86 - 19
rtl/linux/i386/si_prc.inc

@@ -35,10 +35,16 @@
 
 
 procedure PASCALMAIN; external name 'PASCALMAIN';
 procedure PASCALMAIN; external name 'PASCALMAIN';
 
 
+function fpc_geteipasebx : pointer; compilerproc; nostackframe; assembler;
+asm  
+  movl (%esp),%ebx  
+  ret  
+end;
+
 {******************************************************************************
 {******************************************************************************
                           Process start/halt
                           Process start/halt
  ******************************************************************************}
  ******************************************************************************}
-{$asmmode ATT}
+{$asmmode att}
 
 
 var
 var
   dlexitproc: pointer;
   dlexitproc: pointer;
@@ -46,27 +52,54 @@ var
 procedure _FPC_proc_start; assembler; nostackframe; public name '_start';
 procedure _FPC_proc_start; assembler; nostackframe; public name '_start';
 asm
 asm
   { First locate the start of the environment variables }
   { First locate the start of the environment variables }
+
   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    $0xfffffff8,%esp        { Align stack }
 
 
-  movl    %eax,operatingsystem_parameter_envp
-  movl    %ecx,operatingsystem_parameter_argc
-  movl    %ebx,operatingsystem_parameter_argv
+  {$ifdef FPC_PIC}
+        pushl %ebx
+        pushl %ecx
+	
+	call fpc_geteipasebx
+        addl  $_GLOBAL_OFFSET_TABLE_,%ebx
+
+	movl  dlexitproc@GOT(%ebx),%ecx
+	movl  %edx,(%ecx)
+
+	movl  operatingsystem_parameter_envp@GOT(%ebx),%ecx
+	movl  %eax,(%ecx)
 
 
-  movl    %edx, dlexitproc
+	movl  operatingsystem_parameter_argc@GOT(%ebx),%edx
+	popl  %ecx
+	movl  %ecx,(%edx)
 
 
-  fninit                           { initialize fpu }
-  fwait
-  fldcw   Default8087CW
+	movl  operatingsystem_parameter_argv@GOT(%ebx),%edx
+	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
+  {$endif FPC_PIC}
 
 
-  { Initialize gs for thread local storage }
-  // movw    %ds,%ax 
-  // movw    %ax,%gs
+  { Initialize FPU }
+  call SysResetFPU
 
 
   { Save initial stackpointer }
   { Save initial stackpointer }
-  movl    %esp,initialstkptr
+  {$ifdef FPC_PIC}
+        pushl %ebx
+        call  fpc_geteipasebx
+        addl  $_GLOBAL_OFFSET_TABLE_,%ebx
+	movl  initialstkptr@GOT(%ebx),%ebx
+  	movl  %esp,(%ebx)
+	popl  %ebx
+  {$else FPC_PIC}
+  	movl    %esp,initialstkptr
+  {$endif FPC_PIC}
 
 
   xorl    %ebp,%ebp
   xorl    %ebp,%ebp
   call    PASCALMAIN
   call    PASCALMAIN
@@ -74,25 +107,59 @@ end;
 
 
 procedure _FPC_proc_haltproc; assembler; nostackframe; public name '_haltproc';
 procedure _FPC_proc_haltproc; assembler; nostackframe; public name '_haltproc';
 asm
 asm
+
 .Lhaltproc:
 .Lhaltproc:
-  movl    dlexitproc,%eax
+  {$ifdef FPC_PIC}
+        call  fpc_geteipasebx
+        addl  $_GLOBAL_OFFSET_TABLE_,%ebx
+	movl  dlexitproc@GOT(%ebx),%eax
+	movl  (%eax),%eax
+  {$else FPC_PIC}
+  	movl    dlexitproc,%eax
+  {$endif FPC_PIC}
   testl   %eax,%eax
   testl   %eax,%eax
   je      .Lnodlexitproc
   je      .Lnodlexitproc
   call    *%eax
   call    *%eax
 .Lnodlexitproc:
 .Lnodlexitproc:
   movl    syscall_nr_exit_group,%eax
   movl    syscall_nr_exit_group,%eax
-{$if sizeof(ExitCode)=2}  
+
+{$ifdef FPC_PIC}
+  call    fpc_geteipasebx
+  addl    $_GLOBAL_OFFSET_TABLE_,%ebx
+  movl    ExitCode@GOT(%ebx),%ebx
+ {$if sizeof(ExitCode)=2}
+  movzwl  (%ebx),%ebx
+ {$else}
+  mov     (%ebx),%ebx
+ {$endif}
+{$else FPC_PIC}
+ {$if sizeof(ExitCode)=2}
   movzwl  ExitCode,%ebx
   movzwl  ExitCode,%ebx
-{$else}
+ {$else}
   mov     ExitCode,%ebx
   mov     ExitCode,%ebx
-{$endif}
+ {$endif}
+{$endif FPC_PIC}
+
   int     $0x80
   int     $0x80
   movl    syscall_nr_exit,%eax
   movl    syscall_nr_exit,%eax
-{$if sizeof(ExitCode)=2}  
+
+{$ifdef FPC_PIC}
+  call    fpc_geteipasebx
+  addl    $_GLOBAL_OFFSET_TABLE_,%ebx
+  movl    ExitCode@GOT(%ebx),%ebx
+ {$if sizeof(ExitCode)=2}
+  movzwl  (%ebx),%ebx
+ {$else}
+  mov     (%ebx),%ebx
+ {$endif}
+{$else FPC_PIC}
+ {$if sizeof(ExitCode)=2}
   movzwl  ExitCode,%ebx
   movzwl  ExitCode,%ebx
-{$else}
+ {$else}
   mov     ExitCode,%ebx
   mov     ExitCode,%ebx
-{$endif}
+ {$endif}
+{$endif FPC_PIC}
+
   int     $0x80
   int     $0x80
   jmp     .Lhaltproc
   jmp     .Lhaltproc
 end;
 end;

+ 116 - 53
rtl/linux/i386/si_uc.inc

@@ -40,75 +40,138 @@
 }
 }
 
 
 
 
-procedure libc_init; external name '__uClibc_init';
-procedure libc_fini; external name '__uClibc_fini';
-procedure libc_exit; external name '_exit';
-procedure libc_main; external name '__uClibc_main';
+var
+  dlexitproc: pointer; { atexit from loader }
 
 
+procedure uclibc_init; external name '__uClibc_init';
+procedure uclibc_fini; external name '__uClibc_fini';
+procedure uclibc_exit; external name '_exit';
+procedure uclibc_main; external name '__uClibc_main';
 procedure PASCALMAIN; external name 'PASCALMAIN';
 procedure PASCALMAIN; external name 'PASCALMAIN';
 
 
+{ Some helpers }
+
+{$ifdef FPC_PIC}
+function get3eipasebx : pointer; compilerproc; nostackframe; assembler; 
+asm  
+  movl (%esp),%ebx  
+  ret  
+end;
+{$endif FPC_PIC}
+
+procedure _init_fini_dummy; compilerproc; nostackframe; assembler;
+asm
+  ret
+end; 
+
 {******************************************************************************
 {******************************************************************************
-                          C library start/halt
+                       glibc 2.1 lib + profiling start/halt
  ******************************************************************************}
  ******************************************************************************}
 {$asmmode ATT}
 {$asmmode ATT}
 
 
-procedure _FPC_libc_start; assembler; nostackframe; public name '_start';
+procedure _FPC_libc21_start; assembler; nostackframe; public name '_start';
 asm
 asm
-  xorl    %ebp,%ebp               { clear outer most frame for backtraces }
-  popl    %esi                    { Get argc in ecx }
-  movl    %esp,%ecx               { Esp now points to the arguments }
-  leal    4(%esp,%esi,4),%eax     { The start of the environment is: esp+4*eax+8 }
-  andl    $0xfffffff0,%esp        { Align stack }
-  pushl   %eax                    { push garbage, so we push 32 bytes in total }
-
-  movl    %eax,operatingsystem_parameter_envp    { save the environment pointer }
-  movl    %esi,operatingsystem_parameter_argc    { save the argument counter    }
-  movl    %ecx,operatingsystem_parameter_argv    { save the argument pointer    }
-  movl    %esp,initialstkptr                     { save initial stack pointer   }
-
-  pushl   %esp            { provide highest stack address to C library }
-  pushl   %edx            { push address of shared library finalization }
-
-{$ifdef PIC}
-  call    .L0
-.L0:
-  pop     %ebx
-  addl    $_GLOBAL_OFFSET_TABLE_+[.-.L0],%ebx
-
-  pushl   _fini@GOT(%ebx) { push address of entry points }
-  pushl   _init@GOT(%ebx)
-
-  pushl   %ecx            { push argv }                                 
-  pushl   %esi            { push argc }
-                                                                       
-  pushl   $PASCALMAIN     { push fpc main procedure }
-  call    libc_main       { let fpc main be called from libc startup }
-{$else}
-  pushl   $libc_fini      { push address of entry points }
-  pushl   $libc_init
-
-  pushl   %ecx            { push argv }
-  pushl   %esi            { push argc }
-
-  pushl   $PASCALMAIN     { push fpc main procedure }
-  call    libc_main       { let fpc main be called from libc startup }
-{$endif}
+  xorl    %ebp,%ebp
+  { First locate the start of the environment variables }
+
+  popl    %ecx                    { Get argc in ecx }
+
+  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 }
+  andl    $0xfffffff8,%esp        { Align stack }
+
+  {$ifdef FPC_PIC}
+        pushl %edx
+        pushl %ebx
+        pushl %ecx
+	
+	call get3eipasebx
+        addl  $_GLOBAL_OFFSET_TABLE_,%ebx
+
+	movl  dlexitproc@GOT(%ebx),%ecx 
+	movl  %edx,(%ecx)
+
+	movl  operatingsystem_parameter_envp@GOT(%ebx),%ecx
+	movl  %eax,(%ecx)
+
+	movl  operatingsystem_parameter_argc@GOT(%ebx),%edx
+	popl  %ecx
+	movl  %ecx,(%edx)
+
+	movl  operatingsystem_parameter_argv@GOT(%ebx),%edx
+	popl  %ebx
+	movl  %ebx,(%edx)
+	popl  %edx
+  {$else FPC_PIC}
+  	movl  %edx, dlexitproc
+  	movl  %eax,operatingsystem_parameter_envp
+  	movl  %ecx,operatingsystem_parameter_argc
+  	movl  %ebx,operatingsystem_parameter_argv
+  {$endif FPC_PIC}
+
+  { Save initial stackpointer }
+  {$ifdef FPC_PIC}
+        pushl %ebx
+        call  get3eipasebx
+        addl  $_GLOBAL_OFFSET_TABLE_,%ebx
+	movl  initialstkptr@GOT(%ebx),%ebx
+  	movl  %esp,(%ebx)
+	popl  %ebx
+  {$else FPC_PIC}
+  	movl    %esp,initialstkptr
+  {$endif FPC_PIC}
+
+        { int __libc_start_main(
+		int *(main) (int, char * *, char * *), 
+		int argc, 
+		char * * ubp_av, 
+		void (*init) (void), 
+		void (*fini) (void), 
+		void (*rtld_fini) (void), 
+		void (* stack_end)); } 
+
+        pushl %ebp   			{ padding }
+        pushl %esp   			{ stack_end }
+        pushl %edx   			{ function to be registered with
+                      			  atexit(), passed by loader }
+  	pushl $_init_fini_dummy
+  	pushl $_init_fini_dummy
+	pushl %ebx             		{ Push second argument: argv.  }
+	pushl %ecx             		{ Push first argument: argc.  }
+
+	pushl $PASCALMAIN
+
+  	call  uclibc_main
+	hlt
 end;
 end;
 
 
-procedure _FPC_libc_haltproc; assembler; nostackframe; public name '_haltproc';
+procedure _FPC_libc21_haltproc; assembler; nostackframe; public name '_haltproc';
 asm
 asm
 .Lhaltproc:
 .Lhaltproc:
-{$if sizeof(ExitCode)=2}
-  movzwl  ExitCode,%ebx
-{$else}
-  mov     ExitCode,%ebx
-{$endif}
+
+  {$ifdef FPC_PIC}
+        call    get3eipasebx
+        addl    $_GLOBAL_OFFSET_TABLE_,%ebx
+        movl    ExitCode@GOT(%ebx),%ebx
+    {$if sizeof(ExitCode)=2}
+        movzwl  (%ebx),%ebx
+    {$else}
+        mov     (%ebx),%ebx
+    {$endif}
+  {$else FPC_PIC}
+    {$if sizeof(ExitCode)=2}
+        movzwl  ExitCode,%ebx
+    {$else}
+        mov     ExitCode,%ebx
+    {$endif}
+  {$endif FPC_PIC}
+
   pushl   %ebx
   pushl   %ebx
-  call    libc_exit
+  call    uclibc_exit
   xorl    %eax,%eax
   xorl    %eax,%eax
   incl    %eax                    { eax=1, exit call }
   incl    %eax                    { eax=1, exit call }
   popl    %ebx
   popl    %ebx
   int     $0x80
   int     $0x80
   jmp     .Lhaltproc
   jmp     .Lhaltproc
-end;
 
 
+end;

+ 219 - 53
rtl/linux/i386/syscall.inc

@@ -77,17 +77,34 @@ end;
 
 
 Procedure fpc_geteipasebx;[external name 'fpc_geteipasebx'];
 Procedure fpc_geteipasebx;[external name 'fpc_geteipasebx'];
 
 
-function FpSysCall(sysnr:TSysParam):TSysResult; assembler; register; [public,alias:'FPC_SYSCALL0'];
+function FpSysCall(sysnr:TSysParam):TSysResult; assembler; register;  [public,alias:'FPC_SYSCALL0'];
 { Var sysnr located in register eax }
 { Var sysnr located in register eax }
 asm
 asm
-//      movl  sysnr,%eax
-        cmp  $0, sysenter_supported
-        jne  .LSysEnter
-        int $0x80
+        push  %ebx
+        push  %ecx
+  {$ifdef FPC_PIC}
+        call  fpc_geteipasebx
+        addl  $_GLOBAL_OFFSET_TABLE_,%ebx
+        movl  sysenter_supported@GOT(%ebx),%ecx
+        movl  (%ecx),%ecx
+        cmp   $0, %ecx
+  {$else FPC_PIC}
+        cmp   $0, sysenter_supported
+  {$endif FPC_PIC}
+        jne   .LSysEnter
+        int   $0x80
         jmp   .LTail
         jmp   .LTail
   .LSysEnter:
   .LSysEnter:
-        call psysinfo
+  {$ifdef FPC_PIC}
+        movl  psysinfo@GOT(%ebx),%ecx
+        movl  (%ecx),%ecx
+	call  *%ecx
+  {$else FPC_PIC}
+        call  psysinfo
+  {$endif FPC_PIC}
   .LTail:
   .LTail:
+	pop   %ecx
+	pop   %ebx
         cmpl  $-4095,%eax
         cmpl  $-4095,%eax
         jb    .LSyscOK
         jb    .LSyscOK
         negl  %eax
         negl  %eax
@@ -96,21 +113,40 @@ asm
   .LSyscOK:
   .LSyscOK:
 end;
 end;
 
 
+
 function FpSysCall(sysnr,param1 : TSysParam):TSysResult; assembler; register; [public,alias:'FPC_SYSCALL1'];
 function FpSysCall(sysnr,param1 : TSysParam):TSysResult; assembler; register; [public,alias:'FPC_SYSCALL1'];
 { Var sysnr located in register eax
 { Var sysnr located in register eax
   Var param1 located in register edx }
   Var param1 located in register edx }
 asm
 asm
-        movl  %ebx,%ecx
-//      movl  sysnr,%eax
-        movl  %edx,%ebx
+        push  %ebx
+        push  %ecx
+  {$ifdef FPC_PIC}
+        call  fpc_geteipasebx
+        addl  $_GLOBAL_OFFSET_TABLE_,%ebx
+        movl  sysenter_supported@GOT(%ebx),%ecx
+        movl  (%ecx),%ecx
+        cmp   $0, %ecx
+  {$else FPC_PIC}
         cmp   $0, sysenter_supported
         cmp   $0, sysenter_supported
+  {$endif FPC_PIC}
+
         jne   .LSysEnter
         jne   .LSysEnter
+        movl  %edx,%ebx		// param1
         int   $0x80
         int   $0x80
         jmp   .LTail
         jmp   .LTail
   .LSysEnter:
   .LSysEnter:
-        call psysinfo
+  {$ifdef FPC_PIC}
+        movl  psysinfo@GOT(%ebx),%ecx
+        movl  (%ecx),%ecx
+        movl  %edx,%ebx		// param1
+	call  *%ecx
+  {$else FPC_PIC}
+        movl  %edx,%ebx		// param1
+        call  psysinfo
+  {$endif FPC_PIC}
   .LTail:
   .LTail:
-        movl  %ecx,%ebx
+	pop   %ecx
+	pop   %ebx
         cmpl  $-4095,%eax
         cmpl  $-4095,%eax
         jb    .LSyscOK
         jb    .LSyscOK
         negl  %eax
         negl  %eax
@@ -125,17 +161,37 @@ function FpSysCall(sysnr,param1,param2 : TSysParam):TSysResult; assembler; regis
   Var param2 located in register ecx }
   Var param2 located in register ecx }
 asm
 asm
         push  %ebx
         push  %ebx
-//      movl  sysnr,%eax
-        movl  %edx,%ebx
-//      movl  param2,%ecx
+        push  %edx
+        push  %ecx
+  {$ifdef FPC_PIC}
+        call  fpc_geteipasebx
+        addl  $_GLOBAL_OFFSET_TABLE_,%ebx
+        movl  sysenter_supported@GOT(%ebx),%ecx
+        movl  (%ecx),%ecx
+        cmp   $0, %ecx
+  {$else FPC_PIC}
         cmp   $0, sysenter_supported
         cmp   $0, sysenter_supported
+  {$endif FPC_PIC}
         jne   .LSysEnter
         jne   .LSysEnter
+        movl  %edx,%ebx		// param1
+	pop   %ecx		// param2
         int   $0x80
         int   $0x80
         jmp   .LTail
         jmp   .LTail
   .LSysEnter:
   .LSysEnter:
-        call psysinfo
+  {$ifdef FPC_PIC}
+        movl  psysinfo@GOT(%ebx),%ecx
+        movl  %edx,%ebx		// param1
+        movl  (%ecx),%edx
+	pop   %ecx		// param2
+	call  *%edx
+  {$else FPC_PIC}
+        movl  %edx,%ebx		// param1
+	pop   %ecx		// param2
+        call  psysinfo
+  {$endif FPC_PIC}
   .LTail:
   .LTail:
-        pop   %ebx
+	pop   %edx
+	pop   %ebx
         cmpl  $-4095,%eax
         cmpl  $-4095,%eax
         jb    .LSyscOK
         jb    .LSyscOK
         negl  %eax
         negl  %eax
@@ -149,20 +205,45 @@ function FpSysCall(sysnr,param1,param2,param3:TSysParam):TSysResult; assembler;
   Var param1 located in register edx
   Var param1 located in register edx
   Var param2 located in register ecx
   Var param2 located in register ecx
   Var param3 located at ebp+20 }
   Var param3 located at ebp+20 }
+var
+  _psysinfo: LongWord;
 asm
 asm
         push  %ebx
         push  %ebx
-//      movl  sysnr,%eax
-        movl  %edx,%ebx
-//      movl  param2,%ecx
-        movl  param3,%edx
+        push  %edx
+        push  %ecx
+  {$ifdef FPC_PIC}
+        call  fpc_geteipasebx
+        addl  $_GLOBAL_OFFSET_TABLE_,%ebx
+        movl  sysenter_supported@GOT(%ebx),%ecx
+        movl  (%ecx),%ecx
+        cmp   $0, %ecx
+  {$else FPC_PIC}
         cmp   $0, sysenter_supported
         cmp   $0, sysenter_supported
+  {$endif FPC_PIC}
         jne   .LSysEnter
         jne   .LSysEnter
+        movl  %edx,%ebx		// param1
+	pop   %ecx		// param2
+        movl  param3,%edx	// param3
         int   $0x80
         int   $0x80
         jmp   .LTail
         jmp   .LTail
   .LSysEnter:
   .LSysEnter:
+  {$ifdef FPC_PIC}
+        movl  psysinfo@GOT(%ebx),%ecx
+        movl  (%ecx),%ecx
+        movl  %ecx,_psysinfo
+        movl  %edx,%ebx		// param1
+	pop   %ecx		// param2
+        movl  param3,%edx	// param3
+        call  _psysinfo 
+  {$else FPC_PIC}
+        movl  %edx,%ebx		// param1
+	pop   %ecx		// param2
+        movl  param3,%edx	// param3
         call psysinfo
         call psysinfo
+  {$endif FPC_PIC}
   .LTail:
   .LTail:
-        pop   %ebx
+	pop   %edx
+	pop   %ebx
         cmpl  $-4095,%eax
         cmpl  $-4095,%eax
         jb    .LSyscOK
         jb    .LSyscOK
         negl  %eax
         negl  %eax
@@ -177,23 +258,48 @@ function FpSysCall(sysnr,param1,param2,param3,param4:TSysParam):TSysResult; asse
   Var param2 located in register ecx
   Var param2 located in register ecx
   Var param3 located at ebp+20
   Var param3 located at ebp+20
   Var param4 located at ebp+16 }
   Var param4 located at ebp+16 }
+var
+  _psysinfo: LongWord;
 asm
 asm
         push  %ebx
         push  %ebx
         push  %esi
         push  %esi
-//      movl  sysnr,%eax
-        movl  %edx,%ebx
-//      movl  param2,%ecx
-        movl  param3,%edx
-        movl  param4,%esi
+        push  %ecx
+  {$ifdef FPC_PIC}
+        call  fpc_geteipasebx
+        addl  $_GLOBAL_OFFSET_TABLE_,%ebx
+        movl  sysenter_supported@GOT(%ebx),%ecx
+        movl  (%ecx),%ecx
+        cmp   $0, %ecx
+  {$else FPC_PIC}
         cmp   $0, sysenter_supported
         cmp   $0, sysenter_supported
-        jne   .LSysEnter
+  {$endif FPC_PIC}
+        jne  .LSysEnter
+        movl  %edx,%ebx		// param1
+	pop   %ecx		// param2
+        movl  param3,%edx	// param3
+        movl  param4,%esi	// param4
         int   $0x80
         int   $0x80
-        jmp  .LTail
+        jmp   .LTail
   .LSysEnter:
   .LSysEnter:
-        call psysinfo
+  {$ifdef FPC_PIC}
+        movl  psysinfo@GOT(%ebx),%ecx
+        movl  (%ecx),%ecx
+        movl  %ecx,_psysinfo
+        movl  %edx,%ebx		// param1
+	pop   %ecx		// param2
+        movl  param3,%edx	// param3
+        movl  param4,%esi	// param4
+        call  _psysinfo 
+  {$else FPC_PIC}
+        movl  %edx,%ebx		// param1
+	pop   %ecx		// param2
+        movl  param3,%edx	// param3
+        movl  param4,%esi	// param4
+        call  psysinfo
+  {$endif FPC_PIC}
   .LTail:
   .LTail:
-        pop   %esi
-        pop   %ebx
+  	pop   %esi
+	pop   %ebx
         cmpl  $-4095,%eax
         cmpl  $-4095,%eax
         jb    .LSyscOK
         jb    .LSyscOK
         negl  %eax
         negl  %eax
@@ -209,26 +315,55 @@ function FpSysCall(sysnr,param1,param2,param3,param4,param5 : TSysParam):TSysRes
   Var param3 located at ebp+20
   Var param3 located at ebp+20
   Var param4 located at ebp+16
   Var param4 located at ebp+16
   Var param5 located at ebp+12 }
   Var param5 located at ebp+12 }
+var
+  _psysinfo: LongWord;
 asm
 asm
         push  %ebx
         push  %ebx
+        push  %edx
         push  %esi
         push  %esi
         push  %edi
         push  %edi
-//      movl  sysnr,%eax
-        movl  %edx,%ebx
-//      movl  param2,%ecx
-        movl  param3,%edx
-        movl  param4,%esi
-        movl  param5,%edi
+        push  %ecx
+  {$ifdef FPC_PIC}
+        call  fpc_geteipasebx
+        addl  $_GLOBAL_OFFSET_TABLE_,%ebx
+        movl  sysenter_supported@GOT(%ebx),%ecx
+        movl  (%ecx),%ecx
+        cmp   $0, %ecx
+  {$else FPC_PIC}
         cmp   $0, sysenter_supported
         cmp   $0, sysenter_supported
+  {$endif FPC_PIC}
         jne   .LSysEnter
         jne   .LSysEnter
-        int   $0x80
+        movl  %edx,%ebx		// param1
+	pop   %ecx		// param2
+        movl  param3,%edx	// param3
+        movl  param4,%esi	// param4
+	movl  param5,%edi	// param5
+        int $0x80
         jmp   .LTail
         jmp   .LTail
   .LSysEnter:
   .LSysEnter:
+  {$ifdef FPC_PIC}
+        movl  psysinfo@GOT(%ebx),%ecx
+        movl  (%ecx),%ecx
+        movl  %ecx,_psysinfo
+        movl  %edx,%ebx		// param1
+	pop   %ecx		// param2
+        movl  param3,%edx	// param3
+        movl  param4,%esi	// param4
+	movl  param5,%edi	// param5
+        call  _psysinfo 
+  {$else FPC_PIC}
+        movl  %edx,%ebx		// param1
+	pop   %ecx		// param2
+        movl  param3,%edx	// param3
+        movl  param4,%esi	// param4
+	movl  param5,%edi	// param5
         call psysinfo
         call psysinfo
+  {$endif FPC_PIC}
   .LTail:
   .LTail:
-        pop   %edi
-        pop   %esi
-        pop   %ebx
+  	pop   %edi
+  	pop   %esi
+	pop   %edx
+	pop   %ebx
         cmpl  $-4095,%eax
         cmpl  $-4095,%eax
         jb    .LSyscOK
         jb    .LSyscOK
         negl  %eax
         negl  %eax
@@ -245,29 +380,60 @@ function FpSysCall(sysnr,param1,param2,param3,param4,param5,param6: TSysParam):T
   Var param4 located at ebp+16
   Var param4 located at ebp+16
   Var param5 located at ebp+12
   Var param5 located at ebp+12
   Var param6 located at ebp+8 }
   Var param6 located at ebp+8 }
+var
+  _psysinfo: LongWord;
 asm
 asm
         push  %ebx
         push  %ebx
+	push  %edx
         push  %esi
         push  %esi
         push  %edi
         push  %edi
-        push  %ebp
-//      movl  sysnr,%eax
-        movl  %edx,%ebx
-//      movl  param2,%ecx
-        movl  param3,%edx
-        movl  param4,%esi
-        movl  param5,%edi
-        movl  param6,%ebp
+	push  %ebp
+        push  %ecx
+  {$ifdef FPC_PIC}
+        call  fpc_geteipasebx
+        addl  $_GLOBAL_OFFSET_TABLE_,%ebx
+        movl  sysenter_supported@GOT(%ebx),%ecx
+        movl  (%ecx),%ecx
+        cmp   $0, %ecx
+  {$else FPC_PIC}
         cmp   $0, sysenter_supported
         cmp   $0, sysenter_supported
+  {$endif FPC_PIC}
         jne   .LSysEnter
         jne   .LSysEnter
+        movl  %edx,%ebx		// param1
+	pop   %ecx		// param2
+        movl  param3,%edx	// param3
+        movl  param4,%esi	// param4
+	movl  param5,%edi	// param5
+	movl  param6,%ebp	// param6
         int   $0x80
         int   $0x80
         jmp   .LTail
         jmp   .LTail
   .LSysEnter:
   .LSysEnter:
+  {$ifdef FPC_PIC}
+        movl  psysinfo@GOT(%ebx),%ecx
+        movl  (%ecx),%ecx
+        movl  %ecx,_psysinfo
+        movl  %edx,%ebx		// param1
+	pop   %ecx		// param2
+        movl  param3,%edx	// param3
+        movl  param4,%esi	// param4
+	movl  param5,%edi	// param5
+	movl  param6,%ebp	// param6
+        call  _psysinfo 
+  {$else FPC_PIC}
+        movl  %edx,%ebx		// param1
+	pop   %ecx		// param2
+        movl  param3,%edx	// param3
+        movl  param4,%esi	// param4
+	movl  param5,%edi	// param5
+	movl  param6,%ebp	// param6
         call psysinfo
         call psysinfo
+  {$endif FPC_PIC}
   .LTail:
   .LTail:
-        pop   %ebp
-        pop   %edi
-        pop   %esi
-        pop   %ebx
+	pop   %ebp
+  	pop   %edi
+  	pop   %esi
+	pop   %edx
+	pop   %ebx
         cmpl  $-4095,%eax
         cmpl  $-4095,%eax
         jb    .LSyscOK
         jb    .LSyscOK
         negl  %eax
         negl  %eax

+ 6 - 3
rtl/linux/m68k/dllprt0.as

@@ -19,9 +19,9 @@
         .globl  _startlib
         .globl  _startlib
         .type   _startlib,@function
         .type   _startlib,@function
 _startlib:
 _startlib:
-        .globl  FPC_LIB_START
-        .type   FPC_LIB_START,@function
-FPC_LIB_START:
+        .globl  FPC_SHARED_LIB_START
+        .type   FPC_SHARED_LIB_START,@function
+FPC_SHARED_LIB_START:
 |
 |
 |       The args and envs are not tested yet
 |       The args and envs are not tested yet
 |
 |
@@ -36,6 +36,9 @@ FPC_LIB_START:
         .globl  _haltproc
         .globl  _haltproc
         .type   _haltproc,@function
         .type   _haltproc,@function
 haltproc:
 haltproc:
+        .globl  FPC_SHARED_LIB_EXIT
+        .type   FPC_SHARED_LIB_EXIT,@function
+FPC_SHARED_LIB_EXIT:
         moveq.l   #1,%d0
         moveq.l   #1,%d0
         move.w    U_SYSLINUX_EXITCODE,%d1
         move.w    U_SYSLINUX_EXITCODE,%d1
         trap      #0
         trap      #0

+ 7 - 3
rtl/linux/x86_64/dllprt0.as

@@ -35,9 +35,9 @@
 */
 */
 .section .init
 .section .init
 	.align 16
 	.align 16
-	.globl FPC_LIB_START
-	.type FPC_LIB_START,@function
-FPC_LIB_START:
+	.globl FPC_SHARED_LIB_START
+	.type FPC_SHARED_LIB_START,@function
+FPC_SHARED_LIB_START:
 	jmp	_startlib@PLT
 	jmp	_startlib@PLT
 
 
         .text
         .text
@@ -68,6 +68,10 @@ _startlib:
         .globl  _haltproc
         .globl  _haltproc
         .type   _haltproc,@function
         .type   _haltproc,@function
 _haltproc:
 _haltproc:
+	.globl FPC_SHARED_LIB_EXIT
+	.type FPC_SHARED_LIB_EXIT,@function
+FPC_SHARED_LIB_EXIT:
+	call	FPC_LIB_EXIT@PLT
         movl    $231,%eax                 /* exit_group call */
         movl    $231,%eax                 /* exit_group call */
         movq    operatingsystem_result@GOTPCREL(%rip),%rbx
         movq    operatingsystem_result@GOTPCREL(%rip),%rbx
         movzwl  (%rbx),%edi
         movzwl  (%rbx),%edi