You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@teaclave.apache.org by sh...@apache.org on 2022/11/11 05:17:54 UTC
[incubator-teaclave-java-tee-sdk] 14/48: [Enc] Support static linking with musl
This is an automated email from the ASF dual-hosted git repository.
shaojunwang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-teaclave-java-tee-sdk.git
commit cee5dd4f97f84b9014cf10b0919577077d608062
Author: cengfeng.lzy <ce...@alibaba-inc.com>
AuthorDate: Thu Mar 31 10:24:28 2022 +0800
[Enc] Support static linking with musl
Summary: Native-image doesn't suport compiling musl based static
library. We loose this restriction in this commit.
But we only need native-image to complie the relocatable file (the .o file),
and the static linking is done by ourselves.
Test Plan: all tests pass
Reviewers: lei.yul, jeffery.wsj, sanhong.lsh
Issue: https://aone.alibaba-inc.com/task/41423615
CR:
https://code.aone.alibaba-inc.com/java-tee/JavaEnclave/codereview/8660164
---
sdk/enclave/pom.xml | 44 +++-------------
.../enclave/EnclaveFeature.java | 35 +++++++++++++
.../enclave/system/EnclaveMuslLibcFeature.java | 35 +++++++++++++
.../enclave/AroundNativeTest.java | 49 ------------------
.../enclave/NativeImageTest.java | 59 ++++++++++++++++++----
5 files changed, 128 insertions(+), 94 deletions(-)
diff --git a/sdk/enclave/pom.xml b/sdk/enclave/pom.xml
index 8b66556..eaf153d 100644
--- a/sdk/enclave/pom.xml
+++ b/sdk/enclave/pom.xml
@@ -74,9 +74,13 @@
<target>11</target>
<compilerArgs>
<arg>--add-modules</arg>
- <arg>jdk.internal.vm.ci</arg>
+ <arg>jdk.internal.vm.ci,jdk.internal.vm.compiler</arg>
<arg>--add-exports</arg>
<arg>jdk.internal.vm.ci/jdk.vm.ci.meta=ALL-UNNAMED</arg>
+ <arg>--add-exports</arg>
+ <arg>jdk.internal.vm.compiler/org.graalvm.compiler.serviceprovider=ALL-UNNAMED</arg>
+ <arg>--add-exports</arg>
+ <arg>jdk.internal.vm.compiler/org.graalvm.compiler.options=ALL-UNNAMED</arg>
</compilerArgs>
<!--OptionProcessor can automatically generate OptionDescriptor classes at javac time-->
<annotationProcessorPaths>
@@ -115,9 +119,11 @@
<doclint>none</doclint>
<additionalJOptions>
<additionalJOption>--add-modules</additionalJOption>
- <additionalJOption>jdk.internal.vm.ci</additionalJOption>
+ <additionalJOption>jdk.internal.vm.ci,jdk.internal.vm.compiler</additionalJOption>
<additionalJOption>--add-exports</additionalJOption>
<additionalJOption>jdk.internal.vm.ci/jdk.vm.ci.meta=ALL-UNNAMED</additionalJOption>
+ <additionalJOption>--add-exports</additionalJOption>
+ <additionalJOption>jdk.internal.vm.compiler/org.graalvm.compiler.serviceprovider=ALL-UNNAMED</additionalJOption>
</additionalJOptions>
</configuration>
<version>3.2.0</version>
@@ -155,44 +161,10 @@
</execution>
</executions>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>exec-maven-plugin</artifactId>
- <version>3.0.0</version>
- <executions>
- <execution>
- <id>preTest</id>
- <phase>test-compile</phase>
- <goals>
- <goal>java</goal>
- </goals>
- <configuration>
- <mainClass>com.alibaba.confidentialcomputing.enclave.AroundNativeTest$PreTest</mainClass>
- <classpathScope>test</classpathScope>
- </configuration>
- </execution>
- <execution>
- <id>postTest</id>
- <phase>test</phase>
- <goals>
- <goal>java</goal>
- </goals>
- <configuration>
- <mainClass>com.alibaba.confidentialcomputing.enclave.AroundNativeTest$PostTest</mainClass>
- <classpathScope>test</classpathScope>
- </configuration>
- </execution>
- </executions>
- </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
- <configuration>
- <environmentVariables>
- <LD_LIBRARY_PATH>/tmp/javaenclavetest-native-libs</LD_LIBRARY_PATH>
- </environmentVariables>
- </configuration>
</plugin>
</plugins>
</build>
diff --git a/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/EnclaveFeature.java b/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/EnclaveFeature.java
index 2c6a346..8875700 100644
--- a/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/EnclaveFeature.java
+++ b/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/EnclaveFeature.java
@@ -7,10 +7,12 @@ import com.alibaba.confidentialcomputing.enclave.framework.LoadServiceInvoker;
import com.alibaba.confidentialcomputing.enclave.framework.ServiceMethodInvoker;
import com.alibaba.confidentialcomputing.enclave.framework.UnloadServiceInvoker;
import com.oracle.svm.core.annotate.AutomaticFeature;
+import com.oracle.svm.core.c.libc.TemporaryBuildDirectoryProvider;
import com.oracle.svm.core.jdk.resources.NativeImageResourceFileSystemUtil;
import com.oracle.svm.core.util.VMError;
import com.oracle.svm.hosted.FeatureImpl;
import com.oracle.svm.hosted.ImageClassLoader;
+import com.oracle.svm.hosted.NativeImageGenerator;
import com.oracle.svm.hosted.ServiceLoaderFeature;
import com.oracle.svm.reflect.hosted.ReflectionFeature;
import com.oracle.svm.reflect.serialize.hosted.SerializationFeature;
@@ -27,6 +29,12 @@ import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.nio.charset.StandardCharsets;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.attribute.BasicFileAttributes;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
@@ -96,6 +104,33 @@ public class EnclaveFeature implements Feature {
}
}
+ /**
+ * Copy the relocatable file and header file from temporary directory to output path.
+ */
+ @Override
+ public void afterImageWrite(AfterImageWriteAccess access) {
+ FeatureImpl.AfterImageWriteAccessImpl a = (FeatureImpl.AfterImageWriteAccessImpl) access;
+ Path outputDirectory = NativeImageGenerator.generatedFiles(a.getUniverse().getBigBang().getOptions());
+ Path tempDirectory = ImageSingletons.lookup(TemporaryBuildDirectoryProvider.class).getTemporaryBuildDirectory();
+ try {
+ if (Files.notExists(outputDirectory)) {
+ Files.createDirectory(outputDirectory);
+ }
+ Files.walkFileTree(tempDirectory, new SimpleFileVisitor<>() {
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+ String fileName = file.getFileName().toString();
+ if (fileName.endsWith(".o") || fileName.endsWith(".h")) {
+ Path target = outputDirectory.resolve(fileName).toAbsolutePath();
+ Files.copy(file, target, StandardCopyOption.REPLACE_EXISTING);
+ }
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ } catch (IOException e) {
+ VMError.shouldNotReachHere("Fail to copy file from temporary", e);
+ }
+ }
private void collectConfigs(Class<?> clazz, List<Method> methods) {
reflectionCandidateTypes.putIfAbsent(clazz, false);
diff --git a/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/system/EnclaveMuslLibcFeature.java b/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/system/EnclaveMuslLibcFeature.java
new file mode 100644
index 0000000..313ce5f
--- /dev/null
+++ b/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/system/EnclaveMuslLibcFeature.java
@@ -0,0 +1,35 @@
+package com.alibaba.confidentialcomputing.enclave.system;
+
+import com.oracle.svm.core.annotate.AutomaticFeature;
+import com.oracle.svm.core.c.libc.LibCBase;
+import com.oracle.svm.core.posix.linux.libc.LibCFeature;
+import com.oracle.svm.core.posix.linux.libc.MuslLibC;
+import com.oracle.svm.core.util.UserError;
+import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
+import org.graalvm.nativeimage.ImageSingletons;
+
+import java.util.ServiceLoader;
+
+@AutomaticFeature
+public class EnclaveMuslLibcFeature extends LibCFeature {
+
+ @Override
+ public void afterRegistration(AfterRegistrationAccess access) {
+ String targetLibC = LibCOptions.UseLibC.getValue();
+ ServiceLoader<LibCBase> loader = ServiceLoader.load(LibCBase.class);
+ for (LibCBase libc : loader) {
+ if (libc.getName().equals(targetLibC)) {
+ if (libc.getName().equals(MuslLibC.NAME)) {
+ if (JavaVersionUtil.JAVA_SPEC < 11) {
+ throw UserError.abort("Musl can only be used with labsjdk 11+.");
+ }
+ } else {
+ libc.checkIfLibCSupported();
+ }
+ ImageSingletons.add(LibCBase.class, libc);
+ return;
+ }
+ }
+ throw UserError.abort("Unknown libc %s selected. Please use one of the available libc implementations.", targetLibC);
+ }
+}
diff --git a/sdk/enclave/src/test/java/com/alibaba/confidentialcomputing/enclave/AroundNativeTest.java b/sdk/enclave/src/test/java/com/alibaba/confidentialcomputing/enclave/AroundNativeTest.java
deleted file mode 100644
index ec28e4e..0000000
--- a/sdk/enclave/src/test/java/com/alibaba/confidentialcomputing/enclave/AroundNativeTest.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package com.alibaba.confidentialcomputing.enclave;
-
-import java.io.IOException;
-import java.nio.file.FileVisitResult;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.SimpleFileVisitor;
-import java.nio.file.attribute.BasicFileAttributes;
-
-/**
- * This class holds 2 main classes that are executed before and after maven surefire test by <a href="https://www.mojohaus.org/exec-maven-plugin/">exec-maven-plugin</a>.
- */
-public class AroundNativeTest {
- public static final Path tmpTestNativeLibsDir = Paths.get("/tmp/javaenclavetest-native-libs");
-
- /**
- * Before test starts, create the temporary directory to hold the dynamic native libraries that will be created
- * during test. But the directory must be created beforehand, so that the {@code export LD_LIBRARY_PATH} action
- * taken by surefire plugin can take effect.
- */
- public static class PreTest {
- public static void main(String[] args) throws IOException {
- if (Files.notExists(tmpTestNativeLibsDir)) {
- Files.createDirectories(tmpTestNativeLibsDir);
- }
- }
- }
-
- public static class PostTest {
- public static void main(String[] args) throws IOException {
- if (Files.exists(tmpTestNativeLibsDir)) {
- Files.walkFileTree(tmpTestNativeLibsDir, new SimpleFileVisitor<>() {
- @Override
- public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
- Files.delete(file);
- return super.visitFile(file, attrs);
- }
-
- @Override
- public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
- Files.delete(dir);
- return super.postVisitDirectory(dir, exc);
- }
- });
- }
- }
- }
-}
diff --git a/sdk/enclave/src/test/java/com/alibaba/confidentialcomputing/enclave/NativeImageTest.java b/sdk/enclave/src/test/java/com/alibaba/confidentialcomputing/enclave/NativeImageTest.java
index ed676da..a9519f6 100644
--- a/sdk/enclave/src/test/java/com/alibaba/confidentialcomputing/enclave/NativeImageTest.java
+++ b/sdk/enclave/src/test/java/com/alibaba/confidentialcomputing/enclave/NativeImageTest.java
@@ -21,6 +21,9 @@ public abstract class NativeImageTest implements NativeImageTestable {
private static final String SVM_OUT = "svm-out";
private static final String SVM_ENCLAVE_LIB = "svm_enclave_sdk";
+ private static final boolean useStaticLink = true;
+ public static final String ENC_INVOKE_ENTRY_TEST_C = "enc_invoke_entry_test.c";
+
static {
if (!GRAALVM_HOME.toFile().exists()) {
throw new RuntimeException("System environment variable GRAALVM_HOME is set to " + GRAALVM_HOME
@@ -99,11 +102,7 @@ public abstract class NativeImageTest implements NativeImageTestable {
svmCompile();
afterSVMCompile();
compileJNILibrary();
- Path so1 = workingDir.resolve("lib" + JNI_LIB_NAME + ".so");
- Path so2 = workingDir.resolve("lib" + SVM_ENCLAVE_LIB + ".so");
- copyFile(so1, AroundNativeTest.tmpTestNativeLibsDir.resolve(so1.getFileName()), null);
- copyFile(so2, AroundNativeTest.tmpTestNativeLibsDir.resolve(so2.getFileName()), null);
- System.loadLibrary(JNI_LIB_NAME);
+ System.load(workingDir.resolve("lib" + JNI_LIB_NAME + ".so").toAbsolutePath().toString());
}
private void collectSVMCompileItems() {
@@ -163,8 +162,11 @@ public abstract class NativeImageTest implements NativeImageTestable {
});
command.add(sb.deleteCharAt(sb.length() - 1).toString());
command.add("--shared");
+ if (useStaticLink) {
+ command.add("--libc=musl");
+ }
command.add("--no-fallback");
- command.add("-H:OutputRelocatableImage=.");
+ // command.add("-H:OutputRelocatableImage=.");
command.add("-H:Path=" + SVM_OUT);
command.add("-H:+AllowIncompleteClasspath");
command.add("-H:+ReportExceptionStackTraces");
@@ -185,15 +187,55 @@ public abstract class NativeImageTest implements NativeImageTestable {
requiredFilePaths.add(svmOutputDir.resolve("lib" + SVM_ENCLAVE_LIB + ".h"));
requiredFilePaths.add(svmOutputDir.resolve("graal_isolate.h"));
requiredFilePaths.add(svmOutputDir.resolve("enc_environment.h"));
- requiredFilePaths.add(svmOutputDir.resolve("lib" + SVM_ENCLAVE_LIB + ".so"));
+ if (useStaticLink) {
+ requiredFilePaths.add(svmOutputDir.resolve("lib" + SVM_ENCLAVE_LIB + ".o"));
+ } else {
+ requiredFilePaths.add(svmOutputDir.resolve("lib" + SVM_ENCLAVE_LIB + ".so"));
+ }
requiredFilePaths.forEach(p -> copyFile(p, workingDir.resolve(p.getFileName()), null));
List<String> command = new ArrayList<>();
+ if (useStaticLink) {
+ prepareStaticLinkingCommand(command);
+ } else {
+ prepareDynamicLinkingCommand(command);
+ }
+ executeNewProcess(command, workingDir);
+ }
+
+ private void prepareStaticLinkingCommand(List<String> command) {
+ Path graalvmHome = GRAALVM_HOME.toAbsolutePath();
+ command.add("gcc");
+ command.add("-z");
+ command.add("noexecstack");
+ command.add("-fPIC");
+ command.add("-I" + graalvmHome.resolve("include").toString());
+ command.add("-I" + graalvmHome.resolve("include/linux").toString());
+ command.add(ENC_INVOKE_ENTRY_TEST_C);
+ command.add("lib" + SVM_ENCLAVE_LIB + ".o");
+ command.add("-I.");
+ command.add("-L.");
+ command.add(graalvmHome.resolve("lib/svm/clibraries/linux-amd64/liblibchelper.a").toString());
+ command.add(graalvmHome.resolve("lib/svm/clibraries/linux-amd64/libjvm.a").toString());
+ command.add(graalvmHome.resolve("lib/static/linux-amd64/musl/libnio.a").toString());
+ command.add(graalvmHome.resolve("lib/static/linux-amd64/musl/libzip.a").toString());
+ command.add(graalvmHome.resolve("lib/static/linux-amd64/musl/libnet.a").toString());
+ command.add(graalvmHome.resolve("lib/static/linux-amd64/musl/libjava.a").toString());
+ command.add(graalvmHome.resolve("lib/static/linux-amd64/musl/libsunec.a").toString());
+ command.add(graalvmHome.resolve("lib/static/linux-amd64/musl/libfdlibm.a").toString());
+ command.add("-std=c99");
+ command.add("-lc");
+ command.add("-shared");
+ command.add("-o");
+ command.add("lib" + JNI_LIB_NAME + ".so");
+ }
+
+ private void prepareDynamicLinkingCommand(List<String> command) {
command.add("gcc");
command.add("-fPIC");
command.add("-I" + GRAALVM_HOME.toAbsolutePath() + "/include");
command.add("-I" + GRAALVM_HOME.toAbsolutePath() + "/include/linux");
- command.add("enc_invoke_entry_test.c");
+ command.add(ENC_INVOKE_ENTRY_TEST_C);
command.add("-I.");
command.add("-L.");
command.add("-std=c99");
@@ -202,7 +244,6 @@ public abstract class NativeImageTest implements NativeImageTestable {
command.add("-shared");
command.add("-o");
command.add("lib" + JNI_LIB_NAME + ".so");
- executeNewProcess(command, workingDir);
}
public static int executeNewProcess(List<String> command, Path workDir) {
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@teaclave.apache.org
For additional commands, e-mail: commits-help@teaclave.apache.org