mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-05-31 07:22:44 +02:00
* 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 -
This commit is contained in:
parent
cc5aeb09de
commit
92ff07deaf
@ -1074,8 +1074,8 @@ begin
|
||||
|
||||
{ Create some replacements }
|
||||
{ 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^);
|
||||
|
||||
{ Call linker }
|
||||
|
@ -94,10 +94,12 @@ function mmx_support : boolean;
|
||||
mmx_support:=false;
|
||||
end;
|
||||
|
||||
{$ifndef FPC_PIC}
|
||||
{$if not defined(FPC_SYSTEM_HAS_MOVE) and defined(REGCALL) }
|
||||
{$define USE_FASTMOVE}
|
||||
{$i fastmove.inc}
|
||||
{$endif FPC_SYSTEM_HAS_MOVE}
|
||||
{$endif FPC_PIC}
|
||||
|
||||
procedure fpc_cpuinit;
|
||||
begin
|
||||
@ -1476,7 +1478,17 @@ asm
|
||||
jl .Lj3596
|
||||
.Lj3603:
|
||||
// [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
|
||||
{$endif FPC_PIC}
|
||||
jne .Lj3610
|
||||
decl (%edx)
|
||||
je .Lj3620
|
||||
|
@ -19,9 +19,9 @@
|
||||
.globl _startlib
|
||||
.type _startlib,@function
|
||||
_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
|
||||
movl %esp,%ebp
|
||||
|
||||
@ -47,6 +47,10 @@ FPC_LIB_START:
|
||||
.type _haltproc,@function
|
||||
_haltproc:
|
||||
_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
|
||||
incl %eax /* eax=1, exit call */
|
||||
movzwl operatingsystem_result,%ebx
|
||||
|
@ -46,6 +46,7 @@ procedure libc_setfpucw; external name '__setfpucw';
|
||||
procedure libc_start_main; external name '__libc_start_main';
|
||||
|
||||
procedure PASCALMAIN; external name 'PASCALMAIN';
|
||||
Procedure fpc_geteipasebx;[external name 'fpc_geteipasebx'];
|
||||
|
||||
{******************************************************************************
|
||||
C library start/halt
|
||||
@ -53,38 +54,102 @@ procedure PASCALMAIN; external name 'PASCALMAIN';
|
||||
{$asmmode ATT}
|
||||
|
||||
procedure _FPC_libc_start; assembler; nostackframe; public name '_start';
|
||||
var
|
||||
_ebx: LongInt;
|
||||
_ecx: LongInt;
|
||||
_libc_init_proc: LongInt;
|
||||
asm
|
||||
{ First locate the start of the environment variables }
|
||||
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 }
|
||||
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 %ebx
|
||||
pushl %ecx
|
||||
|
||||
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
|
||||
call libc_setfpucw
|
||||
popl %eax
|
||||
pushl $libc_fini_proc
|
||||
call libc_atexit
|
||||
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
|
||||
|
||||
{ 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
|
||||
call PASCALMAIN { start the program }
|
||||
@ -93,12 +158,26 @@ end;
|
||||
procedure _FPC_libc_haltproc; assembler; nostackframe; public name '_haltproc';
|
||||
asm
|
||||
.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
|
||||
{$else}
|
||||
{$else}
|
||||
mov ExitCode,%ebx
|
||||
{$endif}
|
||||
{$endif}
|
||||
{$endif FPC_PIC}
|
||||
|
||||
pushl %ebx
|
||||
|
||||
call libc_exit
|
||||
xorl %eax,%eax
|
||||
incl %eax { eax=1, exit call }
|
||||
|
@ -33,83 +33,166 @@
|
||||
argc <--- esp
|
||||
}
|
||||
|
||||
{$asmmode att}
|
||||
|
||||
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 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';
|
||||
asm
|
||||
xorl %ebp,%ebp
|
||||
{ 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 }
|
||||
|
||||
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 .Lpiclab
|
||||
.Lpiclab:
|
||||
popl %ebx
|
||||
addl $_GLOBAL_OFFSET_TABLE_,%ebx
|
||||
|
||||
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
|
||||
movl dlexitproc@GOT(%ebx),%ecx
|
||||
movl %edx,(%ecx)
|
||||
|
||||
{ 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
|
||||
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 }
|
||||
movl %esp,initialstkptr
|
||||
{$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}
|
||||
|
||||
{ start the program }
|
||||
xorl %ebp,%ebp
|
||||
call PASCALMAIN
|
||||
hlt
|
||||
{ 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;
|
||||
|
||||
procedure _FPC_libc21_haltproc; assembler; nostackframe; public name '_haltproc';
|
||||
asm
|
||||
{$if sizeof(ExitCode)=2}
|
||||
movzwl ExitCode,%eax
|
||||
{$else}
|
||||
mov ExitCode,%eax
|
||||
{$endif}
|
||||
.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
|
||||
|
||||
movl libc21_fpc_ret,%edx { return to libc }
|
||||
movl libc21_fpc_ret_ebp,%ebp
|
||||
movl libc21_fpc_ret_ebx,%ebx
|
||||
push %edx
|
||||
ret
|
||||
{$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;
|
||||
|
||||
|
@ -33,116 +33,224 @@
|
||||
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.
|
||||
|
||||
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_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';
|
||||
|
||||
procedure PASCALMAIN; external name 'PASCALMAIN';
|
||||
|
||||
{******************************************************************************
|
||||
glibc 2.1 lib + profiling start/halt
|
||||
******************************************************************************}
|
||||
{$asmmode ATT}
|
||||
var
|
||||
dlexitproc: pointer; { atexit from loader }
|
||||
|
||||
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
|
||||
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 %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 }
|
||||
|
||||
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)
|
||||
|
||||
{ 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_envp@GOT(%ebx),%ecx
|
||||
movl %eax,(%ecx)
|
||||
|
||||
call _FPC_libc21_gprof_gmon_start
|
||||
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 }
|
||||
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
|
||||
{ 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; assembler; nostackframe; public name '_haltproc';
|
||||
asm
|
||||
{$if sizeof(ExitCode)=2}
|
||||
movzwl ExitCode,%eax
|
||||
{$else}
|
||||
mov ExitCode,%eax
|
||||
{$endif}
|
||||
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
|
||||
|
||||
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
|
||||
{$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;
|
||||
|
||||
|
@ -35,18 +35,19 @@
|
||||
|
||||
procedure PASCALMAIN; external name 'PASCALMAIN';
|
||||
|
||||
function get1eipasebx : pointer; compilerproc; nostackframe; assembler;
|
||||
asm
|
||||
movl (%esp),%ebx
|
||||
ret
|
||||
end;
|
||||
|
||||
{******************************************************************************
|
||||
Shared library start/halt
|
||||
******************************************************************************}
|
||||
{$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
|
||||
{ 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_argv:=argv; { Copy the argument pointer }
|
||||
@ -54,53 +55,45 @@ begin
|
||||
|
||||
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;
|
||||
end;
|
||||
|
||||
{$ifndef VER2_0}
|
||||
Procedure lib_exit; external name 'FPC_LIB_EXIT';
|
||||
|
||||
{ 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;
|
||||
procedure _FPC_shared_lib_haltproc; assembler; nostackframe; public name 'FPC_SHARED_LIB_EXIT'; public name '_haltproc';
|
||||
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 _FPC_shared_lib_haltproc; assembler; nostackframe; public name '_haltproc';
|
||||
asm
|
||||
{$ifdef FPC_PIC}
|
||||
call fpc_geteipasebx
|
||||
addl $_GLOBAL_OFFSET_TABLE_,%ebx
|
||||
{$endif}
|
||||
.Lhaltproc:
|
||||
call lib_exit
|
||||
{$ifdef FPC_PIC}
|
||||
call get1eipasebx
|
||||
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}
|
||||
xorl %eax,%eax
|
||||
incl %eax { eax=1, exit call }
|
||||
{$ifdef FPC_PIC}
|
||||
pushl %ebx
|
||||
movl ExitCode@GOT(%ebx),%ebx
|
||||
{$if sizeof(ExitCode)=2}
|
||||
movzwl (%ebx),%ebx
|
||||
{$else}
|
||||
mov (%ebx),%ebx
|
||||
{$endif}
|
||||
{$endif}
|
||||
int $0x80
|
||||
jmp .Lhaltproc
|
||||
popl %ebx
|
||||
end;
|
||||
|
||||
|
@ -90,11 +90,23 @@ end;
|
||||
procedure _FPC_proc_gprof_haltproc; assembler; nostackframe; public name '_haltproc';
|
||||
asm
|
||||
.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
|
||||
{$else}
|
||||
{$else}
|
||||
mov ExitCode,%ebx
|
||||
{$endif}
|
||||
{$endif}
|
||||
{$endif FPC_PIC}
|
||||
|
||||
pushl %ebx
|
||||
call libc_exit { call libc exit, this will write the gmon.out }
|
||||
movl syscall_nr_exit_group,%eax
|
||||
|
@ -35,10 +35,16 @@
|
||||
|
||||
procedure PASCALMAIN; external name 'PASCALMAIN';
|
||||
|
||||
function fpc_geteipasebx : pointer; compilerproc; nostackframe; assembler;
|
||||
asm
|
||||
movl (%esp),%ebx
|
||||
ret
|
||||
end;
|
||||
|
||||
{******************************************************************************
|
||||
Process start/halt
|
||||
******************************************************************************}
|
||||
{$asmmode ATT}
|
||||
{$asmmode att}
|
||||
|
||||
var
|
||||
dlexitproc: pointer;
|
||||
@ -46,27 +52,54 @@ var
|
||||
procedure _FPC_proc_start; assembler; nostackframe; public name '_start';
|
||||
asm
|
||||
{ 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 }
|
||||
|
||||
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 %edx, dlexitproc
|
||||
movl dlexitproc@GOT(%ebx),%ecx
|
||||
movl %edx,(%ecx)
|
||||
|
||||
fninit { initialize fpu }
|
||||
fwait
|
||||
fldcw Default8087CW
|
||||
movl operatingsystem_parameter_envp@GOT(%ebx),%ecx
|
||||
movl %eax,(%ecx)
|
||||
|
||||
{ Initialize gs for thread local storage }
|
||||
// movw %ds,%ax
|
||||
// movw %ax,%gs
|
||||
movl operatingsystem_parameter_argc@GOT(%ebx),%edx
|
||||
popl %ecx
|
||||
movl %ecx,(%edx)
|
||||
|
||||
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 FPU }
|
||||
call SysResetFPU
|
||||
|
||||
{ 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
|
||||
call PASCALMAIN
|
||||
@ -74,25 +107,59 @@ end;
|
||||
|
||||
procedure _FPC_proc_haltproc; assembler; nostackframe; public name '_haltproc';
|
||||
asm
|
||||
|
||||
.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
|
||||
je .Lnodlexitproc
|
||||
call *%eax
|
||||
.Lnodlexitproc:
|
||||
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
|
||||
{$else}
|
||||
{$else}
|
||||
mov ExitCode,%ebx
|
||||
{$endif}
|
||||
{$endif}
|
||||
{$endif FPC_PIC}
|
||||
|
||||
int $0x80
|
||||
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
|
||||
{$else}
|
||||
{$else}
|
||||
mov ExitCode,%ebx
|
||||
{$endif}
|
||||
{$endif}
|
||||
{$endif FPC_PIC}
|
||||
|
||||
int $0x80
|
||||
jmp .Lhaltproc
|
||||
end;
|
||||
|
@ -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';
|
||||
|
||||
{ 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}
|
||||
|
||||
procedure _FPC_libc_start; assembler; nostackframe; public name '_start';
|
||||
procedure _FPC_libc21_start; assembler; nostackframe; public name '_start';
|
||||
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 }
|
||||
xorl %ebp,%ebp
|
||||
{ First locate the start of the environment variables }
|
||||
|
||||
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 }
|
||||
popl %ecx { Get argc in ecx }
|
||||
|
||||
pushl %esp { provide highest stack address to C library }
|
||||
pushl %edx { push address of shared library finalization }
|
||||
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 PIC}
|
||||
call .L0
|
||||
.L0:
|
||||
pop %ebx
|
||||
addl $_GLOBAL_OFFSET_TABLE_+[.-.L0],%ebx
|
||||
{$ifdef FPC_PIC}
|
||||
pushl %edx
|
||||
pushl %ebx
|
||||
pushl %ecx
|
||||
|
||||
call get3eipasebx
|
||||
addl $_GLOBAL_OFFSET_TABLE_,%ebx
|
||||
|
||||
pushl _fini@GOT(%ebx) { push address of entry points }
|
||||
pushl _init@GOT(%ebx)
|
||||
movl dlexitproc@GOT(%ebx),%ecx
|
||||
movl %edx,(%ecx)
|
||||
|
||||
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
|
||||
movl operatingsystem_parameter_envp@GOT(%ebx),%ecx
|
||||
movl %eax,(%ecx)
|
||||
|
||||
pushl %ecx { push argv }
|
||||
pushl %esi { push argc }
|
||||
movl operatingsystem_parameter_argc@GOT(%ebx),%edx
|
||||
popl %ecx
|
||||
movl %ecx,(%edx)
|
||||
|
||||
pushl $PASCALMAIN { push fpc main procedure }
|
||||
call libc_main { let fpc main be called from libc startup }
|
||||
{$endif}
|
||||
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;
|
||||
|
||||
procedure _FPC_libc_haltproc; assembler; nostackframe; public name '_haltproc';
|
||||
procedure _FPC_libc21_haltproc; assembler; nostackframe; public name '_haltproc';
|
||||
asm
|
||||
.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
|
||||
call libc_exit
|
||||
call uclibc_exit
|
||||
xorl %eax,%eax
|
||||
incl %eax { eax=1, exit call }
|
||||
popl %ebx
|
||||
int $0x80
|
||||
jmp .Lhaltproc
|
||||
end;
|
||||
|
||||
end;
|
||||
|
@ -77,17 +77,34 @@ end;
|
||||
|
||||
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 }
|
||||
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
|
||||
.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:
|
||||
pop %ecx
|
||||
pop %ebx
|
||||
cmpl $-4095,%eax
|
||||
jb .LSyscOK
|
||||
negl %eax
|
||||
@ -96,21 +113,40 @@ asm
|
||||
.LSyscOK:
|
||||
end;
|
||||
|
||||
|
||||
function FpSysCall(sysnr,param1 : TSysParam):TSysResult; assembler; register; [public,alias:'FPC_SYSCALL1'];
|
||||
{ Var sysnr located in register eax
|
||||
Var param1 located in register edx }
|
||||
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
|
||||
{$endif FPC_PIC}
|
||||
|
||||
jne .LSysEnter
|
||||
movl %edx,%ebx // param1
|
||||
int $0x80
|
||||
jmp .LTail
|
||||
.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:
|
||||
movl %ecx,%ebx
|
||||
pop %ecx
|
||||
pop %ebx
|
||||
cmpl $-4095,%eax
|
||||
jb .LSyscOK
|
||||
negl %eax
|
||||
@ -125,17 +161,37 @@ function FpSysCall(sysnr,param1,param2 : TSysParam):TSysResult; assembler; regis
|
||||
Var param2 located in register ecx }
|
||||
asm
|
||||
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
|
||||
{$endif FPC_PIC}
|
||||
jne .LSysEnter
|
||||
movl %edx,%ebx // param1
|
||||
pop %ecx // param2
|
||||
int $0x80
|
||||
jmp .LTail
|
||||
.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:
|
||||
pop %ebx
|
||||
pop %edx
|
||||
pop %ebx
|
||||
cmpl $-4095,%eax
|
||||
jb .LSyscOK
|
||||
negl %eax
|
||||
@ -149,20 +205,45 @@ function FpSysCall(sysnr,param1,param2,param3:TSysParam):TSysResult; assembler;
|
||||
Var param1 located in register edx
|
||||
Var param2 located in register ecx
|
||||
Var param3 located at ebp+20 }
|
||||
var
|
||||
_psysinfo: LongWord;
|
||||
asm
|
||||
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
|
||||
{$endif FPC_PIC}
|
||||
jne .LSysEnter
|
||||
movl %edx,%ebx // param1
|
||||
pop %ecx // param2
|
||||
movl param3,%edx // param3
|
||||
int $0x80
|
||||
jmp .LTail
|
||||
.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
|
||||
{$endif FPC_PIC}
|
||||
.LTail:
|
||||
pop %ebx
|
||||
pop %edx
|
||||
pop %ebx
|
||||
cmpl $-4095,%eax
|
||||
jb .LSyscOK
|
||||
negl %eax
|
||||
@ -177,23 +258,48 @@ function FpSysCall(sysnr,param1,param2,param3,param4:TSysParam):TSysResult; asse
|
||||
Var param2 located in register ecx
|
||||
Var param3 located at ebp+20
|
||||
Var param4 located at ebp+16 }
|
||||
var
|
||||
_psysinfo: LongWord;
|
||||
asm
|
||||
push %ebx
|
||||
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
|
||||
jne .LSysEnter
|
||||
{$endif FPC_PIC}
|
||||
jne .LSysEnter
|
||||
movl %edx,%ebx // param1
|
||||
pop %ecx // param2
|
||||
movl param3,%edx // param3
|
||||
movl param4,%esi // param4
|
||||
int $0x80
|
||||
jmp .LTail
|
||||
jmp .LTail
|
||||
.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:
|
||||
pop %esi
|
||||
pop %ebx
|
||||
pop %esi
|
||||
pop %ebx
|
||||
cmpl $-4095,%eax
|
||||
jb .LSyscOK
|
||||
negl %eax
|
||||
@ -209,26 +315,55 @@ function FpSysCall(sysnr,param1,param2,param3,param4,param5 : TSysParam):TSysRes
|
||||
Var param3 located at ebp+20
|
||||
Var param4 located at ebp+16
|
||||
Var param5 located at ebp+12 }
|
||||
var
|
||||
_psysinfo: LongWord;
|
||||
asm
|
||||
push %ebx
|
||||
push %edx
|
||||
push %esi
|
||||
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
|
||||
{$endif FPC_PIC}
|
||||
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
|
||||
.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
|
||||
{$endif FPC_PIC}
|
||||
.LTail:
|
||||
pop %edi
|
||||
pop %esi
|
||||
pop %ebx
|
||||
pop %edi
|
||||
pop %esi
|
||||
pop %edx
|
||||
pop %ebx
|
||||
cmpl $-4095,%eax
|
||||
jb .LSyscOK
|
||||
negl %eax
|
||||
@ -245,29 +380,60 @@ function FpSysCall(sysnr,param1,param2,param3,param4,param5,param6: TSysParam):T
|
||||
Var param4 located at ebp+16
|
||||
Var param5 located at ebp+12
|
||||
Var param6 located at ebp+8 }
|
||||
var
|
||||
_psysinfo: LongWord;
|
||||
asm
|
||||
push %ebx
|
||||
push %edx
|
||||
push %esi
|
||||
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
|
||||
{$endif FPC_PIC}
|
||||
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
|
||||
jmp .LTail
|
||||
.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
|
||||
{$endif FPC_PIC}
|
||||
.LTail:
|
||||
pop %ebp
|
||||
pop %edi
|
||||
pop %esi
|
||||
pop %ebx
|
||||
pop %ebp
|
||||
pop %edi
|
||||
pop %esi
|
||||
pop %edx
|
||||
pop %ebx
|
||||
cmpl $-4095,%eax
|
||||
jb .LSyscOK
|
||||
negl %eax
|
||||
|
@ -19,9 +19,9 @@
|
||||
.globl _startlib
|
||||
.type _startlib,@function
|
||||
_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
|
||||
|
|
||||
@ -36,6 +36,9 @@ FPC_LIB_START:
|
||||
.globl _haltproc
|
||||
.type _haltproc,@function
|
||||
haltproc:
|
||||
.globl FPC_SHARED_LIB_EXIT
|
||||
.type FPC_SHARED_LIB_EXIT,@function
|
||||
FPC_SHARED_LIB_EXIT:
|
||||
moveq.l #1,%d0
|
||||
move.w U_SYSLINUX_EXITCODE,%d1
|
||||
trap #0
|
||||
|
@ -35,9 +35,9 @@
|
||||
*/
|
||||
.section .init
|
||||
.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
|
||||
|
||||
.text
|
||||
@ -68,6 +68,10 @@ _startlib:
|
||||
.globl _haltproc
|
||||
.type _haltproc,@function
|
||||
_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 */
|
||||
movq operatingsystem_result@GOTPCREL(%rip),%rbx
|
||||
movzwl (%rbx),%edi
|
||||
|
Loading…
Reference in New Issue
Block a user