1 19 20 25 26 27 28 29 30 31 32 package soot.coffi; 33 import soot.options.*; 34 import soot.jimple.*; 35 import soot.util.*; 36 import java.util.*; 37 import java.io.*; 38 import soot.baf.*; 39 import soot.tagkit.*; 40 import soot.*; 41 42 43 public class Util 44 { 45 public Util( Singletons.Global g ) {} 46 public static Util v() { return G.v().soot_coffi_Util(); } 47 48 49 Map classNameToAbbreviation; 50 Set markedClasses; 51 LinkedList classesToResolve; 52 53 int activeOriginalIndex = -1; 54 cp_info[] activeConstantPool = null; 55 LocalVariableTable_attribute activeVariableTable; 56 LocalVariableTypeTable_attribute activeVariableTypeTable; 57 boolean useFaithfulNaming = false; 58 boolean isLocalStore = false; boolean isWideLocalStore = false; 60 public void setFaithfulNaming(boolean v) 61 { 62 useFaithfulNaming = v; 63 } 64 65 public void resolveFromClassFile(SootClass aClass, InputStream is, List references) 66 { 67 SootClass bclass = aClass; 68 String className = bclass.getName(); 69 ClassFile coffiClass = new ClassFile(className); 70 71 { 73 boolean success = coffiClass.loadClassFile(is); 74 75 if(!success) 76 { 77 if(!Scene.v().allowsPhantomRefs()) 78 throw new RuntimeException ("Could not load classfile: " + bclass.getName()); 79 else { 80 G.v().out.println("Warning: " + className + " is a phantom class!"); 81 bclass.setPhantom(true); 82 return; 83 } 84 85 } 86 87 CONSTANT_Class_info c = (CONSTANT_Class_info) coffiClass.constant_pool[coffiClass.this_class]; 88 89 String name = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[c.name_index])).convert(); 90 name = name.replace('/', '.'); 91 92 if( !name.equals( bclass.getName() ) ) { 93 throw new RuntimeException ( 94 "Error: class "+name+" read in from a classfile in which "+bclass.getName()+" was expected." ); 95 } 96 } 97 98 bclass.setModifiers(coffiClass.access_flags & (~0x0020)); 100 102 { 104 if(coffiClass.super_class != 0) 105 { 106 108 CONSTANT_Class_info c = (CONSTANT_Class_info) coffiClass.constant_pool[coffiClass.super_class]; 109 110 String superName = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[c.name_index])).convert(); 111 superName = superName.replace('/', '.'); 112 113 references.add(superName); 114 bclass.setSuperclass(SootResolver.v().makeClassRef(superName)); 115 } 116 } 117 118 { 120 for(int i = 0; i < coffiClass.interfaces_count; i++) 121 { 122 CONSTANT_Class_info c = (CONSTANT_Class_info) coffiClass.constant_pool[coffiClass.interfaces[i]]; 123 124 String interfaceName = 125 ((CONSTANT_Utf8_info) (coffiClass.constant_pool[c.name_index])).convert(); 126 127 interfaceName = interfaceName.replace('/', '.'); 128 129 references.add(interfaceName); 130 SootClass interfaceClass = SootResolver.v().makeClassRef(interfaceName); 131 bclass.addInterface(interfaceClass); 132 } 133 } 134 135 for(int i = 0; i < coffiClass.fields_count; i++){ 137 138 field_info fieldInfo = coffiClass.fields[i]; 139 140 String fieldName = ((CONSTANT_Utf8_info) 141 (coffiClass.constant_pool[fieldInfo.name_index])).convert(); 142 143 String fieldDescriptor = ((CONSTANT_Utf8_info) 144 (coffiClass.constant_pool[fieldInfo.descriptor_index])).convert(); 145 146 int modifiers = fieldInfo.access_flags; 147 Type fieldType = jimpleTypeOfFieldDescriptor(fieldDescriptor); 148 149 SootField field = new SootField(fieldName, fieldType, modifiers); 150 bclass.addField(field); 151 152 references.add(fieldType); 153 154 for(int j = 0; j < fieldInfo.attributes_count; j++) { 156 if (fieldInfo.attributes[j] instanceof ConstantValue_attribute){ 158 159 ConstantValue_attribute attr = (ConstantValue_attribute) fieldInfo.attributes[j]; 160 cp_info cval = coffiClass.constant_pool[attr.constantvalue_index]; 161 ConstantValueTag tag; 162 switch (cval.tag) { 163 case cp_info.CONSTANT_Integer: 164 tag = new IntegerConstantValueTag((int)((CONSTANT_Integer_info)cval).bytes); 165 break; 166 case cp_info.CONSTANT_Float: 167 tag = new FloatConstantValueTag(((CONSTANT_Float_info)cval).convert()); 169 break; 170 case cp_info.CONSTANT_Long: 171 { 172 CONSTANT_Long_info lcval = (CONSTANT_Long_info)cval; 173 tag = new LongConstantValueTag((lcval.high << 32) + lcval.low); 174 break; 175 } 176 case cp_info.CONSTANT_Double: 177 { 178 CONSTANT_Double_info dcval = (CONSTANT_Double_info)cval; 179 tag = new DoubleConstantValueTag(dcval.convert()); 181 break; 182 } 183 case cp_info.CONSTANT_String: 184 { 185 CONSTANT_String_info scval = (CONSTANT_String_info)cval; 186 CONSTANT_Utf8_info ucval = (CONSTANT_Utf8_info)coffiClass.constant_pool[scval.string_index]; 187 tag = new StringConstantValueTag(ucval.convert()); 188 break; 189 } 190 default: 191 throw new RuntimeException ("unexpected ConstantValue: " + cval); 192 } 193 field.addTag(tag); 194 } 195 else if (fieldInfo.attributes[j] instanceof Synthetic_attribute){ 197 field.addTag(new SyntheticTag()); 198 } 199 else if (fieldInfo.attributes[j] instanceof Deprecated_attribute){ 201 field.addTag(new DeprecatedTag()); 202 } 203 else if (fieldInfo.attributes[j] instanceof Signature_attribute){ 205 String generic_sig = ((CONSTANT_Utf8_info)(coffiClass.constant_pool[((Signature_attribute)fieldInfo.attributes[j]).signature_index])).convert(); 206 field.addTag(new SignatureTag(generic_sig)); 207 } 208 else if (fieldInfo.attributes[j] instanceof RuntimeVisibleAnnotations_attribute || fieldInfo.attributes[j] instanceof RuntimeInvisibleAnnotations_attribute) 209 { 210 addAnnotationVisibilityAttribute(field, fieldInfo.attributes[j], coffiClass, references); 211 } 212 } 213 } 214 215 for(int i = 0; i < coffiClass.methods_count; i++){ 217 218 method_info methodInfo = coffiClass.methods[i]; 219 220 221 if( (coffiClass.constant_pool[methodInfo.name_index]) == null) { 222 G.v().out.println("method index: " + methodInfo.toName(coffiClass.constant_pool)); 223 throw new RuntimeException ("method has no name"); 224 } 225 226 String methodName = ((CONSTANT_Utf8_info)(coffiClass.constant_pool[methodInfo.name_index])).convert(); 227 String methodDescriptor = ((CONSTANT_Utf8_info)(coffiClass.constant_pool[methodInfo.descriptor_index])).convert(); 228 229 List parameterTypes; 230 Type returnType; 231 232 { 234 Type[] types = jimpleTypesOfFieldOrMethodDescriptor(methodDescriptor); 235 236 parameterTypes = new ArrayList(); 237 for(int j = 0; j < types.length - 1; j++){ 238 references.add(types[j]); 239 parameterTypes.add(types[j]); 240 } 241 242 returnType = types[types.length - 1]; 243 references.add(returnType); 244 } 245 246 int modifiers = methodInfo.access_flags; 247 248 SootMethod method; 249 250 method = new SootMethod(methodName, 251 parameterTypes, returnType, modifiers); 252 bclass.addMethod(method); 253 254 methodInfo.jmethod = method; 255 256 { 258 for(int j = 0; j < methodInfo.attributes_count; j++){ 259 if(methodInfo.attributes[j] instanceof Exception_attribute){ 260 Exception_attribute exceptions = (Exception_attribute) methodInfo.attributes[j]; 261 262 for(int k = 0; k < exceptions.number_of_exceptions; k++) 263 { 264 CONSTANT_Class_info c = (CONSTANT_Class_info) coffiClass. 265 constant_pool[exceptions.exception_index_table[k]]; 266 267 String exceptionName = ((CONSTANT_Utf8_info)(coffiClass.constant_pool[c.name_index])).convert(); 268 269 exceptionName = exceptionName.replace('/', '.'); 270 271 references.add(exceptionName); 272 method.addExceptionIfAbsent(SootResolver.v().makeClassRef(exceptionName)); 273 } 274 } 275 else if (methodInfo.attributes[j] instanceof Synthetic_attribute) { 276 method.addTag(new SyntheticTag()); 277 } 278 else if (methodInfo.attributes[j] instanceof Deprecated_attribute) { 279 method.addTag(new DeprecatedTag()); 280 } 281 else if (methodInfo.attributes[j] instanceof Signature_attribute){ 282 String generic_sig = ((CONSTANT_Utf8_info)(coffiClass.constant_pool[((Signature_attribute)methodInfo.attributes[j]).signature_index])).convert(); 283 method.addTag(new SignatureTag(generic_sig)); 284 } 285 else if (methodInfo.attributes[j] instanceof RuntimeVisibleAnnotations_attribute || methodInfo.attributes[j] instanceof RuntimeInvisibleAnnotations_attribute) 286 { 287 addAnnotationVisibilityAttribute(method, methodInfo.attributes[j], coffiClass, references); 288 } 289 else if (methodInfo.attributes[j] instanceof RuntimeVisibleParameterAnnotations_attribute || methodInfo.attributes[j] instanceof RuntimeInvisibleParameterAnnotations_attribute) 290 { 291 addAnnotationVisibilityParameterAttribute(method, methodInfo.attributes[j], coffiClass, references); 292 } 293 else if (methodInfo.attributes[j] instanceof AnnotationDefault_attribute) 294 { 295 AnnotationDefault_attribute attr = (AnnotationDefault_attribute)methodInfo.attributes[j]; 296 element_value [] input = new element_value[1]; 297 input[0] = attr.default_value; 298 ArrayList list = createElementTags(1, coffiClass, input); 299 method.addTag(new AnnotationDefaultTag((AnnotationElem)list.get(0))); 300 } 301 } 302 } 303 304 { 306 for(int k = 0; k < coffiClass.constant_pool_count; k++) { 307 if(coffiClass.constant_pool[k] instanceof CONSTANT_Class_info) 308 { 309 CONSTANT_Class_info c = (CONSTANT_Class_info) coffiClass.constant_pool[k]; 310 311 String desc = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[c.name_index])).convert(); 312 String name = desc.replace('/', '.'); 313 314 if(name.startsWith("[")) 315 references.add(jimpleTypeOfFieldDescriptor(desc)); 316 else 317 references.add(name); 318 } 319 if(coffiClass.constant_pool[k] instanceof CONSTANT_Fieldref_info 320 || coffiClass.constant_pool[k] instanceof CONSTANT_Methodref_info 321 || coffiClass.constant_pool[k] instanceof CONSTANT_InterfaceMethodref_info) { 322 Type[] types = jimpleTypesOfFieldOrMethodDescriptor( 323 cp_info.getTypeDescr(coffiClass.constant_pool,k)); 324 for( int ii = 0; ii < types.length; ii++ ) { 325 references.add(types[ii]); 326 } 327 } 328 329 } 330 } 331 } 332 333 for(int i = 0; i < coffiClass.methods_count; i++) 335 { 336 method_info methodInfo = coffiClass.methods[i]; 337 methodInfo.jmethod.setSource(new CoffiMethodSource(coffiClass, methodInfo)); 339 } 340 341 for(int i = 0; i < coffiClass.attributes_count; i++){ 343 344 if(coffiClass.attributes[i] instanceof SourceFile_attribute){ 345 346 SourceFile_attribute attr = (SourceFile_attribute)coffiClass.attributes[i]; 347 String sourceFile = ((CONSTANT_Utf8_info)(coffiClass.constant_pool[attr.sourcefile_index])).convert(); 348 349 if( sourceFile.indexOf(' ') >= 0 ) { 350 G.v().out.println( "Warning: Class "+className+" has invalid SourceFile attribute (will be ignored)." ); 351 } else { 352 bclass.addTag(new SourceFileTag( sourceFile ) ); 353 } 354 355 } 356 else if(coffiClass.attributes[i] instanceof InnerClasses_attribute){ 358 359 InnerClasses_attribute attr = (InnerClasses_attribute)coffiClass.attributes[i]; 360 for (int j = 0; j < attr.inner_classes_length; j++) 361 { 362 inner_class_entry e = attr.inner_classes[j]; 363 String inner = null; 364 String outer = null; 365 String name = null; 366 int class_index; 367 368 if (e.inner_class_index != 0) 369 inner = ((CONSTANT_Utf8_info)coffiClass.constant_pool[((CONSTANT_Class_info)coffiClass.constant_pool[e.inner_class_index]).name_index]).convert(); 370 if (e.outer_class_index != 0) 371 outer = ((CONSTANT_Utf8_info)coffiClass.constant_pool[((CONSTANT_Class_info)coffiClass.constant_pool[e.outer_class_index]).name_index]).convert(); 372 if (e.name_index != 0) 373 name = ((CONSTANT_Utf8_info)(coffiClass.constant_pool[e.name_index])).convert(); 374 bclass.addTag(new InnerClassTag(inner, outer, name, e.access_flags)); 375 } 376 } 377 else if(coffiClass.attributes[i] instanceof Synthetic_attribute){ 379 380 Synthetic_attribute attr = (Synthetic_attribute)coffiClass.attributes[i]; 381 bclass.addTag(new SyntheticTag()); 382 } 383 else if(coffiClass.attributes[i] instanceof Deprecated_attribute){ 385 386 Deprecated_attribute attr = (Deprecated_attribute)coffiClass.attributes[i]; 387 bclass.addTag(new DeprecatedTag()); 388 } 389 else if (coffiClass.attributes[i] instanceof Signature_attribute){ 390 String generic_sig = ((CONSTANT_Utf8_info)(coffiClass.constant_pool[((Signature_attribute)coffiClass.attributes[i]).signature_index])).convert(); 391 bclass.addTag(new SignatureTag(generic_sig)); 392 } 393 else if (coffiClass.attributes[i] instanceof EnclosingMethod_attribute){ 394 EnclosingMethod_attribute attr = (EnclosingMethod_attribute)coffiClass.attributes[i]; 395 String class_name = ((CONSTANT_Utf8_info)coffiClass.constant_pool[((CONSTANT_Class_info)coffiClass.constant_pool[ attr.class_index ]).name_index]).convert(); 396 CONSTANT_NameAndType_info info = (CONSTANT_NameAndType_info)coffiClass.constant_pool[attr.method_index]; 397 398 String method_name = ""; 399 String method_sig = ""; 400 401 if (info != null){ 402 method_name = ((CONSTANT_Utf8_info)coffiClass.constant_pool[info.name_index]).convert(); 403 method_sig = ((CONSTANT_Utf8_info)coffiClass.constant_pool[info.descriptor_index]).convert(); 404 } 405 bclass.addTag(new EnclosingMethodTag(class_name, method_name, method_sig)); 406 } 407 else if (coffiClass.attributes[i] instanceof RuntimeVisibleAnnotations_attribute || coffiClass.attributes[i] instanceof RuntimeInvisibleAnnotations_attribute) 408 { 409 addAnnotationVisibilityAttribute(bclass, coffiClass.attributes[i], coffiClass, references); 410 } 411 412 } 413 } 414 415 416 417 Type jimpleReturnTypeOfMethodDescriptor(String descriptor) 418 { 419 Type[] types = jimpleTypesOfFieldOrMethodDescriptor(descriptor); 420 421 return types[types.length - 1]; 422 } 423 424 private ArrayList conversionTypes = new ArrayList(); 425 426 533 534 535 private Map cache = new HashMap(); 536 public Type[] jimpleTypesOfFieldOrMethodDescriptor(String descriptor) 537 { 538 Type[] ret = (Type[]) cache.get(descriptor); 539 if( ret != null ) return ret; 540 char[] d = descriptor.toCharArray(); 541 int p = 0; 542 conversionTypes.clear(); 543 544 outer: 545 while(p<d.length) 546 { 547 boolean isArray = false; 548 int numDimensions = 0; 549 Type baseType = null; 550 551 swtch: 552 while(p<d.length) { 553 switch( d[p] ) { 554 case '(': case ')': 556 p++; 557 continue outer; 558 559 case '[': 560 isArray = true; 561 numDimensions++; 562 p++; 563 continue swtch; 564 case 'B': 565 baseType = ByteType.v(); 566 p++; 567 break swtch; 568 case 'C': 569 baseType = CharType.v(); 570 p++; 571 break swtch; 572 case 'D': 573 baseType = DoubleType.v(); 574 p++; 575 break swtch; 576 case 'F': 577 baseType = FloatType.v(); 578 p++; 579 break swtch; 580 case 'I': 581 baseType = IntType.v(); 582 p++; 583 break swtch; 584 case 'J': 585 baseType = LongType.v(); 586 p++; 587 break swtch; 588 case 'L': 589 int index = p+1; 590 while(index < d.length && d[index] != ';') { 591 if(d[index] == '/') d[index] = '.'; 592 index++; 593 } 594 if( index >= d.length ) 595 throw new RuntimeException ("Class reference has no ending ;"); 596 String className = new String (d, p+1, index - p - 1); 597 baseType = RefType.v(className); 598 p = index+1; 599 break swtch; 600 case 'S': 601 baseType = ShortType.v(); 602 p++; 603 break swtch; 604 case 'Z': 605 baseType = BooleanType.v(); 606 p++; 607 break swtch; 608 case 'V': 609 baseType = VoidType.v(); 610 p++; 611 break swtch; 612 default: 613 throw new RuntimeException ("Unknown field type!"); 614 } 615 } 616 if( baseType == null ) continue; 617 618 Type t; 620 if(isArray) 621 t = ArrayType.v(baseType, numDimensions); 622 else 623 t = baseType; 624 625 conversionTypes.add(t); 626 } 627 628 ret = (Type[]) conversionTypes.toArray(new Type[0]); 629 cache.put(descriptor, ret); 630 return ret; 631 } 632 633 public Type jimpleTypeOfFieldDescriptor(String descriptor) 634 { 635 boolean isArray = false; 636 int numDimensions = 0; 637 Type baseType; 638 639 while(descriptor.startsWith("[")) 641 { 642 isArray = true; 643 numDimensions++; 644 descriptor = descriptor.substring(1); 645 } 646 647 if(descriptor.equals("B")) 649 baseType = ByteType.v(); 650 else if(descriptor.equals("C")) 651 baseType = CharType.v(); 652 else if(descriptor.equals("D")) 653 baseType = DoubleType.v(); 654 else if(descriptor.equals("F")) 655 baseType = FloatType.v(); 656 else if(descriptor.equals("I")) 657 baseType = IntType.v(); 658 else if(descriptor.equals("J")) 659 baseType = LongType.v(); 660 else if(descriptor.equals("V")) 661 baseType = VoidType.v(); 662 else if(descriptor.startsWith("L")) 663 { 664 if(!descriptor.endsWith(";")) 665 throw new RuntimeException ("Class reference does not end with ;"); 666 667 String className = descriptor.substring(1, descriptor.length() - 1); 668 669 baseType = RefType.v(className.replace('/', '.')); 670 } 671 else if(descriptor.equals("S")) 672 baseType = ShortType.v(); 673 else if(descriptor.equals("Z")) 674 baseType = BooleanType.v(); 675 else 676 throw new RuntimeException ("Unknown field type: " + descriptor); 677 678 if(isArray) 680 return ArrayType.v(baseType, numDimensions); 681 else 682 return baseType; 683 } 684 685 int nextEasyNameIndex; 686 687 void resetEasyNames() 688 { 689 nextEasyNameIndex = 0; 690 } 691 692 String getNextEasyName() 693 { 694 final String [] easyNames = 695 {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", 696 "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"}; 697 698 int justifiedIndex = nextEasyNameIndex++; 699 700 if(justifiedIndex >= easyNames.length) 701 return "local" + (justifiedIndex - easyNames.length); 702 else 703 return easyNames[justifiedIndex]; 704 } 705 706 void setClassNameToAbbreviation(Map map) 707 { 708 classNameToAbbreviation = map; 709 } 710 711 Local getLocalForStackOp(JimpleBody listBody, TypeStack typeStack, 712 int index) 713 { 714 if(typeStack.get(index).equals(Double2ndHalfType.v()) || 715 typeStack.get(index).equals(Long2ndHalfType.v())) 716 { 717 index--; 718 } 719 720 return getLocalCreatingIfNecessary(listBody, "$stack" + index, UnknownType.v()); 721 } 722 723 String getAbbreviationOfClassName(String className) 724 { 725 StringBuffer buffer = new StringBuffer (new Character (className.charAt(0)).toString()); 726 int periodIndex = 0; 727 728 for(;;) 729 { 730 periodIndex = className.indexOf('.', periodIndex + 1); 731 732 if(periodIndex == -1) 733 break; 734 735 buffer.append(Character.toLowerCase(className.charAt(periodIndex + 1))); 736 } 737 738 return buffer.toString(); 739 } 740 741 String getNormalizedClassName(String className) 742 { 743 className = className.replace('/', '.'); 744 745 if(className.endsWith(";")) 746 className = className.substring(0, className.length() - 1); 747 748 { 750 int numDimensions = 0; 751 752 while(className.startsWith("[")) 753 { 754 numDimensions++; 755 className = className.substring(1, className.length()); 756 className = className + "[]"; 757 } 758 759 if(numDimensions != 0) 760 { 761 if(!className.startsWith("L")) 762 throw new RuntimeException ("For some reason an array reference does not start with L"); 763 764 className = className.substring(1, className.length()); 765 } 766 } 767 768 769 return className; 770 } 771 772 public Local getLocal(Body b, String name) 773 throws soot.jimple.NoSuchLocalException 774 { 775 Iterator localIt = b.getLocals().iterator(); 776 777 while(localIt.hasNext()) 778 { 779 Local local = (Local) localIt.next(); 780 781 if(local.getName().equals(name)) 782 return local; 783 } 784 785 throw new soot.jimple.NoSuchLocalException(); 786 } 787 788 789 public boolean declaresLocal(Body b, String localName) 790 { 791 Iterator localIt = b.getLocals().iterator(); 792 793 while(localIt.hasNext()) 794 { 795 Local local = (Local) localIt.next(); 796 797 if(local.getName().equals(localName)) 798 return true; 799 } 800 801 return false; 802 } 803 804 Local 805 getLocalCreatingIfNecessary(JimpleBody listBody, String name, Type type) 806 { 807 if(declaresLocal(listBody, name)) 808 { 809 return getLocal(listBody, name); 810 } 811 else { 812 Local l = Jimple.v().newLocal(name, type); 813 listBody.getLocals().add(l); 814 815 return l; 816 } 817 } 818 819 Local getLocalForIndex(JimpleBody listBody, int index) 820 { 821 String name = null; 822 String debug_type = null; 823 boolean assignedName = false; 824 boolean assignedType = false; 825 826 if(useFaithfulNaming && activeVariableTable != null) 827 { 828 if(activeOriginalIndex != -1) 829 { 830 831 if(isLocalStore) 835 activeOriginalIndex++; 836 if(isWideLocalStore) 837 activeOriginalIndex++; 838 839 name = activeVariableTable.getLocalVariableName(activeConstantPool, index, activeOriginalIndex); 840 if (activeVariableTypeTable != null){ 841 debug_type = activeVariableTypeTable.getLocalVariableType(activeConstantPool, index, activeOriginalIndex); 842 if (debug_type != null){ 843 assignedType = true; 844 } 845 } 846 if(name != null) 847 assignedName = true; 848 } 849 } 850 851 if(!assignedName) 852 name = "l" + index; 853 854 if(declaresLocal(listBody, name)) 855 return getLocal(listBody, name); 856 else { 857 Local l = Jimple.v().newLocal(name, 858 UnknownType.v()); 859 860 listBody.getLocals().add(l); 861 864 865 return l; 866 } 867 } 868 869 909 910 921 boolean isValidJimpleName(String prospectiveName) { 922 if(prospectiveName == null) return false; 923 for (int i = 0; i < prospectiveName.length(); i++) { 924 char c = prospectiveName.charAt(i); 925 if (i == 0 && c >= '0' && c <= '9') 926 return false; 927 928 if (!((c >= '0' && c <= '9') || 929 (c >= 'a' && c <= 'z') || 930 (c >= 'A' && c <= 'Z') || 931 (c == '_' || c == '$'))) 932 return false; 933 } 934 return true; 935 } 936 937 private void addAnnotationVisibilityAttribute(Host host, attribute_info attribute, ClassFile coffiClass, List references){ 938 VisibilityAnnotationTag tag; 939 if (attribute instanceof RuntimeVisibleAnnotations_attribute){ 940 tag = new VisibilityAnnotationTag(AnnotationConstants.RUNTIME_VISIBLE); 941 RuntimeVisibleAnnotations_attribute attr = (RuntimeVisibleAnnotations_attribute)attribute; 942 addAnnotations(attr.number_of_annotations, attr.annotations, coffiClass, tag, references); 943 } 944 else { 945 tag = new VisibilityAnnotationTag(AnnotationConstants.RUNTIME_INVISIBLE); 946 RuntimeInvisibleAnnotations_attribute attr = (RuntimeInvisibleAnnotations_attribute)attribute; 947 addAnnotations(attr.number_of_annotations, attr.annotations, coffiClass, tag, references); 948 } 949 host.addTag(tag); 950 } 951 952 private void addAnnotationVisibilityParameterAttribute(Host host, attribute_info attribute, ClassFile coffiClass, List references){ 953 VisibilityParameterAnnotationTag tag; 954 if (attribute instanceof RuntimeVisibleParameterAnnotations_attribute){ 955 RuntimeVisibleParameterAnnotations_attribute attr = (RuntimeVisibleParameterAnnotations_attribute)attribute; 956 tag = new VisibilityParameterAnnotationTag(attr.num_parameters, AnnotationConstants.RUNTIME_VISIBLE); 957 for (int i = 0; i < attr.num_parameters; i++){ 958 parameter_annotation pAnnot = attr.parameter_annotations[i]; 959 VisibilityAnnotationTag vTag = new VisibilityAnnotationTag(AnnotationConstants.RUNTIME_VISIBLE); 960 addAnnotations(pAnnot.num_annotations, pAnnot.annotations, coffiClass, vTag, references); 961 tag.addVisibilityAnnotation(vTag); 962 } 963 } 964 else { 965 RuntimeInvisibleParameterAnnotations_attribute attr = (RuntimeInvisibleParameterAnnotations_attribute)attribute; 966 tag = new VisibilityParameterAnnotationTag(attr.num_parameters, AnnotationConstants.RUNTIME_INVISIBLE); 967 for (int i = 0; i < attr.num_parameters; i++){ 968 parameter_annotation pAnnot = attr.parameter_annotations[i]; 969 VisibilityAnnotationTag vTag = new VisibilityAnnotationTag(AnnotationConstants.RUNTIME_INVISIBLE); 970 addAnnotations(pAnnot.num_annotations, pAnnot.annotations, coffiClass, vTag, references); 971 tag.addVisibilityAnnotation(vTag); 972 } 973 } 974 host.addTag(tag); 975 } 976 977 private void addAnnotations(int numAnnots, annotation [] annotations, ClassFile coffiClass, VisibilityAnnotationTag tag, List references){ 978 for (int i = 0; i < numAnnots; i++){ 979 annotation annot = annotations[i]; 980 String annotType = ((CONSTANT_Utf8_info)coffiClass.constant_pool[annot.type_index]).convert(); 981 String ref = annotType.substring(1, annotType.length()-1); 982 ref = ref.replace('/', '.'); 983 references.add(ref); 984 int numElems = annot.num_element_value_pairs; 985 AnnotationTag annotTag = new AnnotationTag(annotType, numElems); 986 annotTag.setElems(createElementTags(numElems, coffiClass, annot.element_value_pairs)); 987 tag.addAnnotation(annotTag); 988 } 989 } 990 991 private ArrayList createElementTags(int count, ClassFile coffiClass, element_value [] elems){ 992 ArrayList list = new ArrayList(); 993 for (int j = 0; j < count; j++){ 994 element_value ev = (element_value)elems[j]; 995 char kind = ev.tag; 996 String elemName = "default"; 997 if (ev.name_index != 0){ 998 elemName = ((CONSTANT_Utf8_info)coffiClass.constant_pool[ev.name_index]).convert(); 999 } 1000 if (kind == 'B' || kind == 'C' || kind == 'I' || kind == 'S' || kind == 'Z' || kind == 'D' || kind == 'F' || kind == 'J' || kind == 's'){ 1001 constant_element_value cev = (constant_element_value)ev; 1002 if (kind == 'B' || kind == 'C' || kind == 'I' || kind == 'S' || kind == 'Z'){ 1003 cp_info cval = coffiClass.constant_pool[cev.constant_value_index]; 1004 int constant_val = (int)((CONSTANT_Integer_info)cval).bytes; 1005 AnnotationIntElem elem = new AnnotationIntElem(constant_val, kind, elemName); 1006 list.add(elem); 1007 } 1008 else if (kind == 'D'){ 1009 cp_info cval = coffiClass.constant_pool[cev.constant_value_index]; 1010 double constant_val = ((CONSTANT_Double_info)cval).convert(); 1011 AnnotationDoubleElem elem = new AnnotationDoubleElem(constant_val, kind, elemName); 1012 list.add(elem); 1013 1014 } 1015 else if (kind == 'F'){ 1016 cp_info cval = coffiClass.constant_pool[cev.constant_value_index]; 1017 float constant_val = ((CONSTANT_Float_info)cval).convert(); 1018 AnnotationFloatElem elem = new AnnotationFloatElem(constant_val, kind, elemName); 1019 list.add(elem); 1020 1021 } 1022 else if (kind == 'J'){ 1023 cp_info cval = coffiClass.constant_pool[cev.constant_value_index]; 1024 CONSTANT_Long_info lcval = (CONSTANT_Long_info)cval; 1025 long constant_val = (lcval.high << 32) + lcval.low; 1026 AnnotationLongElem elem = new AnnotationLongElem(constant_val, kind, elemName); 1027 list.add(elem); 1028 1029 } 1030 else if (kind == 's'){ 1031 cp_info cval = coffiClass.constant_pool[cev.constant_value_index]; 1032 String constant_val = ((CONSTANT_Utf8_info)cval).convert(); 1033 AnnotationStringElem elem = new AnnotationStringElem(constant_val, kind, elemName); 1034 list.add(elem); 1035 } 1036 } 1037 else if (kind == 'e'){ 1038 enum_constant_element_value ecev = (enum_constant_element_value)ev; 1039 cp_info type_val = coffiClass.constant_pool[ecev.type_name_index]; 1040 String type_name = ((CONSTANT_Utf8_info)type_val).convert(); 1041 cp_info name_val = coffiClass.constant_pool[ecev.constant_name_index]; 1042 String constant_name = ((CONSTANT_Utf8_info)name_val).convert(); 1043 AnnotationEnumElem elem = new AnnotationEnumElem(type_name, constant_name, kind, elemName); 1044 list.add(elem); 1045 } 1046 else if (kind == 'c'){ 1047 class_element_value cev = (class_element_value)ev; 1048 cp_info cval = coffiClass.constant_pool[cev.class_info_index]; 1049 CONSTANT_Utf8_info sval = (CONSTANT_Utf8_info)cval; 1050 String desc = sval.convert(); 1051 1052 AnnotationClassElem elem = new AnnotationClassElem(desc, kind, elemName); 1053 list.add(elem); 1054 } 1055 else if (kind == '['){ 1056 array_element_value aev = (array_element_value)ev; 1057 int num_vals = aev.num_values; 1058 1059 ArrayList elemVals = createElementTags(num_vals, coffiClass, aev.values); 1060 AnnotationArrayElem elem = new AnnotationArrayElem(elemVals, kind, elemName); 1061 list.add(elem); 1062 } 1063 else if (kind == '@'){ 1064 annotation_element_value aev = (annotation_element_value)ev; 1065 annotation annot = aev.annotation_value; 1066 String annotType = ((CONSTANT_Utf8_info)coffiClass.constant_pool[annot.type_index]).convert(); 1067 int numElems = annot.num_element_value_pairs; 1068 AnnotationTag annotTag = new AnnotationTag(annotType, numElems); 1069 annotTag.setElems(createElementTags(numElems, coffiClass, annot.element_value_pairs)); 1070 1071 AnnotationAnnotationElem elem = new AnnotationAnnotationElem(annotTag, kind, elemName); 1072 list.add(elem); 1073 } 1074 } 1075 1076 return list; 1077 } 1078} 1079 | Popular Tags |