use of soot.tagkit.SyntheticTag in project soot by Sable.
the class Util method resolveFromClassFile.
public void resolveFromClassFile(SootClass aClass, InputStream is, String filePath, Collection<Type> references) {
SootClass bclass = aClass;
String className = bclass.getName();
ClassFile coffiClass = new ClassFile(className);
// Load up class file, and retrieve bclass from class manager.
{
boolean success = coffiClass.loadClassFile(is);
if (!success) {
if (!Scene.v().allowsPhantomRefs())
throw new RuntimeException("Could not load classfile: " + bclass.getName());
else {
logger.warn("" + className + " is a phantom class!");
bclass.setPhantomClass();
return;
}
}
CONSTANT_Class_info c = (CONSTANT_Class_info) coffiClass.constant_pool[coffiClass.this_class];
String name = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[c.name_index])).convert();
name = name.replace('/', '.');
if (!name.equals(bclass.getName())) {
throw new RuntimeException("Error: class " + name + " read in from a classfile in which " + bclass.getName() + " was expected.");
}
}
// Set modifier
bclass.setModifiers(coffiClass.access_flags & (~0x0020));
// don't want the ACC_SUPER flag, it is always supposed to be set
// anyways
// Set superclass
{
if (coffiClass.super_class != 0) {
// This object is not java.lang.Object, so must have a super
// class
CONSTANT_Class_info c = (CONSTANT_Class_info) coffiClass.constant_pool[coffiClass.super_class];
String superName = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[c.name_index])).convert();
superName = superName.replace('/', '.');
references.add(RefType.v(superName));
bclass.setSuperclass(SootResolver.v().makeClassRef(superName));
}
}
// Add interfaces to the bclass
{
for (int i = 0; i < coffiClass.interfaces_count; i++) {
CONSTANT_Class_info c = (CONSTANT_Class_info) coffiClass.constant_pool[coffiClass.interfaces[i]];
String interfaceName = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[c.name_index])).convert();
interfaceName = interfaceName.replace('/', '.');
references.add(RefType.v(interfaceName));
SootClass interfaceClass = SootResolver.v().makeClassRef(interfaceName);
interfaceClass.setModifiers(interfaceClass.getModifiers() | Modifier.INTERFACE);
bclass.addInterface(interfaceClass);
}
}
// Add every field to the bclass
for (int i = 0; i < coffiClass.fields_count; i++) {
field_info fieldInfo = coffiClass.fields[i];
String fieldName = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[fieldInfo.name_index])).convert();
String fieldDescriptor = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[fieldInfo.descriptor_index])).convert();
int modifiers = fieldInfo.access_flags;
Type fieldType = jimpleTypeOfFieldDescriptor(fieldDescriptor);
SootField field = Scene.v().makeSootField(fieldName, fieldType, modifiers);
bclass.addField(field);
references.add(fieldType);
// add initialization constant, if any
for (int j = 0; j < fieldInfo.attributes_count; j++) {
// add constant value attributes
if (fieldInfo.attributes[j] instanceof ConstantValue_attribute) {
ConstantValue_attribute attr = (ConstantValue_attribute) fieldInfo.attributes[j];
cp_info cval = coffiClass.constant_pool[attr.constantvalue_index];
ConstantValueTag tag;
switch(cval.tag) {
case cp_info.CONSTANT_Integer:
tag = new IntegerConstantValueTag((int) ((CONSTANT_Integer_info) cval).bytes);
break;
case cp_info.CONSTANT_Float:
// tag = new
// FloatConstantValueTag((int)((CONSTANT_Float_info)cval).bytes);
tag = new FloatConstantValueTag(((CONSTANT_Float_info) cval).convert());
break;
case cp_info.CONSTANT_Long:
{
CONSTANT_Long_info lcval = (CONSTANT_Long_info) cval;
tag = new LongConstantValueTag((lcval.high << 32) + lcval.low);
break;
}
case cp_info.CONSTANT_Double:
{
CONSTANT_Double_info dcval = (CONSTANT_Double_info) cval;
// tag = new DoubleConstantValueTag((dcval.high << 32) +
// dcval.low);
tag = new DoubleConstantValueTag(dcval.convert());
break;
}
case cp_info.CONSTANT_String:
{
CONSTANT_String_info scval = (CONSTANT_String_info) cval;
CONSTANT_Utf8_info ucval = (CONSTANT_Utf8_info) coffiClass.constant_pool[scval.string_index];
tag = new StringConstantValueTag(ucval.convert());
break;
}
default:
throw new RuntimeException("unexpected ConstantValue: " + cval);
}
field.addTag(tag);
} else // add synthetic tag
if (fieldInfo.attributes[j] instanceof Synthetic_attribute) {
field.addTag(new SyntheticTag());
} else // add deprecated tag
if (fieldInfo.attributes[j] instanceof Deprecated_attribute) {
field.addTag(new DeprecatedTag());
} else // add signature tag
if (fieldInfo.attributes[j] instanceof Signature_attribute) {
String generic_sig = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[((Signature_attribute) fieldInfo.attributes[j]).signature_index])).convert();
field.addTag(new SignatureTag(generic_sig));
} else if (fieldInfo.attributes[j] instanceof RuntimeVisibleAnnotations_attribute || fieldInfo.attributes[j] instanceof RuntimeInvisibleAnnotations_attribute) {
addAnnotationVisibilityAttribute(field, fieldInfo.attributes[j], coffiClass, references);
} else if (fieldInfo.attributes[j] instanceof Generic_attribute) {
Generic_attribute attr = (Generic_attribute) fieldInfo.attributes[j];
String name = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[attr.attribute_name])).convert();
field.addTag(new GenericAttribute(name, attr.info));
}
}
}
// Add every method to the bclass
for (int i = 0; i < coffiClass.methods_count; i++) {
method_info methodInfo = coffiClass.methods[i];
if ((coffiClass.constant_pool[methodInfo.name_index]) == null) {
logger.debug("method index: " + methodInfo.toName(coffiClass.constant_pool));
throw new RuntimeException("method has no name");
}
String methodName = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[methodInfo.name_index])).convert();
String methodDescriptor = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[methodInfo.descriptor_index])).convert();
List<Type> parameterTypes;
Type returnType;
// Generate parameterTypes & returnType
{
Type[] types = jimpleTypesOfFieldOrMethodDescriptor(methodDescriptor);
parameterTypes = new ArrayList<Type>();
for (int j = 0; j < types.length - 1; j++) {
references.add(types[j]);
parameterTypes.add(types[j]);
}
returnType = types[types.length - 1];
references.add(returnType);
}
int modifiers = methodInfo.access_flags;
SootMethod method;
method = Scene.v().makeSootMethod(methodName, parameterTypes, returnType, modifiers);
bclass.addMethod(method);
methodInfo.jmethod = method;
// add exceptions to method
{
for (int j = 0; j < methodInfo.attributes_count; j++) {
if (methodInfo.attributes[j] instanceof Exception_attribute) {
Exception_attribute exceptions = (Exception_attribute) methodInfo.attributes[j];
for (int k = 0; k < exceptions.number_of_exceptions; k++) {
CONSTANT_Class_info c = (CONSTANT_Class_info) coffiClass.constant_pool[exceptions.exception_index_table[k]];
String exceptionName = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[c.name_index])).convert();
exceptionName = exceptionName.replace('/', '.');
references.add(RefType.v(exceptionName));
method.addExceptionIfAbsent(SootResolver.v().makeClassRef(exceptionName));
}
} else if (methodInfo.attributes[j] instanceof Synthetic_attribute) {
method.addTag(new SyntheticTag());
} else if (methodInfo.attributes[j] instanceof Deprecated_attribute) {
method.addTag(new DeprecatedTag());
} else if (methodInfo.attributes[j] instanceof Signature_attribute) {
String generic_sig = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[((Signature_attribute) methodInfo.attributes[j]).signature_index])).convert();
method.addTag(new SignatureTag(generic_sig));
} else if (methodInfo.attributes[j] instanceof RuntimeVisibleAnnotations_attribute || methodInfo.attributes[j] instanceof RuntimeInvisibleAnnotations_attribute) {
addAnnotationVisibilityAttribute(method, methodInfo.attributes[j], coffiClass, references);
} else if (methodInfo.attributes[j] instanceof RuntimeVisibleParameterAnnotations_attribute || methodInfo.attributes[j] instanceof RuntimeInvisibleParameterAnnotations_attribute) {
addAnnotationVisibilityParameterAttribute(method, methodInfo.attributes[j], coffiClass, references);
} else if (methodInfo.attributes[j] instanceof AnnotationDefault_attribute) {
AnnotationDefault_attribute attr = (AnnotationDefault_attribute) methodInfo.attributes[j];
element_value[] input = new element_value[1];
input[0] = attr.default_value;
ArrayList<AnnotationElem> list = createElementTags(1, coffiClass, input);
method.addTag(new AnnotationDefaultTag(list.get(0)));
} else if (methodInfo.attributes[j] instanceof Generic_attribute) {
Generic_attribute attr = (Generic_attribute) methodInfo.attributes[j];
String name = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[attr.attribute_name])).convert();
method.addTag(new GenericAttribute(name, attr.info));
}
}
}
// Go through the constant pool, forcing all mentioned classes to be
// resolved.
{
for (int k = 0; k < coffiClass.constant_pool_count; k++) {
if (coffiClass.constant_pool[k] instanceof CONSTANT_Class_info) {
CONSTANT_Class_info c = (CONSTANT_Class_info) coffiClass.constant_pool[k];
String desc = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[c.name_index])).convert();
String name = desc.replace('/', '.');
if (name.startsWith("["))
references.add(jimpleTypeOfFieldDescriptor(desc));
else
references.add(RefType.v(name));
}
if (coffiClass.constant_pool[k] instanceof CONSTANT_Fieldref_info || coffiClass.constant_pool[k] instanceof CONSTANT_Methodref_info || coffiClass.constant_pool[k] instanceof CONSTANT_InterfaceMethodref_info) {
Type[] types = jimpleTypesOfFieldOrMethodDescriptor(cp_info.getTypeDescr(coffiClass.constant_pool, k));
for (Type element : types) {
references.add(element);
}
}
}
}
}
// Set coffi source of method
for (int i = 0; i < coffiClass.methods_count; i++) {
method_info methodInfo = coffiClass.methods[i];
// methodInfo.jmethod.setSource(coffiClass, methodInfo);
methodInfo.jmethod.setSource(new CoffiMethodSource(coffiClass, methodInfo));
}
// Set "SourceFile" attribute tag
for (int i = 0; i < coffiClass.attributes_count; i++) {
if (coffiClass.attributes[i] instanceof SourceFile_attribute) {
SourceFile_attribute attr = (SourceFile_attribute) coffiClass.attributes[i];
String sourceFile = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[attr.sourcefile_index])).convert();
if (sourceFile.indexOf(' ') >= 0) {
logger.debug("" + "Warning: Class " + className + " has invalid SourceFile attribute (will be ignored).");
} else {
bclass.addTag(new SourceFileTag(sourceFile, filePath));
}
} else // Set "InnerClass" attribute tag
if (coffiClass.attributes[i] instanceof InnerClasses_attribute) {
InnerClasses_attribute attr = (InnerClasses_attribute) coffiClass.attributes[i];
for (int j = 0; j < attr.inner_classes_length; j++) {
inner_class_entry e = attr.inner_classes[j];
String inner = null;
String outer = null;
String name = null;
if (e.inner_class_index != 0)
inner = ((CONSTANT_Utf8_info) coffiClass.constant_pool[((CONSTANT_Class_info) coffiClass.constant_pool[e.inner_class_index]).name_index]).convert();
if (e.outer_class_index != 0)
outer = ((CONSTANT_Utf8_info) coffiClass.constant_pool[((CONSTANT_Class_info) coffiClass.constant_pool[e.outer_class_index]).name_index]).convert();
if (e.name_index != 0)
name = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[e.name_index])).convert();
bclass.addTag(new InnerClassTag(inner, outer, name, e.access_flags));
}
} else // set synthetic tags
if (coffiClass.attributes[i] instanceof Synthetic_attribute) {
bclass.addTag(new SyntheticTag());
} else // set deprectaed tags
if (coffiClass.attributes[i] instanceof Deprecated_attribute) {
bclass.addTag(new DeprecatedTag());
} else if (coffiClass.attributes[i] instanceof Signature_attribute) {
String generic_sig = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[((Signature_attribute) coffiClass.attributes[i]).signature_index])).convert();
bclass.addTag(new SignatureTag(generic_sig));
} else if (coffiClass.attributes[i] instanceof EnclosingMethod_attribute) {
EnclosingMethod_attribute attr = (EnclosingMethod_attribute) coffiClass.attributes[i];
String class_name = ((CONSTANT_Utf8_info) coffiClass.constant_pool[((CONSTANT_Class_info) coffiClass.constant_pool[attr.class_index]).name_index]).convert();
CONSTANT_NameAndType_info info = (CONSTANT_NameAndType_info) coffiClass.constant_pool[attr.method_index];
String method_name = "";
String method_sig = "";
if (info != null) {
method_name = ((CONSTANT_Utf8_info) coffiClass.constant_pool[info.name_index]).convert();
method_sig = ((CONSTANT_Utf8_info) coffiClass.constant_pool[info.descriptor_index]).convert();
}
bclass.addTag(new EnclosingMethodTag(class_name, method_name, method_sig));
} else if (coffiClass.attributes[i] instanceof RuntimeVisibleAnnotations_attribute || coffiClass.attributes[i] instanceof RuntimeInvisibleAnnotations_attribute) {
addAnnotationVisibilityAttribute(bclass, coffiClass.attributes[i], coffiClass, references);
} else if (coffiClass.attributes[i] instanceof Generic_attribute) {
Generic_attribute attr = (Generic_attribute) coffiClass.attributes[i];
String name = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[attr.attribute_name])).convert();
bclass.addTag(new GenericAttribute(name, attr.info));
}
}
}
Aggregations