use of soot.SootField in project soot by Sable.
the class DexPrinter method addAsClassDefItem.
private void addAsClassDefItem(SootClass c) {
// add source file tag if any
String sourceFile = null;
if (c.hasTag("SourceFileTag")) {
SourceFileTag sft = (SourceFileTag) c.getTag("SourceFileTag");
sourceFile = sft.getSourceFile();
}
String classType = SootToDexUtils.getDexTypeDescriptor(c.getType());
int accessFlags = c.getModifiers();
String superClass = c.hasSuperclass() ? SootToDexUtils.getDexTypeDescriptor(c.getSuperclass().getType()) : null;
List<String> interfaces = null;
if (!c.getInterfaces().isEmpty()) {
interfaces = new ArrayList<String>();
for (SootClass ifc : c.getInterfaces()) interfaces.add(SootToDexUtils.getDexTypeDescriptor(ifc.getType()));
}
List<Field> fields = null;
if (!c.getFields().isEmpty()) {
fields = new ArrayList<Field>();
for (SootField f : c.getFields()) {
// We do not want to write out phantom fields
if (f.isPhantom())
continue;
// Look for a static initializer
EncodedValue staticInit = null;
for (Tag t : f.getTags()) {
if (t instanceof ConstantValueTag) {
if (staticInit != null) {
LOGGER.warn("More than one constant tag for field \"{}\": \"{}\"", f, t);
} else {
staticInit = makeConstantItem(f, t);
}
}
}
if (staticInit == null)
staticInit = BuilderEncodedValues.defaultValueForType(SootToDexUtils.getDexTypeDescriptor(f.getType()));
// Build field annotations
Set<Annotation> fieldAnnotations = buildFieldAnnotations(f);
ImmutableField field = new ImmutableField(classType, f.getName(), SootToDexUtils.getDexTypeDescriptor(f.getType()), f.getModifiers(), staticInit, fieldAnnotations);
fields.add(field);
}
}
Collection<Method> methods = toMethods(c);
ClassDef classDef = new ImmutableClassDef(classType, accessFlags, superClass, interfaces, sourceFile, buildClassAnnotations(c), fields, methods);
dexBuilder.internClass(classDef);
}
use of soot.SootField in project soot by Sable.
the class ConstantInitializerToTagTransformer method transformClass.
/**
* Transforms the given class, i.e. scans for a <clinit> method and
* generates new constant value tags for all constant assignments to static
* final fields.
*
* @param sc
* The class to transform
* @param removeAssignments
* True if the assignments inside the <clinit> method shall be
* removed, otherwise false
*/
public void transformClass(SootClass sc, boolean removeAssignments) {
// If this class has no <clinit> method, we're done
SootMethod smInit = sc.getMethodByNameUnsafe("<clinit>");
if (smInit == null || !smInit.isConcrete())
return;
Set<SootField> nonConstantFields = new HashSet<SootField>();
Map<SootField, ConstantValueTag> newTags = new HashMap<SootField, ConstantValueTag>();
// in case of
Set<SootField> removeTagList = new HashSet<SootField>();
for (Iterator<Unit> itU = smInit.getActiveBody().getUnits().snapshotIterator(); itU.hasNext(); ) {
Unit u = itU.next();
if (u instanceof AssignStmt) {
AssignStmt assign = (AssignStmt) u;
if (assign.getLeftOp() instanceof StaticFieldRef && assign.getRightOp() instanceof Constant) {
SootField field = null;
try {
field = ((StaticFieldRef) assign.getLeftOp()).getField();
if (field == null || nonConstantFields.contains(field))
continue;
} catch (ConflictingFieldRefException ex) {
// Ignore this statement
continue;
}
if (field.getDeclaringClass().equals(sc) && field.isStatic() && field.isFinal()) {
// Do we already have a constant value for this field?
boolean found = false;
for (Tag t : field.getTags()) {
if (t instanceof ConstantValueTag) {
if (checkConstantValue((ConstantValueTag) t, (Constant) assign.getRightOp())) {
// the assignment.
if (removeAssignments)
itU.remove();
} else {
logger.debug("" + "WARNING: Constant value for field '" + field + "' mismatch between code (" + assign.getRightOp() + ") and constant table (" + t + ")");
removeTagList.add(field);
}
found = true;
break;
}
}
if (!found) {
// tags.
if (!checkConstantValue(newTags.get(field), (Constant) assign.getRightOp())) {
nonConstantFields.add(field);
newTags.remove(field);
removeTagList.add(field);
continue;
}
ConstantValueTag newTag = createConstantTagFromValue((Constant) assign.getRightOp());
if (newTag != null)
newTags.put(field, newTag);
}
}
} else if (assign.getLeftOp() instanceof StaticFieldRef) {
// a non-constant is assigned to the field
try {
SootField sf = ((StaticFieldRef) assign.getLeftOp()).getField();
if (sf != null)
removeTagList.add(sf);
} catch (ConflictingFieldRefException ex) {
// let's assume that a broken field doesn't cause any
// harm
}
}
}
}
// Do the actual assignment
for (Entry<SootField, ConstantValueTag> entry : newTags.entrySet()) {
SootField field = entry.getKey();
if (removeTagList.contains(field))
continue;
field.addTag(entry.getValue());
}
if (removeAssignments && !newTags.isEmpty())
for (Iterator<Unit> itU = smInit.getActiveBody().getUnits().snapshotIterator(); itU.hasNext(); ) {
Unit u = itU.next();
if (u instanceof AssignStmt) {
AssignStmt assign = (AssignStmt) u;
if (assign.getLeftOp() instanceof FieldRef)
try {
SootField fld = ((FieldRef) assign.getLeftOp()).getField();
if (fld != null && newTags.containsKey(fld))
itU.remove();
} catch (ConflictingFieldRefException ex) {
// Ignore broken code
}
}
}
// remove constant tags
for (SootField sf : removeTagList) {
if (removeTagList.contains(sf)) {
List<Tag> toRemoveTagList = new ArrayList<Tag>();
for (Tag t : sf.getTags()) {
if (t instanceof ConstantValueTag) {
toRemoveTagList.add(t);
}
}
for (Tag t : toRemoveTagList) {
sf.getTags().remove(t);
}
}
}
}
use of soot.SootField in project soot by Sable.
the class TypeDecl method getSootField_compute.
/**
* @apilevel internal
*/
private SootField getSootField_compute(String name, TypeDecl type) {
SootField f = Scene.v().makeSootField(name, type.getSootType(), 0);
getSootClassDecl().addField(f);
return f;
}
use of soot.SootField in project soot by Sable.
the class TypeDecl method getSootField.
/**
* @attribute syn
* @aspect EmitJimple
* @declaredat /Users/eric/Documents/workspaces/clara-soot/JastAddExtensions/JimpleBackend/EmitJimple.jrag:996
*/
@SuppressWarnings({ "unchecked", "cast" })
public SootField getSootField(String name, TypeDecl type) {
java.util.List _parameters = new java.util.ArrayList(2);
_parameters.add(name);
_parameters.add(type);
if (getSootField_String_TypeDecl_values == null)
getSootField_String_TypeDecl_values = new java.util.HashMap(4);
if (getSootField_String_TypeDecl_values.containsKey(_parameters)) {
return (SootField) getSootField_String_TypeDecl_values.get(_parameters);
}
ASTNode$State state = state();
int num = state.boundariesCrossed;
boolean isFinal = this.is$Final();
SootField getSootField_String_TypeDecl_value = getSootField_compute(name, type);
if (isFinal && num == state().boundariesCrossed)
getSootField_String_TypeDecl_values.put(_parameters, getSootField_String_TypeDecl_value);
return getSootField_String_TypeDecl_value;
}
use of soot.SootField 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