1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package org.kit.furia.fragment.soot.representation;
28 import soot.options.*;
29
30 import soot.*;
31 import soot.jimple.*;
32 import soot.jimple.internal.*;
33 import soot.shimple.ShimpleBody;
34 import soot.tagkit.CodeAttribute;
35 import soot.tagkit.Tag;
36 import java.util.*;
37
38
39 public class FrimpBody extends StmtBody
40 {
41
42
43
44 private static final long serialVersionUID = -559420704371577505L;
45
46
47
48
49
50
51 FrimpBody(SootMethod m)
52 {
53 super(m);
54 }
55
56 public Object clone()
57 {
58 Body b = Frimp.v().newBody(getMethod());
59 b.importBodyContentsFrom(this);
60 return b;
61 }
62
63
64
65
66
67 public FrimpBody(Body body)
68 {
69 super(body.getMethod());
70
71 if(Options.v().verbose())
72 G.v().out.println("[" + getMethod().getName() + "] Constructing FrimpBody...");
73
74 if(! (body instanceof ShimpleBody || body instanceof JimpleBody))
75 throw new RuntimeException("Can only construct FrimpBody's from ShimpleBody (for now)");
76
77 Body jBody = body;
78
79
80
81 Iterator it = jBody.getLocals().iterator();
82 while (it.hasNext())
83 getLocals().add(((Local)(it.next())));
84
85
86 it = jBody.getUnits().iterator();
87
88 final HashMap oldToNew = new HashMap(getUnits().size() * 2 + 1, 0.7f);
89 LinkedList updates = new LinkedList();
90
91
92 while (it.hasNext())
93 {
94 Stmt oldStmt = (Stmt)(it.next());
95 final StmtBox newStmtBox = (StmtBox) Frimp.v().newStmtBox(null);
96 final StmtBox updateStmtBox = (StmtBox) Frimp.v().newStmtBox(null);
97
98
99
100 oldStmt.apply(new AbstractStmtSwitch()
101 {
102 public void caseAssignStmt(AssignStmt s)
103 {
104 newStmtBox.setUnit(Frimp.v().newAssignStmt(s));
105 }
106 public void caseIdentityStmt(IdentityStmt s)
107 {
108 newStmtBox.setUnit(Frimp.v().newIdentityStmt(s));
109 }
110 public void caseBreakpointStmt(BreakpointStmt s)
111 {
112 newStmtBox.setUnit(Frimp.v().newBreakpointStmt(s));
113 }
114 public void caseInvokeStmt(InvokeStmt s)
115 {
116 newStmtBox.setUnit(Frimp.v().newInvokeStmt(s));
117 }
118 public void caseEnterMonitorStmt(EnterMonitorStmt s)
119 {
120 newStmtBox.setUnit(Frimp.v().newEnterMonitorStmt(s));
121 }
122 public void caseExitMonitorStmt(ExitMonitorStmt s)
123 {
124 newStmtBox.setUnit(Frimp.v().newExitMonitorStmt(s));
125 }
126 public void caseGotoStmt(GotoStmt s)
127 {
128 newStmtBox.setUnit(Frimp.v().newGotoStmt(s));
129 updateStmtBox.setUnit(s);
130 }
131 public void caseIfStmt(IfStmt s)
132 {
133 newStmtBox.setUnit(Frimp.v().newIfStmt(s));
134 updateStmtBox.setUnit(s);
135 }
136 public void caseLookupSwitchStmt(LookupSwitchStmt s)
137 {
138 newStmtBox.setUnit(Frimp.v().newLookupSwitchStmt(s));
139 updateStmtBox.setUnit(s);
140 }
141 public void caseNopStmt(NopStmt s)
142 {
143 newStmtBox.setUnit(Frimp.v().newNopStmt(s));
144 }
145
146 public void caseReturnStmt(ReturnStmt s)
147 {
148 newStmtBox.setUnit(Frimp.v().newReturnStmt(s));
149 }
150 public void caseReturnVoidStmt(ReturnVoidStmt s)
151 {
152 newStmtBox.setUnit(Frimp.v().newReturnVoidStmt(s));
153 }
154 public void caseTableSwitchStmt(TableSwitchStmt s)
155 {
156 newStmtBox.setUnit(Frimp.v().newTableSwitchStmt(s));
157 updateStmtBox.setUnit(s);
158 }
159 public void caseThrowStmt(ThrowStmt s)
160 {
161 newStmtBox.setUnit(Frimp.v().newThrowStmt(s));
162 }
163 });
164
165
166 Stmt newStmt = (Stmt)(newStmtBox.getUnit());
167 Iterator useBoxesIt;
168 useBoxesIt = newStmt.getUseBoxes().iterator();
169 while(useBoxesIt.hasNext())
170 {
171 ValueBox b = (ValueBox) (useBoxesIt.next());
172 b.setValue(Frimp.v().newExpr(b.getValue()));
173 }
174 useBoxesIt = newStmt.getDefBoxes().iterator();
175 while(useBoxesIt.hasNext())
176 {
177 ValueBox b = (ValueBox) (useBoxesIt.next());
178 b.setValue(Frimp.v().newExpr(b.getValue()));
179 }
180
181 getUnits().add(newStmt);
182 oldToNew.put(oldStmt, newStmt);
183 if (updateStmtBox.getUnit() != null)
184 updates.add(updateStmtBox.getUnit());
185 }
186
187
188 it = updates.iterator();
189 while (it.hasNext())
190 {
191 Stmt stmt = (Stmt)(it.next());
192
193 stmt.apply(new AbstractStmtSwitch()
194 {
195 public void caseGotoStmt(GotoStmt s)
196 {
197 GotoStmt newStmt = (GotoStmt)(oldToNew.get(s));
198 newStmt.setTarget((Stmt)oldToNew.get(newStmt.getTarget()));
199 }
200 public void caseIfStmt(IfStmt s)
201 {
202 IfStmt newStmt = (IfStmt)(oldToNew.get(s));
203 newStmt.setTarget((Stmt)oldToNew.get(newStmt.getTarget()));
204 }
205 public void caseLookupSwitchStmt(LookupSwitchStmt s)
206 {
207 LookupSwitchStmt newStmt =
208 (LookupSwitchStmt)(oldToNew.get(s));
209 newStmt.setDefaultTarget
210 ((Unit)(oldToNew.get(newStmt.getDefaultTarget())));
211 Unit[] newTargList = new Unit[newStmt.getTargetCount()];
212 for (int i = 0; i < newStmt.getTargetCount(); i++)
213 newTargList[i] = (Unit)(oldToNew.get
214 (newStmt.getTarget(i)));
215 newStmt.setTargets(newTargList);
216 }
217 public void caseTableSwitchStmt(TableSwitchStmt s)
218 {
219 TableSwitchStmt newStmt =
220 (TableSwitchStmt)(oldToNew.get(s));
221 newStmt.setDefaultTarget
222 ((Unit)(oldToNew.get(newStmt.getDefaultTarget())));
223 int tc = newStmt.getHighIndex() - newStmt.getLowIndex()+1;
224 LinkedList newTargList = new LinkedList();
225 for (int i = 0; i < tc; i++)
226 newTargList.add(oldToNew.get
227 (newStmt.getTarget(i)));
228 newStmt.setTargets(newTargList);
229 }
230 });
231 }
232
233 it = jBody.getTraps().iterator();
234 while (it.hasNext())
235 {
236 Trap oldTrap = (Trap)(it.next());
237 getTraps().add(Frimp.v().newTrap
238 (oldTrap.getException(),
239 (Unit)(oldToNew.get(oldTrap.getBeginUnit())),
240 (Unit)(oldToNew.get(oldTrap.getEndUnit())),
241 (Unit)(oldToNew.get(oldTrap.getHandlerUnit()))));
242 }
243
244
245 }
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265 public List getAllUnitBoxes()
266 {
267 ArrayList unitBoxList = new ArrayList();
268 {
269 Iterator it = unitChain.iterator();
270 while(it.hasNext()) {
271 Unit item = (Unit) it.next();
272 assert item.getUnitBoxes() !=null: "This item returns null unitboxes: " + item + "\n class: " + item.getClass().getName();
273 unitBoxList.addAll(item.getUnitBoxes());
274 }
275 }
276
277 {
278 Iterator it = trapChain.iterator();
279 while(it.hasNext()) {
280 Trap item = (Trap) it.next();
281 unitBoxList.addAll(item.getUnitBoxes());
282 }
283 }
284
285 {
286 Iterator it = getTags().iterator();
287 while(it.hasNext()) {
288 Tag t = (Tag) it.next();
289 if( t instanceof CodeAttribute)
290 unitBoxList.addAll(((CodeAttribute) t).getUnitBoxes());
291 }
292 }
293
294 return unitBoxList;
295 }
296
297 }