mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-05-12 06:12:43 +02:00
510 lines
12 KiB
PHP
510 lines
12 KiB
PHP
{
|
|
This file is part of the Free Pascal run time library.
|
|
Copyright (c) 1999-2000 by Michael Van Canneyt,
|
|
member of the Free Pascal development team.
|
|
|
|
The syscalls for the new RTL, moved to platform dependant dir.
|
|
Old linux calling convention is still kept.
|
|
|
|
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.
|
|
|
|
**********************************************************************}
|
|
|
|
{$ASMMODE ATT}
|
|
|
|
{*************************SYSENTER CODE********************************}
|
|
|
|
{ included by system.pp in linux rtl }
|
|
const
|
|
AT_NULL = 0;
|
|
{* Pointer to the global system page used for system calls and other
|
|
nice things. *}
|
|
AT_SYSINFO = 32;
|
|
AT_SYSINFO_EHDR = 33;
|
|
|
|
type
|
|
TAuxiliaryValue = cuInt32;
|
|
|
|
TInternalUnion = record
|
|
a_val: cuint32; //* Integer value */
|
|
{* We use to have pointer elements added here. We cannot do that,
|
|
though, since it does not work when using 32-bit definitions
|
|
on 64-bit platforms and vice versa. *}
|
|
end;
|
|
|
|
Elf32_auxv_t = record
|
|
a_type: cuint32; //* Entry type */
|
|
a_un: TInternalUnion;
|
|
end;
|
|
TElf32AuxiliaryVector = Elf32_auxv_t;
|
|
PElf32AuxiliaryVector = ^TElf32AuxiliaryVector;
|
|
|
|
var
|
|
psysinfo: LongWord = 0;
|
|
|
|
procedure InitSyscallIntf;
|
|
var
|
|
ep: PPChar;
|
|
auxv: PElf32AuxiliaryVector;
|
|
begin
|
|
|
|
psysinfo := 0;
|
|
ep := envp;
|
|
while ep^ <> nil do
|
|
Inc(ep);
|
|
|
|
Inc(ep);
|
|
|
|
auxv := PElf32AuxiliaryVector(ep);
|
|
|
|
repeat
|
|
if auxv^.a_type = AT_SYSINFO then begin
|
|
psysinfo := auxv^.a_un.a_val;
|
|
if psysinfo <> 0 then
|
|
sysenter_supported := 1; // descision factor in asm syscall routines
|
|
Break;
|
|
end;
|
|
Inc(auxv);
|
|
until auxv^.a_type = AT_NULL;
|
|
end;
|
|
|
|
{***********************SYSENTER CODE END******************************}
|
|
|
|
Procedure fpc_geteipasebx;[external name 'fpc_geteipasebx'];
|
|
|
|
{$ifdef FPC_PROFILE}
|
|
procedure mcount; external name 'mcount';
|
|
{$endif FPC_PROFILE}
|
|
|
|
function FpSysCall(sysnr:TSysParam):TSysResult; assembler; register; [public,alias:'FPC_SYSCALL0'];
|
|
{ Var sysnr located in register eax }
|
|
asm
|
|
{$ifdef FPC_PROFILE}
|
|
push %eax
|
|
call mcount
|
|
pop %eax
|
|
{$endif FPC_PROFILE}
|
|
push %ebx
|
|
push %ecx
|
|
{$ifdef FPC_PIC}
|
|
call fpc_geteipasebx
|
|
addl $_GLOBAL_OFFSET_TABLE_,%ebx
|
|
movl sysenter_supported@GOT(%ebx),%ecx
|
|
movl (%ecx),%ecx
|
|
cmp $0, %ecx
|
|
{$else FPC_PIC}
|
|
cmp $0, sysenter_supported
|
|
{$endif FPC_PIC}
|
|
jne .LSysEnter
|
|
int $0x80
|
|
jmp .LTail
|
|
.LSysEnter:
|
|
{$ifdef FPC_PIC}
|
|
movl psysinfo@GOT(%ebx),%ecx
|
|
movl (%ecx),%ecx
|
|
call *%ecx
|
|
{$else FPC_PIC}
|
|
call psysinfo
|
|
{$endif FPC_PIC}
|
|
.LTail:
|
|
pop %ecx
|
|
pop %ebx
|
|
cmpl $-4095,%eax
|
|
jb .LSyscOK
|
|
negl %eax
|
|
call seterrno
|
|
movl $-1,%eax
|
|
.LSyscOK:
|
|
end;
|
|
|
|
|
|
function FpSysCall(sysnr,param1 : TSysParam):TSysResult; assembler; register; [public,alias:'FPC_SYSCALL1'];
|
|
{ Var sysnr located in register eax
|
|
Var param1 located in register edx }
|
|
asm
|
|
{$ifdef FPC_PROFILE}
|
|
push %eax
|
|
push %edx
|
|
call mcount
|
|
pop %edx
|
|
pop %eax
|
|
{$endif FPC_PROFILE}
|
|
push %ebx
|
|
push %ecx
|
|
{$ifdef FPC_PIC}
|
|
call fpc_geteipasebx
|
|
addl $_GLOBAL_OFFSET_TABLE_,%ebx
|
|
movl sysenter_supported@GOT(%ebx),%ecx
|
|
movl (%ecx),%ecx
|
|
cmp $0, %ecx
|
|
{$else FPC_PIC}
|
|
cmp $0, sysenter_supported
|
|
{$endif FPC_PIC}
|
|
|
|
jne .LSysEnter
|
|
movl %edx,%ebx // param1
|
|
int $0x80
|
|
jmp .LTail
|
|
.LSysEnter:
|
|
{$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:
|
|
pop %ecx
|
|
pop %ebx
|
|
cmpl $-4095,%eax
|
|
jb .LSyscOK
|
|
negl %eax
|
|
call seterrno
|
|
movl $-1,%eax
|
|
.LSyscOK:
|
|
end;
|
|
|
|
function FpSysCall(sysnr,param1,param2 : TSysParam):TSysResult; assembler; register; [public,alias:'FPC_SYSCALL2'];
|
|
{ Var sysnr located in register eax
|
|
Var param1 located in register edx
|
|
Var param2 located in register ecx }
|
|
asm
|
|
{$ifdef FPC_PROFILE}
|
|
push %eax
|
|
push %edx
|
|
push %ecx
|
|
call mcount
|
|
pop %ecx
|
|
pop %edx
|
|
pop %eax
|
|
{$endif FPC_PROFILE}
|
|
push %ebx
|
|
push %edx
|
|
push %ecx
|
|
{$ifdef FPC_PIC}
|
|
call fpc_geteipasebx
|
|
addl $_GLOBAL_OFFSET_TABLE_,%ebx
|
|
movl sysenter_supported@GOT(%ebx),%ecx
|
|
movl (%ecx),%ecx
|
|
cmp $0, %ecx
|
|
{$else FPC_PIC}
|
|
cmp $0, sysenter_supported
|
|
{$endif FPC_PIC}
|
|
jne .LSysEnter
|
|
movl %edx,%ebx // param1
|
|
pop %ecx // param2
|
|
int $0x80
|
|
jmp .LTail
|
|
.LSysEnter:
|
|
{$ifdef FPC_PIC}
|
|
movl psysinfo@GOT(%ebx),%ecx
|
|
movl %edx,%ebx // param1
|
|
movl (%ecx),%edx
|
|
pop %ecx // param2
|
|
call *%edx
|
|
{$else FPC_PIC}
|
|
movl %edx,%ebx // param1
|
|
pop %ecx // param2
|
|
call psysinfo
|
|
{$endif FPC_PIC}
|
|
.LTail:
|
|
pop %edx
|
|
pop %ebx
|
|
cmpl $-4095,%eax
|
|
jb .LSyscOK
|
|
negl %eax
|
|
call seterrno
|
|
movl $-1,%eax
|
|
.LSyscOK:
|
|
end;
|
|
|
|
function FpSysCall(sysnr,param1,param2,param3:TSysParam):TSysResult; assembler; register; [public,alias:'FPC_SYSCALL3'];
|
|
{ Var sysnr located in register eax
|
|
Var param1 located in register edx
|
|
Var param2 located in register ecx
|
|
Var param3 located at ebp+20 }
|
|
var
|
|
_psysinfo: LongWord;
|
|
asm
|
|
{$ifdef FPC_PROFILE}
|
|
push %eax
|
|
push %edx
|
|
push %ecx
|
|
call mcount
|
|
pop %ecx
|
|
pop %edx
|
|
pop %eax
|
|
{$endif FPC_PROFILE}
|
|
push %ebx
|
|
push %edx
|
|
push %ecx
|
|
{$ifdef FPC_PIC}
|
|
call fpc_geteipasebx
|
|
addl $_GLOBAL_OFFSET_TABLE_,%ebx
|
|
movl sysenter_supported@GOT(%ebx),%ecx
|
|
movl (%ecx),%ecx
|
|
cmp $0, %ecx
|
|
{$else FPC_PIC}
|
|
cmp $0, sysenter_supported
|
|
{$endif FPC_PIC}
|
|
jne .LSysEnter
|
|
movl %edx,%ebx // param1
|
|
pop %ecx // param2
|
|
movl param3,%edx // param3
|
|
int $0x80
|
|
jmp .LTail
|
|
.LSysEnter:
|
|
{$ifdef FPC_PIC}
|
|
movl psysinfo@GOT(%ebx),%ecx
|
|
movl (%ecx),%ecx
|
|
movl %ecx,_psysinfo
|
|
movl %edx,%ebx // param1
|
|
pop %ecx // param2
|
|
movl param3,%edx // param3
|
|
call _psysinfo
|
|
{$else FPC_PIC}
|
|
movl %edx,%ebx // param1
|
|
pop %ecx // param2
|
|
movl param3,%edx // param3
|
|
call psysinfo
|
|
{$endif FPC_PIC}
|
|
.LTail:
|
|
pop %edx
|
|
pop %ebx
|
|
cmpl $-4095,%eax
|
|
jb .LSyscOK
|
|
negl %eax
|
|
call seterrno
|
|
movl $-1,%eax
|
|
.LSyscOK:
|
|
end;
|
|
|
|
function FpSysCall(sysnr,param1,param2,param3,param4:TSysParam):TSysResult; assembler; register; [public,alias:'FPC_SYSCALL4'];
|
|
{ Var sysnr located in register eax
|
|
Var param1 located in register edx
|
|
Var param2 located in register ecx
|
|
Var param3 located at ebp+20
|
|
Var param4 located at ebp+16 }
|
|
var
|
|
_psysinfo: LongWord;
|
|
asm
|
|
{$ifdef FPC_PROFILE}
|
|
push %eax
|
|
push %edx
|
|
push %ecx
|
|
call mcount
|
|
pop %ecx
|
|
pop %edx
|
|
pop %eax
|
|
{$endif FPC_PROFILE}
|
|
push %ebx
|
|
push %esi
|
|
push %ecx
|
|
{$ifdef FPC_PIC}
|
|
call fpc_geteipasebx
|
|
addl $_GLOBAL_OFFSET_TABLE_,%ebx
|
|
movl sysenter_supported@GOT(%ebx),%ecx
|
|
movl (%ecx),%ecx
|
|
cmp $0, %ecx
|
|
{$else FPC_PIC}
|
|
cmp $0, sysenter_supported
|
|
{$endif FPC_PIC}
|
|
jne .LSysEnter
|
|
movl %edx,%ebx // param1
|
|
pop %ecx // param2
|
|
movl param3,%edx // param3
|
|
movl param4,%esi // param4
|
|
int $0x80
|
|
jmp .LTail
|
|
.LSysEnter:
|
|
{$ifdef FPC_PIC}
|
|
movl psysinfo@GOT(%ebx),%ecx
|
|
movl (%ecx),%ecx
|
|
movl %ecx,_psysinfo
|
|
movl %edx,%ebx // param1
|
|
pop %ecx // param2
|
|
movl param3,%edx // param3
|
|
movl param4,%esi // param4
|
|
call _psysinfo
|
|
{$else FPC_PIC}
|
|
movl %edx,%ebx // param1
|
|
pop %ecx // param2
|
|
movl param3,%edx // param3
|
|
movl param4,%esi // param4
|
|
call psysinfo
|
|
{$endif FPC_PIC}
|
|
.LTail:
|
|
pop %esi
|
|
pop %ebx
|
|
cmpl $-4095,%eax
|
|
jb .LSyscOK
|
|
negl %eax
|
|
call seterrno
|
|
movl $-1,%eax
|
|
.LSyscOK:
|
|
end;
|
|
|
|
function FpSysCall(sysnr,param1,param2,param3,param4,param5 : TSysParam):TSysResult; assembler; register; [public,alias:'FPC_SYSCALL5'];
|
|
{ Var sysnr located in register eax
|
|
Var param1 located in register edx
|
|
Var param2 located in register ecx
|
|
Var param3 located at ebp+20
|
|
Var param4 located at ebp+16
|
|
Var param5 located at ebp+12 }
|
|
var
|
|
_psysinfo: LongWord;
|
|
asm
|
|
{$ifdef FPC_PROFILE}
|
|
push %eax
|
|
push %edx
|
|
push %ecx
|
|
call mcount
|
|
pop %ecx
|
|
pop %edx
|
|
pop %eax
|
|
{$endif FPC_PROFILE}
|
|
push %ebx
|
|
push %edx
|
|
push %esi
|
|
push %edi
|
|
push %ecx
|
|
{$ifdef FPC_PIC}
|
|
call fpc_geteipasebx
|
|
addl $_GLOBAL_OFFSET_TABLE_,%ebx
|
|
movl sysenter_supported@GOT(%ebx),%ecx
|
|
movl (%ecx),%ecx
|
|
cmp $0, %ecx
|
|
{$else FPC_PIC}
|
|
cmp $0, sysenter_supported
|
|
{$endif FPC_PIC}
|
|
jne .LSysEnter
|
|
movl %edx,%ebx // param1
|
|
pop %ecx // param2
|
|
movl param3,%edx // param3
|
|
movl param4,%esi // param4
|
|
movl param5,%edi // param5
|
|
int $0x80
|
|
jmp .LTail
|
|
.LSysEnter:
|
|
{$ifdef FPC_PIC}
|
|
movl psysinfo@GOT(%ebx),%ecx
|
|
movl (%ecx),%ecx
|
|
movl %ecx,_psysinfo
|
|
movl %edx,%ebx // param1
|
|
pop %ecx // param2
|
|
movl param3,%edx // param3
|
|
movl param4,%esi // param4
|
|
movl param5,%edi // param5
|
|
call _psysinfo
|
|
{$else FPC_PIC}
|
|
movl %edx,%ebx // param1
|
|
pop %ecx // param2
|
|
movl param3,%edx // param3
|
|
movl param4,%esi // param4
|
|
movl param5,%edi // param5
|
|
call psysinfo
|
|
{$endif FPC_PIC}
|
|
.LTail:
|
|
pop %edi
|
|
pop %esi
|
|
pop %edx
|
|
pop %ebx
|
|
cmpl $-4095,%eax
|
|
jb .LSyscOK
|
|
negl %eax
|
|
call seterrno
|
|
movl $-1,%eax
|
|
.LSyscOK:
|
|
end;
|
|
|
|
function FpSysCall(sysnr,param1,param2,param3,param4,param5,param6: TSysParam):TSysResult; assembler; register; [public,alias:'FPC_SYSCALL6'];
|
|
{ Var sysnr located in register eax
|
|
Var param1 located in register edx
|
|
Var param2 located in register ecx
|
|
Var param3 located at ebp+20
|
|
Var param4 located at ebp+16
|
|
Var param5 located at ebp+12
|
|
Var param6 located at ebp+8 }
|
|
var
|
|
_psysinfo: LongWord;
|
|
asm
|
|
{$ifdef FPC_PROFILE}
|
|
push %eax
|
|
push %edx
|
|
push %ecx
|
|
call mcount
|
|
pop %ecx
|
|
pop %edx
|
|
pop %eax
|
|
{$endif FPC_PROFILE}
|
|
push %ebx
|
|
push %edx
|
|
push %esi
|
|
push %edi
|
|
push %ebp
|
|
push %ecx
|
|
{$ifdef FPC_PIC}
|
|
call fpc_geteipasebx
|
|
addl $_GLOBAL_OFFSET_TABLE_,%ebx
|
|
movl sysenter_supported@GOT(%ebx),%ecx
|
|
movl (%ecx),%ecx
|
|
cmp $0, %ecx
|
|
{$else FPC_PIC}
|
|
cmp $0, sysenter_supported
|
|
{$endif FPC_PIC}
|
|
jne .LSysEnter
|
|
movl %edx,%ebx // param1
|
|
pop %ecx // param2
|
|
movl param3,%edx // param3
|
|
movl param4,%esi // param4
|
|
movl param5,%edi // param5
|
|
movl param6,%ebp // param6
|
|
int $0x80
|
|
jmp .LTail
|
|
.LSysEnter:
|
|
{$ifdef FPC_PIC}
|
|
movl psysinfo@GOT(%ebx),%ecx
|
|
movl (%ecx),%ecx
|
|
movl %ecx,_psysinfo
|
|
movl %edx,%ebx // param1
|
|
pop %ecx // param2
|
|
movl param3,%edx // param3
|
|
movl param4,%esi // param4
|
|
movl param5,%edi // param5
|
|
movl param6,%ebp // param6
|
|
call _psysinfo
|
|
{$else FPC_PIC}
|
|
movl %edx,%ebx // param1
|
|
pop %ecx // param2
|
|
movl param3,%edx // param3
|
|
movl param4,%esi // param4
|
|
movl param5,%edi // param5
|
|
movl param6,%ebp // param6
|
|
call psysinfo
|
|
{$endif FPC_PIC}
|
|
.LTail:
|
|
pop %ebp
|
|
pop %edi
|
|
pop %esi
|
|
pop %edx
|
|
pop %ebx
|
|
cmpl $-4095,%eax
|
|
jb .LSyscOK
|
|
negl %eax
|
|
call seterrno
|
|
movl $-1,%eax
|
|
.LSyscOK:
|
|
end;
|
|
|
|
{No debugging for syslinux include !}
|
|
{$IFDEF SYS_LINUX}
|
|
{$UNDEF SYSCALL_DEBUG}
|
|
{$ENDIF SYS_LINUX}
|