[PATCH] simplify pie/pic handling for android

Rafael Ávila de Espíndola rafael.espindola at gmail.com
Tue Apr 29 07:27:32 PDT 2014


Hi chandlerc, pcc,

Android is quiet peculiar in that it default to PIC, not PIE. To enable PIE only optimizations on has to explicitly pass -fPIE. I just checked that behaviour with r9d sdk using gcc 4.8 -E -dM. 

Currently that is implemented with some custom logic in the driver. The attached patch moves some of that to isPICDefault and isPIEDefault. The changes are

* Declare that android isPIEDefault and isPICDefault
* For running -cc1, give preference to isPICDefault over isPIEDefault, since that is the most restrictive. 

The main behaviour is unchanged:

* clang -target arm-linux-android -S test.c -> -mrelocation-model pic -pic-level 1 
* clang -target arm-linux-android -S test.c -fPIC -> -mrelocation-model pic -pic-level 2
* clang -target arm-linux-android -S test.c -fPIE ->  -mrelocation-model pic -pic-level 2 -pie-level 2

The one change (which is reflected in the tests) is that enabling sanitizers doesn't force PIE. It is quiet surprising that currently enabling the sanitizers moves us from PIC to PIE.

http://reviews.llvm.org/D3542

Files:
  lib/Driver/ToolChains.cpp
  lib/Driver/ToolChains.h
  lib/Driver/Tools.cpp
  test/Driver/fsanitize.c

Index: lib/Driver/ToolChains.cpp
===================================================================
--- lib/Driver/ToolChains.cpp
+++ lib/Driver/ToolChains.cpp
@@ -3379,9 +3379,15 @@
 }
 
 bool Linux::isPIEDefault() const {
+  if (getTriple().getEnvironment() == llvm::Triple::Android)
+    return true;
   return getSanitizerArgs().hasZeroBaseShadow();
 }
 
+bool Linux::isPICDefault() const {
+  return getTriple().getEnvironment() == llvm::Triple::Android;
+}
+
 /// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.
 
 DragonFly::DragonFly(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
Index: lib/Driver/ToolChains.h
===================================================================
--- lib/Driver/ToolChains.h
+++ lib/Driver/ToolChains.h
@@ -661,6 +661,7 @@
   AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
                                llvm::opt::ArgStringList &CC1Args) const override;
   bool isPIEDefault() const override;
+  bool isPICDefault() const override;
 
   std::string Linker;
   std::vector<std::string> ExtraOpts;
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -2371,8 +2371,15 @@
 
   CheckCodeGenerationOptions(D, Args);
 
-  bool PIE = getToolChain().isPIEDefault();
-  bool PIC = PIE || getToolChain().isPICDefault();
+  bool PIE = false;
+  bool PIC = false;
+  if (getToolChain().isPICDefault()) {
+    PIC = true;
+    PIE = false;
+  } else if (getToolChain().isPIEDefault()) {
+    PIC = PIE = true;
+  }
+
   bool IsPICLevelTwo = PIC;
 
   // Android-specific defaults for PIC/PIE
@@ -2386,13 +2393,7 @@
     case llvm::Triple::mipsel:
     case llvm::Triple::mips64:
     case llvm::Triple::mips64el:
-      PIC = true; // "-fpic"
-      break;
-
-    case llvm::Triple::x86:
-    case llvm::Triple::x86_64:
-      PIC = true; // "-fPIC"
-      IsPICLevelTwo = true;
+      IsPICLevelTwo = false;
       break;
 
     default:
@@ -6916,13 +6917,8 @@
   const bool isAndroid =
     ToolChain.getTriple().getEnvironment() == llvm::Triple::Android;
   const bool IsPIE =
-    !Args.hasArg(options::OPT_shared) &&
-    !Args.hasArg(options::OPT_static) &&
-    (Args.hasArg(options::OPT_pie) || ToolChain.isPIEDefault() ||
-     // On Android every code is PIC so every executable is PIE
-     // Cannot use isPIEDefault here since otherwise
-     // PIE only logic will be enabled during compilation
-     isAndroid);
+      !Args.hasArg(options::OPT_shared) && !Args.hasArg(options::OPT_static) &&
+      (Args.hasArg(options::OPT_pie) || ToolChain.isPIEDefault());
 
   ArgStringList CmdArgs;
 
Index: test/Driver/fsanitize.c
===================================================================
--- test/Driver/fsanitize.c
+++ test/Driver/fsanitize.c
@@ -113,7 +113,7 @@
 // CHECK-MSAN-NO-PIE: "-pie"
 
 // RUN: %clang -target arm-linux-androideabi -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ANDROID-ASAN-NO-PIE
-// CHECK-ANDROID-ASAN-NO-PIE: "-mrelocation-model" "pic" "-pic-level" "2" "-pie-level" "2"
+// CHECK-ANDROID-ASAN-NO-PIE: "-mrelocation-model" "pic" "-pic-level" "1"
 // CHECK-ANDROID-ASAN-NO-PIE: "-pie"
 
 // RUN: %clang -target arm-linux-androideabi %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ANDROID-NO-ASAN
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D3542.8921.patch
Type: text/x-patch
Size: 3357 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140429/495c79fd/attachment.bin>


More information about the cfe-commits mailing list