}
void X86Process::clone(ThreadContext *old_tc, ThreadContext *new_tc,
- Process *p, TheISA::IntReg flags)
+ Process *p, RegVal flags)
{
Process::clone(old_tc, new_tc, p, flags);
X86Process *process = (X86Process*)p;
vsyscallPage.vtimeOffset = 0x400;
vsyscallPage.vgettimeofdayOffset = 0x0;
- Addr brk_point = roundUp(objFile->dataBase() + objFile->dataSize() +
- objFile->bssSize(), PageBytes);
+ Addr brk_point = roundUp(image.maxAddr(), PageBytes);
Addr stack_base = 0x7FFFFFFFF000ULL;
Addr max_stack_size = 8 * 1024 * 1024;
Addr next_thread_stack_base = stack_base - max_stack_size;
next_thread_stack_base, mmap_end);
}
-void
-I386Process::syscall(int64_t callnum, ThreadContext *tc, Fault *fault)
-{
- TheISA::PCState pc = tc->pcState();
- Addr eip = pc.pc();
- if (eip >= vsyscallPage.base &&
- eip < vsyscallPage.base + vsyscallPage.size) {
- pc.npc(vsyscallPage.base + vsyscallPage.vsysexitOffset);
- tc->pcState(pc);
- }
- X86Process::syscall(callnum, tc, fault);
-}
-
I386Process::I386Process(ProcessParams *params, ObjectFile *objFile,
SyscallDesc *_syscallDescs, int _numSyscallDescs)
: X86Process(params, objFile, _syscallDescs, _numSyscallDescs)
{
+ if (kvmInSE)
+ panic("KVM CPU model does not support 32 bit processes");
+
_gdtStart = ULL(0xffffd000);
_gdtSize = PageBytes;
vsyscallPage.vsyscallOffset = 0x400;
vsyscallPage.vsysexitOffset = 0x410;
- Addr brk_point = roundUp(objFile->dataBase() + objFile->dataSize() +
- objFile->bssSize(), PageBytes);
+ Addr brk_point = roundUp(image.maxAddr(), PageBytes);
Addr stack_base = _gdtStart;
Addr max_stack_size = 8 * 1024 * 1024;
Addr next_thread_stack_base = stack_base - max_stack_size;
{
X86Process::initState();
+ if (useForClone)
+ return;
+
argsInit(PageBytes);
// Set up the vsyscall page for this process.
uint8_t numGDTEntries = 0;
uint64_t nullDescriptor = 0;
physProxy.writeBlob(gdtPhysAddr + numGDTEntries * 8,
- (uint8_t *)(&nullDescriptor), 8);
+ &nullDescriptor, 8);
numGDTEntries++;
SegDescriptor initDesc = 0;
initDesc.p = 1; // present
initDesc.l = 1; // longmode - 64 bit
initDesc.d = 0; // operand size
+ initDesc.g = 1;
initDesc.s = 1; // system segment
initDesc.limit = 0xFFFFFFFF;
initDesc.base = 0;
csLowPLDesc.dpl = 0;
uint64_t csLowPLDescVal = csLowPLDesc;
physProxy.writeBlob(gdtPhysAddr + numGDTEntries * 8,
- (uint8_t *)(&csLowPLDescVal), 8);
+ &csLowPLDescVal, 8);
numGDTEntries++;
dsLowPLDesc.dpl = 0;
uint64_t dsLowPLDescVal = dsLowPLDesc;
physProxy.writeBlob(gdtPhysAddr + numGDTEntries * 8,
- (uint8_t *)(&dsLowPLDescVal), 8);
+ &dsLowPLDescVal, 8);
numGDTEntries++;
dsDesc.dpl = 3;
uint64_t dsDescVal = dsDesc;
physProxy.writeBlob(gdtPhysAddr + numGDTEntries * 8,
- (uint8_t *)(&dsDescVal), 8);
+ &dsDescVal, 8);
numGDTEntries++;
csDesc.dpl = 3;
uint64_t csDescVal = csDesc;
physProxy.writeBlob(gdtPhysAddr + numGDTEntries * 8,
- (uint8_t *)(&csDescVal), 8);
+ &csDescVal, 8);
numGDTEntries++;
} tssDescVal = {TSSDescLow, TSSDescHigh};
physProxy.writeBlob(gdtPhysAddr + numGDTEntries * 8,
- (uint8_t *)(&tssDescVal), sizeof(tssDescVal));
+ &tssDescVal, sizeof(tssDescVal));
numGDTEntries++;
efer.sce = 1; // Enable system call extensions.
efer.lme = 1; // Enable long mode.
efer.lma = 1; // Activate long mode.
- efer.nxe = 0; // Enable nx support.
- efer.svme = 1; // Enable svm support for now.
+ efer.nxe = 1; // Enable nx support.
+ efer.svme = 0; // Enable svm support for now.
efer.ffxsr = 0; // Turn on fast fxsave and fxrstor.
tc->setMiscReg(MISCREG_EFER, efer);
CR4 cr4 = 0;
//Turn on pae.
- cr4.osxsave = 1; // Enable XSAVE and Proc Extended States
- cr4.osxmmexcpt = 1; // Operating System Unmasked Exception
+ cr4.osxsave = 0; // Enable XSAVE and Proc Extended States
+ cr4.osxmmexcpt = 0; // Operating System Unmasked Exception
cr4.osfxsr = 1; // Operating System FXSave/FSRSTOR Support
cr4.pce = 0; // Performance-Monitoring Counter Enable
cr4.pge = 0; // Page-Global Enable
tc->setMiscReg(MISCREG_IDTR_LIMIT, 0xffff);
/* enabling syscall and sysret */
- MiscReg star = ((MiscReg)sret << 48) | ((MiscReg)scall << 32);
+ RegVal star = ((RegVal)sret << 48) | ((RegVal)scall << 32);
tc->setMiscReg(MISCREG_STAR, star);
- MiscReg lstar = (MiscReg)syscallCodeVirtAddr;
+ RegVal lstar = (RegVal)syscallCodeVirtAddr;
tc->setMiscReg(MISCREG_LSTAR, lstar);
- MiscReg sfmask = (1 << 8) | (1 << 10); // TF | DF
+ RegVal sfmask = (1 << 8) | (1 << 10); // TF | DF
tc->setMiscReg(MISCREG_SF_MASK, sfmask);
}
tss.RSP1_high = tss.IST1_high;
tss.RSP2_low = tss.IST1_low;
tss.RSP2_high = tss.IST1_high;
- physProxy.writeBlob(tssPhysAddr, (uint8_t *)(&tss), sizeof(tss));
+ physProxy.writeBlob(tssPhysAddr, &tss, sizeof(tss));
/* Setting IDT gates */
GateDescriptorLow PFGateLow = 0;
uint64_t high;
} PFGate = {PFGateLow, PFGateHigh};
- physProxy.writeBlob(idtPhysAddr + 0xE0,
- (uint8_t *)(&PFGate), sizeof(PFGate));
+ physProxy.writeBlob(idtPhysAddr + 0xE0, &PFGate, sizeof(PFGate));
/* System call handler */
uint8_t syscallBlob[] = {
{
int intSize = sizeof(IntType);
- typedef AuxVector<IntType> auxv_t;
- std::vector<auxv_t> auxv = extraAuxvs;
+ std::vector<AuxVector<IntType>> auxv = extraAuxvs;
string filename;
if (argv.size() < 1)
// We want 16 byte alignment
uint64_t align = 16;
- // Patch the ld_bias for dynamic executables.
- updateBias();
-
- // load object file into target memory
- objFile->loadSections(initVirtMem);
-
enum X86CpuFeature {
X86_OnboardFPU = 1 << 0,
X86_VirtualModeExtensions = 1 << 1,
// Bits which describe the system hardware capabilities
// XXX Figure out what these should be
- auxv.push_back(auxv_t(M5_AT_HWCAP, features));
+ auxv.emplace_back(M5_AT_HWCAP, features);
// The system page size
- auxv.push_back(auxv_t(M5_AT_PAGESZ, X86ISA::PageBytes));
+ auxv.emplace_back(M5_AT_PAGESZ, X86ISA::PageBytes);
// Frequency at which times() increments
// Defined to be 100 in the kernel source.
- auxv.push_back(auxv_t(M5_AT_CLKTCK, 100));
+ auxv.emplace_back(M5_AT_CLKTCK, 100);
// This is the virtual address of the program header tables if they
// appear in the executable image.
- auxv.push_back(auxv_t(M5_AT_PHDR, elfObject->programHeaderTable()));
+ auxv.emplace_back(M5_AT_PHDR, elfObject->programHeaderTable());
// This is the size of a program header entry from the elf file.
- auxv.push_back(auxv_t(M5_AT_PHENT, elfObject->programHeaderSize()));
+ auxv.emplace_back(M5_AT_PHENT, elfObject->programHeaderSize());
// This is the number of program headers from the original elf file.
- auxv.push_back(auxv_t(M5_AT_PHNUM, elfObject->programHeaderCount()));
+ auxv.emplace_back(M5_AT_PHNUM, elfObject->programHeaderCount());
// This is the base address of the ELF interpreter; it should be
// zero for static executables or contain the base address for
// dynamic executables.
- auxv.push_back(auxv_t(M5_AT_BASE, getBias()));
+ auxv.emplace_back(M5_AT_BASE, getBias());
// XXX Figure out what this should be.
- auxv.push_back(auxv_t(M5_AT_FLAGS, 0));
+ auxv.emplace_back(M5_AT_FLAGS, 0);
// The entry point to the program
- auxv.push_back(auxv_t(M5_AT_ENTRY, objFile->entryPoint()));
+ auxv.emplace_back(M5_AT_ENTRY, objFile->entryPoint());
// Different user and group IDs
- auxv.push_back(auxv_t(M5_AT_UID, uid()));
- auxv.push_back(auxv_t(M5_AT_EUID, euid()));
- auxv.push_back(auxv_t(M5_AT_GID, gid()));
- auxv.push_back(auxv_t(M5_AT_EGID, egid()));
+ auxv.emplace_back(M5_AT_UID, uid());
+ auxv.emplace_back(M5_AT_EUID, euid());
+ auxv.emplace_back(M5_AT_GID, gid());
+ auxv.emplace_back(M5_AT_EGID, egid());
// Whether to enable "secure mode" in the executable
- auxv.push_back(auxv_t(M5_AT_SECURE, 0));
+ auxv.emplace_back(M5_AT_SECURE, 0);
// The address of 16 "random" bytes.
- auxv.push_back(auxv_t(M5_AT_RANDOM, 0));
+ auxv.emplace_back(M5_AT_RANDOM, 0);
// The name of the program
- auxv.push_back(auxv_t(M5_AT_EXECFN, 0));
+ auxv.emplace_back(M5_AT_EXECFN, 0);
// The platform string
- auxv.push_back(auxv_t(M5_AT_PLATFORM, 0));
+ auxv.emplace_back(M5_AT_PLATFORM, 0);
}
// Figure out how big the initial stack needs to be
// figure out argc
IntType argc = argv.size();
- IntType guestArgc = X86ISA::htog(argc);
+ IntType guestArgc = htole(argc);
// Write out the sentry void *
IntType sentry_NULL = 0;
- initVirtMem.writeBlob(sentry_base, (uint8_t*)&sentry_NULL, sentry_size);
+ initVirtMem.writeBlob(sentry_base, &sentry_NULL, sentry_size);
// Write the file name
initVirtMem.writeString(file_name_base, filename.c_str());
// Fix up the aux vectors which point to data
- assert(auxv[auxv.size() - 3].a_type == M5_AT_RANDOM);
- auxv[auxv.size() - 3].a_val = aux_data_base;
- assert(auxv[auxv.size() - 2].a_type == M5_AT_EXECFN);
- auxv[auxv.size() - 2].a_val = argv_array_base;
- assert(auxv[auxv.size() - 1].a_type == M5_AT_PLATFORM);
- auxv[auxv.size() - 1].a_val = aux_data_base + numRandomBytes;
+ assert(auxv[auxv.size() - 3].type == M5_AT_RANDOM);
+ auxv[auxv.size() - 3].val = aux_data_base;
+ assert(auxv[auxv.size() - 2].type == M5_AT_EXECFN);
+ auxv[auxv.size() - 2].val = argv_array_base;
+ assert(auxv[auxv.size() - 1].type == M5_AT_PLATFORM);
+ auxv[auxv.size() - 1].val = aux_data_base + numRandomBytes;
// Copy the aux stuff
- for (int x = 0; x < auxv.size(); x++) {
- initVirtMem.writeBlob(auxv_array_base + x * 2 * intSize,
- (uint8_t*)&(auxv[x].a_type), intSize);
- initVirtMem.writeBlob(auxv_array_base + (x * 2 + 1) * intSize,
- (uint8_t*)&(auxv[x].a_val), intSize);
+ Addr auxv_array_end = auxv_array_base;
+ for (const auto &aux: auxv) {
+ initVirtMem.write(auxv_array_end, aux, GuestByteOrder);
+ auxv_array_end += sizeof(aux);
}
// Write out the terminating zeroed auxiliary vector
- const uint64_t zero = 0;
- initVirtMem.writeBlob(auxv_array_base + auxv.size() * 2 * intSize,
- (uint8_t*)&zero, intSize);
- initVirtMem.writeBlob(auxv_array_base + (auxv.size() * 2 + 1) * intSize,
- (uint8_t*)&zero, intSize);
+ const AuxVector<uint64_t> zero(0, 0);
+ initVirtMem.write(auxv_array_end, zero);
+ auxv_array_end += sizeof(zero);
initVirtMem.writeString(aux_data_base, platform.c_str());
- copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
- copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem);
+ copyStringArray(envp, envp_array_base, env_data_base,
+ LittleEndianByteOrder, initVirtMem);
+ copyStringArray(argv, argv_array_base, arg_data_base,
+ LittleEndianByteOrder, initVirtMem);
- initVirtMem.writeBlob(argc_base, (uint8_t*)&guestArgc, intSize);
+ initVirtMem.writeBlob(argc_base, &guestArgc, intSize);
ThreadContext *tc = system->getThreadContext(contextIds[0]);
// Set the stack pointer register
X86_64Process::argsInit(int pageSize)
{
std::vector<AuxVector<uint64_t> > extraAuxvs;
- extraAuxvs.push_back(AuxVector<uint64_t>(M5_AT_SYSINFO_EHDR,
- vsyscallPage.base));
+ extraAuxvs.emplace_back(M5_AT_SYSINFO_EHDR, vsyscallPage.base);
X86Process::argsInit<uint64_t>(pageSize, extraAuxvs);
}
{
std::vector<AuxVector<uint32_t> > extraAuxvs;
//Tell the binary where the vsyscall part of the vsyscall page is.
- extraAuxvs.push_back(AuxVector<uint32_t>(M5_AT_SYSINFO,
- vsyscallPage.base + vsyscallPage.vsyscallOffset));
- extraAuxvs.push_back(AuxVector<uint32_t>(M5_AT_SYSINFO_EHDR,
- vsyscallPage.base));
+ extraAuxvs.emplace_back(M5_AT_SYSINFO,
+ vsyscallPage.base + vsyscallPage.vsyscallOffset);
+ extraAuxvs.emplace_back(M5_AT_SYSINFO_EHDR, vsyscallPage.base);
X86Process::argsInit<uint32_t>(pageSize, extraAuxvs);
}
tc->setIntReg(INTREG_RAX, retval.encodedValue());
}
-X86ISA::IntReg
+RegVal
X86_64Process::getSyscallArg(ThreadContext *tc, int &i)
{
assert(i < NumArgumentRegs);
return tc->readIntReg(ArgumentReg[i++]);
}
-void
-X86_64Process::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val)
-{
- assert(i < NumArgumentRegs);
- return tc->setIntReg(ArgumentReg[i], val);
-}
-
void
X86_64Process::clone(ThreadContext *old_tc, ThreadContext *new_tc,
- Process *p, TheISA::IntReg flags)
+ Process *p, RegVal flags)
{
X86Process::clone(old_tc, new_tc, p, flags);
((X86_64Process*)p)->vsyscallPage = vsyscallPage;
}
-X86ISA::IntReg
+RegVal
I386Process::getSyscallArg(ThreadContext *tc, int &i)
{
assert(i < NumArgumentRegs32);
return tc->readIntReg(ArgumentReg32[i++]);
}
-X86ISA::IntReg
+RegVal
I386Process::getSyscallArg(ThreadContext *tc, int &i, int width)
{
assert(width == 32 || width == 64);
return retVal;
}
-void
-I386Process::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val)
-{
- assert(i < NumArgumentRegs);
- return tc->setIntReg(ArgumentReg[i], val);
-}
-
void
I386Process::clone(ThreadContext *old_tc, ThreadContext *new_tc,
- Process *p, TheISA::IntReg flags)
+ Process *p, RegVal flags)
{
X86Process::clone(old_tc, new_tc, p, flags);
((I386Process*)p)->vsyscallPage = vsyscallPage;