1 //===-- ExecutionEngine.cpp - Common Implementation shared by EE's --------===// 2 // 3 // This file defines the common interface used by the various execution engine 4 // subclasses. 5 // 6 //===----------------------------------------------------------------------===// 7 8 #include "ExecutionEngine.h" 9 #include "GenericValue.h" 10 #include "llvm/DerivedTypes.h" 11 #include "llvm/Constants.h" 12 #include "llvm/Module.h" 13 #include "llvm/Target/TargetData.h" 14 #include "Support/Statistic.h" 15 16 Statistic<> NumInitBytes("lli", "Number of bytes of global vars initialized"); 17 18 // getPointerToGlobal - This returns the address of the specified global 19 // value. This may involve code generation if it's a function. 20 // 21 void *ExecutionEngine::getPointerToGlobal(const GlobalValue *GV) { 22 if (const Function *F = dyn_cast<Function>(GV)) 23 return getPointerToFunction(F); 24 25 assert(GlobalAddress[GV] && "Global hasn't had an address allocated yet?"); 26 return GlobalAddress[GV]; 27 } 28 29 30 GenericValue ExecutionEngine::getConstantValue(const Constant *C) { 31 GenericValue Result; 32 #define GET_CONST_VAL(TY, CLASS) \ 33 case Type::TY##TyID: Result.TY##Val = cast<CLASS>(C)->getValue(); break 34 35 switch (C->getType()->getPrimitiveID()) { 36 GET_CONST_VAL(Bool , ConstantBool); 37 GET_CONST_VAL(UByte , ConstantUInt); 38 GET_CONST_VAL(SByte , ConstantSInt); 39 GET_CONST_VAL(UShort , ConstantUInt); 40 GET_CONST_VAL(Short , ConstantSInt); 41 GET_CONST_VAL(UInt , ConstantUInt); 42 GET_CONST_VAL(Int , ConstantSInt); 43 GET_CONST_VAL(ULong , ConstantUInt); 44 GET_CONST_VAL(Long , ConstantSInt); 45 GET_CONST_VAL(Float , ConstantFP); 46 GET_CONST_VAL(Double , ConstantFP); 47 #undef GET_CONST_VAL 48 case Type::PointerTyID: 49 if (isa<ConstantPointerNull>(C)) { 50 Result.PointerVal = 0; 51 } else if (const ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(C)){ 52 Result = PTOGV(getPointerToGlobal(CPR->getValue())); 53 54 } else { 55 assert(0 && "Unknown constant pointer type!"); 56 } 57 break; 58 default: 59 std::cout << "ERROR: Constant unimp for type: " << C->getType() << "\n"; 60 } 61 return Result; 62 } 63 64 void ExecutionEngine::StoreValueToMemory(GenericValue Val, GenericValue *Ptr, 65 const Type *Ty) { 66 if (getTargetData().isLittleEndian()) { 67 switch (Ty->getPrimitiveID()) { 68 case Type::BoolTyID: 69 case Type::UByteTyID: 70 case Type::SByteTyID: Ptr->Untyped[0] = Val.UByteVal; break; 71 case Type::UShortTyID: 72 case Type::ShortTyID: Ptr->Untyped[0] = Val.UShortVal & 255; 73 Ptr->Untyped[1] = (Val.UShortVal >> 8) & 255; 74 break; 75 case Type::FloatTyID: 76 case Type::UIntTyID: 77 case Type::IntTyID: Ptr->Untyped[0] = Val.UIntVal & 255; 78 Ptr->Untyped[1] = (Val.UIntVal >> 8) & 255; 79 Ptr->Untyped[2] = (Val.UIntVal >> 16) & 255; 80 Ptr->Untyped[3] = (Val.UIntVal >> 24) & 255; 81 break; 82 case Type::DoubleTyID: 83 case Type::ULongTyID: 84 case Type::LongTyID: 85 case Type::PointerTyID: Ptr->Untyped[0] = Val.ULongVal & 255; 86 Ptr->Untyped[1] = (Val.ULongVal >> 8) & 255; 87 Ptr->Untyped[2] = (Val.ULongVal >> 16) & 255; 88 Ptr->Untyped[3] = (Val.ULongVal >> 24) & 255; 89 Ptr->Untyped[4] = (Val.ULongVal >> 32) & 255; 90 Ptr->Untyped[5] = (Val.ULongVal >> 40) & 255; 91 Ptr->Untyped[6] = (Val.ULongVal >> 48) & 255; 92 Ptr->Untyped[7] = (Val.ULongVal >> 56) & 255; 93 break; 94 default: 95 std::cout << "Cannot store value of type " << Ty << "!\n"; 96 } 97 } else { 98 switch (Ty->getPrimitiveID()) { 99 case Type::BoolTyID: 100 case Type::UByteTyID: 101 case Type::SByteTyID: Ptr->Untyped[0] = Val.UByteVal; break; 102 case Type::UShortTyID: 103 case Type::ShortTyID: Ptr->Untyped[1] = Val.UShortVal & 255; 104 Ptr->Untyped[0] = (Val.UShortVal >> 8) & 255; 105 break; 106 case Type::FloatTyID: 107 case Type::UIntTyID: 108 case Type::IntTyID: Ptr->Untyped[3] = Val.UIntVal & 255; 109 Ptr->Untyped[2] = (Val.UIntVal >> 8) & 255; 110 Ptr->Untyped[1] = (Val.UIntVal >> 16) & 255; 111 Ptr->Untyped[0] = (Val.UIntVal >> 24) & 255; 112 break; 113 case Type::DoubleTyID: 114 case Type::ULongTyID: 115 case Type::LongTyID: 116 case Type::PointerTyID: Ptr->Untyped[7] = Val.ULongVal & 255; 117 Ptr->Untyped[6] = (Val.ULongVal >> 8) & 255; 118 Ptr->Untyped[5] = (Val.ULongVal >> 16) & 255; 119 Ptr->Untyped[4] = (Val.ULongVal >> 24) & 255; 120 Ptr->Untyped[3] = (Val.ULongVal >> 32) & 255; 121 Ptr->Untyped[2] = (Val.ULongVal >> 40) & 255; 122 Ptr->Untyped[1] = (Val.ULongVal >> 48) & 255; 123 Ptr->Untyped[0] = (Val.ULongVal >> 56) & 255; 124 break; 125 default: 126 std::cout << "Cannot store value of type " << Ty << "!\n"; 127 } 128 } 129 } 130 131 // InitializeMemory - Recursive function to apply a Constant value into the 132 // specified memory location... 133 // 134 void ExecutionEngine::InitializeMemory(const Constant *Init, void *Addr) { 135 if (Init->getType()->isFirstClassType()) { 136 GenericValue Val = getConstantValue(Init); 137 StoreValueToMemory(Val, (GenericValue*)Addr, Init->getType()); 138 return; 139 } 140 141 switch (Init->getType()->getPrimitiveID()) { 142 case Type::ArrayTyID: { 143 const ConstantArray *CPA = cast<ConstantArray>(Init); 144 const std::vector<Use> &Val = CPA->getValues(); 145 unsigned ElementSize = 146 getTargetData().getTypeSize(cast<ArrayType>(CPA->getType())->getElementType()); 147 for (unsigned i = 0; i < Val.size(); ++i) 148 InitializeMemory(cast<Constant>(Val[i].get()), (char*)Addr+i*ElementSize); 149 return; 150 } 151 152 case Type::StructTyID: { 153 const ConstantStruct *CPS = cast<ConstantStruct>(Init); 154 const StructLayout *SL = 155 getTargetData().getStructLayout(cast<StructType>(CPS->getType())); 156 const std::vector<Use> &Val = CPS->getValues(); 157 for (unsigned i = 0; i < Val.size(); ++i) 158 InitializeMemory(cast<Constant>(Val[i].get()), 159 (char*)Addr+SL->MemberOffsets[i]); 160 return; 161 } 162 163 default: 164 std::cerr << "Bad Type: " << Init->getType() << "\n"; 165 assert(0 && "Unknown constant type to initialize memory with!"); 166 } 167 } 168 169 170 171 void *ExecutionEngine::CreateArgv(const std::vector<std::string> &InputArgv) { 172 // Pointers are 64 bits... 173 // FIXME: Assumes 64 bit target 174 PointerTy *Result = new PointerTy[InputArgv.size()+1]; 175 DEBUG(std::cerr << "ARGV = " << (void*)Result << "\n"); 176 177 for (unsigned i = 0; i < InputArgv.size(); ++i) { 178 unsigned Size = InputArgv[i].size()+1; 179 char *Dest = new char[Size]; 180 DEBUG(std::cerr << "ARGV[" << i << "] = " << (void*)Dest << "\n"); 181 182 copy(InputArgv[i].begin(), InputArgv[i].end(), Dest); 183 Dest[Size-1] = 0; 184 185 // Endian safe: Result[i] = (PointerTy)Dest; 186 StoreValueToMemory(PTOGV(Dest), (GenericValue*)(Result+i), 187 Type::LongTy); // 64 bit assumption 188 } 189 190 Result[InputArgv.size()] = 0; 191 return Result; 192 } 193 194 /// EmitGlobals - Emit all of the global variables to memory, storing their 195 /// addresses into GlobalAddress. This must make sure to copy the contents of 196 /// their initializers into the memory. 197 /// 198 void ExecutionEngine::emitGlobals() { 199 const TargetData &TD = getTargetData(); 200 201 // Loop over all of the global variables in the program, allocating the memory 202 // to hold them. 203 for (Module::giterator I = getModule().gbegin(), E = getModule().gend(); 204 I != E; ++I) 205 if (!I->isExternal()) { 206 // Get the type of the global... 207 const Type *Ty = I->getType()->getElementType(); 208 209 // Allocate some memory for it! 210 unsigned Size = TD.getTypeSize(Ty); 211 GlobalAddress[I] = new char[Size]; 212 NumInitBytes += Size; 213 214 DEBUG(std::cerr << "Global '" << I->getName() << "' -> " 215 << (void*)GlobalAddress[I] << "\n"); 216 } else if (I->getName() == "stdout") { 217 GlobalAddress[I] = &stdout; 218 } else if (I->getName() == "stderr") { 219 GlobalAddress[I] = &stderr; 220 } else if (I->getName() == "stdin") { 221 GlobalAddress[I] = &stdin; 222 } else { 223 std::cerr << "Global: " << I->getName() << "\n"; 224 assert(0 && "References to external globals not handled yet!"); 225 } 226 227 // Now that all of the globals are set up in memory, loop through them all and 228 // initialize their contents. 229 for (Module::giterator I = getModule().gbegin(), E = getModule().gend(); 230 I != E; ++I) 231 if (!I->isExternal()) 232 InitializeMemory(I->getInitializer(), GlobalAddress[I]); 233 } 234 235