All Downloads are FREE. Search and download functionalities are using the official Maven repository.

qilin.pta.tools.BasePTA Maven / Gradle / Ivy

/* Qilin - a Java Pointer Analysis Framework
 * Copyright (C) 2021-2030 Qilin developers
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3.0 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Lesser Public License for more details.
 *
 * You should have received a copy of the GNU General Lesser Public
 * License along with this program.  If not, see
 * .
 */

package qilin.pta.tools;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import qilin.CoreConfig;
import qilin.core.CorePTA;
import qilin.core.PTA;
import qilin.core.PTAScene;
import qilin.core.builder.CallGraphBuilder;
import qilin.core.pag.AllocNode;
import qilin.core.pag.ContextVarNode;
import qilin.core.pag.GlobalVarNode;
import qilin.core.pag.LocalVarNode;
import qilin.core.pag.Node;
import qilin.core.pag.PAG;
import qilin.core.pag.ValNode;
import qilin.core.pag.VarNode;
import qilin.core.sets.PointsToSet;
import qilin.core.solver.Propagator;
import qilin.core.solver.Solver;
import qilin.stat.IEvaluator;
import qilin.stat.SimplifiedEvaluator;
import qilin.util.PTAUtils;
import sootup.core.model.SootClass;
import sootup.core.model.SootField;
import sootup.core.model.SootMethod;

public abstract class BasePTA extends CorePTA {
  protected IEvaluator evaluator;

  public BasePTA(PTAScene scene) {
    super(scene);
    //    this.evaluator = new PTAEvaluator(this);
    this.evaluator = new SimplifiedEvaluator(this);
  }

  public IEvaluator evaluator() {
    return this.evaluator;
  }

  @Override
  protected PAG createPAG() {
    return new PAG(this);
  }

  @Override
  protected CallGraphBuilder createCallGraphBuilder() {
    return new CallGraphBuilder(this);
  }

  @Override
  public Propagator getPropagator() {
    return new Solver(this);
  }

  @Override
  public void run() {
    evaluator.begin();
    pureRun();
    evaluator.end();
    dumpStats();
    System.out.println(evaluator());
  }

  protected void dumpStats() {
    if (CoreConfig.v().getOutConfig().dumppts) {
      dumpPts(this, !CoreConfig.v().getOutConfig().dumplibpts);
    }
  }

  /** dump pts to sootoutput/pts */
  private void dumpPts(PTA pta, boolean appOnly) {
    final String output_dir = CoreConfig.v().getOutConfig().outDir;
    Map nodes = new TreeMap<>();
    try {
      PrintWriter file = new PrintWriter(new File(output_dir, "pts.txt"));
      file.println("Points-to results:");
      for (final ValNode vn : pta.getPag().getValNodes()) {
        if (!(vn instanceof VarNode)) {
          continue;
        }
        SootClass clz = null;
        if (vn instanceof LocalVarNode) {
          SootMethod sm = ((LocalVarNode) vn).getMethod();
          if (sm != null && !PTAUtils.isFakeMainMethod(sm)) {
            clz = getView().getClass(sm.getDeclaringClassType()).get();
          }
        } else if (vn instanceof GlobalVarNode) {
          GlobalVarNode gvn = (GlobalVarNode) vn;
          Object variable = gvn.getVariable();
          if (variable instanceof SootField) {
            SootField sf = (SootField) variable;
            clz = getView().getClass(sf.getDeclaringClassType()).get();
          }
        } else if (vn instanceof ContextVarNode) {
          ContextVarNode cv = (ContextVarNode) vn;
          VarNode varNode = cv.base();
          if (varNode instanceof LocalVarNode) {
            LocalVarNode cvbase = (LocalVarNode) varNode;
            clz = getView().getClass(cvbase.getMethod().getDeclaringClassType()).get();
          } else if (varNode instanceof GlobalVarNode) {
            GlobalVarNode gvn = (GlobalVarNode) varNode;
            Object variable = gvn.getVariable();
            if (variable instanceof SootField) {
              SootField sf = (SootField) variable;
              clz = getView().getClass(sf.getDeclaringClassType()).get();
            }
          }
        }
        if (appOnly && clz != null && !clz.isApplicationClass()) {
          continue;
        }

        String label = PTAUtils.getNodeLabel(vn);
        nodes.put("[" + label + "]", vn);
        file.print(label + " -> {");
        PointsToSet p2set = pta.reachingObjects(vn);

        if (p2set == null || p2set.isEmpty()) {
          file.print(" empty }\n");
          continue;
        }
        for (Iterator it = p2set.iterator(); it.hasNext(); ) {
          Node n = it.next();
          label = PTAUtils.getNodeLabel(n);
          nodes.put("[" + label + "]", n);
          file.print(" ");
          file.print(label);
        }
        file.print(" }\n");
      }
      nodes.forEach((l, n) -> file.println(l + n));
      file.close();
    } catch (IOException e) {
      throw new RuntimeException("Couldn't dump solution." + e);
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy