No public description

PiperOrigin-RevId: 918490230
diff --git a/centipede/BUILD b/centipede/BUILD
index b01c22c..1000d7f 100644
--- a/centipede/BUILD
+++ b/centipede/BUILD
@@ -1255,6 +1255,11 @@
     ],
 )
 
+cc_library(
+    name = "engine_abi",
+    hdrs = ["engine_abi.h"],
+)
+
 sh_library(
     name = "test_fuzzing_util_sh",
     srcs = ["test_fuzzing_util.sh"],
diff --git a/centipede/engine_abi.h b/centipede/engine_abi.h
new file mode 100644
index 0000000..43e81c7
--- /dev/null
+++ b/centipede/engine_abi.h
@@ -0,0 +1,247 @@
+// Copyright 2026 The FuzzTest Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef FUZZTEST_CENTIPEDE_ENGINE_ABI_H_
+#define FUZZTEST_CENTIPEDE_ENGINE_ABI_H_
+
+// FuzzTest engine ABI.
+//
+// This header needs to be C-compatible.
+
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Opaque handles for in-memory input objects used by the test, which
+// may be serialized/deserialized by the engine.
+typedef uintptr_t FuzzTestInputHandle;
+
+typedef struct {
+  const uint8_t* data;
+  size_t size;
+} FuzzTestBytesView;
+
+// Sink for diagnostics during the setup and execution of the test
+// methods. Methods in this sink are async-safe and thread-safe.
+typedef struct FuzzTestDiagnosticSinkCtx FuzzTestDiagnosticSinkCtx;
+typedef struct {
+  FuzzTestDiagnosticSinkCtx* ctx;
+
+  // Emits an unrecoverable error with a human-readable `message`. Engine would
+  // propagate the error to the controller command when in the worker mode.
+  void (*EmitError)(FuzzTestDiagnosticSinkCtx* ctx,
+                    const FuzzTestBytesView* message);
+
+  // Emits a warning with a human-readable `message`. Engine would log
+  // the warning and continue gracefully when in the worker mode.
+  void (*EmitWarning)(FuzzTestDiagnosticSinkCtx* ctx,
+                      const FuzzTestBytesView* message);
+
+  // Emits a finding for running a test input within `Execute()` with a
+  // human-readable `description`, and `signature` for deduplication.
+  //
+  // Must not be called if the engine is not calling `Execute()`. If called
+  // multiple times within the same `Execute()` window, a random one would take
+  // effect.
+  void (*EmitFinding)(FuzzTestDiagnosticSinkCtx* ctx,
+                      const FuzzTestBytesView* description,
+                      const FuzzTestBytesView* signature);
+} FuzzTestDiagnosticSink;
+
+// Sink for bytes data.
+typedef struct FuzzTestBytesSinkCtx FuzzTestBytesSinkCtx;
+typedef struct {
+  FuzzTestBytesSinkCtx* ctx;
+
+  // Emits a byte buffer. Multiple emissions are concatenated.
+  void (*Emit)(FuzzTestBytesSinkCtx* ctx, const FuzzTestBytesView* view);
+} FuzzTestBytesSink;
+
+// Sink for seed inputs.
+typedef struct FuzzTestInputSinkCtx FuzzTestInputSinkCtx;
+typedef struct {
+  FuzzTestInputSinkCtx* ctx;
+
+  // Emits a test `input` to the engine. Engine would call
+  // `FuzzTestAdapter::FreeTestInput` on the emitted input after the engine is
+  // done with it.
+  void (*Emit)(FuzzTestInputSinkCtx* ctx, FuzzTestInputHandle input);
+} FuzzTestInputSink;
+
+typedef struct {
+  const uint64_t* data;
+  size_t size;
+} FuzzTestUint64sView;
+
+// Sink for execution feedback.
+typedef struct FuzzTestFeedbackSinkCtx FuzzTestFeedbackSinkCtx;
+typedef struct {
+  FuzzTestFeedbackSinkCtx* ctx;
+
+  // Emits an array of coverage features captured from the execution
+  // inside `Execute` call.
+  //
+  // Each feature is a 64-bit unsigned integer with the following layout:
+  //
+  //   - Bits 63..59: 5-bit domain ID of the feature. Each domain is a
+  //     logically independent feature namespace registered in
+  //     `FuzzTestAdapter::GetCoverageDomains`.
+  //   - Bits 58..32: 27-bit feature ID within the domain.
+  //   - Bits 31..0:  32-bit counter value of the feature.
+  //
+  // Multiple emissions are concatenated.
+  void (*EmitCoverageFeatures)(FuzzTestFeedbackSinkCtx* ctx,
+                               const FuzzTestUint64sView* features);
+} FuzzTestFeedbackSink;
+
+// Information of a coverage domain.
+typedef struct {
+  // 5-bit domain ID.
+  uint8_t domain_id;
+  // Human-readable name of the domain for logging.
+  FuzzTestBytesView name;
+  // Number of bits used for the feature IDs in this domain, must be <= 27.
+  uint8_t feature_id_bit_size;
+  // Number of bits used for the counter values in this domain, must be <= 32.
+  uint8_t counter_bit_size;
+} FuzzTestCoverageDomain;
+
+typedef struct FuzzTestDomainRegistryCtx FuzzTestDomainRegistryCtx;
+typedef struct {
+  FuzzTestDomainRegistryCtx* ctx;
+
+  // Registers a new coverage `domain`.
+  void (*Register)(FuzzTestDomainRegistryCtx* ctx,
+                   const FuzzTestCoverageDomain* domain);
+} FuzzTestCoverageDomainRegistry;
+
+typedef struct FuzzTestAdapterCtx FuzzTestAdapterCtx;
+typedef struct FuzzTestAdapter {
+  FuzzTestAdapterCtx* ctx;
+
+  // Registers coverage domains with `registry`.
+  void (*GetCoverageDomains)(FuzzTestAdapterCtx* ctx,
+                             const FuzzTestCoverageDomainRegistry* registry);
+
+  // [Optional] Emits any preset seed inputs of the test using `sink`.
+  // The output must be deterministic.
+  void (*GetPresetSeedInputs)(FuzzTestAdapterCtx* ctx,
+                              const FuzzTestInputSink* sink);
+
+  // Emits a randomly generated seed input using `sink`.
+  void (*GetRandomSeedInput)(FuzzTestAdapterCtx* ctx,
+                             const FuzzTestInputSink* sink);
+
+  // Mutates from `origin`, and emits the mutant using `sink`. `shrink` != 0
+  // means to generate smaller mutant.
+  //
+  // It should not change the content/metadata of `origin`.
+  void (*Mutate)(FuzzTestAdapterCtx* ctx, FuzzTestInputHandle origin,
+                 int shrink, const FuzzTestInputSink* sink);
+
+  // [Optional] Performs cross-over mutation using `origin` and `other`, and
+  // emits the mutant using `sink`.
+  //
+  // It should not change the content/metadata of `origin` or `other`.
+  void (*CrossOver)(FuzzTestAdapterCtx* ctx, FuzzTestInputHandle origin,
+                    FuzzTestInputHandle other, const FuzzTestInputSink* sink);
+
+  // Executes `input` for testing and emits any feedback to `sink`.
+  //
+  // The `input` metadata may be updated by the adapter for further
+  // mutations. The `input` content, which affects the test behavior of
+  // `Execute()`, should not be changed.
+  void (*Execute)(FuzzTestAdapterCtx* ctx, FuzzTestInputHandle input,
+                  const FuzzTestFeedbackSink* sink);
+
+  // Serializes the test `input` content into bytes using `sink`.
+  void (*SerializeInputContent)(FuzzTestAdapterCtx* ctx,
+                                FuzzTestInputHandle input,
+                                const FuzzTestBytesSink* sink);
+
+  // Deserializes the test `input` content from serialized `content` into
+  // a `FuzzTestInputHandle` using `sink`.
+  void (*DeserializeInputContent)(FuzzTestAdapterCtx* ctx,
+                                  const FuzzTestBytesView* content,
+                                  const FuzzTestInputSink* sink);
+
+  // [Optional] Serializes the test `input` metadata into bytes using `sink`.
+  void (*SerializeInputMetadata)(FuzzTestAdapterCtx* ctx,
+                                 FuzzTestInputHandle input,
+                                 const FuzzTestBytesSink* sink);
+
+  // [Optional] Updates the test `input` metadata from serialized `metadata`.
+  void (*UpdateInputMetadata)(FuzzTestAdapterCtx* ctx,
+                              const FuzzTestBytesView* metadata,
+                              FuzzTestInputHandle input);
+
+  // Drops the ownership of `input` from the engine.
+  void (*FreeTestInput)(FuzzTestAdapterCtx* ctx, FuzzTestInputHandle input);
+
+  // Drops the ownership of `ctx` from the engine.
+  void (*FreeCtx)(FuzzTestAdapterCtx* ctx);
+} FuzzTestAdapter;
+
+typedef struct FuzzTestAdapterManagerCtx FuzzTestAdapterManagerCtx;
+typedef struct {
+  FuzzTestAdapterManagerCtx* ctx;
+
+  // [Optional] Emits the ID for the current binary.
+  void (*GetBinaryId)(FuzzTestAdapterManagerCtx* ctx,
+                      const FuzzTestBytesSink* sink);
+
+  // Emits the test name.
+  void (*GetTestName)(FuzzTestAdapterManagerCtx* ctx,
+                      const FuzzTestBytesSink* sink);
+
+  // Constructs an adapter of the test into `adapter_out`. Any diagnostics
+  // happening during the construction or running the adapter should be emitted
+  // to `diagnostic_sink`.
+  void (*ConstructAdapter)(FuzzTestAdapterManagerCtx* ctx,
+                           const FuzzTestDiagnosticSink* diagnostic_sink,
+                           FuzzTestAdapter* adapter_out);
+} FuzzTestAdapterManager;
+
+typedef enum {
+  kFuzzTestWorkerSuccess = 0,  // Test should finish with a success
+  kFuzzTestWorkerFailure,      // Test should finish with a failure.
+  kFuzzTestWorkerNotRequired,  // Test should continue with controller commands.
+} FuzzTestWorkerStatus;
+
+// Try to run as a FuzzTest worker with `manager` if needed.
+FuzzTestWorkerStatus FuzzTestWorkerMaybeRun(
+    const FuzzTestAdapterManager* manager);
+
+typedef enum {
+  kFuzzTestControllerSuccess = 0,
+  kFuzzTestControllerFailure,
+} FuzzTestControllerStatus;
+
+typedef struct {
+  const FuzzTestBytesView* views;
+  size_t count;
+} FuzzTestBytesViews;
+
+// Run the FuzzTest controller with `flags` and `manager`.
+FuzzTestControllerStatus FuzzTestControllerRun(
+    const FuzzTestAdapterManager* manager, const FuzzTestBytesViews* flags);
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif  // FUZZTEST_CENTIPEDE_ENGINE_ABI_H_