const void tg00_0(arm_state *arm, UINT32 pc, UINT32 op) /* Shift left */ { UINT32 rs, rd, rrs; INT32 offs; SET_CPSR(GET_CPSR & ~(N_MASK | Z_MASK)); rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT; rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT; rrs = GET_REGISTER(arm, rs); offs = (op & THUMB_SHIFT_AMT) >> THUMB_SHIFT_AMT_SHIFT; if (offs != 0) { SET_REGISTER(arm, rd, rrs << offs); if (rrs & (1 << (31 - (offs - 1)))) { SET_CPSR(GET_CPSR | C_MASK); } else { SET_CPSR(GET_CPSR & ~C_MASK); } } else { SET_REGISTER(arm, rd, rrs); } SET_CPSR(GET_CPSR & ~(Z_MASK | N_MASK)); SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(arm, rd))); R15 += 2; }
GOTO_TARGET_END GOTO_TARGET(invokeInterface, bool methodCallRange) { Object* thisPtr; ClassObject* thisClass; EXPORT_PC(); vsrc1 = INST_AA(inst); /* AA (count) or BA (count + arg 5) */ ref = FETCH(1); /* method ref */ vdst = FETCH(2); /* 4 regs -or- first reg */ /* * The object against which we are executing a method is always * in the first argument. */ if (methodCallRange) { assert(vsrc1 > 0); ILOGV("|invoke-interface-range args=%d @0x%04x {regs=v%d-v%d}", vsrc1, ref, vdst, vdst+vsrc1-1); thisPtr = (Object*) GET_REGISTER(vdst); } else { assert((vsrc1>>4) > 0); ILOGV("|invoke-interface args=%d @0x%04x {regs=0x%04x %x}", vsrc1 >> 4, ref, vdst, vsrc1 & 0x0f); thisPtr = (Object*) GET_REGISTER(vdst & 0x0f); } if (!checkForNull(thisPtr)) GOTO_exceptionThrown(); thisClass = thisPtr->clazz; /* * Given a class and a method index, find the Method* with the * actual code we want to execute. */ methodToCall = dvmFindInterfaceMethodInCache(thisClass, ref, curMethod, methodClassDex); #if defined(WITH_JIT) && defined(MTERP_STUB) self->callsiteClass = thisClass; self->methodToCall = methodToCall; #endif if (methodToCall == NULL) { assert(dvmCheckException(self)); GOTO_exceptionThrown(); } GOTO_invokeMethod(methodCallRange, methodToCall, vsrc1, vdst); }
GOTO_TARGET_END GOTO_TARGET(invokeDirect, bool methodCallRange) { u2 thisReg; vsrc1 = INST_AA(inst); /* AA (count) or BA (count + arg 5) */ ref = FETCH(1); /* method ref */ vdst = FETCH(2); /* 4 regs -or- first reg */ EXPORT_PC(); if (methodCallRange) { ILOGV("|invoke-direct-range args=%d @0x%04x {regs=v%d-v%d}", vsrc1, ref, vdst, vdst+vsrc1-1); thisReg = vdst; } else { ILOGV("|invoke-direct args=%d @0x%04x {regs=0x%04x %x}", vsrc1 >> 4, ref, vdst, vsrc1 & 0x0f); thisReg = vdst & 0x0f; } if (!checkForNull((Object*) GET_REGISTER(thisReg))) GOTO_exceptionThrown(); methodToCall = dvmDexGetResolvedMethod(methodClassDex, ref); if (methodToCall == NULL) { methodToCall = dvmResolveMethod(curMethod->clazz, ref, METHOD_DIRECT); if (methodToCall == NULL) { ILOGV("+ unknown direct method\n"); // should be impossible GOTO_exceptionThrown(); } } GOTO_invokeMethod(methodCallRange, methodToCall, vsrc1, vdst); }
const void tg00_1(arm_state *arm, UINT32 pc, UINT32 op) /* Shift right */ { UINT32 rs, rd, rrs; INT32 offs; rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT; rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT; rrs = GET_REGISTER(arm, rs); offs = (op & THUMB_SHIFT_AMT) >> THUMB_SHIFT_AMT_SHIFT; if (offs != 0) { SET_REGISTER(arm, rd, rrs >> offs); if (rrs & (1 << (offs - 1))) { SET_CPSR(GET_CPSR | C_MASK); } else { SET_CPSR(GET_CPSR & ~C_MASK); } }
LSL 0 = Result = RM, Carry = Old Contents of CPSR C Bit LSL(0,31) = Result shifted, least significant bit is in carry out LSL 32 = Result of 0, Carry = Bit 0 of RM LSL >32 = Result of 0, Carry out 0 LSR 0 = LSR 32 (see below) LSR 32 = Result of 0, Carry = Bit 31 of RM LSR >32 = Result of 0, Carry out 0 ASR >=32 = ENTIRE Result = bit 31 of RM ROR 32 = Result = RM, Carry = Bit 31 of RM ROR >32 = Same result as ROR n-32 until amount in range of 1-32 then follow rules */ UINT32 decodeShift(arm_state *cpustate, UINT32 insn, UINT32 *pCarry) { UINT32 k = (insn & INSN_OP2_SHIFT) >> INSN_OP2_SHIFT_SHIFT; // Bits 11-7 UINT32 rm = GET_REGISTER(cpustate, insn & INSN_OP2_RM); UINT32 t = (insn & INSN_OP2_SHIFT_TYPE) >> INSN_OP2_SHIFT_TYPE_SHIFT; if ((insn & INSN_OP2_RM) == 0xf) { // "If a register is used to specify the shift amount the PC will be 12 bytes ahead." (instead of 8) rm += t & 1 ? 12 : 8; } /* All shift types ending in 1 are Rk, not #k */ if (t & 1) { // LOG(("%08x: RegShift %02x %02x\n", R15, k >> 1, GET_REGISTER(cpustate, k >> 1))); #if ARM7_DEBUG_CORE if ((insn & 0x80) == 0x80) LOG(("%08x: RegShift ERROR (p36)\n", R15)); #endif
MOZ_ASAN_BLACKLIST void ThreadStackHelper::FillThreadContext(void* aContext) { #ifdef MOZ_THREADSTACKHELPER_NATIVE if (!mContextToFill) { return; } #if 0 // TODO: remove dependency on Breakpad structs. #if defined(XP_LINUX) const ucontext_t& context = *reinterpret_cast<ucontext_t*>(aContext); #if defined(MOZ_THREADSTACKHELPER_X86) mContextToFill->mContext.context_flags = MD_CONTEXT_X86_FULL; mContextToFill->mContext.edi = context.uc_mcontext.gregs[REG_EDI]; mContextToFill->mContext.esi = context.uc_mcontext.gregs[REG_ESI]; mContextToFill->mContext.ebx = context.uc_mcontext.gregs[REG_EBX]; mContextToFill->mContext.edx = context.uc_mcontext.gregs[REG_EDX]; mContextToFill->mContext.ecx = context.uc_mcontext.gregs[REG_ECX]; mContextToFill->mContext.eax = context.uc_mcontext.gregs[REG_EAX]; mContextToFill->mContext.ebp = context.uc_mcontext.gregs[REG_EBP]; mContextToFill->mContext.eip = context.uc_mcontext.gregs[REG_EIP]; mContextToFill->mContext.eflags = context.uc_mcontext.gregs[REG_EFL]; mContextToFill->mContext.esp = context.uc_mcontext.gregs[REG_ESP]; #elif defined(MOZ_THREADSTACKHELPER_X64) mContextToFill->mContext.context_flags = MD_CONTEXT_AMD64_FULL; mContextToFill->mContext.eflags = uint32_t(context.uc_mcontext.gregs[REG_EFL]); mContextToFill->mContext.rax = context.uc_mcontext.gregs[REG_RAX]; mContextToFill->mContext.rcx = context.uc_mcontext.gregs[REG_RCX]; mContextToFill->mContext.rdx = context.uc_mcontext.gregs[REG_RDX]; mContextToFill->mContext.rbx = context.uc_mcontext.gregs[REG_RBX]; mContextToFill->mContext.rsp = context.uc_mcontext.gregs[REG_RSP]; mContextToFill->mContext.rbp = context.uc_mcontext.gregs[REG_RBP]; mContextToFill->mContext.rsi = context.uc_mcontext.gregs[REG_RSI]; mContextToFill->mContext.rdi = context.uc_mcontext.gregs[REG_RDI]; memcpy(&mContextToFill->mContext.r8, &context.uc_mcontext.gregs[REG_R8], 8 * sizeof(int64_t)); mContextToFill->mContext.rip = context.uc_mcontext.gregs[REG_RIP]; #elif defined(MOZ_THREADSTACKHELPER_ARM) mContextToFill->mContext.context_flags = MD_CONTEXT_ARM_FULL; memcpy(&mContextToFill->mContext.iregs[0], &context.uc_mcontext.arm_r0, 17 * sizeof(int32_t)); #else #error "Unsupported architecture" #endif // architecture #elif defined(XP_WIN) // Breakpad context struct is based off of the Windows CONTEXT struct, // so we assume they are the same; do some sanity checks to make sure. static_assert(sizeof(ThreadContext::Context) == sizeof(::CONTEXT), "Context struct mismatch"); static_assert(offsetof(ThreadContext::Context, context_flags) == offsetof(::CONTEXT, ContextFlags), "Context struct mismatch"); mContextToFill->mContext.context_flags = CONTEXT_FULL; NS_ENSURE_TRUE_VOID(::GetThreadContext(mThreadID, reinterpret_cast<::CONTEXT*>(&mContextToFill->mContext))); #elif defined(XP_MACOSX) #if defined(MOZ_THREADSTACKHELPER_X86) const thread_state_flavor_t flavor = x86_THREAD_STATE32; x86_thread_state32_t state = {}; mach_msg_type_number_t count = x86_THREAD_STATE32_COUNT; #elif defined(MOZ_THREADSTACKHELPER_X64) const thread_state_flavor_t flavor = x86_THREAD_STATE64; x86_thread_state64_t state = {}; mach_msg_type_number_t count = x86_THREAD_STATE64_COUNT; #elif defined(MOZ_THREADSTACKHELPER_ARM) const thread_state_flavor_t flavor = ARM_THREAD_STATE; arm_thread_state_t state = {}; mach_msg_type_number_t count = ARM_THREAD_STATE_COUNT; #endif NS_ENSURE_TRUE_VOID(KERN_SUCCESS == ::thread_get_state( mThreadID, flavor, reinterpret_cast<thread_state_t>(&state), &count)); #if __DARWIN_UNIX03 #define GET_REGISTER(s, r) ((s).__##r) #else #define GET_REGISTER(s, r) ((s).r) #endif #if defined(MOZ_THREADSTACKHELPER_X86) mContextToFill->mContext.context_flags = MD_CONTEXT_X86_FULL; mContextToFill->mContext.edi = GET_REGISTER(state, edi); mContextToFill->mContext.esi = GET_REGISTER(state, esi); mContextToFill->mContext.ebx = GET_REGISTER(state, ebx); mContextToFill->mContext.edx = GET_REGISTER(state, edx); mContextToFill->mContext.ecx = GET_REGISTER(state, ecx); mContextToFill->mContext.eax = GET_REGISTER(state, eax); mContextToFill->mContext.ebp = GET_REGISTER(state, ebp); mContextToFill->mContext.eip = GET_REGISTER(state, eip); mContextToFill->mContext.eflags = GET_REGISTER(state, eflags); mContextToFill->mContext.esp = GET_REGISTER(state, esp); #elif defined(MOZ_THREADSTACKHELPER_X64) mContextToFill->mContext.context_flags = MD_CONTEXT_AMD64_FULL; mContextToFill->mContext.eflags = uint32_t(GET_REGISTER(state, rflags)); mContextToFill->mContext.rax = GET_REGISTER(state, rax); mContextToFill->mContext.rcx = GET_REGISTER(state, rcx); mContextToFill->mContext.rdx = GET_REGISTER(state, rdx); mContextToFill->mContext.rbx = GET_REGISTER(state, rbx); mContextToFill->mContext.rsp = GET_REGISTER(state, rsp); mContextToFill->mContext.rbp = GET_REGISTER(state, rbp); mContextToFill->mContext.rsi = GET_REGISTER(state, rsi); mContextToFill->mContext.rdi = GET_REGISTER(state, rdi); memcpy(&mContextToFill->mContext.r8, &GET_REGISTER(state, r8), 8 * sizeof(int64_t)); mContextToFill->mContext.rip = GET_REGISTER(state, rip); #elif defined(MOZ_THREADSTACKHELPER_ARM) mContextToFill->mContext.context_flags = MD_CONTEXT_ARM_FULL; memcpy(mContextToFill->mContext.iregs, GET_REGISTER(state, r), 17 * sizeof(int32_t)); #else #error "Unsupported architecture" #endif // architecture #undef GET_REGISTER #else #error "Unsupported platform" #endif // platform intptr_t sp = 0; #if defined(MOZ_THREADSTACKHELPER_X86) sp = mContextToFill->mContext.esp; #elif defined(MOZ_THREADSTACKHELPER_X64) sp = mContextToFill->mContext.rsp; #elif defined(MOZ_THREADSTACKHELPER_ARM) sp = mContextToFill->mContext.iregs[13]; #else #error "Unsupported architecture" #endif // architecture NS_ENSURE_TRUE_VOID(sp); NS_ENSURE_TRUE_VOID(mThreadStackBase); size_t stackSize = std::min(intptr_t(ThreadContext::kMaxStackSize), std::abs(sp - mThreadStackBase)); if (mContextToFill->mStackEnd) { // Limit the start of stack to a certain location if specified. stackSize = std::min(intptr_t(stackSize), std::abs(sp - intptr_t(mContextToFill->mStackEnd))); } #ifndef MOZ_THREADSTACKHELPER_STACK_GROWS_DOWN // If if the stack grows upwards, and we need to recalculate our // stack copy's base address. Subtract sizeof(void*) so that the // location pointed to by sp is included. sp -= stackSize - sizeof(void*); #endif #ifndef MOZ_ASAN memcpy(mContextToFill->mStack.get(), reinterpret_cast<void*>(sp), stackSize); // Valgrind doesn't care about the access outside the stack frame, but // the presence of uninitialised values on the stack does cause it to // later report a lot of false errors when Breakpad comes to unwind it. // So mark the extracted data as defined. MOZ_MAKE_MEM_DEFINED(mContextToFill->mStack.get(), stackSize); #else // ASan will flag memcpy for access outside of stack frames, // so roll our own memcpy here. intptr_t* dst = reinterpret_cast<intptr_t*>(&mContextToFill->mStack[0]); const intptr_t* src = reinterpret_cast<intptr_t*>(sp); for (intptr_t len = stackSize; len > 0; len -= sizeof(*src)) { *(dst++) = *(src++); } #endif mContextToFill->mStackBase = uintptr_t(sp); mContextToFill->mStackSize = stackSize; mContextToFill->mValid = true; #endif #endif // MOZ_THREADSTACKHELPER_NATIVE }
HANDLE_OPCODE($opcode /*vAA*/) vsrc1 = INST_AA(inst); ILOGV("|return%s v%d", (INST_INST(inst) == OP_RETURN) ? "" : "-object", vsrc1); retval.i = GET_REGISTER(vsrc1); GOTO(returnFromMethod); OP_END
GOTO_TARGET_END GOTO_TARGET(invokeSuper, bool methodCallRange) { Method* baseMethod; u2 thisReg; EXPORT_PC(); vsrc1 = INST_AA(inst); /* AA (count) or BA (count + arg 5) */ ref = FETCH(1); /* method ref */ vdst = FETCH(2); /* 4 regs -or- first reg */ if (methodCallRange) { ILOGV("|invoke-super-range args=%d @0x%04x {regs=v%d-v%d}", vsrc1, ref, vdst, vdst+vsrc1-1); thisReg = vdst; } else { ILOGV("|invoke-super args=%d @0x%04x {regs=0x%04x %x}", vsrc1 >> 4, ref, vdst, vsrc1 & 0x0f); thisReg = vdst & 0x0f; } /* impossible in well-formed code, but we must check nevertheless */ if (!checkForNull((Object*) GET_REGISTER(thisReg))) GOTO_exceptionThrown(); /* * Resolve the method. This is the correct method for the static * type of the object. We also verify access permissions here. * The first arg to dvmResolveMethod() is just the referring class * (used for class loaders and such), so we don't want to pass * the superclass into the resolution call. */ baseMethod = dvmDexGetResolvedMethod(methodClassDex, ref); if (baseMethod == NULL) { baseMethod = dvmResolveMethod(curMethod->clazz, ref,METHOD_VIRTUAL); if (baseMethod == NULL) { ILOGV("+ unknown method or access denied\n"); GOTO_exceptionThrown(); } } /* * Combine the object we found with the vtable offset in the * method's class. * * We're using the current method's class' superclass, not the * superclass of "this". This is because we might be executing * in a method inherited from a superclass, and we want to run * in that class' superclass. */ if (baseMethod->methodIndex >= curMethod->clazz->super->vtableCount) { /* * Method does not exist in the superclass. Could happen if * superclass gets updated. */ dvmThrowException("Ljava/lang/NoSuchMethodError;", baseMethod->name); GOTO_exceptionThrown(); } methodToCall = curMethod->clazz->super->vtable[baseMethod->methodIndex]; #if 0 if (dvmIsAbstractMethod(methodToCall)) { dvmThrowException("Ljava/lang/AbstractMethodError;", "abstract method not implemented"); GOTO_exceptionThrown(); } #else assert(!dvmIsAbstractMethod(methodToCall) || methodToCall->nativeFunc != NULL); #endif LOGVV("+++ base=%s.%s super-virtual=%s.%s\n", baseMethod->clazz->descriptor, baseMethod->name, methodToCall->clazz->descriptor, methodToCall->name); assert(methodToCall != NULL); GOTO_invokeMethod(methodCallRange, methodToCall, vsrc1, vdst); }
* * License : This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License in $CORINETROOT/licenses for more details. * **********************************************************************************************/ #include <Model/Concr/ConcreteIntegrationSites.h> #include <Util/Factory.h> namespace CORINET { GET_REGISTER(CIntegrationSite) REGISTER_CLASS_1(CIntegrationSite,CIntegrationSiteAddInt1,addInt1) REGISTER_CLASS_1(CIntegrationSite,CIntegrationSiteMaxInt1,maxInt1) REGISTER_CLASS_1(CIntegrationSite,CIntegrationSiteCompInt1,compInt1) REGISTER_CLASS_1(CIntegrationSite,CIntegrationSiteDisj1,disj1) REGISTER_CLASS_1(CIntegrationSite,CIntegrationSiteDisj2,disj2) REGISTER_CLASS_1(CIntegrationSite,CIntegrationSiteConj1,conj1) REGISTER_CLASS_1(CIntegrationSite,CIntegrationSiteConj2,conj2) REGISTER_CLASS_1(CIntegrationSite,CIntegrationSiteConj3,conj3) } //end namespace CORINETFactory
* Purpose : This file registers the available concrete types of external data sources with * the factory manager for the abstract CDataSource type. The name used here should * be the name used in XML CORINET language definition. * * Notes : * * Info : http://www.corinet.org * * Copyright : 2006, King's College London * * License : This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License in $CORINETROOT/licenses for more details. * **********************************************************************************************/ #include <Util/Factory.h> #include <Task/Concr/ConcreteDataSources.h> namespace CORINET { GET_REGISTER(CDataSource) } //end namespace CORINET
HANDLE_OPCODE($opcode /*vAA, vBBBB*/) vdst = INST_AA(inst); vsrc1 = FETCH(1); ILOGV("|move%s/from16 v%d,v%d %s(v%d=0x%08x)", (INST_INST(inst) == OP_MOVE_FROM16) ? "" : "-object", vdst, vsrc1, kSpacing, vdst, GET_REGISTER(vsrc1)); SET_REGISTER(vdst, GET_REGISTER(vsrc1)); /* ifdef WITH_TAINT_TRACKING */ SET_REGISTER_TAINT(vdst, GET_REGISTER_TAINT(vsrc1)); /* endif */ FINISH(2); OP_END
* * Notes : * * Info : http://www.corinet.org * * Copyright : 2006, King's College London * * License : This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License in $CORINETROOT/licenses for more details. * **********************************************************************************************/ #include <Engine/Concr/ConcreteExecutionElement.h> #include <Util/Factory.h> namespace CORINET { GET_REGISTER(CExecutionElement) REGISTER_CLASS_2(CExecutionElement,CExecutionSequenceV1,sequenceV1) //doesn't take parameters REGISTER_CLASS_1(CExecutionElement,CExecutionPartV1,partV1) //takes parameters } //end namespace CORINET
HANDLE_OPCODE($opcode /*vAAAA, vBBBB*/) vdst = FETCH(1); vsrc1 = FETCH(2); ILOGV("|move%s/16 v%d,v%d %s(v%d=0x%08x)", (INST_INST(inst) == OP_MOVE_16) ? "" : "-object", vdst, vsrc1, kSpacing, vdst, GET_REGISTER(vsrc1)); SET_REGISTER(vdst, GET_REGISTER(vsrc1)); #if defined(LOCCS_DIAOS) #if INST_INST(inst) != OP_MOVE_16 //ALOG(LOG_VERBOSE,"YWB","need to verify object"); diaos_monitor_object(curMethod, (Object*)GET_REGISTER(vdst)); #endif #endif FINISH(3); OP_END
* * Copyright : 2006, King's College London * * License : This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License in $CORINETROOT/licenses for more details. * **********************************************************************************************/ #include <Event/Concr/ConcreteConditions.h> #include <Util/Factory.h> namespace CORINET { GET_REGISTER(FCondition) REGISTER_CLASS_2(FCondition,FCMultiple,multiple) REGISTER_CLASS_2(FCondition,FCEquals,equals) REGISTER_CLASS_2(FCondition,FCGT,gt) REGISTER_CLASS_2(FCondition,FCGTE,gteq) REGISTER_CLASS_2(FCondition,FCLT,lt) REGISTER_CLASS_2(FCondition,FCLTE,lteq) } //end namespace CORINET
HANDLE_OPCODE($opcode /*vAA*/) vdst = INST_AA(inst); ILOGV("|move-result%s v%d %s(v%d=0x%08x)", (INST_INST(inst) == OP_MOVE_RESULT) ? "" : "-object", vdst, kSpacing+4, vdst,retval.i); SET_REGISTER(vdst, retval.i); #if defined(LOCCS_DIAOS) #if INST_INST(inst) != OP_MOVE_RESULT //ALOG(LOG_VERBOSE,"YWB","need to verify object"); diaos_monitor_object(curMethod, (Object*)GET_REGISTER(vdst)); #endif #endif FINISH(1); OP_END
* * Info : http://www.corinet.org * * Copyright : 2006, King's College London * * License : This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License in $CORINETROOT/licenses for more details. * **********************************************************************************************/ #include <Common/Concr/ConcreteNoiseFunction.h> #include <Util/Factory.h> namespace CORINET { GET_REGISTER(FNoiseFunction) REGISTER_CLASS_1(FNoiseFunction,FNoiseFunctionAdditive,additive) REGISTER_CLASS_1(FNoiseFunction,FNoiseFunctionMultiplicative,multiplicative) REGISTER_CLASS_1(FNoiseFunction,FNoiseFunctionAdditiveClip,additiveClip) REGISTER_CLASS_1(FNoiseFunction,FNoiseFunctionMultiplicativeClip,multiplicativeClip) } //end namespace CORINET
GOTO_TARGET(filledNewArray, bool methodCallRange) { ClassObject* arrayClass; ArrayObject* newArray; u4* contents; char typeCh; int i; u4 arg5; EXPORT_PC(); ref = FETCH(1); /* class ref */ vdst = FETCH(2); /* first 4 regs -or- range base */ if (methodCallRange) { vsrc1 = INST_AA(inst); /* #of elements */ arg5 = -1; /* silence compiler warning */ ILOGV("|filled-new-array-range args=%d @0x%04x {regs=v%d-v%d}", vsrc1, ref, vdst, vdst+vsrc1-1); } else { arg5 = INST_A(inst); vsrc1 = INST_B(inst); /* #of elements */ ILOGV("|filled-new-array args=%d @0x%04x {regs=0x%04x %x}", vsrc1, ref, vdst, arg5); } /* * Resolve the array class. */ arrayClass = dvmDexGetResolvedClass(methodClassDex, ref); if (arrayClass == NULL) { arrayClass = dvmResolveClass(curMethod->clazz, ref, false); if (arrayClass == NULL) GOTO_exceptionThrown(); } /* if (!dvmIsArrayClass(arrayClass)) { dvmThrowException("Ljava/lang/RuntimeError;", "filled-new-array needs array class"); GOTO_exceptionThrown(); } */ /* verifier guarantees this is an array class */ assert(dvmIsArrayClass(arrayClass)); assert(dvmIsClassInitialized(arrayClass)); /* * Create an array of the specified type. */ LOGVV("+++ filled-new-array type is '%s'\n", arrayClass->descriptor); typeCh = arrayClass->descriptor[1]; if (typeCh == 'D' || typeCh == 'J') { /* category 2 primitives not allowed */ dvmThrowException("Ljava/lang/RuntimeError;", "bad filled array req"); GOTO_exceptionThrown(); } else if (typeCh != 'L' && typeCh != '[' && typeCh != 'I') { /* TODO: requires multiple "fill in" loops with different widths */ LOGE("non-int primitives not implemented\n"); dvmThrowException("Ljava/lang/InternalError;", "filled-new-array not implemented for anything but 'int'"); GOTO_exceptionThrown(); } newArray = dvmAllocArrayByClass(arrayClass, vsrc1, ALLOC_DONT_TRACK); if (newArray == NULL) GOTO_exceptionThrown(); /* * Fill in the elements. It's legal for vsrc1 to be zero. */ contents = (u4*) newArray->contents; if (methodCallRange) { for (i = 0; i < vsrc1; i++) contents[i] = GET_REGISTER(vdst+i); } else { assert(vsrc1 <= 5); if (vsrc1 == 5) { contents[4] = GET_REGISTER(arg5); vsrc1--; } for (i = 0; i < vsrc1; i++) { contents[i] = GET_REGISTER(vdst & 0x0f); vdst >>= 4; } } retval.l = newArray; }
LSL 0 = Result = RM, Carry = Old Contents of CPSR C Bit LSL(0,31) = Result shifted, least significant bit is in carry out LSL 32 = Result of 0, Carry = Bit 0 of RM LSL >32 = Result of 0, Carry out 0 LSR 0 = LSR 32 (see below) LSR 32 = Result of 0, Carry = Bit 31 of RM LSR >32 = Result of 0, Carry out 0 ASR >=32 = ENTIRE Result = bit 31 of RM ROR 32 = Result = RM, Carry = Bit 31 of RM ROR >32 = Same result as ROR n-32 until amount in range of 1-32 then follow rules */ UINT32 arm7_cpu_device::decodeShift(UINT32 insn, UINT32 *pCarry) { UINT32 k = (insn & INSN_OP2_SHIFT) >> INSN_OP2_SHIFT_SHIFT; // Bits 11-7 UINT32 rm = GET_REGISTER(insn & INSN_OP2_RM); UINT32 t = (insn & INSN_OP2_SHIFT_TYPE) >> INSN_OP2_SHIFT_TYPE_SHIFT; if ((insn & INSN_OP2_RM) == 0xf) { // "If a register is used to specify the shift amount the PC will be 12 bytes ahead." (instead of 8) rm += t & 1 ? 12 : 8; } /* All shift types ending in 1 are Rk, not #k */ if (t & 1) { // LOG(("%08x: RegShift %02x %02x\n", R15, k >> 1, GET_REGISTER(k >> 1))); #if ARM7_DEBUG_CORE if ((insn & 0x80) == 0x80) LOG(("%08x: RegShift ERROR (p36)\n", R15)); #endif
GOTO_TARGET_END GOTO_TARGET(invokeVirtual, bool methodCallRange) { Method* baseMethod; Object* thisPtr; EXPORT_PC(); vsrc1 = INST_AA(inst); /* AA (count) or BA (count + arg 5) */ ref = FETCH(1); /* method ref */ vdst = FETCH(2); /* 4 regs -or- first reg */ /* * The object against which we are executing a method is always * in the first argument. */ if (methodCallRange) { assert(vsrc1 > 0); ILOGV("|invoke-virtual-range args=%d @0x%04x {regs=v%d-v%d}", vsrc1, ref, vdst, vdst+vsrc1-1); thisPtr = (Object*) GET_REGISTER(vdst); } else { assert((vsrc1>>4) > 0); ILOGV("|invoke-virtual args=%d @0x%04x {regs=0x%04x %x}", vsrc1 >> 4, ref, vdst, vsrc1 & 0x0f); thisPtr = (Object*) GET_REGISTER(vdst & 0x0f); } if (!checkForNull(thisPtr)) GOTO_exceptionThrown(); /* * Resolve the method. This is the correct method for the static * type of the object. We also verify access permissions here. */ baseMethod = dvmDexGetResolvedMethod(methodClassDex, ref); if (baseMethod == NULL) { baseMethod = dvmResolveMethod(curMethod->clazz, ref,METHOD_VIRTUAL); if (baseMethod == NULL) { ILOGV("+ unknown method or access denied\n"); GOTO_exceptionThrown(); } } /* * Combine the object we found with the vtable offset in the * method. */ assert(baseMethod->methodIndex < thisPtr->clazz->vtableCount); methodToCall = thisPtr->clazz->vtable[baseMethod->methodIndex]; #if 0 if (dvmIsAbstractMethod(methodToCall)) { /* * This can happen if you create two classes, Base and Sub, where * Sub is a sub-class of Base. Declare a protected abstract * method foo() in Base, and invoke foo() from a method in Base. * Base is an "abstract base class" and is never instantiated * directly. Now, Override foo() in Sub, and use Sub. This * Works fine unless Sub stops providing an implementation of * the method. */ dvmThrowException("Ljava/lang/AbstractMethodError;", "abstract method not implemented"); GOTO_exceptionThrown(); } #else assert(!dvmIsAbstractMethod(methodToCall) || methodToCall->nativeFunc != NULL); #endif LOGVV("+++ base=%s.%s virtual[%d]=%s.%s\n", baseMethod->clazz->descriptor, baseMethod->name, (u4) baseMethod->methodIndex, methodToCall->clazz->descriptor, methodToCall->name); assert(methodToCall != NULL); #if 0 if (vsrc1 != methodToCall->insSize) { LOGW("WRONG METHOD: base=%s.%s virtual[%d]=%s.%s\n", baseMethod->clazz->descriptor, baseMethod->name, (u4) baseMethod->methodIndex, methodToCall->clazz->descriptor, methodToCall->name); //dvmDumpClass(baseMethod->clazz); //dvmDumpClass(methodToCall->clazz); dvmDumpAllClasses(0); } #endif GOTO_invokeMethod(methodCallRange, methodToCall, vsrc1, vdst); }