If the user requested a zero-base-shadow sanitizer, infer -pie and -fPIC when appropriate.

Differential Revision: http://llvm-reviews.chandlerc.com/D502

llvm-svn: 179082
This commit is contained in:
Peter Collingbourne 2013-04-09 04:35:11 +00:00
parent 61e221f68d
commit 54d770cb1f
10 changed files with 107 additions and 76 deletions

View File

@ -46,7 +46,7 @@ to disable inlining (just use ``-O1``) and tail call elimination
return 0; return 0;
} }
% clang -fsanitize=memory -fPIE -pie -fno-omit-frame-pointer -g -O2 umr.cc % clang -fsanitize=memory -fno-omit-frame-pointer -g -O2 umr.cc
If a bug is detected, the program will print an error message to If a bug is detected, the program will print an error message to
stderr and exit with a non-zero exit code. Currently, MemorySanitizer stderr and exit with a non-zero exit code. Currently, MemorySanitizer
@ -103,7 +103,7 @@ the example above,
.. code-block:: console .. code-block:: console
% clang -fsanitize=memory -fsanitize-memory-track-origins -fPIE -pie -fno-omit-frame-pointer -g -O2 umr.cc % clang -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -g -O2 umr.cc
% ./a.out 2>log % ./a.out 2>log
% projects/compiler-rt/lib/asan/scripts/asan_symbolize.py / < log | c++filt % projects/compiler-rt/lib/asan/scripts/asan_symbolize.py / < log | c++filt
==14425== WARNING: MemorySanitizer: UMR (uninitialized-memory-read) ==14425== WARNING: MemorySanitizer: UMR (uninitialized-memory-read)
@ -160,7 +160,10 @@ Limitations
address space. This means that tools like ``ulimit`` may not work as address space. This means that tools like ``ulimit`` may not work as
usually expected. usually expected.
* Static linking is not supported. * Static linking is not supported.
* Non-position-independent executables are not supported. * Non-position-independent executables are not supported. Therefore, the
``fsanitize=memory`` flag will cause Clang to act as though the ``-fPIE``
flag had been supplied if compiling without ``-fPIC``, and as though the
``-pie`` flag had been supplied if linking an executable.
* Depending on the version of Linux kernel, running without ASLR may * Depending on the version of Linux kernel, running without ASLR may
be not supported. Note that GDB disables ASLR by default. To debug be not supported. Note that GDB disables ASLR by default. To debug
instrumented programs, use "set disable-randomization off". instrumented programs, use "set disable-randomization off".

View File

@ -25,9 +25,9 @@ platforms is problematic and not yet planned.
Usage Usage
----- -----
Simply compile your program with ``-fsanitize=thread -fPIE`` and link it with Simply compile and link your program with ``-fsanitize=thread``. To get a
``-fsanitize=thread -pie``. To get a reasonable performance add ``-O1`` or reasonable performance add ``-O1`` or higher. Use ``-g`` to get file names
higher. Use ``-g`` to get file names and line numbers in the warning messages. and line numbers in the warning messages.
Example: Example:
@ -48,7 +48,7 @@ Example:
return Global; return Global;
} }
$ clang -fsanitize=thread -g -O1 tiny_race.c -fPIE -pie $ clang -fsanitize=thread -g -O1 tiny_race.c
If a bug is detected, the program will print an error message to stderr. If a bug is detected, the program will print an error message to stderr.
Currently, ThreadSanitizer symbolizes its output using an external Currently, ThreadSanitizer symbolizes its output using an external
@ -107,7 +107,10 @@ Limitations
* ThreadSanitizer maps (but does not reserve) a lot of virtual address space. * ThreadSanitizer maps (but does not reserve) a lot of virtual address space.
This means that tools like ``ulimit`` may not work as usually expected. This means that tools like ``ulimit`` may not work as usually expected.
* Libc/libstdc++ static linking is not supported. * Libc/libstdc++ static linking is not supported.
* ThreadSanitizer requires ``-fPIE -pie`` compiler flags. * Non-position-independent executables are not supported. Therefore, the
``fsanitize=thread`` flag will cause Clang to act as though the ``-fPIE``
flag had been supplied if compiling without ``-fPIC``, and as though the
``-pie`` flag had been supplied if linking an executable.
Current Status Current Status
-------------- --------------

View File

@ -105,8 +105,6 @@ def err_arc_unsupported_on_toolchain : Error< // feel free to generalize this
"-fobjc-arc is not supported on versions of OS X prior to 10.6">; "-fobjc-arc is not supported on versions of OS X prior to 10.6">;
def err_drv_mg_requires_m_or_mm : Error< def err_drv_mg_requires_m_or_mm : Error<
"option '-MG' requires '-M' or '-MM'">; "option '-MG' requires '-M' or '-MM'">;
def err_drv_asan_android_requires_pie : Error<
"AddressSanitizer on Android requires '-pie'">;
def err_drv_unknown_objc_runtime : Error< def err_drv_unknown_objc_runtime : Error<
"unknown or ill-formed Objective-C runtime '%0'">; "unknown or ill-formed Objective-C runtime '%0'">;

View File

@ -195,9 +195,13 @@ public:
/// \brief Test whether this toolchain defaults to PIC. /// \brief Test whether this toolchain defaults to PIC.
virtual bool isPICDefault() const = 0; virtual bool isPICDefault() const = 0;
/// \brief Tests whether this toolchain forces its default for PIC or non-PIC. /// \brief Test whether this toolchain defaults to PIE.
/// If this returns true, any PIC related flags should be ignored and instead virtual bool isPIEDefault() const = 0;
/// the result of \c isPICDefault() is used exclusively.
/// \brief Tests whether this toolchain forces its default for PIC, PIE or
/// non-PIC. If this returns true, any PIC related flags should be ignored
/// and instead the results of \c isPICDefault() and \c isPIEDefault() are
/// used exclusively.
virtual bool isPICDefaultForced() const = 0; virtual bool isPICDefaultForced() const = 0;
/// SupportsProfiling - Does this tool chain support -pg. /// SupportsProfiling - Does this tool chain support -pg.

View File

@ -38,7 +38,8 @@ class SanitizerArgs {
NeedsTsanRt = Thread, NeedsTsanRt = Thread,
NeedsMsanRt = Memory, NeedsMsanRt = Memory,
NeedsUbsanRt = Undefined | Integer, NeedsUbsanRt = Undefined | Integer,
NotAllowedWithTrap = Vptr NotAllowedWithTrap = Vptr,
HasZeroBaseShadow = Thread | Memory
}; };
unsigned Kind; unsigned Kind;
std::string BlacklistFile; std::string BlacklistFile;
@ -50,7 +51,7 @@ class SanitizerArgs {
SanitizerArgs() : Kind(0), BlacklistFile(""), MsanTrackOrigins(false), SanitizerArgs() : Kind(0), BlacklistFile(""), MsanTrackOrigins(false),
AsanZeroBaseShadow(false), UbsanTrapOnError(false) {} AsanZeroBaseShadow(false), UbsanTrapOnError(false) {}
/// Parses the sanitizer arguments from an argument list. /// 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 needsAsanRt() const { return Kind & NeedsAsanRt; }
bool needsTsanRt() const { return Kind & NeedsTsanRt; } bool needsTsanRt() const { return Kind & NeedsTsanRt; }
@ -63,6 +64,9 @@ class SanitizerArgs {
bool sanitizesVptr() const { return Kind & Vptr; } bool sanitizesVptr() const { return Kind & Vptr; }
bool notAllowedWithTrap() const { return Kind & NotAllowedWithTrap; } bool notAllowedWithTrap() const { return Kind & NotAllowedWithTrap; }
bool hasZeroBaseShadow() const {
return (Kind & HasZeroBaseShadow) || AsanZeroBaseShadow;
}
void addArgs(const ArgList &Args, ArgStringList &CmdArgs) const { void addArgs(const ArgList &Args, ArgStringList &CmdArgs) const {
if (!Kind) if (!Kind)

View File

@ -294,7 +294,7 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
} }
} }
SanitizerArgs Sanitize(getDriver(), Args); SanitizerArgs Sanitize(*this, Args);
// Add Ubsan runtime library, if required. // Add Ubsan runtime library, if required.
if (Sanitize.needsUbsanRt()) { if (Sanitize.needsUbsanRt()) {
@ -878,6 +878,10 @@ bool Darwin::isPICDefault() const {
return true; return true;
} }
bool Darwin::isPIEDefault() const {
return false;
}
bool Darwin::isPICDefaultForced() const { bool Darwin::isPICDefaultForced() const {
return getArch() == llvm::Triple::x86_64; return getArch() == llvm::Triple::x86_64;
} }
@ -1396,6 +1400,10 @@ bool Generic_GCC::isPICDefault() const {
return false; return false;
} }
bool Generic_GCC::isPIEDefault() const {
return false;
}
bool Generic_GCC::isPICDefaultForced() const { bool Generic_GCC::isPICDefaultForced() const {
return false; return false;
} }
@ -1630,6 +1638,10 @@ bool TCEToolChain::isPICDefault() const {
return false; return false;
} }
bool TCEToolChain::isPIEDefault() const {
return false;
}
bool TCEToolChain::isPICDefaultForced() const { bool TCEToolChain::isPICDefaultForced() const {
return false; return false;
} }
@ -2197,6 +2209,8 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
} }
addPathIfExists(SysRoot + "/lib", Paths); addPathIfExists(SysRoot + "/lib", Paths);
addPathIfExists(SysRoot + "/usr/lib", Paths); addPathIfExists(SysRoot + "/usr/lib", Paths);
IsPIEDefault = SanitizerArgs(*this, Args).hasZeroBaseShadow();
} }
bool Linux::HasNativeLLVMSupport() const { 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 tool chain which can call as(1) and ld(1) directly.
DragonFly::DragonFly(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) DragonFly::DragonFly(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)

View File

@ -123,6 +123,7 @@ public:
virtual bool IsUnwindTablesDefault() const; virtual bool IsUnwindTablesDefault() const;
virtual bool isPICDefault() const; virtual bool isPICDefault() const;
virtual bool isPIEDefault() const;
virtual bool isPICDefaultForced() const; virtual bool isPICDefaultForced() const;
protected: protected:
@ -332,6 +333,7 @@ public:
return ToolChain::RLT_CompilerRT; return ToolChain::RLT_CompilerRT;
} }
virtual bool isPICDefault() const; virtual bool isPICDefault() const;
virtual bool isPIEDefault() const;
virtual bool isPICDefaultForced() const; virtual bool isPICDefaultForced() const;
virtual bool SupportsProfiling() const; virtual bool SupportsProfiling() const;
@ -509,9 +511,11 @@ public:
ArgStringList &CC1Args) const; ArgStringList &CC1Args) const;
virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const; ArgStringList &CC1Args) const;
virtual bool isPIEDefault() const;
std::string Linker; std::string Linker;
std::vector<std::string> ExtraOpts; std::vector<std::string> ExtraOpts;
bool IsPIEDefault;
protected: protected:
virtual Tool *buildAssembler() const; virtual Tool *buildAssembler() const;
@ -562,6 +566,7 @@ public:
bool IsMathErrnoDefault() const; bool IsMathErrnoDefault() const;
bool isPICDefault() const; bool isPICDefault() const;
bool isPIEDefault() const;
bool isPICDefaultForced() const; bool isPICDefaultForced() const;
}; };
@ -572,6 +577,7 @@ public:
virtual bool IsIntegratedAssemblerDefault() const; virtual bool IsIntegratedAssemblerDefault() const;
virtual bool IsUnwindTablesDefault() const; virtual bool IsUnwindTablesDefault() const;
virtual bool isPICDefault() const; virtual bool isPICDefault() const;
virtual bool isPIEDefault() const;
virtual bool isPICDefaultForced() const; virtual bool isPICDefaultForced() const;
virtual void AddClangSystemIncludeArgs(const ArgList &DriverArgs, virtual void AddClangSystemIncludeArgs(const ArgList &DriverArgs,

View File

@ -1508,11 +1508,12 @@ static bool UseRelaxAll(Compilation &C, const ArgList &Args) {
RelaxDefault); RelaxDefault);
} }
SanitizerArgs::SanitizerArgs(const Driver &D, const ArgList &Args) SanitizerArgs::SanitizerArgs(const ToolChain &TC, const ArgList &Args)
: Kind(0), BlacklistFile(""), MsanTrackOrigins(false), : Kind(0), BlacklistFile(""), MsanTrackOrigins(false),
AsanZeroBaseShadow(false) { AsanZeroBaseShadow(false) {
unsigned AllKinds = 0; // All kinds of sanitizers that were turned on unsigned AllKinds = 0; // All kinds of sanitizers that were turned on
// at least once (possibly, disabled further). // at least once (possibly, disabled further).
const Driver &D = TC.getDriver();
for (ArgList::const_iterator I = Args.begin(), E = Args.end(); I != E; ++I) { for (ArgList::const_iterator I = Args.begin(), E = Args.end(); I != E; ++I) {
unsigned Add, Remove; unsigned Add, Remove;
if (!parse(D, Args, *I, Add, Remove, true)) 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. // Parse -f(no-)sanitize-address-zero-base-shadow options.
if (NeedsAsan) if (NeedsAsan)
AsanZeroBaseShadow = AsanZeroBaseShadow =
TC.getTriple().getEnvironment() == llvm::Triple::Android ||
Args.hasFlag(options::OPT_fsanitize_address_zero_base_shadow, Args.hasFlag(options::OPT_fsanitize_address_zero_base_shadow,
options::OPT_fno_sanitize_address_zero_base_shadow, options::OPT_fno_sanitize_address_zero_base_shadow,
/* Default */false); /* Default */false);
@ -1656,11 +1658,6 @@ static void addSanitizerRTLinkFlagsLinux(
static void addAsanRTLinux(const ToolChain &TC, const ArgList &Args, static void addAsanRTLinux(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs) { ArgStringList &CmdArgs) {
if(TC.getTriple().getEnvironment() == llvm::Triple::Android) { 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); SmallString<128> LibAsan(TC.getDriver().ResourceDir);
llvm::sys::path::append(LibAsan, "lib", "linux", llvm::sys::path::append(LibAsan, "lib", "linux",
(Twine("libclang_rt.asan-") + (Twine("libclang_rt.asan-") +
@ -1668,13 +1665,6 @@ static void addAsanRTLinux(const ToolChain &TC, const ArgList &Args,
CmdArgs.insert(CmdArgs.begin(), Args.MakeArgString(LibAsan)); CmdArgs.insert(CmdArgs.begin(), Args.MakeArgString(LibAsan));
} else { } else {
if (!Args.hasArg(options::OPT_shared)) { 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); 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, static void addTsanRTLinux(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs) { ArgStringList &CmdArgs) {
if (!Args.hasArg(options::OPT_shared)) { 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); 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, static void addMsanRTLinux(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs) { ArgStringList &CmdArgs) {
if (!Args.hasArg(options::OPT_shared)) { 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); addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "msan", true);
} }
} }
@ -2000,16 +1984,21 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CheckCodeGenerationOptions(D, Args); CheckCodeGenerationOptions(D, Args);
// For the PIC and PIE flag options, this logic is different from the legacy bool PIE = getToolChain().isPIEDefault();
// logic in very old versions of GCC, as that logic was just a bug no one had bool PIC = PIE || getToolChain().isPICDefault();
// 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 IsPICLevelTwo = PIC; bool IsPICLevelTwo = PIC;
// 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()) {
// 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, if (Arg *A = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
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,
@ -2018,19 +2007,14 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) || if (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) ||
O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie)) { O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie)) {
PIE = 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); PIC = PIE || O.matches(options::OPT_fPIC) ||
O.matches(options::OPT_fpic);
IsPICLevelTwo = O.matches(options::OPT_fPIE) || IsPICLevelTwo = O.matches(options::OPT_fPIE) ||
O.matches(options::OPT_fPIC); O.matches(options::OPT_fPIC);
} else { } else {
PIE = PIC = false; 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;
} }
// Inroduce a Darwin-specific hack. If the default is PIC but the flags // 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_fdiagnostics_show_template_tree);
Args.AddLastArg(CmdArgs, options::OPT_fno_elide_type); Args.AddLastArg(CmdArgs, options::OPT_fno_elide_type);
SanitizerArgs Sanitize(D, Args); SanitizerArgs Sanitize(getToolChain(), Args);
Sanitize.addArgs(Args, CmdArgs); Sanitize.addArgs(Args, CmdArgs);
if (!Args.hasFlag(options::OPT_fsanitize_recover, 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); 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, // If we're building a dynamic lib with -fsanitize=address,
// unresolved symbols may appear. Mark all // unresolved symbols may appear. Mark all
// of them as dynamic_lookup. Linking executables is handled in // 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 Driver &D = ToolChain.getDriver();
const bool isAndroid = const bool isAndroid =
ToolChain.getTriple().getEnvironment() == llvm::Triple::Android; 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; ArgStringList CmdArgs;
@ -5801,7 +5789,7 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA,
if (!D.SysRoot.empty()) if (!D.SysRoot.empty())
CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); 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"); CmdArgs.push_back("-pie");
if (Args.hasArg(options::OPT_rdynamic)) if (Args.hasArg(options::OPT_rdynamic))
@ -5907,7 +5895,7 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA,
if (!isAndroid) { if (!isAndroid) {
const char *crt1 = NULL; const char *crt1 = NULL;
if (!Args.hasArg(options::OPT_shared)){ if (!Args.hasArg(options::OPT_shared)){
if (Args.hasArg(options::OPT_pie)) if (IsPIE)
crt1 = "Scrt1.o"; crt1 = "Scrt1.o";
else else
crt1 = "crt1.o"; crt1 = "crt1.o";
@ -5923,7 +5911,7 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA,
crtbegin = isAndroid ? "crtbegin_static.o" : "crtbeginT.o"; crtbegin = isAndroid ? "crtbegin_static.o" : "crtbeginT.o";
else if (Args.hasArg(options::OPT_shared)) else if (Args.hasArg(options::OPT_shared))
crtbegin = isAndroid ? "crtbegin_so.o" : "crtbeginS.o"; crtbegin = isAndroid ? "crtbegin_so.o" : "crtbeginS.o";
else if (Args.hasArg(options::OPT_pie)) else if (IsPIE)
crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbeginS.o"; crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbeginS.o";
else else
crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbegin.o"; 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); AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
SanitizerArgs Sanitize(D, Args);
// Call these before we add the C++ ABI library. // Call these before we add the C++ ABI library.
if (Sanitize.needsUbsanRt()) if (Sanitize.needsUbsanRt())
addUbsanRTLinux(getToolChain(), Args, CmdArgs, D.CCCIsCXX, addUbsanRTLinux(getToolChain(), Args, CmdArgs, D.CCCIsCXX,
@ -6033,7 +6019,7 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA,
const char *crtend; const char *crtend;
if (Args.hasArg(options::OPT_shared)) if (Args.hasArg(options::OPT_shared))
crtend = isAndroid ? "crtend_so.o" : "crtendS.o"; crtend = isAndroid ? "crtend_so.o" : "crtendS.o";
else if (Args.hasArg(options::OPT_pie)) else if (IsPIE)
crtend = isAndroid ? "crtend_android.o" : "crtendS.o"; crtend = isAndroid ? "crtend_android.o" : "crtendS.o";
else else
crtend = isAndroid ? "crtend_android.o" : "crtend.o"; crtend = isAndroid ? "crtend_android.o" : "crtend.o";

View File

@ -60,6 +60,10 @@ bool Windows::isPICDefault() const {
return getArch() == llvm::Triple::x86_64; return getArch() == llvm::Triple::x86_64;
} }
bool Windows::isPIEDefault() const {
return false;
}
bool Windows::isPICDefaultForced() const { bool Windows::isPICDefaultForced() const {
return getArch() == llvm::Triple::x86_64; return getArch() == llvm::Triple::x86_64;
} }

View File

@ -95,19 +95,24 @@
// CHECK-DEPRECATED: argument '-fbounds-checking' is deprecated, use '-fsanitize=bounds' instead // CHECK-DEPRECATED: argument '-fbounds-checking' is deprecated, use '-fsanitize=bounds' instead
// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-NO-PIE // RUN: %clang -target x86_64-linux-gnu -fsanitize=thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-NO-PIE
// CHECK-TSAN-NO-PIE: invalid argument '-fsanitize=thread' only allowed with '-pie' // CHECK-TSAN-NO-PIE: "-mrelocation-model" "pic" "-pic-level" "2" "-pie-level" "2"
// CHECK-TSAN-NO-PIE: "-pie"
// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-MSAN-NO-PIE // RUN: %clang -target x86_64-linux-gnu -fsanitize=memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-MSAN-NO-PIE
// CHECK-MSAN-NO-PIE: invalid argument '-fsanitize=memory' only allowed with '-pie' // CHECK-MSAN-NO-PIE: "-mrelocation-model" "pic" "-pic-level" "2" "-pie-level" "2"
// CHECK-MSAN-NO-PIE: "-pie"
// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-address-zero-base-shadow %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-ZERO-BASE-SHADOW-NO-PIE // RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-address-zero-base-shadow %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-ZERO-BASE-SHADOW-NO-PIE
// CHECK-ASAN-ZERO-BASE-SHADOW-NO-PIE: invalid argument '-fsanitize-address-zero-base-shadow' only allowed with '-pie' // CHECK-ASAN-ZERO-BASE-SHADOW-NO-PIE: "-mrelocation-model" "pic" "-pic-level" "2" "-pie-level" "2"
// CHECK-ASAN-ZERO-BASE-SHADOW-NO-PIE: "-pie"
// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-address-zero-base-shadow -fno-sanitize-address-zero-base-shadow %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-ZERO-BASE-SHADOW-CANCEL // RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-address-zero-base-shadow -fno-sanitize-address-zero-base-shadow %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-ZERO-BASE-SHADOW-CANCEL
// CHECK-ASAN-ZERO-BASE-SHADOW-CANCEL-NOT: '-fsanitize-address-zero-base-shadow' only allowed with '-pie' // CHECK-ASAN-ZERO-BASE-SHADOW-CANCEL-NOT: "-mrelocation-model" "pic" "-pic-level" "2" "-pie-level" "2"
// CHECK-ASAN-ZERO-BASE-SHADOW-CANCEL-NOT: "-pie"
// RUN: %clang -target arm-linux-androideabi -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ANDROID-ASAN-NO-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: AddressSanitizer on Android requires '-pie' // CHECK-ANDROID-ASAN-NO-PIE: "-mrelocation-model" "pic" "-pic-level" "2" "-pie-level" "2"
// CHECK-ANDROID-ASAN-NO-PIE: "-pie"
// RUN: %clang -target x86_64-linux-gnu %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RECOVER // RUN: %clang -target x86_64-linux-gnu %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RECOVER
// RUN: %clang -target x86_64-linux-gnu %s -fsanitize-recover -### 2>&1 | FileCheck %s --check-prefix=CHECK-RECOVER // RUN: %clang -target x86_64-linux-gnu %s -fsanitize-recover -### 2>&1 | FileCheck %s --check-prefix=CHECK-RECOVER