Example #1
0
FunctionType* ArgumentRecovery::createFunctionType(TargetInfo& info, const CallInformation& callInfo, llvm::Module& module, StringRef returnTypeName, SmallVectorImpl<string>& parameterNames)
{
	LLVMContext& ctx = module.getContext();
	Type* integer = Type::getIntNTy(ctx, info.getPointerSize() * CHAR_BIT);
	
	SmallVector<Type*, 8> parameterTypes;
	for (const auto& param : callInfo.parameters())
	{
		if (param.type == ValueInformation::IntegerRegister)
		{
			parameterTypes.push_back(integer);
			parameterNames.push_back(param.registerInfo->name);
		}
		else if (param.type == ValueInformation::Stack)
		{
			parameterTypes.push_back(integer);
			parameterNames.emplace_back();
			raw_string_ostream(parameterNames.back()) << "sp" << param.frameBaseOffset;
		}
		else
		{
			llvm_unreachable("not implemented");
		}
	}
	
	SmallVector<Type*, 2> returnTypes;
	for (const auto& ret : callInfo.returns())
	{
		if (ret.type == ValueInformation::IntegerRegister)
		{
			returnTypes.push_back(integer);
		}
		else
		{
			llvm_unreachable("not implemented");
		}
	}
	
	Type* returnType;
	if (returnTypes.size() == 0)
	{
		returnType = Type::getVoidTy(ctx);
	}
	else if (returnTypes.size() == 1)
	{
		returnType = returnTypes.front();
	}
	else
	{
		StructType* structTy = StructType::create(ctx, returnTypeName);
		structTy->setBody(returnTypes);
		md::setRecoveredReturnFieldNames(module, *structTy, callInfo);
		returnType = structTy;
	}
	
	assert(!callInfo.isVararg() && "not implemented");
	return FunctionType::get(returnType, parameterTypes, false);
}
Example #2
0
void TypeMapTy::linkDefinedTypeBodies() {
  SmallVector<Type *, 16> Elements;
  for (StructType *SrcSTy : SrcDefinitionsToResolve) {
    StructType *DstSTy = cast<StructType>(MappedTypes[SrcSTy]);
    assert(DstSTy->isOpaque());

    // Map the body of the source type over to a new body for the dest type.
    Elements.resize(SrcSTy->getNumElements());
    for (unsigned I = 0, E = Elements.size(); I != E; ++I)
      Elements[I] = get(SrcSTy->getElementType(I));

    DstSTy->setBody(Elements, SrcSTy->isPacked());
    DstStructTypesSet.switchToNonOpaque(DstSTy);
  }
  SrcDefinitionsToResolve.clear();
  DstResolvedOpaqueTypes.clear();
}
Example #3
0
int main(int argc, char **argv)
{
    InitializeNativeTarget();
    LLVMContext &Context = getGlobalContext();
    Module *m = new Module("test", Context);
    Type *intTy  = Type::getInt64Ty(Context);

    StructType* structTy = StructType::create(Context, "struct.list");
    std::vector<Type*> fields;
    fields.push_back(intTy);
    fields.push_back(PointerType::get(structTy, 0));
    if (structTy->isOpaque()) {
        structTy->setBody(fields, false);
    }

    /*
     * int f1(struct x *p) { return p->next->l1; }
     */
    std::vector<Type*> args_type;
    args_type.push_back(PointerType::get(structTy, 0));

    FunctionType *fnTy = FunctionType::get(intTy, args_type, false);
    Function *func = Function::Create(fnTy,
            GlobalValue::ExternalLinkage, "f1", m);
    Value *v = func->arg_begin();
    BasicBlock *bb = BasicBlock::Create(Context, "EntryBlock", func);
    IRBuilder<> *builder = new IRBuilder<>(bb);
    v = builder->CreateStructGEP(v, 1);
    v = builder->CreateLoad(v, "load0");
    v = builder->CreateStructGEP(v, 0);
    v = builder->CreateLoad(v, "load1");
    builder->CreateRet(v);

    (*m).dump();
    {
        ExecutionEngine *ee = EngineBuilder(m). 
            setEngineKind(EngineKind::JIT).create();
        void *f = ee->getPointerToFunction(func);
        typedef int (*func_t) (struct x *);
        struct x o = {10, NULL}, v = {};
        v.next = &o;
        std::cout << ((func_t)f)(&v) << std::endl;
    }
    return 0;
}
Example #4
0
StructType *StructType::get(LLVMContext &Context, ArrayRef<Type*> ETypes, 
                            bool isPacked) {
  LLVMContextImpl *pImpl = Context.pImpl;
  AnonStructTypeKeyInfo::KeyTy Key(ETypes, isPacked);
  auto I = pImpl->AnonStructTypes.find_as(Key);
  StructType *ST;

  if (I == pImpl->AnonStructTypes.end()) {
    // Value not found.  Create a new type!
    ST = new (Context.pImpl->TypeAllocator) StructType(Context);
    ST->setSubclassData(SCDB_IsLiteral);  // Literal struct.
    ST->setBody(ETypes, isPacked);
    Context.pImpl->AnonStructTypes.insert(ST);
  } else {
    ST = *I;
  }

  return ST;
}
Example #5
0
void Preparer::expandGlobal(Module &M, GlobalVariable *GV) {
  if (GV->isDeclaration()) return;
  if (GV->getLinkage() == GlobalValue::AppendingLinkage) return;
  Type *OrigType = GV->getType()->getTypeAtIndex((unsigned)0);
  StructType *NewType = StructType::create(GV->getContext(), "pad_global_type");
  NewType->setBody(OrigType, IntegerType::get(GV->getContext(), 8), NULL);

  // FIXME: AddressSpace?
  GlobalVariable *NewGV;
  Constant *NewInit = NULL;
  if (GV->hasInitializer()) {
    assert(GV->getInitializer()->getType() == OrigType);
    NewInit = ConstantStruct::get(NewType, GV->getInitializer(),
        ConstantInt::get(IntegerType::get(GV->getContext(), 8), 0), NULL);
  }
  NewGV = new GlobalVariable(M, NewType, GV->isConstant(), GV->getLinkage(),
      NewInit, "pad_global", GV, GV->isThreadLocal(), 0);

  Constant *NewValue = ConstantExpr::getBitCast(NewGV, GV->getType());
  assert(NewValue->getType() == GV->getType());
  GV->replaceAllUsesWith(NewValue);
}
bool PNaClSjLjEH::runOnModule(Module &M) {
  Type *JmpBufTy = ArrayType::get(Type::getInt8Ty(M.getContext()),
                                  kPNaClJmpBufSize);

  // Define "struct ExceptionFrame".
  StructType *ExceptionFrameTy = StructType::create(M.getContext(),
                                                    "ExceptionFrame");
  Type *ExceptionFrameFields[] = {
    JmpBufTy,  // jmp_buf
    ExceptionFrameTy->getPointerTo(),  // struct ExceptionFrame *next
    Type::getInt32Ty(M.getContext())  // Exception info (clause list ID)
  };
  ExceptionFrameTy->setBody(ExceptionFrameFields);

  ExceptionInfoWriter ExcInfoWriter(&M.getContext());
  for (Module::iterator Func = M.begin(), E = M.end(); Func != E; ++Func) {
    FuncRewriter Rewriter(ExceptionFrameTy, &ExcInfoWriter, Func);
    Rewriter.expandFunc();
  }
  ExcInfoWriter.defineGlobalVariables(&M);
  return true;
}
Example #7
0
/// linkDefinedTypeBodies - Produce a body for an opaque type in the dest
/// module from a type definition in the source module.
void TypeMapTy::linkDefinedTypeBodies() {
  SmallVector<Type*, 16> Elements;
  SmallString<16> TmpName;
  
  // Note that processing entries in this loop (calling 'get') can add new
  // entries to the SrcDefinitionsToResolve vector.
  while (!SrcDefinitionsToResolve.empty()) {
    StructType *SrcSTy = SrcDefinitionsToResolve.pop_back_val();
    StructType *DstSTy = cast<StructType>(MappedTypes[SrcSTy]);
    
    // TypeMap is a many-to-one mapping, if there were multiple types that
    // provide a body for DstSTy then previous iterations of this loop may have
    // already handled it.  Just ignore this case.
    if (!DstSTy->isOpaque()) continue;
    assert(!SrcSTy->isOpaque() && "Not resolving a definition?");
    
    // Map the body of the source type over to a new body for the dest type.
    Elements.resize(SrcSTy->getNumElements());
    for (unsigned i = 0, e = Elements.size(); i != e; ++i)
      Elements[i] = getImpl(SrcSTy->getElementType(i));
    
    DstSTy->setBody(Elements, SrcSTy->isPacked());
    
    // If DstSTy has no name or has a longer name than STy, then viciously steal
    // STy's name.
    if (!SrcSTy->hasName()) continue;
    StringRef SrcName = SrcSTy->getName();
    
    if (!DstSTy->hasName() || DstSTy->getName().size() > SrcName.size()) {
      TmpName.insert(TmpName.end(), SrcName.begin(), SrcName.end());
      SrcSTy->setName("");
      DstSTy->setName(TmpName.str());
      TmpName.clear();
    }
  }
  
  DstResolvedOpaqueTypes.clear();
}
Example #8
0
File: Type.cpp Project: c-ong/llvm
StructType *StructType::create(LLVMContext &Context, ArrayRef<Type*> Elements,
                               StringRef Name, bool isPacked) {
  StructType *ST = create(Context, Name);
  ST->setBody(Elements, isPacked);
  return ST;
}
bool AllocateDataSegment::runOnModule(Module &M) {
  DataLayout DL(&M);
  Type *I8 = Type::getInt8Ty(M.getContext());
  Type *I32 = Type::getInt32Ty(M.getContext());
  Type *IntPtrType = DL.getIntPtrType(M.getContext());

  // First, we do a pass over the global variables, in which we compute
  // the amount of required padding between them and consequently their
  // addresses relative to the memory base of the sandbox. References to each
  // global are then replaced with direct memory pointers.
  uint32_t VarOffset = 0;
  DenseMap<GlobalVariable*, uint32_t> VarPadding;
  for (Module::global_iterator GV = M.global_begin(), E = M.global_end();
       GV != E; ++GV) {
    assert(GV->hasInitializer());

    uint32_t Padding = getPadding(VarOffset, GV, DL);
    VarPadding[GV] = Padding;
    VarOffset += Padding;

    GV->replaceAllUsesWith(
        ConstantExpr::getIntToPtr(
            ConstantInt::get(IntPtrType,
                             DataSegmentBaseAddress + VarOffset),
            GV->getType()));

    VarOffset += DL.getTypeStoreSize(GV->getType()->getPointerElementType());
  }

  // Using the offsets computed above, we prepare the layout and the contents
  // of the desired data structure. After the type and initializer of each
  // global is copied, the global is not needed any more and it is erased.
  SmallVector<Type*, 10> TemplateLayout;
  SmallVector<Constant*, 10> TemplateData;
  for (Module::global_iterator It = M.global_begin(), E = M.global_end();
       It != E; ) {
    GlobalVariable *GV = It++;

    uint32_t Padding = VarPadding[GV];
    if (Padding > 0) {
      Type *PaddingType = ArrayType::get(I8, Padding);
      TemplateLayout.push_back(PaddingType);
      TemplateData.push_back(ConstantAggregateZero::get(PaddingType));
    }

    TemplateLayout.push_back(GV->getType()->getPointerElementType());
    TemplateData.push_back(GV->getInitializer());

    GV->eraseFromParent();
  }

  // Finally, we create the struct and size global variables.
  StructType *TemplateType =
      StructType::create(M.getContext(), ExternalSymName_DataSegment);
  TemplateType->setBody(TemplateLayout, /*isPacked=*/true);

  Constant *Template = ConstantStruct::get(TemplateType, TemplateData);
  new GlobalVariable(M, Template->getType(), /*isConstant=*/true,
                     GlobalVariable::ExternalLinkage, Template,
                     ExternalSymName_DataSegment);

  Constant *TemplateSize =
      ConstantInt::get(I32, DL.getTypeAllocSize(TemplateType));
  new GlobalVariable(M, TemplateSize->getType(), /*isConstant=*/true,
                     GlobalVariable::ExternalLinkage, TemplateSize,
                     ExternalSymName_DataSegmentSize);

  return true;
}
Example #10
0
void doGlobalInit(Module *M) {
    //create the "reg" struct type
    StructType  *regs = StructType::create(M->getContext(), "struct.regs");
    vector<Type *>  regFields;

    initInstructionDispatch();

    //UPDATEREGS -- when we add something to 'regs', add it here
    //GPRs 
    regFields.push_back(IntegerType::get(M->getContext(), 32)); // EAX // 0
    regFields.push_back(IntegerType::get(M->getContext(), 32)); // EBX // 1
    regFields.push_back(IntegerType::get(M->getContext(), 32)); // ECX // 2
    regFields.push_back(IntegerType::get(M->getContext(), 32)); // EDX // 3
    regFields.push_back(IntegerType::get(M->getContext(), 32)); // ESI // 4
    regFields.push_back(IntegerType::get(M->getContext(), 32)); // EDI // 5
    regFields.push_back(IntegerType::get(M->getContext(), 32)); // ESP // 6
    regFields.push_back(IntegerType::get(M->getContext(), 32)); // EBP // 7
                                                                // 32 bytes

    //flags
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // CF // 8
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // PF // 9
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // AF // 10
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // ZF // 11
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // SF // 12
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // OF // 13
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // DF // 14
                                                                   // 28 bytes

    // FPU
    ArrayType  *fpu_regs = ArrayType::get(Type::getX86_FP80Ty(M->getContext()), 8);
    regFields.push_back(fpu_regs);                                 // 80 bytes // 15
    
    // FPU Status Word
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU BUSY // 16
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Condition Code C3 // 17
    regFields.push_back(IntegerType::get(M->getContext(), 3)); // TOP OF STACK // 18
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Condition Code C2 // 19
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Condition Code C1 // 20
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Condition Code C0 // 21
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Error Summary Status // 22
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Stack Fault // 23
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Precision Flag // 24 
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Underflow Flag // 25
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Overflow Flag // 26
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // ZeroDivide Flag // 27
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Denormalized Operand Flag // 28
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Invalid Operation Flag // 29
                                                                   // 56 bytes

    // 80 + 56 + 28 + 32 = 196 bytes

    
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU Infinity Flag // 30
    regFields.push_back(IntegerType::get(M->getContext(), 2)); // FPU Rounding Control // 31
    regFields.push_back(IntegerType::get(M->getContext(), 2)); // FPU Precision Control // 32
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU Precision Mask // 33
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU Underflow Mask // 34
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU Overflow Mask // 35
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU Zero Divide Mask // 36
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU Denormal Operand Mask // 37
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU Invalid Operation Mask // 38

    // FPU tag word; 8 element array of 2-bit entries
    ArrayType  *fpu_tag_word = ArrayType::get(Type::getIntNTy(M->getContext(), 8), 8);
    regFields.push_back(fpu_tag_word);                                 // 80 bytes // 39

    regFields.push_back(IntegerType::getInt16Ty(M->getContext())); // Last Instruction Ptr Segment 40
    regFields.push_back(IntegerType::getInt32Ty(M->getContext())); // Last Instruction Ptr Offset 41
    regFields.push_back(IntegerType::getInt16Ty(M->getContext())); // Last Data Ptr Segment 42
    regFields.push_back(IntegerType::getInt32Ty(M->getContext())); // Last Data Ptr Offset 43
    
    regFields.push_back(IntegerType::get(M->getContext(), 11)); // FPU FOPCODE 44

    // vector registers
    regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM0 45
    regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM1 46
    regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM2 47
    regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM3 48
    regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM4 49
    regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM5 50
    regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM6 51
    regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM7 52

    // non-register values in structRegs
    regFields.push_back(IntegerType::getInt32Ty(M->getContext())); // 53: stack base (biggest value)
    regFields.push_back(IntegerType::getInt32Ty(M->getContext())); // 54: stack limit (smallest value)
    

    PointerType *ptrToRegs = PointerType::get(regs, 0);
    regs->setBody(regFields, true);

    vector<Type*> callValArgs;
    callValArgs.push_back(Type::getInt32Ty(M->getContext()));
    callValArgs.push_back(ptrToRegs);

    FunctionType  *callVal = FunctionType::get(
                                      Type::getVoidTy(M->getContext()),
                                      callValArgs,
                                      false);

    //GlobalVariable* g_StateBackup = 
    //    new GlobalVariable(*M, regs, false, GlobalValue::ExternalLinkage, 0, "state.backup");
    Type *int32ty = IntegerType::getInt32Ty(M->getContext());
    g_StateBackup = new GlobalVariable(*M, int32ty, 
                false, 
                GlobalValue::PrivateLinkage, 
                0, 
                "state.backup");
    g_StateBackup->setThreadLocalMode(GlobalVariable::GeneralDynamicTLSModel);


    Constant *zero = ConstantInt::get(int32ty, 0, false);
    g_StateBackup->setInitializer(zero);
    


    g_RegStruct = regs;
    g_PRegStruct = ptrToRegs;

    archAddCallValue(M);

    return;
}
// Transforms any type that could transitively reference a function pointer
// into a simplified type.
// We enter this function trying to determine the mapping of a type. Because
// of how structs are handled (not interned by llvm - see further comments
// below) we may be working with temporary types - types (pointers, for example)
// transitively referencing "tentative" structs. For that reason, we do not
// memoize anything here, except for structs. The latter is so that we avoid
// unnecessary repeated creation of types (pointers, function types, etc),
// as we try to map a given type.
SimplifiedFuncTypeMap::MappingResult
SimplifiedFuncTypeMap::getSimpleAggregateTypeInternal(LLVMContext &Ctx,
                                                      Type *Ty,
                                                      StructMap &Tentatives) {
  // Leverage the map for types we encounter on the way.
  auto Found = MappedTypes.find(Ty);
  if (Found != MappedTypes.end()) {
    return {Found->second, Found->second != Ty};
  }

  if (auto *OldFnTy = dyn_cast<FunctionType>(Ty)) {
    return getSimpleFuncType(Ctx, Tentatives, OldFnTy);
  }

  if (auto PtrTy = dyn_cast<PointerType>(Ty)) {
    auto NewTy = getSimpleAggregateTypeInternal(
        Ctx, PtrTy->getPointerElementType(), Tentatives);

    return {NewTy->getPointerTo(PtrTy->getAddressSpace()), NewTy.isChanged()};
  }

  if (auto ArrTy = dyn_cast<ArrayType>(Ty)) {
    auto NewTy = getSimpleAggregateTypeInternal(
        Ctx, ArrTy->getArrayElementType(), Tentatives);
    return {ArrayType::get(NewTy, ArrTy->getArrayNumElements()),
            NewTy.isChanged()};
  }

  if (auto VecTy = dyn_cast<VectorType>(Ty)) {
    auto NewTy = getSimpleAggregateTypeInternal(
        Ctx, VecTy->getVectorElementType(), Tentatives);
    return {VectorType::get(NewTy, VecTy->getVectorNumElements()),
            NewTy.isChanged()};
  }

  // LLVM doesn't intern identified structs (the ones with a name). This,
  // together with the fact that such structs can be recursive,
  // complicates things a bit. We want to make sure that we only change
  // "unsimplified" structs (those that somehow reference funcs that
  // are not simple).
  // We don't want to change "simplified" structs, otherwise converting
  // instruction types will become trickier.
  if (auto StructTy = dyn_cast<StructType>(Ty)) {
    ParamTypeVector ElemTypes;
    if (!StructTy->isLiteral()) {
      // Literals - struct without a name - cannot be recursive, so we
      // don't need to form tentatives.
      auto Found = Tentatives.find(StructTy);

      // Having a tentative means we are in a recursion trying to map this
      // particular struct, so arriving back to it is not a change.
      // We will determine if this struct is actually
      // changed by checking its other fields.
      if (Found != Tentatives.end()) {
        return {Found->second, false};
      }
      // We have never seen this struct, so we start a tentative.
      std::string NewName = StructTy->getStructName();
      NewName += ".simplified";
      StructType *Tentative = StructType::create(Ctx, NewName);
      Tentatives[StructTy] = Tentative;

      bool Changed = isChangedStruct(Ctx, StructTy, ElemTypes, Tentatives);

      Tentatives.erase(StructTy);
      // We can now decide the mapping of the struct. We will register it
      // early with MappedTypes, to avoid leaking tentatives unnecessarily.
      // We are leaking the created struct here, but there is no way to
      // correctly delete it.
      if (!Changed) {
        return {MappedTypes[StructTy] = StructTy, false};
      } else {
        Tentative->setBody(ElemTypes, StructTy->isPacked());
        return {MappedTypes[StructTy] = Tentative, true};
      }
    } else {
      bool Changed = isChangedStruct(Ctx, StructTy, ElemTypes, Tentatives);
      return {MappedTypes[StructTy] =
                  StructType::get(Ctx, ElemTypes, StructTy->isPacked()),
              Changed};
    }
  }

  // Anything else stays the same.
  return {Ty, false};
}
Example #12
0
int main() {
    InitializeNativeTarget();
    LLVMContext& Context = getGlobalContext();
    Module *M = new Module("test C++ exception handling ", Context);


    StructType* MyStructType = StructType::create(Context, "struct.MyStruct");
    Type* MyStructFields[] = {
        Type::getInt32Ty(Context),
        Type::getInt32Ty(Context)
    };
    MyStructType->setBody(MyStructFields);

    GlobalValue* throwFunc = cast<GlobalValue>(M->getOrInsertFunction("throwMyStruct", Type::getVoidTy(Context), NULL));
    GlobalValue* MyStructTypeInfo = cast<GlobalValue>(M->getOrInsertGlobal("MyStructTypeInfo", Type::getInt8Ty(Context)));

    Function* gxx_personality = Function::Create(FunctionType::get(Type::getInt32Ty(Context), true), Function::ExternalLinkage, "__gxx_personality_v0", M);
    Function* begin_catch     = Function::Create(FunctionType::get(Type::getInt8PtrTy(Context), Type::getInt8PtrTy(Context), false), Function::ExternalLinkage, "__cxa_begin_catch", M);
    Function* end_catch       = Function::Create(FunctionType::get(Type::getVoidTy(Context), false), Function::ExternalLinkage, "__cxa_end_catch", M);

    Function* testExceptions = cast<Function>(M->getOrInsertFunction("testExceptions", Type::getInt32Ty(Context), NULL));

    BasicBlock* entryBB   = BasicBlock::Create(Context, "", testExceptions);
    BasicBlock* landPadBB = BasicBlock::Create(Context, "landPad", testExceptions);
    BasicBlock* noErrorBB = BasicBlock::Create(Context, "noError", testExceptions);


    IRBuilder<> builder(entryBB);

    Value* invokeThrow = builder.CreateInvoke(throwFunc, noErrorBB, landPadBB);

    builder.SetInsertPoint(noErrorBB);
    builder.CreateRet( builder.getInt32(666) ); // should never happen

    //writing landingpad! <<<<<<<

    builder.SetInsertPoint(landPadBB);

    Value* gxx_personality_i8 = builder.CreateBitCast(gxx_personality, Type::getInt8PtrTy(Context));
    Type* caughtType = StructType::get(builder.getInt8PtrTy(), builder.getInt32Ty(), NULL);

    LandingPadInst* caughtResult = builder.CreateLandingPad(caughtType, gxx_personality_i8, 1);

    // we can catch any C++ exception we want
    // but now we are catching MyStruct
    caughtResult->addClause(MyStructTypeInfo);

    //we are sure to catch MyStruct so no other checks are needed
    //if throwMyStruct() throws anything but MyStruct it won't pass to the current landingpad BB

    Value* thrownExctn  = builder.CreateExtractValue(caughtResult, 0);
    Value* thrownObject = builder.CreateCall(begin_catch, thrownExctn);
    Value* object       = builder.CreateBitCast(thrownObject, MyStructType->getPointerTo());
    Value* resultPtr    = builder.CreateStructGEP(object, 1);
    Value* result       = builder.CreateLoad(resultPtr);

    builder.CreateCall(end_catch);

    builder.CreateRet( result ); // << z.y

    TargetOptions Opts;
    Opts.JITExceptionHandling = true; // DO NOT FORGET THIS OPTION !!!!!!11


    ExecutionEngine* EE = EngineBuilder(M)
                        .setEngineKind(EngineKind::JIT)
                        .setTargetOptions(Opts)
                        .create();

    EE->addGlobalMapping(throwFunc, reinterpret_cast<void*>(&throwMyStruct));
    EE->addGlobalMapping(MyStructTypeInfo, MyStruct::getTypeInfo());

    verifyFunction(*testExceptions);
    outs() << *testExceptions;

    std::vector<GenericValue> noArgs;
    GenericValue gv = EE->runFunction(testExceptions, noArgs);

    outs() << "\ntestExceptions result: " << gv.IntVal << "\n";

    delete EE;
    llvm_shutdown();
    return 0;
}
Example #13
0
void doGlobalInit(Module *M) {

	unsigned int regWidth = getPointerSize(M);

    //create the "reg" struct type
    StructType  *regs = StructType::create(M->getContext(), "struct.regs");
    vector<Type *>  regFields;

    initInstructionDispatch();

    //UPDATEREGS -- when we add something to 'regs', add it here
    //GPRs
    regFields.push_back(IntegerType::get(M->getContext(), regWidth)); // RAX/EAX // 0
    regFields.push_back(IntegerType::get(M->getContext(), regWidth)); // RBX/EBX // 1
    regFields.push_back(IntegerType::get(M->getContext(), regWidth)); // RCX/ECX // 2
    regFields.push_back(IntegerType::get(M->getContext(), regWidth)); // RDX/EDX // 3
    regFields.push_back(IntegerType::get(M->getContext(), regWidth)); // RSI/ESI // 4
    regFields.push_back(IntegerType::get(M->getContext(), regWidth)); // RDI/EDI // 5
    regFields.push_back(IntegerType::get(M->getContext(), regWidth)); // RSP/ESP // 6
    regFields.push_back(IntegerType::get(M->getContext(), regWidth)); // RBP/EBP // 7

	if(getSystemArch(M) == _X86_64_){
		regFields.push_back(IntegerType::get(M->getContext(), regWidth)); // R8  // 8
		regFields.push_back(IntegerType::get(M->getContext(), regWidth)); // R9  // 9
		regFields.push_back(IntegerType::get(M->getContext(), regWidth)); // R10 // 10
		regFields.push_back(IntegerType::get(M->getContext(), regWidth)); // R11 // 11
		regFields.push_back(IntegerType::get(M->getContext(), regWidth)); // R12 // 12
		regFields.push_back(IntegerType::get(M->getContext(), regWidth)); // R13 // 13
		regFields.push_back(IntegerType::get(M->getContext(), regWidth)); // R14 // 14
		regFields.push_back(IntegerType::get(M->getContext(), regWidth)); // R15 // 15

		// RIP for rip relative instructions
		regFields.push_back(IntegerType::get(M->getContext(), regWidth)); // RIP // 16
	}

    //flags
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // CF // 17
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // PF // 18
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // AF // 19
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // ZF // 20
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // SF // 21
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // OF // 22
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // DF // 23

    ArrayType  *fpu_regs = ArrayType::get(Type::getX86_FP80Ty(M->getContext()), 8);
    regFields.push_back(fpu_regs);                            // 80 bytes 24


	// FPU Status Word
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU BUSY // 25
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Condition Code C3 // 26
    regFields.push_back(IntegerType::get(M->getContext(), 3)); // TOP OF STACK // 27
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Condition Code C2 // 28
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Condition Code C1 // 29
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Condition Code C0 // 30
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Error Summary Status // 31
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Stack Fault // 32
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Precision Flag // 33
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Underflow Flag // 34
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Overflow Flag // 35
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // ZeroDivide Flag // 36
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Denormalized Operand Flag // 37
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Invalid Operation Flag // 38


    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU Infinity Flag // 39
    regFields.push_back(IntegerType::get(M->getContext(), 2)); // FPU Rounding Control // 40
    regFields.push_back(IntegerType::get(M->getContext(), 2)); // FPU Precision Control // 41
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU Precision Mask // 42
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU Underflow Mask // 43
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU Overflow Mask // 44
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU Zero Divide Mask // 45
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU Denormal Operand Mask // 46
    regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU Invalid Operation Mask // 47

	// FPU tag word; 8 element array of 2-bit entries
    ArrayType  *fpu_tag_word = ArrayType::get(Type::getIntNTy(M->getContext(), 8), 8);
    regFields.push_back(fpu_tag_word);                                               // 48

    regFields.push_back(IntegerType::getInt16Ty(M->getContext())); // Last Instruction Ptr Segment 49
    regFields.push_back(IntegerType::getIntNTy(M->getContext(), regWidth)); // Last Instruction Ptr Offset 50
    regFields.push_back(IntegerType::getInt16Ty(M->getContext())); // Last Data Ptr Segment 51
    regFields.push_back(IntegerType::getIntNTy(M->getContext(), regWidth)); // Last Data Ptr Offset 52

    regFields.push_back(IntegerType::get(M->getContext(), 11)); // FPU FOPCODE 53


    // vector registers
    regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM0 54
    regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM1 55
    regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM2 56
    regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM3 57
    regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM4 58
    regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM5 59
    regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM6 60
    regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM7 61

	if(getSystemArch(M) == _X86_64_){
		regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM8 62
		regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM9 63
		regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM10 64
		regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM11 65
		regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM12 66
		regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM13 67
		regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM14 68
		regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM15 69
	}

    // non-register values in structRegs
    regFields.push_back(IntegerType::getIntNTy(M->getContext(), regWidth)); // 70: stack base (biggest value)
    regFields.push_back(IntegerType::getIntNTy(M->getContext(), regWidth)); // 71: stack limit (smallest value)


    PointerType *ptrToRegs = PointerType::get(regs, 0);
    regs->setBody(regFields, true);

    vector<Type*> callValArgs;
    callValArgs.push_back(Type::getIntNTy(M->getContext(), regWidth));
    callValArgs.push_back(ptrToRegs);

    FunctionType  *callVal = FunctionType::get(
                                      Type::getVoidTy(M->getContext()),
                                      callValArgs,
                                      false);

    //GlobalVariable* g_StateBackup =
    //    new GlobalVariable(*M, regs, false, GlobalValue::ExternalLinkage, 0, "state.backup");
    Type *intType = IntegerType::getIntNTy(M->getContext(), regWidth);
    g_StateBackup = new GlobalVariable(*M, intType,
                false,
                GlobalValue::PrivateLinkage,
                0,
                "state.backup");
    g_StateBackup->setThreadLocalMode(GlobalVariable::GeneralDynamicTLSModel);


    Constant *zero = ConstantInt::get(intType, 0, false);
    g_StateBackup->setInitializer(zero);



    g_RegStruct = regs;
    g_PRegStruct = ptrToRegs;

    archAddCallValue(M);

    return;
}
Example #14
0
static PointerType *buildTlsTemplate(Module &M, std::vector<VarInfo> *TlsVars) {
  std::vector<Type*> FieldBssTypes;
  std::vector<Type*> FieldInitTypes;
  std::vector<Constant*> FieldInitValues;
  PassState State(&M);

  for (Module::global_iterator GV = M.global_begin();
       GV != M.global_end();
       ++GV) {
    if (GV->isThreadLocal()) {
      if (!GV->hasInitializer()) {
        // Since this is a whole-program transformation, "extern" TLS
        // variables are not allowed at this point.
        report_fatal_error(std::string("TLS variable without an initializer: ")
                           + GV->getName());
      }
      if (!GV->getInitializer()->isNullValue()) {
        addVarToTlsTemplate(&State, &FieldInitTypes,
                            &FieldInitValues, GV);
        VarInfo Info;
        Info.TlsVar = GV;
        Info.IsBss = false;
        Info.TemplateIndex = FieldInitTypes.size() - 1;
        TlsVars->push_back(Info);
      }
    }
  }
  // Handle zero-initialized TLS variables in a second pass, because
  // these should follow non-zero-initialized TLS variables.
  for (Module::global_iterator GV = M.global_begin();
       GV != M.global_end();
       ++GV) {
    if (GV->isThreadLocal() && GV->getInitializer()->isNullValue()) {
      addVarToTlsTemplate(&State, &FieldBssTypes, NULL, GV);
      VarInfo Info;
      Info.TlsVar = GV;
      Info.IsBss = true;
      Info.TemplateIndex = FieldBssTypes.size() - 1;
      TlsVars->push_back(Info);
    }
  }
  // Add final alignment padding so that
  //   (struct tls_struct *) __nacl_read_tp() - 1
  // gives the correct, aligned start of the TLS variables given the
  // x86-style layout we are using.  This requires some more bytes to
  // be memset() to zero at runtime.  This wastage doesn't seem
  // important gives that we're not trying to optimize packing by
  // reordering to put similarly-aligned variables together.
  padToAlignment(&State, &FieldBssTypes, NULL, State.Alignment);

  // We create the TLS template structs as "packed" because we insert
  // alignment padding ourselves, and LLVM's implicit insertion of
  // padding would interfere with ours.  tls_bss_template can start at
  // a non-aligned address immediately following the last field in
  // tls_init_template.
  StructType *InitTemplateType =
      StructType::create(M.getContext(), "tls_init_template");
  InitTemplateType->setBody(FieldInitTypes, /*isPacked=*/true);
  StructType *BssTemplateType =
      StructType::create(M.getContext(), "tls_bss_template");
  BssTemplateType->setBody(FieldBssTypes, /*isPacked=*/true);

  StructType *TemplateType = StructType::create(M.getContext(), "tls_struct");
  SmallVector<Type*, 2> TemplateTopFields;
  TemplateTopFields.push_back(InitTemplateType);
  TemplateTopFields.push_back(BssTemplateType);
  TemplateType->setBody(TemplateTopFields, /*isPacked=*/true);
  PointerType *TemplatePtrType = PointerType::get(TemplateType, 0);

  // We define the following symbols, which are the same as those
  // defined by NaCl's original customized binutils linker scripts:
  //   __tls_template_start
  //   __tls_template_tdata_end
  //   __tls_template_end
  // We also define __tls_template_alignment, which was not defined by
  // the original linker scripts.

  const char *StartSymbol = "__tls_template_start";
  Constant *TemplateData = ConstantStruct::get(InitTemplateType,
                                               FieldInitValues);
  GlobalVariable *TemplateDataVar =
      new GlobalVariable(M, InitTemplateType, /*isConstant=*/true,
                         GlobalValue::InternalLinkage, TemplateData);
  setGlobalVariableValue(M, StartSymbol, TemplateDataVar);
  TemplateDataVar->setName(StartSymbol);

  Constant *TdataEnd = ConstantExpr::getGetElementPtr(
      TemplateDataVar,
      ConstantInt::get(M.getContext(), APInt(32, 1)));
  setGlobalVariableValue(M, "__tls_template_tdata_end", TdataEnd);

  Constant *TotalEnd = ConstantExpr::getGetElementPtr(
      ConstantExpr::getBitCast(TemplateDataVar, TemplatePtrType),
      ConstantInt::get(M.getContext(), APInt(32, 1)));
  setGlobalVariableValue(M, "__tls_template_end", TotalEnd);

  const char *AlignmentSymbol = "__tls_template_alignment";
  Type *i32 = Type::getInt32Ty(M.getContext());
  GlobalVariable *AlignmentVar = new GlobalVariable(
      M, i32, /*isConstant=*/true,
      GlobalValue::InternalLinkage,
      ConstantInt::get(M.getContext(), APInt(32, State.Alignment)));
  setGlobalVariableValue(M, AlignmentSymbol, AlignmentVar);
  AlignmentVar->setName(AlignmentSymbol);

  return TemplatePtrType;
}