diff --git a/lib/ExecutionEngine/Interpreter/Execution.cpp b/lib/ExecutionEngine/Interpreter/Execution.cpp index 98b352c439f..524237b2dda 100644 --- a/lib/ExecutionEngine/Interpreter/Execution.cpp +++ b/lib/ExecutionEngine/Interpreter/Execution.cpp @@ -764,34 +764,54 @@ static void executeFreeInst(FreeInst *I, ExecutionContext &SF) { // function returns the offset that arguments ArgOff+1 -> NumArgs specify for // the pointer type specified by argument Arg. // -static PointerTy getElementOffset(Instruction *I, unsigned ArgOff) { - assert(isa(I->getOperand(ArgOff)->getType()) && +static PointerTy getElementOffset(MemAccessInst *I, ExecutionContext &SF) { + assert(isa(I->getPointerOperand()->getType()) && "Cannot getElementOffset of a nonpointer type!"); PointerTy Total = 0; const Type *Ty = - cast(I->getOperand(ArgOff++)->getType())->getValueType(); + cast(I->getPointerOperand()->getType())->getValueType(); + unsigned ArgOff = I->getFirstIndexOperandNumber(); while (ArgOff < I->getNumOperands()) { - const StructType *STy = cast(Ty); - const StructLayout *SLO = TD.getStructLayout(STy); - - // Indicies must be ubyte constants... - const ConstPoolUInt *CPU = cast(I->getOperand(ArgOff++)); - assert(CPU->getType() == Type::UByteTy); - unsigned Index = CPU->getValue(); - + if (const StructType *STy = dyn_cast(Ty)) { + const StructLayout *SLO = TD.getStructLayout(STy); + + // Indicies must be ubyte constants... + const ConstPoolUInt *CPU = cast(I->getOperand(ArgOff++)); + assert(CPU->getType() == Type::UByteTy); + unsigned Index = CPU->getValue(); + #ifdef PROFILE_STRUCTURE_FIELDS - if (ProfileStructureFields) { - // Do accounting for this field... - vector &OfC = FieldAccessCounts[STy]; - if (OfC.size() == 0) OfC.resize(STy->getElementTypes().size()); - OfC[Index]++; - } + if (ProfileStructureFields) { + // Do accounting for this field... + vector &OfC = FieldAccessCounts[STy]; + if (OfC.size() == 0) OfC.resize(STy->getElementTypes().size()); + OfC[Index]++; + } #endif + + Total += SLO->MemberOffsets[Index]; + Ty = STy->getElementTypes()[Index]; + } else { + const ArrayType *AT = cast(Ty); - Total += SLO->MemberOffsets[Index]; - Ty = STy->getElementTypes()[Index]; + // Get the index number for the array... which must be uint type... + assert(I->getOperand(ArgOff)->getType() == Type::UIntTy); + unsigned Idx = getOperandValue(I->getOperand(ArgOff++), SF).UIntVal; + if (AT->isSized() && Idx >= (unsigned)AT->getNumElements()) { + cerr << "Out of range memory access to element #" << Idx + << " of a " << AT->getNumElements() << " element array." + << " Subscript #" << (ArgOff-I->getFirstIndexOperandNumber()) + << "\n"; + // Get outta here!!! + siglongjmp(SignalRecoverBuffer, -1); + } + + Ty = AT->getElementType(); + unsigned Size = TD.getTypeSize(Ty); + Total += Size*Idx; + } } return Total; @@ -802,14 +822,14 @@ static void executeGEPInst(GetElementPtrInst *I, ExecutionContext &SF) { PointerTy SrcPtr = SRC.PointerVal; GenericValue Result; - Result.PointerVal = SrcPtr + getElementOffset(I, 0); + Result.PointerVal = SrcPtr + getElementOffset(I, SF); SetValue(I, Result, SF); } static void executeLoadInst(LoadInst *I, ExecutionContext &SF) { GenericValue SRC = getOperandValue(I->getPointerOperand(), SF); PointerTy SrcPtr = SRC.PointerVal; - PointerTy Offset = getElementOffset(I, 0); // Handle any structure indices + PointerTy Offset = getElementOffset(I, SF); // Handle any structure indices SrcPtr += Offset; GenericValue *Ptr = (GenericValue*)SrcPtr; @@ -838,7 +858,7 @@ static void executeLoadInst(LoadInst *I, ExecutionContext &SF) { static void executeStoreInst(StoreInst *I, ExecutionContext &SF) { GenericValue SRC = getOperandValue(I->getPointerOperand(), SF); PointerTy SrcPtr = SRC.PointerVal; - SrcPtr += getElementOffset(I, 1); // Handle any structure indices + SrcPtr += getElementOffset(I, SF); // Handle any structure indices GenericValue *Ptr = (GenericValue *)SrcPtr; GenericValue Val = getOperandValue(I->getOperand(0), SF); @@ -1117,10 +1137,10 @@ bool Interpreter::executeInstruction() { // if (int SigNo = sigsetjmp(SignalRecoverBuffer, 1)) { --SF.CurInst; // Back up to erroring instruction - if (SigNo != SIGINT) { + if (SigNo != SIGINT && SigNo != -1) { cout << "EXCEPTION OCCURRED [" << _sys_siglistp[SigNo] << "]:\n"; printStackTrace(); - } else { + } else if (SigNo == SIGINT) { cout << "CTRL-C Detected, execution halted.\n"; } InInstruction = false; diff --git a/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp b/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp index 00549a41be0..b42fb50ecdd 100644 --- a/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp +++ b/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp @@ -213,6 +213,14 @@ GenericValue lle_X_free(MethodType *M, const vector &Args) { return GenericValue(); } +// int atoi(char *) +GenericValue lle_X_atoi(MethodType *M, const vector &Args) { + assert(Args.size() == 1); + GenericValue GV; + GV.IntVal = atoi((char*)Args[0].PointerVal); + return GV; +} + // double pow(double, double) GenericValue lle_X_pow(MethodType *M, const vector &Args) { assert(Args.size() == 2); @@ -237,6 +245,14 @@ GenericValue lle_X_log(MethodType *M, const vector &Args) { return GV; } +// double floor(double) +GenericValue lle_X_floor(MethodType *M, const vector &Args) { + assert(Args.size() == 1); + GenericValue GV; + GV.DoubleVal = floor(Args[0].DoubleVal); + return GV; +} + // double drand48() GenericValue lle_X_drand48(MethodType *M, const vector &Args) { assert(Args.size() == 0); @@ -260,6 +276,12 @@ GenericValue lle_X_srand48(MethodType *M, const vector &Args) { return GenericValue(); } +// void srand(uint) +GenericValue lle_X_srand(MethodType *M, const vector &Args) { + assert(Args.size() == 1); + srand(Args[0].UIntVal); + return GenericValue(); +} // int printf(sbyte *, ...) - a very rough implementation to make output useful. GenericValue lle_X_printf(MethodType *M, const vector &Args) { @@ -352,8 +374,11 @@ void Interpreter::initializeExternalMethods() { FuncNames["lle_X_exit"] = lle_X_exit; FuncNames["lle_X_malloc"] = lle_X_malloc; FuncNames["lle_X_free"] = lle_X_free; + FuncNames["lle_X_atoi"] = lle_X_atoi; FuncNames["lle_X_pow"] = lle_X_pow; FuncNames["lle_X_log"] = lle_X_log; + FuncNames["lle_X_floor"] = lle_X_floor; + FuncNames["lle_X_srand"] = lle_X_srand; FuncNames["lle_X_drand48"] = lle_X_drand48; FuncNames["lle_X_srand48"] = lle_X_srand48; FuncNames["lle_X_lrand48"] = lle_X_lrand48;