示例#1
0
 @Test
 public void testSystemProperties()
     throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
   AnalysisScope scope =
       CallGraphTestUtil.makeJ2SEAnalysisScope(
           TestConstants.WALA_TESTDATA, CallGraphTestUtil.REGRESSION_EXCLUSIONS);
   ClassHierarchy cha = ClassHierarchy.make(scope);
   Iterable<Entrypoint> entrypoints =
       com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(
           scope, cha, "LstaticInit/TestSystemProperties");
   AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
   SSAPropagationCallGraphBuilder builder =
       Util.makeZeroCFABuilder(options, new AnalysisCache(), cha, scope);
   CallGraph cg = builder.makeCallGraph(options);
   for (CGNode n : cg) {
     if (n.toString()
         .equals(
             "Node: < Application, LstaticInit/TestSystemProperties, main([Ljava/lang/String;)V > Context: Everywhere")) {
       boolean foundToCharArray = false;
       for (CGNode callee : Iterator2Iterable.make(cg.getSuccNodes(n))) {
         if (callee.getMethod().getName().toString().equals("toCharArray")) {
           foundToCharArray = true;
           break;
         }
       }
       Assert.assertTrue(foundToCharArray);
       break;
     }
   }
 }
 private void addParamEdges(LocalPointerKey pk, CGNode node) {
   // get parameter position: value number - 1?
   int paramPos = pk.getValueNumber() - 1;
   // iterate over callers
   for (CGNode caller : cg) {
     // TODO we don't need to add the graph if null is passed
     // as the argument
     addSubgraphForNode(caller);
     IR ir = caller.getIR();
     for (Iterator<CallSiteReference> iterator = ir.iterateCallSites(); iterator.hasNext(); ) {
       CallSiteReference call = iterator.next();
       if (cg.getPossibleTargets(caller, call).contains(node)) {
         SSAAbstractInvokeInstruction[] callInstrs = ir.getCalls(call);
         for (int i = 0; i < callInstrs.length; i++) {
           SSAAbstractInvokeInstruction callInstr = callInstrs[i];
           PointerKey actualPk =
               heapModel.getPointerKeyForLocal(caller, callInstr.getUse(paramPos));
           assert containsNode(actualPk);
           assert containsNode(pk);
           addEdge(pk, actualPk);
         }
       }
     }
   }
 }
 public void addSubgraphForNode(CGNode node) {
   int n = cg.getNumber(node);
   if (!cgNodesVisited.contains(n)) {
     cgNodesVisited.add(n);
     unconditionallyAddConstraintsFromNode(node);
     addNodesForParameters(node);
   }
 }
  /** @param pk value being def'fed by a call instruction (either normal or exceptional) */
  private void addReturnEdges(LocalPointerKey pk, SSAInvokeInstruction callInstr) {
    boolean isExceptional = pk.getValueNumber() == callInstr.getException();

    // get call targets
    Collection<CGNode> possibleCallees =
        cg.getPossibleTargets(pk.getNode(), callInstr.getCallSite());
    // construct graph for each target
    for (CGNode callee : possibleCallees) {
      addSubgraphForNode(callee);
      PointerKey retVal =
          isExceptional
              ? heapModel.getPointerKeyForExceptionalReturnValue(callee)
              : heapModel.getPointerKeyForReturnValue(callee);
      assert containsNode(retVal);
      addEdge(pk, retVal);
    }
  }
  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);
    }
  }
示例#6
0
  private static List<Pair<CGNode, SSACheckCastInstruction>> findFailingCasts(
      CallGraph cg, DemandRefinementPointsTo dmp) {
    final IClassHierarchy cha = dmp.getClassHierarchy();
    List<Pair<CGNode, SSACheckCastInstruction>> failing =
        new ArrayList<Pair<CGNode, SSACheckCastInstruction>>();

    int numSafe = 0, numMightFail = 0;
    outer:
    for (Iterator<? extends CGNode> nodeIter = cg.iterator(); nodeIter.hasNext(); ) {
      CGNode node = nodeIter.next();
      TypeReference declaringClass = node.getMethod().getReference().getDeclaringClass();
      // skip library classes
      if (declaringClass.getClassLoader().equals(ClassLoaderReference.Primordial)) {
        continue;
      }
      IR ir = node.getIR();
      if (ir == null) continue;
      SSAInstruction[] instrs = ir.getInstructions();
      for (int i = 0; i < instrs.length; i++) {
        if (numSafe + numMightFail > MAX_CASTS) break outer;
        SSAInstruction instruction = instrs[i];
        if (instruction instanceof SSACheckCastInstruction) {
          SSACheckCastInstruction castInstr = (SSACheckCastInstruction) instruction;
          final TypeReference[] declaredResultTypes = castInstr.getDeclaredResultTypes();

          boolean primOnly = true;
          for (TypeReference t : declaredResultTypes) {
            if (!t.isPrimitiveType()) {
              primOnly = false;
            }
          }
          if (primOnly) {
            continue;
          }

          System.err.println("CHECKING " + castInstr + " in " + node.getMethod());
          PointerKey castedPk = heapModel.getPointerKeyForLocal(node, castInstr.getUse(0));
          Predicate<InstanceKey> castPred =
              new Predicate<InstanceKey>() {

                @Override
                public boolean test(InstanceKey ik) {
                  TypeReference ikTypeRef = ik.getConcreteType().getReference();
                  for (TypeReference t : declaredResultTypes) {
                    if (cha.isAssignableFrom(cha.lookupClass(t), cha.lookupClass(ikTypeRef))) {
                      return true;
                    }
                  }
                  return false;
                }
              };
          long startTime = System.currentTimeMillis();
          Pair<PointsToResult, Collection<InstanceKey>> queryResult =
              dmp.getPointsTo(castedPk, castPred);
          long runningTime = System.currentTimeMillis() - startTime;
          System.err.println("running time: " + runningTime + "ms");
          final FieldRefinePolicy fieldRefinePolicy =
              dmp.getRefinementPolicy().getFieldRefinePolicy();
          switch (queryResult.fst) {
            case SUCCESS:
              System.err.println("SAFE: " + castInstr + " in " + node.getMethod());
              if (fieldRefinePolicy instanceof ManualFieldPolicy) {
                ManualFieldPolicy hackedFieldPolicy = (ManualFieldPolicy) fieldRefinePolicy;
                System.err.println(hackedFieldPolicy.getHistory());
              }
              System.err.println("TRAVERSED " + dmp.getNumNodesTraversed() + " nodes");
              numSafe++;
              break;
            case NOMOREREFINE:
              if (queryResult.snd != null) {
                System.err.println(
                    "MIGHT FAIL: no more refinement possible for "
                        + castInstr
                        + " in "
                        + node.getMethod());
              } else {
                System.err.println(
                    "MIGHT FAIL: exceeded budget for " + castInstr + " in " + node.getMethod());
              }
              failing.add(Pair.make(node, castInstr));
              numMightFail++;
              break;
            case BUDGETEXCEEDED:
              System.err.println(
                  "MIGHT FAIL: exceeded budget for " + castInstr + " in " + node.getMethod());
              failing.add(Pair.make(node, castInstr));
              numMightFail++;
              break;
            default:
              Assertions.UNREACHABLE();
          }
        }
      }
      // break outer;
    }
    System.err.println("TOTAL SAFE: " + numSafe);
    System.err.println("TOTAL MIGHT FAIL: " + numMightFail);
    return failing;
  }
示例#7
0
  private static Result getOrigSDG(Config cfg, IProgressMonitor progress)
      throws IllegalArgumentException, CancelException, PDGFormatException, IOException,
          WalaException, InvalidClassFileException {
    progress.beginTask(Messages.getString("Analyzer.Task_Prepare_IR"), -1); // $NON-NLS-1$

    com.ibm.wala.ipa.callgraph.impl.Util.setNativeSpec(cfg.nativesXML);

    progress.subTask(Messages.getString("Analyzer.SubTask_Analysis_Scope")); // $NON-NLS-1$

    ClassLoader loader = cfg.getClass().getClassLoader();
    AnalysisScope scope = Util.makeAnalysisScope(cfg, loader);
    // AnalysisScopeReader.makeJavaBinaryAnalysisScope(cfg.scopeFile, cfg.classpath, null);
    progress.done();

    ClassHierarchy cha = ClassHierarchy.make(scope, progress);

    Iterable<Entrypoint> entrypoints =
        com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, cfg.mainClass);
    AnalysisOptions options = new AnalysisOptions(scope, entrypoints);
    AnalysisCache cache = new AnalysisCache();

    progress.subTask(
        Messages.getString("Analyzer.SubTask_Call_Graph_Builder") + cfg.pointsTo); // $NON-NLS-1$
    SSAPropagationCallGraphBuilder builder =
        SDGFactory.getCallGraphBuilder(cfg.pointsTo, options, cache, cha, scope);

    /**
     * Change the wala internal pointer and instancekeyfactory of the callgraph builder to our
     * adapter. So we can keep track of the created InstanceKeys and PointerKeys. This information
     * is used later on when creating subobject trees for accessed field variables.
     */
    InstanceAndPointerKeyFactoryAdapter adapter = null;
    InstanceKeyFactory ikFact = builder.getInstanceKeys();
    PointerKeyFactory pkFact = builder.getPointerKeyFactory();
    adapter = new InstanceAndPointerKeyFactoryAdapter(ikFact, pkFact);

    builder.setInstanceKeys(adapter);
    builder.setPointerKeyFactory(adapter);

    progress.done();

    progress.subTask(Messages.getString("Analyzer.SubTask_Call_Graph")); // $NON-NLS-1$
    CallGraph cg = builder.makeCallGraph(options, progress);

    if (cfg.optimizeCg >= 0) {
      CallGraphPruning opt = new CallGraphPruning(cg);
      System.out.println("Call Graph has " + cg.getNumberOfNodes() + " Nodes.");
      Set<CGNode> sopt = opt.findApplicationNodes(cfg.optimizeCg);
      cg = new PrunedCallGraph(cg, sopt);
      System.out.println("Optimized Call Graph has " + cg.getNumberOfNodes() + " Nodes.");
    }

    if (Debug.Var.DUMP_CALLGRAPH.isSet()) {
      Util.dumpCallGraph(cg, cfg.mainClass.replace('/', '.').substring(1), progress);
    }

    if (Debug.Var.DUMP_HEAP_GRAPH.isSet()) {
      PointerAnalysis pta = builder.getPointerAnalysis();
      HeapGraph hg = pta.getHeapGraph();
      Util.dumpHeapGraph(
          cfg.mainClass.replace('/', '.').substring(1) + "." + cfg.pointsTo, hg, null);
    }

    PointerAnalysis pta = builder.getPointerAnalysis();
    progress.done();

    DemandRefinementPointsTo demandPts = null;
    if (cfg.useDemandPts) {
      throw new UnsupportedOperationException();
      //		    MemoryAccessMap mam = new PABasedMemoryAccessMap(cg, builder.getPointerAnalysis());
      //			demandPts = new DemandRefinementPointsTo(cg,
      //				new ThisFilteringHeapModel(builder,cha), mam, cha, options, getStateMachineFactory());
    }

    IPointerAnalysis pts = new PointsToWrapper(demandPts, pta);

    progress.subTask(Messages.getString("Analyzer.SubTask_Search_Main")); // $NON-NLS-1$
    IMethod main =
        edu.kit.joana.deprecated.jsdg.util.Util.searchMethod(
            entrypoints, "main([Ljava/lang/String;)V"); // $NON-NLS-1$
    progress.done();

    progress.done();

    SDG sdg = SDG.create(main, cg, cache, adapter, pts, cfg, progress);
    sdg.setAnalysisScope(scope);
    sdg.setPointerAnalysis(pta);

    progress.done();

    if (Debug.Var.PRINT_FIELD_PTS_INFO.isSet()) {
      Log.info("search for field allocs called " + PDG.searchFieldAllocs + " times.");
    }

    if (Debug.Var.PRINT_UNRESOLVED_CLASSES.isSet()) {
      for (TypeReference tRef : cg.getClassHierarchy().getUnresolvedClasses()) {
        Log.warn("Could not resolve: " + Util.typeName(tRef.getName()));
      }
    }

    return new Result(null, sdg, cg, pta, null);
  }
示例#8
0
  /**
   * @param name
   * @param cg
   * @return a graph whose nodes are MethodReferences, and whose edges represent calls between
   *     MethodReferences
   * @throws IllegalArgumentException if cg is null
   */
  public static Graph<MethodReference> squashCallGraph(final String name, final CallGraph cg) {
    if (cg == null) {
      throw new IllegalArgumentException("cg is null");
    }
    final Set<MethodReference> nodes = HashSetFactory.make();
    for (Iterator<CGNode> nodesI = cg.iterator(); nodesI.hasNext(); ) {
      nodes.add((nodesI.next()).getMethod().getReference());
    }

    return new Graph<MethodReference>() {
      @Override
      public String toString() {
        StringBuffer result = new StringBuffer();
        result.append("squashed " + name + " call graph\n");
        result.append("Original graph:");
        result.append(cg.toString());
        return result.toString();
      }

      /*
       * @see com.ibm.wala.util.graph.NodeManager#iterateNodes()
       */
      @Override
      public Iterator<MethodReference> iterator() {
        return nodes.iterator();
      }

      /*
       * @see com.ibm.wala.util.graph.NodeManager#containsNode(java.lang.Object)
       */
      @Override
      public boolean containsNode(MethodReference N) {
        return nodes.contains(N);
      }

      /*
       * @see com.ibm.wala.util.graph.NodeManager#getNumberOfNodes()
       */
      @Override
      public int getNumberOfNodes() {
        return nodes.size();
      }

      /*
       * @see com.ibm.wala.util.graph.EdgeManager#getPredNodes(java.lang.Object)
       */
      @Override
      public Iterator<MethodReference> getPredNodes(MethodReference N) {
        Set<MethodReference> pred = HashSetFactory.make(10);
        MethodReference methodReference = N;
        for (Iterator<CGNode> i = cg.getNodes(methodReference).iterator(); i.hasNext(); )
          for (Iterator<? extends CGNode> ps = cg.getPredNodes(i.next()); ps.hasNext(); )
            pred.add(((CGNode) ps.next()).getMethod().getReference());

        return pred.iterator();
      }

      /*
       * @see com.ibm.wala.util.graph.EdgeManager#getPredNodeCount(java.lang.Object)
       */
      @Override
      public int getPredNodeCount(MethodReference N) {
        int count = 0;
        for (Iterator<? extends MethodReference> ps = getPredNodes(N);
            ps.hasNext();
            count++, ps.next()) ;
        return count;
      }

      /*
       * @see com.ibm.wala.util.graph.EdgeManager#getSuccNodes(java.lang.Object)
       */
      @Override
      public Iterator<MethodReference> getSuccNodes(MethodReference N) {
        Set<MethodReference> succ = HashSetFactory.make(10);
        MethodReference methodReference = N;
        for (Iterator<? extends CGNode> i = cg.getNodes(methodReference).iterator(); i.hasNext(); )
          for (Iterator<? extends CGNode> ps = cg.getSuccNodes(i.next()); ps.hasNext(); )
            succ.add(((CGNode) ps.next()).getMethod().getReference());

        return succ.iterator();
      }

      /*
       * @see com.ibm.wala.util.graph.EdgeManager#getSuccNodeCount(java.lang.Object)
       */
      @Override
      public int getSuccNodeCount(MethodReference N) {
        int count = 0;
        for (Iterator<MethodReference> ps = getSuccNodes(N); ps.hasNext(); count++, ps.next()) ;
        return count;
      }

      /*
       * @see com.ibm.wala.util.graph.NodeManager#addNode(java.lang.Object)
       */
      @Override
      public void addNode(MethodReference n) {
        Assertions.UNREACHABLE();
      }

      /*
       * @see com.ibm.wala.util.graph.NodeManager#removeNode(java.lang.Object)
       */
      @Override
      public void removeNode(MethodReference n) {
        Assertions.UNREACHABLE();
      }

      /*
       * @see com.ibm.wala.util.graph.EdgeManager#addEdge(java.lang.Object, java.lang.Object)
       */
      @Override
      public void addEdge(MethodReference src, MethodReference dst) {
        Assertions.UNREACHABLE();
      }

      @Override
      public void removeEdge(MethodReference src, MethodReference dst) {
        Assertions.UNREACHABLE();
      }

      /*
       * @see com.ibm.wala.util.graph.EdgeManager#removeAllIncidentEdges(java.lang.Object)
       */
      @Override
      public void removeAllIncidentEdges(MethodReference node) {
        Assertions.UNREACHABLE();
      }

      /*
       * @see com.ibm.wala.util.graph.Graph#removeNodeAndEdges(java.lang.Object)
       */
      @Override
      public void removeNodeAndEdges(MethodReference N) {
        Assertions.UNREACHABLE();
      }

      @Override
      public void removeIncomingEdges(MethodReference node) {
        // TODO Auto-generated method stubMethodReference
        Assertions.UNREACHABLE();
      }

      @Override
      public void removeOutgoingEdges(MethodReference node) {
        // TODO Auto-generated method stub
        Assertions.UNREACHABLE();
      }

      @Override
      public boolean hasEdge(MethodReference src, MethodReference dst) {
        for (Iterator<MethodReference> succNodes = getSuccNodes(src); succNodes.hasNext(); ) {
          if (dst.equals(succNodes.next())) {
            return true;
          }
        }
        return false;
      }
    };
  }
 public ContextSensitiveProbablyNotInitializedAnalysis(CallGraph cg, AnalysisCache cache) {
   this.cha = cg.getClassHierarchy();
   // we use an ICFGSupergraph, which basically adapts ExplodedInterproceduralCFG to the
   // ISupergraph interface
   this.supergraph = ICFGSupergraph.make(cg, cache);
 }