瀏覽代碼

* i386-linux: reworked and cleaned up libc-related startup code:
* Don't replace intended initialization routines with dummy ones, so libc can properly initialize itself.
* Profiling support (si_c21g.pp) only needs to contain the __gmon_start__ procedure, so it can reuse the entire si_c21.inc, and separate si_21g.inc file is no longer needed.

git-svn-id: trunk@32984 -

sergei 9 年之前
父節點
當前提交
77285b63eb
共有 6 個文件被更改,包括 46 次插入296 次删除
  1. 0 1
      .gitattributes
  2. 1 1
      rtl/linux/Makefile
  3. 1 1
      rtl/linux/Makefile.fpc
  4. 23 71
      rtl/linux/i386/si_c21.inc
  5. 0 221
      rtl/linux/i386/si_c21g.inc
  6. 21 1
      rtl/linux/si_c21g.pp

+ 0 - 1
.gitattributes

@@ -8925,7 +8925,6 @@ rtl/linux/fpmake.inc svneol=native#text/plain
 rtl/linux/i386/bsyscall.inc svneol=native#text/plain
 rtl/linux/i386/si_c.inc svneol=native#text/plain
 rtl/linux/i386/si_c21.inc svneol=native#text/plain
-rtl/linux/i386/si_c21g.inc svneol=native#text/plain
 rtl/linux/i386/si_dll.inc svneol=native#text/plain
 rtl/linux/i386/si_g.inc svneol=native#text/plain
 rtl/linux/i386/si_prc.inc svneol=native#text/plain

+ 1 - 1
rtl/linux/Makefile

@@ -3631,7 +3631,7 @@ ifndef ARMTHUMB
 endif
 si_prc$(PPUEXT) : si_prc.pp si_intf.inc $(ARCH)/sysnr.inc $(ARCH)/si_prc.inc $(SYSTEMUNIT)$(PPUEXT)
 	$(COMPILER) si_prc.pp
-si_c21g$(PPUEXT) : si_c21g.pp si_intf.inc $(ARCH)/sysnr.inc $(ARCH)/si_c21g.inc $(SYSTEMUNIT)$(PPUEXT)
+si_c21g$(PPUEXT) : si_c21g.pp si_intf.inc $(ARCH)/sysnr.inc $(ARCH)/si_c21.inc $(SYSTEMUNIT)$(PPUEXT)
 	$(COMPILER) si_c21g.pp
 si_c21$(PPUEXT) : si_c21.pp si_intf.inc $(ARCH)/sysnr.inc $(ARCH)/si_c21.inc $(SYSTEMUNIT)$(PPUEXT)
 	$(COMPILER) si_c21.pp

+ 1 - 1
rtl/linux/Makefile.fpc

@@ -220,7 +220,7 @@ endif
 si_prc$(PPUEXT) : si_prc.pp si_intf.inc $(ARCH)/sysnr.inc $(ARCH)/si_prc.inc $(SYSTEMUNIT)$(PPUEXT)
 	$(COMPILER) si_prc.pp
 
-si_c21g$(PPUEXT) : si_c21g.pp si_intf.inc $(ARCH)/sysnr.inc $(ARCH)/si_c21g.inc $(SYSTEMUNIT)$(PPUEXT)
+si_c21g$(PPUEXT) : si_c21g.pp si_intf.inc $(ARCH)/sysnr.inc $(ARCH)/si_c21.inc $(SYSTEMUNIT)$(PPUEXT)
 	$(COMPILER) si_c21g.pp
 
 si_c21$(PPUEXT) : si_c21.pp si_intf.inc $(ARCH)/sysnr.inc $(ARCH)/si_c21.inc $(SYSTEMUNIT)$(PPUEXT)

+ 23 - 71
rtl/linux/i386/si_c21.inc

@@ -35,18 +35,12 @@
 
 {$asmmode att}
 
-var
-  dlexitproc: pointer; { atexit from loader }
-
+procedure __libc_csu_init; cdecl; external;
+procedure __libc_csu_fini; cdecl; external;
 procedure libc_start_main; external name '__libc_start_main';
+procedure libc_exit(code: longint); cdecl; external name 'exit';
 procedure PASCALMAIN; external name 'PASCALMAIN';
 
-{ Some helpers }
-
-procedure _init_fini_dummy; compilerproc; nostackframe; assembler;
-asm
-  ret
-end; 
 
 {******************************************************************************
                        glibc 2.1 lib + profiling start/halt
@@ -59,53 +53,32 @@ asm
 
   popl    %ecx                    { Get argc in ecx }
 
-  movl    %esp,%ebx               { Esp now points to the arguments }
+  movl    %esp,%esi               { Esp now points to the arguments }
   leal    4(%esp,%ecx,4),%eax     { The start of the environment is: esp+4*eax+4 }
   andl    $0xfffffff0,%esp        { Align stack to 16 bytes }
 
   {$ifdef FPC_PIC}
-        pushl %edx
-        pushl %ebx
-        pushl %ecx
-	
 	call .Lpiclab
 .Lpiclab:
         popl  %ebx
         addl  $_GLOBAL_OFFSET_TABLE_+1,%ebx
 
-	movl  dlexitproc@GOT(%ebx),%ecx
-	movl  %edx,(%ecx)
+	movl  operatingsystem_parameter_envp@GOT(%ebx),%edi
+	movl  %eax,(%edi)
 
-	movl  operatingsystem_parameter_envp@GOT(%ebx),%ecx
-	movl  %eax,(%ecx)
+	movl  operatingsystem_parameter_argc@GOT(%ebx),%edi
+	movl  %ecx,(%edi)
 
-	movl  operatingsystem_parameter_argc@GOT(%ebx),%edx
-	popl  %ecx
-	movl  %ecx,(%edx)
+	movl  operatingsystem_parameter_argv@GOT(%ebx),%edi
+	movl  %esi,(%edi)
 
-	movl  operatingsystem_parameter_argv@GOT(%ebx),%edx
-	popl  %ebx
-	movl  %ebx,(%edx)
-	popl  %edx
+        movl  initialstkptr@GOT(%ebx),%edi
+        movl  %esp,(%edi)
   {$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  .Lpiclab2
-.Lpiclab2:
-        popl  %ebx
-        addl  $_GLOBAL_OFFSET_TABLE_+1,%ebx
-	movl  initialstkptr@GOT(%ebx),%ebx
-  	movl  %esp,(%ebx)
-	popl  %ebx
-  {$else FPC_PIC}
-  	movl    %esp,initialstkptr
+  	movl  %esi,operatingsystem_parameter_argv
+        movl  %esp,initialstkptr
   {$endif FPC_PIC}
 
         { int __libc_start_main(
@@ -121,40 +94,19 @@ asm
         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
+        pushl $__libc_csu_fini
+        pushl $__libc_csu_init
+        pushl %esi                      { Push second argument: argv.  }
+        pushl %ecx                      { Push first argument: argc.  }
 
-  	call  libc_start_main
+        pushl $PASCALMAIN
+        call  libc_start_main
 	hlt
 end;
 
 procedure _FPC_libc21_haltproc(e: longint); cdecl; assembler; public name '_haltproc';
 asm
-  {$ifdef FPC_PIC}
-        call  .Lpiclab
-.Lpiclab:
-        popl  %ebx
-        addl  $_GLOBAL_OFFSET_TABLE_+1,%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
-  movl    e,%ebx
-  int     $0x80
-
-  movl    syscall_nr_exit,%eax
-  movl    e,%ebx
-
-  int     $0x80
-  jmp     .Lnodlexitproc
+        push  e
+        call  libc_exit
+        hlt
 end;

+ 0 - 221
rtl/linux/i386/si_c21g.inc

@@ -1,221 +0,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.
-
-    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
-}
-
-{$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';
-
-var
-  dlexitproc: pointer; { atexit from loader }
-
-  gmon_start : record end;external name 'PASCALMAIN';
-  gmon_etext : record end;external name '_etext';
-
-  gmon_monstarted: longint = 0;
-
-{******************************************************************************
-                          Process start/halt
- ******************************************************************************}
-
-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;
-
-procedure _FPC_libc21_gprof_start; assembler; nostackframe; public name '_start';
-asm
-  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    $0xfffffff0,%esp        { Align stack to 16 bytes }
-
-  {$ifdef FPC_PIC}
-        pushl %edx
-        pushl %ebx
-        pushl %ecx
-	
-	call fpc0geteipasebx
-        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  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}
-
-        { 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 $_FPC_libc21_gprof_gmon_start
-
-        call  libc_start_main
-	hlt
-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;

+ 21 - 1
rtl/linux/si_c21g.pp

@@ -21,6 +21,26 @@ interface
 implementation
 
 {$i sysnr.inc}
-{$i si_c21g.inc}
+{$i si_c21.inc}
+
+var
+  gmon_started: boolean;
+  gmon_start : record end;external name 'PASCALMAIN';
+  gmon_etext : record end;external name '_etext';
+
+
+procedure atexit(p: pointer); cdecl; external;
+procedure monstartup (main,etext : pointer); cdecl; external;
+procedure _mcleanup; cdecl; external;
+
+procedure __gmon_start__; cdecl; public;
+  begin
+    if not gmon_started then
+      begin
+        gmon_started:=true;
+        monstartup(@gmon_start,@gmon_etext);
+        atexit(@_mcleanup);
+      end;
+  end;
 
 end.