Browse Source

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

git-svn-id: trunk@6992 -
Almindor 18 years ago
parent
commit
c626740043
3 changed files with 106 additions and 2 deletions
  1. 98 1
      rtl/linux/i386/syscall.inc
  2. 4 0
      rtl/linux/i386/syscallh.inc
  3. 4 1
      rtl/linux/system.pp

+ 98 - 1
rtl/linux/i386/syscall.inc

@@ -17,13 +17,74 @@
 
 
 {$ASMMODE ATT}
 {$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;
+
+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'];
 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
 //      movl  sysnr,%eax
-        int   $0x80
+        cmp  $0, sysenter_supported
+        jne  .LSysEnter
+        int $0x80
+        jmp   .LTail
+  .LSysEnter:
+        call psysinfo
+  .LTail:
         cmpl  $-4095,%eax
         cmpl  $-4095,%eax
         jb    .LSyscOK
         jb    .LSyscOK
         negl  %eax
         negl  %eax
@@ -39,7 +100,13 @@ asm
         movl  %ebx,%ecx
         movl  %ebx,%ecx
 //      movl  sysnr,%eax
 //      movl  sysnr,%eax
         movl  %edx,%ebx
         movl  %edx,%ebx
+        cmp   $0, sysenter_supported
+        jne   .LSysEnter
         int   $0x80
         int   $0x80
+        jmp   .LTail
+  .LSysEnter:
+        call psysinfo
+  .LTail:
         movl  %ecx,%ebx
         movl  %ecx,%ebx
         cmpl  $-4095,%eax
         cmpl  $-4095,%eax
         jb    .LSyscOK
         jb    .LSyscOK
@@ -58,7 +125,13 @@ asm
 //      movl  sysnr,%eax
 //      movl  sysnr,%eax
         movl  %edx,%ebx
         movl  %edx,%ebx
 //      movl  param2,%ecx
 //      movl  param2,%ecx
+        cmp   $0, sysenter_supported
+        jne   .LSysEnter
         int   $0x80
         int   $0x80
+        jmp   .LTail
+  .LSysEnter:
+        call psysinfo
+  .LTail:
         pop   %ebx
         pop   %ebx
         cmpl  $-4095,%eax
         cmpl  $-4095,%eax
         jb    .LSyscOK
         jb    .LSyscOK
@@ -79,7 +152,13 @@ asm
         movl  %edx,%ebx
         movl  %edx,%ebx
 //      movl  param2,%ecx
 //      movl  param2,%ecx
         movl  param3,%edx
         movl  param3,%edx
+        cmp   $0, sysenter_supported
+        jne   .LSysEnter
         int   $0x80
         int   $0x80
+        jmp   .LTail
+  .LSysEnter:
+        call psysinfo
+  .LTail:
         pop   %ebx
         pop   %ebx
         cmpl  $-4095,%eax
         cmpl  $-4095,%eax
         jb    .LSyscOK
         jb    .LSyscOK
@@ -103,7 +182,13 @@ asm
 //      movl  param2,%ecx
 //      movl  param2,%ecx
         movl  param3,%edx
         movl  param3,%edx
         movl  param4,%esi
         movl  param4,%esi
+        cmp   $0, sysenter_supported
+        jne   .LSysEnter
         int   $0x80
         int   $0x80
+        jmp  .LTail
+  .LSysEnter:
+        call psysinfo
+  .LTail:
         pop   %esi
         pop   %esi
         pop   %ebx
         pop   %ebx
         cmpl  $-4095,%eax
         cmpl  $-4095,%eax
@@ -131,7 +216,13 @@ asm
         movl  param3,%edx
         movl  param3,%edx
         movl  param4,%esi
         movl  param4,%esi
         movl  param5,%edi
         movl  param5,%edi
+        cmp   $0, sysenter_supported
+        jne   .LSysEnter
         int   $0x80
         int   $0x80
+        jmp   .LTail
+  .LSysEnter:
+        call psysinfo
+  .LTail:
         pop   %edi
         pop   %edi
         pop   %esi
         pop   %esi
         pop   %ebx
         pop   %ebx
@@ -163,7 +254,13 @@ asm
         movl  param4,%esi
         movl  param4,%esi
         movl  param5,%edi
         movl  param5,%edi
         movl  param6,%ebp
         movl  param6,%ebp
+        cmp   $0, sysenter_supported
+        jne   .LSysEnter
         int   $0x80
         int   $0x80
+        jmp   .LTail
+  .LSysEnter:
+        call psysinfo
+  .LTail:
         pop   %ebp
         pop   %ebp
         pop   %edi
         pop   %edi
         pop   %esi
         pop   %esi

+ 4 - 0
rtl/linux/i386/syscallh.inc

@@ -32,6 +32,10 @@ Type
 // 64-bit machines don't have only 64-bit params.
 // 64-bit machines don't have only 64-bit params.
 
 
   TSysParam  = Longint;
   TSysParam  = Longint;
+  
+var
+  psysinfo: LongWord;
+  sysenter_supported: LongInt = 0;
 
 
 function Do_SysCall(sysnr:TSysParam):TSysResult; register; external name 'FPC_SYSCALL0';
 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:TSysParam):TSysResult; register; external name 'FPC_SYSCALL1';

+ 4 - 1
rtl/linux/system.pp

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