From d1e533a1e243b75b3257e2f96deb385a3b10e09b Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 26 Jul 2007 22:13:14 -0700 Subject: [PATCH] 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 --- src/arch/alpha/freebsd/system.cc | 5 +++-- src/arch/alpha/isa_traits.hh | 12 +++++------- src/arch/mips/isa_traits.hh | 10 +++++----- src/arch/sparc/isa_traits.hh | 12 +++++------- src/arch/sparc/process.cc | 10 ++++++---- src/arch/x86/isa_traits.hh | 17 +++++++++++------ src/arch/x86/process.cc | 5 +++-- src/cpu/o3/alpha/cpu_impl.hh | 6 ++++-- src/cpu/o3/mips/cpu_impl.hh | 6 ++++-- src/cpu/o3/sparc/cpu_impl.hh | 6 ++++-- src/cpu/ozone/cpu.hh | 10 ++++++++-- src/cpu/simple_thread.hh | 6 ++++-- src/kern/tru64/tru64.hh | 2 +- src/kern/tru64/tru64_events.cc | 2 +- src/sim/process.cc | 5 +++-- 15 files changed, 67 insertions(+), 47 deletions(-) diff --git a/src/arch/alpha/freebsd/system.cc b/src/arch/alpha/freebsd/system.cc index db0be29ab..f666de604 100644 --- a/src/arch/alpha/freebsd/system.cc +++ b/src/arch/alpha/freebsd/system.cc @@ -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); diff --git a/src/arch/alpha/isa_traits.hh b/src/arch/alpha/isa_traits.hh index a267ac034..7dc7e5151 100644 --- a/src/arch/alpha/isa_traits.hh +++ b/src/arch/alpha/isa_traits.hh @@ -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 diff --git a/src/arch/mips/isa_traits.hh b/src/arch/mips/isa_traits.hh index 5ab6957a3..5d4403553 100644 --- a/src/arch/mips/isa_traits.hh +++ b/src/arch/mips/isa_traits.hh @@ -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); diff --git a/src/arch/sparc/isa_traits.hh b/src/arch/sparc/isa_traits.hh index 8b3ec36a6..0edbdec4b 100644 --- a/src/arch/sparc/isa_traits.hh +++ b/src/arch/sparc/isa_traits.hh @@ -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; diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index 0776694ec..bc950301a 100644 --- a/src/arch/sparc/process.cc +++ b/src/arch/sparc/process.cc @@ -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(); diff --git a/src/arch/x86/isa_traits.hh b/src/arch/x86/isa_traits.hh index 4c02ee35e..63bcfead9 100644 --- a/src/arch/x86/isa_traits.hh +++ b/src/arch/x86/isa_traits.hh @@ -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 diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index 7deb54945..09962fdb6 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -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(); diff --git a/src/cpu/o3/alpha/cpu_impl.hh b/src/cpu/o3/alpha/cpu_impl.hh index 1754300d2..7f8f0547b 100644 --- a/src/cpu/o3/alpha/cpu_impl.hh +++ b/src/cpu/o3/alpha/cpu_impl.hh @@ -293,14 +293,16 @@ template TheISA::IntReg AlphaO3CPU::getSyscallArg(int i, int tid) { - return this->readArchIntReg(AlphaISA::ArgumentReg0 + i, tid); + assert(i < TheISA::NumArgumentRegs); + return this->readArchIntReg(AlphaISA::ArgumentReg[i], tid); } template void AlphaO3CPU::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 diff --git a/src/cpu/o3/mips/cpu_impl.hh b/src/cpu/o3/mips/cpu_impl.hh index d1135f048..09d73b4a2 100644 --- a/src/cpu/o3/mips/cpu_impl.hh +++ b/src/cpu/o3/mips/cpu_impl.hh @@ -196,14 +196,16 @@ template TheISA::IntReg MipsO3CPU::getSyscallArg(int i, int tid) { - return this->readArchIntReg(MipsISA::ArgumentReg0 + i, tid); + assert(i < TheISA::NumArgumentRegs); + return this->readArchIntReg(MipsISA::ArgumentReg[i], tid); } template void MipsO3CPU::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 diff --git a/src/cpu/o3/sparc/cpu_impl.hh b/src/cpu/o3/sparc/cpu_impl.hh index 2e398577e..068057fc0 100644 --- a/src/cpu/o3/sparc/cpu_impl.hh +++ b/src/cpu/o3/sparc/cpu_impl.hh @@ -270,8 +270,9 @@ template TheISA::IntReg SparcO3CPU::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 void SparcO3CPU::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); } diff --git a/src/cpu/ozone/cpu.hh b/src/cpu/ozone/cpu.hh index 2432df55e..92b00af26 100644 --- a/src/cpu/ozone/cpu.hh +++ b/src/cpu/ozone/cpu.hh @@ -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()); } diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index c20fe3d90..6c6d5f842 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -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) diff --git a/src/kern/tru64/tru64.hh b/src/kern/tru64/tru64.hh index a7703be7c..70fb4d688 100644 --- a/src/kern/tru64/tru64.hh +++ b/src/kern/tru64/tru64.hh @@ -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); diff --git a/src/kern/tru64/tru64_events.cc b/src/kern/tru64/tru64_events.cc index 4db5df067..c84b25dab 100644 --- a/src/kern/tru64/tru64_events.cc +++ b/src/kern/tru64/tru64_events.cc @@ -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; diff --git a/src/sim/process.cc b/src/sim/process.cc index c556ade12..7343039df 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -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();