mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-06-06 10:38:26 +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 }
|
{ 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';
|
InitStr:='-init FPC_SHARED_LIB_START';
|
||||||
FiniStr:='-fini FPC_LIB_EXIT';
|
FiniStr:='-fini FPC_SHARED_LIB_EXIT';
|
||||||
SoNameStr:='-soname '+ExtractFileName(current_module.sharedlibfilename^);
|
SoNameStr:='-soname '+ExtractFileName(current_module.sharedlibfilename^);
|
||||||
|
|
||||||
{ Call linker }
|
{ Call linker }
|
||||||
|
@ -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
|
||||||
|
@ -19,9 +19,9 @@
|
|||||||
.globl _startlib
|
.globl _startlib
|
||||||
.type _startlib,@function
|
.type _startlib,@function
|
||||||
_startlib:
|
_startlib:
|
||||||
.globl FPC_LIB_START
|
.globl FPC_SHARED_LIB_START
|
||||||
.type FPC_LIB_START,@function
|
.type FPC_SHARED_LIB_START,@function
|
||||||
FPC_LIB_START:
|
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
|
||||||
|
@ -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 }
|
{$ifdef FPC_PIC}
|
||||||
movl %ecx,operatingsystem_parameter_argc { Move the argument counter }
|
pushl %ecx
|
||||||
movl %ebx,operatingsystem_parameter_argv { Move the argument pointer }
|
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 }
|
||||||
|
@ -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
|
popl %ecx { Get argc in ecx }
|
||||||
movl %eax,%edi
|
|
||||||
|
|
||||||
movl %esp,%ebx { Points to the arguments }
|
movl %esp,%ebx { Esp now points to the arguments }
|
||||||
movl %esi,%eax
|
leal 4(%esp,%ecx,4),%eax { The start of the environment is: esp+4*eax+4 }
|
||||||
incl %eax
|
|
||||||
shll $2,%eax
|
|
||||||
addl %esp,%eax
|
|
||||||
andl $0xfffffff8,%esp { Align stack }
|
andl $0xfffffff8,%esp { Align stack }
|
||||||
|
|
||||||
movl %eax,operatingsystem_parameter_envp { Move the environment pointer }
|
{$ifdef FPC_PIC}
|
||||||
movl %esi,operatingsystem_parameter_argc { Move the argument counter }
|
pushl %edx
|
||||||
movl %ebx,operatingsystem_parameter_argv { Move the argument pointer }
|
pushl %ebx
|
||||||
|
pushl %ecx
|
||||||
|
|
||||||
|
call .Lpiclab
|
||||||
|
.Lpiclab:
|
||||||
|
popl %ebx
|
||||||
|
addl $_GLOBAL_OFFSET_TABLE_,%ebx
|
||||||
|
|
||||||
xorl %ebp,%ebp
|
movl dlexitproc@GOT(%ebx),%ecx
|
||||||
pushl %edi
|
movl %edx,(%ecx)
|
||||||
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 }
|
movl operatingsystem_parameter_envp@GOT(%ebx),%ecx
|
||||||
.Lmain:
|
movl %eax,(%ecx)
|
||||||
{ save return address }
|
|
||||||
popl %eax
|
movl operatingsystem_parameter_argc@GOT(%ebx),%edx
|
||||||
movl %eax,libc21_fpc_ret
|
popl %ecx
|
||||||
movl %ebx,libc21_fpc_ret_ebx
|
movl %ecx,(%edx)
|
||||||
movl %ebp,libc21_fpc_ret_ebp
|
|
||||||
pushl %eax
|
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 .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 }
|
{ int __libc_start_main(
|
||||||
xorl %ebp,%ebp
|
int *(main) (int, char * *, char * *),
|
||||||
call PASCALMAIN
|
int argc,
|
||||||
hlt
|
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}
|
.Lhaltproc:
|
||||||
movzwl ExitCode,%eax
|
{$ifdef FPC_PIC}
|
||||||
{$else}
|
call .Lpiclab
|
||||||
mov ExitCode,%eax
|
.Lpiclab:
|
||||||
{$endif}
|
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 }
|
{$ifdef FPC_PIC}
|
||||||
movl libc21_fpc_ret_ebp,%ebp
|
call .Lpiclab2
|
||||||
movl libc21_fpc_ret_ebx,%ebx
|
.Lpiclab2:
|
||||||
push %edx
|
popl %ebx
|
||||||
ret
|
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;
|
||||||
|
|
||||||
|
@ -33,116 +33,224 @@
|
|||||||
argc <--- esp
|
argc <--- esp
|
||||||
}
|
}
|
||||||
|
|
||||||
var
|
{
|
||||||
gmon_etext: longint; external name '_etext';
|
This file is part of the Free Pascal run time library.
|
||||||
gmon_start: longint; external name '_start';
|
Copyright (c) 2005 by Michael Van Canneyt, Peter Vreman,
|
||||||
gmon_mcleanup: procedure; external name '_mcleanup';
|
& Daniel Mantione, members of the Free Pascal development team.
|
||||||
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;
|
|
||||||
|
|
||||||
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 libc_start_main; external name '__libc_start_main';
|
||||||
|
|
||||||
procedure PASCALMAIN; external name 'PASCALMAIN';
|
procedure PASCALMAIN; external name 'PASCALMAIN';
|
||||||
|
|
||||||
{******************************************************************************
|
var
|
||||||
glibc 2.1 lib + profiling start/halt
|
dlexitproc: pointer; { atexit from loader }
|
||||||
******************************************************************************}
|
|
||||||
{$asmmode ATT}
|
|
||||||
|
|
||||||
procedure _FPC_libc21_gprof_gmon_start; assembler; nostackframe;
|
gmon_start : record end;external name 'PASCALMAIN';
|
||||||
asm
|
gmon_etext : record end;external name '_etext';
|
||||||
pushl %ebp
|
|
||||||
movl gmon_monstarted,%eax
|
gmon_monstarted: longint = 0;
|
||||||
leal 0x1(%eax),%edx
|
|
||||||
movl %esp,%ebp
|
{******************************************************************************
|
||||||
movl %edx,gmon_monstarted
|
Process start/halt
|
||||||
testl %eax,%eax
|
******************************************************************************}
|
||||||
jnz .Lnomonstart
|
|
||||||
pushl $gmon_start
|
procedure _FPC_libc21_gprof_gmon_start; public name '_FPC_libc21_gprof_gmon_start';
|
||||||
pushl $gmon_etext { Initialize gmon }
|
begin
|
||||||
call gmon_monstartup
|
if gmon_monstarted=0 then
|
||||||
addl $8,%esp
|
begin
|
||||||
pushl $gmon_mcleanup
|
inc(gmon_monstarted);
|
||||||
call libc_atexit
|
gmon_monstartup(@gmon_start,@gmon_etext);
|
||||||
addl $4,%esp
|
end;
|
||||||
.Lnomonstart:
|
PASCALMAIN;
|
||||||
movl %ebp,%esp
|
|
||||||
popl %ebp
|
|
||||||
ret
|
|
||||||
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 }
|
popl %ecx { Get argc in ecx }
|
||||||
movl %esi,%eax
|
|
||||||
incl %eax
|
movl %esp,%ebx { Esp now points to the arguments }
|
||||||
shll $2,%eax
|
leal 4(%esp,%ecx,4),%eax { The start of the environment is: esp+4*eax+4 }
|
||||||
addl %esp,%eax
|
|
||||||
andl $0xfffffff8,%esp { Align stack }
|
andl $0xfffffff8,%esp { Align stack }
|
||||||
|
|
||||||
movl %eax,operatingsystem_parameter_envp { Move the environment pointer }
|
{$ifdef FPC_PIC}
|
||||||
movl %esi,operatingsystem_parameter_argc { Move the argument counter }
|
pushl %edx
|
||||||
movl %ebx,operatingsystem_parameter_argv { Move the argument pointer }
|
pushl %ebx
|
||||||
|
pushl %ecx
|
||||||
|
|
||||||
|
call fpc0geteipasebx
|
||||||
|
addl $_GLOBAL_OFFSET_TABLE_,%ebx
|
||||||
|
|
||||||
movl %edi,%eax
|
movl dlexitproc@GOT(%ebx),%ecx
|
||||||
xorl %ebp,%ebp
|
movl %edx,(%ecx)
|
||||||
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
|
|
||||||
|
|
||||||
{ fake main routine which will be run from libc }
|
movl operatingsystem_parameter_envp@GOT(%ebx),%ecx
|
||||||
.Lcmain:
|
movl %eax,(%ecx)
|
||||||
{ 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
|
|
||||||
|
|
||||||
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 }
|
{ 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 }
|
{ int __libc_start_main(
|
||||||
call PASCALMAIN
|
int *(main) (int, char * *, char * *),
|
||||||
hlt
|
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;
|
end;
|
||||||
|
|
||||||
procedure _FPC_libc21_gprof_haltproc; assembler; nostackframe; public name '_haltproc';
|
procedure _FPC_libc21_gprof_haltproc(e:longint);cdecl;public name '_haltproc';
|
||||||
asm
|
begin
|
||||||
{$if sizeof(ExitCode)=2}
|
if gmon_monstarted=1 then
|
||||||
movzwl ExitCode,%eax
|
begin
|
||||||
{$else}
|
dec(gmon_monstarted);
|
||||||
mov ExitCode,%eax
|
gmon_mcleanup;
|
||||||
{$endif}
|
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 }
|
{$ifdef FPC_PIC}
|
||||||
movl libc21_fpc_ret_ebx,%ebx
|
call fpc0geteipasebx
|
||||||
movl libc21_fpc_ret_esi,%esi
|
addl $_GLOBAL_OFFSET_TABLE_,%ebx
|
||||||
movl libc21_fpc_ret_edi,%edi
|
movl ExitCode@GOT(%ebx),%ebx
|
||||||
push %edx
|
{$if sizeof(ExitCode)=2}
|
||||||
ret
|
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;
|
end;
|
||||||
|
|
||||||
|
@ -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}
|
Procedure lib_exit; external name 'FPC_LIB_EXIT';
|
||||||
|
|
||||||
{ this hack is needed so we can make the reference below to _FPC_shared_lib_start }
|
procedure _FPC_shared_lib_haltproc; assembler; nostackframe; public name 'FPC_SHARED_LIB_EXIT'; public name '_haltproc';
|
||||||
{ 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
|
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:
|
.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
|
xorl %eax,%eax
|
||||||
incl %eax { eax=1, exit call }
|
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
|
int $0x80
|
||||||
jmp .Lhaltproc
|
jmp .Lhaltproc
|
||||||
popl %ebx
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
{$ifdef FPC_PIC}
|
||||||
movl %ecx,operatingsystem_parameter_argc
|
pushl %ebx
|
||||||
movl %ebx,operatingsystem_parameter_argv
|
pushl %ecx
|
||||||
|
|
||||||
|
call fpc_geteipasebx
|
||||||
|
addl $_GLOBAL_OFFSET_TABLE_,%ebx
|
||||||
|
|
||||||
movl %edx, dlexitproc
|
movl dlexitproc@GOT(%ebx),%ecx
|
||||||
|
movl %edx,(%ecx)
|
||||||
|
|
||||||
fninit { initialize fpu }
|
movl operatingsystem_parameter_envp@GOT(%ebx),%ecx
|
||||||
fwait
|
movl %eax,(%ecx)
|
||||||
fldcw Default8087CW
|
|
||||||
|
|
||||||
{ Initialize gs for thread local storage }
|
movl operatingsystem_parameter_argc@GOT(%ebx),%edx
|
||||||
// movw %ds,%ax
|
popl %ecx
|
||||||
// movw %ax,%gs
|
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 }
|
{ 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;
|
||||||
|
@ -40,75 +40,138 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
procedure libc_init; external name '__uClibc_init';
|
var
|
||||||
procedure libc_fini; external name '__uClibc_fini';
|
dlexitproc: pointer; { atexit from loader }
|
||||||
procedure libc_exit; external name '_exit';
|
|
||||||
procedure libc_main; external name '__uClibc_main';
|
|
||||||
|
|
||||||
|
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 }
|
xorl %ebp,%ebp
|
||||||
popl %esi { Get argc in ecx }
|
{ First locate the start of the environment variables }
|
||||||
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 }
|
popl %ecx { Get argc in ecx }
|
||||||
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 }
|
movl %esp,%ebx { Esp now points to the arguments }
|
||||||
pushl %edx { push address of shared library finalization }
|
leal 4(%esp,%ecx,4),%eax { The start of the environment is: esp+4*eax+4 }
|
||||||
|
andl $0xfffffff8,%esp { Align stack }
|
||||||
|
|
||||||
{$ifdef PIC}
|
{$ifdef FPC_PIC}
|
||||||
call .L0
|
pushl %edx
|
||||||
.L0:
|
pushl %ebx
|
||||||
pop %ebx
|
pushl %ecx
|
||||||
addl $_GLOBAL_OFFSET_TABLE_+[.-.L0],%ebx
|
|
||||||
|
call get3eipasebx
|
||||||
|
addl $_GLOBAL_OFFSET_TABLE_,%ebx
|
||||||
|
|
||||||
pushl _fini@GOT(%ebx) { push address of entry points }
|
movl dlexitproc@GOT(%ebx),%ecx
|
||||||
pushl _init@GOT(%ebx)
|
movl %edx,(%ecx)
|
||||||
|
|
||||||
pushl %ecx { push argv }
|
movl operatingsystem_parameter_envp@GOT(%ebx),%ecx
|
||||||
pushl %esi { push argc }
|
movl %eax,(%ecx)
|
||||||
|
|
||||||
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 }
|
movl operatingsystem_parameter_argc@GOT(%ebx),%edx
|
||||||
pushl %esi { push argc }
|
popl %ecx
|
||||||
|
movl %ecx,(%edx)
|
||||||
|
|
||||||
pushl $PASCALMAIN { push fpc main procedure }
|
movl operatingsystem_parameter_argv@GOT(%ebx),%edx
|
||||||
call libc_main { let fpc main be called from libc startup }
|
popl %ebx
|
||||||
{$endif}
|
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
|
{$ifdef FPC_PIC}
|
||||||
{$else}
|
call get3eipasebx
|
||||||
mov ExitCode,%ebx
|
addl $_GLOBAL_OFFSET_TABLE_,%ebx
|
||||||
{$endif}
|
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;
|
||||||
|
@ -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
|
push %ebx
|
||||||
cmp $0, sysenter_supported
|
push %ecx
|
||||||
jne .LSysEnter
|
{$ifdef FPC_PIC}
|
||||||
int $0x80
|
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
|
push %ebx
|
||||||
// movl sysnr,%eax
|
push %ecx
|
||||||
movl %edx,%ebx
|
{$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
|
push %edx
|
||||||
movl %edx,%ebx
|
push %ecx
|
||||||
// movl param2,%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
|
push %edx
|
||||||
movl %edx,%ebx
|
push %ecx
|
||||||
// movl param2,%ecx
|
{$ifdef FPC_PIC}
|
||||||
movl param3,%edx
|
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
|
push %ecx
|
||||||
movl %edx,%ebx
|
{$ifdef FPC_PIC}
|
||||||
// movl param2,%ecx
|
call fpc_geteipasebx
|
||||||
movl param3,%edx
|
addl $_GLOBAL_OFFSET_TABLE_,%ebx
|
||||||
movl param4,%esi
|
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 %esi
|
||||||
pop %ebx
|
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
|
push %ecx
|
||||||
movl %edx,%ebx
|
{$ifdef FPC_PIC}
|
||||||
// movl param2,%ecx
|
call fpc_geteipasebx
|
||||||
movl param3,%edx
|
addl $_GLOBAL_OFFSET_TABLE_,%ebx
|
||||||
movl param4,%esi
|
movl sysenter_supported@GOT(%ebx),%ecx
|
||||||
movl param5,%edi
|
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 %edi
|
||||||
pop %esi
|
pop %esi
|
||||||
pop %ebx
|
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
|
push %ebp
|
||||||
// movl sysnr,%eax
|
push %ecx
|
||||||
movl %edx,%ebx
|
{$ifdef FPC_PIC}
|
||||||
// movl param2,%ecx
|
call fpc_geteipasebx
|
||||||
movl param3,%edx
|
addl $_GLOBAL_OFFSET_TABLE_,%ebx
|
||||||
movl param4,%esi
|
movl sysenter_supported@GOT(%ebx),%ecx
|
||||||
movl param5,%edi
|
movl (%ecx),%ecx
|
||||||
movl param6,%ebp
|
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 %ebp
|
||||||
pop %edi
|
pop %edi
|
||||||
pop %esi
|
pop %esi
|
||||||
pop %ebx
|
pop %edx
|
||||||
|
pop %ebx
|
||||||
cmpl $-4095,%eax
|
cmpl $-4095,%eax
|
||||||
jb .LSyscOK
|
jb .LSyscOK
|
||||||
negl %eax
|
negl %eax
|
||||||
|
@ -19,9 +19,9 @@
|
|||||||
.globl _startlib
|
.globl _startlib
|
||||||
.type _startlib,@function
|
.type _startlib,@function
|
||||||
_startlib:
|
_startlib:
|
||||||
.globl FPC_LIB_START
|
.globl FPC_SHARED_LIB_START
|
||||||
.type FPC_LIB_START,@function
|
.type FPC_SHARED_LIB_START,@function
|
||||||
FPC_LIB_START:
|
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
|
||||||
|
@ -35,9 +35,9 @@
|
|||||||
*/
|
*/
|
||||||
.section .init
|
.section .init
|
||||||
.align 16
|
.align 16
|
||||||
.globl FPC_LIB_START
|
.globl FPC_SHARED_LIB_START
|
||||||
.type FPC_LIB_START,@function
|
.type FPC_SHARED_LIB_START,@function
|
||||||
FPC_LIB_START:
|
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
|
||||||
|
Loading…
Reference in New Issue
Block a user