| // Copyright 2021 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| library fuchsia.fuzzer; |
| |
| using zx; |
| |
| /// Collects VMOs used to share code coverage from instrumented target processes. |
| /// |
| /// The instrumented target processes act as clients to this protocol, which is implemented by |
| /// test_manager's fuzz_coverage component. The protocol coordinates feedback collection and other |
| /// diagnostics with target processes under test. The connection should be established very early in |
| /// a target process's lifecycle, i.e. before `main` begins. |
| /// |
| @discoverable |
| closed protocol CoverageDataCollector { |
| /// Registers the instrumented target process. |
| /// |
| /// This method is called once per connection to set up: |
| /// * The eventpair used to synchronize the start and end of code coverage collection. |
| /// * The process Handle used to monitor the target process for errors. |
| /// |
| /// This method must be called before the target process can call `AddLlvmModule`. |
| /// |
| /// It returns the currently set options; see `fuchsia.fuzzer.Controller/Configure`. |
| /// |
| /// Certain options determine sanitizer behaviors before `main` is called, and cannot |
| /// subsequently be changed while the target process is running. This is the root cause of the |
| /// constraint in `Controller` against modifying options during "long-running workflows", i.e |
| /// those that spawn target processes. |
| /// |
| /// The channel is closed on FIDL error. Clients should not attempt to reconnect. |
| strict Initialize(resource struct { |
| eventpair zx.Handle:EVENTPAIR; |
| process zx.Handle:PROCESS; |
| }) -> (struct { |
| options Options; |
| }); |
| |
| /// Adds a VMO with the code coverage of an LLVM module. |
| /// |
| /// The VMO used to share inline 8-bit code-coverage edge counters for a single LLVM module in |
| /// an instrumented target process. |
| /// |
| /// Its ZX_PROP_NAME property must be set, and client and server implementations must agree on |
| /// how to use it to uniquely identify the module. If the same module is added more than once by |
| /// different processes, the module identifiers must match so that the code counters can be |
| /// combined. |
| /// |
| /// Its ZX_PROP_VMO_CONTENT_SIZE property must be set to the actual number of counters present. |
| /// |
| /// It is an error to call this method without first calling |Initialize|. |
| /// |
| /// The channel is closed on FIDL error. Clients should not attempt to reconnect. |
| /// |
| /// See also: |
| /// https://clang.llvm.org/docs/SanitizerCoverage.html#inline-8bit-counters |
| strict AddInline8bitCounters(resource struct { |
| inline_8bit_counters zx.Handle:VMO; |
| }) -> (); |
| }; |
| |
| |
| /// Represents an instrumented target process under test. |
| /// |
| /// This struct wraps the eventpair and process provided to `CoverageDataCollector.Initialize` and |
| /// associates it with a unique per-`CoverageDataCollector`-client target id. |
| type InstrumentedProcess = resource struct { |
| eventpair zx.Handle:EVENTPAIR; |
| process zx.Handle:PROCESS; |
| }; |
| |
| /// Represents an instrumented target process or the code coverage it is sharing. |
| type CoverageData = resource struct { |
| // Unique per-`CoverageDataCollector`-client target id. |
| target_id uint64; |
| |
| data flexible resource union { |
| /// An instrumented target process under test. |
| 1: instrumented InstrumentedProcess; |
| |
| /// See https://clang.llvm.org/docs/SanitizerCoverage.html#inline-8bit-counters |
| 2: inline_8bit_counters zx.Handle:VMO; |
| }; |
| }; |
| |
| /// Maximum length of a vector of CoverageData structs. |
| /// |
| /// This value matches the maximum number of LLVM modules libFuzzer can track. |
| const MAX_COVERAGE_DATA uint64 = 4096; |
| |
| /// Provides the process Handles and VMOs used to share code coverage to the fuzzing engine. |
| /// |
| /// This protocol is implemented by `test_manager`'s `fuzz_coverage` component. The fuzzing engine |
| /// acts as a client, although it does not connect directly. Instead the `fuzz_test_runner` makes |
| /// the connection and passes it off to fuzzing engine on process start. It allows the engine to |
| /// retrieve the coverage-related Handles published by instrumented target processes. |
| /// |
| /// The channel is closed on FIDL error. Clients should exit and not attempt to reconnect. |
| @discoverable |
| closed protocol CoverageDataProvider { |
| /// Sets the options to be returned by `fuchsia.fuzzer.CoverageDataCollector/Initialize`. |
| strict SetOptions(struct { |
| options Options; |
| }); |
| |
| /// Provides coverage data collected from multiple processes. |
| /// |
| /// Returns a vector of `CoverageData` structs containing the information provided by clients of |
| /// `fuchsia.fuzzer.CoverageDataCollector`. This method uses the "hanging get" pattern: The |
| /// initial call will immediately return whatever data is available, up to `MAX_COVERAGE_DATA`. |
| /// If no fuzzed components have been started yet, this be an empty vector. If there are more |
| /// than `MAX_COVERAGE_DATA` elements available, the remainder are retained for subsequent |
| /// calls. If there is no more data available, subsequent calls will block until new coverage |
| /// data is available. |
| /// |
| /// The channel is closed on FIDL error. Clients should exit and not attempt to reconnect. |
| strict WatchCoverageData() -> (resource struct { |
| coverage_data vector<CoverageData>:MAX_COVERAGE_DATA; |
| }); |
| }; |