From: Peter Collingbourne Date: Mon, 27 May 2013 21:40:20 +0000 (+0000) Subject: Driver: implement --dyld-prefix option. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bdaa13418851be5cc1ca3be88fbd82b15efecde7;p=clang Driver: implement --dyld-prefix option. This option is used to select a dynamic loader prefix to be used at runtime. Currently this is implemented for the Linux toolchain. Differential Revision: http://llvm-reviews.chandlerc.com/D851 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@182744 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h index d9053d1972..1b17578bbb 100644 --- a/include/clang/Driver/Driver.h +++ b/include/clang/Driver/Driver.h @@ -79,6 +79,9 @@ public: /// sysroot, if present std::string SysRoot; + /// Dynamic loader prefix, if present + std::string DyldPrefix; + /// If the standard library is used bool UseStdLib; diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index ec1270720a..a2d7688cf3 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -1163,6 +1163,8 @@ def _debug : Flag<["--"], "debug">, Alias; def _define_macro_EQ : Joined<["--"], "define-macro=">, Alias; def _define_macro : Separate<["--"], "define-macro">, Alias; def _dependencies : Flag<["--"], "dependencies">, Alias; +def _dyld_prefix_EQ : Joined<["--"], "dyld-prefix=">; +def _dyld_prefix : Separate<["--"], "dyld-prefix">, Alias<_dyld_prefix_EQ>; def _encoding_EQ : Joined<["--"], "encoding=">, Alias; def _encoding : Separate<["--"], "encoding">, Alias; def _entry : Flag<["--"], "entry">, Alias; diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 1dbbc9a342..5e8dde353b 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -289,6 +289,8 @@ Compilation *Driver::BuildCompilation(ArrayRef ArgList) { } if (const Arg *A = Args->getLastArg(options::OPT__sysroot_EQ)) SysRoot = A->getValue(); + if (const Arg *A = Args->getLastArg(options::OPT__dyld_prefix_EQ)) + DyldPrefix = A->getValue(); if (Args->hasArg(options::OPT_nostdlib)) UseStdLib = false; diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 6d66e4b816..106c642b44 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -5924,6 +5924,38 @@ static bool hasMipsN32ABIArg(const ArgList &Args) { return A && (A->getValue() == StringRef("n32")); } +static StringRef getLinuxDynamicLinker(const ArgList &Args, + const toolchains::Linux &ToolChain) { + if (ToolChain.getTriple().getEnvironment() == llvm::Triple::Android) + return "/system/bin/linker"; + else if (ToolChain.getArch() == llvm::Triple::x86) + return "/lib/ld-linux.so.2"; + else if (ToolChain.getArch() == llvm::Triple::aarch64) + return "/lib/ld-linux-aarch64.so.1"; + else if (ToolChain.getArch() == llvm::Triple::arm || + ToolChain.getArch() == llvm::Triple::thumb) { + if (ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUEABIHF) + return "/lib/ld-linux-armhf.so.3"; + else + return "/lib/ld-linux.so.3"; + } else if (ToolChain.getArch() == llvm::Triple::mips || + ToolChain.getArch() == llvm::Triple::mipsel) + return "/lib/ld.so.1"; + else if (ToolChain.getArch() == llvm::Triple::mips64 || + ToolChain.getArch() == llvm::Triple::mips64el) { + if (hasMipsN32ABIArg(Args)) + return "/lib32/ld.so.1"; + else + return "/lib64/ld.so.1"; + } else if (ToolChain.getArch() == llvm::Triple::ppc) + return "/lib/ld.so.1"; + else if (ToolChain.getArch() == llvm::Triple::ppc64 || + ToolChain.getArch() == llvm::Triple::systemz) + return "/lib64/ld64.so.1"; + else + return "/lib64/ld-linux-x86-64.so.2"; +} + void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, @@ -6021,36 +6053,8 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA, (!Args.hasArg(options::OPT_static) && !Args.hasArg(options::OPT_shared))) { CmdArgs.push_back("-dynamic-linker"); - if (isAndroid) - CmdArgs.push_back("/system/bin/linker"); - else if (ToolChain.getArch() == llvm::Triple::x86) - CmdArgs.push_back("/lib/ld-linux.so.2"); - else if (ToolChain.getArch() == llvm::Triple::aarch64) - CmdArgs.push_back("/lib/ld-linux-aarch64.so.1"); - else if (ToolChain.getArch() == llvm::Triple::arm || - ToolChain.getArch() == llvm::Triple::thumb) { - if (ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUEABIHF) - CmdArgs.push_back("/lib/ld-linux-armhf.so.3"); - else - CmdArgs.push_back("/lib/ld-linux.so.3"); - } - else if (ToolChain.getArch() == llvm::Triple::mips || - ToolChain.getArch() == llvm::Triple::mipsel) - CmdArgs.push_back("/lib/ld.so.1"); - else if (ToolChain.getArch() == llvm::Triple::mips64 || - ToolChain.getArch() == llvm::Triple::mips64el) { - if (hasMipsN32ABIArg(Args)) - CmdArgs.push_back("/lib32/ld.so.1"); - else - CmdArgs.push_back("/lib64/ld.so.1"); - } - else if (ToolChain.getArch() == llvm::Triple::ppc) - CmdArgs.push_back("/lib/ld.so.1"); - else if (ToolChain.getArch() == llvm::Triple::ppc64 || - ToolChain.getArch() == llvm::Triple::systemz) - CmdArgs.push_back("/lib64/ld64.so.1"); - else - CmdArgs.push_back("/lib64/ld-linux-x86-64.so.2"); + CmdArgs.push_back(Args.MakeArgString( + D.DyldPrefix + getLinuxDynamicLinker(Args, ToolChain))); } CmdArgs.push_back("-o"); diff --git a/test/Driver/dyld-prefix.c b/test/Driver/dyld-prefix.c new file mode 100644 index 0000000000..de24f00932 --- /dev/null +++ b/test/Driver/dyld-prefix.c @@ -0,0 +1,7 @@ +// RUN: touch %t.o + +// RUN: %clang -target i386-unknown-linux --dyld-prefix /foo -### %t.o 2>&1 | FileCheck --check-prefix=CHECK-32 %s +// CHECK-32: "-dynamic-linker" "/foo/lib/ld-linux.so.2" + +// RUN: %clang -target x86_64-unknown-linux --dyld-prefix /foo -### %t.o 2>&1 | FileCheck --check-prefix=CHECK-64 %s +// CHECK-64: "-dynamic-linker" "/foo/lib64/ld-linux-x86-64.so.2"