[Soot-list] Generating invalid code
Marc Hull (Imperial College)
mfh02 at doc.ic.ac.uk
Thu Feb 9 13:26:17 EST 2006
Hi,
I'm trying to use Soot to add code to the start of certain methods, but
I keep generating bytecode that fails verifier checks when I run it.
I've narrowed it down to the statement that ties the 'this' reference to
a local:
SootClass sClass = Scene.v().loadClassAndSupport(a.getClass().getName());
... snip (obtain SootMethod for required method and store it in
'method') ...
Local a0 = Jimple.v().newLocal("a0", RefType.v(method.getDeclaringClass()));
body.getLocals().add(a0);
units.add(
Jimple.v().newIdentityStmt(
a0,
Jimple.v().newThisRef(
RefType.v(method.getDeclaringClass())
)
)
);
Chain oldUnits = body.getUnits();
oldUnits.insertBefore(units, oldUnits.getFirst());
... snip ...
fileName = "C:/temp/A.class";
streamOut = new JasminOutputStream(new FileOutputStream(fileName));
writerOut = new PrintWriter(new OutputStreamWriter(streamOut));
JasminClass jasminClass = new soot.jimple.JasminClass(sClass);
jasminClass.print(writerOut);
writerOut.flush();
streamOut.close();
When I try to load the class, I get (where 'String getName()' is the
altered method):
Exception in thread "main" java.lang.VerifyError: (class: test/A,
method: getName signature: ()Ljava/lang/String;) Incompatible type for
getting or setting field
at uk.ac.ic.doc.cuXca.prototypes.soot.SootTest1.main(SootTest1.java:55)
Looking at the bytecode for the class reveals:
public java.lang.String getName();
Code:
Stack=2, Locals=1, Args_size=1
0: getstatic #12; //Field
java/lang/System.out:Ljava/io/PrintStream;
3: astore_0
4: aload_0
5: ldc #11; //String Called A.getName()
7: invokevirtual #24; //Method
java/io/PrintStream.println:(Ljava/lang/St
ring;)V
10: aload_0
11: getfield #25; //Field name:Ljava/lang/String;
14: astore_0
15: aload_0
16: areturn
The bytecode for the original, unaltered method is:
public java.lang.String getName();
Code:
Stack=2, Locals=1, Args_size=1
0: getstatic #23; //Field
java/lang/System.out:Ljava/io/PrintStream;
3: ldc #25; //String Called A.getName()
5: invokevirtual #31; //Method
java/io/PrintStream.println:(Ljava/lang/St
ring;)V
8: aload_0
9: getfield #33; //Field name:Ljava/lang/String;
12: areturn
Am I right in thinking that astore_0 is overwriting the 'this' pointer
and that's why the verify is failing? I've only ever seen astore_0 in
static methods, but this is definitely an instance method. I can't work
out why this would be inserted when I'm just trying to access the 'this'
pointer, not set it.
Any help greatly appreciated,
Marc
More information about the Soot-list
mailing list