blob: b9328b82a421db29f28e8701a42a4cd28c971aee [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_TYPE_DECODER_H_
#define TOOLS_FIDLCAT_LIB_TYPE_DECODER_H_
#include <zircon/rights.h>
#include <zircon/syscalls/debug.h>
#include <zircon/syscalls/exception.h>
#include <zircon/syscalls/hypervisor.h>
#include <zircon/syscalls/object.h>
#include <zircon/syscalls/resource.h>
#include <zircon/types.h>
#include <cinttypes>
#include <cstdint>
#include <ostream>
#include "src/lib/fidl_codec/printer.h"
#include "src/lib/fidl_codec/status.h"
namespace fidlcat {
constexpr int kCharactersPerByte = 2;
// Types for syscall arguments.
enum class SyscallType {
kBool,
kBtiPerm,
kCachePolicy,
kChannelOption,
kChar,
kClock,
kDuration,
kExceptionChannelType,
kExceptionState,
kFeatureKind,
kFutex,
kGpAddr,
kGuestTrap,
kHandle,
kInfoMapsType,
kInt32,
kInt64,
kInterruptFlags,
kIommuType,
kKoid,
kKtraceControlAction,
kMonotonicTime,
kObjType,
kObjectInfoTopic,
kPacketGuestVcpuType,
kPacketPageRequestCommand,
kPaddr,
kPciBarType,
kPolicyAction,
kPolicyCondition,
kPolicyTopic,
kPortPacketType,
kProfileInfoFlags,
kPropType,
kRights,
kRsrcKind,
kSignals,
kSize,
kSocketCreateOptions,
kSocketReadOptions,
kSocketDisposition,
kStatus,
kStruct,
kSystemEventType,
kSystemPowerctl,
kThreadState,
kThreadStateTopic,
kTime,
kTimerOption,
kUint8,
kUint8Hexa,
kUint16,
kUint16Hexa,
kUint32,
kUint32Hexa,
kUint64,
kUint64Hexa,
kUint128Hexa,
kUintptr,
kVaddr,
kVcpu,
kVmOption,
kVmoCreationOption,
kVmoOp,
kVmoOption,
kVmoType
};
enum class SyscallReturnType {
kNoReturn,
kVoid,
kStatus,
kStringView,
kTicks,
kTime,
kUint32,
kUint64,
};
std::string_view TypeName(SyscallType type);
void DisplayType(SyscallType type, fidl_codec::PrettyPrinter& printer);
class DisplayDuration {
public:
DisplayDuration(zx_duration_t duration_ns) : duration_ns_(duration_ns) {}
[[nodiscard]] zx_duration_t duration_ns() const { return duration_ns_; }
private:
const zx_duration_t duration_ns_;
};
inline fidl_codec::PrettyPrinter& operator<<(fidl_codec::PrettyPrinter& printer,
const DisplayDuration& duration) {
printer.DisplayDuration(duration.duration_ns());
return printer;
}
class DisplayStatus {
public:
explicit DisplayStatus(zx_status_t status) : status_(status) {}
[[nodiscard]] zx_status_t status() const { return status_; }
private:
const zx_status_t status_;
};
inline fidl_codec::PrettyPrinter& operator<<(fidl_codec::PrettyPrinter& printer,
const DisplayStatus& status) {
printer << fidl_codec::StatusName(status.status());
return printer;
}
class DisplayTime {
public:
DisplayTime(zx_time_t time_ns) : time_ns_(time_ns) {}
[[nodiscard]] zx_time_t time_ns() const { return time_ns_; }
private:
const zx_time_t time_ns_;
};
inline fidl_codec::PrettyPrinter& operator<<(fidl_codec::PrettyPrinter& printer,
const DisplayTime& time) {
if (time.time_ns() == ZX_TIME_INFINITE) {
printer << fidl_codec::Blue << "ZX_TIME_INFINITE" << fidl_codec::ResetColor;
} else if (time.time_ns() == ZX_TIME_INFINITE_PAST) {
printer << fidl_codec::Blue << "ZX_TIME_INFINITE_PAST" << fidl_codec::ResetColor;
} else {
time_t value = time.time_ns() / fidl_codec::kOneBillion;
struct tm tm;
if (localtime_r(&value, &tm) == &tm) {
char buffer[100];
strftime(buffer, sizeof(buffer), "%c", &tm);
printer << fidl_codec::Blue << buffer << " and ";
snprintf(buffer, sizeof(buffer), "%09" PRId64, time.time_ns() % fidl_codec::kOneBillion);
printer << buffer << " ns" << fidl_codec::ResetColor;
} else {
printer << fidl_codec::Red << "unknown time" << fidl_codec::ResetColor;
}
}
return printer;
}
typedef struct {
uint64_t low;
uint64_t high;
} zx_uint128_t;
// This is a copy of zx_packet_guest_mem from zircon/system/public/zircon/syscalls/port.h
// specialized for AArch64.
struct zx_packet_guest_mem_aarch64 {
zx_gpaddr_t addr;
uint8_t access_size;
bool sign_extend;
uint8_t xt;
bool read;
uint64_t data;
uint64_t reserved;
};
using zx_packet_guest_mem_aarch64_t = struct zx_packet_guest_mem_aarch64;
// TODO(https://bugs.fuchsia.dev/p/fuchsia/issues/detail?id=36188): Remove all
// these copies when zircon will define them.
// This is a copy of zx_packet_guest_mem from zircon/system/public/zircon/syscalls/port.h
// specialized for X86.
struct zx_packet_guest_mem_x86 {
zx_gpaddr_t addr;
// NOTE: x86 instructions are guaranteed to be 15 bytes or fewer.
#define X86_MAX_INST_LEN 15u
uint8_t inst_len;
uint8_t inst_buf[X86_MAX_INST_LEN];
uint8_t default_operand_size;
uint8_t reserved[7];
};
using zx_packet_guest_mem_x86_t = struct zx_packet_guest_mem_x86;
// This this extracted from zx_pci_init_arg_t in the file
// zircon/system/public/zircon/syscalls/pci.h
struct zx_pci_init_arg_irq {
uint32_t global_irq;
bool level_triggered;
bool active_high;
};
using zx_pci_init_arg_irq_t = struct zx_pci_init_arg_irq;
struct zx_pci_init_arg_addr_window {
uint64_t base;
size_t size;
uint8_t bus_start;
uint8_t bus_end;
uint8_t cfg_space_type;
bool has_ecam;
};
using zx_pci_init_arg_addr_window_t = struct zx_pci_init_arg_addr_window;
// This is a copy of zx_thread_state_general_regs_t from
// zircon/system/public/zircon/syscalls/debug.h for __aarch64__.
typedef struct zx_thread_state_general_regs_aarch64 {
uint64_t r[30];
uint64_t lr;
uint64_t sp;
uint64_t pc;
uint64_t cpsr;
uint64_t tpidr;
} zx_thread_state_general_regs_aarch64_t;
// This is a copy of zx_thread_state_general_regs_t from
// zircon/system/public/zircon/syscalls/debug.h for __x86_64__.
typedef struct zx_thread_state_general_regs_x86 {
uint64_t rax;
uint64_t rbx;
uint64_t rcx;
uint64_t rdx;
uint64_t rsi;
uint64_t rdi;
uint64_t rbp;
uint64_t rsp;
uint64_t r8;
uint64_t r9;
uint64_t r10;
uint64_t r11;
uint64_t r12;
uint64_t r13;
uint64_t r14;
uint64_t r15;
uint64_t rip;
uint64_t rflags;
uint64_t fs_base;
uint64_t gs_base;
} zx_thread_state_general_regs_x86_t;
// This is a copy of zx_thread_state_fp_regs_t from
// zircon/system/public/zircon/syscalls/debug.h for __x86_64__.
typedef struct zx_thread_state_fp_regs_x86 {
uint16_t fcw; // Control word.
uint16_t fsw; // Status word.
uint8_t ftw; // Tag word.
uint8_t reserved;
uint16_t fop; // Opcode.
uint64_t fip; // Instruction pointer.
uint64_t fdp; // Data pointer.
// The x87/MMX state. For x87 the each "st" entry has the low 80 bits used for the register
// contents. For MMX, the low 64 bits are used. The higher bits are unused.
__ALIGNED(16)
zx_uint128_t st[8];
} zx_thread_state_fp_regs_x86_t;
// This is a copy of zx_thread_state_vector_regs_t from
// zircon/system/public/zircon/syscalls/debug.h for __aarch64__.
typedef struct zx_thread_state_vector_regs_aarch64 {
uint32_t fpcr;
uint32_t fpsr;
zx_uint128_t v[32];
} zx_thread_state_vector_regs_aarch64_t;
// This is a copy of zx_thread_state_vector_regs_t from
// zircon/system/public/zircon/syscalls/debug.h for __x86_64__
typedef struct {
uint64_t v[8];
} zx_thread_state_vector_regs_x86_zmm_t;
typedef struct zx_thread_state_vector_regs_x86 {
zx_thread_state_vector_regs_x86_zmm_t zmm[32];
// AVX-512 opmask registers. Will be 0 unless AVX-512 is supported.
uint64_t opmask[8];
// SIMD control and status register.
uint32_t mxcsr;
} zx_thread_state_vector_regs_x86_t;
// This is a copy of zx_thread_state_debug_regs_t from
// zircon/system/public/zircon/syscalls/debug.h for __aarch64__.
// ARMv8-A provides 2 to 16 hardware breakpoint registers.
// The number is obtained by the BRPs field in the EDDFR register.
#define AARCH64_MAX_HW_BREAKPOINTS 16
// ARMv8-A provides 2 to 16 watchpoint breakpoint registers.
// The number is obtained by the WRPs field in the EDDFR register.
#define AARCH64_MAX_HW_WATCHPOINTS 16
typedef struct {
uint32_t dbgbcr; // HW Breakpoint Control register.
uint64_t dbgbvr; // HW Breakpoint Value register.
} zx_thread_state_debug_regs_aarch64_bp_t;
typedef struct {
uint32_t dbgwcr; // HW Watchpoint Control register.
uint64_t dbgwvr; // HW Watchpoint Value register.
} zx_thread_state_debug_regs_aarch64_wp_t;
// Value for XZ_THREAD_STATE_DEBUG_REGS for ARM64 platforms.
typedef struct zx_thread_state_debug_regs_aarch64 {
zx_thread_state_debug_regs_aarch64_bp_t hw_bps[AARCH64_MAX_HW_BREAKPOINTS];
uint8_t hw_bps_count;
zx_thread_state_debug_regs_aarch64_wp_t hw_wps[AARCH64_MAX_HW_WATCHPOINTS];
uint8_t hw_wps_count;
// The esr value since the last exception.
uint32_t esr;
} zx_thread_state_debug_regs_aarch64_t;
// This is a copy of zx_thread_state_debug_regs_t from
// zircon/system/public/zircon/syscalls/debug.h for __x86_64__
typedef struct zx_thread_state_debug_regs_x86 {
uint64_t dr[4];
// DR4 and D5 are not used.
uint64_t dr6; // Status register.
uint64_t dr7; // Control register.
} zx_thread_state_debug_regs_x86_t;
// This is a copy of zx_vcpu_state_t from
// zircon/system/public/zircon/syscalls/hypervisor.h for __aarch64__.
typedef struct zx_vcpu_state_aarch64 {
uint64_t x[31];
uint64_t sp;
uint32_t cpsr;
} zx_vcpu_state_aarch64_t;
// This is a copy of zx_vcpu_state_t from
// zircon/system/public/zircon/syscalls/hypervisor.h for __x86_64__.
typedef struct zx_vcpu_state_x86 {
uint64_t rax;
uint64_t rcx;
uint64_t rdx;
uint64_t rbx;
uint64_t rsp;
uint64_t rbp;
uint64_t rsi;
uint64_t rdi;
uint64_t r8;
uint64_t r9;
uint64_t r10;
uint64_t r11;
uint64_t r12;
uint64_t r13;
uint64_t r14;
uint64_t r15;
uint64_t rflags;
} zx_vcpu_state_x86_t;
} // namespace fidlcat
#endif // TOOLS_FIDLCAT_LIB_TYPE_DECODER_H_