Skip to content

Commit bc20486

Browse files
usama54321Mariusz Borsa
authored and
Mariusz Borsa
committed
[Sanitizer] Add new flag -sanitize-stable-abi flag to link against the
new sanitiers stable ABI in compiler-rt. Compiler-rt recently introduced a stable ABI for sanitizers. This patch adds a flag to pass this flag to swift-frontend during compilation and clang at link time to link against the new stable ABI. rdar://118997873
1 parent d5c60fe commit bc20486

File tree

6 files changed

+53
-2
lines changed

6 files changed

+53
-2
lines changed

Sources/SwiftDriver/Driver/Driver.swift

+16-2
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,8 @@ public struct Driver {
841841

842842
Self.validateSanitizerAddressUseOdrIndicatorFlag(&parsedOptions, diagnosticEngine: diagnosticsEngine, addressSanitizerEnabled: enabledSanitizers.contains(.address))
843843

844+
Self.validateSanitizeStableABI(&parsedOptions, diagnosticEngine: diagnosticsEngine, addressSanitizerEnabled: enabledSanitizers.contains(.address))
845+
844846
Self.validateSanitizerRecoverArgValues(&parsedOptions, diagnosticEngine: diagnosticsEngine, enabledSanitizers: enabledSanitizers)
845847

846848
Self.validateSanitizerCoverageArgs(&parsedOptions,
@@ -2439,14 +2441,15 @@ extension Driver {
24392441
continue
24402442
}
24412443

2444+
let stableAbi = sanitizer == .address && parsedOptions.contains(.sanitizeStableAbiEQ)
24422445
// Support is determined by existence of the sanitizer library.
24432446
// FIXME: Should we do this? This prevents cross-compiling with sanitizers
24442447
// enabled.
24452448
var sanitizerSupported = try toolchain.runtimeLibraryExists(
2446-
for: sanitizer,
2449+
for: stableAbi ? .address_stable_abi : sanitizer,
24472450
targetInfo: targetInfo,
24482451
parsedOptions: &parsedOptions,
2449-
isShared: sanitizer != .fuzzer
2452+
isShared: sanitizer != .fuzzer && !stableAbi
24502453
)
24512454

24522455
if sanitizer == .thread {
@@ -3062,6 +3065,17 @@ extension Driver {
30623065
}
30633066
}
30643067

3068+
private static func validateSanitizeStableABI(
3069+
_ parsedOptions: inout ParsedOptions,
3070+
diagnosticEngine: DiagnosticsEngine,
3071+
addressSanitizerEnabled: Bool
3072+
) {
3073+
if (parsedOptions.hasArgument(.sanitizeStableAbiEQ) && !addressSanitizerEnabled) {
3074+
diagnosticEngine.emit(
3075+
.warning_option_requires_sanitizer(currentOption: .sanitizeStableAbiEQ, currentOptionValue: "", sanitizerRequired: .address))
3076+
}
3077+
}
3078+
30653079
/// Validates the set of `-sanitize-recover={sanitizer}` arguments
30663080
private static func validateSanitizerRecoverArgValues(
30673081
_ parsedOptions: inout ParsedOptions,

Sources/SwiftDriver/Jobs/DarwinToolchain+LinkerSupport.swift

+4
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,10 @@ extension DarwinToolchain {
209209
.sorted() // Sort so we get a stable, testable order
210210
.joined(separator: ",")
211211
commandLine.appendFlag("-fsanitize=\(sanitizerNames)")
212+
213+
if parsedOptions.contains(.sanitizeStableAbiEQ) {
214+
commandLine.appendFlag("-fsanitize-stable-abi")
215+
}
212216
}
213217

214218
if parsedOptions.contains(.embedBitcode) {

Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift

+3
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,9 @@ extension Driver {
220220
try commandLine.appendLast(.sanitizeEQ, from: &parsedOptions)
221221
try commandLine.appendLast(.sanitizeRecoverEQ, from: &parsedOptions)
222222
try commandLine.appendLast(.sanitizeAddressUseOdrIndicator, from: &parsedOptions)
223+
if isFrontendArgSupported(.sanitizeStableAbiEQ) {
224+
try commandLine.appendLast(.sanitizeStableAbiEQ, from: &parsedOptions)
225+
}
223226
try commandLine.appendLast(.sanitizeCoverageEQ, from: &parsedOptions)
224227
try commandLine.appendLast(.static, from: &parsedOptions)
225228
try commandLine.appendLast(.swiftVersion, from: &parsedOptions)

Sources/SwiftDriver/Utilities/Sanitizer.swift

+4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ public enum Sanitizer: String, Hashable {
1616
/// Address sanitizer (ASan)
1717
case address
1818

19+
// Address sanitizer Stable ABI (ASan)
20+
case address_stable_abi
21+
1922
/// Thread sanitizer (TSan)
2023
case thread
2124

@@ -34,6 +37,7 @@ public enum Sanitizer: String, Hashable {
3437
var libraryName: String {
3538
switch self {
3639
case .address: return "asan"
40+
case .address_stable_abi: return "asan_abi"
3741
case .thread: return "tsan"
3842
case .undefinedBehavior: return "ubsan"
3943
case .fuzzer: return "fuzzer"

Sources/SwiftOptions/Options.swift

+2
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,7 @@ extension Option {
696696
public static let sanitizeAddressUseOdrIndicator: Option = Option("-sanitize-address-use-odr-indicator", .flag, attributes: [.helpHidden, .frontend, .noInteractive], helpText: "When using AddressSanitizer enable ODR indicator globals to avoid false ODR violation reports in partially sanitized programs at the cost of an increase in binary size")
697697
public static let sanitizeCoverageEQ: Option = Option("-sanitize-coverage=", .commaJoined, attributes: [.frontend, .noInteractive], metaVar: "<type>", helpText: "Specify the type of coverage instrumentation for Sanitizers and additional options separated by commas")
698698
public static let sanitizeRecoverEQ: Option = Option("-sanitize-recover=", .commaJoined, attributes: [.frontend, .noInteractive], metaVar: "<check>", helpText: "Specify which sanitizer runtime checks (see -sanitize=) will generate instrumentation that allows error recovery. Listed checks should be comma separated. Default behavior is to not allow error recovery.")
699+
public static let sanitizeStableAbiEQ: Option = Option("-sanitize-stable-abi", .flag, attributes: [.frontend, .noInteractive], helpText: "ABI instrumentation for sanitizer runtime.")
699700
public static let sanitizeEQ: Option = Option("-sanitize=", .commaJoined, attributes: [.frontend, .noInteractive], metaVar: "<check>", helpText: "Turn on runtime checks for erroneous behavior.")
700701
public static let saveOptimizationRecordPasses: Option = Option("-save-optimization-record-passes", .separate, attributes: [.frontend], metaVar: "<regex>", helpText: "Only include passes which match a specified regular expression in the generated optimization record (by default, include all passes)")
701702
public static let saveOptimizationRecordPath: Option = Option("-save-optimization-record-path", .separate, attributes: [.frontend, .argumentIsPath], helpText: "Specify the file name of any generated optimization record")
@@ -1523,6 +1524,7 @@ extension Option {
15231524
Option.sanitizeAddressUseOdrIndicator,
15241525
Option.sanitizeCoverageEQ,
15251526
Option.sanitizeRecoverEQ,
1527+
Option.sanitizeStableAbiEQ,
15261528
Option.sanitizeEQ,
15271529
Option.saveOptimizationRecordPasses,
15281530
Option.saveOptimizationRecordPath,

Tests/SwiftDriverTests/SwiftDriverTests.swift

+24
Original file line numberDiff line numberDiff line change
@@ -2781,6 +2781,30 @@ final class SwiftDriverTests: XCTestCase {
27812781
}
27822782
}
27832783

2784+
func testSanitizeStableAbi() throws {
2785+
var driver = try Driver(args: ["swiftc", "-sanitize=address", "-sanitize-stable-abi", "Test.swift"])
2786+
guard driver.isFrontendArgSupported(.sanitizeStableAbiEQ) else {
2787+
return
2788+
}
2789+
2790+
do {
2791+
let plannedJobs = try driver.planBuild().removingAutolinkExtractJobs()
2792+
XCTAssertEqual(plannedJobs.count, 2)
2793+
XCTAssertEqual(plannedJobs[0].kind, .compile)
2794+
XCTAssert(plannedJobs[0].commandLine.contains(.flag("-sanitize=address")))
2795+
XCTAssert(plannedJobs[0].commandLine.contains(.flag("-sanitize-stable-abi")))
2796+
2797+
XCTAssert(plannedJobs[1].commandLine.contains(.flag("-fsanitize=address")))
2798+
XCTAssert(plannedJobs[1].commandLine.contains(.flag("-fsanitize-stable-abi")))
2799+
}
2800+
2801+
do {
2802+
try assertDriverDiagnostics(args: ["swiftc","-sanitize-stable-abi", "Test.swift"]) {
2803+
$1.expect(.warning("option '-sanitize-stable-abi' has no effect when 'address' sanitizer is disabled. Use -sanitize=address to enable the sanitizer"))
2804+
}
2805+
}
2806+
}
2807+
27842808
func testADDITIONAL_SWIFT_DRIVER_FLAGS() throws {
27852809
var env = ProcessEnv.vars
27862810
env["ADDITIONAL_SWIFT_DRIVER_FLAGS"] = "-Xfrontend -unknown1 -Xfrontend -unknown2"

0 commit comments

Comments
 (0)