blob: cdf175e284afa1bcf79c5da8f7b1e4396d5b51b0 [file] [log] [blame]
// 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.
#include "src/sys/fuzzing/framework/adapters/llvm.h"
#include <lib/syslog/cpp/macros.h>
#include <zircon/errors.h>
#include <zircon/status.h>
#include <string>
#include <vector>
namespace fuzzing {
LLVMTargetAdapter::LLVMTargetAdapter(ExecutorPtr executor)
: binding_(this), executor_(executor), eventpair_(executor) {}
fidl::InterfaceRequestHandler<TargetAdapter> LLVMTargetAdapter::GetHandler() {
return [this](fidl::InterfaceRequest<TargetAdapter> request) {
binding_.Bind(std::move(request), executor_->dispatcher());
};
}
void LLVMTargetAdapter::SetParameters(const std::vector<std::string>& parameters) {
parameters_ = std::vector<std::string>(parameters.begin(), parameters.end());
}
void LLVMTargetAdapter::GetParameters(GetParametersCallback callback) {
callback(std::vector<std::string>(parameters_.begin(), parameters_.end()));
}
void LLVMTargetAdapter::Connect(zx::eventpair eventpair, Buffer test_input,
ConnectCallback callback) {
test_input_.LinkReserved(std::move(test_input));
test_input_.SetPoisoning(true);
eventpair_.Pair(std::move(eventpair));
executor_->schedule_task(Run());
callback();
}
Promise<> LLVMTargetAdapter::Run() {
return fpromise::make_promise(
[this, start = ZxFuture<zx_signals_t>()](Context& context) mutable -> Result<> {
while (true) {
if (!start) {
start = eventpair_.WaitFor(kStart);
}
if (!start(context)) {
return fpromise::pending();
}
if (start.is_error()) {
return fpromise::ok();
}
auto status = eventpair_.SignalSelf(start.take_value(), 0);
if (status != ZX_OK) {
FX_LOGS(WARNING) << "Engine disconnected unexpectedly.";
return fpromise::error();
}
auto result = LLVMFuzzerTestOneInput(test_input_.data(), test_input_.size());
if (result) {
FX_LOGS(FATAL) << "Fuzz target function returned non-zero result: " << result;
}
status = eventpair_.SignalPeer(0, kFinish);
if (status != ZX_OK) {
FX_LOGS(WARNING) << "Engine disconnected unexpectedly.";
return fpromise::error();
}
}
})
.wrap_with(scope_);
}
} // namespace fuzzing