Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 26 additions & 23 deletions src/sanitizers.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,26 @@ The rustc compiler contains support for following sanitizers:
* [Hardware-assisted AddressSanitizer][clang-hwasan] a tool similar to
AddressSanitizer but based on partial hardware assistance.
* [KernelControlFlowIntegrity][clang-kcfi] LLVM Kernel Control Flow Integrity
(KCFI) provides forward-edge control flow protection for operating systems
kernels.
(KCFI) provides forward-edge control flow protection for operating systems kernels.
* [LeakSanitizer][clang-lsan] a run-time memory leak detector.
* [MemorySanitizer][clang-msan] a detector of uninitialized reads.
* [ThreadSanitizer][clang-tsan] a fast data race detector.

## How to use the sanitizers?

To enable a sanitizer compile with `-Z sanitizer=...` option, where value is one
of `address`, `cfi`, `hwaddress`, `kcfi`, `leak`, `memory` or `thread`. For more
details on how to use sanitizers please refer to the sanitizer flag in [the
unstable book](https://doc.rust-lang.org/unstable-book/).
of `address`, `cfi`, `hwaddress`, `kcfi`, `leak`, `memory` or `thread`.
For more details on how to use sanitizers,
please refer to the sanitizer flag in [The Unstable Book].

[The Unstable Book]: https://doc.rust-lang.org/unstable-book

## How are sanitizers implemented in rustc?

The implementation of sanitizers (except CFI) relies almost entirely on LLVM.
The rustc is an integration point for LLVM compile time instrumentation passes
and runtime libraries. Highlight of the most important aspects of the
implementation:
and runtime libraries.
Highlight of the most important aspects of the implementation:

* The sanitizer runtime libraries are part of the [compiler-rt] project, and
[will be built][sanitizer-build] on [supported targets][sanitizer-targets]
Expand All @@ -43,23 +44,26 @@ implementation:

* During LLVM code generation, the functions intended for instrumentation are
[marked][sanitizer-attribute] with appropriate LLVM attribute:
`SanitizeAddress`, `SanitizeHWAddress`, `SanitizeMemory`, or
`SanitizeThread`. By default all functions are instrumented, but this
`SanitizeAddress`, `SanitizeHWAddress`, `SanitizeMemory`, or `SanitizeThread`.
By default, all functions are instrumented, but this
behaviour can be changed with `#[sanitize(xyz = "on|off|<other>")]`.

* The decision whether to perform instrumentation or not is possible only at a
function granularity. In the cases were those decision differ between
functions it might be necessary to inhibit inlining, both at [MIR
function granularity.
In the cases were those decision differ between
functions, it might be necessary to inhibit inlining, both at [MIR
level][inline-mir] and [LLVM level][inline-llvm].

* The LLVM IR generated by rustc is instrumented by [dedicated LLVM
passes][sanitizer-pass], different for each sanitizer. Instrumentation
passes are invoked after optimization passes.
passes][sanitizer-pass], different for each sanitizer.
Instrumentation passes are invoked after optimization passes.

* When producing an executable, the sanitizer specific runtime library is
[linked in][sanitizer-link]. The libraries are searched for in the target
libdir. First relative to the overridden system root and subsequently
relative to the default system root. Fall-back to the default system root
[linked in][sanitizer-link].
The libraries are searched for in the target libdir.
First, the search is relative to the overridden system root, and subsequently,
it is relative to the default system root.
Fall-back to the default system root
ensures that sanitizer runtimes remain available when using sysroot overrides
constructed by cargo `-Z build-std` or xargo.

Expand All @@ -80,21 +84,20 @@ Sanitizers are validated by code generation tests in
[`tests/ui/sanitizer/`][test-ui] directory.

Testing sanitizer functionality requires the sanitizer runtimes (built when
`sanitizer = true` in `bootstrap.toml`) and target providing support for particular
sanitizer. When sanitizer is unsupported on given target, sanitizers tests will
be ignored. This behaviour is controlled by compiletest `needs-sanitizer-*`
directives.
`sanitizer = true` in `bootstrap.toml`) and target providing support for particular a sanitizer.
When a sanitizer is unsupported on a given target, sanitizer tests will be ignored.
This behaviour is controlled by compiletest `needs-sanitizer-*` directives.

[test-cg]: https://github.com/rust-lang/rust/tree/HEAD/tests/codegen-llvm
[test-ui]: https://github.com/rust-lang/rust/tree/HEAD/tests/ui/sanitizer

## Enabling sanitizer on a new target
## Enabling a sanitizer on a new target

To enable a sanitizer on a new target which is already supported by LLVM:

1. Include the sanitizer in the list of `supported_sanitizers` in [the target
definition][target-definition]. `rustc --target .. -Zsanitizer=..` should now
recognize sanitizer as supported.
definition][target-definition].
`rustc --target .. -Zsanitizer=..` should now recognize the sanitizer as supported.
2. [Build the runtime for the target and include it in the libdir.][sanitizer-targets]
3. [Teach compiletest that your target now supports the sanitizer.][compiletest-definition]
Tests marked with `needs-sanitizer-*` should now run on the target.
Expand Down
Loading