1// Copyright 2016 The Fuchsia Authors 2// 3// Use of this source code is governed by a MIT-style 4// license that can be found in the LICENSE file or at 5// https://opensource.org/licenses/MIT 6 7#ifdef __x86_64__ // entire file 8 9#include <inttypes.h> 10 11#include "lib/mtrace.h" 12#include "trace.h" 13 14#include <lib/zircon-internal/mtrace.h> 15 16#include "arch/x86/proc_trace.h" 17 18#define LOCAL_TRACE 0 19 20zx_status_t mtrace_insntrace_control(uint32_t action, uint32_t options, 21 user_inout_ptr<void> arg, size_t size) { 22 TRACEF("action %u, options 0x%x, arg %p, size 0x%zx\n", 23 action, options, arg.get(), size); 24 25 switch (action) { 26 case MTRACE_INSNTRACE_ALLOC_TRACE: { 27 if (options != 0) 28 return ZX_ERR_INVALID_ARGS; 29 uint32_t mode; 30 if (size != sizeof(mode)) 31 return ZX_ERR_INVALID_ARGS; 32 zx_status_t status = arg.reinterpret<uint32_t>().copy_from_user(&mode); 33 if (status != ZX_OK) 34 return status; 35 TRACEF("action %u, mode 0x%x\n", action, mode); 36 switch (mode) { 37 case IPT_MODE_CPUS: 38 return x86_ipt_alloc_trace(IPT_TRACE_CPUS); 39 case IPT_MODE_THREADS: 40 return x86_ipt_alloc_trace(IPT_TRACE_THREADS); 41 default: 42 return ZX_ERR_INVALID_ARGS; 43 } 44 } 45 46 case MTRACE_INSNTRACE_FREE_TRACE: 47 if (options != 0 || size != 0) 48 return ZX_ERR_INVALID_ARGS; 49 return x86_ipt_free_trace(); 50 51 case MTRACE_INSNTRACE_STAGE_TRACE_DATA: { 52 zx_x86_pt_regs_t regs; 53 if (size != sizeof(regs)) 54 return ZX_ERR_INVALID_ARGS; 55 zx_status_t status = arg.reinterpret<zx_x86_pt_regs_t>().copy_from_user(®s); 56 if (status != ZX_OK) 57 return status; 58 zx_itrace_buffer_descriptor_t descriptor = options; 59 TRACEF("action %u, descriptor %u, ctl 0x%" PRIx64 ", output_base 0x%" PRIx64 "\n", 60 action, descriptor, regs.ctl, regs.output_base); 61 return x86_ipt_stage_trace_data(descriptor, ®s); 62 } 63 64 case MTRACE_INSNTRACE_GET_TRACE_DATA: { 65 zx_x86_pt_regs_t regs; 66 if (size != sizeof(regs)) 67 return ZX_ERR_INVALID_ARGS; 68 zx_itrace_buffer_descriptor_t descriptor = options; 69 auto status = x86_ipt_get_trace_data(descriptor, ®s); 70 if (status != ZX_OK) 71 return status; 72 TRACEF("action %u, descriptor %u, ctl 0x%" PRIx64 ", output_base 0x%" PRIx64 "\n", 73 action, descriptor, regs.ctl, regs.output_base); 74 status = arg.reinterpret<zx_x86_pt_regs_t>().copy_to_user(regs); 75 if (status != ZX_OK) 76 return status; 77 return ZX_OK; 78 } 79 80 case MTRACE_INSNTRACE_START: 81 if (options != 0 || size != 0) 82 return ZX_ERR_INVALID_ARGS; 83 return x86_ipt_start(); 84 85 case MTRACE_INSNTRACE_STOP: 86 if (options != 0 || size != 0) 87 return ZX_ERR_INVALID_ARGS; 88 return x86_ipt_stop(); 89 90 default: 91 return ZX_ERR_INVALID_ARGS; 92 } 93} 94 95#endif 96