use of org.apache.bcel.generic.InstructionHandle in project jop by jop-devel.
the class InstructionFinder method search.
/**
* Search for the given pattern in the instruction list. You can search for
* any valid opcode via its symbolic name, e.g. "istore". You can also use a
* super class or an interface name to match a whole set of instructions, e.g.
* "BranchInstruction" or "LoadInstruction". "istore" is also an alias for all
* "istore_x" instructions. Additional aliases are "if" for "ifxx", "if_icmp"
* for "if_icmpxx", "if_acmp" for "if_acmpxx".
*
* BUGFIX: wrong length (WP)
*
* Consecutive instruction names must be separated by white space which will
* be removed during the compilation of the pattern.
*
* For the rest the usual pattern matching rules for regular expressions
* apply.
* <P>
* Example pattern:
*
* <pre>
* search("BranchInstruction NOP ((IfInstruction|GOTO)+ ISTORE Instruction)*");
* </pre>
*
* <p>
* If you alter the instruction list upon a match such that other matching
* areas are affected, you should call reread() to update the finder and call
* search() again, because the matches are cached.
*
* @param pattern
* the instruction pattern to search for, where case is ignored
* @param from
* where to start the search in the instruction list
* @param constraint
* optional CodeConstraint to check the found code pattern for
* user-defined constraints
* @return iterator of matches where e.nextElement() returns an array of
* instruction handles describing the matched area
*/
public final Iterator search(String pattern, InstructionHandle from, CodeConstraint constraint) {
String search = compilePattern(pattern);
int start = -1;
for (int i = 0; i < handles.length; i++) {
if (handles[i] == from) {
// Where to start search from (index)
start = i;
break;
}
}
if (start == -1) {
throw new ClassGenException("Instruction handle " + from + " not found in instruction list.");
}
Pattern regex = Pattern.compile(search);
List matches = new ArrayList();
Matcher matcher = regex.matcher(il_string);
while (start < il_string.length() && matcher.find(start)) {
int startExpr = matcher.start();
int endExpr = matcher.end();
// int lenExpr = (endExpr - startExpr) + 1;
int lenExpr = (endExpr - startExpr);
InstructionHandle[] match = getMatch(startExpr, lenExpr);
if ((constraint == null) || constraint.checkCode(match)) {
matches.add(match);
}
start = endExpr;
}
return matches.iterator();
}
use of org.apache.bcel.generic.InstructionHandle 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 org.apache.bcel.generic.InstructionHandle 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 org.apache.bcel.generic.InstructionHandle 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;
}
use of org.apache.bcel.generic.InstructionHandle in project jop by jop-devel.
the class CallStringReceiverTypes method doInvokeStatic.
private void doInvokeStatic(String methodName, InstructionHandle stmt, Context context, ContextMap<CallString, Set<TypeMapping>> input, Interpreter<CallString, Set<TypeMapping>> interpreter, Map<InstructionHandle, ContextMap<CallString, Set<TypeMapping>>> state, ContextMap<CallString, Set<TypeMapping>> result) {
DFATool p = interpreter.getDFATool();
MethodInfo method = p.getMethod(methodName);
if (method == null) {
throw new AppInfoError("DFA: cannot find static method " + methodName);
}
//noinspection AssignmentToMethodParameter
methodName = method.getClassName() + "." + method.getMethodSignature();
recordReceiver(stmt, context, methodName);
if (method.isNative()) {
handleNative(method, context, input, result);
} 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(context.getMethodInfo(), stmt, callStringLength);
// carry only minimal information with call
Set<TypeMapping> in = input.get(context.callString);
Set<TypeMapping> out = new LinkedHashSet<TypeMapping>();
ContextMap<CallString, Set<TypeMapping>> tmpresult = new ContextMap<CallString, Set<TypeMapping>>(c, new LinkedHashMap<CallString, Set<TypeMapping>>());
tmpresult.put(c.callString, out);
for (TypeMapping m : in) {
if (m.stackLoc < 0) {
out.add(m);
}
if (m.stackLoc >= varPtr) {
out.add(new TypeMapping(m.stackLoc - varPtr, m.type));
}
}
InstructionHandle entry = p.getEntryHandle(method);
state.put(entry, join(state.get(entry), tmpresult));
// interpret method
Map<InstructionHandle, ContextMap<CallString, Set<TypeMapping>>> r = interpreter.interpret(c, entry, state, false);
// pull out relevant information from call
InstructionHandle exit = p.getExitHandle(method);
if (r.get(exit) != null) {
Set<TypeMapping> returned = r.get(exit).get(c.callString);
if (returned != null) {
filterReturnSet(returned, result.get(context.callString), varPtr);
}
}
}
}
Aggregations