[Soot-list] How transform local variables into class' s fields.
adriano cosimati
agenteborghese at gmail.com
Thu Dec 30 01:33:26 EST 2010
I want to inspect the local variables of a method of a class of which I do
not have the source code.
I thought to turn the .class file into a .jimple file and then change the code,
and turn local variables into instance fields, so I can debug them.
This is the original java code of an example class:
package test;
import java.util.Vector;
public class Demo_local
{
private Vector buffer;
Demo_local() {
buffer = new Vector();
buffer.add("c");
buffer.add("d");
buffer.add("a");
}
public int getStringPos(String string) {
for( int *counter* = 0; counter < buffer.size(); counter++)
{
String *curString* = (String)buffer.elementAt(counter);
if(curString.equals(string))
{
buffer.remove(counter);
return counter;
}
}
return -1;
}
}
( 'counter' and 'curString' are the variables of interest)
I compiled the code above with the javac -g:none option.
The resulting .jimple code is:
public class test.Demo_local extends java.lang.Object
{
private java.util.Vector buffer;
void <init>()
{
test.Demo_local r0;
java.util.Vector $r1, $r2, $r3, $r4;
r0 := @this: test.Demo_local;
specialinvoke r0.<java.lang.Object: void <init>()>();
$r1 = new java.util.Vector;
specialinvoke $r1.<java.util.Vector: void <init>()>();
r0.<test.Demo_local: java.util.Vector buffer> = $r1;
$r2 = r0.<test.Demo_local: java.util.Vector buffer>;
virtualinvoke $r2.<java.util.Vector: boolean
add(java.lang.Object)>("c");
$r3 = r0.<test.Demo_local: java.util.Vector buffer>;
virtualinvoke $r3.<java.util.Vector: boolean
add(java.lang.Object)>("d");
$r4 = r0.<test.Demo_local: java.util.Vector buffer>;
virtualinvoke $r4.<java.util.Vector: boolean
add(java.lang.Object)>("a");
return;
}
public int getStringPos(java.lang.String)
{
test.Demo_local r0;
java.lang.String r1, r2;
int i0, $i1;
java.util.Vector $r3, $r4, $r6;
java.lang.Object $r5;
boolean $z0;
r0 := @this: test.Demo_local;
r1 := @parameter0: java.lang.String;
*i0* = 0;
label0:
$r3 = r0.<test.Demo_local: java.util.Vector buffer>;
$i1 = virtualinvoke $r3.<java.util.Vector: int size()>();
if i0 >= $i1 goto label2;
$r4 = r0.<test.Demo_local: java.util.Vector buffer>;
$r5 = virtualinvoke $r4.<java.util.Vector: java.lang.Object
elementAt(int)>(i0);
*r2* = (java.lang.String) $r5;
$z0 = virtualinvoke r2.<java.lang.String: boolean
equals(java.lang.Object)>(r1);
if $z0 == 0 goto label1;
$r6 = r0.<test.Demo_local: java.util.Vector buffer>;
virtualinvoke $r6.<java.util.Vector: java.lang.Object
remove(int)>(i0);
return i0;
label1:
i0 = i0 + 1;
goto label0;
label2:
return -1;
}
}
So i have made these changes:
public class test.Demo_local extends java.lang.Object
{
private java.util.Vector buffer;
private int *counter*;
private java.lang.String *curString*;
void <init>()
{
test.Demo_local r0;
java.util.Vector $r1, $r2, $r3, $r4;
r0 := @this: test.Demo_local;
specialinvoke r0.<java.lang.Object: void <init>()>();
$r1 = new java.util.Vector;
specialinvoke $r1.<java.util.Vector: void <init>()>();
r0.<test.Demo_local: java.util.Vector buffer> = $r1;
$r2 = r0.<test.Demo_local: java.util.Vector buffer>;
virtualinvoke $r2.<java.util.Vector: boolean
add(java.lang.Object)>("c");
$r3 = r0.<test.Demo_local: java.util.Vector buffer>;
virtualinvoke $r3.<java.util.Vector: boolean
add(java.lang.Object)>("d");
$r4 = r0.<test.Demo_local: java.util.Vector buffer>;
virtualinvoke $r4.<java.util.Vector: boolean
add(java.lang.Object)>("a");
return;
}
public int getStringPos(java.lang.String)
{
test.Demo_local r0;
java.lang.String r1, $r2;
int $i0, $i1;
java.util.Vector $r3, $r4, $r6;
java.lang.Object $r5;
boolean $z0;
r0 := @this: test.Demo_local;
r1 := @parameter0: java.lang.String;
*$r2* = r0.<test.Demo_local: java.lang.String *curString*>;
*$i0* = r0.<test.Demo_local: int *counter*>;
$i0 = 0;
label0:
$r3 = r0.<test.Demo_local: java.util.Vector buffer>;
$i1 = virtualinvoke $r3.<java.util.Vector: int size()>();
if $i0 >= $i1 goto label2;
$r4 = r0.<test.Demo_local: java.util.Vector buffer>;
$r5 = virtualinvoke $r4.<java.util.Vector: java.lang.Object
elementAt(int)>($i0);
$r2 = (java.lang.String) $r5;
$z0 = virtualinvoke $r2.<java.lang.String: boolean
equals(java.lang.Object)>(r1);
if $z0 == 0 goto label1;
$r6 = r0.<test.Demo_local: java.util.Vector buffer>;
virtualinvoke $r6.<java.util.Vector: java.lang.Object
remove(int)>($i0);
return $i0;
label1:
$i0 = $i0 + 1;
goto label0;
label2:
return -1;
}
}
When i compile into the .class file, the corresponding .java source is the
same i started from
(with a little optimization), but no trace of the two added instance's
fileds.
Where am I wrong ?
Thanks in advance.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mailman.cs.mcgill.ca/pipermail/soot-list/attachments/20101230/3896a113/attachment-0001.html
More information about the Soot-list
mailing list