public static String getDescriptor(soot.Type t) { if (t instanceof PrimType) { if (t.equals(BooleanType.v())) { return "Z"; } else if (t.equals(ByteType.v())) { return "B"; } else if (t.equals(ShortType.v())) { return "S"; } else if (t.equals(CharType.v())) { return "C"; } else if (t.equals(IntType.v())) { return "I"; } else if (t.equals(LongType.v())) { return "J"; } else if (t.equals(FloatType.v())) { return "F"; } else { // DoubleType return "D"; } } else if (t.equals(VoidType.v())) { return "V"; } else if (t instanceof soot.ArrayType) { soot.ArrayType at = (soot.ArrayType) t; return "[" + getDescriptor(at.getElementType()); } else { // RefType RefType rt = (RefType) t; return "L" + rt.getClassName().replace('.', '/') + ";"; } }
public static Type getType(soot.Type sootType) { if (sootType.equals(soot.BooleanType.v())) { return Type.I8; } else if (sootType.equals(soot.ByteType.v())) { return Type.I8; } else if (sootType.equals(soot.ShortType.v())) { return Type.I16; } else if (sootType.equals(soot.CharType.v())) { return Type.I16; } else if (sootType.equals(soot.IntType.v())) { return Type.I32; } else if (sootType.equals(soot.LongType.v())) { return Type.I64; } else if (sootType.equals(soot.FloatType.v())) { return Type.FLOAT; } else if (sootType.equals(soot.DoubleType.v())) { return Type.DOUBLE; } else if (sootType.equals(soot.VoidType.v())) { return Type.VOID; } else if (sootType instanceof soot.RefLikeType || sootType.equals(BottomType.v())) { return OBJECT_PTR; } else { throw new IllegalArgumentException("Unknown Type: " + sootType); } }
public static int getFieldSize(Arch arch, SootField f) { soot.Type t = f.getType(); if (LongType.v().equals(t) || DoubleType.v().equals(t)) { return 8; } if (IntType.v().equals(t) || FloatType.v().equals(t)) { return 4; } if (t instanceof RefLikeType) { return arch.is32Bit() ? 4 : 8; } if (ShortType.v().equals(t) || CharType.v().equals(t)) { return 2; } if (ByteType.v().equals(t) || BooleanType.v().equals(t)) { return 1; } throw new IllegalArgumentException("Unknown Type: " + t); }
private static int getFieldSize(SootField f) { soot.Type t = f.getType(); if (LongType.v().equals(t) || DoubleType.v().equals(t)) { return 8; } if (IntType.v().equals(t) || FloatType.v().equals(t)) { return 4; } if (t instanceof RefLikeType) { // Assume pointers are 32-bit return 4; } if (ShortType.v().equals(t) || CharType.v().equals(t)) { return 2; } if (ByteType.v().equals(t) || BooleanType.v().equals(t)) { return 1; } throw new IllegalArgumentException("Unknown Type: " + t); }
public void outABooleanBaseType(ABooleanBaseType node) { mProductions.addLast(BooleanType.v()); }
void doWeave( SootMethod method, LocalGeneratorEx lg, AdviceApplication adviceappl, Residue residue, WeavingContext wc) { AdviceInliner.v().addShadowMethod(method); ShadowPoints shadowpoints = adviceappl.shadowmatch.sp; AbstractAdviceDecl advicedecl = adviceappl.advice; Body b = method.getActiveBody(); Chain units = b.getUnits().getNonPatchingChain(); // end of shadow Stmt endshadow = shadowpoints.getEnd(); NopStmt nop2 = Jimple.v().newNopStmt(); GotoStmt goto1 = Jimple.v().newGotoStmt(nop2); if (advicedecl instanceof CflowSetup) { Tagger.tagStmt(goto1, InstructionKindTag.CFLOW_EXIT); } else if (advicedecl instanceof PerCflowSetup) { Tagger.tagStmt(goto1, InstructionKindTag.PERCFLOW_EXIT); } else if (advicedecl instanceof DeclareSoft) { Tagger.tagStmt(goto1, InstructionKindTag.EXCEPTION_SOFTENER); } else if (advicedecl instanceof DeclareMessage) { Tagger.tagStmt(goto1, InstructionKindTag.DECLARE_MESSAGE); } else { Tagger.tagStmt(goto1, InstructionKindTag.AFTER_THROWING_HANDLER); } Tagger.tagStmt(goto1, new InstructionSourceTag(advicedecl.sourceId)); Tagger.tagStmt(goto1, new InstructionShadowTag(adviceappl.shadowmatch.shadowId)); units.insertBefore(nop2, endshadow); units.insertBefore(goto1, nop2); // have ... // goto1: goto nop2; // nop2: nop; // endshadow: nop; RefType catchType = getCatchType(); Local exception = lg.generateLocal(catchType, "exception"); bindException(wc, advicedecl, exception); CaughtExceptionRef exceptRef = Jimple.v().newCaughtExceptionRef(); IdentityStmt idStmt = Jimple.v().newIdentityStmt(exception, exceptRef); units.insertAfter(idStmt, goto1); ThrowStmt throwStmt = Jimple.v().newThrowStmt(exception); throwStmt.addTag(new ThrowCreatedByCompilerTag()); if (advicedecl instanceof CflowSetup) { Tagger.tagStmt(throwStmt, InstructionKindTag.CFLOW_EXIT); } else if (advicedecl instanceof PerCflowSetup) { Tagger.tagStmt(throwStmt, InstructionKindTag.PERCFLOW_EXIT); } else if (advicedecl instanceof DeclareSoft) { Tagger.tagStmt(throwStmt, InstructionKindTag.EXCEPTION_SOFTENER); } else if (advicedecl instanceof DeclareMessage) { Tagger.tagStmt(throwStmt, InstructionKindTag.DECLARE_MESSAGE); } else { Tagger.tagStmt(throwStmt, InstructionKindTag.AFTER_THROWING_HANDLER); } Tagger.tagStmt(throwStmt, new InstructionSourceTag(advicedecl.sourceId)); Tagger.tagStmt(throwStmt, new InstructionShadowTag(adviceappl.shadowmatch.shadowId)); // store shadow/source tag for this residue in weaving context if (advicedecl instanceof CflowSetup) { wc.setKindTag(InstructionKindTag.CFLOW_TEST); } if (advicedecl instanceof PerCflowSetup) { wc.setKindTag(InstructionKindTag.CFLOW_TEST); } wc.setShadowTag(new InstructionShadowTag(adviceappl.shadowmatch.shadowId)); wc.setSourceTag(new InstructionSourceTag(adviceappl.advice.sourceId)); Stmt endresidue = residue.codeGen(method, lg, units, idStmt, throwStmt, true, wc); // have ... // java.lang.Exception exception; // // goto1: goto nop2; // idStmt: exception := @caughtexception // nop2: nop; // endshadow: nop; units.insertAfter(throwStmt, endresidue); Chain invokestmts = advicedecl.makeAdviceExecutionStmts(adviceappl, lg, wc); for (Iterator stmtlist = invokestmts.iterator(); stmtlist.hasNext(); ) { Stmt nextstmt = (Stmt) stmtlist.next(); units.insertBefore(nextstmt, throwStmt); } if (method.getName().equals("<clinit>")) // have to handle case of ExceptionInInitialzerError { // if (exception instanceof java.lang.ExceptionInIntializerError) // throw (exception); debug("Adding extra check in clinit"); Local isInitError = lg.generateLocal(soot.BooleanType.v(), "isInitError"); Stmt assignbool = Jimple.v() .newAssignStmt( isInitError, Jimple.v() .newInstanceOfExpr( exception, RefType.v("java.lang.ExceptionInInitializerError"))); Stmt ifstmt = Jimple.v().newIfStmt(Jimple.v().newNeExpr(isInitError, IntConstant.v(0)), throwStmt); // ThrowStmt throwInitError = Jimple.v().newThrowStmt(exception); // units.insertAfter(throwInitError, idStmt); units.insertAfter(ifstmt, idStmt); units.insertAfter(assignbool, idStmt); } Stmt beginshadow = shadowpoints.getBegin(); Stmt begincode = (Stmt) units.getSuccOf(beginshadow); // have ... // java.lang.Exception exception; // <AspectType> theAspect; // // beginshadow: nop // begincode: <some statement> // .... <stuff in between> // goto1: goto nop2; // idStmt: exception := @caughtexception; // assignStmt: theAspect = new AspectOf(); // .... invoke statements .... // throwStmt: throw exception; // nop2: nop; // endshadow: nop; Chain traps = b.getTraps(); Trap t = traps.size() > 0 ? (Trap) traps.getFirst() : null; // assume no exception ranges overlap with this one; make sure // we go after any that would be enclosed within this one. while (t != null && (units.follows(t.getBeginUnit(), begincode) || (t.getBeginUnit() == begincode && units.follows(idStmt, t.getEndUnit())))) t = (Trap) traps.getSuccOf(t); Trap newt = Jimple.v().newTrap(catchType.getSootClass(), begincode, idStmt, idStmt); if (t == null) traps.addLast(newt); else traps.insertBefore(newt, t); // added // catch java.lang.Throwable // from begincode upto idStmt handlewith idStmt } // method doWeave
protected void readRefField(OpenCLField ref_field) { SootField soot_field = ref_field.getSootField(); SootClass soot_class = Scene.v().getSootClass(soot_field.getDeclaringClass().getName()); BytecodeLanguage bcl = m_bcl.top(); Local gc_obj_visit = m_gcObjVisitor.top(); BclMemory bcl_mem = new BclMemory(bcl, m_currMem.top()); Local ref = bcl_mem.readRef(); bcl_mem.useInstancePointer(); bcl_mem.pushAddress(); bcl_mem.setAddress(ref); // bcl.println("reading field: "+ref_field.getName()); SootClass obj_class = Scene.v().getSootClass("java.lang.Object"); SootClass string = Scene.v().getSootClass("java.lang.String"); SootClass class_class = Scene.v().getSootClass("java.lang.Class"); Local original_field_value; if (soot_class.isApplicationClass() == false) { if (ref_field.isInstance()) { bcl.pushMethod( gc_obj_visit, "readField", obj_class.getType(), obj_class.getType(), string.getType()); original_field_value = bcl.invokeMethodRet( gc_obj_visit, m_objSerializing.top(), StringConstant.v(soot_field.getName())); } else { bcl.pushMethod( gc_obj_visit, "readStaticField", obj_class.getType(), class_class.getType(), string.getType()); Local cls = bcl.classConstant(soot_field.getDeclaringClass().getType()); original_field_value = bcl.invokeMethodRet(gc_obj_visit, cls, StringConstant.v(soot_field.getName())); } } else { if (ref_field.isInstance()) { original_field_value = bcl.refInstanceField(m_objSerializing.top(), ref_field.getName()); } else { original_field_value = bcl.refStaticField(soot_class.getType(), ref_field.getName()); } } bcl.pushMethod( gc_obj_visit, "readFromHeap", obj_class.getType(), obj_class.getType(), BooleanType.v(), LongType.v()); int should_read = 1; Local ret_obj = bcl.invokeMethodRet(gc_obj_visit, original_field_value, IntConstant.v(should_read), ref); Type type = soot_field.getType(); Local ret = bcl.cast(type, ret_obj); if (soot_class.isApplicationClass() == false) { if (ref_field.isInstance()) { bcl.pushMethod( gc_obj_visit, "writeField", VoidType.v(), obj_class.getType(), string.getType(), obj_class.getType()); bcl.invokeMethodNoRet( gc_obj_visit, m_objSerializing.top(), StringConstant.v(soot_field.getName()), ret); } else { bcl.pushMethod( gc_obj_visit, "writeStaticField", VoidType.v(), class_class.getType(), string.getType(), obj_class.getType()); Local cls = bcl.classConstant(soot_field.getDeclaringClass().getType()); bcl.invokeMethodNoRet(gc_obj_visit, cls, StringConstant.v(soot_field.getName()), ret); } } else { if (ref_field.isInstance()) { bcl.setInstanceField(soot_field, m_objSerializing.top(), ret); } else { bcl.setStaticField(soot_field, ret); } } bcl_mem.popAddress(); }
private StructureConstant createClassInfoStruct() { int flags = 0; if (Modifier.isPublic(sootClass.getModifiers())) { flags |= CI_PUBLIC; } if (Modifier.isFinal(sootClass.getModifiers())) { flags |= CI_FINAL; } if (Modifier.isInterface(sootClass.getModifiers())) { flags |= CI_INTERFACE; } if (Modifier.isAbstract(sootClass.getModifiers())) { flags |= CI_ABSTRACT; } if ((sootClass.getModifiers() & 0x1000) > 0) { flags |= CI_SYNTHETIC; } if (Modifier.isAnnotation(sootClass.getModifiers())) { flags |= CI_ANNOTATION; } if (Modifier.isEnum(sootClass.getModifiers())) { flags |= CI_ENUM; } if (attributesEncoder.classHasAttributes()) { flags |= CI_ATTRIBUTES; } if (hasFinalizer(sootClass)) { flags |= CI_FINALIZABLE; } // Create the ClassInfoHeader structure. StructureConstantBuilder header = new StructureConstantBuilder(); header.add(new NullConstant(I8_PTR)); // Points to the runtime Class struct header.add(new IntegerConstant(flags)); header.add(getString(getInternalName(sootClass))); if (sootClass.declaresMethod("<clinit>", Collections.emptyList(), VoidType.v())) { SootMethod method = sootClass.getMethod("<clinit>", Collections.emptyList(), VoidType.v()); header.add(new FunctionRef(mangleMethod(method), getFunctionType(method))); } else { header.add(new NullConstant(I8_PTR)); } header.add(sizeof(classType)); header.add(sizeof(instanceType)); if (!instanceFields.isEmpty()) { header.add(offsetof(instanceType, 1, 1)); } else { header.add(sizeof(instanceType)); } header.add(new IntegerConstant((short) countReferences(classFields))); header.add(new IntegerConstant((short) countReferences(instanceFields))); PackedStructureConstantBuilder body = new PackedStructureConstantBuilder(); body.add(new IntegerConstant((short) sootClass.getInterfaceCount())); body.add(new IntegerConstant((short) sootClass.getFieldCount())); body.add(new IntegerConstant((short) sootClass.getMethodCount())); if (!sootClass.isInterface()) { body.add( getStringOrNull( sootClass.hasSuperclass() ? getInternalName(sootClass.getSuperclass()) : null)); } if (attributesEncoder.classHasAttributes()) { body.add(new ConstantBitcast(attributesEncoder.getClassAttributes().ref(), I8_PTR)); } for (SootClass s : sootClass.getInterfaces()) { body.add(getString(getInternalName(s))); } for (SootField f : sootClass.getFields()) { flags = 0; soot.Type t = f.getType(); if (t instanceof PrimType) { if (t.equals(BooleanType.v())) { flags |= DESC_Z; } else if (t.equals(ByteType.v())) { flags |= DESC_B; } else if (t.equals(ShortType.v())) { flags |= DESC_S; } else if (t.equals(CharType.v())) { flags |= DESC_C; } else if (t.equals(IntType.v())) { flags |= DESC_I; } else if (t.equals(LongType.v())) { flags |= DESC_J; } else if (t.equals(FloatType.v())) { flags |= DESC_F; } else if (t.equals(DoubleType.v())) { flags |= DESC_D; } flags <<= 12; } if (Modifier.isPublic(f.getModifiers())) { flags |= FI_PUBLIC; } else if (Modifier.isPrivate(f.getModifiers())) { flags |= FI_PRIVATE; } else if (Modifier.isProtected(f.getModifiers())) { flags |= FI_PROTECTED; } if (Modifier.isStatic(f.getModifiers())) { flags |= FI_STATIC; } if (Modifier.isFinal(f.getModifiers())) { flags |= FI_FINAL; } if (Modifier.isVolatile(f.getModifiers())) { flags |= FI_VOLATILE; } if (Modifier.isTransient(f.getModifiers())) { flags |= FI_TRANSIENT; } if ((f.getModifiers() & 0x1000) > 0) { flags |= FI_SYNTHETIC; } if (Modifier.isEnum(f.getModifiers())) { flags |= FI_ENUM; } if (attributesEncoder.fieldHasAttributes(f)) { flags |= FI_ATTRIBUTES; } body.add(new IntegerConstant((short) flags)); body.add(getString(f.getName())); if (!(t instanceof PrimType)) { body.add(getString(getDescriptor(f))); } if (f.isStatic()) { int index = classFields.indexOf(f); body.add(offsetof(classType, 1, index, 1)); } else { int index = instanceFields.indexOf(f); body.add(offsetof(instanceType, 1, 1 + index, 1)); } if (attributesEncoder.fieldHasAttributes(f)) { body.add(new ConstantBitcast(attributesEncoder.getFieldAttributes(f).ref(), I8_PTR)); } } for (SootMethod m : sootClass.getMethods()) { soot.Type t = m.getReturnType(); flags = 0; if (Modifier.isPublic(m.getModifiers())) { flags |= MI_PUBLIC; } else if (Modifier.isPrivate(m.getModifiers())) { flags |= MI_PRIVATE; } else if (Modifier.isProtected(m.getModifiers())) { flags |= MI_PROTECTED; } if (Modifier.isStatic(m.getModifiers())) { flags |= MI_STATIC; } if (Modifier.isFinal(m.getModifiers())) { flags |= MI_FINAL; } if (Modifier.isSynchronized(m.getModifiers())) { flags |= MI_SYNCHRONIZED; } if ((m.getModifiers() & 0x0040) > 0) { flags |= MI_BRIDGE; } if ((m.getModifiers() & 0x0080) > 0) { flags |= MI_VARARGS; } if (Modifier.isNative(m.getModifiers())) { if (!isStruct(sootClass) && !isStructMember(m)) { flags |= MI_NATIVE; } } if (Modifier.isAbstract(m.getModifiers())) { flags |= MI_ABSTRACT; } if (Modifier.isStrictFP(m.getModifiers())) { flags |= MI_STRICT; } if ((m.getModifiers() & 0x1000) > 0) { flags |= MI_SYNTHETIC; } if (attributesEncoder.methodHasAttributes(m)) { flags |= MI_ATTRIBUTES; } if (isBridge(m)) { flags |= MI_BRO_BRIDGE; } if (isCallback(m)) { flags |= MI_BRO_CALLBACK; } if ((t instanceof PrimType || t == VoidType.v()) && m.getParameterCount() == 0) { flags |= MI_COMPACT_DESC; } body.add(new IntegerConstant((short) flags)); body.add(getString(m.getName())); if ((flags & MI_COMPACT_DESC) > 0) { int desc = 0; if (t.equals(BooleanType.v())) { desc = DESC_Z; } else if (t.equals(ByteType.v())) { desc = DESC_B; } else if (t.equals(ShortType.v())) { desc = DESC_S; } else if (t.equals(CharType.v())) { desc = DESC_C; } else if (t.equals(IntType.v())) { desc = DESC_I; } else if (t.equals(LongType.v())) { desc = DESC_J; } else if (t.equals(FloatType.v())) { desc = DESC_F; } else if (t.equals(DoubleType.v())) { desc = DESC_D; } else if (t.equals(VoidType.v())) { desc = DESC_V; } body.add(new IntegerConstant((byte) desc)); } else { body.add(getString(getDescriptor(m))); } if (attributesEncoder.methodHasAttributes(m)) { body.add(new ConstantBitcast(attributesEncoder.getMethodAttributes(m).ref(), I8_PTR)); } if (!m.isAbstract()) { body.add(new ConstantBitcast(new FunctionRef(mangleMethod(m), getFunctionType(m)), I8_PTR)); body.add( new IntegerConstant( DUMMY_METHOD_SIZE)); // Size of function. This value will be modified later by // patching the .s file. if (m.isSynchronized()) { body.add( new ConstantBitcast( new FunctionRef(mangleMethod(m) + "_synchronized", getFunctionType(m)), I8_PTR)); } } if (isBridge(m)) { body.add(new GlobalRef(BridgeMethodCompiler.getTargetFnPtrName(m), I8_PTR)); } if (isCallback(m)) { body.add( new ConstantBitcast( new FunctionRef(mangleMethod(m) + "_callback", getCallbackFunctionType(m)), I8_PTR)); } } // Return the struct {header, body}. To be compatible with the C code in classinfo.c // it is important that the header is padded the same as in C so that the body starts // after sizeof(ClassInfoHeader) bytes. return new StructureConstantBuilder().add(header.build()).add(body.build()).build(); }
@Before public void setup() { BOOLEAN = new SootTypeType(BooleanType.v()); VOID = new SootTypeType(VoidType.v()); }