use of com.jopdesign.common.code.CallString in project jop by jop-devel.
the class AppInfo method findImplementations.
/**
* Find all methods which might get invoked for a given methodRef.
* This does not use the callgraph to eliminate methods. If you want a more precise result,
* use {@link #findImplementations(InvokeSite, CallString)} and use callgraph thinning first.
* <p>
* Note that this method is slightly different from {@link MethodInfo#getImplementations(boolean)}, since
* it returns only methods for subclasses of the invokee class, not of the implementing class.
* </p>
* <p>To handle invocations of super-methods correctly, use {@link #findImplementations(InvokeSite)}
* instead.</p>
*
* @see #findImplementations(InvokeSite)
* @see MethodInfo#overrides(MethodRef, boolean)
* @param invokee the method to resolve.
* @return all possible implementations, including native methods.
*/
public Set<MethodInfo> findImplementations(final MethodRef invokee) {
final Set<MethodInfo> methods = new LinkedHashSet<MethodInfo>();
// 'method' may refer to an inherited MethodInfo or to an interface method if there is no implementation
final MethodInfo method = invokee.getMethodInfo();
if (method != null && (method.isStatic() || method.isPrivate())) {
methods.add(method);
return methods;
}
final String methodSig = invokee.getMethodSignature();
final ClassInfo invokeeClass = invokee.getClassRef().getClassInfo();
if (invokeeClass == null) {
// ok, now, if the target class is unknown, there is not much we can do, so return an empty set
logger.debug("Trying to find implementations of a method in an unknown class " + invokee.toString());
return methods;
}
// Constructors are only called by invokespecial
if ("<init>".equals(invokee.getName())) {
MethodInfo init = invokee.getMethodInfo();
if (init == null) {
throw new JavaClassFormatError("Constructor not found: " + invokee);
}
if (init.isAbstract()) {
throw new JavaClassFormatError("Found abstract constructor, this isn't right..: " + invokee);
}
methods.add(init);
return methods;
}
boolean undefinedBaseMethod = false;
// check if method is defined in the referenced class or in a superclass
if (invokeeClass.getMethodInfo(methodSig) == null) {
// method is inherited, add to implementations
if (method != null && !method.isAbstract()) {
methods.add(method);
} else if (method == null) {
// hm, invoke to an unknown method (maybe excluded or native), what should we do?
if (invokeeClass.isFullyKnown(true)) {
// .. or maybe the method has not been loaded somehow when the MethodRef was created (check!)
throw new JavaClassFormatError("Method implementation not found in superclass: " + invokee.toString());
} else {
// maybe defined in excluded superclass, but we do not know for sure..
// We *must* return an empty set, but lets try to continue for now and
// handle it like an excluded class, and abort only if we find overriding methods
logger.debug("Method implementation not found in incomplete superclass: " + invokee.toString());
undefinedBaseMethod = true;
}
}
}
// now, we have a virtual call on our hands ..
ClassVisitor visitor = new ClassVisitor() {
public boolean visitClass(ClassInfo classInfo) {
// Note: we also handle interface classes here, because they can contain <clinit> methods
MethodInfo m;
if (invokeeClass.isInterface() && !classInfo.isInterface()) {
// If we invoke an interface method, we also need to find inherited methods in implementing
// classes
m = classInfo.getMethodInfoInherited(methodSig, true);
} else {
// If we do not invoke an interface method, 'method' is already the only possible inherited
// method; If the visited class is an interface, it does not inherit implementations.
m = classInfo.getMethodInfo(methodSig);
}
if (m != null) {
if (m.isPrivate() && !classInfo.equals(invokeeClass)) {
// found an overriding method which is private .. this is interesting..
logger.error("Found private method " + m.getMethodSignature() + " in " + classInfo.getClassName() + " overriding non-private method in " + invokee.getClassName());
}
if (!m.isAbstract() && (method == null || m.overrides(method, false))) {
methods.add(m);
}
}
return true;
}
public void finishClass(ClassInfo classInfo) {
}
};
ClassHierarchyTraverser traverser = new ClassHierarchyTraverser(visitor);
traverser.setVisitSubclasses(true, true);
traverser.traverseDown(invokeeClass);
if (undefinedBaseMethod && methods.size() > 0) {
// overriding methods, this we cannot handle for now
throw new JavaClassFormatError("Found overriding methods for " + invokee + " but superclasses are undefined!");
}
return methods;
}
use of com.jopdesign.common.code.CallString in project jop by jop-devel.
the class SymbolicPointsTo method transfer.
public ContextMap<CallString, SymbolicAddressMap> transfer(InstructionHandle stmt, FlowEdge edge, ContextMap<CallString, SymbolicAddressMap> input, Interpreter<CallString, SymbolicAddressMap> interpreter, Map<InstructionHandle, ContextMap<CallString, SymbolicAddressMap>> state) {
Context context = new Context(input.getContext());
if (DEBUG_PRINT) {
System.out.println("[S] " + context.callString.toStringList() + ": " + context.method() + " / " + stmt);
}
SymbolicAddressMap in = input.get(context.callString);
ContextMap<CallString, SymbolicAddressMap> retval = new ContextMap<CallString, SymbolicAddressMap>(context, input);
Instruction instruction = stmt.getInstruction();
int newStackPtr = context.stackPtr + instruction.produceStack(context.constPool()) - instruction.consumeStack(context.constPool());
int opcode = instruction.getOpcode();
switch(opcode) {
/* Constants (boring) */
case Constants.DCONST_0:
case Constants.DCONST_1:
case Constants.LCONST_0:
case Constants.LCONST_1:
/* Instructions above need two stack slots */
case Constants.FCONST_0:
case Constants.FCONST_1:
case Constants.FCONST_2:
case Constants.ICONST_M1:
case Constants.ICONST_0:
case Constants.ICONST_1:
case Constants.ICONST_2:
case Constants.ICONST_3:
case Constants.ICONST_4:
case Constants.ICONST_5:
case Constants.BIPUSH:
case Constants.SIPUSH:
{
retval.put(context.callString, in.cloneFilterStack(newStackPtr));
}
break;
case Constants.ACONST_NULL:
{
// Null -> No reference
SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
result.putStack(newStackPtr - 1, bsFactory.empty());
retval.put(context.callString, result);
}
break;
/* Long/Double Constants */
case Constants.LDC2_W:
{
retval.put(context.callString, in.cloneFilterStack(newStackPtr));
}
break;
/* Int/Float/String Constants */
case Constants.LDC:
case Constants.LDC_W:
{
LDC ldc = (LDC) instruction;
Type t = ldc.getType(context.constPool());
if (t instanceof ReferenceType) {
SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
/* FIXME: This is overly conservative, but class pointer not available here */
String classContext = context.getMethodInfo().getMemberID().toString();
SymbolicAddress addr = SymbolicAddress.stringLiteral(classContext, ldc.getIndex());
result.putStack(newStackPtr - 1, bsFactory.singleton(addr));
retval.put(context.callString, result);
} else {
retval.put(context.callString, in.cloneFilterStack(newStackPtr));
}
}
break;
case Constants.DSTORE:
case Constants.DSTORE_0:
case Constants.DSTORE_1:
case Constants.DSTORE_2:
case Constants.DSTORE_3:
case Constants.LSTORE:
case Constants.LSTORE_0:
case Constants.LSTORE_1:
case Constants.LSTORE_2:
case Constants.LSTORE_3:
case Constants.FSTORE:
case Constants.FSTORE_0:
case Constants.FSTORE_1:
case Constants.FSTORE_2:
case Constants.FSTORE_3:
case Constants.ISTORE_0:
case Constants.ISTORE_1:
case Constants.ISTORE_2:
case Constants.ISTORE_3:
case Constants.ISTORE:
{
retval.put(context.callString, in.cloneFilterStack(newStackPtr));
}
break;
//
case Constants.ASTORE_0:
case Constants.ASTORE_1:
case Constants.ASTORE_2:
case Constants.ASTORE_3:
case Constants.ASTORE:
{
// copy value to local variable
StoreInstruction instr = (StoreInstruction) instruction;
SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
if (DEBUG_PRINT) {
System.out.println(String.format("[DD] Copy: stack[%d] <- stack[%d]", instr.getIndex(), context.stackPtr - 1));
}
result.copyStack(in, instr.getIndex(), context.stackPtr - 1);
retval.put(context.callString, result);
}
break;
/* Load variables (boring) */
case Constants.DLOAD_0:
case Constants.DLOAD_1:
case Constants.DLOAD_2:
case Constants.DLOAD_3:
case Constants.DLOAD:
case Constants.LLOAD_0:
case Constants.LLOAD_1:
case Constants.LLOAD_2:
case Constants.LLOAD_3:
case Constants.LLOAD:
/* Instructions above need two stack slots */
case Constants.FLOAD_0:
case Constants.FLOAD_1:
case Constants.FLOAD_2:
case Constants.FLOAD_3:
case Constants.FLOAD:
case Constants.ILOAD_0:
case Constants.ILOAD_1:
case Constants.ILOAD_2:
case Constants.ILOAD_3:
case Constants.ILOAD:
{
retval.put(context.callString, in.cloneFilterStack(newStackPtr));
}
break;
/* Floating Point Comparison (boring) */
case Constants.DCMPG:
case Constants.DCMPL:
case Constants.LCMP:
/* Instructions above need two stack slots */
case Constants.FCMPG:
case Constants.FCMPL:
{
retval.put(context.callString, in.cloneFilterStack(newStackPtr));
}
break;
case Constants.ALOAD_0:
case Constants.ALOAD_1:
case Constants.ALOAD_2:
case Constants.ALOAD_3:
case Constants.ALOAD:
{
LoadInstruction instr = (LoadInstruction) instruction;
// copy value from local variable
SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
result.copyStack(in, context.stackPtr, instr.getIndex());
retval.put(context.callString, result);
}
break;
// Access Object Handle (area), top of stack
case Constants.ARRAYLENGTH:
{
putResult(stmt, context, input.get(context.callString).getStack(context.stackPtr - 1));
retval.put(context.callString, in.cloneFilterStack(newStackPtr));
}
break;
// Access Object Handle, second on stack
case Constants.PUTFIELD:
{
PUTFIELD instr = (PUTFIELD) instruction;
putResult(stmt, context, input.get(context.callString).getStack(context.stackPtr - 1 - instr.getType(context.constPool()).getSize()));
SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
// Change alias information
if (instr.getFieldType(context.constPool()) instanceof ReferenceType) {
String ty = instr.getFieldType(context.constPool()).getSignature();
result.addAlias(ty, in.getStack(context.stackPtr - 1));
}
retval.put(context.callString, result);
}
break;
// Access Object Handle, top of stack
case Constants.GETFIELD:
{
putResult(stmt, context, input.get(context.callString).getStack(context.stackPtr - 1));
GETFIELD instr = (GETFIELD) instruction;
SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
if (instr.getFieldType(context.constPool()) instanceof ReferenceType) {
BoundedSet<SymbolicAddress> newMapping = SymbolicAddress.fieldAccess(bsFactory, in.getStack(context.stackPtr - 1), instr.getFieldName(context.constPool()));
newMapping.addAll(in.getAliases(instr.getFieldType(context.constPool()).getSignature()));
result.putStack(context.stackPtr - 1, newMapping);
}
retval.put(context.callString, result);
}
break;
// Handles the same way as MOV
case Constants.PUTSTATIC:
{
PUTSTATIC instr = (PUTSTATIC) instruction;
SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
if (instr.getFieldType(context.constPool()) instanceof ReferenceType) {
BoundedSet<SymbolicAddress> pointers = in.getStack(context.stackPtr - 1);
result.putHeap(fieldSignature(context, instr), pointers);
}
retval.put(context.callString, result);
}
break;
// Handled the same as MOV
case Constants.GETSTATIC:
{
GETSTATIC instr = (GETSTATIC) instruction;
SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
if (instr.getFieldType(context.constPool()) instanceof ReferenceType) {
result.putStack(context.stackPtr, in.getHeap(fieldSignature(context, instr)));
}
retval.put(context.callString, result);
}
break;
case Constants.LASTORE:
case Constants.DASTORE:
case Constants.IASTORE:
case Constants.FASTORE:
case Constants.CASTORE:
case Constants.SASTORE:
case Constants.BASTORE:
{
int offset = 3;
if (opcode == Constants.LASTORE || opcode == Constants.DASTORE)
offset = 4;
putResult(stmt, context, input.get(context.callString).getStack(context.stackPtr - offset));
retval.put(context.callString, in.cloneFilterStack(newStackPtr));
}
break;
// changing the heap -> TOP
case Constants.AASTORE:
{
putResult(stmt, context, input.get(context.callString).getStack(context.stackPtr - 3));
AASTORE instr = (AASTORE) stmt.getInstruction();
SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
// Change alias information
if (instr.getType(context.constPool()) instanceof ReferenceType) {
String ty = instr.getType(context.constPool()).getSignature();
result.addAlias(ty, in.getStack(context.stackPtr - 1));
}
retval.put(context.callString, result);
}
break;
case Constants.DALOAD:
case Constants.LALOAD:
case Constants.IALOAD:
case Constants.FALOAD:
case Constants.CALOAD:
case Constants.SALOAD:
case Constants.BALOAD:
{
putResult(stmt, context, input.get(context.callString).getStack(context.stackPtr - 2));
retval.put(context.callString, in.cloneFilterStack(newStackPtr));
}
break;
// TODO: Use index info
case Constants.AALOAD:
{
putResult(stmt, context, input.get(context.callString).getStack(context.stackPtr - 2));
// AALOAD instr = (AALOAD)instruction;
SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
BoundedSet<SymbolicAddress> objectMapping = in.getStack(context.stackPtr - 2);
BoundedSet<SymbolicAddress> newMapping;
LoopBounds bounds = interpreter.getDFATool().getLoopBounds();
if (executedOnce.query(stmt)) {
newMapping = bsFactory.singleton(SymbolicAddress.newName());
} else if (objectMapping.isSaturated() || bounds == null) {
newMapping = bsFactory.top();
} else {
Interval interval = bounds.getArrayIndices(stmt, context.callString);
if (interval.hasLb() && interval.hasUb()) {
newMapping = bsFactory.empty();
for (SymbolicAddress addr : objectMapping.getSet()) {
for (int i = interval.getLb(); i <= interval.getUb(); i++) {
newMapping.add(addr.accessArray(i));
}
}
} else {
newMapping = bsFactory.top();
}
}
// Doesn't work, but is probably stupid anyway :(
// LoopBounds bounds = interpreter.getDFATool().getLoopBounds();
// bounds.getArraySizes().get(stmt).get(context.callString);
// newMapping = bsFactory.empty();
// Interval[] sizeBounds = { new Interval(2,3) };
// for(Interval i : sizeBounds) {
// if(! i.hasUb()) {
// newMapping = bsFactory.top();
// }
// int ub = i.getUb();
// for(int j = 0; j <= ub; j++) {
// for(SymbolicAddress addr: objectMapping.getSet()) {
// newMapping.add(addr.accessArray(j));
// }
// }
// }
// }
result.putStack(context.stackPtr - 2, newMapping);
retval.put(context.callString, result);
}
break;
case Constants.DUP:
{
// copy value on stack
SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
result.copyStack(in, context.stackPtr, context.stackPtr - 1);
retval.put(context.callString, result);
}
break;
case Constants.DUP_X1:
{
// copy value on stack
SymbolicAddressMap result = in.cloneFilterStack(context.stackPtr - 2);
result.copyStack(in, context.stackPtr - 2, context.stackPtr - 1);
result.copyStack(in, context.stackPtr - 1, context.stackPtr - 2);
result.copyStack(in, context.stackPtr, context.stackPtr - 1);
retval.put(context.callString, result);
}
break;
case Constants.DUP_X2:
{
// copy value on stack
SymbolicAddressMap result = in.cloneFilterStack(context.stackPtr - 3);
result.copyStack(in, context.stackPtr - 3, context.stackPtr - 1);
result.copyStack(in, context.stackPtr - 2, context.stackPtr - 3);
result.copyStack(in, context.stackPtr - 1, context.stackPtr - 2);
result.copyStack(in, context.stackPtr, context.stackPtr - 1);
retval.put(context.callString, result);
}
break;
case Constants.DUP2:
{
// v1,v2 -> v1,v2,v1,v2
SymbolicAddressMap result = in.cloneFilterStack(context.stackPtr);
result.copyStack(in, context.stackPtr, context.stackPtr - 2);
result.copyStack(in, context.stackPtr + 1, context.stackPtr - 1);
retval.put(context.callString, result);
}
break;
case Constants.POP:
case Constants.POP2:
{
retval.put(context.callString, in.cloneFilterStack(newStackPtr));
}
break;
case Constants.IINC:
{
retval.put(context.callString, in.cloneFilterStack(newStackPtr));
}
break;
case Constants.IADD:
case Constants.ISUB:
case Constants.INEG:
case Constants.IUSHR:
case Constants.ISHR:
case Constants.IAND:
case Constants.IOR:
case Constants.IXOR:
case Constants.IMUL:
case Constants.IDIV:
case Constants.IREM:
case Constants.ISHL:
{
retval.put(context.callString, in.cloneFilterStack(newStackPtr));
}
break;
/* Long,Float and Double operations (boring) */
case Constants.DADD:
case Constants.DSUB:
case Constants.DMUL:
case Constants.DDIV:
case Constants.DREM:
case Constants.LADD:
case Constants.LSUB:
case Constants.LUSHR:
case Constants.LSHR:
case Constants.LAND:
case Constants.LOR:
case Constants.LXOR:
case Constants.LMUL:
case Constants.LDIV:
case Constants.LREM:
case Constants.LSHL:
/* Instructions above need two stack slots */
case Constants.DNEG:
case Constants.LNEG:
case Constants.FADD:
case Constants.FSUB:
case Constants.FNEG:
case Constants.FMUL:
case Constants.FDIV:
case Constants.FREM:
{
retval.put(context.callString, in.cloneFilterStack(newStackPtr));
}
break;
/* Conversion of primitives (boring) */
case Constants.D2F:
case Constants.D2I:
/* Instructions above need two stack slots */
case Constants.D2L:
{
retval.put(context.callString, in.cloneFilterStack(newStackPtr));
}
break;
case Constants.L2F:
case Constants.L2I:
/* Instructions above need two stack slots */
case Constants.L2D:
{
retval.put(context.callString, in.cloneFilterStack(newStackPtr));
}
break;
case Constants.F2D:
case Constants.I2D:
case Constants.F2L:
case Constants.I2L:
/* Instructions above need one stack slot less */
case Constants.F2I:
case Constants.I2B:
case Constants.I2C:
case Constants.I2F:
case Constants.I2S:
{
retval.put(context.callString, in.cloneFilterStack(newStackPtr));
}
break;
case Constants.MONITORENTER:
// not supported yet
if (ASSUME_NO_CONC)
retval.put(context.callString, in.cloneFilterStack(newStackPtr));
else
retval.put(context.callString, SymbolicAddressMap.top());
break;
case Constants.MONITOREXIT:
// not supported yet
retval.put(context.callString, in.cloneFilterStack(newStackPtr));
break;
case Constants.CHECKCAST:
retval.put(context.callString, in.cloneFilterStack(newStackPtr));
break;
case Constants.INSTANCEOF:
{
retval.put(context.callString, in.cloneFilterStack(newStackPtr));
}
break;
case Constants.NEW:
case Constants.NEWARRAY:
case Constants.ANEWARRAY:
{
SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
BoundedSet<SymbolicAddress> newMapping;
if (executedOnce.query(stmt)) {
newMapping = bsFactory.singleton(SymbolicAddress.newName());
} else {
newMapping = bsFactory.top();
}
int objPtr = (instruction.getOpcode() == Constants.NEW) ? context.stackPtr : (context.stackPtr - 1);
result.putStack(objPtr, newMapping);
retval.put(context.callString, result);
}
break;
case Constants.MULTIANEWARRAY:
{
// not supported yet
retval.put(context.callString, SymbolicAddressMap.top());
}
break;
case Constants.GOTO:
retval.put(context.callString, in.cloneFilterStack(newStackPtr));
break;
case Constants.IFNULL:
case Constants.IFNONNULL:
{
retval.put(context.callString, in.cloneFilterStack(newStackPtr));
}
break;
case Constants.IF_ACMPEQ:
case Constants.IF_ACMPNE:
{
retval.put(context.callString, in.cloneFilterStack(newStackPtr));
}
break;
case Constants.IFEQ:
case Constants.IFNE:
case Constants.IFLT:
case Constants.IFGE:
case Constants.IFLE:
case Constants.IFGT:
retval.put(context.callString, in.cloneFilterStack(newStackPtr));
break;
case Constants.IF_ICMPEQ:
case Constants.IF_ICMPNE:
case Constants.IF_ICMPLT:
case Constants.IF_ICMPGE:
case Constants.IF_ICMPGT:
case Constants.IF_ICMPLE:
retval.put(context.callString, in.cloneFilterStack(newStackPtr));
break;
case Constants.LOOKUPSWITCH:
case Constants.TABLESWITCH:
retval.put(context.callString, in.cloneFilterStack(newStackPtr));
break;
case Constants.INVOKEVIRTUAL:
case Constants.INVOKEINTERFACE:
case Constants.INVOKESTATIC:
case Constants.INVOKESPECIAL:
{
DFATool p = interpreter.getDFATool();
Set<String> receivers = p.getReceivers(stmt, context.callString);
retval.put(context.callString, new SymbolicAddressMap(bsFactory));
if (receivers == null || receivers.size() == 0) {
String errMsg = String.format("%s : invoke %s: %s receivers", context.method(), instruction.toString(context.constPool().getConstantPool()), (receivers == null ? "Unknown" : "No"));
// Get static receivers (FIXME: this just workarounds DFA bugs)
if (opcode == Constants.INVOKESTATIC) {
receivers = new HashSet<String>();
InvokeInstruction invInstruction = (InvokeInstruction) instruction;
String klass = invInstruction.getClassName(context.constPool());
String name = invInstruction.getMethodName(context.constPool());
String sig = invInstruction.getSignature(context.constPool());
String recv = klass + "." + name + sig;
Logger.getLogger(this.getClass()).info("Using static receiver: " + recv);
receivers.add(recv);
} else {
Logger.getLogger(this.getClass()).error(errMsg);
throw new AssertionError(errMsg);
}
}
if (instruction.getOpcode() == Constants.INVOKEVIRTUAL || instruction.getOpcode() == Constants.INVOKEINTERFACE) {
MethodInfo mi = p.getMethod(receivers.iterator().next());
int refPos = MethodHelper.getArgSize(mi);
// mi.methodId,refPos,context.stackPtr,input.get(context.callString)));
try {
putResult(stmt, context, input.get(context.callString).getStack(context.stackPtr - refPos));
} catch (Error e) {
System.err.println("We have problems with method " + mi);
System.err.println(e.getMessage());
}
}
for (String methodName : receivers) {
doInvoke(methodName, stmt, context, input, interpreter, state, retval);
}
}
break;
case Constants.ARETURN:
{
SymbolicAddressMap result = in.cloneFilterStack(0);
// store results
result.copyStack(in, 0, context.stackPtr - 1);
retval.put(context.callString, result);
}
break;
/* The values of other return statements are not of interest here */
case Constants.DRETURN:
case Constants.LRETURN:
case Constants.FRETURN:
case Constants.IRETURN:
case Constants.RETURN:
{
retval.put(context.callString, in.cloneFilterStack(newStackPtr));
}
break;
default:
System.err.println("unknown instruction: " + stmt + " in method " + context.method());
retval.put(context.callString, in.cloneFilterStack(newStackPtr));
break;
}
// DEBUGGING
if (DEBUG_PRINT) {
System.out.println("[F] " + context.method() + " / " + stmt);
System.out.println(" Stackptr: " + context.stackPtr + " -> " + newStackPtr);
System.out.println(" Before: ");
input.get(context.callString).print(System.out, 4);
System.out.println(" After: ");
retval.get(context.callString).print(System.out, 4);
}
context.stackPtr = newStackPtr;
return retval;
}
use of com.jopdesign.common.code.CallString in project jop by jop-devel.
the class SymbolicPointsTo method printResult.
public void printResult(DFATool program) {
Map<String, String> getFields = new TreeMap<String, String>();
for (InstructionHandle instr : usedRefs.keySet()) {
ContextMap<CallString, BoundedSet<SymbolicAddress>> r = usedRefs.get(instr);
Context c = r.getContext();
MethodInfo method = c.getMethodInfo();
if (method == null) {
throw new AssertionError("Internal Error: No method '" + c.method() + "'");
}
LineNumberTable lines = method.getCode().getLineNumberTable();
int sourceLine = lines.getSourceLine(instr.getPosition());
for (CallString callString : r.keySet()) {
System.out.println(c.method() + ":" + sourceLine + ":" + callString + ": " + instr);
BoundedSet<SymbolicAddress> symAddr = r.get(callString);
String infoStr;
if (instr.getInstruction() instanceof GETFIELD) {
GETFIELD gfInstr = (GETFIELD) instr.getInstruction();
infoStr = String.format("GETFIELD %s %s %s", symAddr.toString(), gfInstr.getFieldName(c.constPool()), gfInstr.getFieldType(c.constPool()));
} else if (instr.getInstruction() instanceof ARRAYLENGTH) {
infoStr = String.format("ARRAYLENGTH %s", symAddr.toString());
} else if (instr.getInstruction() instanceof ArrayInstruction) {
ArrayInstruction aInstr = (ArrayInstruction) instr.getInstruction();
infoStr = String.format("%s %s %s[]", aInstr.getName().toUpperCase(), symAddr.toString(), aInstr.getType(c.constPool()));
} else {
infoStr = String.format("%s %s", instr.getInstruction().getName().toUpperCase(), symAddr.toString());
}
if (infoStr != null) {
String infoKey = String.format("%s:%04d:%s", c.method(), sourceLine, callString);
while (getFields.containsKey(infoKey)) infoKey += "'";
getFields.put(infoKey, infoStr);
}
}
}
for (Entry<String, String> entry : getFields.entrySet()) {
System.out.println(entry.getKey());
System.out.println(" " + entry.getValue());
}
}
use of com.jopdesign.common.code.CallString in project jop by jop-devel.
the class SymbolicPointsTo method doInvoke.
private void doInvoke(String methodName, InstructionHandle stmt, Context context, ContextMap<CallString, SymbolicAddressMap> input, Interpreter<CallString, SymbolicAddressMap> interpreter, Map<InstructionHandle, ContextMap<CallString, SymbolicAddressMap>> state, ContextMap<CallString, SymbolicAddressMap> retval) {
DFATool p = interpreter.getDFATool();
MethodInfo method = p.getMethod(methodName);
if (method.isNative()) {
handleNative(method, context, input, retval);
} else {
// set up new context
int varPtr = context.stackPtr - MethodHelper.getArgSize(method);
Context c = new Context(context);
c.stackPtr = method.getCode().getMaxLocals();
if (method.isSynchronized()) {
c.syncLevel = context.syncLevel + 1;
}
c.setMethodInfo(method);
c.callString = c.callString.push(method, stmt, callStringLength);
// carry only minimal information with call
SymbolicAddressMap in = input.get(context.callString);
SymbolicAddressMap out = in.cloneInvoke(varPtr);
HashMap<CallString, SymbolicAddressMap> initialMap = new HashMap<CallString, SymbolicAddressMap>();
ContextMap<CallString, SymbolicAddressMap> tmpresult = new ContextMap<CallString, SymbolicAddressMap>(c, initialMap);
tmpresult.put(c.callString, out);
InstructionHandle entry = p.getEntryHandle(method);
state.put(entry, join(state.get(entry), tmpresult));
if (DEBUG_PRINT) {
System.out.println("[I] Invoke: " + method.getMemberID());
System.out.println(String.format(" StackPtr: %d, framePtr: %d, args: %d", context.stackPtr, varPtr, MethodHelper.getArgSize(method)));
}
// interpret method
Map<InstructionHandle, ContextMap<CallString, SymbolicAddressMap>> r = interpreter.interpret(c, entry, state, false);
SymbolicAddressMap ctxInfo = retval.get(context.callString);
// pull out relevant information from call
InstructionHandle exit = p.getExitHandle(method);
if (r.get(exit) != null) {
SymbolicAddressMap returned = r.get(exit).get(c.callString);
if (returned != null) {
ctxInfo.joinReturned(returned, varPtr);
} else {
System.err.println("doInvoke(): No exit information for callstring ?");
}
} else {
System.err.println("Symbolic Points To[doInvoke()]: No exit information from " + methodName + "?");
}
// add relevant information to result
ctxInfo.addStackUpto(in, context.stackPtr - MethodHelper.getArgSize(method));
if (DEBUG_PRINT) {
System.out.println("[R] Invoke: " + method.getMemberID());
System.out.println(String.format(" StackPtr: %d, framePtr: %d, args: %d", context.stackPtr, varPtr, MethodHelper.getArgSize(method)));
}
}
}
use of com.jopdesign.common.code.CallString in project jop by jop-devel.
the class AnalysisResultSerialization method fromContextMapResult.
/**
* <p>Result Map: MethodInfo -> Instruction Offset -> Callstring -> R</p>
* <p>TODO: More efficient representations are possible</p>
* @param result the result of the DFA analysis
* @param serializer converter for the result domain (if not serializable), or null
* if the results of type T should be serialized directly
*/
public static <T, R> AnalysisResultSerialization<R> fromContextMapResult(Map<InstructionHandle, ContextMap<CallString, T>> result, Serializer<T, R> serializer) {
AnalysisResultSerialization<R> analysisResult = new AnalysisResultSerialization<R>();
/* sort instruction handle by: method, offset */
for (InstructionHandle instr : result.keySet()) {
ContextMap<CallString, T> r = result.get(instr);
Context c = r.getContext();
InstructionList il = c.getMethodInfo().getCode().getInstructionList(true, false);
for (CallString cs : r.keySet()) {
Integer position = instr.getPosition();
// skip stuff that is not used anymore
if (position < 0)
continue;
if (il.findHandle(position) != instr)
continue;
if (serializer != null) {
T rValue = r.get(cs);
R sValue = serializer.serializedRepresentation(rValue);
analysisResult.addResult(c.getMethodInfo(), position, cs, sValue);
} else {
analysisResult.addResult(c.getMethodInfo(), position, cs, (R) r.get(cs));
}
}
}
return analysisResult;
}
Aggregations