diff options
Diffstat (limited to 'lib/Driver')
-rw-r--r-- | lib/Driver/SanitizerArgs.h | 8 | ||||
-rw-r--r-- | lib/Driver/ToolChains.cpp | 20 | ||||
-rw-r--r-- | lib/Driver/ToolChains.h | 6 | ||||
-rw-r--r-- | lib/Driver/Tools.cpp | 96 | ||||
-rw-r--r-- | lib/Driver/WindowsToolChain.cpp | 4 |
5 files changed, 76 insertions, 58 deletions
diff --git a/lib/Driver/SanitizerArgs.h b/lib/Driver/SanitizerArgs.h index e61f15ad62..326d80db72 100644 --- a/lib/Driver/SanitizerArgs.h +++ b/lib/Driver/SanitizerArgs.h @@ -38,7 +38,8 @@ class SanitizerArgs { NeedsTsanRt = Thread, NeedsMsanRt = Memory, NeedsUbsanRt = Undefined | Integer, - NotAllowedWithTrap = Vptr + NotAllowedWithTrap = Vptr, + HasZeroBaseShadow = Thread | Memory }; unsigned Kind; std::string BlacklistFile; @@ -50,7 +51,7 @@ class SanitizerArgs { SanitizerArgs() : Kind(0), BlacklistFile(""), MsanTrackOrigins(false), AsanZeroBaseShadow(false), UbsanTrapOnError(false) {} /// Parses the sanitizer arguments from an argument list. - SanitizerArgs(const Driver &D, const ArgList &Args); + SanitizerArgs(const ToolChain &TC, const ArgList &Args); bool needsAsanRt() const { return Kind & NeedsAsanRt; } bool needsTsanRt() const { return Kind & NeedsTsanRt; } @@ -63,6 +64,9 @@ class SanitizerArgs { bool sanitizesVptr() const { return Kind & Vptr; } bool notAllowedWithTrap() const { return Kind & NotAllowedWithTrap; } + bool hasZeroBaseShadow() const { + return (Kind & HasZeroBaseShadow) || AsanZeroBaseShadow; + } void addArgs(const ArgList &Args, ArgStringList &CmdArgs) const { if (!Kind) diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index bcfe51ef7b..9732d9c21e 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -294,7 +294,7 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, } } - SanitizerArgs Sanitize(getDriver(), Args); + SanitizerArgs Sanitize(*this, Args); // Add Ubsan runtime library, if required. if (Sanitize.needsUbsanRt()) { @@ -878,6 +878,10 @@ bool Darwin::isPICDefault() const { return true; } +bool Darwin::isPIEDefault() const { + return false; +} + bool Darwin::isPICDefaultForced() const { return getArch() == llvm::Triple::x86_64; } @@ -1396,6 +1400,10 @@ bool Generic_GCC::isPICDefault() const { return false; } +bool Generic_GCC::isPIEDefault() const { + return false; +} + bool Generic_GCC::isPICDefaultForced() const { return false; } @@ -1630,6 +1638,10 @@ bool TCEToolChain::isPICDefault() const { return false; } +bool TCEToolChain::isPIEDefault() const { + return false; +} + bool TCEToolChain::isPICDefaultForced() const { return false; } @@ -2197,6 +2209,8 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) } addPathIfExists(SysRoot + "/lib", Paths); addPathIfExists(SysRoot + "/usr/lib", Paths); + + IsPIEDefault = SanitizerArgs(*this, Args).hasZeroBaseShadow(); } bool Linux::HasNativeLLVMSupport() const { @@ -2422,6 +2436,10 @@ void Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, } } +bool Linux::isPIEDefault() const { + return IsPIEDefault; +} + /// 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) diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h index 3421c53eb2..945acf7a02 100644 --- a/lib/Driver/ToolChains.h +++ b/lib/Driver/ToolChains.h @@ -123,6 +123,7 @@ public: virtual bool IsUnwindTablesDefault() const; virtual bool isPICDefault() const; + virtual bool isPIEDefault() const; virtual bool isPICDefaultForced() const; protected: @@ -332,6 +333,7 @@ public: return ToolChain::RLT_CompilerRT; } virtual bool isPICDefault() const; + virtual bool isPIEDefault() const; virtual bool isPICDefaultForced() const; virtual bool SupportsProfiling() const; @@ -509,9 +511,11 @@ public: ArgStringList &CC1Args) const; virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const; + virtual bool isPIEDefault() const; std::string Linker; std::vector<std::string> ExtraOpts; + bool IsPIEDefault; protected: virtual Tool *buildAssembler() const; @@ -562,6 +566,7 @@ public: bool IsMathErrnoDefault() const; bool isPICDefault() const; + bool isPIEDefault() const; bool isPICDefaultForced() const; }; @@ -572,6 +577,7 @@ public: virtual bool IsIntegratedAssemblerDefault() const; virtual bool IsUnwindTablesDefault() const; virtual bool isPICDefault() const; + virtual bool isPIEDefault() const; virtual bool isPICDefaultForced() const; virtual void AddClangSystemIncludeArgs(const ArgList &DriverArgs, diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index a2c0d0fbbd..8c181c5825 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -1508,11 +1508,12 @@ static bool UseRelaxAll(Compilation &C, const ArgList &Args) { RelaxDefault); } -SanitizerArgs::SanitizerArgs(const Driver &D, const ArgList &Args) +SanitizerArgs::SanitizerArgs(const ToolChain &TC, const ArgList &Args) : Kind(0), BlacklistFile(""), MsanTrackOrigins(false), AsanZeroBaseShadow(false) { unsigned AllKinds = 0; // All kinds of sanitizers that were turned on // at least once (possibly, disabled further). + const Driver &D = TC.getDriver(); for (ArgList::const_iterator I = Args.begin(), E = Args.end(); I != E; ++I) { unsigned Add, Remove; if (!parse(D, Args, *I, Add, Remove, true)) @@ -1606,6 +1607,7 @@ SanitizerArgs::SanitizerArgs(const Driver &D, const ArgList &Args) // Parse -f(no-)sanitize-address-zero-base-shadow options. if (NeedsAsan) AsanZeroBaseShadow = + TC.getTriple().getEnvironment() == llvm::Triple::Android || Args.hasFlag(options::OPT_fsanitize_address_zero_base_shadow, options::OPT_fno_sanitize_address_zero_base_shadow, /* Default */false); @@ -1656,11 +1658,6 @@ static void addSanitizerRTLinkFlagsLinux( static void addAsanRTLinux(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) { if(TC.getTriple().getEnvironment() == llvm::Triple::Android) { - if (!Args.hasArg(options::OPT_shared)) { - if (!Args.hasArg(options::OPT_pie)) - TC.getDriver().Diag(diag::err_drv_asan_android_requires_pie); - } - SmallString<128> LibAsan(TC.getDriver().ResourceDir); llvm::sys::path::append(LibAsan, "lib", "linux", (Twine("libclang_rt.asan-") + @@ -1668,13 +1665,6 @@ static void addAsanRTLinux(const ToolChain &TC, const ArgList &Args, CmdArgs.insert(CmdArgs.begin(), Args.MakeArgString(LibAsan)); } else { if (!Args.hasArg(options::OPT_shared)) { - bool ZeroBaseShadow = Args.hasFlag( - options::OPT_fsanitize_address_zero_base_shadow, - options::OPT_fno_sanitize_address_zero_base_shadow, false); - if (ZeroBaseShadow && !Args.hasArg(options::OPT_pie)) { - TC.getDriver().Diag(diag::err_drv_argument_only_allowed_with) << - "-fsanitize-address-zero-base-shadow" << "-pie"; - } addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "asan", true); } } @@ -1685,9 +1675,6 @@ static void addAsanRTLinux(const ToolChain &TC, const ArgList &Args, static void addTsanRTLinux(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) { if (!Args.hasArg(options::OPT_shared)) { - if (!Args.hasArg(options::OPT_pie)) - TC.getDriver().Diag(diag::err_drv_argument_only_allowed_with) << - "-fsanitize=thread" << "-pie"; addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "tsan", true); } } @@ -1697,9 +1684,6 @@ static void addTsanRTLinux(const ToolChain &TC, const ArgList &Args, static void addMsanRTLinux(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) { if (!Args.hasArg(options::OPT_shared)) { - if (!Args.hasArg(options::OPT_pie)) - TC.getDriver().Diag(diag::err_drv_argument_only_allowed_with) << - "-fsanitize=memory" << "-pie"; addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "msan", true); } } @@ -2000,37 +1984,37 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CheckCodeGenerationOptions(D, Args); - // For the PIC and PIE flag options, this logic is different from the legacy - // logic in very old versions of GCC, as that logic was just a bug no one had - // ever fixed. This logic is both more rational and consistent with GCC's new - // logic now that the bugs are fixed. The last argument relating to either - // PIC or PIE wins, and no other argument is used. If the last argument is - // any flavor of the '-fno-...' arguments, both PIC and PIE are disabled. Any - // PIE option implicitly enables PIC at the same level. - bool PIE = false; - bool PIC = getToolChain().isPICDefault(); + bool PIE = getToolChain().isPIEDefault(); + bool PIC = PIE || getToolChain().isPICDefault(); bool IsPICLevelTwo = PIC; - if (Arg *A = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC, - options::OPT_fpic, options::OPT_fno_pic, - options::OPT_fPIE, options::OPT_fno_PIE, - options::OPT_fpie, options::OPT_fno_pie)) { - Option O = A->getOption(); - if (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) || - O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie)) { - PIE = O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie); - PIC = PIE || O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic); - IsPICLevelTwo = O.matches(options::OPT_fPIE) || - O.matches(options::OPT_fPIC); - } else { - PIE = PIC = false; - } - } + // Check whether the tool chain trumps the PIC-ness decision. If the PIC-ness // is forced, then neither PIC nor PIE flags will have no effect. - if (getToolChain().isPICDefaultForced()) { - PIE = false; - PIC = getToolChain().isPICDefault(); - IsPICLevelTwo = PIC; + if (!getToolChain().isPICDefaultForced()) { + // For the PIC and PIE flag options, this logic is different from the + // legacy logic in very old versions of GCC, as that logic was just + // a bug no one had ever fixed. This logic is both more rational and + // consistent with GCC's new logic now that the bugs are fixed. The last + // argument relating to either PIC or PIE wins, and no other argument is + // used. If the last argument is any flavor of the '-fno-...' arguments, + // both PIC and PIE are disabled. Any PIE option implicitly enables PIC + // at the same level. + if (Arg *A = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC, + options::OPT_fpic, options::OPT_fno_pic, + options::OPT_fPIE, options::OPT_fno_PIE, + options::OPT_fpie, options::OPT_fno_pie)) { + Option O = A->getOption(); + if (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) || + O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie)) { + PIE = O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie); + PIC = PIE || O.matches(options::OPT_fPIC) || + O.matches(options::OPT_fpic); + IsPICLevelTwo = O.matches(options::OPT_fPIE) || + O.matches(options::OPT_fPIC); + } else { + PIE = PIC = false; + } + } } // Inroduce a Darwin-specific hack. If the default is PIC but the flags @@ -2708,7 +2692,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_show_template_tree); Args.AddLastArg(CmdArgs, options::OPT_fno_elide_type); - SanitizerArgs Sanitize(D, Args); + SanitizerArgs Sanitize(getToolChain(), Args); Sanitize.addArgs(Args, CmdArgs); if (!Args.hasFlag(options::OPT_fsanitize_recover, @@ -4582,7 +4566,7 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA, Args.AddAllArgs(CmdArgs, options::OPT_L); - SanitizerArgs Sanitize(getToolChain().getDriver(), Args); + SanitizerArgs Sanitize(getToolChain(), Args); // If we're building a dynamic lib with -fsanitize=address, // unresolved symbols may appear. Mark all // of them as dynamic_lookup. Linking executables is handled in @@ -5787,6 +5771,10 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA, const Driver &D = ToolChain.getDriver(); const bool isAndroid = ToolChain.getTriple().getEnvironment() == llvm::Triple::Android; + SanitizerArgs Sanitize(getToolChain(), Args); + const bool IsPIE = + !Args.hasArg(options::OPT_shared) && + (Args.hasArg(options::OPT_pie) || Sanitize.hasZeroBaseShadow()); ArgStringList CmdArgs; @@ -5801,7 +5789,7 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA, if (!D.SysRoot.empty()) CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); - if (Args.hasArg(options::OPT_pie) && !Args.hasArg(options::OPT_shared)) + if (IsPIE) CmdArgs.push_back("-pie"); if (Args.hasArg(options::OPT_rdynamic)) @@ -5907,7 +5895,7 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA, if (!isAndroid) { const char *crt1 = NULL; if (!Args.hasArg(options::OPT_shared)){ - if (Args.hasArg(options::OPT_pie)) + if (IsPIE) crt1 = "Scrt1.o"; else crt1 = "crt1.o"; @@ -5923,7 +5911,7 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA, crtbegin = isAndroid ? "crtbegin_static.o" : "crtbeginT.o"; else if (Args.hasArg(options::OPT_shared)) crtbegin = isAndroid ? "crtbegin_so.o" : "crtbeginS.o"; - else if (Args.hasArg(options::OPT_pie)) + else if (IsPIE) crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbeginS.o"; else crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbegin.o"; @@ -5974,8 +5962,6 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA, AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs); - SanitizerArgs Sanitize(D, Args); - // Call these before we add the C++ ABI library. if (Sanitize.needsUbsanRt()) addUbsanRTLinux(getToolChain(), Args, CmdArgs, D.CCCIsCXX, @@ -6033,7 +6019,7 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA, const char *crtend; if (Args.hasArg(options::OPT_shared)) crtend = isAndroid ? "crtend_so.o" : "crtendS.o"; - else if (Args.hasArg(options::OPT_pie)) + else if (IsPIE) crtend = isAndroid ? "crtend_android.o" : "crtendS.o"; else crtend = isAndroid ? "crtend_android.o" : "crtend.o"; diff --git a/lib/Driver/WindowsToolChain.cpp b/lib/Driver/WindowsToolChain.cpp index dac7e77d60..622c49296d 100644 --- a/lib/Driver/WindowsToolChain.cpp +++ b/lib/Driver/WindowsToolChain.cpp @@ -60,6 +60,10 @@ bool Windows::isPICDefault() const { return getArch() == llvm::Triple::x86_64; } +bool Windows::isPIEDefault() const { + return false; +} + bool Windows::isPICDefaultForced() const { return getArch() == llvm::Triple::x86_64; } |