Переглянути джерело

Merged revisions 6776,6992,7363 via svnmerge from
http://svn.freepascal.org/svn/fpc/trunk

........
r6776 | ivost | 2007-03-10 19:09:13 +0100 (Sat, 10 Mar 2007) | 2 lines

* changed i386 syscall from oldfpccall to register calling convention

........
r6992 | Almindor | 2007-03-25 12:06:23 +0200 (Sun, 25 Mar 2007) | 2 lines

* adds support for sysenter syscall style for i386 on 2.6 kernels

........
r7363 | jonas | 2007-05-16 17:13:36 +0200 (Wed, 16 May 2007) | 2 lines

* -dFPC_USE_LIBC fix

........

git-svn-id: branches/fixes_2_2@8404 -

peter 18 роки тому
батько
коміт
45580f2ac9
3 змінених файлів з 248 додано та 247 видалено
  1. 232 235
      rtl/linux/i386/syscall.inc
  2. 12 11
      rtl/linux/i386/syscallh.inc
  3. 4 1
      rtl/linux/system.pp

+ 232 - 235
rtl/linux/i386/syscall.inc

@@ -17,264 +17,261 @@
 
 {$ASMMODE ATT}
 
-Procedure fpc_geteipasebx;[external name 'fpc_geteipasebx'];
+{*************************SYSENTER CODE********************************}
 
-function FpSysCall(sysnr:TSysParam):TSysResult; assembler; oldfpccall;[public,alias:'FPC_SYSCALL0'];
+{ 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;
 
-asm
-{ load the registers... }
-  movl  sysnr,%eax
-  int   $0x80
-  cmpl  $-4095,%eax
-  jb   .LSyscOK
-  negl  %eax
-{$ifdef FPC_PIC}
-  call  fpc_geteipasebx
-  addl  $_GLOBAL_OFFSET_TABLE_,%ebx
-  movl  fpc_threadvar_relocate_proc@GOT(%ebx),%ecx
-  movl  (%ecx),%ecx
-  movl  Errno@GOT(%ebx),%edi
-{$else FPC_PIC}
-  leal  Errno,%edi
-  movl  fpc_threadvar_relocate_proc,%ecx
-{$endif FPC_PIC}
-  testl %ecx,%ecx
-  jne   .LThread
-  movl  %eax,4(%edi)
-  jmp   .LNoThread
-.LThread:
-  movl  %eax,%ebx
-  movl  (%edi),%eax
-  call  *%ecx
-  movl  %ebx,(%eax)
-.LNoThread:
-  movl  $-1,%eax
-.LSyscOK:
-end;
+type
+  TAuxiliaryValue = cuInt32;
 
-function FpSysCall(sysnr,param1 : TSysParam):TSysResult; assembler; oldfpccall;[public,alias:'FPC_SYSCALL1'];
+  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;
 
-asm
-{ load the registers... }
-  movl sysnr,%eax
-  movl param1,%ebx
-  int $0x80
-  cmpl  $-4095,%eax
-  jb   .LSyscOK
-  negl  %eax
-{$ifdef FPC_PIC}
-  call  fpc_geteipasebx
-  addl  $_GLOBAL_OFFSET_TABLE_,%ebx
-  movl  fpc_threadvar_relocate_proc@GOT(%ebx),%ecx
-  movl  (%ecx),%ecx
-  movl  Errno@GOT(%ebx),%edi
-{$else FPC_PIC}
-  leal  Errno,%edi
-  movl  fpc_threadvar_relocate_proc,%ecx
-{$endif FPC_PIC}
-  testl %ecx,%ecx
-  jne   .LThread
-  movl  %eax,4(%edi)
-  jmp   .LNoThread
-.LThread:
-  movl  %eax,%ebx
-  movl  (%edi),%eax
-  call  *%ecx
-  movl  %ebx,(%eax)
-.LNoThread:
-  movl  $-1,%eax
-.LSyscOK:
-end;
+  Elf32_auxv_t = record
+    a_type: cuint32;              //* Entry type */
+    a_un: TInternalUnion;
+  end;
+  TElf32AuxiliaryVector = Elf32_auxv_t;
+  PElf32AuxiliaryVector = ^TElf32AuxiliaryVector;
 
-function FpSysCall(sysnr,param1,param2 : TSysParam):TSysResult; assembler; oldfpccall; [public,alias:'FPC_SYSCALL2'];
+procedure InitSyscallIntf;
+var
+  ep: PPChar;
+  auxv: PElf32AuxiliaryVector;
+begin
 
-asm
-{ load the registers... }
-  movl sysnr,%eax
-  movl param1,%ebx
-  movl param2,%ecx
-  int $0x80
-  cmpl  $-4095,%eax
-  jb   .LSyscOK
-  negl  %eax
-{$ifdef FPC_PIC}
-  call  fpc_geteipasebx
-  addl  $_GLOBAL_OFFSET_TABLE_,%ebx
-  movl  fpc_threadvar_relocate_proc@GOT(%ebx),%ecx
-  movl  (%ecx),%ecx
-  movl  Errno@GOT(%ebx),%edi
-{$else FPC_PIC}
-  leal  Errno,%edi
-  movl  fpc_threadvar_relocate_proc,%ecx
-{$endif FPC_PIC}
-  testl %ecx,%ecx
-  jne   .LThread
-  movl  %eax,4(%edi)
-  jmp   .LNoThread
-.LThread:
-  movl  %eax,%ebx
-  movl (%edi),%eax
-  call  *%ecx
-  movl  %ebx,(%eax)
-.LNoThread:
-  movl  $-1,%eax
-.LSyscOK:
+  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;
 
-function FpSysCall(sysnr,param1,param2,param3:TSysParam):TSysResult; assembler; oldfpccall; [public,alias:'FPC_SYSCALL3'];
+{***********************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
-{ load the registers... }
-  movl sysnr,%eax
-  movl param1,%ebx
-  movl param2,%ecx
-  movl param3,%edx
-  int $0x80
-  cmpl  $-4095,%eax
-  jb   .LSyscOK
-  negl  %eax
-{$ifdef FPC_PIC}
-  call  fpc_geteipasebx
-  addl  $_GLOBAL_OFFSET_TABLE_,%ebx
-  movl  fpc_threadvar_relocate_proc@GOT(%ebx),%ecx
-  movl  (%ecx),%ecx
-  movl  Errno@GOT(%ebx),%edi
-{$else FPC_PIC}
-  leal  Errno,%edi
-  movl  fpc_threadvar_relocate_proc,%ecx
-{$endif FPC_PIC}
-  testl %ecx,%ecx
-  jne   .LThread
-  movl  %eax,4(%edi)
-  jmp   .LNoThread
-.LThread:
-  movl  %eax,%ebx
-  movl  (%edi),%eax
-  call  *%ecx
-  movl  %ebx,(%eax)
-.LNoThread:
-  movl  $-1,%eax
-.LSyscOK:
+//      movl  sysnr,%eax
+        cmp  $0, sysenter_supported
+        jne  .LSysEnter
+        int $0x80
+        jmp   .LTail
+  .LSysEnter:
+        call psysinfo
+  .LTail:
+        cmpl  $-4095,%eax
+        jb    .LSyscOK
+        negl  %eax
+        call  seterrno
+        movl  $-1,%eax
+  .LSyscOK:
 end;
 
-function FpSysCall(sysnr,param1,param2,param3,param4:TSysParam):TSysResult; assembler; oldfpccall; [public,alias:'FPC_SYSCALL4'];
+function FpSysCall(sysnr,param1 : TSysParam):TSysResult; assembler; register; [public,alias:'FPC_SYSCALL1'];
+{ Var sysnr located in register eax
+  Var param1 located in register edx }
+asm
+        movl  %ebx,%ecx
+//      movl  sysnr,%eax
+        movl  %edx,%ebx
+        cmp   $0, sysenter_supported
+        jne   .LSysEnter
+        int   $0x80
+        jmp   .LTail
+  .LSysEnter:
+        call psysinfo
+  .LTail:
+        movl  %ecx,%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
-{ load the registers... }
-  movl sysnr,%eax
-  movl param1,%ebx
-  movl param2,%ecx
-  movl param3,%edx
-  movl param4,%esi
-  int $0x80
-  cmpl  $-4095,%eax
-  jb   .LSyscOK
-  negl  %eax
-{$ifdef FPC_PIC}
-  call  fpc_geteipasebx
-  addl  $_GLOBAL_OFFSET_TABLE_,%ebx
-  movl  fpc_threadvar_relocate_proc@GOT(%ebx),%ecx
-  movl  (%ecx),%ecx
-  movl  Errno@GOT(%ebx),%edi
-{$else FPC_PIC}
-  leal  Errno,%edi
-  movl  fpc_threadvar_relocate_proc,%ecx
-{$endif FPC_PIC}
-  testl %ecx,%ecx
-  jne   .LThread
-  movl  %eax,4(%edi)
-  jmp   .LNoThread
-.LThread:
-  movl  %eax,%ebx
-  movl  (%edi),%eax
-  call  *%ecx
-  movl  %ebx,(%eax)
-.LNoThread:
-  movl  $-1,%eax
-.LSyscOK:
+        push  %ebx
+//      movl  sysnr,%eax
+        movl  %edx,%ebx
+//      movl  param2,%ecx
+        cmp   $0, sysenter_supported
+        jne   .LSysEnter
+        int   $0x80
+        jmp   .LTail
+  .LSysEnter:
+        call psysinfo
+  .LTail:
+        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; oldfpccall;[public,alias:'FPC_SYSCALL5'];
+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 }
+asm
+        push  %ebx
+//      movl  sysnr,%eax
+        movl  %edx,%ebx
+//      movl  param2,%ecx
+        movl  param3,%edx
+        cmp   $0, sysenter_supported
+        jne   .LSysEnter
+        int   $0x80
+        jmp   .LTail
+  .LSysEnter:
+        call psysinfo
+  .LTail:
+        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 }
 asm
-{ load the registers... }
-  movl sysnr,%eax
-  movl param1,%ebx
-  movl param2,%ecx
-  movl param3,%edx
-  movl param4,%esi
-  movl param5,%edi
-  int $0x80
-  cmpl  $-4095,%eax
-  jb   .LSyscOK
-  negl  %eax
-{$ifdef FPC_PIC}
-  call  fpc_geteipasebx
-  addl  $_GLOBAL_OFFSET_TABLE_,%ebx
-  movl  fpc_threadvar_relocate_proc@GOT(%ebx),%ecx
-  movl  (%ecx),%ecx
-  movl  Errno@GOT(%ebx),%edi
-{$else FPC_PIC}
-  leal  Errno,%edi
-  movl  fpc_threadvar_relocate_proc,%ecx
-{$endif FPC_PIC}
-  testl %ecx,%ecx
-  jne   .LThread
-  movl  %eax,4(%edi)
-  jmp   .LNoThread
-.LThread:
-  movl  %eax,%ebx
-  movl  (%edi),%eax
-  call  *%ecx
-  movl  %ebx,(%eax)
-.LNoThread:
-  movl  $-1,%eax
-.LSyscOK:
+        push  %ebx
+        push  %esi
+//      movl  sysnr,%eax
+        movl  %edx,%ebx
+//      movl  param2,%ecx
+        movl  param3,%edx
+        movl  param4,%esi
+        cmp   $0, sysenter_supported
+        jne   .LSysEnter
+        int   $0x80
+        jmp  .LTail
+  .LSysEnter:
+        call psysinfo
+  .LTail:
+        pop   %esi
+        pop   %ebx
+        cmpl  $-4095,%eax
+        jb    .LSyscOK
+        negl  %eax
+        call  seterrno
+        movl  $-1,%eax
+  .LSyscOK:
 end;
 
-{.$ifdef notsupported}
-{ Only 5 params are pushed, so it'll not work as expected (PFV) }
-function FpSysCall(sysnr,param1,param2,param3,param4,param5,param6 : TSysParam):TSysResult; assembler; oldfpccall;[public,alias:'FPC_SYSCALL6'];
+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 }
+asm
+        push  %ebx
+        push  %esi
+        push  %edi
+//      movl  sysnr,%eax
+        movl  %edx,%ebx
+//      movl  param2,%ecx
+        movl  param3,%edx
+        movl  param4,%esi
+        movl  param5,%edi
+        cmp   $0, sysenter_supported
+        jne   .LSysEnter
+        int   $0x80
+        jmp   .LTail
+  .LSysEnter:
+        call psysinfo
+  .LTail:
+        pop   %edi
+        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,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 }
 asm
-{ load the registers... }
-  push %ebp
-  movl sysnr,%eax
-  movl param1,%ebx
-  movl param2,%ecx
-  movl param3,%edx
-  movl param4,%esi
-  movl param5,%edi
-  movl param6,%ebp
-  int $0x80
-  pop  %ebp
-  cmpl  $-4095,%eax
-  jb   .LSyscOK
-  negl  %eax
-{$ifdef FPC_PIC}
-  call  fpc_geteipasebx
-  addl  $_GLOBAL_OFFSET_TABLE_,%ebx
-  movl  fpc_threadvar_relocate_proc@GOT(%ebx),%ecx
-  movl  (%ecx),%ecx
-  movl  Errno@GOT(%ebx),%edi
-{$else FPC_PIC}
-  leal  Errno,%edi
-  movl  fpc_threadvar_relocate_proc,%ecx
-{$endif FPC_PIC}
-  testl %ecx,%ecx
-  jne   .LThread
-  movl  %eax,4(%edi)
-  jmp   .LNoThread
-.LThread:
-  movl  %eax,%ebx
-  movl  (%edi),%eax
-  call  *%ecx
-  movl  %ebx,(%eax)
-.LNoThread:
-  movl  $-1,%eax
-.LSyscOK:
+        push  %ebx
+        push  %esi
+        push  %edi
+        push  %ebp
+//      movl  sysnr,%eax
+        movl  %edx,%ebx
+//      movl  param2,%ecx
+        movl  param3,%edx
+        movl  param4,%esi
+        movl  param5,%edi
+        movl  param6,%ebp
+        cmp   $0, sysenter_supported
+        jne   .LSysEnter
+        int   $0x80
+        jmp   .LTail
+  .LSysEnter:
+        call psysinfo
+  .LTail:
+        pop   %ebp
+        pop   %edi
+        pop   %esi
+        pop   %ebx
+        cmpl  $-4095,%eax
+        jb    .LSyscOK
+        negl  %eax
+        call  seterrno
+        movl  $-1,%eax
+  .LSyscOK:
 end;
-{.$endif notsupported}
 
 {No debugging for syslinux include !}
 {$IFDEF SYS_LINUX}

+ 12 - 11
rtl/linux/i386/syscallh.inc

@@ -32,14 +32,15 @@ Type
 // 64-bit machines don't have only 64-bit params.
 
   TSysParam  = Longint;
-
-function Do_SysCall(sysnr:TSysParam):TSysResult;  oldfpccall; external name 'FPC_SYSCALL0';
-function Do_SysCall(sysnr,param1:TSysParam):TSysResult; oldfpccall; external name 'FPC_SYSCALL1';
-function Do_SysCall(sysnr,param1,param2:TSysParam):TSysResult;  oldfpccall; external name 'FPC_SYSCALL2';
-function Do_SysCall(sysnr,param1,param2,param3:TSysParam):TSysResult; oldfpccall; external name 'FPC_SYSCALL3';
-function Do_SysCall(sysnr,param1,param2,param3,param4:TSysParam):TSysResult; oldfpccall; external name 'FPC_SYSCALL4';
-function Do_SysCall(sysnr,param1,param2,param3,param4,param5:TSysParam):TSysResult;  oldfpccall; external name 'FPC_SYSCALL5';
-{.$ifdef notsupported}
-function Do_SysCall(sysnr,param1,param2,param3,param4,param5,param6:TSysParam):TSysResult;  oldfpccall; external name 'FPC_SYSCALL6';
-{.$endif notsupported}
-
+  
+var
+  psysinfo: LongWord;
+  sysenter_supported: LongInt = 0;
+
+function Do_SysCall(sysnr:TSysParam):TSysResult; register; external name 'FPC_SYSCALL0';
+function Do_SysCall(sysnr,param1:TSysParam):TSysResult; register; external name 'FPC_SYSCALL1';
+function Do_SysCall(sysnr,param1,param2:TSysParam):TSysResult; register; external name 'FPC_SYSCALL2';
+function Do_SysCall(sysnr,param1,param2,param3:TSysParam):TSysResult; register; external name 'FPC_SYSCALL3';
+function Do_SysCall(sysnr,param1,param2,param3,param4:TSysParam):TSysResult; register; external name 'FPC_SYSCALL4';
+function Do_SysCall(sysnr,param1,param2,param3,param4,param5:TSysParam):TSysResult; register; external name 'FPC_SYSCALL5';
+function Do_SysCall(sysnr,param1,param2,param3,param4,param5,param6:TSysParam):TSysResult; register; external name 'FPC_SYSCALL6';

+ 4 - 1
rtl/linux/system.pp

@@ -227,7 +227,6 @@ begin
   reenable_signal:=geterrno=0;
 end;
 
-
 // signal handler is arch dependant due to processorexception to language
 // exception translation
 
@@ -299,6 +298,10 @@ end;
 var
   initialstkptr : Pointer;external name '__stkptr';
 begin
+{$if defined(i386) and not defined(FPC_USE_LIBC)}
+  InitSyscallIntf;
+{$endif}
+
   SysResetFPU;
 {$if defined(cpupowerpc)}
   // some PPC kernels set the exception bits FE0/FE1 in the MSR to zero,