blob: 658ad9c35415f78035765e789099d1575c8b3729 [file] [log] [blame]
// Copyright 2016 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 GARNET_BIN_KTRACE_PROVIDER_IMPORTER_H_
#define GARNET_BIN_KTRACE_PROVIDER_IMPORTER_H_
#include "stddef.h"
#include "stdint.h"
#include <array>
#include <tuple>
#include <unordered_map>
#include <vector>
#include <fbl/string.h>
#include <fbl/string_piece.h>
#include <trace-engine/context.h>
#include "garnet/bin/ktrace_provider/tags.h"
#include "lib/fxl/macros.h"
namespace ktrace_provider {
class Reader;
class Importer {
public:
Importer(trace_context* context);
~Importer();
bool Import(Reader& reader);
private:
using KernelThread = uint32_t;
bool ImportRecord(const ktrace_header_t* record, size_t record_size);
bool ImportBasicRecord(const ktrace_header_t* record,
const TagInfo& tag_info);
bool ImportQuadRecord(const ktrace_rec_32b_t* record,
const TagInfo& tag_info);
bool ImportNameRecord(const ktrace_rec_name_t* record,
const TagInfo& tag_info);
bool ImportProbeRecord(const ktrace_header_t* record, size_t record_size);
bool ImportUnknownRecord(const ktrace_header_t* record, size_t record_size);
bool HandleKernelThreadName(KernelThread kernel_thread,
const fbl::StringPiece& name);
bool HandleThreadName(zx_koid_t thread, zx_koid_t process,
const fbl::StringPiece& name);
bool HandleProcessName(zx_koid_t process, const fbl::StringPiece& name);
bool HandleSyscallName(uint32_t syscall, const fbl::StringPiece& name);
bool HandleIRQName(uint32_t irq, const fbl::StringPiece& name);
bool HandleProbeName(uint32_t probe, const fbl::StringPiece& name);
bool HandleVcpuMeta(uint32_t meta, const fbl::StringPiece& name);
bool HandleVcpuExitMeta(uint32_t exit, const fbl::StringPiece& name);
bool HandleIRQEnter(trace_ticks_t event_time, trace_cpu_number_t cpu_number,
uint32_t irq);
bool HandleIRQExit(trace_ticks_t event_time, trace_cpu_number_t cpu_number,
uint32_t irq);
bool HandleSyscallEnter(trace_ticks_t event_time,
trace_cpu_number_t cpu_number, uint32_t syscall);
bool HandleSyscallExit(trace_ticks_t event_time,
trace_cpu_number_t cpu_number, uint32_t syscall);
bool HandlePageFault(trace_ticks_t event_time, trace_cpu_number_t cpu_number,
uint64_t virtual_address, uint32_t flags);
bool HandleContextSwitch(trace_ticks_t event_time,
trace_cpu_number_t cpu_number,
trace_thread_state_t outgoing_thread_state,
trace_thread_priority_t outgoing_thread_priority,
trace_thread_priority_t incoming_thread_priority,
zx_koid_t outgoing_thread,
KernelThread outgoing_kernel_thread,
zx_koid_t incoming_thread,
KernelThread incoming_kernel_thread);
bool HandleObjectDelete(trace_ticks_t event_time, zx_koid_t thread,
zx_koid_t object);
bool HandleThreadCreate(trace_ticks_t event_time, zx_koid_t thread,
zx_koid_t affected_thread,
zx_koid_t affected_process);
bool HandleThreadStart(trace_ticks_t event_time, zx_koid_t thread,
zx_koid_t affected_thread);
bool HandleThreadExit(trace_ticks_t event_time, zx_koid_t thread);
bool HandleProcessCreate(trace_ticks_t event_time, zx_koid_t thread,
zx_koid_t affected_process);
bool HandleProcessStart(trace_ticks_t event_time, zx_koid_t thread,
zx_koid_t affected_thread,
zx_koid_t affected_process);
bool HandleProcessExit(trace_ticks_t event_time, zx_koid_t thread,
zx_koid_t affected_process);
bool HandleChannelCreate(trace_ticks_t event_time, zx_koid_t thread,
zx_koid_t channel0, zx_koid_t channel1,
uint32_t flags);
bool HandleChannelWrite(trace_ticks_t event_time, zx_koid_t thread,
zx_koid_t channel, uint32_t num_bytes,
uint32_t num_handles);
bool HandleChannelRead(trace_ticks_t event_time, zx_koid_t thread,
zx_koid_t channel, uint32_t num_bytes,
uint32_t num_handles);
bool HandlePortWait(trace_ticks_t event_time, zx_koid_t thread,
zx_koid_t port);
bool HandlePortWaitDone(trace_ticks_t event_time, zx_koid_t thread,
zx_koid_t port, uint32_t status);
bool HandlePortCreate(trace_ticks_t event_time, zx_koid_t thread,
zx_koid_t port);
bool HandlePortQueue(trace_ticks_t event_time, zx_koid_t thread,
zx_koid_t port, uint32_t num_bytes);
bool HandleWaitOne(trace_ticks_t event_time, zx_koid_t thread,
zx_koid_t object, uint32_t signals, zx_time_t timeout);
bool HandleWaitOneDone(trace_ticks_t event_time, zx_koid_t thread,
zx_koid_t object, uint32_t status, uint32_t pending);
bool HandleProbe(trace_ticks_t event_time, zx_koid_t thread, uint32_t probe);
bool HandleProbe(trace_ticks_t event_time, zx_koid_t thread, uint32_t probe,
uint32_t arg0, uint32_t arg1);
bool HandleVcpuEnter(trace_ticks_t event_time, zx_koid_t thread);
bool HandleVcpuExit(trace_ticks_t event_time, zx_koid_t thread, uint32_t exit,
uint64_t exit_address);
bool HandleVcpuBlock(trace_ticks_t event_time, zx_koid_t thread,
uint32_t meta);
bool HandleVcpuUnblock(trace_ticks_t event_time, zx_koid_t thread,
uint32_t meta);
struct CpuInfo {
zx_koid_t current_thread = ZX_KOID_INVALID;
trace_thread_ref_t current_thread_ref = trace_make_unknown_thread_ref();
};
trace_thread_ref_t GetCpuCurrentThreadRef(trace_cpu_number_t cpu_number);
zx_koid_t GetCpuCurrentThread(trace_cpu_number_t cpu_number);
trace_thread_ref_t SwitchCpuToThread(trace_cpu_number_t cpu_number,
zx_koid_t thread);
trace_thread_ref_t SwitchCpuToKernelThread(trace_cpu_number_t cpu_number,
KernelThread kernel_thread);
const trace_string_ref_t& GetNameRef(
std::unordered_map<uint32_t, trace_string_ref_t>& table, const char* kind,
uint32_t id);
const trace_thread_ref_t& GetThreadRef(zx_koid_t thread);
const trace_thread_ref_t& GetKernelThreadRef(KernelThread kernel_thread);
trace_context_t* const context_;
const TagMap& tags_;
trace_string_ref_t const kernel_string_ref_;
trace_string_ref_t const ipc_category_ref_;
trace_string_ref_t const irq_category_ref_;
trace_string_ref_t const probe_category_ref_;
trace_string_ref_t const syscall_category_ref_;
trace_string_ref_t const channel_category_ref_;
trace_string_ref_t const vcpu_category_ref_;
trace_string_ref_t const channel_read_name_ref_;
trace_string_ref_t const channel_write_name_ref_;
trace_string_ref_t const num_bytes_name_ref_;
trace_string_ref_t const num_handles_name_ref_;
trace_string_ref_t const page_fault_name_ref_;
trace_string_ref_t const vaddr_name_ref_;
trace_string_ref_t const flags_name_ref_;
trace_string_ref_t const exit_address_name_ref_;
trace_string_ref_t const arg0_name_ref_;
trace_string_ref_t const arg1_name_ref_;
uint32_t version_ = 0u;
std::vector<CpuInfo> cpu_infos_;
std::unordered_map<KernelThread, trace_thread_ref_t> kernel_thread_refs_;
std::unordered_map<zx_koid_t, trace_thread_ref_t> thread_refs_;
struct VcpuDuration {
trace_ticks_t begin;
bool valid = false;
};
std::unordered_map<zx_koid_t, VcpuDuration> vcpu_durations_;
struct SyscallDuration {
trace_ticks_t begin;
uint32_t syscall;
bool valid = false;
};
std::unordered_map<zx_koid_t, SyscallDuration> syscall_durations_;
std::unordered_map<uint32_t, trace_string_ref_t> irq_names_;
std::unordered_map<uint32_t, trace_string_ref_t> probe_names_;
std::unordered_map<uint32_t, trace_string_ref_t> syscall_names_;
std::unordered_map<uint32_t, trace_string_ref_t> vcpu_meta_;
std::unordered_map<uint32_t, trace_string_ref_t> vcpu_exit_meta_;
struct Channels {
using ChannelId = uint64_t;
using MessageCounter = uint64_t;
static constexpr size_t kReadCounterIndex = 0;
static constexpr size_t kWriteCounterIndex = 1;
ChannelId next_id_ = 0;
std::unordered_map<zx_koid_t, ChannelId> ids_;
std::unordered_map<ChannelId, std::tuple<MessageCounter, MessageCounter>>
message_counters_;
} channels_;
FXL_DISALLOW_COPY_AND_ASSIGN(Importer);
};
} // namespace ktrace_provider
#endif // GARNET_BIN_KTRACE_PROVIDER_IMPORTER_H_