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
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
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to