| // Copyright 2022 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. |
| |
| #include "src/sys/fuzzing/framework/testing/coverage.h" |
| |
| #include <lib/syslog/cpp/macros.h> |
| #include <zircon/status.h> |
| |
| namespace fuzzing { |
| |
| FakeCoverage::FakeCoverage(ExecutorPtr executor) |
| : collector_(this), provider_(this), executor_(executor) {} |
| |
| fidl::InterfaceRequestHandler<Publisher> FakeCoverage::GetPublisherHandler() { |
| return [this](fidl::InterfaceRequest<Publisher> request) { |
| auto handler = GetCollectorHandler(); |
| // See target/instrumented-process.cc. |
| // This fakes the protocol recasting performed by test_manager's `fuzz_coverage` component. |
| handler(fidl::InterfaceRequest<CoverageDataCollector>(request.TakeChannel())); |
| }; |
| } |
| |
| fidl::InterfaceRequestHandler<CoverageDataCollector> FakeCoverage::GetCollectorHandler() { |
| return [this](fidl::InterfaceRequest<CoverageDataCollector> request) { |
| if (auto status = collector_.Bind(request.TakeChannel(), executor_->dispatcher()); |
| status != ZX_OK) { |
| FX_LOGS(ERROR) << "Failed to bind fuchsia.fuzzer.CoverageDataCollector request: " |
| << zx_status_get_string(status); |
| } |
| }; |
| } |
| |
| fidl::InterfaceRequestHandler<CoverageDataProvider> FakeCoverage::GetProviderHandler() { |
| return [this](fidl::InterfaceRequest<CoverageDataProvider> request) { |
| if (auto status = provider_.Bind(std::move(request), executor_->dispatcher()); |
| status != ZX_OK) { |
| FX_LOGS(ERROR) << "Failed to bind fuchsia.fuzzer.CoverageDataProvider request: " |
| << zx_status_get_string(status); |
| } |
| }; |
| } |
| |
| void FakeCoverage::Initialize(InstrumentedProcess instrumented, InitializeCallback callback) { |
| auto coverage_data = CoverageData::WithInstrumented(std::move(instrumented)); |
| if (auto status = pipe_.Send(std::move(coverage_data)); status != ZX_OK) { |
| FX_LOGS(ERROR) << "Failed to send instrumented process to provider: " |
| << zx_status_get_string(status); |
| return; |
| } |
| callback(CopyOptions(options_)); |
| } |
| |
| void FakeCoverage::AddLlvmModule(zx::vmo inline_8bit_counters, AddLlvmModuleCallback callback) { |
| auto coverage_data = CoverageData::WithInline8bitCounters(std::move(inline_8bit_counters)); |
| if (auto status = pipe_.Send(std::move(coverage_data)); status != ZX_OK) { |
| FX_LOGS(ERROR) << "Failed to send inline 8-bit counters to provider: " |
| << zx_status_get_string(status); |
| return; |
| } |
| callback(); |
| } |
| |
| void FakeCoverage::SetOptions(Options options) { options_ = std::move(options); } |
| |
| void FakeCoverage::GetCoverageData(GetCoverageDataCallback callback) { |
| auto task = pipe_.Receive() |
| .and_then([callback = std::move(callback)]( |
| CoverageData& coverage_data) mutable -> Result<> { |
| callback(std::move(coverage_data)); |
| return fpromise::ok(); |
| }) |
| .wrap_with(scope_); |
| executor_->schedule_task(std::move(task)); |
| } |
| |
| } // namespace fuzzing |