diff --git a/phosphor-instrument-jigsaw/pom.xml b/phosphor-instrument-jigsaw/pom.xml
index ee59f2268..3169721cc 100644
--- a/phosphor-instrument-jigsaw/pom.xml
+++ b/phosphor-instrument-jigsaw/pom.xml
@@ -40,35 +40,6 @@
-
- org.apache.maven.plugins
- maven-javadoc-plugin
- 3.1.1
-
- true
-
-
-
- attach-javadoc
-
- jar
-
-
-
-
-
- org.apache.maven.plugins
- maven-plugin-plugin
- 3.6.0
-
-
- mojo-descriptor
-
- descriptor
-
-
-
-
org.apache.maven.plugins
maven-shade-plugin
@@ -119,34 +90,6 @@
-
-
- release-sign-artifacts
-
-
- gpg.passphrase
-
-
-
-
-
- org.apache.maven.plugins
- maven-gpg-plugin
- 1.4
-
-
- sign-artifacts
- verify
-
- sign
-
-
-
-
-
-
-
-
edu.gmu.swe.phosphor
diff --git a/phosphor-instrument-jigsaw/src/main/java/edu/columbia/cs/psl/jigsaw/phosphor/instrumenter/JLinkInvoker.java b/phosphor-instrument-jigsaw/src/main/java/edu/columbia/cs/psl/jigsaw/phosphor/instrumenter/JLinkInvoker.java
index 6111cd943..b26793847 100644
--- a/phosphor-instrument-jigsaw/src/main/java/edu/columbia/cs/psl/jigsaw/phosphor/instrumenter/JLinkInvoker.java
+++ b/phosphor-instrument-jigsaw/src/main/java/edu/columbia/cs/psl/jigsaw/phosphor/instrumenter/JLinkInvoker.java
@@ -1,48 +1,41 @@
package edu.columbia.cs.psl.jigsaw.phosphor.instrumenter;
import edu.columbia.cs.psl.phosphor.Configuration;
+import edu.columbia.cs.psl.phosphor.PhosphorOption;
+import edu.columbia.cs.psl.phosphor.org.apache.commons.cli.Option;
+import edu.columbia.cs.psl.phosphor.org.apache.commons.cli.Options;
+
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
+import java.util.stream.Collectors;
public class JLinkInvoker {
-
public static final String MODULES_PROPERTY = "jvmModules";
+ public static final String PACK_KEY = "phosphor.pack";
public static void invokeJLink(File jvmDir, File instJVMDir, Properties properties) {
-
String jlinkBin = jvmDir + File.separator + "bin" + File.separator + "jlink";
- File jlinkFile = getPhosphorJLinkJarFile();
+ File jlinkFile = getClassPathElement(JLinkInvoker.class);
String modulesToAdd = properties.getProperty(MODULES_PROPERTY,
"java.base,jdk.jdwp.agent,java.instrument,jdk.unsupported");
-
- Set classPaths = new HashSet<>();
- if (Configuration.PRIOR_CLASS_VISITOR != null) {
- classPaths.add(Configuration.PRIOR_CLASS_VISITOR.getProtectionDomain().getCodeSource().getLocation().getPath());
- }
- if (Configuration.POST_CLASS_VISITOR != null) {
- classPaths.add(Configuration.POST_CLASS_VISITOR.getProtectionDomain().getCodeSource().getLocation().getPath());
- }
- if (Configuration.taintTagFactoryPackage != null) {
- classPaths.add(Configuration.taintTagFactory.getClass().getProtectionDomain().getCodeSource().getLocation().getPath());
- }
-
- ProcessBuilder pb = new ProcessBuilder(jlinkBin, "-J-javaagent:" + jlinkFile,
+ String classPath = buildClassPath(properties);
+ ProcessBuilder pb = new ProcessBuilder(
+ jlinkBin,
+ String.format("-J-D%s=%s", PACK_KEY, classPath),
+ "-J-javaagent:" + jlinkFile,
"-J--module-path=" + jlinkFile,
"-J--add-modules=edu.columbia.cs.psl.jigsaw.phosphor.instrumenter",
- "-J--class-path=" + String.join(":", classPaths),
+ "-J--class-path=" + classPath,
"--output=" + instJVMDir,
"--phosphor-transformer=transform" + createPhosphorJLinkPluginArgument(properties),
"--add-modules=" + modulesToAdd
);
try {
- for(String s : pb.command()){
- System.out.print(s + " ");
- }
- System.out.println();
+ System.out.println(String.join(" ", pb.command()));
Process p = pb.inheritIO().start();
p.waitFor();
} catch (IOException | InterruptedException e) {
@@ -50,15 +43,36 @@ public static void invokeJLink(File jvmDir, File instJVMDir, Properties properti
}
}
- /**
- * @return a File object pointing to the JAR file for Phosphor-jlink bridge
- */
- public static File getPhosphorJLinkJarFile() {
- try {
- return new File(JLinkInvoker.class.getProtectionDomain().getCodeSource().getLocation().toURI());
- } catch (URISyntaxException e) {
- throw new AssertionError();
+ private static String buildClassPath(Properties properties) {
+ Set> classes = new HashSet<>();
+ Options options = PhosphorOption.createOptions(false);
+ for (Option option : options.getOptions()) {
+ if (option.getType().equals(Class.class)) {
+ String key = option.getOpt();
+ if (properties.containsKey(key)) {
+ try {
+ Class> clazz = Class.forName(properties.getProperty(key));
+ classes.add(clazz);
+ } catch (ReflectiveOperationException e) {
+ String message = String.format("Failed to create %s class: %s", key, properties.getProperty(key));
+ throw new IllegalArgumentException(message, e);
+ }
+ }
+ }
+ }
+ if (Configuration.PRIOR_CLASS_VISITOR != null) {
+ classes.add(Configuration.PRIOR_CLASS_VISITOR);
+ }
+ if (Configuration.POST_CLASS_VISITOR != null) {
+ classes.add(Configuration.POST_CLASS_VISITOR);
}
+ if (Configuration.taintTagFactoryPackage != null) {
+ classes.add(Configuration.taintTagFactory.getClass());
+ }
+ return classes.stream()
+ .map(JLinkInvoker::getClassPathElement)
+ .map(File::getAbsolutePath)
+ .collect(Collectors.joining(File.pathSeparator));
}
/**
@@ -74,7 +88,7 @@ public static String createPhosphorJLinkPluginArgument(Properties properties) {
StringBuilder builder = new StringBuilder();
Set propNames = properties.stringPropertyNames();
for (String propName : propNames) {
- if(propName.equals(MODULES_PROPERTY)) {
+ if (propName.equals(MODULES_PROPERTY)) {
continue;
}
builder.append(':');
@@ -84,4 +98,12 @@ public static String createPhosphorJLinkPluginArgument(Properties properties) {
return builder.toString();
}
}
+
+ public static File getClassPathElement(Class> clazz) {
+ try {
+ return new File(clazz.getProtectionDomain().getCodeSource().getLocation().toURI());
+ } catch (URISyntaxException e) {
+ throw new AssertionError();
+ }
+ }
}
diff --git a/phosphor-instrument-jigsaw/src/main/java/edu/columbia/cs/psl/jigsaw/phosphor/instrumenter/PhosphorJLinkPlugin.java b/phosphor-instrument-jigsaw/src/main/java/edu/columbia/cs/psl/jigsaw/phosphor/instrumenter/PhosphorJLinkPlugin.java
index 304885b65..cd0f75be6 100644
--- a/phosphor-instrument-jigsaw/src/main/java/edu/columbia/cs/psl/jigsaw/phosphor/instrumenter/PhosphorJLinkPlugin.java
+++ b/phosphor-instrument-jigsaw/src/main/java/edu/columbia/cs/psl/jigsaw/phosphor/instrumenter/PhosphorJLinkPlugin.java
@@ -8,13 +8,12 @@
import jdk.tools.jlink.plugin.ResourcePoolEntry;
import java.io.File;
-import java.net.URISyntaxException;
import java.util.*;
public class PhosphorJLinkPlugin implements Plugin {
public static final String NAME = "phosphor-transformer";
- private static File phosphorJar;
+ private Set elementsToPack;
@Override
public boolean hasArguments() {
@@ -31,15 +30,15 @@ public Category getType() {
* created arguments
* @return an array formatted for {@link Instrumenter#main(String[])} Instrumenter.main's} String[] argument
*/
- public static String[] createPhosphorMainArguments(Map properties) {
+ public static String[] createPhosphorMainArguments(Map properties) {
LinkedList arguments = new LinkedList<>();
Set propNames = properties.keySet();
- for(String propName : propNames) {
- if(propName.equals("phosphor-transformer")){
+ for (String propName : propNames) {
+ if (propName.equals("phosphor-transformer")) {
continue;
}
arguments.addLast("-" + propName);
- if(!"true".equals(properties.get(propName))) {
+ if (!"true".equals(properties.get(propName))) {
arguments.addLast(properties.get(propName));
}
}
@@ -54,8 +53,16 @@ public void configure(Map config) {
TaintTrackingClassVisitor.IS_RUNTIME_INST = false;
TaintUtils.VERIFY_CLASS_GENERATION = true;
PhosphorOption.configure(false, createPhosphorMainArguments(config));
- phosphorJar = getPhosphorJarFile();
+ File phosphorJar = JLinkInvoker.getClassPathElement(Instrumenter.class);
System.out.println("Embedding Phosphor from: " + phosphorJar);
+ String pack = System.getProperty(JLinkInvoker.PACK_KEY);
+ this.elementsToPack = new HashSet<>();
+ elementsToPack.add(phosphorJar);
+ if (pack != null && !pack.isEmpty()) {
+ Arrays.stream(pack.split(File.pathSeparator))
+ .map(File::new)
+ .forEach(elementsToPack::add);
+ }
//TODO process args
}
@@ -63,7 +70,7 @@ public void configure(Map config) {
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
TaintUtils.VERIFY_CLASS_GENERATION = true;
PreMain.RUNTIME_INST = false;
- PhosphorPacker packer = new PhosphorPacker(in, phosphorJar);
+ PhosphorPacker packer = new PhosphorPacker(in, elementsToPack);
in.transformAndCopy((resourcePoolEntry) -> {
if (resourcePoolEntry.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
if (resourcePoolEntry.path().endsWith(".class")) {
@@ -74,7 +81,8 @@ public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
resourcePoolEntry = packer.pack(resourcePoolEntry, out);
}
} else {
- byte[] newContent = Instrumenter.instrumentClass(resourcePoolEntry.path(), resourcePoolEntry.content(), true);
+ byte[] newContent = Instrumenter.instrumentClass(resourcePoolEntry.path(),
+ resourcePoolEntry.content(), true);
if (newContent != null) {
resourcePoolEntry = resourcePoolEntry.copyWithContent(newContent);
}
@@ -95,17 +103,6 @@ public String getName() {
public String getDescription() {
return "Transforms the runtime image to be compatible with Phosphor";
}
-
- /**
- * @return a File object pointing to the JAR file for Phosphor
- */
- public static File getPhosphorJarFile() {
- try {
- return new File(Instrumenter.class.getProtectionDomain().getCodeSource().getLocation().toURI());
- } catch(URISyntaxException e) {
- throw new AssertionError();
- }
- }
}
diff --git a/phosphor-instrument-jigsaw/src/main/java/edu/columbia/cs/psl/jigsaw/phosphor/instrumenter/PhosphorPacker.java b/phosphor-instrument-jigsaw/src/main/java/edu/columbia/cs/psl/jigsaw/phosphor/instrumenter/PhosphorPacker.java
index 1ebf98b29..45b7df43c 100644
--- a/phosphor-instrument-jigsaw/src/main/java/edu/columbia/cs/psl/jigsaw/phosphor/instrumenter/PhosphorPacker.java
+++ b/phosphor-instrument-jigsaw/src/main/java/edu/columbia/cs/psl/jigsaw/phosphor/instrumenter/PhosphorPacker.java
@@ -8,21 +8,22 @@
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
+import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
class PhosphorPacker {
- private final File phosphorJar;
private final PhosphorPatcher patcher;
+ private final Set elementsToPack;
- PhosphorPacker(ResourcePool pool, File phosphorJar) {
- if (phosphorJar == null) {
- throw new NullPointerException();
- }
- this.phosphorJar = phosphorJar;
+ PhosphorPacker(ResourcePool pool, Set elementsToPack) {
+ this.elementsToPack = Collections.unmodifiableSet(new HashSet<>(elementsToPack));
ResourcePoolEntry entry = pool.findEntry("/java.base/jdk/internal/misc/Unsafe.class")
.orElseThrow(() -> new IllegalArgumentException("Unable to find entry for jdk/internal/misc/Unsafe"));
try (InputStream in = entry.content()) {
@@ -53,10 +54,42 @@ ResourcePoolEntry pack(ResourcePoolEntry entry, ResourcePoolBuilder out) {
}
private Set packClasses(ResourcePoolBuilder out) throws IOException {
- // Pack the Phosphor JAR into the resource pool
+ // Pack the JARs and directories into the resource pool
// Return the set of packages for packed classes
Set packages = new HashSet<>();
- try (ZipFile zip = new ZipFile(phosphorJar)) {
+ for (File element : elementsToPack) {
+ if (element.isDirectory()) {
+ packDirectory(out, element, packages);
+ } else {
+ packJar(out, element, packages);
+ }
+ }
+ return packages;
+ }
+
+ private void packClass(ResourcePoolBuilder out, String name, File classFile, Set packages) {
+ try {
+ if (shouldInclude(name)) {
+ byte[] content = patcher.patch(name, Files.readAllBytes(classFile.toPath()));
+ out.add(ResourcePoolEntry.create("/java.base/" + name, content));
+ packages.add(name.substring(0, name.lastIndexOf('/')));
+ }
+ } catch (IOException e) {
+ throw new IllegalArgumentException("Failed to pack: " + name, e);
+ }
+ }
+
+ private void packDirectory(ResourcePoolBuilder out, File directory, Set packages) throws IOException {
+ try (Stream walk = Files.walk(directory.toPath())) {
+ walk.filter(Files::isRegularFile)
+ .forEach(p -> packClass(out, directory.toPath().relativize(p).toFile().getPath(),
+ p.toAbsolutePath().toFile(),
+ packages));
+ }
+ }
+
+ private void packJar(ResourcePoolBuilder out, File element, Set packages) throws IOException {
+ try (ZipFile zip = new ZipFile(element)) {
Enumeration extends ZipEntry> entries = zip.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
@@ -69,6 +102,5 @@ private Set packClasses(ResourcePoolBuilder out) throws IOException {
}
}
}
- return packages;
}
}
diff --git a/phosphor-instrument-jigsaw/src/main/java/module-info.java b/phosphor-instrument-jigsaw/src/main/java/module-info.java
index 36e590539..5361cd48f 100644
--- a/phosphor-instrument-jigsaw/src/main/java/module-info.java
+++ b/phosphor-instrument-jigsaw/src/main/java/module-info.java
@@ -1,8 +1,23 @@
module edu.columbia.cs.psl.jigsaw.phosphor.instrumenter {
exports edu.columbia.cs.psl.jigsaw.phosphor.instrumenter;
- opens edu.columbia.cs.psl.phosphor.instrumenter;
+ opens edu.columbia.cs.psl.jigsaw.phosphor.instrumenter;
+ opens edu.columbia.cs.psl.phosphor.instrumenter.analyzer;
opens edu.columbia.cs.psl.phosphor.struct.harmony.util;
+ opens edu.columbia.cs.psl.phosphor.control.graph;
+ opens edu.columbia.cs.psl.phosphor.instrumenter;
+ opens edu.columbia.cs.psl.phosphor.runtime.jdk.unsupported;
+ opens edu.columbia.cs.psl.phosphor.control.type;
+ opens edu.columbia.cs.psl.phosphor.org.objectweb.asm.tree;
+ opens edu.columbia.cs.psl.phosphor.org.objectweb.asm.commons;
+ opens edu.columbia.cs.psl.phosphor.struct;
+ opens edu.columbia.cs.psl.phosphor.control.standard;
+ opens edu.columbia.cs.psl.phosphor.instrumenter.asm;
+ opens edu.columbia.cs.psl.phosphor.control;
+ opens edu.columbia.cs.psl.phosphor.org.objectweb.asm.analysis;
+ opens edu.columbia.cs.psl.phosphor;
opens edu.columbia.cs.psl.phosphor.org.objectweb.asm;
+ opens edu.columbia.cs.psl.phosphor.runtime;
+ opens edu.columbia.cs.psl.phosphor.runtime.proxied;
requires jdk.jlink;
requires java.instrument;
}