コード例 #1
0
ファイル: JoanaConverter.java プロジェクト: serialcake/joana
  private static PDGNode[] getAllNodesSorted(SDGBuilder builder, IProgressMonitor progress)
      throws CancelException {
    ArrayList<PDGNode> nodes = new ArrayList<PDGNode>();

    for (PDG pdg : builder.getAllPDGs()) {
      for (PDGNode node : pdg.vertexSet()) {
        if (node.getPdgId() == pdg.getId()) {
          nodes.add(node);
        }
      }
    }

    PDGNode[] copy = new PDGNode[nodes.size()];
    copy = nodes.toArray(copy);

    progress.worked(1);
    MonitorUtil.throwExceptionIfCanceled(progress);

    Arrays.sort(
        copy,
        new Comparator<PDGNode>() {
          public int compare(PDGNode o1, PDGNode o2) {
            return o1.getId() - o2.getId();
          }
        });
    progress.worked(1);
    MonitorUtil.throwExceptionIfCanceled(progress);

    return copy;
  }
コード例 #2
0
ファイル: JoanaConverter.java プロジェクト: serialcake/joana
  private static void addEdgesForNode(
      SDG sdg, PDGNode node, Map<PDGNode, SDGNode> pdg2sdg, SDGBuilder b) {
    PDG pdg = b.getPDGforId(node.getPdgId());
    SDGNode from = pdg2sdg.get(node);

    if (!pdg.containsVertex(node)) {
      throw new IllegalStateException();
    }

    for (PDGEdge edge : pdg.outgoingEdgesOf(node)) {
      SDGNode to = pdg2sdg.get(edge.to);
      SDGEdge sdgEdge = createEdge(from, to, edge.kind, edge.getLabel());
      sdg.addEdge(from, to, sdgEdge);
    }
  }
コード例 #3
0
  private void createActualInAndOut(
      final Map<PDGNode, Node> pdg2cfg,
      final ModRefCandidates modref,
      final PDG pdg,
      final CallGraph cg) {
    for (final PDGNode call : pdg.getCalls()) {
      final Node cn = pdg2cfg.get(call);
      final SSAInvokeInstruction invk = (SSAInvokeInstruction) pdg.getInstruction(call);
      final CallSiteReference site = invk.getCallSite();

      final Set<ModRefFieldCandidate> modRefCands = new HashSet<ModRefFieldCandidate>();

      for (final CGNode tgt : cg.getPossibleTargets(pdg.cgNode, site)) {
        final InterProcCandidateModel tgtModRef = modref.getCandidates(tgt);

        if (tgtModRef == null) {
          continue;
        }

        for (final ModRefFieldCandidate c : tgtModRef) {
          modRefCands.add(c);
        }
      }

      final List<ModRefFieldCandidate> refs = new LinkedList<ModRefFieldCandidate>();
      final List<ModRefFieldCandidate> mods = new LinkedList<ModRefFieldCandidate>();

      for (final ModRefFieldCandidate c : modRefCands) {
        if (c.isMod()) {
          mods.add(c);
        }

        if (c.isRef()) {
          refs.add(c);
        }
      }

      addNodesBefore(cn, refs, Node.Kind.ACTUAL_IN);
      addNodesAfter(cn, mods, Node.Kind.ACTUAL_OUT);
    }
  }
コード例 #4
0
  private void createInitalNodesAndFlow(
      final Map<PDGNode, Node> pdg2cfg, final ModRefCandidates modref, final PDG pdg) {
    final Node nEntry = createNOPNode(pdg.entry);
    this.entry = nEntry;
    pdg2cfg.put(pdg.entry, nEntry);
    final Node nExit = createNOPNode(pdg.exit);
    this.exit = nExit;
    pdg2cfg.put(pdg.exit, nExit);

    for (final PDGField fref : pdg.getFieldReads()) {
      if (!fref.field.isStatic()) {
        final SSAInstruction instr = pdg.getInstruction(fref.node);
        final ModRefFieldCandidate refCand = modref.createRefCandidate(pdg.cgNode, instr);
        final Node n = createNode(refCand, fref.accfield, Node.Kind.READ);
        pdg2cfg.put(fref.accfield, n);
      }
    }

    for (final PDGField fmod : pdg.getFieldWrites()) {
      if (!fmod.field.isStatic()) {
        final SSAInstruction instr = pdg.getInstruction(fmod.node);
        final ModRefFieldCandidate refCand = modref.createModCandidate(pdg.cgNode, instr);
        final Node n = createNode(refCand, fmod.accfield, Node.Kind.WRITE);
        pdg2cfg.put(fmod.accfield, n);
      }
    }

    for (final PDGNode pn : pdg.vertexSet()) {
      if (pn.getPdgId() == pdg.getId() && !pdg2cfg.containsKey(pn)) {
        final Node n = createNOPNode(pn);
        pdg2cfg.put(pn, n);
      }
    }

    for (final PDGEdge e : pdg.edgeSet()) {
      if (e.kind == PDGEdge.Kind.CONTROL_FLOW || e.kind == PDGEdge.Kind.CONTROL_FLOW_EXC) {
        final Node from = pdg2cfg.get(e.from);
        final Node to = pdg2cfg.get(e.to);
        addEdge(from, to);
      }
    }
  }
コード例 #5
0
ファイル: JoanaConverter.java プロジェクト: serialcake/joana
  private static SDGNode convertNode(SDGBuilder sdg, PDGNode node) {
    Operation op = null;
    Kind kind = null;
    int[] allocNodes = null;

    switch (node.getKind()) {
      case ACTUAL_IN:
        op = Operation.ACTUAL_IN;
        kind = Kind.ACTUAL_IN;
        break;
      case ACTUAL_OUT:
        op = Operation.ACTUAL_OUT;
        kind = Kind.ACTUAL_OUT;
        break;
      case CALL:
        op = Operation.CALL;
        kind = Kind.CALL;
        if (sdg.cfg.computeInterference) {
          TIntSet allocNodesAsSet = sdg.getAllocationNodes(node);
          if (allocNodesAsSet != null) {
            allocNodes = allocNodesAsSet.toArray();
          }
        }
        break;
      case ENTRY:
        op = Operation.ENTRY;
        kind = Kind.ENTRY;
        break;
      case EXIT:
        op = Operation.EXIT;
        kind = Kind.EXIT;
        break;
      case EXPRESSION:
        op = Operation.ASSIGN;
        kind = Kind.EXPRESSION;
        break;
      case FOLDED:
        op = Operation.COMPOUND;
        kind = Kind.FOLDED;
        break;
      case FORMAL_IN:
        op = Operation.FORMAL_IN;
        kind = Kind.FORMAL_IN;
        break;
      case FORMAL_OUT:
        op = Operation.FORMAL_OUT;
        kind = Kind.FORMAL_OUT;
        break;
      case HREAD:
        op = Operation.REFERENCE;
        kind = Kind.EXPRESSION;
        break;
      case HWRITE:
        op = Operation.MODIFY;
        kind = Kind.EXPRESSION;
        break;
      case JOIN:
        op = Operation.COMPOUND;
        kind = Kind.JOIN;
        break;
      case NEW:
        op = Operation.DECLARATION;
        kind = Kind.NORMAL;
        break;
      case NORMAL:
        op = Operation.COMPOUND;
        kind = Kind.NORMAL;
        break;
      case PHI:
        op = Operation.ASSIGN;
        kind = Kind.EXPRESSION;
        break;
      case PREDICATE:
        op = Operation.IF;
        kind = Kind.PREDICATE;
        break;
      case SYNCHRONIZATION:
        op = Operation.MONITOR;
        kind = Kind.SYNCHRONIZATION;
        break;
      default:
        throw new IllegalStateException("Unknown node kind: " + node.getKind().name());
    }
    SourceLocation sloc = node.getSourceLocation();

    SDGNode sn =
        new SecurityNode(
            node.getId(),
            op,
            node.getLabel(),
            node.getPdgId(),
            node.getType(),
            sloc.getSourceFile(),
            sloc.getStartRow(),
            sloc.getStartColumn(),
            sloc.getEndRow(),
            sloc.getEndColumn(),
            node.getBytecodeName(),
            node.getBytecodeIndex());

    if (node.getKind() == PDGNode.Kind.ENTRY) {
      PDG pdg = sdg.getPDGforId(node.getPdgId());
      IMethod im = pdg.getMethod();

      if (im != null) {
        IClass cls = im.getDeclaringClass();

        if (cls != null) {
          String clsLoader = cls.getClassLoader().toString();
          sn.setClassLoader(clsLoader);
        }
      }
    }

    if (allocNodes != null) {
      sn.setAllocationSites(allocNodes);
    }

    if (node.getAliasDataSources() != null) {
      sn.setAliasDataSources(node.getAliasDataSources());
    }

    assert sn.getKind() == kind;

    return sn;
  }
コード例 #6
0
  private void run(IProgressMonitor progress) throws CancelException {
    final Map<PDGNode, PDGNode[]> entry2out = new HashMap<PDGNode, PDGNode[]>();

    // add out nodes for each non-primitive parameter
    for (final PDG pdg : sdg.getAllPDGs()) {
      // primitive types nodes are null
      final PDGNode[] formOuts = new PDGNode[pdg.params.length];

      for (int i = 0; i < pdg.params.length; i++) {
        final PDGNode formIn = pdg.params[i];
        final TypeReference type = pdg.getParamType(i);

        if (createOutputParamFor(type)) {
          final PDGNode formOut =
              pdg.addOutputFieldChildTo(
                  pdg.entry,
                  formIn.getLabel(),
                  formIn.getBytecodeName(),
                  formIn.getBytecodeIndex(),
                  formIn.getTypeRef());
          formOuts[i] = formOut;
        }
      }

      entry2out.put(pdg.entry, formOuts);

      for (final PDGNode call : pdg.getCalls()) {
        final PDGNode[] actIns = pdg.getParamIn(call);
        final PDGNode[] actOuts = new PDGNode[actIns.length];

        for (int i = 0; i < actIns.length; i++) {
          final PDGNode actIn = actIns[i];
          final TypeReference type = pdg.getParamType(call, i);

          if (createOutputParamFor(type)) {
            final PDGNode actOut =
                pdg.addOutputFieldChildTo(
                    call,
                    actIn.getLabel(),
                    actIn.getBytecodeName(),
                    actIn.getBytecodeIndex(),
                    actIn.getTypeRef());
            actOuts[i] = actOut;
          }
        }

        entry2out.put(call, actOuts);
      }
    }

    // connect form-outs of called procedures with act-outs
    for (final PDG pdg : sdg.getAllPDGs()) {
      for (final PDGNode call : pdg.getCalls()) {
        final PDGNode[] actOuts = entry2out.get(call);
        assert actOuts != null;

        for (final PDGEdge out : pdg.outgoingEdgesOf(call)) {
          if (out.kind == PDGEdge.Kind.CALL_STATIC || out.kind == PDGEdge.Kind.CALL_VIRTUAL) {
            final PDGNode calleeEntry = out.to;
            final PDGNode[] formOuts = entry2out.get(calleeEntry);
            final PDG callee = sdg.getPDGforId(calleeEntry.getPdgId());
            assert formOuts != null;
            assert actOuts.length == formOuts.length;

            for (int i = 0; i < actOuts.length; i++) {
              final PDGNode actOut = actOuts[i];
              if (actOut != null) {
                // primitive type (and immutable type) params have no act out
                callee.addVertex(actOut);
                final PDGNode formOut = formOuts[i];

                if (formOut != null) {
                  callee.addEdge(formOut, actOut, PDGEdge.Kind.PARAMETER_OUT);
                }
              }
            }
          }
        }
      }
    }

    // collect reachable points-to elements for reachable fields for each parameter
    for (final PDG pdg : sdg.getAllPDGs()) {
      final Map<PDGNode, OrdinalSet<InstanceKey>> node2ptsMod =
          new HashMap<PDGNode, OrdinalSet<InstanceKey>>();
      final Map<PDGNode, OrdinalSet<InstanceKey>> node2ptsRef =
          new HashMap<PDGNode, OrdinalSet<InstanceKey>>();

      final IR ir = pdg.cgNode.getIR();

      if (ir == null) {
        continue;
      }

      for (int i = 0; i < pdg.params.length; i++) {
        if (!pdg.getParamType(i).isPrimitiveType()) {
          final PDGNode formIn = pdg.params[i];
          final int ssaVar = ir.getParameter(i);

          if (ssaVar >= 0) {
            final OrdinalSet<InstanceKey> ptsSet = findReachableInstances(pdg.cgNode, ssaVar);
            node2ptsMod.put(formIn, ptsSet);
          }
        }
      }

      final PDGNode[] formOuts = entry2out.get(pdg.entry);
      for (int i = 0; i < formOuts.length; i++) {
        final PDGNode formOut = formOuts[i];

        if (formOut != null) {
          final PDGNode formIn = pdg.params[i];
          final OrdinalSet<InstanceKey> ptsSet = node2ptsMod.get(formIn);
          node2ptsRef.put(formOut, ptsSet);
        }
      }

      final TypeReference retType = pdg.getMethod().getReturnType();
      if (retType != TypeReference.Void && !retType.isPrimitiveType()) {
        for (final PDGNode retNode : pdg.getReturns()) {
          final SSAReturnInstruction ret = (SSAReturnInstruction) pdg.getInstruction(retNode);
          final int ssaVar = ret.getResult();
          final OrdinalSet<InstanceKey> ptsSet = findReachableInstances(pdg.cgNode, ssaVar);

          node2ptsRef.put(retNode, ptsSet);
        }
      }

      for (final PDGNode call : pdg.getCalls()) {
        final PDGNode[] actIns = pdg.getParamIn(call);

        final SSAAbstractInvokeInstruction invk =
            (SSAAbstractInvokeInstruction) pdg.getInstruction(call);

        for (int i = 0; i < actIns.length; i++) {

          if (!pdg.getParamType(call, i).isPrimitiveType()) {
            final PDGNode actIn = actIns[i];
            final int ssaVar = invk.getUse(i);

            if (ssaVar >= 0) {
              final OrdinalSet<InstanceKey> ptsSet = findReachableInstances(pdg.cgNode, ssaVar);
              node2ptsRef.put(actIn, ptsSet);
            }
          }
        }

        final PDGNode actOuts[] = entry2out.get(call);
        for (int i = 0; i < actIns.length; i++) {
          final PDGNode actOut = actOuts[i];

          if (actOut != null) {
            final PDGNode actIn = actIns[i];
            final OrdinalSet<InstanceKey> ptsSet = node2ptsRef.get(actIn);
            node2ptsMod.put(actOut, ptsSet);
          }
        }

        final TypeReference callRetType = invk.getDeclaredTarget().getReturnType();
        if (callRetType != TypeReference.Void && !callRetType.isPrimitiveType()) {
          final int ssaVar = invk.getReturnValue(0);
          final OrdinalSet<InstanceKey> ptsSet = findReachableInstances(pdg.cgNode, ssaVar);
          final PDGNode retNode = pdg.getReturnOut(call);
          node2ptsMod.put(retNode, ptsSet);
        }
      }

      // create mod/ref sets for get & set instructions
      for (final PDGField read : pdg.getFieldReads()) {
        if (!read.field.isStatic()) {
          if (read.field.isArray()) {
            final SSAArrayLoadInstruction ali =
                (SSAArrayLoadInstruction) pdg.getInstruction(read.node);
            final int ssaVarBase = ali.getArrayRef();

            if (ssaVarBase >= 0) {
              final OrdinalSet<InstanceKey> ptsSet = pointsToArrayField(pdg.cgNode, ssaVarBase);
              node2ptsRef.put(read.accfield, ptsSet);
            }
          } else {
            final SSAGetInstruction get = (SSAGetInstruction) pdg.getInstruction(read.node);
            final int ssaVarBase = get.getRef();

            if (ssaVarBase >= 0) {
              final IField field = sdg.getClassHierarchy().resolveField(get.getDeclaredField());
              final OrdinalSet<InstanceKey> ptsSet =
                  pointsToObjectField(pdg.cgNode, ssaVarBase, field);
              node2ptsRef.put(read.accfield, ptsSet);
            }
          }

          //					final SSAInstruction get = pdg.getInstruction(read.node);
          //					final int ssaVar = get.getDef();
          //					if (ssaVar >= 0) {
          //						final OrdinalSet<InstanceKey> ptsSet = findReachableInstances(pdg.cgNode, ssaVar);
          //						node2ptsRef.put(read.accfield, ptsSet);
          //					}
        }
      }

      for (final PDGField write : pdg.getFieldWrites()) {
        if (!write.field.isStatic()) {
          if (write.field.isArray()) {
            final SSAArrayStoreInstruction asi =
                (SSAArrayStoreInstruction) pdg.getInstruction(write.node);
            final int ssaVarBase = asi.getArrayRef();

            if (ssaVarBase >= 0) {
              final OrdinalSet<InstanceKey> ptsSet = pointsToArrayField(pdg.cgNode, ssaVarBase);
              node2ptsMod.put(write.accfield, ptsSet);
            }
          } else {
            final SSAPutInstruction put = (SSAPutInstruction) pdg.getInstruction(write.node);
            final int ssaVarBase = put.getRef();

            if (ssaVarBase >= 0) {
              final IField field = sdg.getClassHierarchy().resolveField(put.getDeclaredField());
              final OrdinalSet<InstanceKey> ptsSet =
                  pointsToObjectField(pdg.cgNode, ssaVarBase, field);
              node2ptsMod.put(write.accfield, ptsSet);
            }
          }
        }
      }

      // add data flow for each pdg
      FlatHeapParamsDataFlow.compute(
          pdg,
          node2ptsMod,
          node2ptsRef,
          (sdg.cfg.accessPath ? PDGEdge.Kind.DATA_ALIAS : PDGEdge.Kind.DATA_HEAP),
          progress);
    }
  }