From 96c9ae52cfda8c297a6743997dcb0cb60117427d Mon Sep 17 00:00:00 2001 From: rodrigo-bruno Date: Sat, 1 Jul 2017 22:34:50 +0100 Subject: [PATCH 1/2] Changed JCallGraph to be able to process not only JAR files, but also directories, class files. --- .../gr/gousiosg/javacg/stat/JCallGraph.java | 71 ++++++++++++------- 1 file changed, 46 insertions(+), 25 deletions(-) diff --git a/src/main/java/gr/gousiosg/javacg/stat/JCallGraph.java b/src/main/java/gr/gousiosg/javacg/stat/JCallGraph.java index 4d19408d..bc3717d0 100644 --- a/src/main/java/gr/gousiosg/javacg/stat/JCallGraph.java +++ b/src/main/java/gr/gousiosg/javacg/stat/JCallGraph.java @@ -37,44 +37,65 @@ import org.apache.bcel.classfile.ClassParser; /** - * Constructs a callgraph out of a JAR archive. Can combine multiple archives - * into a single call graph. + * Constructs a callgraph out of a set of directories, classes and JAR archives. + * Can combine multiple archives into a single call graph. * * @author Georgios Gousios * */ public class JCallGraph { - public static void main(String[] args) { - ClassParser cp; - try { - for (String arg : args) { + public static void processClass(String class_name) throws IOException { + ClassParser cp = new ClassParser(class_name); + ClassVisitor visitor = new ClassVisitor(cp.parse()); + visitor.start(); + } + + public static void processClass(String jar_name, String class_name) throws IOException { + ClassParser cp = new ClassParser(jar_name,class_name); + ClassVisitor visitor = new ClassVisitor(cp.parse()); + visitor.start(); + } + + public static void processJar(JarFile jar) throws IOException { + Enumeration entries = jar.entries(); + while (entries.hasMoreElements()) { + JarEntry entry = entries.nextElement(); + if (entry.isDirectory()) + continue; - File f = new File(arg); - - if (!f.exists()) { - System.err.println("Jar file " + arg + " does not exist"); - } - - JarFile jar = new JarFile(f); + if (!entry.getName().endsWith(".class")) + continue; - Enumeration entries = jar.entries(); - while (entries.hasMoreElements()) { - JarEntry entry = entries.nextElement(); - if (entry.isDirectory()) - continue; + processClass(jar.getName(),entry.getName()); + } + } - if (!entry.getName().endsWith(".class")) - continue; + public static void processFile(File file) { + try { + if (!file.exists()) + System.err.println("File " + file.getName() + " does not exist"); - cp = new ClassParser(arg,entry.getName()); - ClassVisitor visitor = new ClassVisitor(cp.parse()); - visitor.start(); - } + else if (file.isDirectory()) { + for (File dfile : file.listFiles()) + processFile(dfile); } + + else if (file.getName().endsWith(".jar")) + processJar(new JarFile(file)); + + else if (file.getName().endsWith(".class")) + processClass(file.getAbsolutePath()); + } catch (IOException e) { - System.err.println("Error while processing jar: " + e.getMessage()); + System.err.println("Error while processing file: " + e.getMessage()); e.printStackTrace(); } } + + public static void main(String[] args) { + for (String arg : args) { + processFile(new File(arg)); + } + } } From d0bcf629a044bdac519b564c39ea3db8d50235f5 Mon Sep 17 00:00:00 2001 From: rodrigo-bruno Date: Sat, 1 Jul 2017 23:32:02 +0100 Subject: [PATCH 2/2] Added bci to method calls. --- .../java/gr/gousiosg/javacg/stat/MethodVisitor.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/gr/gousiosg/javacg/stat/MethodVisitor.java b/src/main/java/gr/gousiosg/javacg/stat/MethodVisitor.java index 4dd0821b..f8d2e9e6 100644 --- a/src/main/java/gr/gousiosg/javacg/stat/MethodVisitor.java +++ b/src/main/java/gr/gousiosg/javacg/stat/MethodVisitor.java @@ -48,7 +48,7 @@ public MethodVisitor(MethodGen m, JavaClass jc) { visitedClass = jc; mg = m; cp = mg.getConstantPool(); - format = "M:" + visitedClass.getClassName() + ":" + mg.getName() + "(" + argumentList(mg.getArgumentTypes()) + ")" + format = "M:" + visitedClass.getClassName() + ":" + mg.getName() + "(" + argumentList(mg.getArgumentTypes()) + "):%d" + " " + "(%s)%s:%s(%s)"; } @@ -84,27 +84,27 @@ private boolean visitInstruction(Instruction i) { @Override public void visitINVOKEVIRTUAL(INVOKEVIRTUAL i) { - System.out.println(String.format(format,"M",i.getReferenceType(cp),i.getMethodName(cp),argumentList(i.getArgumentTypes(cp)))); + System.out.println(String.format(format,i.getIndex(),"M",i.getReferenceType(cp),i.getMethodName(cp),argumentList(i.getArgumentTypes(cp)))); } @Override public void visitINVOKEINTERFACE(INVOKEINTERFACE i) { - System.out.println(String.format(format,"I",i.getReferenceType(cp),i.getMethodName(cp),argumentList(i.getArgumentTypes(cp)))); + System.out.println(String.format(format,i.getIndex(),"I",i.getReferenceType(cp),i.getMethodName(cp),argumentList(i.getArgumentTypes(cp)))); } @Override public void visitINVOKESPECIAL(INVOKESPECIAL i) { - System.out.println(String.format(format,"O",i.getReferenceType(cp),i.getMethodName(cp),argumentList(i.getArgumentTypes(cp)))); + System.out.println(String.format(format,i.getIndex(),"O",i.getReferenceType(cp),i.getMethodName(cp),argumentList(i.getArgumentTypes(cp)))); } @Override public void visitINVOKESTATIC(INVOKESTATIC i) { - System.out.println(String.format(format,"S",i.getReferenceType(cp),i.getMethodName(cp),argumentList(i.getArgumentTypes(cp)))); + System.out.println(String.format(format,i.getIndex(),"S",i.getReferenceType(cp),i.getMethodName(cp),argumentList(i.getArgumentTypes(cp)))); } @Override public void visitINVOKEDYNAMIC(INVOKEDYNAMIC i) { - System.out.println(String.format(format,"D",i.getType(cp),i.getMethodName(cp), + System.out.println(String.format(format,i.getIndex(),"D",i.getType(cp),i.getMethodName(cp), argumentList(i.getArgumentTypes(cp)))); } }