]> granicus.if.org Git - clang/commitdiff
Driver: support ARM/HF on a single toolchain
authorSaleem Abdulrasool <compnerd@compnerd.org>
Sat, 26 Sep 2015 03:26:44 +0000 (03:26 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Sat, 26 Sep 2015 03:26:44 +0000 (03:26 +0000)
ARM EABI adds target attributes to the object file.  Amongst the attributes that
are emitted is the VFP argument passing (Hard vs Soft).  The linker is
responsible for checking these attributes and erroring on mismatches.  This
causes problems for the compiler-rt builtins when targeting both hard and
soft.  Because both of these options name the builtins compiler-rt component
the same (libclang_rt.builtins-arm.a or libclang_rt.builtins-arm-android).  GCC
is able to get away with this as it does one target per toolchain.  This
changes the naming convention for the ARM compiler-rt builtins to differentiate
between HF and Soft.  Although this means that compiler-rt may be duplicated, it
enables supporting both variants from a single toolchain.  A similar approach is
taken by the Darwin toolchain, naming the library to differentiate between the
calling conventions.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@248649 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Driver/SanitizerArgs.cpp
lib/Driver/Tools.cpp
lib/Driver/Tools.h
test/Driver/arm-compiler-rt.c [new file with mode: 0644]

index dee0dcfa49db9bb00e403103520acc94f4bc4721..4b0778f60aec9a00886723253ddc5bbf4ca4c158 100644 (file)
@@ -609,12 +609,13 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
   if (TC.getTriple().isOSWindows() && needsUbsanRt()) {
     // Instruct the code generator to embed linker directives in the object file
     // that cause the required runtime libraries to be linked.
-    CmdArgs.push_back(Args.MakeArgString(
-        "--dependent-lib=" + tools::getCompilerRT(TC, "ubsan_standalone")));
+    CmdArgs.push_back(
+        Args.MakeArgString("--dependent-lib=" +
+                           tools::getCompilerRT(TC, Args, "ubsan_standalone")));
     if (types::isCXX(InputType))
-      CmdArgs.push_back(
-          Args.MakeArgString("--dependent-lib=" +
-                             tools::getCompilerRT(TC, "ubsan_standalone_cxx")));
+      CmdArgs.push_back(Args.MakeArgString(
+          "--dependent-lib=" +
+          tools::getCompilerRT(TC, Args, "ubsan_standalone_cxx")));
   }
 }
 
index e13144ffebf0adbfe151f9f0d264d5a84477d7a7..62f86e15e6ea2de74e3186f1e03be8351593c0ba 100644 (file)
@@ -2403,12 +2403,19 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
 }
 
 // Until ARM libraries are build separately, we have them all in one library
-static StringRef getArchNameForCompilerRTLib(const ToolChain &TC) {
-  if (TC.getTriple().isWindowsMSVCEnvironment() &&
-      TC.getArch() == llvm::Triple::x86)
+static StringRef getArchNameForCompilerRTLib(const ToolChain &TC,
+                                             const ArgList &Args) {
+  const llvm::Triple &Triple = TC.getTriple();
+  bool IsWindows = Triple.isOSWindows();
+
+  if (Triple.isWindowsMSVCEnvironment() && TC.getArch() == llvm::Triple::x86)
     return "i386";
+
   if (TC.getArch() == llvm::Triple::arm || TC.getArch() == llvm::Triple::armeb)
-    return "arm";
+    return (arm::getARMFloatABI(TC, Args) == arm::FloatABI::Hard && !IsWindows)
+               ? "armhf"
+               : "arm";
+
   return TC.getArchName();
 }
 
@@ -2423,8 +2430,8 @@ static SmallString<128> getCompilerRTLibDir(const ToolChain &TC) {
   return Res;
 }
 
-SmallString<128> tools::getCompilerRT(const ToolChain &TC, StringRef Component,
-                                      bool Shared) {
+SmallString<128> tools::getCompilerRT(const ToolChain &TC, const ArgList &Args,
+                                      StringRef Component, bool Shared) {
   const char *Env = TC.getTriple().getEnvironment() == llvm::Triple::Android
                         ? "-android"
                         : "";
@@ -2432,7 +2439,7 @@ SmallString<128> tools::getCompilerRT(const ToolChain &TC, StringRef Component,
   bool IsOSWindows = TC.getTriple().isOSWindows();
   bool IsITANMSVCWindows = TC.getTriple().isWindowsMSVCEnvironment() ||
                            TC.getTriple().isWindowsItaniumEnvironment();
-  StringRef Arch = getArchNameForCompilerRTLib(TC);
+  StringRef Arch = getArchNameForCompilerRTLib(TC, Args);
   const char *Prefix = IsITANMSVCWindows ? "" : "lib";
   const char *Suffix =
       Shared ? (IsOSWindows ? ".dll" : ".so") : (IsITANMSVCWindows ? ".lib" : ".a");
@@ -2444,12 +2451,19 @@ SmallString<128> tools::getCompilerRT(const ToolChain &TC, StringRef Component,
   return Path;
 }
 
+static const char *getCompilerRTArgString(const ToolChain &TC,
+                                          const llvm::opt::ArgList &Args,
+                                          StringRef Component,
+                                          bool Shared = false) {
+  return Args.MakeArgString(getCompilerRT(TC, Args, Component, Shared));
+}
+
 // This adds the static libclang_rt.builtins-arch.a directly to the command line
 // FIXME: Make sure we can also emit shared objects if they're requested
 // and available, check for possible errors, etc.
 static void addClangRT(const ToolChain &TC, const ArgList &Args,
                        ArgStringList &CmdArgs) {
-  CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, "builtins")));
+  CmdArgs.push_back(getCompilerRTArgString(TC, Args, "builtins"));
 }
 
 static void addProfileRT(const ToolChain &TC, const ArgList &Args,
@@ -2464,7 +2478,7 @@ static void addProfileRT(const ToolChain &TC, const ArgList &Args,
         Args.hasArg(options::OPT_coverage)))
     return;
 
-  CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, "profile")));
+  CmdArgs.push_back(getCompilerRTArgString(TC, Args, "profile"));
 }
 
 namespace {
@@ -2545,7 +2559,7 @@ static void addSanitizerRuntime(const ToolChain &TC, const ArgList &Args,
   // whole-archive.
   if (!IsShared)
     CmdArgs.push_back("-whole-archive");
-  CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, Sanitizer, IsShared)));
+  CmdArgs.push_back(getCompilerRTArgString(TC, Args, Sanitizer, IsShared));
   if (!IsShared)
     CmdArgs.push_back("-no-whole-archive");
 }
@@ -2555,7 +2569,7 @@ static void addSanitizerRuntime(const ToolChain &TC, const ArgList &Args,
 static bool addSanitizerDynamicList(const ToolChain &TC, const ArgList &Args,
                                     ArgStringList &CmdArgs,
                                     StringRef Sanitizer) {
-  SmallString<128> SanRT = getCompilerRT(TC, Sanitizer);
+  SmallString<128> SanRT = getCompilerRT(TC, Args, Sanitizer);
   if (llvm::sys::fs::exists(SanRT + ".syms")) {
     CmdArgs.push_back(Args.MakeArgString("--dynamic-list=" + SanRT + ".syms"));
     return true;
@@ -9016,19 +9030,18 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
           "asan_dynamic", "asan_dynamic_runtime_thunk",
       };
       for (const auto &Component : CompilerRTComponents)
-        CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, Component)));
+        CmdArgs.push_back(getCompilerRTArgString(TC, Args, Component));
       // Make sure the dynamic runtime thunk is not optimized out at link time
       // to ensure proper SEH handling.
       CmdArgs.push_back(Args.MakeArgString("-include:___asan_seh_interceptor"));
     } else if (DLL) {
-      CmdArgs.push_back(
-          Args.MakeArgString(getCompilerRT(TC, "asan_dll_thunk")));
+      CmdArgs.push_back(getCompilerRTArgString(TC, Args, "asan_dll_thunk"));
     } else {
       static const char *CompilerRTComponents[] = {
           "asan", "asan_cxx",
       };
       for (const auto &Component : CompilerRTComponents)
-        CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, Component)));
+        CmdArgs.push_back(getCompilerRTArgString(TC, Args, Component));
     }
   }
 
index 3f63aface9f81fbb5d8efbc01d3b48834aa5c1ab..30ddcc90c235eb1007f620866397b615f47dece2 100644 (file)
@@ -37,8 +37,9 @@ class Compiler;
 
 using llvm::opt::ArgStringList;
 
-SmallString<128> getCompilerRT(const ToolChain &TC, StringRef Component,
-                               bool Shared = false);
+SmallString<128> getCompilerRT(const ToolChain &TC,
+                               const llvm::opt::ArgList &Args,
+                               StringRef Component, bool Shared = false);
 
 /// \brief Clang compiler tool.
 class LLVM_LIBRARY_VISIBILITY Clang : public Tool {
diff --git a/test/Driver/arm-compiler-rt.c b/test/Driver/arm-compiler-rt.c
new file mode 100644 (file)
index 0000000..6942318
--- /dev/null
@@ -0,0 +1,21 @@
+// RUN: %clang -target arm-linux-gnueabi -rtlib=compiler-rt -### %s 2>&1 | FileCheck %s -check-prefix ARM-GNUEABI
+// ARM-GNUEABI: "{{.*}}/libclang_rt.builtins-arm.a"
+
+// RUN: %clang -target arm-linux-gnueabi -rtlib=compiler-rt -mfloat-abi=hard -### %s 2>&1 | FileCheck %s -check-prefix ARM-GNUEABI-ABI
+// ARM-GNUEABI-ABI: "{{.*}}/libclang_rt.builtins-armhf.a"
+
+// RUN: %clang -target arm-linux-gnueabihf -rtlib=compiler-rt -### %s 2>&1 | FileCheck %s -check-prefix ARM-GNUEABIHF
+// ARM-GNUEABIHF: "{{.*}}/libclang_rt.builtins-armhf.a"
+
+// RUN: %clang -target arm-linux-gnueabihf -rtlib=compiler-rt -mfloat-abi=soft -### %s 2>&1 | FileCheck %s -check-prefix ARM-GNUEABIHF-ABI
+// ARM-GNUEABIHF-ABI: "{{.*}}/libclang_rt.builtins-arm.a"
+
+// RUN: %clang -target arm-windows-itanium -rtlib=compiler-rt -### %s 2>&1 | FileCheck %s -check-prefix ARM-WINDOWS
+// ARM-WINDOWS: "{{.*}}/clang_rt.builtins-arm.lib"
+
+// RUN: %clang -target arm-linux-androideabi -rtlib=compiler-rt -### %s 2>&1 | FileCheck %s -check-prefix ARM-ANDROID
+// ARM-ANDROID: "{{.*}}/libclang_rt.builtins-arm-android.a"
+
+// RUN: %clang -target arm-linux-androideabi -rtlib=compiler-rt -mfloat-abi=hard -### %s 2>&1 | FileCheck %s -check-prefix ARM-ANDROIDHF
+// ARM-ANDROIDHF: "{{.*}}/libclang_rt.builtins-armhf-android.a"
+