{ 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']; function FpSysCall(sysnr:TSysParam):TSysResult; assembler; register; [public,alias:'FPC_SYSCALL0']; { Var sysnr located in register eax } asm 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 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 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 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 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 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 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}