X86: Add the arch_prctl system call and fix up some microcoding.
authorGabe Black <gblack@eecs.umich.edu>
Sun, 5 Aug 2007 03:02:41 +0000 (20:02 -0700)
committerGabe Black <gblack@eecs.umich.edu>
Sun, 5 Aug 2007 03:02:41 +0000 (20:02 -0700)
The arch_prctl system call is used to set and get the FS and GS segment
bases. The FS segment is use for TLS, so glibc needs to be able to set it
up.

--HG--
extra : convert_revision : 79501491a15967a7a862add846ff88a934fb1b37

src/arch/x86/isa/insts/logical.py
src/arch/x86/linux/syscalls.cc

index 81a4730def474424b36d8b01da75ae80efb339ac..b30f31421438aaffe290e003284f21d4f0acf2f0 100644 (file)
@@ -133,9 +133,9 @@ def macroop XOR_P_I
 {
     limm t2, imm
     rdip t7
-    ld t1, ds, [scale, index, base], disp
+    ld t1, ds, [1, t0, t7], disp
     xor t1, t1, t2, flags=(OF,SF,ZF,PF,CF)
-    st t1, ds, [scale, index, base], disp
+    st t1, ds, [1, t0, t7], disp
 };
 
 def macroop XOR_M_R
@@ -148,7 +148,7 @@ def macroop XOR_M_R
 def macroop XOR_P_R
 {
     rdip t7
-    ld t1, ds, [scale, index, base], disp
+    ld t1, ds, [1, t0, t7], disp
     xor t1, t1, reg, flags=(OF,SF,ZF,PF,CF)
     st t1, ds, [scale, index, base], disp
 };
@@ -162,7 +162,7 @@ def macroop XOR_R_M
 def macroop XOR_R_P
 {
     rdip t7
-    ld t1, ds, [scale, index, base], disp
+    ld t1, ds, [1, t0, t7], disp
     xor reg, reg, t1, flags=(OF,SF,ZF,PF,CF)
 };
 
@@ -180,7 +180,7 @@ def macroop AND_R_M
 def macroop AND_R_P
 {
     rdip t7
-    ld t1, ds, [scale, index, base], disp
+    ld t1, ds, [1, t0, t7], disp
     and reg, reg, t1, flags=(OF,SF,ZF,PF,CF)
 };
 
@@ -201,10 +201,10 @@ def macroop AND_M_I
 def macroop AND_P_I
 {
     rdip t7
-    ld t2, ds, [scale, index, base], disp
+    ld t2, ds, [0, t0, t7], disp
     limm t1, imm
     and t2, t2, t1, flags=(OF,SF,ZF,PF,CF)
-    st t2, ds, [scale, index, base], disp
+    st t2, ds, [0, t0, t7], disp
 };
 
 def macroop AND_M_R
@@ -217,9 +217,9 @@ def macroop AND_M_R
 def macroop AND_P_R
 {
     rdip t7
-    ld t1, ds, [scale, index, base], disp
+    ld t1, ds, [0, t0, t7], disp
     and t1, t1, reg, flags=(OF,SF,ZF,PF,CF)
-    st t1, ds, [scale, index, base], disp
+    st t1, ds, [0, t0, t7], disp
 };
 
 def macroop NOT_R
index efbe33dfaf7a35c3deeec09d528f3b855499789b..1146af708ed39e8625fdbd7461039579d0474f41 100644 (file)
@@ -57,6 +57,7 @@
 
 #include "arch/x86/linux/process.hh"
 #include "arch/x86/linux/linux.hh"
+#include "arch/x86/miscregs.hh"
 #include "kern/linux/linux.hh"
 #include "sim/syscall_emul.hh"
 
@@ -80,6 +81,45 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
     return 0;
 }
 
+static SyscallReturn
+archPrctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
+              ThreadContext *tc)
+{
+    enum ArchPrctlCodes
+    {
+        SetFS = 0x1002,
+        GetFS = 0x1003,
+        SetGS = 0x1001,
+        GetGS = 0x1004
+    };
+
+    //First argument is the code, second is the address
+    int code = tc->getSyscallArg(0);
+    uint64_t addr = tc->getSyscallArg(1);
+    uint64_t fsBase, gsBase;
+    TranslatingPort *p = tc->getMemPort();
+    switch(code)
+    {
+      //Each of these valid options should actually check addr.
+      case SetFS:
+        tc->setMiscRegNoEffect(MISCREG_FS_BASE, addr);
+        return 0;
+      case GetFS:
+        fsBase = tc->readMiscRegNoEffect(MISCREG_FS_BASE);
+        p->write(addr, fsBase);
+        return 0;
+      case SetGS:
+        tc->setMiscRegNoEffect(MISCREG_GS_BASE, addr);
+        return 0;
+      case GetGS:
+        gsBase = tc->readMiscRegNoEffect(MISCREG_GS_BASE);
+        p->write(addr, gsBase);
+        return 0;
+      default:
+        return -EINVAL;
+    }
+}
+
 SyscallDesc X86LinuxProcess::syscallDescs[] = {
     /*   0 */ SyscallDesc("read", readFunc),
     /*   1 */ SyscallDesc("write", writeFunc),
@@ -239,7 +279,7 @@ SyscallDesc X86LinuxProcess::syscallDescs[] = {
     /* 155 */ SyscallDesc("pivot_root", unimplementedFunc),
     /* 156 */ SyscallDesc("_sysctl", unimplementedFunc),
     /* 157 */ SyscallDesc("prctl", unimplementedFunc),
-    /* 158 */ SyscallDesc("arch_prctl", unimplementedFunc),
+    /* 158 */ SyscallDesc("arch_prctl", archPrctlFunc),
     /* 159 */ SyscallDesc("adjtimex", unimplementedFunc),
     /* 160 */ SyscallDesc("setrlimit", unimplementedFunc),
     /* 161 */ SyscallDesc("chroot", unimplementedFunc),