X86: Add a vsyscall page for 32 bit processes to use.
This commit is contained in:
parent
c3d7d7ed0e
commit
db3c51d3a0
2 changed files with 66 additions and 8 deletions
|
@ -152,12 +152,32 @@ X86_64LiveProcess::X86_64LiveProcess(LiveProcessParams *params,
|
|||
mmap_start = mmap_end = (Addr)0x2aaaaaaab000ULL;
|
||||
}
|
||||
|
||||
void
|
||||
I386LiveProcess::syscall(int64_t callnum, ThreadContext *tc)
|
||||
{
|
||||
Addr eip = tc->readPC();
|
||||
if (eip >= vsyscallPage.base &&
|
||||
eip < vsyscallPage.base + vsyscallPage.size) {
|
||||
tc->setNextPC(vsyscallPage.base + vsyscallPage.vsysexitOffset);
|
||||
}
|
||||
X86LiveProcess::syscall(callnum, tc);
|
||||
}
|
||||
|
||||
|
||||
I386LiveProcess::I386LiveProcess(LiveProcessParams *params,
|
||||
ObjectFile *objFile, SyscallDesc *_syscallDescs,
|
||||
int _numSyscallDescs) :
|
||||
X86LiveProcess(params, objFile, _syscallDescs, _numSyscallDescs)
|
||||
{
|
||||
stack_base = (Addr)0xffffe000ULL;
|
||||
_gdtStart = 0x100000000;
|
||||
_gdtSize = VMPageSize;
|
||||
|
||||
vsyscallPage.base = 0xffffe000ULL;
|
||||
vsyscallPage.size = VMPageSize;
|
||||
vsyscallPage.vsyscallOffset = 0x400;
|
||||
vsyscallPage.vsysexitOffset = 0x410;
|
||||
|
||||
stack_base = vsyscallPage.base;
|
||||
|
||||
// Set pointer for next thread stack. Reserve 8M for main stack.
|
||||
next_thread_stack_base = stack_base - (8 * 1024 * 1024);
|
||||
|
@ -255,8 +275,6 @@ I386LiveProcess::startup()
|
|||
* Set up a GDT for this process. The whole GDT wouldn't really be for
|
||||
* this process, but the only parts we care about are.
|
||||
*/
|
||||
_gdtStart = stack_base;
|
||||
_gdtSize = VMPageSize;
|
||||
pTable->allocate(_gdtStart, _gdtSize);
|
||||
uint64_t zero = 0;
|
||||
assert(_gdtSize % sizeof(zero) == 0);
|
||||
|
@ -265,6 +283,27 @@ I386LiveProcess::startup()
|
|||
initVirtMem->write(gdtCurrent, zero);
|
||||
}
|
||||
|
||||
// Set up the vsyscall page for this process.
|
||||
pTable->allocate(vsyscallPage.base, vsyscallPage.size);
|
||||
uint8_t vsyscallBlob[] = {
|
||||
0x51, // push %ecx
|
||||
0x52, // push %edp
|
||||
0x55, // push %ebp
|
||||
0x89, 0xe5, // mov %esp, %ebp
|
||||
0x0f, 0x34 // sysenter
|
||||
};
|
||||
initVirtMem->writeBlob(vsyscallPage.base + vsyscallPage.vsyscallOffset,
|
||||
vsyscallBlob, sizeof(vsyscallBlob));
|
||||
|
||||
uint8_t vsysexitBlob[] = {
|
||||
0x5d, // pop %ebp
|
||||
0x5a, // pop %edx
|
||||
0x59, // pop %ecx
|
||||
0xc3 // ret
|
||||
};
|
||||
initVirtMem->writeBlob(vsyscallPage.base + vsyscallPage.vsysexitOffset,
|
||||
vsysexitBlob, sizeof(vsysexitBlob));
|
||||
|
||||
for (int i = 0; i < contextIds.size(); i++) {
|
||||
ThreadContext * tc = system->getThreadContext(contextIds[i]);
|
||||
|
||||
|
@ -332,12 +371,13 @@ I386LiveProcess::startup()
|
|||
|
||||
template<class IntType>
|
||||
void
|
||||
X86LiveProcess::argsInit(int pageSize)
|
||||
X86LiveProcess::argsInit(int pageSize,
|
||||
std::vector<AuxVector<IntType> > extraAuxvs)
|
||||
{
|
||||
int intSize = sizeof(IntType);
|
||||
|
||||
typedef AuxVector<IntType> auxv_t;
|
||||
std::vector<auxv_t> auxv;
|
||||
std::vector<auxv_t> auxv = extraAuxvs;
|
||||
|
||||
string filename;
|
||||
if(argv.size() < 1)
|
||||
|
@ -608,13 +648,19 @@ X86LiveProcess::argsInit(int pageSize)
|
|||
void
|
||||
X86_64LiveProcess::argsInit(int intSize, int pageSize)
|
||||
{
|
||||
X86LiveProcess::argsInit<uint64_t>(pageSize);
|
||||
std::vector<AuxVector<uint64_t> > extraAuxvs;
|
||||
X86LiveProcess::argsInit<uint64_t>(pageSize, extraAuxvs);
|
||||
}
|
||||
|
||||
void
|
||||
I386LiveProcess::argsInit(int intSize, int pageSize)
|
||||
{
|
||||
X86LiveProcess::argsInit<uint32_t>(pageSize);
|
||||
std::vector<AuxVector<uint32_t> > extraAuxvs;
|
||||
//Tell the binary where the vsyscall part of the vsyscall page is.
|
||||
extraAuxvs.push_back(AuxVector<uint32_t>(0x20,
|
||||
vsyscallPage.base + vsyscallPage.vsyscallOffset));
|
||||
extraAuxvs.push_back(AuxVector<uint32_t>(0x21, vsyscallPage.base));
|
||||
X86LiveProcess::argsInit<uint32_t>(pageSize, extraAuxvs);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -80,7 +80,8 @@ namespace X86ISA
|
|||
SyscallDesc *_syscallDescs, int _numSyscallDescs);
|
||||
|
||||
template<class IntType>
|
||||
void argsInit(int pageSize);
|
||||
void argsInit(int pageSize,
|
||||
std::vector<AuxVector<IntType> > extraAuxvs);
|
||||
|
||||
public:
|
||||
Addr gdtStart()
|
||||
|
@ -114,10 +115,21 @@ namespace X86ISA
|
|||
I386LiveProcess(LiveProcessParams *params, ObjectFile *objFile,
|
||||
SyscallDesc *_syscallDescs, int _numSyscallDescs);
|
||||
|
||||
class VSyscallPage
|
||||
{
|
||||
public:
|
||||
Addr base;
|
||||
Addr size;
|
||||
Addr vsyscallOffset;
|
||||
Addr vsysexitOffset;
|
||||
};
|
||||
VSyscallPage vsyscallPage;
|
||||
|
||||
public:
|
||||
void argsInit(int intSize, int pageSize);
|
||||
void startup();
|
||||
|
||||
void syscall(int64_t callnum, ThreadContext *tc);
|
||||
X86ISA::IntReg getSyscallArg(ThreadContext *tc, int i);
|
||||
void setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue