Пример #1
0
	 // accessors
	 bool lookup(const std::string& name, Symbol& symbol) const {
	    auto it = symbols.find(name);
	    if (it == symbols.end()) {
	       if (outer) {
		  return outer->lookup(name, symbol);
	       } else {
		  return false;
	       }
	    } else {
	       symbol = it->second;
	       return true;
	    }
	 }
Пример #2
0
static void set(SymMap &symbols, const llvm::BasicBlock::iterator &it, Val v) {
    if (VERBOSITY() >= 2) {
        printf("Setting to %lx / %f: ", v.n, v.d);
        fflush(stdout);
        it->dump();
    }

    SymMap::iterator f = symbols.find(it);
    if (f != symbols.end())
        f->second = v;
    else
        symbols.insert(std::make_pair(static_cast<llvm::Value*>(&(*it)), v));
//#define SET(v) symbols.insert(std::make_pair(static_cast<llvm::Value*>(&(*it)), Val(v)))
}
   void init_symbol_map()
   {
      map.clear();

      // On Windows, you cannot lookup these symbols ... <_<
      struct mapper { const char* sym; retro_proc_address_t proc; };
#define _D(sym) { #sym, reinterpret_cast<retro_proc_address_t>(sym) }
      static const mapper bind_map[] = {
         _D(glEnable),
         _D(glDisable),
         _D(glBlendFunc),
         _D(glClearColor),
         _D(glTexImage2D),
         _D(glViewport),
         _D(glClear),
         _D(glTexParameteri),
         _D(glDeleteTextures),
         _D(glGenTextures),
         _D(glBindTexture),
         _D(glDrawArrays),
         _D(glGetError),
         _D(glFrontFace),
#if defined(__APPLE__) && !defined(IOS)
         _D(glActiveTexture),
	 _D(glCreateProgram),
         _D(glCreateShader),
	 _D(glShaderSource),
	 _D(glCompileShader),
	 _D(glGetShaderiv),
	 _D(glAttachShader),
	 _D(glLinkProgram),
	 _D(glGetProgramiv),
	 _D(glGenerateMipmap),
	 _D(glGetIntegerv),
	 _D(glGenBuffers),
	 _D(glBindBuffer),
	 _D(glBufferData),
	 _D(glBindFramebuffer),
	 _D(glUseProgram),
	 _D(glUniform1i),
         _D(glGetUniformLocation),
	 _D(glUniformMatrix4fv),
	 _D(glUniform3fv),
	 _D(glUniform1f),
	 _D(glGetAttribLocation),
	 _D(glEnableVertexAttribArray),
	 _D(glVertexAttribPointer),
	 _D(glDisableVertexAttribArray),
#endif
      };
#undef _D

      for (unsigned i = 0; i < sizeof(bind_map) / sizeof(bind_map[0]); i++)
         map[bind_map[i].sym] = bind_map[i].proc;
   }
Пример #4
0
void StreamChecker::checkEndPath(CheckerContext &Ctx) const {
  const ProgramState *state = Ctx.getState();
  typedef llvm::ImmutableMap<SymbolRef, StreamState> SymMap;
  SymMap M = state->get<StreamState>();
  
  for (SymMap::iterator I = M.begin(), E = M.end(); I != E; ++I) {
    StreamState SS = I->second;
    if (SS.isOpened()) {
      ExplodedNode *N = Ctx.addTransition(state);
      if (N) {
        if (!BT_ResourceLeak)
          BT_ResourceLeak.reset(new BuiltinBug("Resource Leak", 
                         "Opened File never closed. Potential Resource leak."));
        BugReport *R = new BugReport(*BT_ResourceLeak, 
                                     BT_ResourceLeak->getDescription(), N);
        Ctx.EmitReport(R);
      }
    }
  }
}
Пример #5
0
void StreamChecker::checkEndPath(EndOfFunctionNodeBuilder &B,
                                 ExprEngine &Eng) const {
    const GRState *state = B.getState();
    typedef llvm::ImmutableMap<SymbolRef, StreamState> SymMap;
    SymMap M = state->get<StreamState>();

    for (SymMap::iterator I = M.begin(), E = M.end(); I != E; ++I) {
        StreamState SS = I->second;
        if (SS.isOpened()) {
            ExplodedNode *N = B.generateNode(state);
            if (N) {
                if (!BT_ResourceLeak)
                    BT_ResourceLeak.reset(new BuiltinBug("Resource Leak",
                                                         "Opened File never closed. Potential Resource leak."));
                BugReport *R = new BugReport(*BT_ResourceLeak,
                                             BT_ResourceLeak->getDescription(), N);
                Eng.getBugReporter().EmitReport(R);
            }
        }
    }
}
Пример #6
0
Box* interpretFunction(llvm::Function *f, int nargs, Box* arg1, Box* arg2, Box* arg3, Box* *args) {
    assert(f);

#ifdef TIME_INTERPRETS
    Timer _t("to interpret", 1000000);
    long this_us = 0;
#endif

    static StatCounter interpreted_runs("interpreted_runs");
    interpreted_runs.log();

    llvm::DataLayout dl(f->getParent());

    //f->dump();
    //assert(nargs == f->getArgumentList().size());

    SymMap symbols;

    void* frame_ptr = __builtin_frame_address(0);
    interpreter_roots[frame_ptr] = &symbols;
    UnregisterHelper helper(frame_ptr);

    int arg_num = -1;
    for (llvm::Argument& arg : f->args()) {
        arg_num++;

        if (arg_num == 0) symbols.insert(std::make_pair(static_cast<llvm::Value*>(&arg), Val(arg1)));
        else if (arg_num == 1) symbols.insert(std::make_pair(static_cast<llvm::Value*>(&arg), Val(arg2)));
        else if (arg_num == 2) symbols.insert(std::make_pair(static_cast<llvm::Value*>(&arg), Val(arg3)));
        else {
            assert(arg_num == 3);
            assert(f->getArgumentList().size() == 4);
            assert(f->getArgumentList().back().getType() == g.llvm_value_type_ptr->getPointerTo());
            symbols.insert(std::make_pair(static_cast<llvm::Value*>(&arg), Val((int64_t)args)));
            //printf("loading %%4 with %p\n", (void*)args);
            break;
        }
    }

    llvm::BasicBlock *prevblock = NULL;
    llvm::BasicBlock *curblock = &f->getEntryBlock();


    while (true) {
        for (llvm::Instruction &_inst : *curblock) {
            llvm::Instruction *inst = &_inst;

            if (VERBOSITY("interpreter") >= 2) {
                printf("executing in %s: ", f->getName().data());
                fflush(stdout);
                inst->dump();
                //f->dump();
            }

#define SET(v) set(symbols, inst, (v))
            if (llvm::LoadInst *li = llvm::dyn_cast<llvm::LoadInst>(inst)) {
                llvm::Value *ptr = li->getOperand(0);
                Val v = fetch(ptr, dl, symbols);
                //printf("loading from %p\n", v.o);

                if (width(li, dl) == 1) {
                    Val r = Val(*(bool*)v.o);
                    SET(r);
                    continue;
                } else if (width(li, dl) == 8) {
                    Val r = Val(*(int64_t*)v.o);
                    SET(r);
                    continue;
                } else {
                    li->dump();
                    RELEASE_ASSERT(0, "");
                }
            } else if (llvm::StoreInst *si = llvm::dyn_cast<llvm::StoreInst>(inst)) {
                llvm::Value *val = si->getOperand(0);
                llvm::Value *ptr = si->getOperand(1);
                Val v = fetch(val, dl, symbols);
                Val p = fetch(ptr, dl, symbols);

                //printf("storing %lx at %lx\n", v.n, p.n);

                if (width(val, dl) == 1) {
                    *(bool*)p.o = v.b;
                    continue;
                } else if (width(val, dl) == 8) {
                    *(int64_t*)p.o = v.n;
                    continue;
                } else {
                    si->dump();
                    RELEASE_ASSERT(0, "");
                }
            } else if (llvm::CmpInst *ci = llvm::dyn_cast<llvm::CmpInst>(inst)) {
                assert(ci->getType() == g.i1);

                Val a0 = fetch(ci->getOperand(0), dl, symbols);
                Val a1 = fetch(ci->getOperand(1), dl, symbols);
                llvm::CmpInst::Predicate pred = ci->getPredicate();
                switch (pred) {
                    case llvm::CmpInst::ICMP_EQ:
                        SET(a0.n == a1.n);
                        continue;
                    case llvm::CmpInst::ICMP_NE:
                        SET(a0.n != a1.n);
                        continue;
                    case llvm::CmpInst::ICMP_SLT:
                        SET(a0.n < a1.n);
                        continue;
                    case llvm::CmpInst::ICMP_SLE:
                        SET(a0.n <= a1.n);
                        continue;
                    case llvm::CmpInst::ICMP_SGT:
                        SET(a0.n > a1.n);
                        continue;
                    case llvm::CmpInst::ICMP_SGE:
                        SET(a0.n >= a1.n);
                        continue;
                    case llvm::CmpInst::FCMP_OEQ:
                        SET(a0.d == a1.d);
                        continue;
                    case llvm::CmpInst::FCMP_UNE:
                        SET(a0.d != a1.d);
                        continue;
                    case llvm::CmpInst::FCMP_OLT:
                        SET(a0.d < a1.d);
                        continue;
                    case llvm::CmpInst::FCMP_OLE:
                        SET(a0.d <= a1.d);
                        continue;
                    case llvm::CmpInst::FCMP_OGT:
                        SET(a0.d > a1.d);
                        continue;
                    case llvm::CmpInst::FCMP_OGE:
                        SET(a0.d >= a1.d);
                        continue;
                    default:
                        ci->dump();
                        RELEASE_ASSERT(0, "");
                }
                continue;
            } else if (llvm::BinaryOperator *bo = llvm::dyn_cast<llvm::BinaryOperator>(inst)) {
                if (bo->getOperand(0)->getType() == g.i64 || bo->getOperand(0)->getType() == g.i1) {
                    //assert(bo->getOperand(0)->getType() == g.i64);
                    //assert(bo->getOperand(1)->getType() == g.i64);

                    Val a0 = fetch(bo->getOperand(0), dl, symbols);
                    Val a1 = fetch(bo->getOperand(1), dl, symbols);
                    llvm::Instruction::BinaryOps opcode = bo->getOpcode();
                    switch (opcode) {
                        case llvm::Instruction::Add:
                            SET(a0.n + a1.n);
                            continue;
                        case llvm::Instruction::And:
                            SET(a0.n & a1.n);
                            continue;
                        case llvm::Instruction::AShr:
                            SET(a0.n >> a1.n);
                            continue;
                        case llvm::Instruction::Mul:
                            SET(a0.n * a1.n);
                            continue;
                        case llvm::Instruction::Or:
                            SET(a0.n | a1.n);
                            continue;
                        case llvm::Instruction::Shl:
                            SET(a0.n << a1.n);
                            continue;
                        case llvm::Instruction::Sub:
                            SET(a0.n - a1.n);
                            continue;
                        case llvm::Instruction::Xor:
                            SET(a0.n ^ a1.n);
                            continue;
                        default:
                            bo->dump();
                            RELEASE_ASSERT(0, "");
                    }
                    continue;
                } else if (bo->getOperand(0)->getType() == g.double_) {
                    //assert(bo->getOperand(0)->getType() == g.i64);
                    //assert(bo->getOperand(1)->getType() == g.i64);

                    double lhs = fetch(bo->getOperand(0), dl, symbols).d;
                    double rhs = fetch(bo->getOperand(1), dl, symbols).d;
                    llvm::Instruction::BinaryOps opcode = bo->getOpcode();
                    switch (opcode) {
                        case llvm::Instruction::FAdd:
                            SET(lhs + rhs);
                            continue;
                        case llvm::Instruction::FMul:
                            SET(lhs * rhs);
                            continue;
                        case llvm::Instruction::FSub:
                            SET(lhs - rhs);
                            continue;
                        default:
                            bo->dump();
                            RELEASE_ASSERT(0, "");
                    }
                    continue;
                } else {
                    bo->dump();
                    RELEASE_ASSERT(0, "");
                }
            } else if (llvm::GetElementPtrInst *gep = llvm::dyn_cast<llvm::GetElementPtrInst>(inst)) {
Пример #7
0
	 // mutators
	 bool insert(const Symbol& symbol) {
	    auto result =
	       symbols.insert(SymMap::value_type(symbol.get_name(), symbol));
	    return result.second;
	 }
Пример #8
0
Box* interpretFunction(llvm::Function* f, int nargs, Box* closure, Box* generator, Box* arg1, Box* arg2, Box* arg3,
                       Box** args) {
    assert(f);

#ifdef TIME_INTERPRETS
    Timer _t("to interpret", 1000000);
    long this_us = 0;
#endif

    static StatCounter interpreted_runs("interpreted_runs");
    interpreted_runs.log();

    llvm::DataLayout dl(f->getParent());

    // f->dump();
    // assert(nargs == f->getArgumentList().size());

    SymMap symbols;

    void* frame_ptr = __builtin_frame_address(0);
    root_stack_set.get()->push_back(&symbols);
    UnregisterHelper helper(frame_ptr);

    int arg_num = -1;
    int closure_indicator = closure ? 1 : 0;
    int generator_indicator = generator ? 1 : 0;
    int arg_offset = closure_indicator + generator_indicator;
    for (llvm::Argument& arg : f->args()) {
        arg_num++;

        if (arg_num == 0 && closure)
            symbols.insert(std::make_pair(static_cast<llvm::Value*>(&arg), Val(closure)));
        else if ((arg_num == 0 || (arg_num == 1 && closure)) && generator)
            symbols.insert(std::make_pair(static_cast<llvm::Value*>(&arg), Val(generator)));
        else if (arg_num == 0 + arg_offset)
            symbols.insert(std::make_pair(static_cast<llvm::Value*>(&arg), Val(arg1)));
        else if (arg_num == 1 + arg_offset)
            symbols.insert(std::make_pair(static_cast<llvm::Value*>(&arg), Val(arg2)));
        else if (arg_num == 2 + arg_offset)
            symbols.insert(std::make_pair(static_cast<llvm::Value*>(&arg), Val(arg3)));
        else {
            assert(arg_num == 3 + arg_offset);
            assert(f->getArgumentList().size() == 4 + arg_offset);
            assert(f->getArgumentList().back().getType() == g.llvm_value_type_ptr->getPointerTo());
            symbols.insert(std::make_pair(static_cast<llvm::Value*>(&arg), Val((int64_t)args)));
            // printf("loading %%4 with %p\n", (void*)args);
            break;
        }
    }

    llvm::BasicBlock* prevblock = NULL;
    llvm::BasicBlock* curblock = &f->getEntryBlock();

    // The symbol table at the end of the previous BB
    // This is important for the following case:
    // %a = phi [0, %l1], [1, %l2]
    // %b = phi [0, %l1], [%a, %l2]
    // The reference to %a in the definition of %b resolves to the *previous* value of %a,
    // not the value of %a that we just set in the phi.
    SymMap prev_symbols;

    struct {
        Box* exc_obj;
        int64_t exc_selector;
    } landingpad_value;

    while (true) {
        for (llvm::Instruction& _inst : *curblock) {
            llvm::Instruction* inst = &_inst;
            cur_instruction_map[frame_ptr] = inst;

            if (VERBOSITY("interpreter") >= 2) {
                printf("executing in %s: ", f->getName().data());
                fflush(stdout);
                inst->dump();
                // f->dump();
            }

#define SET(v) set(symbols, inst, (v))

            if (llvm::LandingPadInst* lpad = llvm::dyn_cast<llvm::LandingPadInst>(inst)) {
                SET((intptr_t)&landingpad_value);
                continue;
            } else if (llvm::ExtractValueInst* ev = llvm::dyn_cast<llvm::ExtractValueInst>(inst)) {
                Val r = fetch(ev->getAggregateOperand(), dl, symbols);
                llvm::ArrayRef<unsigned> indexes = ev->getIndices();

#ifndef NDEBUG
                assert(indexes.size() == 1);
                llvm::Type* t = llvm::ExtractValueInst::getIndexedType(ev->getAggregateOperand()->getType(), indexes);
                assert(width(t, dl) == 8);
#endif

                int64_t* ptr = (int64_t*)r.n;
                int64_t val = ptr[indexes[0]];
                SET(val);
                continue;
            } else if (llvm::LoadInst* li = llvm::dyn_cast<llvm::LoadInst>(inst)) {
                llvm::Value* ptr = li->getOperand(0);
                Val v = fetch(ptr, dl, symbols);
                // printf("loading from %p\n", v.o);

                if (width(li, dl) == 1) {
                    Val r = Val(*(bool*)v.o);
                    SET(r);
                    continue;
                } else if (width(li, dl) == 8) {
                    Val r = Val(*(int64_t*)v.o);
                    SET(r);
                    continue;
                } else {
                    li->dump();
                    RELEASE_ASSERT(0, "");
                }
            } else if (llvm::StoreInst* si = llvm::dyn_cast<llvm::StoreInst>(inst)) {
                llvm::Value* val = si->getOperand(0);
                llvm::Value* ptr = si->getOperand(1);
                Val v = fetch(val, dl, symbols);
                Val p = fetch(ptr, dl, symbols);

                // printf("storing %lx at %lx\n", v.n, p.n);

                if (width(val, dl) == 1) {
                    *(bool*)p.o = v.b;
                    continue;
                } else if (width(val, dl) == 8) {
                    *(int64_t*)p.o = v.n;
                    continue;
                } else {
                    si->dump();
                    RELEASE_ASSERT(0, "");
                }
            } else if (llvm::CmpInst* ci = llvm::dyn_cast<llvm::CmpInst>(inst)) {
                assert(ci->getType() == g.i1);

                Val a0 = fetch(ci->getOperand(0), dl, symbols);
                Val a1 = fetch(ci->getOperand(1), dl, symbols);
                llvm::CmpInst::Predicate pred = ci->getPredicate();
                switch (pred) {
                    case llvm::CmpInst::ICMP_EQ:
                        SET(a0.n == a1.n);
                        continue;
                    case llvm::CmpInst::ICMP_NE:
                        SET(a0.n != a1.n);
                        continue;
                    case llvm::CmpInst::ICMP_SLT:
                        SET(a0.n < a1.n);
                        continue;
                    case llvm::CmpInst::ICMP_SLE:
                        SET(a0.n <= a1.n);
                        continue;
                    case llvm::CmpInst::ICMP_SGT:
                        SET(a0.n > a1.n);
                        continue;
                    case llvm::CmpInst::ICMP_SGE:
                        SET(a0.n >= a1.n);
                        continue;
                    case llvm::CmpInst::FCMP_OEQ:
                        SET(a0.d == a1.d);
                        continue;
                    case llvm::CmpInst::FCMP_UNE:
                        SET(a0.d != a1.d);
                        continue;
                    case llvm::CmpInst::FCMP_OLT:
                        SET(a0.d < a1.d);
                        continue;
                    case llvm::CmpInst::FCMP_OLE:
                        SET(a0.d <= a1.d);
                        continue;
                    case llvm::CmpInst::FCMP_OGT:
                        SET(a0.d > a1.d);
                        continue;
                    case llvm::CmpInst::FCMP_OGE:
                        SET(a0.d >= a1.d);
                        continue;
                    default:
                        ci->dump();
                        RELEASE_ASSERT(0, "");
                }
                continue;
            } else if (llvm::BinaryOperator* bo = llvm::dyn_cast<llvm::BinaryOperator>(inst)) {
                if (bo->getOperand(0)->getType() == g.i64 || bo->getOperand(0)->getType() == g.i1) {
                    // assert(bo->getOperand(0)->getType() == g.i64);
                    // assert(bo->getOperand(1)->getType() == g.i64);

                    Val a0 = fetch(bo->getOperand(0), dl, symbols);
                    Val a1 = fetch(bo->getOperand(1), dl, symbols);
                    llvm::Instruction::BinaryOps opcode = bo->getOpcode();
                    switch (opcode) {
                        case llvm::Instruction::Add:
                            SET(a0.n + a1.n);
                            continue;
                        case llvm::Instruction::And:
                            SET(a0.n & a1.n);
                            continue;
                        case llvm::Instruction::AShr:
                            SET(a0.n >> a1.n);
                            continue;
                        case llvm::Instruction::Mul:
                            SET(a0.n * a1.n);
                            continue;
                        case llvm::Instruction::Or:
                            SET(a0.n | a1.n);
                            continue;
                        case llvm::Instruction::Shl:
                            SET(a0.n << a1.n);
                            continue;
                        case llvm::Instruction::Sub:
                            SET(a0.n - a1.n);
                            continue;
                        case llvm::Instruction::Xor:
                            SET(a0.n ^ a1.n);
                            continue;
                        default:
                            bo->dump();
                            RELEASE_ASSERT(0, "");
                    }
                    continue;
                } else if (bo->getOperand(0)->getType() == g.double_) {
                    // assert(bo->getOperand(0)->getType() == g.i64);
                    // assert(bo->getOperand(1)->getType() == g.i64);

                    double lhs = fetch(bo->getOperand(0), dl, symbols).d;
                    double rhs = fetch(bo->getOperand(1), dl, symbols).d;
                    llvm::Instruction::BinaryOps opcode = bo->getOpcode();
                    switch (opcode) {
                        case llvm::Instruction::FAdd:
                            SET(lhs + rhs);
                            continue;
                        case llvm::Instruction::FMul:
                            SET(lhs * rhs);
                            continue;
                        case llvm::Instruction::FSub:
                            SET(lhs - rhs);
                            continue;
                        default:
                            bo->dump();
                            RELEASE_ASSERT(0, "");
                    }
                    continue;
                } else {
                    bo->dump();
                    RELEASE_ASSERT(0, "");
                }
            } else if (llvm::GetElementPtrInst* gep = llvm::dyn_cast<llvm::GetElementPtrInst>(inst)) {