From df25342b3de442624fad76d23b67b3b760b6e313 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Galder=20Zamarren=CC=83o?= Date: Fri, 9 Jun 2023 10:54:32 +0200 Subject: [PATCH] Add option to produce PIE native binaries #33524 --- .../quarkus/deployment/pkg/NativeConfig.java | 9 +++++++ .../pkg/steps/NativeImageBuildStep.java | 24 ++++++++++++------- .../deployment/pkg/TestNativeConfig.java | 5 ++++ 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/core/deployment/src/main/java/io/quarkus/deployment/pkg/NativeConfig.java b/core/deployment/src/main/java/io/quarkus/deployment/pkg/NativeConfig.java index 1d702c8852e294..ea4f4985d8e7d6 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/pkg/NativeConfig.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/pkg/NativeConfig.java @@ -198,6 +198,15 @@ public interface NativeConfig { */ Optional containerBuild(); + /** + * Explicit configuration option to generate a native Position Independent Executable (PIE) for Linux. + * If the system supports PIE generation, the default behaviour is to disable it for + * performance reasons. + * However, some systems can only run position-independent executables, + * so this option enables the generation of such native executables. + */ + Optional pie(); + /** * If this build is done using a remote docker daemon. */ diff --git a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildStep.java b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildStep.java index 3dddc21dbf89cc..8ea215a11194e8 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildStep.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildStep.java @@ -194,11 +194,15 @@ public NativeImageBuildItem build(NativeConfig nativeConfig, LocalesBuildTimeCon Path outputDir = nativeImageSourceJarBuildItem.getPath().getParent(); final String runnerJarName = runnerJar.getFileName().toString(); - String noPIE = ""; + String pie = ""; boolean isContainerBuild = nativeImageRunner.isContainerBuild(); if (!isContainerBuild && SystemUtils.IS_OS_LINUX) { - noPIE = detectNoPIE(); + if (nativeConfig.pie().isPresent() && nativeConfig.pie().get()) { + pie = detectPIE(); + } else { + pie = detectNoPIE(); + } } String nativeImageName = getNativeImageName(outputTargetBuildItem, packageConfig); @@ -247,7 +251,7 @@ public NativeImageBuildItem build(NativeConfig nativeConfig, LocalesBuildTimeCon .setOutputDir(outputDir) .setRunnerJarName(runnerJarName) .setNativeImageName(nativeImageName) - .setNoPIE(noPIE) + .setPIE(pie) .setGraalVMVersion(graalVMVersion) .setNativeImageFeatures(nativeImageFeatures) .setContainerBuild(isContainerBuild) @@ -527,6 +531,10 @@ private static String detectNoPIE() { return argument.length() == 0 ? testGCCArgument("-nopie") : argument; } + private static String detectPIE() { + return testGCCArgument("-pie"); + } + private static String testGCCArgument(String argument) { try { Process gcc = new ProcessBuilder("cc", "-v", "-E", argument, "-").start(); @@ -567,7 +575,7 @@ static class Builder { private List nativeImageFeatures; private Path outputDir; private String runnerJarName; - private String noPIE = ""; + private String pie = ""; private GraalVM.Version graalVMVersion = GraalVM.Version.UNVERSIONED; private String nativeImageName; private boolean classpathIsBroken; @@ -651,8 +659,8 @@ public Builder setRunnerJarName(String runnerJarName) { return this; } - public Builder setNoPIE(String noPIE) { - this.noPIE = noPIE; + public Builder setPIE(String pie) { + this.pie = pie; return this; } @@ -862,8 +870,8 @@ public NativeImageInvokerInfo build() { if (!inlineBeforeAnalysis) { nativeImageArgs.add("-H:-InlineBeforeAnalysis"); } - if (!noPIE.isEmpty()) { - nativeImageArgs.add("-H:NativeLinkerOption=" + noPIE); + if (!pie.isEmpty()) { + nativeImageArgs.add("-H:NativeLinkerOption=" + pie); } if (!nativeConfig.enableIsolates()) { diff --git a/core/deployment/src/test/java/io/quarkus/deployment/pkg/TestNativeConfig.java b/core/deployment/src/test/java/io/quarkus/deployment/pkg/TestNativeConfig.java index e7890ec83c3f6d..900acdcef123c7 100644 --- a/core/deployment/src/test/java/io/quarkus/deployment/pkg/TestNativeConfig.java +++ b/core/deployment/src/test/java/io/quarkus/deployment/pkg/TestNativeConfig.java @@ -137,6 +137,11 @@ public Optional containerBuild() { return Optional.empty(); } + @Override + public Optional pie() { + return Optional.empty(); + } + @Override public boolean remoteContainerBuild() { return false;