1 19 20 23 24 25 36 37 38 45 package soot.dava.toolkits.base.AST.structuredAnalysis; 46 47 48 import soot.*; 49 import java.util.*; 50 import soot.jimple.*; 51 import soot.dava.internal.AST.*; 52 import soot.dava.internal.SET.*; 53 import soot.dava.internal.asg.*; 54 import soot.dava.internal.javaRep.*; 55 56 57 65 public abstract class StructuredAnalysis{ 66 67 72 DavaFlowSet NOPATH = new DavaFlowSet(); 73 int MERGETYPE; 75 final int UNDEFINED=0; 77 final int UNION=1; 78 final int INTERSECTION=2; 79 80 HashMap beforeSets,afterSets; 82 83 public StructuredAnalysis(){ 84 beforeSets = new HashMap(); 85 afterSets = new HashMap(); 86 MERGETYPE=UNDEFINED; 87 setMergeType(); 89 if(MERGETYPE == UNDEFINED) 91 throw new RuntimeException ("MERGETYPE UNDEFINED"); 92 } 93 94 99 public abstract void setMergeType(); 100 101 105 public abstract Object newInitialFlow(); 106 107 111 public abstract Object cloneFlowSet(Object flowSet); 112 113 117 public abstract Object processStatement(Stmt s, Object input); 118 119 120 121 128 public abstract Object processUnaryBinaryCondition(ASTUnaryBinaryCondition cond,Object input); 129 130 131 132 135 public abstract Object processSynchronizedLocal(Local local,Object input); 136 137 138 139 142 public abstract Object processSwitchKey(Value key,Object input); 143 144 145 146 147 public void print(Object toPrint){ 148 System.out.println(toPrint.toString()); 149 } 150 151 152 153 160 public Object processCondition(ASTCondition cond,Object input){ 161 if(cond instanceof ASTUnaryBinaryCondition){ 162 return processUnaryBinaryCondition((ASTUnaryBinaryCondition)cond,input); 163 } 164 else if (cond instanceof ASTAggregatedCondition){ 165 ASTCondition left = ((ASTAggregatedCondition)cond).getLeftOp(); 166 Object output1 = processCondition(left,input); 167 168 ASTCondition right = ((ASTAggregatedCondition)cond).getRightOp(); 169 Object output2 = processCondition(right,output1); 170 171 return merge(output1,output2); 172 } 173 else{ 174 throw new RuntimeException ("Unknown ASTCondition found in structred flow analysis"); 175 } 176 } 177 178 179 180 181 187 public Object process(Object body, Object input){ 188 if(!(input instanceof DavaFlowSet)) 189 throw new RuntimeException ("process method of StructuredAnalysis invoked with non DavaFlowSet object"); 190 191 if(body instanceof ASTNode){ 192 beforeSets.put(body,input); 193 Object temp=processASTNode((ASTNode)body,input); 194 afterSets.put(body,temp); 195 return temp; 196 } 197 else if(body instanceof Stmt){ 198 beforeSets.put(body,input); 199 Object result=processAbruptStatements((Stmt)body,(DavaFlowSet)input); 200 afterSets.put(body,result); 201 return result; 202 } 203 else if (body instanceof AugmentedStmt){ 204 AugmentedStmt as = (AugmentedStmt)body; 205 Stmt s = as.get_Stmt(); 206 207 beforeSets.put(s,input); 208 Object result=processAbruptStatements(s,(DavaFlowSet)input); 209 afterSets.put(s,result); 210 return result; 211 212 } 213 else if (body instanceof List){ 214 Iterator it = ((List)body).iterator(); 216 Object result=input; 217 while(it.hasNext()){ 218 Object temp = it.next(); 219 if(!(temp instanceof ASTNode)) 220 throw new RuntimeException ("Body sent to be processed by "+ 221 "StructuredAnalysis contains a list which does not have ASTNodes"); 222 else{ 223 227 beforeSets.put(temp,result); 228 result= processASTNode((ASTNode)temp,result); 229 afterSets.put(temp,result); 230 } 231 } 233 return result; 235 } 236 else{ 237 throw new RuntimeException ("Body sent to be processed by "+ 238 "StructuredAnalysis is not a valid body"); 239 } 240 } 241 242 243 247 public Object processASTNode(ASTNode node, Object input){ 248 if(node instanceof ASTDoWhileNode){ 249 return processASTDoWhileNode((ASTDoWhileNode)node,input); 250 } 251 else if(node instanceof ASTForLoopNode){ 252 return processASTForLoopNode((ASTForLoopNode)node,input); 253 } 254 else if(node instanceof ASTIfElseNode){ 255 return processASTIfElseNode((ASTIfElseNode)node,input); 256 } 257 else if(node instanceof ASTIfNode){ 258 return processASTIfNode((ASTIfNode)node,input); 259 } 260 else if(node instanceof ASTLabeledBlockNode){ 261 return processASTLabeledBlockNode((ASTLabeledBlockNode)node,input); 262 } 263 else if(node instanceof ASTMethodNode){ 264 return processASTMethodNode((ASTMethodNode)node,input); 265 } 266 else if(node instanceof ASTStatementSequenceNode){ 267 return processASTStatementSequenceNode((ASTStatementSequenceNode)node,input); 268 } 269 else if(node instanceof ASTSwitchNode){ 270 return processASTSwitchNode((ASTSwitchNode)node,input); 271 } 272 else if(node instanceof ASTSynchronizedBlockNode){ 273 return processASTSynchronizedBlockNode((ASTSynchronizedBlockNode)node,input); 274 } 275 else if(node instanceof ASTTryNode){ 276 return processASTTryNode((ASTTryNode)node,input); 277 } 278 else if(node instanceof ASTWhileNode){ 279 return processASTWhileNode((ASTWhileNode)node,input); 280 } 281 else if(node instanceof ASTUnconditionalLoopNode){ 282 return processASTUnconditionalLoopNode((ASTUnconditionalLoopNode)node,input); 283 } 284 else{ 285 throw new RuntimeException ("processASTNode called using unknown node type"); 286 } 287 } 288 289 290 296 public final Object processSingleSubBodyNode(ASTNode node, Object input){ 297 List subBodies = node.get_SubBodies(); 299 if(subBodies.size()!=1){ 300 throw new RuntimeException ("processSingleSubBodyNode called with a node without one subBody"); 301 } 302 List subBody = (List)subBodies.get(0); 304 return process(subBody,input); 305 } 306 307 308 309 310 314 private String getLabel(ASTNode node){ 315 if(node instanceof ASTLabeledNode){ 316 Object temp = ((ASTLabeledNode)node).get_Label(); 317 if(temp != null) 318 return temp.toString(); 319 } 320 return null; 321 } 322 323 324 325 326 332 public Object processAbruptStatements(Stmt s, DavaFlowSet input){ 333 if(s instanceof ReturnStmt || s instanceof RetStmt || s instanceof ReturnVoidStmt){ 334 return NOPATH; 336 } 337 else if(s instanceof DAbruptStmt){ 338 DAbruptStmt abStmt = (DAbruptStmt)s; 339 340 if(!(abStmt.is_Continue()|| abStmt.is_Break())){ 342 throw new RuntimeException ("Found a DAbruptStmt which is neither break nor continue!!"); 344 } 345 346 347 DavaFlowSet temp = NOPATH; 348 SETNodeLabel nodeLabel = abStmt.getLabel(); 349 if(nodeLabel != null && nodeLabel.toString() != null){ 351 if(abStmt.is_Continue()) 355 temp.addToContinueList(nodeLabel.toString(),input); 356 else if (abStmt.is_Break()) 357 temp.addToBreakList(nodeLabel.toString(),input); 358 else 359 throw new RuntimeException ("Found abruptstmt which is neither break nor continue"); 360 } 361 else{ 362 if(abStmt.is_Continue()) 365 temp.addToImplicitContinues(abStmt,input); 366 else if (abStmt.is_Break()) 367 temp.addToImplicitBreaks(abStmt,input); 368 else 369 throw new RuntimeException ("Found abruptstmt which is neither break nor continue"); 370 } 371 return temp; 372 } 373 else{ 374 375 376 377 return processStatement(s,input); 378 } 379 } 380 381 382 383 384 385 386 387 388 389 390 391 392 393 400 public Object processASTMethodNode(ASTMethodNode node,Object input){ 402 Object temp = processSingleSubBodyNode(node,input); 403 return temp; 404 } 405 406 407 408 409 410 411 412 413 414 415 public Object processASTStatementSequenceNode(ASTStatementSequenceNode node,Object input){ 416 List statements = node.getStatements(); 417 Iterator it = statements.iterator(); 418 419 Object output = cloneFlowSet(input); while(it.hasNext()){ 421 AugmentedStmt as = (AugmentedStmt)it.next(); 422 Stmt s = as.get_Stmt(); 423 427 output=process(s,output); 428 } 429 return output; 430 } 431 432 433 434 435 436 437 438 439 440 441 public Object processASTLabeledBlockNode(ASTLabeledBlockNode node,Object input){ 443 Object output1 = processSingleSubBodyNode(node,input); 444 445 String label = getLabel(node); 447 return handleBreak(label,output1,node); 448 } 449 450 451 452 453 454 455 456 457 458 459 public Object processASTSynchronizedBlockNode(ASTSynchronizedBlockNode node,Object input){ 460 input = processSynchronizedLocal(node.getLocal(),input); 461 462 Object output = processSingleSubBodyNode(node,input); 463 String label = getLabel(node); 464 return handleBreak(label,output,node); 465 } 466 467 468 469 470 471 472 473 474 475 476 477 478 public Object processASTIfNode(ASTIfNode node,Object input){ 480 input = processCondition(node.get_Condition(),input); 481 Object output1 = processSingleSubBodyNode(node,input); 482 483 Object output2 = merge(input,output1); 485 486 String label = getLabel(node); 488 489 Object temp= handleBreak(label,output2,node); 490 return temp; 491 } 492 493 494 495 496 497 498 499 500 501 502 503 504 public Object processASTIfElseNode(ASTIfElseNode node,Object input){ 505 List subBodies = node.get_SubBodies(); 507 if(subBodies.size()!=2){ 508 throw new RuntimeException ("processASTIfElseNode called with a node without two subBodies"); 509 } 510 List subBodyOne = (List)subBodies.get(0); 512 List subBodyTwo = (List)subBodies.get(1); 513 514 input = processCondition(node.get_Condition(),input); 516 Object clonedInput = cloneFlowSet(input); 518 Object output1 = process(subBodyOne,clonedInput); 519 520 clonedInput = cloneFlowSet(input); 521 Object output2 = process(subBodyTwo,clonedInput); 522 523 Object temp=merge(output1,output2); 524 525 String label = getLabel(node); 527 output1 = handleBreak(label,temp,node); 528 return output1; 529 } 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 public Object processASTWhileNode(ASTWhileNode node,Object input){ 551 Object lastin=null; 552 Object initialInput = cloneFlowSet(input); 553 554 String label = getLabel(node); 555 Object output=null; 556 557 input = processCondition(node.get_Condition(),input); 558 559 do{ 560 lastin = cloneFlowSet(input); 561 output = processSingleSubBodyNode(node,input); 562 563 output = handleContinue(label,output,node); 565 566 input = merge(initialInput,output); 568 input = processCondition(node.get_Condition(),input); 569 } while(isDifferent(lastin,input)); 570 571 Object temp= handleBreak(label,input,node); 573 return temp; 574 } 575 576 577 578 579 580 581 582 583 584 585 586 587 public Object processASTDoWhileNode(ASTDoWhileNode node, Object input){ 588 Object lastin=null,output=null; 589 Object initialInput = cloneFlowSet(input); 590 String label = getLabel(node); 591 592 do{ 593 lastin = cloneFlowSet(input); 594 output = processSingleSubBodyNode(node,input); 595 596 output = handleContinue(label,output,node); 598 599 output = processCondition(node.get_Condition(),output); 600 601 input = merge(initialInput,output); 603 } while(isDifferent(lastin,input)); 604 605 Object temp= handleBreak(label,output,node); 607 return temp; 608 609 } 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 public Object processASTUnconditionalLoopNode(ASTUnconditionalLoopNode node,Object input){ 627 Object initialInput = cloneFlowSet(input); 629 Object lastin=null; 630 631 String label = getLabel(node); 632 Object output=null; 633 do{ 634 lastin = cloneFlowSet(input); 635 output = processSingleSubBodyNode(node,input); 636 637 output = handleContinue(label,output,node); 639 640 input = merge(initialInput,output); 642 } while(isDifferent(lastin,input)); 643 644 return getMergedBreakList(label,output,node); 647 } 648 649 650 651 652 653 654 655 656 657 658 659 660 661 public Object processASTForLoopNode(ASTForLoopNode node,Object input){ 662 List init = node.getInit(); 663 Iterator it = init.iterator(); 664 while(it.hasNext()){ 665 AugmentedStmt as = (AugmentedStmt)it.next(); 666 Stmt s = as.get_Stmt(); 667 input = process(s,input); 668 } 669 670 Object initialInput = cloneFlowSet(input); 672 673 input = processCondition(node.get_Condition(),input); 674 Object lastin = null; 675 String label = getLabel(node); 676 Object output2=null; 677 do{ 678 lastin = cloneFlowSet(input); 679 680 Object output1 = processSingleSubBodyNode(node,input); 682 683 output1 = handleContinue(label,output1,node); 685 686 689 output2 = cloneFlowSet(output1); 692 List update = node.getUpdate(); 693 it = update.iterator(); 694 while(it.hasNext()){ 695 AugmentedStmt as = (AugmentedStmt)it.next(); 696 Stmt s = as.get_Stmt(); 697 701 output2 = process(s,output2); 702 } 703 704 706 input = merge(initialInput,output2); 708 input = processCondition(node.get_Condition(),input); 709 }while(isDifferent(lastin,input)); 710 711 return handleBreak(label,input,node); 713 } 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 736 public Object processASTSwitchNode(ASTSwitchNode node,Object input){ 737 List indexList = node.getIndexList(); 738 Map index2BodyList = node.getIndex2BodyList(); 739 740 Iterator it = indexList.iterator(); 741 742 743 input=processSwitchKey(node.get_Key(),input); 744 Object initialIn = cloneFlowSet(input); 745 746 Object out = null; 747 Object defaultOut = null; 748 749 List toMergeBreaks = new ArrayList(); 750 751 while (it.hasNext()) { Object currentIndex = it.next(); 753 List body = (List) index2BodyList.get( currentIndex); 754 755 if(body != null){ 758 out=process(body,input); 759 760 toMergeBreaks.add(cloneFlowSet(out)); 762 763 if(currentIndex instanceof String ){ 764 defaultOut=out; 766 } 767 768 input=merge(out,initialIn); 770 } } 772 773 Object output=null; 775 if(out!=null){ 777 784 if(defaultOut!=null){ 785 790 output=merge(defaultOut,out); 791 }else{ 792 output = merge(initialIn,out); 794 } 795 796 } 797 else 798 output = initialIn; 799 800 String label = getLabel(node); 802 803 805 List outList = new ArrayList(); 806 807 it = toMergeBreaks.iterator(); 809 while(it.hasNext()){ 810 outList.add(handleBreak(label,it.next(),node)); 811 } 812 813 Object finalOut=output; 815 it = outList.iterator(); 816 while(it.hasNext()){ 817 finalOut = merge(finalOut,it.next()); 818 } 819 820 return finalOut; 821 } 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 public Object processASTTryNode(ASTTryNode node,Object input){ 842 List tryBody = node.get_TryBody(); 844 Object tryBodyOutput = process(tryBody,input); 845 847 851 Object inputCatch = newInitialFlow(); 852 853 List catchList = node.get_CatchList(); 854 Iterator it = catchList.iterator(); 855 List catchOutput = new ArrayList(); 856 857 while (it.hasNext()) { 858 ASTTryNode.container catchBody = (ASTTryNode.container)it.next(); 859 860 List body = (List)catchBody.o; 861 863 Object tempResult = process(body,cloneFlowSet(inputCatch)); 865 catchOutput.add(tempResult); 867 } 868 869 String label = getLabel(node); 871 872 873 874 885 List outList = new ArrayList(); 886 887 outList.add(handleBreak(label,tryBodyOutput,node)); 889 891 it = catchOutput.iterator(); 893 while(it.hasNext()){ 894 outList.add(handleBreak(label,it.next(),node)); 895 } 896 897 898 Object out=tryBodyOutput; 900 it = outList.iterator(); 901 while(it.hasNext()){ 902 out = merge(out,it.next()); 903 } 904 905 906 907 909 it = catchOutput.iterator(); 910 while(it.hasNext()){ 911 out = merge(out,it.next()); 912 } 913 return out; 915 } 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 939 public Object merge(Object obj1, Object obj2){ 940 if(MERGETYPE==0) 941 throw new RuntimeException ("Use the setMergeType method to set the type of merge used in the analysis"); 942 943 if( !(obj1 instanceof DavaFlowSet) || !(obj2 instanceof DavaFlowSet) ){ 944 954 955 throw new RuntimeException ("merge not implemented for other flowSet types"); 956 } 957 958 DavaFlowSet in1 = (DavaFlowSet)obj1; 959 DavaFlowSet in2 = (DavaFlowSet)obj2; 960 961 DavaFlowSet out = new DavaFlowSet(); 962 if(in1 == NOPATH && in2 != NOPATH){ 963 out = (DavaFlowSet)in2.clone(); 964 out.copyInternalDataFrom(in1); 965 return out; 966 } 967 else if(in1 != NOPATH && in2 == NOPATH){ 968 out = (DavaFlowSet)in1.clone(); 969 out.copyInternalDataFrom(in2); 970 return out; 971 } 972 else if(in1 == NOPATH && in2 == NOPATH){ 973 out = (DavaFlowSet)in1.clone(); 974 out.copyInternalDataFrom(in2); 975 return out; } 977 else{ if(MERGETYPE==1) ((DavaFlowSet)obj1).union((DavaFlowSet)obj2, out); 980 else if(MERGETYPE==2) ((DavaFlowSet)obj1).intersection((DavaFlowSet)obj2, out); 982 else 983 throw new RuntimeException ("Merge type value"+MERGETYPE+" not recognized"); 984 out.copyInternalDataFrom(obj1); 985 out.copyInternalDataFrom(obj2); 986 return out; 987 } 988 } 989 990 991 992 public Object mergeExplicitAndImplicit(String label,DavaFlowSet output,List explicitSet, List implicitSet){ 993 Object toReturn = output.clone(); 994 995 if(label!=null){ 996 1002 if(explicitSet != null && explicitSet.size()!=0){ 1003 Iterator it = explicitSet.iterator(); 1005 1006 toReturn = merge(output,it.next()); 1008 1009 while(it.hasNext()){ 1010 toReturn = merge(toReturn,it.next()); 1012 } 1013 } } 1016 1018 if(implicitSet != null){ 1020 Iterator it = implicitSet.iterator(); 1022 while(it.hasNext()){ 1023 toReturn = merge(toReturn,it.next()); 1025 } 1026 } 1027 return toReturn; 1028 } 1029 1030 1031 1032 1033 1039 public Object handleBreak(String label,Object output,ASTNode node){ 1040 if( !(output instanceof DavaFlowSet) ) 1041 throw new RuntimeException ("handleBreak is only implemented for DavaFlowSet type"); 1042 1043 DavaFlowSet out = (DavaFlowSet)output; 1044 1045 List explicitSet = out.getBreakSet(label); 1047 if(node ==null) 1050 throw new RuntimeException ("ASTNode sent to handleBreak was null"); 1051 1052 List implicitSet = out.getImplicitlyBrokenSets(node); 1053 1055 return mergeExplicitAndImplicit(label,out,explicitSet,implicitSet); 1057 } 1058 1059 1060 1061 1062 1063 1064 1065 1071 public Object handleContinue(String label,Object output,ASTNode node){ 1072 if( !(output instanceof DavaFlowSet) ) 1073 throw new RuntimeException ("handleContinue is only implemented for DavaFlowSet type"); 1074 1075 DavaFlowSet out = (DavaFlowSet)output; 1076 1077 List explicitSet = out.getContinueSet(label); 1079 1080 if(node ==null) 1082 throw new RuntimeException ("ASTNode sent to handleContinue was null"); 1083 1084 List implicitSet = out.getImplicitlyContinuedSets(node); 1085 1086 return mergeExplicitAndImplicit(label,out,explicitSet,implicitSet); 1088 } 1089 1090 1091 1092 1093 1094 1098 private Object getMergedBreakList(String label,Object output,ASTNode node){ 1099 if( !(output instanceof DavaFlowSet) ) 1100 throw new RuntimeException ("getMergedBreakList is only implemented for DavaFlowSet type"); 1101 1102 List breakSet = ((DavaFlowSet)output).getBreakSet(label); 1103 Object toReturn = null; 1104 1105 if(breakSet ==null){ 1106 toReturn = NOPATH; 1109 } 1110 else if(breakSet.size()==0){ 1111 toReturn = NOPATH; 1114 } 1115 else{ 1116 Iterator it = breakSet.iterator(); 1118 1119 toReturn = it.next(); 1122 1123 while(it.hasNext()){ 1124 toReturn = merge(toReturn,it.next()); 1126 } 1127 } 1129 1131 List implicitSet = ((DavaFlowSet)output).getImplicitlyBrokenSets(node); 1132 if(implicitSet != null){ 1133 Iterator it = implicitSet.iterator(); 1135 1136 if(implicitSet.size()>0) 1138 toReturn = it.next(); 1139 1140 while(it.hasNext()){ 1141 toReturn = merge(toReturn,it.next()); 1143 } 1144 } 1145 return toReturn; 1146 } 1147 1148 1149 public boolean isDifferent(Object oldObj, Object newObj){ 1150 if(oldObj instanceof DavaFlowSet && newObj instanceof DavaFlowSet){ 1151 if (((DavaFlowSet)oldObj).equals(newObj) && ((DavaFlowSet)oldObj).internalDataMatchesTo(newObj)){ 1152 return false; 1154 } 1155 else{ 1156 return true; 1159 } 1160 } 1161 else 1162 throw new RuntimeException ("isDifferent not implemented for other flowSet types"); 1163 } 1164 1165 1166 public Object getBeforeSet(Object beforeThis){ 1167 return beforeSets.get(beforeThis); 1168 } 1169 1170 public Object getAfterSet(Object afterThis){ 1171 return afterSets.get(afterThis); 1172 } 1173} | Popular Tags |