1e8d8bef9SDimitry Andric //===-- CommandObjectTraceStartIntelPT.cpp --------------------------------===// 2e8d8bef9SDimitry Andric // 3e8d8bef9SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4e8d8bef9SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5e8d8bef9SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6e8d8bef9SDimitry Andric // 7e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===// 8e8d8bef9SDimitry Andric 9e8d8bef9SDimitry Andric #include "CommandObjectTraceStartIntelPT.h" 10e8d8bef9SDimitry Andric 11fe6060f1SDimitry Andric #include "TraceIntelPT.h" 12fe6060f1SDimitry Andric #include "TraceIntelPTConstants.h" 13e8d8bef9SDimitry Andric #include "lldb/Host/OptionParser.h" 14fe6060f1SDimitry Andric #include "lldb/Target/Process.h" 15e8d8bef9SDimitry Andric #include "lldb/Target/Trace.h" 16e8d8bef9SDimitry Andric 17e8d8bef9SDimitry Andric using namespace lldb; 18e8d8bef9SDimitry Andric using namespace lldb_private; 19e8d8bef9SDimitry Andric using namespace lldb_private::trace_intel_pt; 20e8d8bef9SDimitry Andric using namespace llvm; 21e8d8bef9SDimitry Andric 22fe6060f1SDimitry Andric // CommandObjectThreadTraceStartIntelPT 23fe6060f1SDimitry Andric 24e8d8bef9SDimitry Andric #define LLDB_OPTIONS_thread_trace_start_intel_pt 25e8d8bef9SDimitry Andric #include "TraceIntelPTCommandOptions.inc" 26e8d8bef9SDimitry Andric 27fe6060f1SDimitry Andric Status CommandObjectThreadTraceStartIntelPT::CommandOptions::SetOptionValue( 28e8d8bef9SDimitry Andric uint32_t option_idx, llvm::StringRef option_arg, 29e8d8bef9SDimitry Andric ExecutionContext *execution_context) { 30e8d8bef9SDimitry Andric Status error; 31e8d8bef9SDimitry Andric const int short_option = m_getopt_table[option_idx].val; 32e8d8bef9SDimitry Andric 33e8d8bef9SDimitry Andric switch (short_option) { 34e8d8bef9SDimitry Andric case 's': { 35*81ad6265SDimitry Andric int64_t ipt_trace_size; 36*81ad6265SDimitry Andric if (option_arg.empty() || option_arg.getAsInteger(0, ipt_trace_size) || 37*81ad6265SDimitry Andric ipt_trace_size < 0) 38e8d8bef9SDimitry Andric error.SetErrorStringWithFormat("invalid integer value for option '%s'", 39e8d8bef9SDimitry Andric option_arg.str().c_str()); 40e8d8bef9SDimitry Andric else 41*81ad6265SDimitry Andric m_ipt_trace_size = ipt_trace_size; 42e8d8bef9SDimitry Andric break; 43e8d8bef9SDimitry Andric } 44fe6060f1SDimitry Andric case 't': { 45fe6060f1SDimitry Andric m_enable_tsc = true; 46fe6060f1SDimitry Andric break; 47fe6060f1SDimitry Andric } 48fe6060f1SDimitry Andric case 'p': { 49fe6060f1SDimitry Andric int64_t psb_period; 50fe6060f1SDimitry Andric if (option_arg.empty() || option_arg.getAsInteger(0, psb_period) || 51fe6060f1SDimitry Andric psb_period < 0) 52e8d8bef9SDimitry Andric error.SetErrorStringWithFormat("invalid integer value for option '%s'", 53e8d8bef9SDimitry Andric option_arg.str().c_str()); 54e8d8bef9SDimitry Andric else 55fe6060f1SDimitry Andric m_psb_period = psb_period; 56e8d8bef9SDimitry Andric break; 57e8d8bef9SDimitry Andric } 58e8d8bef9SDimitry Andric default: 59e8d8bef9SDimitry Andric llvm_unreachable("Unimplemented option"); 60e8d8bef9SDimitry Andric } 61e8d8bef9SDimitry Andric return error; 62e8d8bef9SDimitry Andric } 63e8d8bef9SDimitry Andric 64fe6060f1SDimitry Andric void CommandObjectThreadTraceStartIntelPT::CommandOptions:: 65fe6060f1SDimitry Andric OptionParsingStarting(ExecutionContext *execution_context) { 66*81ad6265SDimitry Andric m_ipt_trace_size = kDefaultIptTraceSize; 67fe6060f1SDimitry Andric m_enable_tsc = kDefaultEnableTscValue; 68fe6060f1SDimitry Andric m_psb_period = kDefaultPsbPeriod; 69e8d8bef9SDimitry Andric } 70e8d8bef9SDimitry Andric 71e8d8bef9SDimitry Andric llvm::ArrayRef<OptionDefinition> 72fe6060f1SDimitry Andric CommandObjectThreadTraceStartIntelPT::CommandOptions::GetDefinitions() { 73e8d8bef9SDimitry Andric return llvm::makeArrayRef(g_thread_trace_start_intel_pt_options); 74e8d8bef9SDimitry Andric } 75e8d8bef9SDimitry Andric 76fe6060f1SDimitry Andric bool CommandObjectThreadTraceStartIntelPT::DoExecuteOnThreads( 77fe6060f1SDimitry Andric Args &command, CommandReturnObject &result, 78fe6060f1SDimitry Andric llvm::ArrayRef<lldb::tid_t> tids) { 79*81ad6265SDimitry Andric if (Error err = m_trace.Start(tids, m_options.m_ipt_trace_size, 80fe6060f1SDimitry Andric m_options.m_enable_tsc, m_options.m_psb_period)) 81fe6060f1SDimitry Andric result.SetError(Status(std::move(err))); 82fe6060f1SDimitry Andric else 83e8d8bef9SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult); 84fe6060f1SDimitry Andric 85fe6060f1SDimitry Andric return result.Succeeded(); 86fe6060f1SDimitry Andric } 87fe6060f1SDimitry Andric 88fe6060f1SDimitry Andric /// CommandObjectProcessTraceStartIntelPT 89fe6060f1SDimitry Andric 90fe6060f1SDimitry Andric #define LLDB_OPTIONS_process_trace_start_intel_pt 91fe6060f1SDimitry Andric #include "TraceIntelPTCommandOptions.inc" 92fe6060f1SDimitry Andric 93fe6060f1SDimitry Andric Status CommandObjectProcessTraceStartIntelPT::CommandOptions::SetOptionValue( 94fe6060f1SDimitry Andric uint32_t option_idx, llvm::StringRef option_arg, 95fe6060f1SDimitry Andric ExecutionContext *execution_context) { 96fe6060f1SDimitry Andric Status error; 97fe6060f1SDimitry Andric const int short_option = m_getopt_table[option_idx].val; 98fe6060f1SDimitry Andric 99fe6060f1SDimitry Andric switch (short_option) { 100fe6060f1SDimitry Andric case 's': { 101*81ad6265SDimitry Andric int64_t ipt_trace_size; 102*81ad6265SDimitry Andric if (option_arg.empty() || option_arg.getAsInteger(0, ipt_trace_size) || 103*81ad6265SDimitry Andric ipt_trace_size < 0) 104fe6060f1SDimitry Andric error.SetErrorStringWithFormat("invalid integer value for option '%s'", 105fe6060f1SDimitry Andric option_arg.str().c_str()); 106fe6060f1SDimitry Andric else 107*81ad6265SDimitry Andric m_ipt_trace_size = ipt_trace_size; 108fe6060f1SDimitry Andric break; 109fe6060f1SDimitry Andric } 110fe6060f1SDimitry Andric case 'l': { 111fe6060f1SDimitry Andric int64_t process_buffer_size_limit; 112fe6060f1SDimitry Andric if (option_arg.empty() || 113fe6060f1SDimitry Andric option_arg.getAsInteger(0, process_buffer_size_limit) || 114fe6060f1SDimitry Andric process_buffer_size_limit < 0) 115fe6060f1SDimitry Andric error.SetErrorStringWithFormat("invalid integer value for option '%s'", 116fe6060f1SDimitry Andric option_arg.str().c_str()); 117fe6060f1SDimitry Andric else 118fe6060f1SDimitry Andric m_process_buffer_size_limit = process_buffer_size_limit; 119fe6060f1SDimitry Andric break; 120fe6060f1SDimitry Andric } 121fe6060f1SDimitry Andric case 't': { 122fe6060f1SDimitry Andric m_enable_tsc = true; 123fe6060f1SDimitry Andric break; 124fe6060f1SDimitry Andric } 125*81ad6265SDimitry Andric case 'c': { 126*81ad6265SDimitry Andric m_per_cpu_tracing = true; 127*81ad6265SDimitry Andric break; 128*81ad6265SDimitry Andric } 129fe6060f1SDimitry Andric case 'p': { 130fe6060f1SDimitry Andric int64_t psb_period; 131fe6060f1SDimitry Andric if (option_arg.empty() || option_arg.getAsInteger(0, psb_period) || 132fe6060f1SDimitry Andric psb_period < 0) 133fe6060f1SDimitry Andric error.SetErrorStringWithFormat("invalid integer value for option '%s'", 134fe6060f1SDimitry Andric option_arg.str().c_str()); 135fe6060f1SDimitry Andric else 136fe6060f1SDimitry Andric m_psb_period = psb_period; 137fe6060f1SDimitry Andric break; 138fe6060f1SDimitry Andric } 139fe6060f1SDimitry Andric default: 140fe6060f1SDimitry Andric llvm_unreachable("Unimplemented option"); 141fe6060f1SDimitry Andric } 142fe6060f1SDimitry Andric return error; 143fe6060f1SDimitry Andric } 144fe6060f1SDimitry Andric 145fe6060f1SDimitry Andric void CommandObjectProcessTraceStartIntelPT::CommandOptions:: 146fe6060f1SDimitry Andric OptionParsingStarting(ExecutionContext *execution_context) { 147*81ad6265SDimitry Andric m_ipt_trace_size = kDefaultIptTraceSize; 148fe6060f1SDimitry Andric m_process_buffer_size_limit = kDefaultProcessBufferSizeLimit; 149fe6060f1SDimitry Andric m_enable_tsc = kDefaultEnableTscValue; 150fe6060f1SDimitry Andric m_psb_period = kDefaultPsbPeriod; 151*81ad6265SDimitry Andric m_per_cpu_tracing = kDefaultPerCpuTracing; 152fe6060f1SDimitry Andric } 153fe6060f1SDimitry Andric 154fe6060f1SDimitry Andric llvm::ArrayRef<OptionDefinition> 155fe6060f1SDimitry Andric CommandObjectProcessTraceStartIntelPT::CommandOptions::GetDefinitions() { 156fe6060f1SDimitry Andric return llvm::makeArrayRef(g_process_trace_start_intel_pt_options); 157fe6060f1SDimitry Andric } 158fe6060f1SDimitry Andric 159fe6060f1SDimitry Andric bool CommandObjectProcessTraceStartIntelPT::DoExecute( 160fe6060f1SDimitry Andric Args &command, CommandReturnObject &result) { 161*81ad6265SDimitry Andric if (Error err = m_trace.Start(m_options.m_ipt_trace_size, 162fe6060f1SDimitry Andric m_options.m_process_buffer_size_limit, 163*81ad6265SDimitry Andric m_options.m_enable_tsc, m_options.m_psb_period, 164*81ad6265SDimitry Andric m_options.m_per_cpu_tracing)) 165fe6060f1SDimitry Andric result.SetError(Status(std::move(err))); 166fe6060f1SDimitry Andric else 167fe6060f1SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult); 168fe6060f1SDimitry Andric 169e8d8bef9SDimitry Andric return result.Succeeded(); 170e8d8bef9SDimitry Andric } 171