@Override public IFigure getTooltip(Object element) { if (element instanceof BasicBlock) { BasicBlock bb = (BasicBlock) element; IR ir = irView.getIR(); IDocument doc = irView.getDocument(); IMethod method = ir.getMethod(); StringBuffer result = new StringBuffer(); int start = bb.getFirstInstructionIndex(); int end = bb.getLastInstructionIndex(); SSAInstruction[] instructions = ir.getInstructions(); for (int j = start; j <= end; j++) { if (instructions[j] != null) { int sourceLineNum = method.getLineNumber(j); int lineNumber = sourceLineNum - 1; // IDocument indexing is 0-based try { int lineOffset = doc.getLineOffset(lineNumber); int lineLength = doc.getLineLength(lineNumber); String sourceCode = doc.get(lineOffset, lineLength).trim(); result.append(sourceCode); } catch (BadLocationException e) { } result.append("\n"); } } return new Label(result.toString()); } return null; }
@Override public void visitJavaScriptInvoke(JavaScriptInvoke invk) { // check whether this instruction corresponds to a function expression/declaration if (isFunctionConstructorInvoke(invk)) { int defn = invk.getDef(); // the name of the function String fnName = symtab.getStringValue(invk.getUse(1)); IClass fnClass = cha.lookupClass(TypeReference.findOrCreate(JavaScriptTypes.jsLoader, fnName)); if (fnClass == null) { System.err.println( "cannot find " + fnName + " at " + ((AstMethod) method).getSourcePosition()); return; } IMethod fn = fnClass.getMethod(AstMethodReference.fnSelector); FuncVertex callee = factory.makeFuncVertex(fnClass); // look at all uses for (Iterator<SSAInstruction> uses = du.getUses(defn); uses.hasNext(); ) { SSAInstruction use = uses.next(); // check whether this is a local call if (use instanceof JavaScriptInvoke && ((JavaScriptInvoke) use).getFunction() == defn) { JavaScriptInvoke use_invk = (JavaScriptInvoke) use; // yes, so add edges from arguments to parameters... for (int i = 2; i < use_invk.getNumberOfParameters(); ++i) flowgraph.addEdge( factory.makeVarVertex(caller, use_invk.getUse(i)), factory.makeParamVertex(callee, i - 1)); // ...and from return to result flowgraph.addEdge( factory.makeRetVertex(callee), factory.makeVarVertex(caller, use.getDef())); // note: local calls are never qualified, so there is no flow into the receiver vertex } else { // no, it's a more complicated use, so add flows from/to unknown for (int i = 1; i < fn.getNumberOfParameters(); ++i) flowgraph.addEdge(factory.makeUnknownVertex(), factory.makeParamVertex(callee, i)); flowgraph.addEdge(factory.makeRetVertex(callee), factory.makeUnknownVertex()); } } } else { // this is a genuine function call; find out where the function came from SSAInstruction def = du.getDef(invk.getFunction()); // if it's not a local call, add flows from/to unknown if (!(def instanceof JavaScriptInvoke) || !isFunctionConstructorInvoke((JavaScriptInvoke) def)) { for (int i = 1; i < invk.getNumberOfParameters(); ++i) flowgraph.addEdge( factory.makeVarVertex(caller, invk.getUse(i)), factory.makeUnknownVertex()); flowgraph.addEdge( factory.makeUnknownVertex(), factory.makeVarVertex(caller, invk.getDef())); } } }
/** * Get all non-constructor, non-class-initializer methods declared by a class if their name is * equal to the specified name. * * @param cls the class * @param name the name */ private Collection<IMethod> getDeclaredNormalMethods(IClass cls, Atom name) { Collection<IMethod> result = HashSetFactory.make(); for (IMethod m : cls.getDeclaredMethods()) { if (!m.isInit() && !m.isClinit() && m.getSelector().getName().equals(name)) { result.add(m); } } return result; }
private static void runComputeModule( final String binDir, final Config cfg, final String outputDir) throws IOException, IllegalArgumentException, CancelException, PDGFormatException, WalaException { Main.checkOrCreateOutputDir(outputDir); System.out.print("Setting up analysis scope... "); // Fuegt die normale Java Bibliothek zum Scope hinzu AnalysisScope scope = AnalysisScopeReader.makePrimordialScope(null); if (cfg.nativesXML != null) { com.ibm.wala.ipa.callgraph.impl.Util.setNativeSpec(cfg.nativesXML); } // if use stubs if (cfg.stubs != null) { scope.addToScope(ClassLoaderReference.Primordial, new JarFile(cfg.stubs)); } // Nimmt unnoetige Klassen raus SetOfClasses exclusions = new FileOfClasses(new ByteArrayInputStream(cfg.exclusions.getBytes())); scope.setExclusions(exclusions); ClassLoaderReference loader = scope.getLoader(AnalysisScope.APPLICATION); AnalysisScopeReader.addClassPathToScope(binDir, scope, loader); System.out.println("done."); ClassHierarchy cha = ClassHierarchy.make(scope); System.out.print("Creating MoJo... "); MoJo mojo = MoJo.create(cha); System.out.println("done."); for (IClass cls : cha) { for (IMethod im : cls.getDeclaredMethods()) { if (im.getDeclaringClass().isInterface() || im.isAbstract()) { // skip methods without a body continue; } MethodInfo nfo = cfg.extern.checkForModuleMethod(im); if (nfo != null) { System.out.println("Found " + nfo + " for " + im); final String sig = Dictionary.extractSignature(im); final String outputMethodDir = outputDir + (outputDir.endsWith(File.separator) ? "" : File.separator) + "m_" + sig; Main.checkOrCreateOutputDir(outputMethodDir); computeVariants(mojo, im, nfo, outputMethodDir); } } } }
@Override public IMethod getCalleeTarget(CGNode caller, CallSiteReference site, IClass receiver) { IMethod target = base.getCalleeTarget(caller, site, receiver); if (target != null && target.getReference().equals(loadFileFunRef)) { Set<String> names = new HashSet<String>(); SSAInstruction call = caller.getIR() .getInstructions()[ caller.getIR().getCallInstructionIndices(site).intIterator().next()]; if (call.getNumberOfUses() > 1) { LocalPointerKey fileNameV = new LocalPointerKey(caller, call.getUse(1)); OrdinalSet<InstanceKey> ptrs = builder.getPointerAnalysis().getPointsToSet(fileNameV); for (InstanceKey k : ptrs) { if (k instanceof ConstantKey) { Object v = ((ConstantKey) k).getValue(); if (v instanceof String) { names.add((String) v); } } } if (names.size() == 1) { String str = names.iterator().next(); try { JavaScriptLoader cl = (JavaScriptLoader) builder.getClassHierarchy().getLoader(JavaScriptTypes.jsLoader); URL url = new URL(builder.getBaseURL(), str); if (!loadedFiles.contains(url)) { // try to open the input stream for the URL. if it fails, we'll get an IOException // and fall through to default case InputStream inputStream = url.openConnection().getInputStream(); inputStream.close(); JSCallGraphUtil.loadAdditionalFile(builder.getClassHierarchy(), cl, url); loadedFiles.add(url); IClass script = builder .getClassHierarchy() .lookupClass( TypeReference.findOrCreate(cl.getReference(), "L" + url.getFile())); return script.getMethod(JavaScriptMethods.fnSelector); } } catch (MalformedURLException e1) { // do nothing, fall through and return 'target' } catch (IOException e) { // do nothing, fall through and return 'target' } catch (RuntimeException e) { // do nothing, fall through and return 'target' } } } } return target; }
@SuppressWarnings("unused") public void run() throws UnsoundGraphException { Set<CGNode> allCalled = findAllCalledMethods(cg.getEntrypointNodes()); for (CGNode method : allCalled) { IMethod im = method.getMethod(); if (!im.isNative() && !im.isAbstract() && !im.isSynthetic()) { ControlFlowGraph<SSAInstruction, IExplodedBasicBlock> cfg = getPruned(method, null); } } }
/** * Get all non-constructor, non-class-initializer methods declared by a class and all its * superclasses if their name is equal to the specified name. * * @param cls the class * @param name the name */ private Collection<IMethod> getAllNormalPublicMethods(IClass cls, Atom name) { Collection<IMethod> result = HashSetFactory.make(); Collection<IMethod> allMethods = null; allMethods = cls.getAllMethods(); for (IMethod m : allMethods) { if (!m.isInit() && !m.isClinit() && m.isPublic() && m.getSelector().getName().equals(name)) { result.add(m); } } return result; }
/** * @param method * @return the receiver class for this method. */ private IClass getReceiverClass(IMethod method) { TypeReference formalType = method.getParameterType(0); IClass C = cha.lookupClass(formalType); if (method.isStatic()) { Assertions.UNREACHABLE("asked for receiver of static method " + method); } if (C == null) { Assertions.UNREACHABLE("no class found for " + formalType + " recv of " + method); } return C; }
public int getMethodEndLineNumber(String methodSig) { try { for (IMethod method : mInfoMap.keySet()) { if (method.getSignature().equals(methodSig)) { return mInfoMap.get(method).getEndLineNumber(); } } return 0; } catch (InvalidClassFileException icfe) { return 0; } }
public Set<String> getSetOfLinesRelatedToAddedMethods() { Set<String> lineNumbersOfAddedMethods = new HashSet<String>(); for (IMethod method : getAddedMethods()) { int getLineNumberOfFirstLineOfMethod = 0; try { getLineNumberOfFirstLineOfMethod = method.getLineNumber(1); // getMethodStartLineNumber(method); } catch (Exception e) { } lineNumbersOfAddedMethods.add( getClassName(method.getDeclaringClass()) + "," + getLineNumberOfFirstLineOfMethod); } return lineNumbersOfAddedMethods; }
/* * @see com.ibm.wala.ipa.callgraph.ContextSelector#getCalleeTarget(com.ibm.wala.ipa.callgraph.CGNode, * com.ibm.wala.classLoader.CallSiteReference, com.ibm.wala.classLoader.IMethod, * com.ibm.wala.ipa.callgraph.propagation.InstanceKey) */ public Context getCalleeTarget( CGNode caller, CallSiteReference site, IMethod callee, InstanceKey[] receiver) { if (callee.getReference().equals(GET_CLASS)) { return new JavaTypeContext(new PointType(receiver[0].getConcreteType())); } return null; }
@SuppressWarnings("unchecked") public void setIR(IR ir) { this.lineToPosition = HashMapFactory.make(); this.pcToLine = HashMapFactory.make(); this.lineToPc = HashMapFactory.make(); int firstLineWithPosition = NA; try { methodName.setText("IR: " + ir.getMethod()); irLineList.clear(); BufferedReader br = new BufferedReader(new StringReader(ir.toString())); int lineNum = 0; int position = NA; String line; while ((line = br.readLine()) != null) { irLineList.addElement(line); int pc = parseIrLine(line); if (pc != NA) { IMethod m = ir.getMethod(); int newPosition = m.getLineNumber(pc); if (newPosition != -1) { position = newPosition; } lineToPc.put(lineNum, pc); pcToLine.put(pc, lineNum); if (position != NA) { lineToPosition.put(lineNum, position); if (firstLineWithPosition == NA) { firstLineWithPosition = lineNum; } } } lineNum++; } } catch (IOException e) { // ??? assert false; } // focusing on the first line with position if (firstLineWithPosition != NA) { irLines.setSelectedIndex(firstLineWithPosition); irLines.ensureIndexIsVisible(firstLineWithPosition); } }
/** * @param m a method reference * @return a SyntheticMethod corresponding to m; or null if none is available. */ protected SyntheticMethod findOrCreateSyntheticMethod(IMethod m, boolean isStatic) { MethodReference ref = m.getReference(); if (syntheticMethods.containsKey(ref)) { return syntheticMethods.get(ref); } else { MethodSummary summ = null; if (canIgnore(ref)) { summ = generateNoOp(ref, isStatic); } else { summ = findSummary(ref); } if (summ != null) { SummarizedMethod n = new SummarizedMethod(ref, summ, m.getDeclaringClass()); syntheticMethods.put(ref, n); return n; } else { syntheticMethods.put(ref, null); return null; } } }
public static Iterable<Entrypoint> makePrimordialPublicEntrypoints( AnalysisScope scope, ClassHierarchy cha, String pkg) { final HashSet<Entrypoint> result = HashSetFactory.make(); for (IClass clazz : cha) { if (clazz.getName().toString().indexOf(pkg) != -1 && !clazz.isInterface() && !clazz.isAbstract()) { for (IMethod method : clazz.getDeclaredMethods()) { if (method.isPublic() && !method.isAbstract()) { System.out.println("Entry:" + method.getReference()); result.add(new DefaultEntrypoint(method, cha)); } } } } return new Iterable<Entrypoint>() { @Override public Iterator<Entrypoint> iterator() { return result.iterator(); } }; }
/** * @see * com.ibm.wala.ipa.callgraph.propagation.SSAContextInterpreter#getIR(com.ibm.wala.ipa.callgraph.CGNode) */ @Override public IR getIR(CGNode node) { if (node == null) { throw new IllegalArgumentException("node is null"); } assert understands(node); if (DEBUG) { System.err.println("generating IR for " + node); } IMethod method = node.getMethod(); GetMethodContext context = (GetMethodContext) node.getContext(); Map<Integer, ConstantValue> constants = HashMapFactory.make(); if (method.getReference().equals(GET_METHOD)) { Atom name = Atom.findOrCreateAsciiAtom(context.getName()); SSAInstruction instrs[] = makeGetMethodStatements(context, constants, name); return new SyntheticIR( method, context, new InducedCFG(instrs, method, context), instrs, SSAOptions.defaultOptions(), constants); } if (method.getReference().equals(GET_DECLARED_METHOD)) { Atom name = Atom.findOrCreateAsciiAtom(context.getName()); SSAInstruction instrs[] = makeGetDeclaredMethodStatements(context, constants, name); return new SyntheticIR( method, context, new InducedCFG(instrs, method, context), instrs, SSAOptions.defaultOptions(), constants); } Assertions.UNREACHABLE("Unexpected method " + node); return null; }
private static void computeAliasVariant( final MoJo mojo, final MayAliasGraph alias, final IMethod method, final boolean ignoreExceptions, final String outDir) throws IllegalArgumentException, CancelException, PDGFormatException, WalaException, FileNotFoundException { final Logger debug = Log.getLogger(Log.L_MOJO_DEBUG); final Logger info = Log.getLogger(Log.L_MOJO_INFO); info.out("Preparing points-to config and call graph..."); final PointsTo pts = MoJo.computePointsTo(alias); if (debug.isEnabled()) { AliasGraphIO.dumpToDot(alias, outDir + ".alias.dot"); } AliasGraphIO.writeOut(alias, new FileOutputStream(outDir + ".alias")); final AnalysisOptions optPts = mojo.createAnalysisOptionsWithPTS(pts, method); final CallGraphResult cg = mojo.computeContextSensitiveCallGraph(optPts); if (debug.isEnabled()) { final PrintStream ssaOut = new PrintStream(outDir + ".ssa.txt"); Util.dumpSSA(cg.cg.getFakeRootNode().getIR(), ssaOut); Util.dumpPhiSSA(cg.cg.getFakeRootNode().getIR(), ssaOut); ssaOut.flush(); ssaOut.close(); Util.dumpHeapGraphToFile( outDir + ".heap.dot", cg.pts.getHeapGraph(), cg.cg.getFakeRootNode().getMethod()); } info.out("done, sdg... "); // run analysis on callgraph with minimal alias configuration // ... final edu.kit.joana.ifc.sdg.graph.SDG sdg = createSDG(cg, optPts, method, ignoreExceptions); SDGSerializer.toPDGFormat(sdg, new BufferedOutputStream(new FileOutputStream(outDir + ".pdg"))); info.out("(" + sdg.edgeSet().size() + " edges)"); if (debug.isEnabled()) { final int summary = outputSummaryEdges(sdg, method.getReference().getSignature(), outDir + ".sum.dot"); debug.out(" (" + summary + " sum)"); } info.outln(" done."); }
public static boolean isRemoteProcedure(IMethod method) { return isCapsuleInterface(method.getDeclaringClass()); }
/** Taken from com.ibm.wala.viz.PDFViewUtil */ @Override public String getText(Object element) { if (element instanceof BasicBlock) { BasicBlock bb = (BasicBlock) element; IR ir = irView.getIR(); StringBuilder result = new StringBuilder(); int start = bb.getFirstInstructionIndex(); int end = bb.getLastInstructionIndex(); result.append("BB").append(bb.getNumber()); if (bb.isEntryBlock()) { result.append(" (en)\n"); } else if (bb.isExitBlock()) { result.append(" (ex)\n"); } if (bb instanceof ExceptionHandlerBasicBlock) { result.append("<Handler>"); } result.append("\n"); for (Iterator<SSAPhiInstruction> it = bb.iteratePhis(); it.hasNext(); ) { SSAPhiInstruction phi = it.next(); if (phi != null) { result.append(phi.toString(ir.getSymbolTable())).append("\n"); } } if (bb instanceof ExceptionHandlerBasicBlock) { ExceptionHandlerBasicBlock ebb = (ExceptionHandlerBasicBlock) bb; SSAGetCaughtExceptionInstruction s = ebb.getCatchInstruction(); if (s != null) { result.append(s.toString(ir.getSymbolTable())).append("\n"); } else { result.append(" No catch instruction. Unreachable?\n"); } } SSAInstruction[] instructions = ir.getInstructions(); IMethod method = ir.getMethod(); for (int j = start; j <= end; j++) { if (instructions[j] != null) { String x; int sourceLineNum = method.getLineNumber(j); x = String.format( j + " [L%03d] " + instructions[j].toString(ir.getSymbolTable()), sourceLineNum); String padded = String.format("%1$-35s", x); result.append(padded); result.append("\n"); result.append(SSAValuesToLocalVariables(instructions[j], j, ir)); result.append("\n"); } } for (Iterator<SSAPiInstruction> it = bb.iteratePis(); it.hasNext(); ) { SSAPiInstruction pi = it.next(); if (pi != null) { result.append(" " + pi.toString(ir.getSymbolTable())).append("\n"); } } return result.toString(); } if (element instanceof EntityConnectionData) { return "\n"; } return ""; }
/** @param method An arbitrary method on a template class annotated with `@Capsule`. */ public static boolean isSpecialCapsuleDecl(IMethod method) { assert isCapsuleTemplate(method.getDeclaringClass()); return isNamed(method, "init") || isNamed(method, "design") || isNamed(method, "run"); }
/** @param method An arbitrary method declared on a template class annotated with `@Capsule`. */ public static boolean isProcedure(IMethod method) { assert isCapsuleTemplate(method.getDeclaringClass()); return method.isPublic() == true // Only a capsule's public methods are procedures. && isSpecialCapsuleDecl(method) == false; // Don't count special decls as procedures. }
public LocalCallSSAVisitor(IMethod method, SymbolTable symtab, DefUse du, FlowGraph flowgraph) { super(method, symtab, du); this.flowgraph = flowgraph; this.factory = flowgraph.getVertexFactory(); this.caller = this.factory.makeFuncVertex(method.getDeclaringClass()); }
protected boolean filterFunction(IMethod function) { return function.getDescriptor().equals(AstMethodReference.fnDesc); }
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; }