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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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