* 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:
Jonas Maebe 2009-09-12 21:57:41 +00:00
parent cc5aeb09de
commit 92ff07deaf
13 changed files with 925 additions and 331 deletions

View File

@ -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 }

View File

@ -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

View File

@ -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

View File

@ -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 }

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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