diff --git a/CMakeLists.txt b/CMakeLists.txt index 7dcda42946cad..e95b84a3ff5c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -575,6 +575,17 @@ set(SWIFT_DARWIN_XCRUN_TOOLCHAIN "XcodeDefault" CACHE STRING set(SWIFT_DARWIN_STDLIB_INSTALL_NAME_DIR "/usr/lib/swift" CACHE STRING "The directory of the install_name for standard library dylibs") +# +# User-configurable OpenBSD-specific options. +# + +option(SWIFT_OPENBSD_BTCFI + "Emit branch target identification instructions and sign return addresses when available" + FALSE) +if(SWIFT_OPENBSD_BTCFI) + add_definitions("-DSWIFT_OPENBSD_BTCFI") +endif() + # We don't want to use the same install_name_dir as the standard library which # will be installed in /usr/lib/swift. These private libraries should continue # to use @rpath for now. diff --git a/include/swift/Basic/Platform.h b/include/swift/Basic/Platform.h index 2a1b984087e70..94515f6dbd890 100644 --- a/include/swift/Basic/Platform.h +++ b/include/swift/Basic/Platform.h @@ -71,6 +71,10 @@ namespace swift { /// (eg. in /usr/lib/swift). bool tripleRequiresRPathForSwiftLibrariesInOS(const llvm::Triple &triple); + /// Returns true if the given triple represents a version of OpenBSD + /// that enforces BTCFI by default. + bool tripleBTCFIByDefaultInOpenBSD(const llvm::Triple &triple); + /// Returns the platform name for a given target triple. /// /// For example, the iOS simulator has the name "iphonesimulator", while real diff --git a/lib/Basic/Platform.cpp b/lib/Basic/Platform.cpp index 7778a3784472e..4b6b827ef6594 100644 --- a/lib/Basic/Platform.cpp +++ b/lib/Basic/Platform.cpp @@ -140,6 +140,10 @@ bool swift::tripleRequiresRPathForSwiftLibrariesInOS( return false; } +bool swift::tripleBTCFIByDefaultInOpenBSD(const llvm::Triple &triple) { + return triple.isOSOpenBSD() && triple.getArch() == llvm::Triple::aarch64; +} + DarwinPlatformKind swift::getDarwinPlatformKind(const llvm::Triple &triple) { if (triple.isiOS()) { if (triple.isTvOS()) { diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp index 40ad9f26ff9ec..53f3a219d7205 100644 --- a/lib/Basic/TargetInfo.cpp +++ b/lib/Basic/TargetInfo.cpp @@ -171,6 +171,16 @@ void printTripleInfo(const CompilerInvocation &invocation, out << " \"compatibilityLibraries\": [ ],\n"; } + if (tripleBTCFIByDefaultInOpenBSD(triple)) { +#if SWIFT_OPENBSD_BTCFI + out << " \"openbsdBTCFIEnabled\": true,\n"; +#else + out << " \"openbsdBTCFIEnabled\": false,\n"; +#endif + } else { + out << " \"openbsdBTCFIEnabled\": false,\n"; + } + out << " \"librariesRequireRPath\": " << (tripleRequiresRPathForSwiftLibrariesInOS(triple) ? "true" : "false") << "\n"; diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 6a7ae73498e00..739e26953bb8d 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -205,12 +205,14 @@ void ToolChain::addCommonFrontendArgs(const OutputInfo &OI, } if (Triple.isOSOpenBSD() && Triple.getArch() == llvm::Triple::aarch64) { +#ifdef SWIFT_OPENBSD_BTCFI arguments.push_back("-Xcc"); arguments.push_back("-Xclang=-mbranch-target-enforce"); arguments.push_back("-Xcc"); arguments.push_back("-Xclang=-msign-return-address=non-leaf"); arguments.push_back("-Xcc"); arguments.push_back("-Xclang=-msign-return-address-key=a_key"); +#endif } if (inputArgs.getLastArg(options::OPT_experimental_serialize_debug_info)) { diff --git a/lib/Driver/UnixToolChains.cpp b/lib/Driver/UnixToolChains.cpp index e016d041199d6..a8a934da16d2e 100644 --- a/lib/Driver/UnixToolChains.cpp +++ b/lib/Driver/UnixToolChains.cpp @@ -211,6 +211,15 @@ toolchains::GenericUnix::constructInvocation(const DynamicLinkJobAction &job, #endif } + if (tripleBTCFIByDefaultInOpenBSD(getTriple())) { +#ifndef SWIFT_OPENBSD_BTCFI + Arguments.push_back("-Xlinker"); + Arguments.push_back("-z"); + Arguments.push_back("-Xlinker"); + Arguments.push_back("nobtcfi"); +#endif + } + // Configure the toolchain. if (const Arg *A = context.Args.getLastArg(options::OPT_tools_directory)) { StringRef toolchainPath(A->getValue()); diff --git a/utils/build-script-impl b/utils/build-script-impl index ab0c488a861d5..b19e6a3fdbf09 100755 --- a/utils/build-script-impl +++ b/utils/build-script-impl @@ -124,6 +124,9 @@ KNOWN_SETTINGS=( darwin-toolchain-require-use-os-runtime "0" "When setting up a plist for a toolchain, require the users of the toolchain to link against the OS instead of the packaged toolchain runtime. 0 for false, 1 for true" darwin-xcrun-toolchain "default" "the name of the toolchain to use on Darwin" + ## OpenBSD options + openbsd-btcfi "" "enables BTCFI when possible. May cause stability problems." + ## Runtime options min-runtime-version "" "Used to specify the minimum host runtime version when building the compiler on non-Darwin platforms" @@ -877,6 +880,12 @@ function set_build_options_for_host() { swift_cmake_options+=( -DCOVERAGE_DB="${COVERAGE_DB}" ) + + if [[ "${OPENBSD_BTCFI}" ]]; then + swift_cmake_options+=( + -DSWIFT_OPENBSD_BTCFI:BOOL=TRUE + ) + fi } function configure_default_options() { @@ -1383,7 +1392,9 @@ function swift_c_flags() { echo -n " -D_GNU_SOURCE -DHAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME" ;; openbsd-aarch64) - echo -n " -Xclang=-msign-return-address=non-leaf -Xclang=-msign-return-address-key=a_key -Xclang=-mbranch-target-enforce" + if [[ "${OPENBSD_BTCFI}" ]]; then + echo -n " -Xclang=-msign-return-address=non-leaf -Xclang=-msign-return-address-key=a_key -Xclang=-mbranch-target-enforce" + fi ;; esac }