X86: Add the arch_prctl system call and fix up some microcoding.

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
This commit is contained in:
Gabe Black 2007-08-04 20:02:41 -07:00
parent 121a894ce0
commit 0e6be2a9b1
2 changed files with 50 additions and 10 deletions

View 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

View 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),