/* Soot - a J*va Optimization Framework * Copyright (C) 1997-1999 Raja Vallee-Rai * * This library 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 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* * Modified by the Sable Research Group and others 1997-1999. * See the 'credits' file distributed with Soot for the complete list of * contributors. (Soot is distributed at http://www.sable.mcgill.ca/soot) */ //package ashes.examples.createclass; import soot.*; import soot.jimple.*; import soot.options.Options; import soot.util.*; import java.io.*; import java.util.*; /** Example of using Soot to create a classfile from scratch. * The 'createclass' example creates a HelloWorld class file using Soot. * It proceeds as follows: * * - Create a SootClass HelloWorld extending java.lang.Object. * * - Create a 'main' method and add it to the class. * * - Create an empty JimpleBody and add it to the 'main' method. * * - Add locals and statements to JimpleBody. * * - Write the result out to a class file. */ public class Main { public static void main(String[] args) throws FileNotFoundException, IOException { SootClass sClass; SootMethod method; // Resolve dependencies Scene.v().loadClassAndSupport("java.lang.Object"); Scene.v().loadClassAndSupport("java.lang.System"); // Declare 'public class HelloWorld' sClass = new SootClass("HelloWorld", Modifier.PUBLIC); // 'extends Object' sClass.setSuperclass(Scene.v().getSootClass("java.lang.Object")); Scene.v().addClass(sClass); // Create the method, public static void main(String[]) method = new SootMethod("main", Arrays.asList(new Type[] {ArrayType.v(RefType.v("java.lang.String"), 1)}), VoidType.v(), Modifier.PUBLIC | Modifier.STATIC); sClass.addMethod(method); // Create the method body { // create empty body JimpleBody body = Jimple.v().newBody(method); method.setActiveBody(body); Chain units = body.getUnits(); Local arg, tmpRef; // Add some locals, java.lang.String l0 arg = Jimple.v().newLocal("l0", ArrayType.v(RefType.v("java.lang.String"), 1)); body.getLocals().add(arg); // Add locals, java.io.printStream tmpRef tmpRef = Jimple.v().newLocal("tmpRef", RefType.v("java.io.PrintStream")); body.getLocals().add(tmpRef); // add "l0 = @parameter0" units.add(Jimple.v().newIdentityStmt(arg, Jimple.v().newParameterRef(ArrayType.v(RefType.v("java.lang.String"), 1), 0))); // add "tmpRef = java.lang.System.out" units.add(Jimple.v().newAssignStmt(tmpRef, Jimple.v().newStaticFieldRef( Scene.v().getField("").makeRef()))); // insert "tmpRef.println("Hello world!")" { SootMethod toCall = Scene.v().getMethod(""); units.add(Jimple.v().newInvokeStmt(Jimple.v().newVirtualInvokeExpr(tmpRef, toCall.makeRef(), StringConstant.v("Hello world!")))); } // insert "return" units.add(Jimple.v().newReturnVoidStmt()); } String fileName = SourceLocator.v().getFileNameFor(sClass, Options.output_format_class); OutputStream streamOut = new JasminOutputStream( new FileOutputStream(fileName)); PrintWriter writerOut = new PrintWriter( new OutputStreamWriter(streamOut)); JasminClass jasminClass = new soot.jimple.JasminClass(sClass); jasminClass.print(writerOut); writerOut.flush(); streamOut.close(); } }