forked from OSchip/llvm-project
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:
parent
61e221f68d
commit
54d770cb1f
|
@ -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".
|
||||||
|
|
|
@ -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
|
||||||
--------------
|
--------------
|
||||||
|
|
|
@ -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'">;
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue