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