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:
Gabe Black 2007-07-26 22:13:14 -07:00
parent 876849724d
commit d1e533a1e2
15 changed files with 67 additions and 47 deletions

View file

@ -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);

View file

@ -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

View file

@ -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);

View file

@ -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;

View file

@ -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();

View file

@ -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

View file

@ -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();

View file

@ -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>

View file

@ -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>

View file

@ -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);
}

View file

@ -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()); }

View file

@ -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)

View file

@ -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);

View file

@ -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;

View file

@ -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();