View Javadoc

1   package org.kit.furia.fragment.asm;
2   
3   import java.io.BufferedInputStream;
4   import java.io.File;
5   import java.io.FileInputStream;
6   import java.io.FileNotFoundException;
7   import java.io.FileWriter;
8   import java.io.IOException;
9   import java.util.HashMap;
10  import java.util.HashSet;
11  import java.util.Iterator;
12  import java.util.LinkedList;
13  import java.util.List;
14  import java.util.Map;
15  import java.util.Set;
16  
17  import org.apache.log4j.Logger;
18  import org.kit.furia.exceptions.IRException;
19  import org.kit.furia.fragment.AbstractFragmentExtractor;
20  import org.kit.furia.fragment.FragmentParseException;
21  import org.kit.furia.fragment.MTDFragmentAST;
22  import org.kit.furia.fragment.OBFragment;
23  import org.kit.furia.fragment.soot.HugeFragmentException;
24  import org.kit.furia.fragment.soot.NoClassesFound;
25  import org.kit.furia.misc.IntegerHolder;
26  import org.objectweb.asm.ClassReader;
27  import org.objectweb.asm.tree.ClassNode;
28  import org.objectweb.asm.tree.MethodNode;
29  import org.objectweb.asm.tree.analysis.Analyzer;
30  import org.objectweb.asm.tree.analysis.Frame;
31  import org.objectweb.asm.tree.analysis.Value;
32  
33  public class FragmentExtractorASM
34          extends AbstractFragmentExtractor {
35      
36      private static final Logger logger = Logger.getLogger(FragmentExtractorASM.class);
37      private int huge = 0;
38      public void extractMethodsFromDirectory(final String directory,
39              final int maxStructuresAllowed, final int minStructuresAllowed,
40              final String outputPath, String outputFile)
41              throws FileNotFoundException, NoClassesFound, IOException,
42              IRException, FragmentParseException {
43  
44          List < File > classFiles = new LinkedList < File >();
45          super.getClassFiles(new File(directory), classFiles);
46          if (classFiles.size() == 0) {
47              throw new NoClassesFound();
48          }
49          Iterator < File > it = classFiles.iterator();
50          HashMap < String, IntegerHolder > fragments = new HashMap < String, IntegerHolder >(100000);
51          int i = 0;
52          while (it.hasNext()) {
53              File f = it.next();
54              //System.out.println(i + " of " + classFiles.size() + " size: " + fragments.size() + " huge: " + huge);
55              //System.out.flush();
56              //logger.info(i + " of " + classFiles.size() + " size: " + fragments.size());
57              processClass(f, fragments, maxStructuresAllowed);
58              i++;
59          }
60          //System.out.println("finished");
61          // now we just have to write the fragments down into the file.
62          FileWriter output = new FileWriter(outputFile);
63          for (Map.Entry < String, IntegerHolder > entry : fragments.entrySet()) {
64              String treeStr = entry.getKey();
65              MTDFragmentAST tree = OBFragment.parseTree(treeStr);
66              // process only if the tree has the expected size.
67              if (tree.getSize() >= minStructuresAllowed
68                      && tree.getSize() <= maxStructuresAllowed) {
69                  output.write(entry.getValue().getValue() + "\t"
70                          + entry.getKey() + "\n");
71              }
72          }
73          output.close();
74      }
75  
76      protected String toString(FValue x, int max) throws HugeFragmentException{
77          StringBuilder treeTemp = new StringBuilder();
78          Set visited = new HashSet();
79          IntegerHolder count = new IntegerHolder(0);
80          x.toFragment(treeTemp, visited, count, max);
81          return treeTemp.toString();
82      }
83  
84      protected void processClass(File f,
85              HashMap < String, IntegerHolder > fragments, int max) throws IOException {
86          
87          FileInputStream read = new FileInputStream(f);
88          
89          ClassReader cr = new ClassReader(new BufferedInputStream(
90                  read));
91          read.close();
92          ClassNode cn = new ClassNode();
93          cr.accept(cn, ClassReader.SKIP_DEBUG);
94          List < MethodNode > methods = cn.methods;
95          Set expanded = new HashSet();        
96          for (MethodNode m : methods) {
97              if (m.instructions.size() > 0) {
98                  Analyzer a = new Analyzer(new FragmentInterpreter());
99                  try {
100                     a.analyze(cn.name, m);
101                 } catch (Exception ignored) {
102                 }
103                 if (a.getFrames() != null) {
104                     for (Frame frame : a.getFrames()) {                        
105                         if (frame != null) {
106                             int i = 0;
107                             while (i < frame.getLocals()) {
108                                 Value val = frame.getLocal(i);
109                                 
110                                 if (val instanceof FValue && ! expanded.contains(val)) {
111                                     try{
112                                     String fragment = toString(((FValue) val), max);
113                                     
114                                     IntegerHolder multiplicity = fragments
115                                             .get(fragment);
116                                     if (multiplicity == null) {
117                                         multiplicity = new IntegerHolder(0);
118                                         fragments.put(fragment, multiplicity);
119                                     }
120                                     multiplicity.inc();
121                                     }catch(HugeFragmentException e){
122                                         huge++;
123                                     }
124                                     expanded.add(val);
125                                 }
126                                 i++;
127                             }
128                         }
129                     }
130                 }
131             }
132         }
133     }
134 
135 }