Skip to content

Commit

Permalink
Merge pull request swiftlang#1434 from apple/asan
Browse files Browse the repository at this point in the history
[asan] Add basic support for Address Sanitizer function instrumentation
  • Loading branch information
AnnaZaks committed Mar 1, 2016
2 parents cc224e1 + 2110235 commit 767d9ca
Show file tree
Hide file tree
Showing 18 changed files with 359 additions and 30 deletions.
5 changes: 5 additions & 0 deletions include/swift/AST/DiagnosticsFrontend.def
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ ERROR(error_unsupported_target_os, none,
ERROR(error_unsupported_target_arch, none,
"unsupported target architecture: '%0'", (StringRef))

ERROR(error_unsupported_opt_for_target, none,
"unsupported option '%0' for target '%1'", (StringRef, StringRef))

ERROR(cannot_open_file,none,
"cannot open file '%0' (%1)", (StringRef, StringRef))
ERROR(cannot_open_serialized_file,none,
Expand All @@ -67,6 +70,8 @@ ERROR(error_unknown_arg,none,
"unknown argument: '%0'", (StringRef))
ERROR(error_invalid_arg_value,none,
"invalid value '%1' in '%0'", (StringRef, StringRef))
ERROR(error_unsupported_option_argument,none,
"unsupported argument '%1' to option '%0'", (StringRef, StringRef))
ERROR(error_immediate_mode_missing_stdlib,none,
"could not load the swift standard library", ())
ERROR(error_immediate_mode_missing_library,none,
Expand Down
7 changes: 6 additions & 1 deletion include/swift/AST/IRGenOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#define SWIFT_AST_IRGENOPTIONS_H

#include "swift/AST/LinkLibrary.h"
#include "swift/Basic/Sanitizers.h"
#include <string>
#include <vector>

Expand Down Expand Up @@ -87,6 +88,9 @@ class IRGenOptions {
/// Whether or not to run optimization passes.
unsigned Optimize : 1;

/// Which sanitizer is turned on.
SanitizerKind Sanitize : 2;

/// Whether we should emit debug info.
IRGenDebugInfoKind DebugInfoKind : 2;

Expand Down Expand Up @@ -153,7 +157,8 @@ class IRGenOptions {
unsigned UseIncrementalLLVMCodeGen : 1;

IRGenOptions() : OutputKind(IRGenOutputKind::LLVMAssembly), Verify(true),
Optimize(false), DebugInfoKind(IRGenDebugInfoKind::None),
Optimize(false), Sanitize(SanitizerKind::None),
DebugInfoKind(IRGenDebugInfoKind::None),
UseJIT(false), DisableLLVMOptzns(false),
DisableLLVMARCOpts(false), DisableLLVMSLPVectorizer(false),
DisableFPElim(true), Playground(false),
Expand Down
14 changes: 14 additions & 0 deletions include/swift/Basic/Platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,17 @@ namespace llvm {
}

namespace swift {

enum class DarwinPlatformKind : unsigned {
MacOS,
IPhoneOS,
IPhoneOSSimulator,
TvOS,
TvOSSimulator,
WatchOS,
WatchOSSimulator
};

/// Returns true if the given triple represents iOS running in a simulator.
bool tripleIsiOSSimulator(const llvm::Triple &triple);

Expand All @@ -43,6 +54,9 @@ namespace swift {
/// If the triple does not correspond to a known platform, the empty string is
/// returned.
StringRef getPlatformNameForTriple(const llvm::Triple &triple);

/// Returns the platform Kind for Darwin triples.
DarwinPlatformKind getDarwinPlatformKind(const llvm::Triple &triple);
}

#endif // SWIFT_BASIC_PLATFORM_H
Expand Down
24 changes: 24 additions & 0 deletions include/swift/Basic/Sanitizers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//===----- Sanitizers.h - Helpers related to sanitizers --------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===---------------------------------------------------------------------===//

#ifndef SWIFT_BASIC_SANITIZERS_H
#define SWIFT_BASIC_SANITIZERS_H

namespace swift {

enum class SanitizerKind : unsigned {
None = 0,
Address,
};

}
#endif // SWIFT_BASIC_SANITIZERS_H
3 changes: 3 additions & 0 deletions include/swift/Driver/Driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include "swift/AST/IRGenOptions.h"
#include "swift/Basic/LLVM.h"
#include "swift/Basic/Sanitizers.h"
#include "swift/Driver/Types.h"
#include "swift/Driver/Util.h"
#include "llvm/ADT/DenseMap.h"
Expand Down Expand Up @@ -112,6 +113,8 @@ class OutputInfo {
/// The path to the SDK against which to build.
/// (If empty, this implies no SDK.)
std::string SDKPath;

enum SanitizerKind SelectedSanitizer;
};

class Driver {
Expand Down
4 changes: 4 additions & 0 deletions include/swift/Option/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -452,4 +452,8 @@ def enable_testing : Flag<["-"], "enable-testing">,
Flags<[FrontendOption, NoInteractiveOption, HelpHidden]>,
HelpText<"Allows this module's internal API to be accessed for testing">;

def sanitize_EQ : CommaJoined<["-"], "sanitize=">,
Flags<[FrontendOption, NoInteractiveOption]>, MetaVarName<"<check>">,
HelpText<"Turn on runtime checks for erroneous behavior.">;

include "FrontendOptions.td"
31 changes: 31 additions & 0 deletions include/swift/Option/SanitizerOptions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//===----- SanitizerOptions.h - Helpers related to sanitizers --*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===---------------------------------------------------------------------===//

#ifndef SWIFT_OPTIONS_SANITIZER_OPTIONS_H
#define SWIFT_OPTIONS_SANITIZER_OPTIONS_H

#include "swift/Basic/Sanitizers.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Option/Arg.h"

namespace swift {
class DiagnosticEngine;

/// \brief Parses a -sanitize= argument's values.
///
/// \param Diag If non null, the argument is used to diagnose invalid values.
/// \return Returns a SanitizerKind.
SanitizerKind parseSanitizerArgValues(const llvm::opt::Arg *A,
const llvm::Triple &Triple,
DiagnosticEngine &Diag);
}
#endif // SWIFT_OPTIONS_SANITIZER_OPTIONS_H
41 changes: 34 additions & 7 deletions lib/Basic/Platform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,27 +39,54 @@ bool swift::tripleIsAnySimulator(const llvm::Triple &triple) {
tripleIsAppleTVSimulator(triple);
}

StringRef swift::getPlatformNameForTriple(const llvm::Triple &triple) {
DarwinPlatformKind swift::getDarwinPlatformKind(const llvm::Triple &triple) {
if (triple.isiOS()) {
if (triple.isTvOS()) {
if (tripleIsAppleTVSimulator(triple))
return "appletvsimulator";
return "appletvos";
return DarwinPlatformKind::TvOSSimulator;
return DarwinPlatformKind::TvOS;
}

if (tripleIsiOSSimulator(triple))
return "iphonesimulator";
return "iphoneos";
return DarwinPlatformKind::IPhoneOSSimulator;
return DarwinPlatformKind::IPhoneOS;
}

if (triple.isWatchOS()) {
if (tripleIsWatchSimulator(triple))
return "watchsimulator";
return "watchos";
return DarwinPlatformKind::WatchOSSimulator;
return DarwinPlatformKind::WatchOS;
}

if (triple.isMacOSX())
return DarwinPlatformKind::MacOS;

llvm_unreachable("Unsupported Darwin platform");
}

static StringRef getPlatformNameForDarwin(const DarwinPlatformKind platform) {
switch (platform) {
case DarwinPlatformKind::MacOS:
return "macosx";
case DarwinPlatformKind::IPhoneOS:
return "iphoneos";
case DarwinPlatformKind::IPhoneOSSimulator:
return "iphonesimulator";
case DarwinPlatformKind::TvOS:
return "appletvos";
case DarwinPlatformKind::TvOSSimulator:
return "appletvsimulator";
case DarwinPlatformKind::WatchOS:
return "watchos";
case DarwinPlatformKind::WatchOSSimulator:
return "watchsimulator";
}
llvm_unreachable("Unsupported Darwin platform");
}

StringRef swift::getPlatformNameForTriple(const llvm::Triple &triple) {
if (triple.isOSDarwin())
return getPlatformNameForDarwin(getDarwinPlatformKind(triple));

if (triple.isOSLinux())
return "linux";
Expand Down
43 changes: 24 additions & 19 deletions lib/ClangImporter/ClangImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,27 @@ void ClangImporter::clearTypeResolver() {
#define SHIMS_INCLUDE_FLAG "-I"
#endif

static StringRef
getMinVersionOptNameForDarwinTriple(const llvm::Triple &triple) {
switch(getDarwinPlatformKind(triple)) {
case DarwinPlatformKind::MacOS:
return "-mmacosx-version-min=";
case DarwinPlatformKind::IPhoneOS:
return "-mios-version-min=";
case DarwinPlatformKind::IPhoneOSSimulator:
return "-mios-simulator-version-min=";
case DarwinPlatformKind::TvOS:
return "-mtvos-version-min=";
case DarwinPlatformKind::TvOSSimulator:
return "-mtvos-simulator-version-min=";
case DarwinPlatformKind::WatchOS:
return "-mwatchos-version-min=";
case DarwinPlatformKind::WatchOSSimulator:
return "-mwatchos-simulator-version-min=";
}
llvm_unreachable("Unsupported Darwin platform");
}

static void
getNormalInvocationArguments(std::vector<std::string> &invocationArgStrs,
ASTContext &ctx,
Expand Down Expand Up @@ -342,31 +363,15 @@ getNormalInvocationArguments(std::vector<std::string> &invocationArgStrs,
if (triple.isOSDarwin()) {
std::string minVersionBuf;
llvm::raw_string_ostream minVersionOpt{minVersionBuf};
minVersionOpt << getMinVersionOptNameForDarwinTriple(triple);

unsigned major, minor, micro;
if (triple.isiOS()) {
bool isiOSSimulator = swift::tripleIsiOSSimulator(triple);
if (triple.isTvOS()) {
if (isiOSSimulator)
minVersionOpt << "-mtvos-simulator-version-min=";
else
minVersionOpt << "-mtvos-version-min=";
} else {
if (isiOSSimulator)
minVersionOpt << "-mios-simulator-version-min=";
else
minVersionOpt << "-mios-version-min=";
}

triple.getiOSVersion(major, minor, micro);
} else if(triple.isWatchOS()) {
if (tripleIsWatchSimulator(triple))
minVersionOpt << "-mwatchos-simulator-version-min=";
else
minVersionOpt << "-mwatchos-version-min=";
triple.getOSVersion(major, minor, micro);
triple.getWatchOSVersion(major, minor, micro);
} else {
assert(triple.isMacOSX());
minVersionOpt << "-mmacosx-version-min=";
triple.getMacOSXVersion(major, minor, micro);
}
minVersionOpt << clang::VersionTuple(major, minor, micro);
Expand Down
5 changes: 5 additions & 0 deletions lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "swift/Driver/OutputFileMap.h"
#include "swift/Driver/ToolChain.h"
#include "swift/Option/Options.h"
#include "swift/Option/SanitizerOptions.h"
#include "swift/Parse/Lexer.h"
#include "swift/Config.h"
#include "llvm/ADT/DenseSet.h"
Expand Down Expand Up @@ -1099,6 +1100,10 @@ void Driver::buildOutputInfo(const ToolChain &TC, const DerivedArgList &Args,
}
}
}

OI.SelectedSanitizer = SanitizerKind::None;
if (const Arg *A = Args.getLastArg(options::OPT_sanitize_EQ))
OI.SelectedSanitizer = parseSanitizerArgValues(A, TC.getTriple(), Diags);
}

void Driver::buildActions(const ToolChain &TC,
Expand Down
Loading

0 comments on commit 767d9ca

Please sign in to comment.