Пример #1
0
 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('.', '/') + ";";
   }
 }
Пример #2
0
 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);
   }
 }
Пример #3
0
 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);
 }
Пример #4
0
 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);
 }
Пример #5
0
 public void outAShortBaseType(AShortBaseType node) {
   mProductions.addLast(ShortType.v());
 }
Пример #6
0
  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();
  }