use of soot.tagkit.SourceFileTag in project robovm by robovm.
the class AttributesEncoder method encodeAttributes.
private Constant encodeAttributes(Host host) {
List<Value> attributes = new ArrayList<Value>();
for (Tag tag : host.getTags()) {
if (tag instanceof SourceFileTag) {
// Skip. We don't need this at this time.
Value sourceFile = getString(((SourceFileTag) tag).getSourceFile());
attributes.add(new PackedStructureConstant(new PackedStructureType(I8, I8_PTR), new IntegerConstant(SOURCE_FILE), sourceFile));
} else if (tag instanceof EnclosingMethodTag) {
EnclosingMethodTag emt = (EnclosingMethodTag) tag;
Value eClass = getString(emt.getEnclosingClass());
Value eMethod = getStringOrNull(emt.getEnclosingMethod());
Value eDesc = getStringOrNull(emt.getEnclosingMethodSig());
attributes.add(new PackedStructureConstant(new PackedStructureType(I8, I8_PTR, I8_PTR, I8_PTR), new IntegerConstant(ENCLOSING_METHOD), eClass, eMethod, eDesc));
} else if (tag instanceof SignatureTag) {
Value signature = getString(((SignatureTag) tag).getSignature());
attributes.add(new PackedStructureConstant(new PackedStructureType(I8, I8_PTR), new IntegerConstant(SIGNATURE), signature));
} else if (tag instanceof InnerClassTag) {
InnerClassTag ict = (InnerClassTag) tag;
Value innerClass = getStringOrNull(ict.getInnerClass());
Value outerClass = getStringOrNull(ict.getOuterClass());
Value innerName = getStringOrNull(ict.getShortName());
Value innerClassAccess = new IntegerConstant(ict.getAccessFlags());
attributes.add(new PackedStructureConstant(new PackedStructureType(I8, I8_PTR, I8_PTR, I8_PTR, I32), new IntegerConstant(INNER_CLASS), innerClass, outerClass, innerName, innerClassAccess));
} else if (tag instanceof AnnotationDefaultTag) {
StructureConstant value = encodeAnnotationElementValue(((AnnotationDefaultTag) tag).getDefaultVal());
attributes.add(new PackedStructureConstant(new PackedStructureType(I8, value.getType()), new IntegerConstant(ANNOTATION_DEFAULT), value));
} else if (tag instanceof VisibilityAnnotationTag) {
VisibilityAnnotationTag vat = (VisibilityAnnotationTag) tag;
if (vat.getVisibility() == AnnotationConstants.RUNTIME_VISIBLE) {
Type[] types = new Type[vat.getAnnotations().size()];
Value[] values = new Value[vat.getAnnotations().size()];
int i = 0;
for (AnnotationTag at : vat.getAnnotations()) {
values[i] = encodeAnnotationTagValue(at);
types[i] = values[i].getType();
i++;
}
attributes.add(new PackedStructureConstant(new PackedStructureType(I8, I32, new PackedStructureType(types)), new IntegerConstant(RUNTIME_VISIBLE_ANNOTATIONS), new IntegerConstant(vat.getAnnotations().size()), new PackedStructureConstant(new PackedStructureType(types), values)));
}
} else if (tag instanceof VisibilityParameterAnnotationTag) {
VisibilityParameterAnnotationTag vpat = (VisibilityParameterAnnotationTag) tag;
List<Type> typesList = new ArrayList<Type>();
List<Value> valuesList = new ArrayList<Value>();
boolean hasRuntimeVisible = false;
for (VisibilityAnnotationTag vat : vpat.getVisibilityAnnotations()) {
typesList.add(I32);
if (vat.getVisibility() == AnnotationConstants.RUNTIME_VISIBLE && vat.getAnnotations() != null && !vat.getAnnotations().isEmpty()) {
hasRuntimeVisible = true;
valuesList.add(new IntegerConstant(vat.getAnnotations().size()));
for (AnnotationTag at : vat.getAnnotations()) {
valuesList.add(encodeAnnotationTagValue(at));
typesList.add(valuesList.get(valuesList.size() - 1).getType());
}
} else {
valuesList.add(new IntegerConstant(0));
}
}
if (hasRuntimeVisible) {
Type[] types = typesList.toArray(new Type[typesList.size()]);
Value[] values = valuesList.toArray(new Value[valuesList.size()]);
attributes.add(new PackedStructureConstant(new PackedStructureType(I8, I32, new PackedStructureType(types)), new IntegerConstant(RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS), new IntegerConstant(vpat.getVisibilityAnnotations().size()), new PackedStructureConstant(new PackedStructureType(types), values)));
}
}
}
if (host instanceof SootMethod) {
List<SootClass> exceptions = ((SootMethod) host).getExceptions();
if (!exceptions.isEmpty()) {
Value[] values = new Value[exceptions.size()];
for (int i = 0; i < exceptions.size(); i++) {
String exName = getInternalName(exceptions.get(i));
values[i] = getString(exName);
addDependency(exName);
}
attributes.add(new PackedStructureConstant(new PackedStructureType(I8, I32, new ArrayType(exceptions.size(), I8_PTR)), new IntegerConstant(EXCEPTIONS), new IntegerConstant(exceptions.size()), new ArrayConstant(new ArrayType(exceptions.size(), I8_PTR), values)));
}
}
if (attributes.isEmpty()) {
return null;
}
attributes.add(0, new IntegerConstant(attributes.size()));
Type[] types = new Type[attributes.size()];
for (int i = 0; i < types.length; i++) {
types[i] = attributes.get(i).getType();
}
return new PackedStructureConstant(new PackedStructureType(types), attributes.toArray(new Value[0]));
}
use of soot.tagkit.SourceFileTag in project soot by Sable.
the class DexPrinter method toMethodImplementation.
private MethodImplementation toMethodImplementation(SootMethod m) {
if (m.isAbstract() || m.isNative()) {
return null;
}
Body activeBody = m.retrieveActiveBody();
// when installing the app
if (m.getName().contains("<") || m.getName().equals(">"))
if (!m.getName().equals("<init>") && !m.getName().equals("<clinit>"))
throw new RuntimeException("Invalid method name: " + m.getName());
// Switch statements may not be empty in dex, so we have to fix this
// first
EmptySwitchEliminator.v().transform(activeBody);
// Dalvik requires synchronized methods to have explicit monitor calls,
// so we insert them here. See
// http://milk.com/kodebase/dalvik-docs-mirror/docs/debugger.html
// We cannot place this upon the developer since it is only required
// for Dalvik, but not for other targets.
SynchronizedMethodTransformer.v().transform(activeBody);
// Tries may not start or end at units which have no corresponding
// Dalvik
// instructions such as IdentityStmts. We reduce the traps to start at
// the
// first "real" instruction. We could also use a TrapTigthener, but that
// would be too expensive for what we need here.
FastDexTrapTightener.v().transform(activeBody);
// Look for sequences of array element assignments that we can collapse
// into bulk initializations
DexArrayInitDetector initDetector = new DexArrayInitDetector();
initDetector.constructArrayInitializations(activeBody);
initDetector.fixTraps(activeBody);
// Split the tries since Dalvik does not supported nested try/catch
// blocks
TrapSplitter.v().transform(activeBody);
// word count of incoming parameters
int inWords = SootToDexUtils.getDexWords(m.getParameterTypes());
if (!m.isStatic()) {
// extra word for "this"
inWords++;
}
// word count of max outgoing parameters
Collection<Unit> units = activeBody.getUnits();
// register count = parameters + additional registers, depending on the
// dex instructions generated (e.g. locals used and constants loaded)
StmtVisitor stmtV = new StmtVisitor(m, initDetector);
Chain<Trap> traps = activeBody.getTraps();
Set<Unit> trapReferences = new HashSet<Unit>(traps.size() * 3);
for (Trap t : activeBody.getTraps()) {
trapReferences.add(t.getBeginUnit());
trapReferences.add(t.getEndUnit());
trapReferences.add(t.getHandlerUnit());
}
toInstructions(units, stmtV, trapReferences);
int registerCount = stmtV.getRegisterCount();
if (inWords > registerCount) {
/*
* as the Dalvik VM moves the parameters into the last registers, the "in" word
* count must be at least equal to the register count. a smaller register count
* could occur if soot generated the method body, see e.g. the handling of
* phantom refs in SootMethodRefImpl.resolve(StringBuffer): the body has no
* locals for the ParameterRefs, it just throws an error.
*
* we satisfy the verifier by just increasing the register count, since calling
* phantom refs will lead to an error anyway.
*/
registerCount = inWords;
}
MethodImplementationBuilder builder = new MethodImplementationBuilder(registerCount);
LabelAssigner labelAssinger = new LabelAssigner(builder);
List<BuilderInstruction> instructions = stmtV.getRealInsns(labelAssinger);
fixLongJumps(instructions, labelAssinger, stmtV);
Map<Local, Integer> seenRegisters = new HashMap<Local, Integer>();
Map<Instruction, LocalRegisterAssignmentInformation> instructionRegisterMap = stmtV.getInstructionRegisterMap();
if (Options.v().write_local_annotations()) {
for (LocalRegisterAssignmentInformation assignment : stmtV.getParameterInstructionsList()) {
// (at least not if it exists with exactly this name)
if (assignment.getLocal().getName().equals("this"))
continue;
addRegisterAssignmentDebugInfo(assignment, seenRegisters, builder);
}
}
for (BuilderInstruction ins : instructions) {
Stmt origStmt = stmtV.getStmtForInstruction(ins);
// If this is a switch payload, we need to place the label
if (stmtV.getInstructionPayloadMap().containsKey(ins))
builder.addLabel(labelAssinger.getLabelName(stmtV.getInstructionPayloadMap().get(ins)));
if (origStmt != null) {
// Do we need a label here because this a trap handler?
if (trapReferences.contains(origStmt))
labelAssinger.getOrCreateLabel(origStmt);
// Add the label if the statement has one
String labelName = labelAssinger.getLabelName(origStmt);
if (labelName != null && !builder.getLabel(labelName).isPlaced())
builder.addLabel(labelName);
// Add the tags
if (stmtV.getStmtForInstruction(ins) != null) {
List<Tag> tags = origStmt.getTags();
for (Tag t : tags) {
if (t instanceof LineNumberTag) {
LineNumberTag lnt = (LineNumberTag) t;
builder.addLineNumber(lnt.getLineNumber());
} else if (t instanceof SourceFileTag) {
SourceFileTag sft = (SourceFileTag) t;
builder.addSetSourceFile(new ImmutableStringReference(sft.getSourceFile()));
}
}
}
}
builder.addInstruction(ins);
LocalRegisterAssignmentInformation registerAssignmentTag = instructionRegisterMap.get(ins);
if (registerAssignmentTag != null) {
// Add start local debugging information: Register -> Local
// assignment
addRegisterAssignmentDebugInfo(registerAssignmentTag, seenRegisters, builder);
}
}
for (int registersLeft : seenRegisters.values()) builder.addEndLocal(registersLeft);
toTries(activeBody.getTraps(), stmtV, builder, labelAssinger);
// Make sure that all labels have been placed by now
for (Label lbl : labelAssinger.getAllLabels()) if (!lbl.isPlaced())
throw new RuntimeException("Label not placed: " + lbl);
return builder.getMethodImplementation();
}
use of soot.tagkit.SourceFileTag 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.tagkit.SourceFileTag in project soot by Sable.
the class InterfaceDecl method jimplify1phase2.
/**
* @ast method
* @aspect EmitJimple
* @declaredat /Users/eric/Documents/workspaces/clara-soot/JastAddExtensions/JimpleBackend/EmitJimple.jrag:186
*/
public void jimplify1phase2() {
SootClass sc = getSootClassDecl();
sc.setResolvingLevel(SootClass.DANGLING);
sc.setModifiers(sootTypeModifiers());
sc.setApplicationClass();
SourceFileTag st = new soot.tagkit.SourceFileTag(sourceNameWithoutPath());
st.setAbsolutePath(compilationUnit().pathName());
sc.addTag(st);
sc.setSuperclass(typeObject().getSootClassDecl());
for (Iterator iter = superinterfacesIterator(); iter.hasNext(); ) {
TypeDecl typeDecl = (TypeDecl) iter.next();
if (typeDecl != typeObject() && !sc.implementsInterface(typeDecl.getSootClassDecl().getName()))
sc.addInterface(typeDecl.getSootClassDecl());
}
if (isNestedType())
sc.setOuterClass(enclosingType().getSootClassDecl());
sc.setResolvingLevel(SootClass.HIERARCHY);
super.jimplify1phase2();
sc.setResolvingLevel(SootClass.SIGNATURES);
}
use of soot.tagkit.SourceFileTag in project soot by Sable.
the class ClassDecl method jimplify1phase2.
/**
* @ast method
* @aspect EmitJimple
* @declaredat /Users/eric/Documents/workspaces/clara-soot/JastAddExtensions/JimpleBackend/EmitJimple.jrag:163
*/
public void jimplify1phase2() {
SootClass sc = getSootClassDecl();
sc.setResolvingLevel(SootClass.DANGLING);
sc.setModifiers(sootTypeModifiers());
sc.setApplicationClass();
SourceFileTag st = new soot.tagkit.SourceFileTag(sourceNameWithoutPath());
st.setAbsolutePath(compilationUnit().pathName());
sc.addTag(st);
if (hasSuperclass()) {
sc.setSuperclass(superclass().getSootClassDecl());
}
for (Iterator iter = interfacesIterator(); iter.hasNext(); ) {
TypeDecl typeDecl = (TypeDecl) iter.next();
if (!sc.implementsInterface(typeDecl.getSootClassDecl().getName()))
sc.addInterface(typeDecl.getSootClassDecl());
}
if (isNestedType())
sc.setOuterClass(enclosingType().getSootClassDecl());
sc.setResolvingLevel(SootClass.HIERARCHY);
super.jimplify1phase2();
sc.setResolvingLevel(SootClass.SIGNATURES);
}
Aggregations