X86: Fix argument register indexing.
Code was assuming that all argument registers followed in order from ArgumentReg0. There is now an ArgumentReg array which is indexed to find the right index. There is a constant, NumArgumentRegs, which can be used to protect against using an invalid ArgumentReg. --HG-- extra : convert_revision : f448a3ca4d6adc3fc3323562870f70eec05a8a1f
This commit is contained in:
parent
876849724d
commit
d1e533a1e2
|
@ -76,8 +76,9 @@ FreebsdAlphaSystem::doCalibrateClocks(ThreadContext *tc)
|
|||
Addr ppc_vaddr = 0;
|
||||
Addr timer_vaddr = 0;
|
||||
|
||||
ppc_vaddr = (Addr)tc->readIntReg(ArgumentReg1);
|
||||
timer_vaddr = (Addr)tc->readIntReg(ArgumentReg2);
|
||||
assert(NumArgumentRegs >= 3);
|
||||
ppc_vaddr = (Addr)tc->readIntReg(ArgumentReg[1]);
|
||||
timer_vaddr = (Addr)tc->readIntReg(ArgumentReg[2]);
|
||||
|
||||
virtPort.write(ppc_vaddr, (uint32_t)Clock::Frequency);
|
||||
virtPort.write(timer_vaddr, (uint32_t)TIMER_FREQUENCY);
|
||||
|
|
|
@ -156,14 +156,12 @@ namespace AlphaISA
|
|||
const int ReturnAddressReg = 26;
|
||||
const int ReturnValueReg = 0;
|
||||
const int FramePointerReg = 15;
|
||||
const int ArgumentReg0 = 16;
|
||||
const int ArgumentReg1 = 17;
|
||||
const int ArgumentReg2 = 18;
|
||||
const int ArgumentReg3 = 19;
|
||||
const int ArgumentReg4 = 20;
|
||||
const int ArgumentReg5 = 21;
|
||||
|
||||
const int ArgumentReg[] = {16, 17, 18, 19, 20, 21};
|
||||
const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int);
|
||||
|
||||
const int SyscallNumReg = ReturnValueReg;
|
||||
const int SyscallPseudoReturnReg = ArgumentReg4;
|
||||
const int SyscallPseudoReturnReg = ArgumentReg[4];
|
||||
const int SyscallSuccessReg = 19;
|
||||
|
||||
const int LogVMPageSize = 13; // 8K bytes
|
||||
|
|
|
@ -74,10 +74,10 @@ namespace MipsISA
|
|||
const int ReturnValueReg = 2;
|
||||
const int ReturnValueReg1 = 2;
|
||||
const int ReturnValueReg2 = 3;
|
||||
const int ArgumentReg0 = 4;
|
||||
const int ArgumentReg1 = 5;
|
||||
const int ArgumentReg2 = 6;
|
||||
const int ArgumentReg3 = 7;
|
||||
|
||||
const int ArgumentReg[] = {4, 5, 6, 7};
|
||||
const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int);
|
||||
|
||||
const int KernelReg0 = 26;
|
||||
const int KernelReg1 = 27;
|
||||
const int GlobalPointerReg = 28;
|
||||
|
@ -87,7 +87,7 @@ namespace MipsISA
|
|||
|
||||
const int SyscallNumReg = ReturnValueReg1;
|
||||
const int SyscallPseudoReturnReg = ReturnValueReg2;
|
||||
const int SyscallSuccessReg = ArgumentReg3;
|
||||
const int SyscallSuccessReg = ArgumentReg[3];
|
||||
|
||||
const int LogVMPageSize = 13; // 8K bytes
|
||||
const int VMPageSize = (1 << LogVMPageSize);
|
||||
|
|
|
@ -69,14 +69,12 @@ namespace SparcISA
|
|||
const int ReturnAddressReg = 31; // post call, precall is 15
|
||||
const int ReturnValueReg = 8; // Post return, 24 is pre-return.
|
||||
const int FramePointerReg = 30;
|
||||
const int ArgumentReg0 = 8;
|
||||
const int ArgumentReg1 = 9;
|
||||
const int ArgumentReg2 = 10;
|
||||
const int ArgumentReg3 = 11;
|
||||
const int ArgumentReg4 = 12;
|
||||
const int ArgumentReg5 = 13;
|
||||
|
||||
const int ArgumentReg[] = {8, 9, 10, 11, 12, 13};
|
||||
const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int);
|
||||
|
||||
// Some OS syscall use a second register (o1) to return a second value
|
||||
const int SyscallPseudoReturnReg = ArgumentReg1;
|
||||
const int SyscallPseudoReturnReg = ArgumentReg[1];
|
||||
|
||||
//XXX These numbers are bogus
|
||||
const int MaxInstSrcRegs = 8;
|
||||
|
|
|
@ -399,8 +399,9 @@ Sparc64LiveProcess::argsInit(int intSize, int pageSize)
|
|||
initVirtMem->writeBlob(spillStart, (uint8_t*)spillHandler64, spillSize);
|
||||
|
||||
//Set up the thread context to start running the process
|
||||
threadContexts[0]->setIntReg(ArgumentReg0, argc);
|
||||
threadContexts[0]->setIntReg(ArgumentReg1, argv_array_base);
|
||||
assert(NumArgumentRegs >= 2);
|
||||
threadContexts[0]->setIntReg(ArgumentReg[0], argc);
|
||||
threadContexts[0]->setIntReg(ArgumentReg[1], argv_array_base);
|
||||
threadContexts[0]->setIntReg(StackPointerReg, stack_min - StackBias);
|
||||
|
||||
Addr prog_entry = objFile->entryPoint();
|
||||
|
@ -627,8 +628,9 @@ Sparc32LiveProcess::argsInit(int intSize, int pageSize)
|
|||
initVirtMem->writeBlob(spillStart, (uint8_t*)spillHandler32, spillSize);
|
||||
|
||||
//Set up the thread context to start running the process
|
||||
//threadContexts[0]->setIntReg(ArgumentReg0, argc);
|
||||
//threadContexts[0]->setIntReg(ArgumentReg1, argv_array_base);
|
||||
//assert(NumArgumentRegs >= 2);
|
||||
//threadContexts[0]->setIntReg(ArgumentReg[0], argc);
|
||||
//threadContexts[0]->setIntReg(ArgumentReg[1], argv_array_base);
|
||||
threadContexts[0]->setIntReg(StackPointerReg, stack_min);
|
||||
|
||||
uint32_t prog_entry = objFile->entryPoint();
|
||||
|
|
|
@ -99,12 +99,17 @@ namespace X86ISA
|
|||
const int ReturnAddressReg = 0;
|
||||
const int ReturnValueReg = INTREG_RAX;
|
||||
const int FramePointerReg = INTREG_RBP;
|
||||
const int ArgumentReg0 = INTREG_RDI;
|
||||
const int ArgumentReg1 = INTREG_RSI;
|
||||
const int ArgumentReg2 = INTREG_RDX;
|
||||
const int ArgumentReg3 = INTREG_RCX;
|
||||
const int ArgumentReg4 = INTREG_R8W;
|
||||
const int ArgumentReg5 = INTREG_R9W;
|
||||
const int ArgumentReg[] = {
|
||||
INTREG_RDI,
|
||||
INTREG_RSI,
|
||||
INTREG_RDX,
|
||||
//This argument register is r10 for syscalls and rcx for C.
|
||||
INTREG_R10W,
|
||||
//INTREG_RCX,
|
||||
INTREG_R8W,
|
||||
INTREG_R9W
|
||||
};
|
||||
const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int);
|
||||
|
||||
// Some OS syscalls use a second register (rdx) to return a second
|
||||
// value
|
||||
|
|
|
@ -338,8 +338,9 @@ X86LiveProcess::argsInit(int intSize, int pageSize)
|
|||
initVirtMem->writeBlob(argc_base, (uint8_t*)&guestArgc, intSize);
|
||||
|
||||
//Set up the thread context to start running the process
|
||||
threadContexts[0]->setIntReg(ArgumentReg0, argc);
|
||||
threadContexts[0]->setIntReg(ArgumentReg1, argv_array_base);
|
||||
assert(NumArgumentRegs >= 2);
|
||||
threadContexts[0]->setIntReg(ArgumentReg[0], argc);
|
||||
threadContexts[0]->setIntReg(ArgumentReg[1], argv_array_base);
|
||||
threadContexts[0]->setIntReg(StackPointerReg, stack_min);
|
||||
|
||||
Addr prog_entry = objFile->entryPoint();
|
||||
|
|
|
@ -293,14 +293,16 @@ template <class Impl>
|
|||
TheISA::IntReg
|
||||
AlphaO3CPU<Impl>::getSyscallArg(int i, int tid)
|
||||
{
|
||||
return this->readArchIntReg(AlphaISA::ArgumentReg0 + i, tid);
|
||||
assert(i < TheISA::NumArgumentRegs);
|
||||
return this->readArchIntReg(AlphaISA::ArgumentReg[i], tid);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
AlphaO3CPU<Impl>::setSyscallArg(int i, TheISA::IntReg val, int tid)
|
||||
{
|
||||
this->setArchIntReg(AlphaISA::ArgumentReg0 + i, val, tid);
|
||||
assert(i < TheISA::NumArgumentRegs);
|
||||
this->setArchIntReg(AlphaISA::ArgumentReg[i], val, tid);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
|
|
|
@ -196,14 +196,16 @@ template <class Impl>
|
|||
TheISA::IntReg
|
||||
MipsO3CPU<Impl>::getSyscallArg(int i, int tid)
|
||||
{
|
||||
return this->readArchIntReg(MipsISA::ArgumentReg0 + i, tid);
|
||||
assert(i < TheISA::NumArgumentRegs);
|
||||
return this->readArchIntReg(MipsISA::ArgumentReg[i], tid);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
MipsO3CPU<Impl>::setSyscallArg(int i, IntReg val, int tid)
|
||||
{
|
||||
this->setArchIntReg(MipsISA::ArgumentReg0 + i, val, tid);
|
||||
assert(i < TheISA::NumArgumentRegs);
|
||||
this->setArchIntReg(MipsISA::ArgumentReg[i], val, tid);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
|
|
|
@ -270,8 +270,9 @@ template <class Impl>
|
|||
TheISA::IntReg
|
||||
SparcO3CPU<Impl>::getSyscallArg(int i, int tid)
|
||||
{
|
||||
assert(i < TheISA::NumArgumentRegs);
|
||||
TheISA::IntReg idx = TheISA::flattenIntIndex(this->tcBase(tid),
|
||||
SparcISA::ArgumentReg0 + i);
|
||||
SparcISA::ArgumentReg[i]);
|
||||
TheISA::IntReg val = this->readArchIntReg(idx, tid);
|
||||
if (bits(this->readMiscRegNoEffect(SparcISA::MISCREG_PSTATE, tid), 3, 3))
|
||||
val = bits(val, 31, 0);
|
||||
|
@ -282,8 +283,9 @@ template <class Impl>
|
|||
void
|
||||
SparcO3CPU<Impl>::setSyscallArg(int i, TheISA::IntReg val, int tid)
|
||||
{
|
||||
assert(i < TheISA::NumArgumentRegs);
|
||||
TheISA::IntReg idx = TheISA::flattenIntIndex(this->tcBase(tid),
|
||||
SparcISA::ArgumentReg0 + i);
|
||||
SparcISA::ArgumentReg[i]);
|
||||
this->setArchIntReg(idx, val, tid);
|
||||
}
|
||||
|
||||
|
|
|
@ -253,11 +253,17 @@ class OzoneCPU : public BaseCPU
|
|||
|
||||
#if !FULL_SYSTEM
|
||||
TheISA::IntReg getSyscallArg(int i)
|
||||
{ return thread->renameTable[TheISA::ArgumentReg0 + i]->readIntResult(); }
|
||||
{
|
||||
assert(i < TheISA::NumArgumentRegs);
|
||||
return thread->renameTable[TheISA::ArgumentReg[i]]->readIntResult();
|
||||
}
|
||||
|
||||
// used to shift args for indirect syscall
|
||||
void setSyscallArg(int i, TheISA::IntReg val)
|
||||
{ thread->renameTable[TheISA::ArgumentReg0 + i]->setIntResult(i); }
|
||||
{
|
||||
assert(i < TheISA::NumArgumentRegs);
|
||||
thread->renameTable[TheISA::ArgumentReg[i]]->setIntResult(i);
|
||||
}
|
||||
|
||||
void setSyscallReturn(SyscallReturn return_value)
|
||||
{ cpu->setSyscallReturn(return_value, thread->readTid()); }
|
||||
|
|
|
@ -377,15 +377,17 @@ class SimpleThread : public ThreadState
|
|||
#if !FULL_SYSTEM
|
||||
TheISA::IntReg getSyscallArg(int i)
|
||||
{
|
||||
assert(i < TheISA::NumArgumentRegs);
|
||||
return regs.readIntReg(TheISA::flattenIntIndex(getTC(),
|
||||
TheISA::ArgumentReg0 + i));
|
||||
TheISA::ArgumentReg[i]));
|
||||
}
|
||||
|
||||
// used to shift args for indirect syscall
|
||||
void setSyscallArg(int i, TheISA::IntReg val)
|
||||
{
|
||||
assert(i < TheISA::NumArgumentRegs);
|
||||
regs.setIntReg(TheISA::flattenIntIndex(getTC(),
|
||||
TheISA::ArgumentReg0 + i), val);
|
||||
TheISA::ArgumentReg[i]), val);
|
||||
}
|
||||
|
||||
void setSyscallReturn(SyscallReturn return_value)
|
||||
|
|
|
@ -690,7 +690,7 @@ class Tru64 : public OperatingSystem
|
|||
|
||||
tc->clearArchRegs();
|
||||
|
||||
tc->setIntReg(TheISA::ArgumentReg0, gtoh(attrp->registers.a0));
|
||||
tc->setIntReg(TheISA::ArgumentReg[0], gtoh(attrp->registers.a0));
|
||||
tc->setIntReg(27/*t12*/, gtoh(attrp->registers.pc));
|
||||
tc->setIntReg(TheISA::StackPointerReg, gtoh(attrp->registers.sp));
|
||||
tc->setMiscRegNoEffect(AlphaISA::MISCREG_UNIQ, uniq_val);
|
||||
|
|
|
@ -51,7 +51,7 @@ BadAddrEvent::process(ThreadContext *tc)
|
|||
// annotation for vmunix::badaddr in:
|
||||
// simos/simulation/apps/tcl/osf/tlaser.tcl
|
||||
|
||||
uint64_t a0 = tc->readIntReg(ArgumentReg0);
|
||||
uint64_t a0 = tc->readIntReg(ArgumentReg[0]);
|
||||
|
||||
AddrRangeList resp;
|
||||
bool snoop;
|
||||
|
|
|
@ -405,8 +405,9 @@ LiveProcess::argsInit(int intSize, int pageSize)
|
|||
copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem);
|
||||
copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
|
||||
|
||||
threadContexts[0]->setIntReg(ArgumentReg0, argc);
|
||||
threadContexts[0]->setIntReg(ArgumentReg1, argv_array_base);
|
||||
assert(NumArgumentRegs >= 2);
|
||||
threadContexts[0]->setIntReg(ArgumentReg[0], argc);
|
||||
threadContexts[0]->setIntReg(ArgumentReg[1], argv_array_base);
|
||||
threadContexts[0]->setIntReg(StackPointerReg, stack_min);
|
||||
|
||||
Addr prog_entry = objFile->entryPoint();
|
||||
|
|
Loading…
Reference in a new issue