blob: 18de6220b732c16ae8a0b9b201116376ea7d3076 [file] [log] [blame]
// Copyright 2019 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 TOOLS_FIDLCAT_LIB_ZX_CHANNEL_PARAMS_H_
#define TOOLS_FIDLCAT_LIB_ZX_CHANNEL_PARAMS_H_
#include <lib/fit/function.h>
#include <stdint.h>
#include <memory>
#include "src/developer/debug/zxdb/client/register.h"
#include "src/developer/debug/zxdb/client/thread.h"
#include "src/developer/debug/zxdb/common/err.h"
#include "src/lib/fxl/memory/weak_ptr.h"
namespace fidlcat {
// We should probably find a way to enforce this properly.
using zx_handle_t = uint32_t;
class ZxChannelWriteParams;
// Can't use fit::function because zxdb doesn't use move semantics for its
// functions, and this needs to be captured as part of a std::function that gets
// passed to a zxdb function.
using ZxChannelWriteCallback =
std::function<void(const zxdb::Err&, const ZxChannelWriteParams&)>;
// Represents the parameters to a zx_channel_write call.
class ZxChannelWriteParams {
public:
ZxChannelWriteParams()
: handle_(0),
options_(0),
bytes_(nullptr),
num_bytes_(0),
handles_(nullptr),
num_handles_(0) {}
zx_handle_t GetHandle() const { return handle_; }
uint32_t GetOptions() const { return options_; }
const std::unique_ptr<uint8_t[]>& GetBytes() const { return bytes_; }
uint32_t GetNumBytes() const { return num_bytes_; }
const std::unique_ptr<zx_handle_t[]>& GetHandles() const { return handles_; }
uint32_t GetNumHandles() const { return num_handles_; }
ZxChannelWriteParams(ZxChannelWriteParams&& from)
: handle_(from.handle_),
options_(from.options_),
bytes_(std::move(from.bytes_)),
num_bytes_(from.num_bytes_),
handles_(std::move(from.handles_)),
num_handles_(from.num_handles_) {}
// move semantics
ZxChannelWriteParams& operator=(ZxChannelWriteParams&& from) {
if (this != &from) {
handle_ = from.handle_;
options_ = from.options_;
bytes_ = std::move(from.bytes_);
num_bytes_ = from.num_bytes_;
handles_ = std::move(from.handles_);
num_handles_ = from.num_handles_;
}
return *this;
}
// Assuming that |thread| is stopped in a zx_channel_write, and that
// |registers| is the set of registers for that thread, do what is necessary
// to populate |params| and invoke fn. Currently only works for x64.
static void BuildZxChannelWriteParamsAndContinue(
fxl::WeakPtr<zxdb::Thread> thread, const zxdb::RegisterSet& registers,
ZxChannelWriteCallback&& fn);
private:
zx_handle_t handle_;
uint32_t options_;
std::unique_ptr<uint8_t[]> bytes_;
uint32_t num_bytes_;
std::unique_ptr<zx_handle_t[]> handles_;
uint32_t num_handles_;
ZxChannelWriteParams(zx_handle_t handle, uint32_t options,
std::unique_ptr<uint8_t[]> bytes, uint32_t num_bytes,
std::unique_ptr<zx_handle_t[]> handles,
uint32_t num_handles)
: handle_(handle),
options_(options),
bytes_(std::move(bytes)),
num_bytes_(num_bytes),
handles_(std::move(handles)),
num_handles_(num_handles) {}
static void BuildX86AndContinue(fxl::WeakPtr<zxdb::Thread> thread,
const std::vector<zxdb::Register>& regs,
ZxChannelWriteCallback&& fn);
bool IsComplete() const {
// NB: The builder functions will attempt to get memory at any location,
// including 0x0. This means that nullptr is used exclusively to indicate
// whether the bytes / handles are set.
return (num_bytes_ == 0 || bytes_ != nullptr) &&
(num_handles_ == 0 || handles_ != nullptr);
}
};
} // namespace fidlcat
#endif // TOOLS_FIDLCAT_LIB_ZX_CHANNEL_PARAMS_H_