| // Copyright 2020 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. |
| |
| #ifndef SRC_LIB_FUZZING_FIDL_COVERAGE_H_ |
| #define SRC_LIB_FUZZING_FIDL_COVERAGE_H_ |
| |
| #include <fuchsia/fuzzer/cpp/fidl.h> |
| #include <fuchsia/mem/cpp/fidl.h> |
| #include <lib/fidl/cpp/binding_set.h> |
| #include <lib/fit/function.h> |
| #include <lib/fxl/synchronization/thread_annotations.h> |
| #include <lib/sync/completion.h> |
| #include <lib/zx/time.h> |
| #include <stddef.h> |
| #include <zircon/types.h> |
| |
| #include <map> |
| #include <mutex> |
| #include <thread> |
| #include <vector> |
| |
| #include "shared-memory.h" |
| #include "traced-instruction.h" |
| |
| namespace fuzzing { |
| namespace { |
| |
| using ::fuchsia::fuzzer::Coverage; |
| using ::fuchsia::mem::Buffer; |
| |
| } // namespace |
| |
| // Forward declaration |
| class AggregatedCoverage; |
| |
| // The Coverage service aggregates coverage information from multiple processes and passes it to the |
| // __sanitizer_cov_* interface. See also |SanitizerCovProxy|, the per-process client of the service. |
| class CoverageImpl : public Coverage { |
| public: |
| explicit CoverageImpl(AggregatedCoverage *aggregate); |
| virtual ~CoverageImpl(); |
| |
| // FIDL Methods |
| void AddInline8BitCounters(Buffer ctrs, AddInline8BitCountersCallback callback) override; |
| void AddPcTable(Buffer pcs, AddPcTableCallback callback) override; |
| void AddTraces(zx::vmo traces, AddTracesCallback callback) override; |
| |
| private: |
| // If |status| indicates an error, asks the AggregatedCoverage to close its binding and returns |
| // false, otherwise returns true. |
| bool Check(zx_status_t status); |
| |
| // Memory from other processes shared with this service. |
| std::vector<SharedMemory> mapped_; |
| SharedMemory traces_; |
| |
| // Interface to the __sanitizer_cov_trace_* calls. |
| AggregatedCoverage *aggregate_; |
| }; |
| |
| // The AggregatedCoverage class manages a collection of single-client Coverage connections. It also |
| // coordinates and provides thread-safety for invoking the __sanitizer_cov_trace_* interface. |
| class AggregatedCoverage final { |
| public: |
| AggregatedCoverage(); |
| ~AggregatedCoverage(); |
| |
| fidl::InterfaceRequestHandler<Coverage> GetHandler(); |
| |
| // Signals all connected proxies that the current iteration is complete, i.e. they should ensure |
| // their coverage data is updated. |
| zx_status_t CompleteIteration(); |
| |
| // Returns this instance to its original state. |
| void Reset(); |
| |
| protected: |
| friend class CoverageImpl; |
| |
| // Adds a wait item for the shared memory from a call to |Coverage::AddTraces|. |
| zx_status_t Add(const SharedMemory &traces) FXL_LOCKS_EXCLUDED(lock_); |
| |
| // Close and removes the binding for an associated coverage instance. |
| void Close(CoverageImpl *coverage, zx_status_t epitaph); |
| |
| private: |
| // Starts processing coverage. |
| void Start(); |
| |
| // Manage the shared VMOs' signals and process the data from the proxies accordingly. |
| void ProcessAll(); |
| void ProcessTraces(Instruction *traces, uint64_t distinguisher); |
| |
| // Stops processing coverage. |
| void Stop(); |
| |
| // Binding set that owns the Coverage objects. |
| fidl::BindingSet<Coverage, std::unique_ptr<Coverage>> bindings_; |
| |
| // Thread used to run |ProcessAll|. |
| std::thread processor_; |
| |
| // An array of wait items used to monitor connected Coverage/Proxy pairs. |
| zx_wait_item_t items_[ZX_WAIT_MANY_MAX_ITEMS]; |
| std::atomic<size_t> num_items_; |
| |
| // The instruction trace data associated with each wait item. This object MUST keep the two arrays |
| // in sync. |
| Instruction *traces_[ZX_WAIT_MANY_MAX_ITEMS]; |
| uint64_t distinguishers_[ZX_WAIT_MANY_MAX_ITEMS]; |
| uint64_t num_distinguishers_; |
| |
| // The first wait item always corresponds to an event used to control iteration state. |
| zx::event controller_; |
| |
| // This lock guards against concurrent calls to |Add|. |
| std::mutex lock_; |
| |
| // Synchronization objects used to coordinate iterations. |
| std::atomic<size_t> pending_; |
| sync_completion_t sync_; |
| }; |
| |
| } // namespace fuzzing |
| |
| #endif // SRC_LIB_FUZZING_FIDL_COVERAGE_H_ |