2007-02-02 17:17:13 +00:00
|
|
|
/******************************************************************************
|
|
|
|
* Copyright (c) 2002 - 2006 IBM Corporation.
|
|
|
|
* All rights reserved. This program and the accompanying materials
|
|
|
|
* are made available under the terms of the Eclipse Public License v1.0
|
|
|
|
* which accompanies this distribution, and is available at
|
|
|
|
* http://www.eclipse.org/legal/epl-v10.html
|
|
|
|
*
|
|
|
|
* Contributors:
|
|
|
|
* IBM Corporation - initial API and implementation
|
|
|
|
*****************************************************************************/
|
|
|
|
package com.ibm.wala.cast.ipa.callgraph;
|
|
|
|
|
2009-04-09 20:31:14 +00:00
|
|
|
import java.io.File;
|
|
|
|
import java.io.IOException;
|
2014-10-02 01:32:36 +00:00
|
|
|
import java.io.InputStream;
|
2009-04-09 20:31:14 +00:00
|
|
|
import java.net.MalformedURLException;
|
|
|
|
import java.net.URL;
|
|
|
|
import java.util.Collections;
|
2014-10-02 01:32:36 +00:00
|
|
|
import org.apache.commons.io.ByteOrderMark;
|
|
|
|
import org.apache.commons.io.input.BOMInputStream;
|
|
|
|
|
2009-04-09 20:31:14 +00:00
|
|
|
import com.ibm.wala.cast.loader.SingleClassLoaderFactory;
|
2012-01-06 21:37:27 +00:00
|
|
|
import com.ibm.wala.classLoader.IMethod;
|
2009-04-09 20:31:14 +00:00
|
|
|
import com.ibm.wala.classLoader.Language;
|
2017-02-03 01:33:27 +00:00
|
|
|
import com.ibm.wala.classLoader.Module;
|
2009-04-09 20:31:14 +00:00
|
|
|
import com.ibm.wala.classLoader.SourceFileModule;
|
2017-02-03 01:33:27 +00:00
|
|
|
import com.ibm.wala.ipa.callgraph.AnalysisCacheImpl;
|
2009-04-09 20:31:14 +00:00
|
|
|
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
|
|
|
import com.ibm.wala.ipa.callgraph.CGNode;
|
|
|
|
import com.ibm.wala.ipa.callgraph.CallGraph;
|
2017-06-28 16:42:49 +00:00
|
|
|
import com.ibm.wala.ipa.callgraph.IAnalysisCacheView;
|
2014-05-20 20:00:06 +00:00
|
|
|
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
2011-04-04 15:02:28 +00:00
|
|
|
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
|
|
|
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
2017-03-11 18:22:45 +00:00
|
|
|
import com.ibm.wala.ipa.callgraph.propagation.SSAContextInterpreter;
|
2012-01-27 20:15:33 +00:00
|
|
|
import com.ibm.wala.ssa.IRFactory;
|
2017-03-11 18:22:45 +00:00
|
|
|
import com.ibm.wala.ssa.IRView;
|
2017-12-04 04:39:28 +00:00
|
|
|
import com.ibm.wala.util.collections.Iterator2Iterable;
|
2007-02-02 17:17:13 +00:00
|
|
|
import com.ibm.wala.util.debug.Assertions;
|
|
|
|
|
2012-02-17 20:21:59 +00:00
|
|
|
public class CAstCallGraphUtil {
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2012-01-06 21:27:42 +00:00
|
|
|
/**
|
|
|
|
* flag to prevent dumping of verbose call graph / pointer analysis output
|
|
|
|
*/
|
2012-01-27 20:15:33 +00:00
|
|
|
public static boolean AVOID_DUMP = true;
|
2012-01-06 21:43:58 +00:00
|
|
|
|
2007-02-02 17:17:13 +00:00
|
|
|
public static SourceFileModule makeSourceModule(URL script, String dir, String name) {
|
2007-02-12 21:16:57 +00:00
|
|
|
// DO NOT use File.separator here, since this name is matched against
|
|
|
|
// URLs. It seems that, in DOS, URL.getFile() does not return a
|
|
|
|
// \-separated file name, but rather one with /'s. Rather makes one
|
2007-02-02 17:17:13 +00:00
|
|
|
// wonder why the function is called get_File_ :(
|
|
|
|
return makeSourceModule(script, dir + "/" + name);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static SourceFileModule makeSourceModule(URL script, String scriptName) {
|
2007-02-12 21:16:57 +00:00
|
|
|
String hackedName = script.getFile().replaceAll("%5c", "/").replaceAll("%20", " ");
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2007-02-12 21:16:57 +00:00
|
|
|
File scriptFile = new File(hackedName);
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2009-04-30 13:16:52 +00:00
|
|
|
assert hackedName.endsWith(scriptName) : scriptName + " does not match file " + script.getFile();
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2014-10-02 01:32:36 +00:00
|
|
|
return new SourceFileModule(scriptFile, scriptName, null) {
|
|
|
|
@Override
|
|
|
|
public InputStream getInputStream() {
|
|
|
|
BOMInputStream bs = new BOMInputStream(super.getInputStream(), false,
|
|
|
|
ByteOrderMark.UTF_8,
|
|
|
|
ByteOrderMark.UTF_16LE, ByteOrderMark.UTF_16BE,
|
|
|
|
ByteOrderMark.UTF_32LE, ByteOrderMark.UTF_32BE);
|
|
|
|
try {
|
|
|
|
if (bs.hasBOM()) {
|
|
|
|
System.err.println("removing BOM " + bs.getBOM());
|
|
|
|
}
|
|
|
|
return bs;
|
2017-03-23 21:32:00 +00:00
|
|
|
} catch (IOException e) {
|
2014-10-02 01:32:36 +00:00
|
|
|
return super.getInputStream();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
|
|
|
|
2017-07-27 21:53:07 +00:00
|
|
|
public static AnalysisScope makeScope(String[] files, SingleClassLoaderFactory loaders, Language language) {
|
2007-12-11 16:37:42 +00:00
|
|
|
CAstAnalysisScope result = new CAstAnalysisScope(files, loaders, Collections.singleton(language));
|
2007-12-10 04:26:21 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2017-07-27 21:53:07 +00:00
|
|
|
public static AnalysisScope makeScope(Module[] files, SingleClassLoaderFactory loaders, Language language) {
|
2007-12-11 16:37:42 +00:00
|
|
|
CAstAnalysisScope result = new CAstAnalysisScope(files, loaders, Collections.singleton(language));
|
2007-12-10 04:26:21 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2017-06-28 16:42:49 +00:00
|
|
|
public static IAnalysisCacheView makeCache(IRFactory<IMethod> factory) {
|
2017-02-03 01:33:27 +00:00
|
|
|
return new AnalysisCacheImpl(factory);
|
2007-12-10 04:26:21 +00:00
|
|
|
}
|
2012-01-06 21:43:58 +00:00
|
|
|
|
2012-01-06 21:37:27 +00:00
|
|
|
public static String getShortName(CGNode nd) {
|
|
|
|
IMethod method = nd.getMethod();
|
|
|
|
return getShortName(method);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static String getShortName(IMethod method) {
|
2012-01-06 21:43:58 +00:00
|
|
|
String origName = method.getName().toString();
|
|
|
|
String result = origName;
|
|
|
|
if (origName.equals("do") || origName.equals("ctor")) {
|
|
|
|
result = method.getDeclaringClass().getName().toString();
|
|
|
|
result = result.substring(result.lastIndexOf('/') + 1);
|
|
|
|
if (origName.equals("ctor")) {
|
|
|
|
if (result.equals("LFunction")) {
|
|
|
|
String s = method.toString();
|
|
|
|
if (s.indexOf('(') != -1) {
|
|
|
|
String functionName = s.substring(s.indexOf('(') + 1, s.indexOf(')'));
|
|
|
|
functionName = functionName.substring(functionName.lastIndexOf('/') + 1);
|
|
|
|
result += " " + functionName;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
result = "ctor of " + result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
2012-01-06 21:37:27 +00:00
|
|
|
}
|
2007-12-10 04:26:21 +00:00
|
|
|
|
2017-03-11 18:22:45 +00:00
|
|
|
public static void dumpCG(SSAContextInterpreter interp, PointerAnalysis<InstanceKey> PA, CallGraph CG) {
|
2012-01-06 21:43:58 +00:00
|
|
|
if (AVOID_DUMP)
|
|
|
|
return;
|
Fix nearly all Eclipse warnings about using raw types
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.
2017-07-09 18:38:35 +00:00
|
|
|
for (CGNode N : CG) {
|
2012-01-06 21:37:27 +00:00
|
|
|
System.err.print("callees of node " + getShortName(N) + " : [");
|
|
|
|
boolean fst = true;
|
2017-12-04 04:39:28 +00:00
|
|
|
for (CGNode n : Iterator2Iterable.make(CG.getSuccNodes(N))) {
|
2012-01-06 21:43:58 +00:00
|
|
|
if (fst)
|
2012-01-06 21:37:27 +00:00
|
|
|
fst = false;
|
|
|
|
else
|
|
|
|
System.err.print(", ");
|
2017-12-04 04:39:28 +00:00
|
|
|
System.err.print(getShortName(n));
|
2009-05-04 14:11:31 +00:00
|
|
|
}
|
2012-01-06 21:37:27 +00:00
|
|
|
System.err.println("]");
|
2012-02-17 20:17:44 +00:00
|
|
|
System.err.println("\nIR of node " + N.getGraphNodeId() + ", context " + N.getContext());
|
2017-03-11 18:22:45 +00:00
|
|
|
IRView ir = interp.getIRView(N);
|
2007-02-12 21:16:57 +00:00
|
|
|
if (ir != null) {
|
2009-04-09 20:31:14 +00:00
|
|
|
System.err.println(ir);
|
2007-02-02 17:17:13 +00:00
|
|
|
} else {
|
2009-04-09 20:31:14 +00:00
|
|
|
System.err.println("no IR!");
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-04-04 15:02:28 +00:00
|
|
|
System.err.println("pointer analysis");
|
Fix nearly all Eclipse warnings about using raw types
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.
2017-07-09 18:38:35 +00:00
|
|
|
for (PointerKey n : PA.getPointerKeys()) {
|
2007-06-28 14:30:15 +00:00
|
|
|
try {
|
2009-04-09 20:31:14 +00:00
|
|
|
System.err.println((n + " --> " + PA.getPointsToSet(n)));
|
2017-03-23 21:32:00 +00:00
|
|
|
} catch (Throwable e) {
|
2009-04-09 20:31:14 +00:00
|
|
|
System.err.println(("error computing set for " + n));
|
2007-06-28 14:30:15 +00:00
|
|
|
}
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-06-01 03:31:35 +00:00
|
|
|
public static SourceFileModule[] handleFileNames(String[] fileNameArgs) {
|
2007-07-06 22:09:29 +00:00
|
|
|
SourceFileModule[] fileNames = new SourceFileModule[fileNameArgs.length];
|
|
|
|
for (int i = 0; i < fileNameArgs.length; i++) {
|
2007-06-01 03:31:35 +00:00
|
|
|
if (new File(fileNameArgs[i]).exists()) {
|
2007-07-06 22:09:29 +00:00
|
|
|
try {
|
2012-02-17 20:21:59 +00:00
|
|
|
fileNames[i] = CAstCallGraphUtil.makeSourceModule(new File(fileNameArgs[i]).toURI().toURL(), fileNameArgs[i]);
|
2007-07-06 22:09:29 +00:00
|
|
|
} catch (MalformedURLException e) {
|
|
|
|
Assertions.UNREACHABLE(e.toString());
|
|
|
|
}
|
2007-06-01 03:31:35 +00:00
|
|
|
} else {
|
2012-02-17 20:21:59 +00:00
|
|
|
URL url = CAstCallGraphUtil.class.getClassLoader().getResource(fileNameArgs[i]);
|
|
|
|
fileNames[i] = CAstCallGraphUtil.makeSourceModule(url, fileNameArgs[i]);
|
2007-06-01 03:31:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return fileNames;
|
|
|
|
}
|
|
|
|
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|