00001 package edu.ksu.cis.bandera.bofa;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 import java.util.Hashtable;
00038 import ca.mcgill.sable.soot.*;
00039 import ca.mcgill.sable.soot.jimple.*;
00040 import ca.mcgill.sable.soot.jimple.Stmt;
00041 import ca.mcgill.sable.util.*;
00042 import edu.ksu.cis.bandera.jjjc.CompilationManager;
00043 import org.apache.log4j.Category;
00044
00045 import edu.ksu.cis.bandera.jext.*;
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 public class FGExpr extends AbstractBanderaValueSwitch
00065
00066 {
00067
00068
00069
00070
00071 private static Hashtable commonTokens = new Hashtable();
00072
00073
00074
00075
00076
00077 private MethodVariant methodVariant;
00078
00079
00080
00081
00082 private Map astNodes;
00083
00084
00085
00086
00087
00088
00089 private Value value;
00090
00091
00092
00093
00094
00095
00096 private Stmt stmt;
00097
00098
00099
00100
00101
00102 private static Category cat;
00103
00104 static {
00105 cat = Category.getInstance(FGExpr.class.getName());
00106 }
00107
00108
00109
00110
00111
00112
00113
00114 public FGExpr(MethodVariant methodVariant, Map astNodes)
00115 {
00116 this.methodVariant = methodVariant;
00117 this.astNodes = astNodes;
00118 }
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 public FGNodeAST build(Value v, Stmt s)
00132 {
00133 stmt = s;
00134 value = v;
00135 v.apply(this);
00136 FGNodeAST astNode = (FGNodeAST)this.getResult();
00137 if (astNode != null) {
00138 astNode.setStmt(stmt);
00139 }
00140 return astNode;
00141 }
00142
00143
00144
00145
00146
00147 public void caseAddExpr(AddExpr v)
00148 {
00149 setResult(null);
00150 }
00151
00152
00153
00154
00155
00156 public void caseAndExpr(AndExpr v)
00157 {
00158 setResult(null);
00159 }
00160
00161
00162
00163
00164
00165 public void caseArrayRef(ArrayRef v)
00166 {
00167 FGNode baseNode = build(v.getBase(), stmt);
00168
00169
00170
00171 ArrayType arrayType = ClassTokenArray.componentToArrayType(v.getType());
00172
00173 ClassTokenArray classTokenArray = ClassTokenArray.select(arrayType);
00174
00175
00176 FGNodeAST arrayRefNode = new FGNodeAST(v);
00177
00178
00179
00180
00181
00182
00183
00184
00185 baseNode.addAction(new FGActionArrayRef(classTokenArray,
00186 arrayRefNode, methodVariant));
00187 setResult(arrayRefNode);
00188 astNodes.put(v,arrayRefNode);
00189 }
00190
00191
00192
00193
00194
00195 public void caseCastExpr(CastExpr v)
00196 {
00197
00198
00199
00200
00201
00202 FGNode baseNode = build(v.getOp(), stmt);
00203 FGNodeAST node = new FGNodeAST(v);
00204 FGNode.makeArc(baseNode, node);
00205 setResult(node);
00206 }
00207
00208
00209
00210
00211
00212 public void caseCaughtExceptionRef(CaughtExceptionRef v)
00213 {
00214 defaultCase(v);
00215 }
00216
00217
00218
00219
00220 public void caseChooseExpr(ChooseExpr v) {
00221 SootClass sc = null;
00222 try {
00223 sc = FA.classManager.getClass("Bandera");
00224 } catch (Exception e) { }
00225
00226 if (sc == null)
00227 {
00228 System.out.println("WARNING: Bandera class is not handled!");
00229 defaultCase(null);
00230 return;
00231 }
00232
00233
00234
00235
00236
00237 SootMethod sm = null;
00238 List args = new LinkedList();
00239 try {
00240 sm = sc.getMethod("choose", args);
00241 } catch(Exception e) {}
00242 if (sm == null)
00243 {
00244 System.out.println("WARNING: Invalid Bandera class detected: No valid choose() method");
00245 }
00246 StaticInvokeExpr choose = Jimple.v().newStaticInvokeExpr(sm, args);
00247
00248 caseStaticInvokeExpr(choose);
00249
00250
00251 }
00252
00253
00254
00255
00256
00257 public void caseCmpExpr(CmpExpr v)
00258 {
00259 setResult(null);
00260 }
00261
00262
00263
00264
00265
00266 public void caseCmpgExpr(CmpgExpr v)
00267 {
00268 setResult(null);
00269 }
00270
00271
00272
00273
00274
00275 public void caseCmplExpr(CmplExpr v)
00276 {
00277 setResult(null);
00278 }
00279
00280
00281
00282
00283 public void caseComplementExpr(ComplementExpr expr) {
00284 defaultCase(expr);
00285 }
00286
00287
00288
00289
00290
00291 public void caseDivExpr(DivExpr v)
00292 {
00293 setResult(null);
00294 }
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 public void caseDoubleConstant(DoubleConstant v)
00306 {
00307 setResult(null);
00308 }
00309
00310
00311
00312
00313
00314 public void caseEqExpr(EqExpr v)
00315 {
00316 setResult(null);
00317 }
00318
00319
00320
00321
00322
00323 public void caseFloatConstant(FloatConstant v)
00324 {
00325 setResult(null);
00326 }
00327
00328
00329
00330
00331
00332 public void caseGeExpr(GeExpr v)
00333 {
00334 setResult(null);
00335 }
00336
00337
00338
00339
00340
00341 public void caseGtExpr(GtExpr v)
00342 {
00343 setResult(null);
00344 }
00345
00346
00347
00348
00349 public void caseInExpr(InExpr v) {
00350 defaultCase(v);
00351 }
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369 public void caseInstanceFieldRef(InstanceFieldRef v)
00370 {
00371 SootField sootField = v.getField();
00372 InstanceVariant instanceVariant
00373 = InstanceVariantManager.select(sootField);
00374 FGNodeAST astNode = new FGNodeAST(v);
00375 FGNode.makeArc(instanceVariant.getNode(), astNode);
00376 astNodes.put(v,astNode);
00377
00378 setResult(astNode);
00379 }
00380
00381
00382
00383
00384
00385 public void caseInstanceOfExpr(InstanceOfExpr v)
00386 {
00387 defaultCase(v);
00388 }
00389
00390
00391
00392
00393
00394 public void caseIntConstant(IntConstant v)
00395 {
00396 ValueVariant valueVariant =
00397 ValueVariantManager.select(ClassTokenSimple.intClassToken,
00398 methodVariant, value, stmt);
00399
00400 FGNodeAST node = new FGNodeAST(v);
00401 FGWork work = new FGWorkSendVals(new FASet(valueVariant), node);
00402 FA.workList.insert(work);
00403
00404 astNodes.put(v, node);
00405 setResult(node);
00406 }
00407
00408
00409
00410
00411
00412 public void caseInterfaceInvokeExpr(InterfaceInvokeExpr v)
00413 {
00414
00415
00416
00417
00418
00419
00420 SootMethod sootMethod = v.getMethod();
00421 int argCount = v.getArgCount();
00422 FGNode baseNode = build(v.getBase(), stmt);
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433 FGNode[] argNodes = new FGNode[argCount];
00434
00435 for (int i=0; i<argCount; i++) {
00436 argNodes[i] = build(v.getArg(i), stmt);
00437 }
00438
00439 FGNodeAST invokeNode = new FGNodeAST(v);
00440
00441
00442 baseNode.addAction(new FGActionInvoke(argCount,
00443 argNodes,
00444 invokeNode,
00445 sootMethod.getName(),
00446 sootMethod.getParameterTypes(),
00447 sootMethod.getReturnType()));
00448 setResult(invokeNode);
00449 astNodes.put(v,invokeNode);
00450 }
00451
00452
00453
00454
00455
00456 public void caseLeExpr(LeExpr v)
00457 {
00458 setResult(null);
00459 }
00460
00461
00462
00463
00464
00465 public void caseLengthExpr(LengthExpr v)
00466 {
00467 defaultCase(v);
00468 }
00469
00470
00471
00472
00473
00474
00475 public void caseLocal(Local v)
00476 {
00477 FGNodeLocal localNode = methodVariant.getLocalNode(v);
00478 FGNodeAST astNode = new FGNodeAST(v);
00479 FGNode.makeArc(localNode, astNode);
00480 astNodes.put(v, astNode);
00481
00482 setResult(astNode);
00483 }
00484
00485
00486
00487
00488 public void caseLocalExpr(LocalExpr v) {
00489 defaultCase(v);
00490 }
00491
00492
00493
00494
00495 public void caseLocationTestExpr(LocationTestExpr e) {
00496 defaultCase(e);
00497 }
00498
00499
00500
00501
00502 public void caseLogicalAndExpr(LogicalAndExpr expr)
00503 {
00504 defaultCase(expr);
00505 }
00506
00507
00508
00509
00510 public void caseLogicalOrExpr(LogicalOrExpr expr) {
00511 defaultCase(expr);
00512 }
00513
00514
00515
00516
00517
00518 public void caseLongConstant(LongConstant v)
00519 {
00520 this.setResult(null);
00521 }
00522
00523
00524
00525
00526
00527 public void caseLtExpr(LtExpr v)
00528 {
00529 setResult(null);
00530 }
00531
00532
00533
00534
00535
00536 public void caseMulExpr(MulExpr v)
00537 {
00538 setResult(null);
00539 }
00540
00541
00542
00543
00544
00545 public void caseNeExpr(NeExpr v)
00546 {
00547 setResult(null);
00548 }
00549
00550
00551
00552
00553
00554 public void caseNegExpr(NegExpr v)
00555 {
00556 setResult(null);
00557 }
00558
00559
00560
00561
00562
00563
00564 public void caseNewArrayExpr(NewArrayExpr v)
00565 {
00566 ArrayType arrayType = (ArrayType) v.getType();
00567 ClassToken classToken = ClassTokenArray.select(arrayType);
00568
00569
00570
00571
00572
00573
00574
00575 ValueVariant valueVariant = ValueVariantManager.select(classToken,
00576 methodVariant,
00577 v, stmt);
00578 FGNodeAST node = new FGNodeAST(v);
00579 FA.workList.insert(new FGWorkSendVals(new FASet(valueVariant), node));
00580
00581
00582
00583
00584
00585
00586
00587 astNodes.put(v,node);
00588 setResult(node);
00589
00590
00591
00592
00593
00594 ArrayVariant arrayVariant = ArrayVariantManager.select(classToken,
00595 valueVariant);
00596
00597
00598
00599
00600
00601
00602
00603 valueVariant =
00604 ValueVariantManager.select(ClassTokenSimple.nullClassToken,
00605 methodVariant, v, stmt);
00606 if ( !(v.getBaseType() instanceof RefType)) {
00607 String elementClassStr =
00608 ((ArrayType)v.getType()).baseType.toString();
00609 Value temp = getValue(elementClassStr);
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620 ClassTokenSimple elementClass =ClassTokenSimple
00621 .select(FA.classManager.getClass(elementClassStr));
00622
00623 valueVariant = ValueVariantManager.select(elementClass,
00624 methodVariant, temp, stmt);
00625 }
00626
00627 arrayVariant.getNode().values.add(valueVariant);
00628 }
00629
00630
00631
00632
00633
00634 public void caseNewExpr(NewExpr v)
00635 {
00636 RefType refType = v.getBaseType();
00637 String className = refType.className;
00638
00639
00640
00641
00642
00643
00644 SootClass sootClass = FA.classManager.getClass(className);
00645 ClassToken classToken = ClassTokenSimple.select(sootClass);
00646
00647
00648
00649
00650
00651
00652
00653 ValueVariant valueVariant = ValueVariantManager.select(classToken,
00654 methodVariant,
00655 v, stmt);
00656
00657 FGNodeAST node = new FGNodeAST(v);
00658
00659 FGWork work = new FGWorkSendVals(new FASet(valueVariant), node);
00660
00661 FA.workList.insert(work);
00662
00663 astNodes.put(v,node);
00664 setResult(node);
00665 }
00666
00667
00668
00669
00670
00671
00672 public void caseNewMultiArrayExpr(NewMultiArrayExpr v)
00673 {
00674 ArrayType arrayType = (ArrayType) v.getType();
00675 ClassToken classToken = ClassTokenArray.select(arrayType);
00676
00677
00678
00679
00680
00681
00682
00683 ValueVariant valueVariant = ValueVariantManager.select(classToken,
00684 methodVariant,
00685 value, stmt);
00686
00687 FGNodeAST node = new FGNodeAST(v);
00688 FGWork work = new FGWorkSendVals(new FASet(valueVariant), node);
00689 FA.workList.insert(work);
00690
00691
00692
00693
00694
00695
00696
00697 astNodes.put(v,node);
00698 setResult(node);
00699
00700
00701
00702
00703
00704
00705
00706
00707 int numSpecDim = v.getSizeCount();
00708 int count;
00709 Value valueOfCountDim;
00710 ArrayType componentType;
00711 ArrayVariant arrayVariant;
00712
00713 for (int j = arrayType.numDimensions - 1; j > arrayType.numDimensions -
00714 numSpecDim; j--) {
00715
00716
00717 componentType = arrayType.v(arrayType.baseType, j);
00718
00719
00720
00721 arrayVariant = ArrayVariantManager.select(classToken, valueVariant);
00722
00723 classToken = ClassTokenArray.select(componentType);
00724
00725 valueVariant = ValueVariantManager.select(classToken,
00726 methodVariant,
00727 value, stmt);
00728
00729 arrayVariant.getNode().values.add(valueVariant);
00730 }
00731
00732
00733
00734 if ( numSpecDim == arrayType.numDimensions) {
00735
00736 arrayVariant = ArrayVariantManager.select(classToken, valueVariant);
00737
00738 Value value = getValue(arrayType.baseType.toString());
00739
00740
00741
00742
00743
00744
00745 valueVariant =
00746 ValueVariantManager.select(ClassTokenSimple.nullClassToken,
00747 methodVariant, value, stmt);
00748 if ( !(v.getType() instanceof RefType)) {
00749 String elementClassStr =
00750 ((ArrayType)v.getType()).baseType.toString();
00751 Value temp = getValue(elementClassStr);
00752 ClassTokenSimple elementClass =
00753 ClassTokenSimple.select
00754 (FA.classManager.getClass(elementClassStr));
00755 valueVariant = ValueVariantManager.select(elementClass,
00756 methodVariant, temp,
00757 stmt);
00758 }
00759
00760
00761
00762 arrayVariant.getNode().values.add(valueVariant);
00763 }
00764 }
00765
00766
00767
00768
00769
00770
00771 public void caseNullConstant(NullConstant v)
00772 {
00773 ValueVariant nullVariant =
00774 ValueVariantManager.select(ClassTokenSimple.nullClassToken,
00775 methodVariant, v, stmt);
00776 FGNodeAST NullNode = new FGNodeAST(v);
00777 FGWork work = new FGWorkSendVals(new FASet(nullVariant), NullNode);
00778 FA.workList.insert(work);
00779 astNodes.put(v, NullNode);
00780 setResult(NullNode);
00781 }
00782
00783
00784
00785
00786
00787 public void caseOrExpr(OrExpr v)
00788 {
00789 setResult(null);
00790 }
00791
00792
00793
00794
00795
00796
00797 public void caseParameterRef(ParameterRef v)
00798 {
00799 int index = v.getIndex();
00800 FGNodeParameter parameterNode = methodVariant.getParameterNode(index);
00801 FGNodeAST astNode = new FGNodeAST(v);
00802 FGNode.makeArc(parameterNode, astNode);
00803 astNodes.put(v,astNode);
00804
00805 setResult(astNode);
00806 }
00807
00808
00809
00810
00811
00812 public void caseRemExpr(RemExpr v)
00813 {
00814 setResult(null);
00815 }
00816
00817
00818
00819
00820
00821 public void caseShlExpr(ShlExpr v)
00822 {
00823 setResult(null);
00824 }
00825
00826
00827
00828
00829
00830 public void caseShrExpr(ShrExpr v)
00831 {
00832 setResult(null);
00833 }
00834
00835
00836
00837
00838
00839 public void caseSpecialInvokeExpr(SpecialInvokeExpr v)
00840 {
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856 SootMethod sootMethod = v.getMethod();
00857 int argCount = v.getArgCount();
00858 FGNode baseNode = build(v.getBase(), stmt);
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869 FGNode[] argNodes = new FGNode[argCount];
00870
00871 for (int i=0; i<argCount; i++) {
00872 argNodes[i] = build(v.getArg(i), stmt);
00873 }
00874
00875 FGNodeAST invokeNode = new FGNodeAST(v);
00876
00877
00878 baseNode.addAction(new FGActionInvoke(argCount,
00879 argNodes,
00880 invokeNode,
00881 sootMethod.getName(),
00882 sootMethod.getParameterTypes(),
00883 sootMethod.getReturnType(),
00884 v.getMethod().getDeclaringClass()));
00885 setResult(invokeNode);
00886 astNodes.put(v,invokeNode);
00887
00888 }
00889
00890
00891
00892
00893
00894
00895 public void caseStaticFieldRef(StaticFieldRef v)
00896 {
00897 SootField sootField = v.getField();
00898 FGNodeAST astNode = new FGNodeAST(v);
00899 FGNode.makeArc(StaticFieldManager.select(sootField), astNode);
00900 astNodes.put(v, astNode);
00901
00902 setResult(astNode);
00903 }
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921 public void caseStaticInvokeExpr(StaticInvokeExpr v)
00922 {
00923 SootMethod sootMethod = v.getMethod();
00924 int argCount = v.getArgCount();
00925 FGNode[] argNodes = new FGNode[argCount];
00926 FGNode paramNode;
00927
00928
00929 MethodVariant methodVariant = MethodVariantManager.select(sootMethod);
00930
00931
00932
00933
00934 for (int i=0; i<argCount; i++) {
00935 argNodes[i] = build(v.getArg(i), stmt);
00936 paramNode = methodVariant.getParameterNode(i);
00937 FGNode.makeArc(argNodes[i], paramNode);
00938 }
00939
00940 FGNodeAST invokeNode = new FGNodeAST(v);
00941
00942 FGNode lastNode = methodVariant.getReturnNode();
00943 FGNode.makeArc(lastNode, invokeNode);
00944
00945 astNodes.put(v,invokeNode);
00946 setResult(invokeNode);
00947 }
00948
00949
00950
00951
00952
00953 public void caseStringConstant(StringConstant v)
00954 {
00955 SootClass sootClass =
00956 FA.classManager.getClass(RefType.v("java.lang.String").className);
00957 ClassToken classToken = ClassTokenSimple.select(sootClass);
00958 ValueVariant valueVariant = ValueVariantManager.select(classToken,
00959 methodVariant,
00960 v, stmt);
00961
00962
00963 FGNodeAST node = new FGNodeAST(v);
00964 FGWork work = new FGWorkSendVals(new FASet(valueVariant), node);
00965 FA.workList.insert(work);
00966
00967 astNodes.put(v,node);
00968 setResult(node);
00969 }
00970
00971
00972
00973
00974
00975 public void caseSubExpr(SubExpr v)
00976 {
00977 setResult(null);
00978 }
00979
00980
00981
00982
00983
00984
00985 public void caseThisRef(ThisRef v)
00986 {
00987 FGNodeThis thisNode = methodVariant.getThisNode();
00988 FGNodeAST astNode = new FGNodeAST(v);
00989 FGNode.makeArc(thisNode, astNode);
00990 astNodes.put(v,astNode);
00991
00992 setResult(astNode);
00993 }
00994
00995
00996
00997
00998
00999 public void caseUshrExpr(UshrExpr v)
01000 {
01001 setResult(null);
01002 }
01003
01004
01005
01006
01007
01008 public void caseVirtualInvokeExpr(VirtualInvokeExpr v)
01009 {
01010 SootMethod sootMethod = v.getMethod();
01011 int argCount = v.getArgCount();
01012 FGNode baseNode = build(v.getBase(), stmt);
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023 FGNode[] argNodes = new FGNode[argCount];
01024
01025 for (int i=0; i<argCount; i++) {
01026 argNodes[i] = build(v.getArg(i), stmt);
01027 }
01028
01029 FGNodeAST invokeNode = new FGNodeAST(v);
01030
01031
01032 baseNode.addAction(new FGActionInvoke(argCount,
01033 argNodes,
01034 invokeNode,
01035 sootMethod.getName(),
01036 sootMethod.getParameterTypes(),
01037 sootMethod.getReturnType()));
01038 setResult(invokeNode);
01039 astNodes.put(v,invokeNode);
01040 BOFA.callbackReg.callVInvoke(v, this);
01041 }
01042
01043
01044
01045
01046
01047 public void caseXorExpr(XorExpr v)
01048 {
01049 setResult(null);
01050 }
01051
01052
01053
01054
01055
01056 public void defaultCase(Object v)
01057 {
01058 cat.debug("Unhandled expression in" + " FGExpr:" + v.getClass() + " " + v);
01059 }
01060
01061
01062
01063
01064
01065
01066
01067
01068 protected static ClassTokenSimple getToken(String type)
01069 {
01070 if (!commonTokens.containsKey(type)) {
01071 commonTokens.put(type, ClassTokenSimple.select(new SootClass(type)));
01072 }
01073 return (ClassTokenSimple)commonTokens.get(type);
01074 }
01075
01076
01077
01078
01079
01080
01081
01082 protected Value getValue(String base)
01083 {
01084 if (base.equals("int"))
01085 return IntConstant.v(0);
01086 else if (base.equals("float"))
01087 return FloatConstant.v(0f);
01088 else if (base.equals("double"))
01089 return DoubleConstant.v(0);
01090 else if (base.equals("long"))
01091 return LongConstant.v(0);
01092 else
01093 return NullConstant.v();
01094 }
01095 }