Пример #1
0
    void processCommand(std::vector< std::string > &args)
    {
/*      printf("PROCESS: ");
      for(int i = 0; i < args.size(); i ++) {
        printf("[%s] ", args[i].c_str());
      }
      printf("\n");*/
      if(args.empty()) {
        *mAction = BNBActions::ERASE;
      } else if(args[0] == "forward")  {
        *mAction = BNBActions::FORWARD | BNBActions::ERASE;
        eraseCommand();
      } else if(args[0] == "drop")  {
        *mAction = BNBActions::DROP | BNBActions::ERASE;
        eraseCommand();
      } else if(args[0] == "var") {
        BNB_ASSERT(args.size() == 2);
        processVar(args[1]);
      } else if(args[0] == "set") {
        BNB_ASSERT(args.size() == 3);
        processAssign(args[1], args[2]);
      } else if(args[0] == "inc") {
        BNB_ASSERT(args.size() == 3);
        processInc(args[1], args[2]);
      } else if(args[0] == "cat") {
        BNB_ASSERT(args.size() == 3);
        processCat(args[1], args[2]);
      } else if(args[0] == "wait") {
        BNB_ASSERT(args.size() == 4);        
        processWait(args[1], args[2], args[3]);
      } else if(args[0] == "echo") {
        processEcho(args);
      } else if(args[0] == "erase") {
        *mAction = BNBActions::ERASE;
        eraseCommand();        
      } else if(args[0] == "save") {
        processSave(args[1], args[2]);
      } else if(args[0] == "append") {
        processAppend(args[1], args[2]);
      } else if(args[0] == "load") {
        processLoad(args[1], args[2]);
      } else if(args[0] == "mkdir") {
        processMkdir(args[1]);
      } else if(args[0] == "skip") {
        eraseCommand();
      } else if(args[0] == "exec") {
        processExec(args[1]);
      } else if(args[0] == "exit") {
        *mAction = BNBActions::EXIT;
        eraseCommand();
      } else {
        printf("%s\n", args[0].c_str());
        BNB_ERROR_REPORT("Unrecognized command");
      }
    }
Пример #2
0
bool PointerAnalysis::processNode(PSNode *node)
{
    bool changed = false;
    std::vector<MemoryObject *> objects;

#ifdef DEBUG_ENABLED
    size_t prev_size = node->pointsTo.size();
#endif

    switch(node->type) {
        case LOAD:
            changed |= processLoad(node);
            break;
        case STORE:
            for (const Pointer& ptr : node->getOperand(1)->pointsTo) {
                PSNode *target = ptr.target;
                assert(target && "Got nullptr as target");

                if (ptr.isNull())
                    continue;

                objects.clear();
                getMemoryObjects(node, ptr, objects);
                for (MemoryObject *o : objects) {
                    for (const Pointer& to : node->getOperand(0)->pointsTo)
                        changed |= o->addPointsTo(ptr.offset, to);
                }
            }
            break;
        case GEP:
            for (const Pointer& ptr : node->getOperand(0)->pointsTo) {
                uint64_t new_offset;
                if (ptr.offset.isUnknown() || node->offset.isUnknown())
                    // set it like this to avoid overflow when adding
                    new_offset = UNKNOWN_OFFSET;
                else
                    new_offset = *ptr.offset + *node->offset;

                // in the case the memory has size 0, then every pointer
                // will have unknown offset with the exception that it points
                // to the begining of the memory - therefore make 0 exception
                if ((new_offset == 0 || new_offset < ptr.target->getSize())
                    && new_offset < max_offset)
                    changed |= node->addPointsTo(ptr.target, new_offset);
                else
                    changed |= node->addPointsToUnknownOffset(ptr.target);
            }
            break;
        case CAST:
            // cast only copies the pointers
            for (const Pointer& ptr : node->getOperand(0)->pointsTo)
                changed |= node->addPointsTo(ptr);
            break;
        case CONSTANT:
            // maybe warn? It has no sense to insert the constants into the graph.
            // On the other hand it is harmless. We can at least check if it is
            // correctly initialized 8-)
            assert(node->pointsTo.size() == 1
                   && "Constant should have exactly one pointer");
            break;
        case CALL_RETURN:
        case RETURN:
            // gather pointers returned from subprocedure - the same way
            // as PHI works
        case PHI:
            for (PSNode *op : node->operands)
                changed |= node->addPointsTo(op->pointsTo);
            break;
        case CALL_FUNCPTR:
            // call via function pointer:
            // first gather the pointers that can be used to the
            // call and if something changes, let backend take some action
            // (for example build relevant subgraph)
            for (const Pointer& ptr : node->getOperand(0)->pointsTo) {
                if (node->addPointsTo(ptr)) {
                    changed = true;

                    if (ptr.isValid()) {
                        functionPointerCall(node, ptr.target);
                    } else {
                        error(node, "Calling invalid pointer as a function!");
                        continue;
                    }
                }
            }
            break;
        case MEMCPY:
            changed |= processMemcpy(node);
            break;
        case ALLOC:
        case DYN_ALLOC:
        case FUNCTION:
            // these two always points to itself
            assert(node->doesPointsTo(node, 0));
            assert(node->pointsTo.size() == 1);
        case CALL:
        case ENTRY:
        case NOOP:
            // just no op
            break;
        default:
            assert(0 && "Unknown type");
    }

#ifdef DEBUG_ENABLED
    // the change of points-to set is not the only
    // change that can happen, so we don't use it as an
    // indicator and we use the 'changed' variable instead.
    // However, this assertion must hold:
    assert((node->pointsTo.size() == prev_size || changed)
           && "BUG: Did not set change but changed points-to sets");
#endif

    return changed;
}