[Driver] Add CLANG_DEFAULT_PIE_ON_LINUX to emulate GCC --enable-default-pie
authorFangrui Song <i@maskray.me>
Tue, 14 Dec 2021 18:08:59 +0000 (10:08 -0800)
committerFangrui Song <i@maskray.me>
Tue, 14 Dec 2021 18:09:00 +0000 (10:09 -0800)
In 2015-05, GCC added the configure option `--enable-default-pie`. When enabled,

* in the absence of -fno-pic/-fpie/-fpic (and their upper-case variants), -fPIE is the default.
* in the absence of -no-pie/-pie/-shared/-static/-static-pie, -pie is the default.

This has been adopted by all(?) major distros.

I think default PIE is the majority in the Linux world, but
--disable-default-pie users is not that uncommon because GCC upstream hasn't
switched the default yet (https://gcc.gnu.org/PR103398).

This patch add CLANG_DEFAULT_PIE_ON_LINUX which allows distros to use default PIE.
The option is justified as its adoption can be very high among Linux distros
to make Clang default match GCC, and is likely a future-new-default, at which
point we will remove CLANG_DEFAULT_PIE_ON_LINUX.
The lit feature `default-pie-on-linux` can be handy to exclude default PIE sensitive tests.

Reviewed By: foutrelis, sylvestre.ledru, thesamesam

Differential Revision: https://reviews.llvm.org/D113372

clang/CMakeLists.txt
clang/docs/ReleaseNotes.rst
clang/include/clang/Config/config.h.cmake
clang/lib/Driver/ToolChains/Linux.cpp
clang/test/Driver/fsanitize.c
clang/test/Driver/linux-default-pie.c [new file with mode: 0644]
clang/test/Driver/linux-ld.c
clang/test/lit.cfg.py
clang/test/lit.site.cfg.py.in
llvm/utils/gn/secondary/clang/include/clang/Config/BUILD.gn
utils/bazel/llvm-project-overlay/clang/include/clang/Config/config.h

index 6f26e94..00243d8 100644 (file)
@@ -227,6 +227,11 @@ set(ENABLE_X86_RELAX_RELOCATIONS ON CACHE BOOL
 set(CLANG_SPAWN_CC1 OFF CACHE BOOL
     "Whether clang should use a new process for the CC1 invocation")
 
+option(CLANG_DEFAULT_PIE_ON_LINUX "Default to -fPIE and -pie on Linux" OFF)
+if(CLANG_DEFAULT_PIE_ON_LINUX)
+  set(CLANG_DEFAULT_PIE_ON_LINUX 1)
+endif()
+
 # TODO: verify the values against LangStandards.def?
 set(CLANG_DEFAULT_STD_C "" CACHE STRING
   "Default standard to use for C/ObjC code (IDENT from LangStandards.def, empty for platform default)")
index 6b0ce5b..07953a8 100644 (file)
@@ -249,7 +249,10 @@ Internal API Changes
 Build System Changes
 --------------------
 
-- ...
+- Linux distros can specify ``-DCLANG_DEFAULT_PIE_ON_LINUX=On`` to use ``-fPIE`` and
+  ``-pie`` by default. This matches GCC installations on many Linux distros
+  (configured with ``--enable-default-pie``).
+  (`D113372 <https://reviews.llvm.org/D113372>`_)
 
 AST Matchers
 ------------
index a240862..53386ef 100644 (file)
@@ -8,6 +8,9 @@
 /* Bug report URL. */
 #define BUG_REPORT_URL "${BUG_REPORT_URL}"
 
+/* Default to -fPIE and -pie on Linux. */
+#cmakedefine01 CLANG_DEFAULT_PIE_ON_LINUX
+
 /* Default linker to use. */
 #define CLANG_DEFAULT_LINKER "${CLANG_DEFAULT_LINKER}"
 
index 7494c21..e413640 100644 (file)
@@ -663,8 +663,8 @@ void Linux::AddIAMCUIncludeArgs(const ArgList &DriverArgs,
 }
 
 bool Linux::isPIEDefault(const llvm::opt::ArgList &Args) const {
-  return getTriple().isAndroid() || getTriple().isMusl() ||
-         getSanitizerArgs(Args).requiresPIE();
+  return CLANG_DEFAULT_PIE_ON_LINUX || getTriple().isAndroid() ||
+         getTriple().isMusl() || getSanitizerArgs(Args).requiresPIE();
 }
 
 bool Linux::IsAArch64OutlineAtomicsDefault(const ArgList &Args) const {
index a6b5776..7bcda5c 100644 (file)
@@ -1,3 +1,4 @@
+// UNSUPPORTED: default-pie-on-linux
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-TRAP
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -fno-sanitize-trap=signed-integer-overflow %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-TRAP2
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined -fsanitize-undefined-trap-on-error %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-TRAP
diff --git a/clang/test/Driver/linux-default-pie.c b/clang/test/Driver/linux-default-pie.c
new file mode 100644 (file)
index 0000000..6772a6c
--- /dev/null
@@ -0,0 +1,7 @@
+// REQUIRES: default-pie-on-linux
+/// Test -DCLANG_DEFAULT_PIE_ON_LINUX=on.
+
+// RUN: %clang -### --target=aarch64-linux-gnu %s 2>&1 | FileCheck %s --check-prefix=PIE2
+
+// PIE2: "-mrelocation-model" "pic" "-pic-level" "2" "-pic-is-pie"
+// PIE2: "-pie"
index 31905e1..b70b712 100644 (file)
@@ -1,4 +1,4 @@
-// UNSUPPORTED: system-windows
+// UNSUPPORTED: system-windows, default-pie-on-linux
 // General tests that ld invocations on Linux targets sane. Note that we use
 // sysroot to make these tests independent of the host system.
 //
index 5a9a1ab..514ddf9 100644 (file)
@@ -121,6 +121,9 @@ config.substitutions.append(('%host_cxx', config.host_cxx))
 if config.has_plugins and config.llvm_plugin_ext:
     config.available_features.add('plugins')
 
+if config.clang_default_pie_on_linux == '1':
+    config.available_features.add('default-pie-on-linux')
+
 # Set available features we allow tests to conditionalize on.
 #
 if config.clang_default_cxx_stdlib != '':
index a99550c..807c1d3 100644 (file)
@@ -22,6 +22,7 @@ config.host_cxx = "@CMAKE_CXX_COMPILER@"
 config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@"
 config.have_zlib = @LLVM_ENABLE_ZLIB@
 config.clang_arcmt = @CLANG_ENABLE_ARCMT@
+config.clang_default_pie_on_linux = "@CLANG_DEFAULT_PIE_ON_LINUX@"
 config.clang_default_cxx_stdlib = "@CLANG_DEFAULT_CXX_STDLIB@"
 config.clang_staticanalyzer = @CLANG_ENABLE_STATIC_ANALYZER@
 config.clang_staticanalyzer_z3 = "@LLVM_WITH_Z3@"
index aa3e40a..f635c0a 100644 (file)
@@ -9,6 +9,7 @@ write_cmake_config("Config") {
   output = "$target_gen_dir/config.h"
   values = [
     "BUG_REPORT_URL=https://bugs.llvm.org/",
+    "CLANG_DEFAULT_PIE_ON_LINUX=0",
     "CLANG_DEFAULT_LINKER=",
     "CLANG_DEFAULT_STD_C=",
     "CLANG_DEFAULT_STD_CXX=",
index 4d5cd05..ee4c627 100644 (file)
@@ -22,6 +22,9 @@
 /* Bug report URL. */
 #define BUG_REPORT_URL "https://bugs.llvm.org/"
 
+/* Default to -fPIE and -pie on Linux. */
+#define CLANG_DEFAULT_PIE_ON_LINUX 0
+
 /* Default linker to use. */
 #define CLANG_DEFAULT_LINKER ""