[Lldb-commits] [lldb] 32bacb7 - [lldb][intel-pt] Remove old plugin
Walter Erquinigo via lldb-commits
lldb-commits at lists.llvm.org
Thu May 27 12:16:41 PDT 2021
Author: Walter Erquinigo
Date: 2021-05-27T12:16:22-07:00
New Revision: 32bacb74107e45cdcedaf3bb2be11bd6e3015390
URL: https://github.com/llvm/llvm-project/commit/32bacb74107e45cdcedaf3bb2be11bd6e3015390
DIFF: https://github.com/llvm/llvm-project/commit/32bacb74107e45cdcedaf3bb2be11bd6e3015390.diff
LOG: [lldb][intel-pt] Remove old plugin
Now that LLDB proper has built-in support for intel-pt traces, we can remove the old plugin written by Intel. It has less features and it's hard to work with.
As a test, I ran "ninja lldbIntelFeatures" and it worked.
Differential Revision: https://reviews.llvm.org/D102866
Added:
Modified:
lldb/tools/intel-features/CMakeLists.txt
lldb/tools/intel-features/README.txt
lldb/tools/intel-features/cli-wrapper.cpp
Removed:
lldb/tools/intel-features/intel-pt/CMakeLists.txt
lldb/tools/intel-features/intel-pt/Decoder.cpp
lldb/tools/intel-features/intel-pt/Decoder.h
lldb/tools/intel-features/intel-pt/PTDecoder.cpp
lldb/tools/intel-features/intel-pt/PTDecoder.h
lldb/tools/intel-features/intel-pt/README_CLI.txt
lldb/tools/intel-features/intel-pt/README_TOOL.txt
lldb/tools/intel-features/intel-pt/cli-wrapper-pt.cpp
lldb/tools/intel-features/intel-pt/cli-wrapper-pt.h
lldb/tools/intel-features/intel-pt/interface/PTDecoder.i
lldb/tools/intel-features/scripts/CMakeLists.txt
lldb/tools/intel-features/scripts/lldb-intel-features.swig
lldb/tools/intel-features/scripts/python-typemaps.txt
################################################################################
diff --git a/lldb/tools/intel-features/CMakeLists.txt b/lldb/tools/intel-features/CMakeLists.txt
index 734167e51bc5..7d48491ec89a 100644
--- a/lldb/tools/intel-features/CMakeLists.txt
+++ b/lldb/tools/intel-features/CMakeLists.txt
@@ -1,9 +1,8 @@
# Flags to control each individual feature
option(LLDB_BUILD_INTEL_MPX "Enable Building of Intel(R) Memory Protection Extensions" ON)
-option(LLDB_BUILD_INTEL_PT "Enable Building of Intel(R) Processor Trace Tool" OFF)
# Return if all features are OFF
-if (NOT LLDB_BUILD_INTEL_MPX AND NOT LLDB_BUILD_INTEL_PT)
+if (NOT LLDB_BUILD_INTEL_MPX)
return()
endif()
@@ -16,34 +15,6 @@ if (LLDB_BUILD_INTEL_MPX AND CMAKE_SYSTEM_NAME MATCHES "Linux")
SET (CLI_WRAPPER_PREPROCESSORS "${CLI_WRAPPER_PREPROCESSORS} -DBUILD_INTEL_MPX")
endif()
-if (LLDB_BUILD_INTEL_PT)
- add_subdirectory(intel-pt)
- LIST (APPEND FEATURE_LIBS ${FEATURE_LIBS} lldbIntelPT)
- SET (CLI_WRAPPER_PREPROCESSORS "${CLI_WRAPPER_PREPROCESSORS} -DBUILD_INTEL_PT")
-endif()
-
-# Add python wrapper if python not disabled
-if (LLDB_ENABLE_PYTHON AND LLDB_BUILD_INTEL_PT)
- list(APPEND FEATURE_LIBS ${FEATURE_LIBS} ${Python3_LIBRARIES})
- set(LLDB_INTEL_FEATURES_PYTHON_WRAP
- ${LLDB_BINARY_DIR}/tools/intel-features/scripts/IntelFeaturesPythonWrap.cpp)
- set_source_files_properties(${LLDB_INTEL_FEATURES_PYTHON_WRAP}
- PROPERTIES GENERATED 1)
-
- if (CLANG_CL)
- set_source_files_properties(${LLDB_INTEL_FEATURES_PYTHON_WRAP}
- PROPERTIES COMPILE_FLAGS -Wno-unused-function)
- endif()
-
- if (LLVM_COMPILER_IS_GCC_COMPATIBLE AND
- NOT "${CMAKE_SYSTEM_NAME}" MATCHES "Darwin")
- set_property(SOURCE ${LLDB_INTEL_FEATURES_PYTHON_WRAP}
- APPEND_STRING PROPERTY COMPILE_FLAGS
- " -Wno-sequence-point -Wno-cast-qual")
- endif ()
- add_subdirectory(scripts)
-endif()
-
if (NOT CLI_WRAPPER_PREPROCESSORS)
return()
endif()
@@ -53,16 +24,10 @@ set_source_files_properties(cli-wrapper.cpp PROPERTIES
add_lldb_library(lldbIntelFeatures SHARED
cli-wrapper.cpp
- ${LLDB_INTEL_FEATURES_PYTHON_WRAP}
LINK_LIBS
${FEATURE_LIBS}
)
-# Add link dependencies for python wrapper
-if (LLDB_ENABLE_PYTHON AND LLDB_BUILD_INTEL_PT)
- add_dependencies(lldbIntelFeatures intel-features-swig_wrapper)
-endif()
-
install(TARGETS lldbIntelFeatures
LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX})
diff --git a/lldb/tools/intel-features/README.txt b/lldb/tools/intel-features/README.txt
index d46bf1392dcf..e46f7c427c0f 100644
--- a/lldb/tools/intel-features/README.txt
+++ b/lldb/tools/intel-features/README.txt
@@ -25,8 +25,8 @@ build to generate a shared library (lldbIntelFeatures) to provide all these
commands.
For each hardware feature, separate cli commands have been developed that are
-provided by wrappers (cli-wrapper-pt.cpp and cli-wrapper-mpxtable.cpp) residing
-in feature specific folders ("intel-pt" and "intel-mpx" respectively).
+provided by wrappers (e.g. cli-wrapper-mpxtable.cpp) residing
+in feature specific folders.
For details regarding cli commands of each feature, please refer to these
feature specific wrappers.
@@ -44,11 +44,6 @@ Furthermore, flexibility is provided to the user to include/exclude a particular
feature while building lldbIntelFeatures library. This is done by flags described
below:
- - LLDB_BUILD_INTEL_PT - The flag enables building of Intel(R) Processor Trace
- feature (inside intel-pt folder). This flag defaults to "OFF" meaning the
- feature is excluded while building lldbIntelFeatures library. Set it to "ON"
- in order to include it.
-
- LLDB_BUILD_INTEL_MPX - Enables building Intel(R) Memory Protection Extensions
feature (inside intel-mpx folder). This flag defaults to "ON" meaning
the feature is excluded while building lldbIntelFeatures library.
diff --git a/lldb/tools/intel-features/cli-wrapper.cpp b/lldb/tools/intel-features/cli-wrapper.cpp
index f04e39a3be90..08fe7b25fe94 100644
--- a/lldb/tools/intel-features/cli-wrapper.cpp
+++ b/lldb/tools/intel-features/cli-wrapper.cpp
@@ -18,10 +18,6 @@
#include "intel-mpx/cli-wrapper-mpxtable.h"
#endif
-#ifdef BUILD_INTEL_PT
-#include "intel-pt/cli-wrapper-pt.h"
-#endif
-
#include "lldb/API/SBDebugger.h"
namespace lldb {
@@ -30,10 +26,6 @@ bool PluginInitialize(lldb::SBDebugger debugger);
bool lldb::PluginInitialize(lldb::SBDebugger debugger) {
-#ifdef BUILD_INTEL_PT
- PTPluginInitialize(debugger);
-#endif
-
#ifdef BUILD_INTEL_MPX
MPXPluginInitialize(debugger);
#endif
diff --git a/lldb/tools/intel-features/intel-pt/CMakeLists.txt b/lldb/tools/intel-features/intel-pt/CMakeLists.txt
deleted file mode 100644
index 9750ed83ce2d..000000000000
--- a/lldb/tools/intel-features/intel-pt/CMakeLists.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-if (NOT LIBIPT_INCLUDE_PATH)
- message (FATAL_ERROR "libipt include path not provided")
-endif()
-
-if (NOT EXISTS "${LIBIPT_INCLUDE_PATH}")
- message (FATAL_ERROR "invalid libipt include path provided")
-endif()
-include_directories(${LIBIPT_INCLUDE_PATH})
-
-if (NOT LIBIPT_LIBRARY_PATH)
- find_library(LIBIPT_LIBRARY ipt)
-else()
- if (NOT EXISTS "${LIBIPT_LIBRARY_PATH}")
- message (FATAL_ERROR "invalid libipt library path provided")
- endif()
- find_library(LIBIPT_LIBRARY ipt PATHS ${LIBIPT_LIBRARY_PATH})
-endif()
-
-if (NOT LIBIPT_LIBRARY)
- message (FATAL_ERROR "libipt library not found")
-endif()
-
-add_lldb_library(lldbIntelPT
- PTDecoder.cpp
- Decoder.cpp
- cli-wrapper-pt.cpp
-
- LINK_LIBS
- ${LIBIPT_LIBRARY}
- liblldb
- )
diff --git a/lldb/tools/intel-features/intel-pt/Decoder.cpp b/lldb/tools/intel-features/intel-pt/Decoder.cpp
deleted file mode 100644
index 21642c75327a..000000000000
--- a/lldb/tools/intel-features/intel-pt/Decoder.cpp
+++ /dev/null
@@ -1,960 +0,0 @@
-//===-- Decoder.cpp ---------------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "Decoder.h"
-
-// C/C++ Includes
-#include <cinttypes>
-#include <cstring>
-
-#include "lldb/API/SBModule.h"
-#include "lldb/API/SBProcess.h"
-#include "lldb/API/SBThread.h"
-
-using namespace ptdecoder_private;
-
-// This function removes entries of all the processes/threads which were once
-// registered in the class but are not alive anymore because they died or
-// finished executing.
-void Decoder::RemoveDeadProcessesAndThreads(lldb::SBProcess &sbprocess) {
- lldb::SBTarget sbtarget = sbprocess.GetTarget();
- lldb::SBDebugger sbdebugger = sbtarget.GetDebugger();
- uint32_t num_targets = sbdebugger.GetNumTargets();
-
- auto itr_process = m_mapProcessUID_mapThreadID_TraceInfo.begin();
- while (itr_process != m_mapProcessUID_mapThreadID_TraceInfo.end()) {
- bool process_found = false;
- lldb::SBTarget target;
- lldb::SBProcess process;
- for (uint32_t i = 0; i < num_targets; i++) {
- target = sbdebugger.GetTargetAtIndex(i);
- process = target.GetProcess();
- if (process.GetUniqueID() == itr_process->first) {
- process_found = true;
- break;
- }
- }
-
- // Remove the process's entry if it was not found in SBDebugger
- if (!process_found) {
- itr_process = m_mapProcessUID_mapThreadID_TraceInfo.erase(itr_process);
- continue;
- }
-
- // If the state of the process is exited or detached then remove process's
- // entry. If not then remove entry for all those registered threads of this
- // process that are not alive anymore.
- lldb::StateType state = process.GetState();
- if ((state == lldb::StateType::eStateDetached) ||
- (state == lldb::StateType::eStateExited))
- itr_process = m_mapProcessUID_mapThreadID_TraceInfo.erase(itr_process);
- else {
- auto itr_thread = itr_process->second.begin();
- while (itr_thread != itr_process->second.end()) {
- if (itr_thread->first == LLDB_INVALID_THREAD_ID) {
- ++itr_thread;
- continue;
- }
-
- lldb::SBThread thread = process.GetThreadByID(itr_thread->first);
- if (!thread.IsValid())
- itr_thread = itr_process->second.erase(itr_thread);
- else
- ++itr_thread;
- }
- ++itr_process;
- }
- }
-}
-
-void Decoder::StartProcessorTrace(lldb::SBProcess &sbprocess,
- lldb::SBTraceOptions &sbtraceoptions,
- lldb::SBError &sberror) {
- sberror.Clear();
- CheckDebuggerID(sbprocess, sberror);
- if (!sberror.Success())
- return;
-
- std::lock_guard<std::mutex> guard(
- m_mapProcessUID_mapThreadID_TraceInfo_mutex);
- RemoveDeadProcessesAndThreads(sbprocess);
-
- if (sbtraceoptions.getType() != lldb::TraceType::eTraceTypeProcessorTrace) {
- sberror.SetErrorStringWithFormat("SBTraceOptions::TraceType not set to "
- "eTraceTypeProcessorTrace; ProcessID = "
- "%" PRIu64,
- sbprocess.GetProcessID());
- return;
- }
- lldb::SBStructuredData sbstructdata = sbtraceoptions.getTraceParams(sberror);
- if (!sberror.Success())
- return;
-
- const char *trace_tech_key = "trace-tech";
- std::string trace_tech_value("intel-pt");
- lldb::SBStructuredData value = sbstructdata.GetValueForKey(trace_tech_key);
- if (!value.IsValid()) {
- sberror.SetErrorStringWithFormat(
- "key \"%s\" not set in custom trace parameters", trace_tech_key);
- return;
- }
-
- char string_value[9];
- size_t bytes_written = value.GetStringValue(
- string_value, sizeof(string_value) / sizeof(*string_value));
- if (!bytes_written ||
- (bytes_written > (sizeof(string_value) / sizeof(*string_value)))) {
- sberror.SetErrorStringWithFormat(
- "key \"%s\" not set in custom trace parameters", trace_tech_key);
- return;
- }
-
- std::size_t pos =
- trace_tech_value.find((const char *)string_value, 0, bytes_written);
- if ((pos == std::string::npos)) {
- sberror.SetErrorStringWithFormat(
- "key \"%s\" not set to \"%s\" in custom trace parameters",
- trace_tech_key, trace_tech_value.c_str());
- return;
- }
-
- // Start Tracing
- lldb::SBError error;
- uint32_t unique_id = sbprocess.GetUniqueID();
- lldb::tid_t tid = sbtraceoptions.getThreadID();
- lldb::SBTrace trace = sbprocess.StartTrace(sbtraceoptions, error);
- if (!error.Success()) {
- if (tid == LLDB_INVALID_THREAD_ID)
- sberror.SetErrorStringWithFormat("%s; ProcessID = %" PRIu64,
- error.GetCString(),
- sbprocess.GetProcessID());
- else
- sberror.SetErrorStringWithFormat(
- "%s; thread_id = %" PRIu64 ", ProcessID = %" PRIu64,
- error.GetCString(), tid, sbprocess.GetProcessID());
- return;
- }
-
- MapThreadID_TraceInfo &mapThreadID_TraceInfo =
- m_mapProcessUID_mapThreadID_TraceInfo[unique_id];
- ThreadTraceInfo &trace_info = mapThreadID_TraceInfo[tid];
- trace_info.SetUniqueTraceInstance(trace);
- trace_info.SetStopID(sbprocess.GetStopID());
-}
-
-void Decoder::StopProcessorTrace(lldb::SBProcess &sbprocess,
- lldb::SBError &sberror, lldb::tid_t tid) {
- sberror.Clear();
- CheckDebuggerID(sbprocess, sberror);
- if (!sberror.Success()) {
- return;
- }
-
- std::lock_guard<std::mutex> guard(
- m_mapProcessUID_mapThreadID_TraceInfo_mutex);
- RemoveDeadProcessesAndThreads(sbprocess);
-
- uint32_t unique_id = sbprocess.GetUniqueID();
- auto itr_process = m_mapProcessUID_mapThreadID_TraceInfo.find(unique_id);
- if (itr_process == m_mapProcessUID_mapThreadID_TraceInfo.end()) {
- sberror.SetErrorStringWithFormat(
- "tracing not active for this process; ProcessID = %" PRIu64,
- sbprocess.GetProcessID());
- return;
- }
-
- lldb::SBError error;
- if (tid == LLDB_INVALID_THREAD_ID) {
- // This implies to stop tracing on the whole process
- lldb::user_id_t id_to_be_ignored = LLDB_INVALID_UID;
- auto itr_thread = itr_process->second.begin();
- while (itr_thread != itr_process->second.end()) {
- // In the case when user started trace on the entire process and then
- // registered newly spawned threads of this process in the class later,
- // these newly spawned threads will have same trace id. If we stopped
- // trace on the entire process then tracing stops automatically for these
- // newly spawned registered threads. Stopping trace on them again will
- // return error and therefore we need to skip stopping trace on them
- // again.
- lldb::SBTrace &trace = itr_thread->second.GetUniqueTraceInstance();
- lldb::user_id_t lldb_pt_user_id = trace.GetTraceUID();
- if (lldb_pt_user_id != id_to_be_ignored) {
- trace.StopTrace(error, itr_thread->first);
- if (!error.Success()) {
- std::string error_string(error.GetCString());
- if ((error_string.find("tracing not active for this process") ==
- std::string::npos) &&
- (error_string.find("tracing not active for this thread") ==
- std::string::npos)) {
- sberror.SetErrorStringWithFormat(
- "%s; thread id=%" PRIu64 ", ProcessID = %" PRIu64,
- error_string.c_str(), itr_thread->first,
- sbprocess.GetProcessID());
- return;
- }
- }
-
- if (itr_thread->first == LLDB_INVALID_THREAD_ID)
- id_to_be_ignored = lldb_pt_user_id;
- }
- itr_thread = itr_process->second.erase(itr_thread);
- }
- m_mapProcessUID_mapThreadID_TraceInfo.erase(itr_process);
- } else {
- // This implies to stop tracing on a single thread.
- // if 'tid' is registered in the class then get the trace id and stop trace
- // on it. If it is not then check if tracing was ever started on the entire
- // process (because there is a possibility that trace is still running for
- // 'tid' but it was not registered in the class because user had started
- // trace on the whole process and 'tid' spawned later). In that case, get
- // the trace id of the process trace instance and stop trace on this thread.
- // If tracing was never started on the entire process then return error
- // because there is no way tracing is active on 'tid'.
- MapThreadID_TraceInfo &mapThreadID_TraceInfo = itr_process->second;
- lldb::SBTrace trace;
- auto itr = mapThreadID_TraceInfo.find(tid);
- if (itr != mapThreadID_TraceInfo.end()) {
- trace = itr->second.GetUniqueTraceInstance();
- } else {
- auto itr = mapThreadID_TraceInfo.find(LLDB_INVALID_THREAD_ID);
- if (itr != mapThreadID_TraceInfo.end()) {
- trace = itr->second.GetUniqueTraceInstance();
- } else {
- sberror.SetErrorStringWithFormat(
- "tracing not active for this thread; thread id=%" PRIu64
- ", ProcessID = %" PRIu64,
- tid, sbprocess.GetProcessID());
- return;
- }
- }
-
- // Stop Tracing
- trace.StopTrace(error, tid);
- if (!error.Success()) {
- std::string error_string(error.GetCString());
- sberror.SetErrorStringWithFormat(
- "%s; thread id=%" PRIu64 ", ProcessID = %" PRIu64,
- error_string.c_str(), tid, sbprocess.GetProcessID());
- if (error_string.find("tracing not active") == std::string::npos)
- return;
- }
- // Delete the entry of 'tid' from this class (if any)
- mapThreadID_TraceInfo.erase(tid);
- }
-}
-
-void Decoder::ReadTraceDataAndImageInfo(lldb::SBProcess &sbprocess,
- lldb::tid_t tid, lldb::SBError &sberror,
- ThreadTraceInfo &threadTraceInfo) {
- // Allocate trace data buffer and parse cpu info for 'tid' if it is registered
- // for the first time in class
- lldb::SBTrace &trace = threadTraceInfo.GetUniqueTraceInstance();
- Buffer &pt_buffer = threadTraceInfo.GetPTBuffer();
- lldb::SBError error;
- if (pt_buffer.size() == 0) {
- lldb::SBTraceOptions traceoptions;
- traceoptions.setThreadID(tid);
- trace.GetTraceConfig(traceoptions, error);
- if (!error.Success()) {
- sberror.SetErrorStringWithFormat("%s; ProcessID = %" PRIu64,
- error.GetCString(),
- sbprocess.GetProcessID());
- return;
- }
- if (traceoptions.getType() != lldb::TraceType::eTraceTypeProcessorTrace) {
- sberror.SetErrorStringWithFormat("invalid TraceType received from LLDB "
- "for this thread; thread id=%" PRIu64
- ", ProcessID = %" PRIu64,
- tid, sbprocess.GetProcessID());
- return;
- }
-
- threadTraceInfo.AllocatePTBuffer(traceoptions.getTraceBufferSize());
- lldb::SBStructuredData sbstructdata = traceoptions.getTraceParams(sberror);
- if (!sberror.Success())
- return;
- CPUInfo &pt_cpu = threadTraceInfo.GetCPUInfo();
- ParseCPUInfo(pt_cpu, sbstructdata, sberror);
- if (!sberror.Success())
- return;
- }
-
- // Call LLDB API to get raw trace data for this thread
- size_t bytes_written = trace.GetTraceData(error, (void *)pt_buffer.data(),
- pt_buffer.size(), 0, tid);
- if (!error.Success()) {
- sberror.SetErrorStringWithFormat(
- "%s; thread_id = %" PRIu64 ", ProcessID = %" PRIu64,
- error.GetCString(), tid, sbprocess.GetProcessID());
- return;
- }
- std::fill(pt_buffer.begin() + bytes_written, pt_buffer.end(), 0);
-
- // Get information of all the modules of the inferior
- lldb::SBTarget sbtarget = sbprocess.GetTarget();
- ReadExecuteSectionInfos &readExecuteSectionInfos =
- threadTraceInfo.GetReadExecuteSectionInfos();
- GetTargetModulesInfo(sbtarget, readExecuteSectionInfos, sberror);
- if (!sberror.Success())
- return;
-}
-
-void Decoder::DecodeProcessorTrace(lldb::SBProcess &sbprocess, lldb::tid_t tid,
- lldb::SBError &sberror,
- ThreadTraceInfo &threadTraceInfo) {
- // Initialize instruction decoder
- struct pt_insn_decoder *decoder = nullptr;
- struct pt_config config;
- Buffer &pt_buffer = threadTraceInfo.GetPTBuffer();
- CPUInfo &pt_cpu = threadTraceInfo.GetCPUInfo();
- ReadExecuteSectionInfos &readExecuteSectionInfos =
- threadTraceInfo.GetReadExecuteSectionInfos();
-
- InitializePTInstDecoder(&decoder, &config, pt_cpu, pt_buffer,
- readExecuteSectionInfos, sberror);
- if (!sberror.Success())
- return;
-
- // Start raw trace decoding
- Instructions &instruction_list = threadTraceInfo.GetInstructionLog();
- instruction_list.clear();
- DecodeTrace(decoder, instruction_list, sberror);
-}
-
-// Raw trace decoding requires information of Read & Execute sections of each
-// module of the inferior. This function updates internal state of the class to
-// store this information.
-void Decoder::GetTargetModulesInfo(
- lldb::SBTarget &sbtarget, ReadExecuteSectionInfos &readExecuteSectionInfos,
- lldb::SBError &sberror) {
- if (!sbtarget.IsValid()) {
- sberror.SetErrorStringWithFormat("Can't get target's modules info from "
- "LLDB; process has an invalid target");
- return;
- }
-
- lldb::SBFileSpec target_file_spec = sbtarget.GetExecutable();
- if (!target_file_spec.IsValid()) {
- sberror.SetErrorStringWithFormat("Target has an invalid file spec");
- return;
- }
-
- uint32_t num_modules = sbtarget.GetNumModules();
- readExecuteSectionInfos.clear();
-
- // Store information of all RX sections of each module of inferior
- for (uint32_t i = 0; i < num_modules; i++) {
- lldb::SBModule module = sbtarget.GetModuleAtIndex(i);
- if (!module.IsValid()) {
- sberror.SetErrorStringWithFormat(
- "Can't get module info [ %" PRIu32
- " ] of target \"%s\" from LLDB, invalid module",
- i, target_file_spec.GetFilename());
- return;
- }
-
- lldb::SBFileSpec module_file_spec = module.GetPlatformFileSpec();
- if (!module_file_spec.IsValid()) {
- sberror.SetErrorStringWithFormat(
- "Can't get module info [ %" PRIu32
- " ] of target \"%s\" from LLDB, invalid file spec",
- i, target_file_spec.GetFilename());
- return;
- }
-
- const char *image(module_file_spec.GetFilename());
- lldb::SBError error;
- char image_complete_path[1024];
- uint32_t path_length = module_file_spec.GetPath(
- image_complete_path, sizeof(image_complete_path));
- size_t num_sections = module.GetNumSections();
-
- // Store information of only RX sections
- for (size_t idx = 0; idx < num_sections; idx++) {
- lldb::SBSection section = module.GetSectionAtIndex(idx);
- uint32_t section_permission = section.GetPermissions();
- if ((section_permission & lldb::Permissions::ePermissionsReadable) &&
- (section_permission & lldb::Permissions::ePermissionsExecutable)) {
- lldb::SBData section_data = section.GetSectionData();
- if (!section_data.IsValid()) {
- sberror.SetErrorStringWithFormat(
- "Can't get module info [ %" PRIu32 " ] \"%s\" of target "
- "\"%s\" from LLDB, invalid "
- "data in \"%s\" section",
- i, image, target_file_spec.GetFilename(), section.GetName());
- return;
- }
-
- // In case section has no data, skip it.
- if (section_data.GetByteSize() == 0)
- continue;
-
- if (!path_length) {
- sberror.SetErrorStringWithFormat(
- "Can't get module info [ %" PRIu32 " ] \"%s\" of target "
- "\"%s\" from LLDB, module "
- "has an invalid path length",
- i, image, target_file_spec.GetFilename());
- return;
- }
-
- std::string image_path(image_complete_path, path_length);
- readExecuteSectionInfos.emplace_back(
- section.GetLoadAddress(sbtarget), section.GetFileOffset(),
- section_data.GetByteSize(), image_path);
- }
- }
- }
-}
-
-// Raw trace decoding requires information of the target cpu on which inferior
-// is running. This function gets the Trace Configuration from LLDB, parses it
-// for cpu model, family, stepping and vendor id info and updates the internal
-// state of the class to store this information.
-void Decoder::ParseCPUInfo(CPUInfo &pt_cpu, lldb::SBStructuredData &s,
- lldb::SBError &sberror) {
- lldb::SBStructuredData custom_trace_params = s.GetValueForKey("intel-pt");
- if (!custom_trace_params.IsValid()) {
- sberror.SetErrorStringWithFormat("lldb couldn't provide cpuinfo");
- return;
- }
-
- uint64_t family = 0, model = 0, stepping = 0;
- char vendor[32];
- const char *key_family = "cpu_family";
- const char *key_model = "cpu_model";
- const char *key_stepping = "cpu_stepping";
- const char *key_vendor = "cpu_vendor";
-
- // parse family
- lldb::SBStructuredData struct_family =
- custom_trace_params.GetValueForKey(key_family);
- if (!struct_family.IsValid()) {
- sberror.SetErrorStringWithFormat(
- "%s info missing in custom trace parameters", key_family);
- return;
- }
- family = struct_family.GetIntegerValue(0x10000);
- if (family > UINT16_MAX) {
- sberror.SetErrorStringWithFormat(
- "invalid CPU family value extracted from custom trace parameters");
- return;
- }
- pt_cpu.family = (uint16_t)family;
-
- // parse model
- lldb::SBStructuredData struct_model =
- custom_trace_params.GetValueForKey(key_model);
- if (!struct_model.IsValid()) {
- sberror.SetErrorStringWithFormat(
- "%s info missing in custom trace parameters; family=%" PRIu16,
- key_model, pt_cpu.family);
- return;
- }
- model = struct_model.GetIntegerValue(0x100);
- if (model > UINT8_MAX) {
- sberror.SetErrorStringWithFormat("invalid CPU model value extracted from "
- "custom trace parameters; family=%" PRIu16,
- pt_cpu.family);
- return;
- }
- pt_cpu.model = (uint8_t)model;
-
- // parse stepping
- lldb::SBStructuredData struct_stepping =
- custom_trace_params.GetValueForKey(key_stepping);
- if (!struct_stepping.IsValid()) {
- sberror.SetErrorStringWithFormat(
- "%s info missing in custom trace parameters; family=%" PRIu16
- ", model=%" PRIu8,
- key_stepping, pt_cpu.family, pt_cpu.model);
- return;
- }
- stepping = struct_stepping.GetIntegerValue(0x100);
- if (stepping > UINT8_MAX) {
- sberror.SetErrorStringWithFormat("invalid CPU stepping value extracted "
- "from custom trace parameters; "
- "family=%" PRIu16 ", model=%" PRIu8,
- pt_cpu.family, pt_cpu.model);
- return;
- }
- pt_cpu.stepping = (uint8_t)stepping;
-
- // parse vendor info
- pt_cpu.vendor = pcv_unknown;
- lldb::SBStructuredData struct_vendor =
- custom_trace_params.GetValueForKey(key_vendor);
- if (!struct_vendor.IsValid()) {
- sberror.SetErrorStringWithFormat(
- "%s info missing in custom trace parameters; family=%" PRIu16
- ", model=%" PRIu8 ", stepping=%" PRIu8,
- key_vendor, pt_cpu.family, pt_cpu.model, pt_cpu.stepping);
- return;
- }
- auto length = struct_vendor.GetStringValue(vendor, sizeof(vendor));
- if (length && strstr(vendor, "GenuineIntel"))
- pt_cpu.vendor = pcv_intel;
-}
-
-// Initialize trace decoder with pt_config structure and populate its image
-// structure with inferior's memory image information. pt_config structure is
-// initialized with trace buffer and cpu info of the inferior before storing it
-// in trace decoder.
-void Decoder::InitializePTInstDecoder(
- struct pt_insn_decoder **decoder, struct pt_config *config,
- const CPUInfo &pt_cpu, Buffer &pt_buffer,
- const ReadExecuteSectionInfos &readExecuteSectionInfos,
- lldb::SBError &sberror) const {
- if (!decoder || !config) {
- sberror.SetErrorStringWithFormat("internal error");
- return;
- }
-
- // Load cpu info of inferior's target in pt_config struct
- pt_config_init(config);
- config->cpu = pt_cpu;
- int errcode = pt_cpu_errata(&(config->errata), &(config->cpu));
- if (errcode < 0) {
- sberror.SetErrorStringWithFormat("processor trace decoding library: "
- "pt_cpu_errata() failed with error: "
- "\"%s\"",
- pt_errstr(pt_errcode(errcode)));
- return;
- }
-
- // Load trace buffer's starting and end address in pt_config struct
- config->begin = pt_buffer.data();
- config->end = pt_buffer.data() + pt_buffer.size();
-
- // Fill trace decoder with pt_config struct
- *decoder = pt_insn_alloc_decoder(config);
- if (*decoder == nullptr) {
- sberror.SetErrorStringWithFormat("processor trace decoding library: "
- "pt_insn_alloc_decoder() returned null "
- "pointer");
- return;
- }
-
- // Fill trace decoder's image with inferior's memory image information
- struct pt_image *image = pt_insn_get_image(*decoder);
- if (!image) {
- sberror.SetErrorStringWithFormat("processor trace decoding library: "
- "pt_insn_get_image() returned null "
- "pointer");
- pt_insn_free_decoder(*decoder);
- return;
- }
-
- for (auto &itr : readExecuteSectionInfos) {
- errcode = pt_image_add_file(image, itr.image_path.c_str(), itr.file_offset,
- itr.size, nullptr, itr.load_address);
- if (errcode < 0) {
- sberror.SetErrorStringWithFormat("processor trace decoding library: "
- "pt_image_add_file() failed with error: "
- "\"%s\"",
- pt_errstr(pt_errcode(errcode)));
- pt_insn_free_decoder(*decoder);
- return;
- }
- }
-}
-
-void Decoder::AppendErrorWithOffsetToInstructionList(
- int errcode, uint64_t decoder_offset, Instructions &instruction_list,
- lldb::SBError &sberror) {
- sberror.SetErrorStringWithFormat(
- "processor trace decoding library: \"%s\" [decoder_offset] => "
- "[0x%" PRIu64 "]",
- pt_errstr(pt_errcode(errcode)), decoder_offset);
- instruction_list.emplace_back(sberror.GetCString());
-}
-
-void Decoder::AppendErrorWithoutOffsetToInstructionList(
- int errcode, Instructions &instruction_list, lldb::SBError &sberror) {
- sberror.SetErrorStringWithFormat("processor trace decoding library: \"%s\"",
- pt_errstr(pt_errcode(errcode)));
- instruction_list.emplace_back(sberror.GetCString());
-}
-
-int Decoder::AppendErrorToInstructionList(int errcode, pt_insn_decoder *decoder,
- Instructions &instruction_list,
- lldb::SBError &sberror) {
- uint64_t decoder_offset = 0;
- int errcode_off = pt_insn_get_offset(decoder, &decoder_offset);
- if (errcode_off < 0) {
- AppendErrorWithoutOffsetToInstructionList(errcode, instruction_list,
- sberror);
- return errcode_off;
- }
- AppendErrorWithOffsetToInstructionList(errcode, decoder_offset,
- instruction_list, sberror);
- return 0;
-}
-
-int Decoder::HandlePTInstructionEvents(pt_insn_decoder *decoder, int errcode,
- Instructions &instruction_list,
- lldb::SBError &sberror) {
- while (errcode & pts_event_pending) {
- pt_event event;
- errcode = pt_insn_event(decoder, &event, sizeof(event));
- if (errcode < 0)
- return errcode;
-
- // The list of events are in
- // https://github.com/intel/libipt/blob/master/doc/man/pt_qry_event.3.md
- if (event.type == ptev_overflow) {
- int append_errcode = AppendErrorToInstructionList(
- errcode, decoder, instruction_list, sberror);
- if (append_errcode < 0)
- return append_errcode;
- }
- // Other events don't signal stream errors
- }
-
- return 0;
-}
-
-// Start actual decoding of raw trace
-void Decoder::DecodeTrace(struct pt_insn_decoder *decoder,
- Instructions &instruction_list,
- lldb::SBError &sberror) {
- uint64_t decoder_offset = 0;
-
- while (1) {
- struct pt_insn insn;
-
- // Try to sync the decoder. If it fails then get the decoder_offset and try
- // to sync again. If the new_decoder_offset is same as decoder_offset then
- // we will not succeed in syncing for any number of pt_insn_sync_forward()
- // operations. Return in that case. Else keep resyncing until either end of
- // trace stream is reached or pt_insn_sync_forward() passes.
- int errcode = pt_insn_sync_forward(decoder);
- if (errcode < 0) {
- if (errcode == -pte_eos)
- return;
-
- int errcode_off = pt_insn_get_offset(decoder, &decoder_offset);
- if (errcode_off < 0) {
- AppendErrorWithoutOffsetToInstructionList(errcode, instruction_list,
- sberror);
- return;
- }
-
- sberror.SetErrorStringWithFormat(
- "processor trace decoding library: \"%s\" [decoder_offset] => "
- "[0x%" PRIu64 "]",
- pt_errstr(pt_errcode(errcode)), decoder_offset);
- instruction_list.emplace_back(sberror.GetCString());
- while (1) {
- errcode = pt_insn_sync_forward(decoder);
- if (errcode >= 0)
- break;
-
- if (errcode == -pte_eos)
- return;
-
- uint64_t new_decoder_offset = 0;
- errcode_off = pt_insn_get_offset(decoder, &new_decoder_offset);
- if (errcode_off < 0) {
- sberror.SetErrorStringWithFormat(
- "processor trace decoding library: \"%s\"",
- pt_errstr(pt_errcode(errcode)));
- instruction_list.emplace_back(sberror.GetCString());
- return;
- } else if (new_decoder_offset <= decoder_offset) {
- // We tried resyncing the decoder and decoder didn't make any
- // progress because the offset didn't change. We will not make any
- // progress further. Hence, returning in this situation.
- return;
- }
- AppendErrorWithOffsetToInstructionList(errcode, new_decoder_offset,
- instruction_list, sberror);
- decoder_offset = new_decoder_offset;
- }
- }
-
- while (1) {
- errcode = HandlePTInstructionEvents(decoder, errcode, instruction_list,
- sberror);
- if (errcode < 0) {
- int append_errcode = AppendErrorToInstructionList(
- errcode, decoder, instruction_list, sberror);
- if (append_errcode < 0)
- return;
- break;
- }
- errcode = pt_insn_next(decoder, &insn, sizeof(insn));
- if (errcode < 0) {
- if (insn.iclass == ptic_error)
- break;
-
- instruction_list.emplace_back(insn);
-
- if (errcode == -pte_eos)
- return;
-
- Diagnose(decoder, errcode, sberror, &insn);
- instruction_list.emplace_back(sberror.GetCString());
- break;
- }
- instruction_list.emplace_back(insn);
- if (errcode & pts_eos)
- return;
- }
- }
-}
-
-// Function to diagnose and indicate errors during raw trace decoding
-void Decoder::Diagnose(struct pt_insn_decoder *decoder, int decode_error,
- lldb::SBError &sberror, const struct pt_insn *insn) {
- int errcode;
- uint64_t offset;
-
- errcode = pt_insn_get_offset(decoder, &offset);
- if (insn) {
- if (errcode < 0)
- sberror.SetErrorStringWithFormat(
- "processor trace decoding library: \"%s\" [decoder_offset, "
- "last_successful_decoded_ip] => [?, 0x%" PRIu64 "]",
- pt_errstr(pt_errcode(decode_error)), insn->ip);
- else
- sberror.SetErrorStringWithFormat(
- "processor trace decoding library: \"%s\" [decoder_offset, "
- "last_successful_decoded_ip] => [0x%" PRIu64 ", 0x%" PRIu64 "]",
- pt_errstr(pt_errcode(decode_error)), offset, insn->ip);
- } else {
- if (errcode < 0)
- sberror.SetErrorStringWithFormat(
- "processor trace decoding library: \"%s\"",
- pt_errstr(pt_errcode(decode_error)));
- else
- sberror.SetErrorStringWithFormat(
- "processor trace decoding library: \"%s\" [decoder_offset] => "
- "[0x%" PRIu64 "]",
- pt_errstr(pt_errcode(decode_error)), offset);
- }
-}
-
-void Decoder::GetInstructionLogAtOffset(lldb::SBProcess &sbprocess,
- lldb::tid_t tid, uint32_t offset,
- uint32_t count,
- InstructionList &result_list,
- lldb::SBError &sberror) {
- sberror.Clear();
- CheckDebuggerID(sbprocess, sberror);
- if (!sberror.Success()) {
- return;
- }
-
- std::lock_guard<std::mutex> guard(
- m_mapProcessUID_mapThreadID_TraceInfo_mutex);
- RemoveDeadProcessesAndThreads(sbprocess);
-
- ThreadTraceInfo *threadTraceInfo = nullptr;
- FetchAndDecode(sbprocess, tid, sberror, &threadTraceInfo);
- if (!sberror.Success()) {
- return;
- }
- if (threadTraceInfo == nullptr) {
- sberror.SetErrorStringWithFormat("internal error");
- return;
- }
-
- // Return instruction log by populating 'result_list'
- Instructions &insn_list = threadTraceInfo->GetInstructionLog();
- uint64_t sum = (uint64_t)offset + 1;
- if (((insn_list.size() <= offset) && (count <= sum) &&
- ((sum - count) >= insn_list.size())) ||
- (count < 1)) {
- sberror.SetErrorStringWithFormat(
- "Instruction Log not available for offset=%" PRIu32
- " and count=%" PRIu32 ", ProcessID = %" PRIu64,
- offset, count, sbprocess.GetProcessID());
- return;
- }
-
- Instructions::iterator itr_first =
- (insn_list.size() <= offset) ? insn_list.begin()
- : insn_list.begin() + insn_list.size() - sum;
- Instructions::iterator itr_last =
- (count <= sum) ? insn_list.begin() + insn_list.size() - (sum - count)
- : insn_list.end();
- Instructions::iterator itr = itr_first;
- while (itr != itr_last) {
- result_list.AppendInstruction(*itr);
- ++itr;
- }
-}
-
-void Decoder::GetProcessorTraceInfo(lldb::SBProcess &sbprocess, lldb::tid_t tid,
- TraceOptions &options,
- lldb::SBError &sberror) {
- sberror.Clear();
- CheckDebuggerID(sbprocess, sberror);
- if (!sberror.Success()) {
- return;
- }
-
- std::lock_guard<std::mutex> guard(
- m_mapProcessUID_mapThreadID_TraceInfo_mutex);
- RemoveDeadProcessesAndThreads(sbprocess);
-
- ThreadTraceInfo *threadTraceInfo = nullptr;
- FetchAndDecode(sbprocess, tid, sberror, &threadTraceInfo);
- if (!sberror.Success()) {
- return;
- }
- if (threadTraceInfo == nullptr) {
- sberror.SetErrorStringWithFormat("internal error");
- return;
- }
-
- // Get SBTraceOptions from LLDB for 'tid', populate 'traceoptions' with it
- lldb::SBTrace &trace = threadTraceInfo->GetUniqueTraceInstance();
- lldb::SBTraceOptions traceoptions;
- lldb::SBError error;
- traceoptions.setThreadID(tid);
- trace.GetTraceConfig(traceoptions, error);
- if (!error.Success()) {
- std::string error_string(error.GetCString());
- if (error_string.find("tracing not active") != std::string::npos) {
- uint32_t unique_id = sbprocess.GetUniqueID();
- auto itr_process = m_mapProcessUID_mapThreadID_TraceInfo.find(unique_id);
- if (itr_process == m_mapProcessUID_mapThreadID_TraceInfo.end())
- return;
- itr_process->second.erase(tid);
- }
- sberror.SetErrorStringWithFormat("%s; ProcessID = %" PRIu64,
- error_string.c_str(),
- sbprocess.GetProcessID());
- return;
- }
- if (traceoptions.getType() != lldb::TraceType::eTraceTypeProcessorTrace) {
- sberror.SetErrorStringWithFormat("invalid TraceType received from LLDB "
- "for this thread; thread id=%" PRIu64
- ", ProcessID = %" PRIu64,
- tid, sbprocess.GetProcessID());
- return;
- }
- options.setType(traceoptions.getType());
- options.setTraceBufferSize(traceoptions.getTraceBufferSize());
- options.setMetaDataBufferSize(traceoptions.getMetaDataBufferSize());
- lldb::SBStructuredData sbstructdata = traceoptions.getTraceParams(sberror);
- if (!sberror.Success())
- return;
- options.setTraceParams(sbstructdata);
- options.setInstructionLogSize(threadTraceInfo->GetInstructionLog().size());
-}
-
-void Decoder::FetchAndDecode(lldb::SBProcess &sbprocess, lldb::tid_t tid,
- lldb::SBError &sberror,
- ThreadTraceInfo **threadTraceInfo) {
- // Return with error if 'sbprocess' is not registered in the class
- uint32_t unique_id = sbprocess.GetUniqueID();
- auto itr_process = m_mapProcessUID_mapThreadID_TraceInfo.find(unique_id);
- if (itr_process == m_mapProcessUID_mapThreadID_TraceInfo.end()) {
- sberror.SetErrorStringWithFormat(
- "tracing not active for this process; ProcessID = %" PRIu64,
- sbprocess.GetProcessID());
- return;
- }
-
- if (tid == LLDB_INVALID_THREAD_ID) {
- sberror.SetErrorStringWithFormat(
- "invalid thread id provided; thread_id = %" PRIu64
- ", ProcessID = %" PRIu64,
- tid, sbprocess.GetProcessID());
- return;
- }
-
- // Check whether 'tid' thread is registered in the class. If it is then in
- // case StopID didn't change then return without doing anything (no need to
- // read and decode trace data then). Otherwise, save new StopID and proceed
- // with reading and decoding trace.
- if (threadTraceInfo == nullptr) {
- sberror.SetErrorStringWithFormat("internal error");
- return;
- }
-
- MapThreadID_TraceInfo &mapThreadID_TraceInfo = itr_process->second;
- auto itr_thread = mapThreadID_TraceInfo.find(tid);
- if (itr_thread != mapThreadID_TraceInfo.end()) {
- if (itr_thread->second.GetStopID() == sbprocess.GetStopID()) {
- *threadTraceInfo = &(itr_thread->second);
- return;
- }
- itr_thread->second.SetStopID(sbprocess.GetStopID());
- } else {
- // Implies 'tid' is not registered in the class. If tracing was never
- // started on the entire process then return an error. Else try to register
- // this thread and proceed with reading and decoding trace.
- lldb::SBError error;
- itr_thread = mapThreadID_TraceInfo.find(LLDB_INVALID_THREAD_ID);
- if (itr_thread == mapThreadID_TraceInfo.end()) {
- sberror.SetErrorStringWithFormat(
- "tracing not active for this thread; ProcessID = %" PRIu64,
- sbprocess.GetProcessID());
- return;
- }
-
- lldb::SBTrace &trace = itr_thread->second.GetUniqueTraceInstance();
- ThreadTraceInfo &trace_info = mapThreadID_TraceInfo[tid];
- trace_info.SetUniqueTraceInstance(trace);
- trace_info.SetStopID(sbprocess.GetStopID());
- itr_thread = mapThreadID_TraceInfo.find(tid);
- }
-
- // Get raw trace data and inferior image from LLDB for the registered thread
- ReadTraceDataAndImageInfo(sbprocess, tid, sberror, itr_thread->second);
- if (!sberror.Success()) {
- std::string error_string(sberror.GetCString());
- if (error_string.find("tracing not active") != std::string::npos)
- mapThreadID_TraceInfo.erase(itr_thread);
- return;
- }
- // Decode raw trace data
- DecodeProcessorTrace(sbprocess, tid, sberror, itr_thread->second);
- if (!sberror.Success()) {
- return;
- }
- *threadTraceInfo = &(itr_thread->second);
-}
-
-// This function checks whether the provided SBProcess instance belongs to same
-// SBDebugger with which this tool instance is associated.
-void Decoder::CheckDebuggerID(lldb::SBProcess &sbprocess,
- lldb::SBError &sberror) {
- if (!sbprocess.IsValid()) {
- sberror.SetErrorStringWithFormat("invalid process instance");
- return;
- }
-
- lldb::SBTarget sbtarget = sbprocess.GetTarget();
- if (!sbtarget.IsValid()) {
- sberror.SetErrorStringWithFormat(
- "process contains an invalid target; ProcessID = %" PRIu64,
- sbprocess.GetProcessID());
- return;
- }
-
- lldb::SBDebugger sbdebugger = sbtarget.GetDebugger();
- if (!sbdebugger.IsValid()) {
- sberror.SetErrorStringWithFormat("process's target contains an invalid "
- "debugger instance; ProcessID = %" PRIu64,
- sbprocess.GetProcessID());
- return;
- }
-
- if (sbdebugger.GetID() != m_debugger_user_id) {
- sberror.SetErrorStringWithFormat(
- "process belongs to a
diff erent SBDebugger instance than the one for "
- "which the tool is instantiated; ProcessID = %" PRIu64,
- sbprocess.GetProcessID());
- return;
- }
-}
diff --git a/lldb/tools/intel-features/intel-pt/Decoder.h b/lldb/tools/intel-features/intel-pt/Decoder.h
deleted file mode 100644
index ff3e6f34b6a8..000000000000
--- a/lldb/tools/intel-features/intel-pt/Decoder.h
+++ /dev/null
@@ -1,325 +0,0 @@
-//===-- Decoder.h -----------------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef Decoder_h_
-#define Decoder_h_
-
-// C/C++ Includes
-#include <map>
-#include <mutex>
-#include <string>
-#include <vector>
-
-#include "lldb/API/SBDebugger.h"
-#include "lldb/API/SBError.h"
-#include "lldb/API/SBProcess.h"
-#include "lldb/API/SBStream.h"
-#include "lldb/API/SBStructuredData.h"
-#include "lldb/API/SBTarget.h"
-#include "lldb/API/SBTrace.h"
-#include "lldb/API/SBTraceOptions.h"
-#include "lldb/lldb-enumerations.h"
-#include "lldb/lldb-types.h"
-
-#include "intel-pt.h"
-
-namespace ptdecoder_private {
-/// \class Instruction
-/// Represents an assembly instruction containing raw
-/// instruction bytes, instruction address along with information
-/// regarding execution flow context and Intel(R) Processor Trace
-/// context.
-class Instruction {
-public:
- Instruction() : ip(0), data(), error(), iclass(ptic_error), speculative(0) {}
-
- Instruction(const Instruction &insn) = default;
-
- Instruction(const struct pt_insn &insn)
- : ip(insn.ip), data(), error(insn.size == 0 ? "invalid instruction" : ""),
- iclass(insn.iclass), speculative(insn.speculative) {
- if (insn.size != 0)
- data.assign(insn.raw, insn.raw + insn.size);
- }
-
- Instruction(const char *err)
- : ip(0), data(), error(err ? err : "unknown error"), iclass(ptic_error),
- speculative(0) {}
-
- ~Instruction() {}
-
- uint64_t GetInsnAddress() const { return ip; }
-
- size_t GetRawBytes(void *buf, size_t size) const {
- if ((buf == nullptr) || (size == 0))
- return data.size();
-
- size_t bytes_to_read = ((size <= data.size()) ? size : data.size());
- ::memcpy(buf, data.data(), bytes_to_read);
- return bytes_to_read;
- }
-
- const std::string &GetError() const { return error; }
-
- bool GetSpeculative() const { return speculative; }
-
-private:
- uint64_t ip; // instruction address in inferior's memory image
- std::vector<uint8_t> data; // raw bytes
- std::string error; // Error string if instruction is invalid
- enum pt_insn_class iclass; // classification of the instruction
- // A collection of flags giving additional information about instruction
- uint32_t speculative : 1; // Instruction was executed speculatively or not
-};
-
-/// \class InstructionList
-/// Represents a list of assembly instructions. Each instruction is of
-/// type Instruction.
-class InstructionList {
-public:
- InstructionList() : m_insn_vec() {}
-
- InstructionList(const InstructionList &insn_list)
- : m_insn_vec(insn_list.m_insn_vec) {}
-
- ~InstructionList() {}
-
- // Get number of instructions in the list
- size_t GetSize() const { return m_insn_vec.size(); }
-
- // Get instruction at index
- Instruction GetInstructionAtIndex(uint32_t idx) {
- return (idx < m_insn_vec.size() ? m_insn_vec[idx]
- : Instruction("invalid instruction"));
- }
-
- // Append intruction at the end of the list
- void AppendInstruction(Instruction inst) { m_insn_vec.push_back(inst); }
-
-private:
- std::vector<Instruction> m_insn_vec;
-};
-
-/// \class TraceOptions
-/// Provides Intel(R) Processor Trace specific configuration options and
-/// other information obtained by decoding and post-processing the trace
-/// data. Currently, this information comprises of the total number of
-/// assembly instructions executed for an inferior.
-class TraceOptions : public lldb::SBTraceOptions {
-public:
- TraceOptions() : lldb::SBTraceOptions(), m_insn_log_size(0) {}
-
- ~TraceOptions() {}
-
- /// Get total number of assembly instructions obtained after decoding the
- /// complete Intel(R) Processor Trace data obtained from LLDB.
- ///
- /// \return
- /// Total number of instructions.
- uint32_t getInstructionLogSize() const { return m_insn_log_size; }
-
- /// Set total number of assembly instructions.
- ///
- /// \param[in] size
- /// Value to be set.
- void setInstructionLogSize(uint32_t size) { m_insn_log_size = size; }
-
-private:
- uint32_t m_insn_log_size;
-};
-
-/// \class Decoder
-/// This class makes use of Intel(R) Processor Trace hardware feature
-/// (implememted inside LLDB) to gather trace data for an inferior (being
-/// debugged with LLDB) to provide meaningful information out of it.
-///
-/// Currently the meaningful information comprises of the execution flow
-/// of the inferior (in terms of assembly instructions executed). The class
-/// enables user to:
-/// - start the trace with configuration options for a thread/process,
-/// - stop the trace for a thread/process,
-/// - get the execution flow (assembly instructions) for a thread and
-/// - get trace specific information for a thread
-class Decoder {
-public:
- typedef std::vector<Instruction> Instructions;
-
- Decoder(lldb::SBDebugger &sbdebugger)
- : m_mapProcessUID_mapThreadID_TraceInfo_mutex(),
- m_mapProcessUID_mapThreadID_TraceInfo(),
- m_debugger_user_id(sbdebugger.GetID()) {}
-
- ~Decoder() {}
-
- void StartProcessorTrace(lldb::SBProcess &sbprocess,
- lldb::SBTraceOptions &sbtraceoptions,
- lldb::SBError &sberror);
-
- void StopProcessorTrace(lldb::SBProcess &sbprocess, lldb::SBError &sberror,
- lldb::tid_t tid = LLDB_INVALID_THREAD_ID);
-
- void GetInstructionLogAtOffset(lldb::SBProcess &sbprocess, lldb::tid_t tid,
- uint32_t offset, uint32_t count,
- InstructionList &result_list,
- lldb::SBError &sberror);
-
- void GetProcessorTraceInfo(lldb::SBProcess &sbprocess, lldb::tid_t tid,
- TraceOptions &traceinfo, lldb::SBError &sberror);
-
-private:
- class ThreadTraceInfo;
- typedef std::vector<uint8_t> Buffer;
-
- // internal class to manage inferior's read-execute section information
- class ReadExecuteSectionInfo {
- public:
- uint64_t load_address;
- uint64_t file_offset;
- uint64_t size;
- std::string image_path;
-
- ReadExecuteSectionInfo(const uint64_t addr, const uint64_t offset,
- const uint64_t sz, const std::string &path)
- : load_address(addr), file_offset(offset), size(sz), image_path(path) {}
-
- ReadExecuteSectionInfo(const ReadExecuteSectionInfo &rxsection) = default;
- };
-
- typedef struct pt_cpu CPUInfo;
- typedef std::vector<ReadExecuteSectionInfo> ReadExecuteSectionInfos;
-
- // Check whether the provided SBProcess belongs to the same SBDebugger with
- // which Decoder class instance was constructed.
- void CheckDebuggerID(lldb::SBProcess &sbprocess, lldb::SBError &sberror);
-
- // Function to remove entries of finished processes/threads in the class
- void RemoveDeadProcessesAndThreads(lldb::SBProcess &sbprocess);
-
- // Parse cpu information from trace configuration received from LLDB
- void ParseCPUInfo(CPUInfo &pt_cpu, lldb::SBStructuredData &s,
- lldb::SBError &sberror);
-
- /// Function performs following tasks for a given process and thread:
- /// - Checks if the given thread is registered in the class or not. If not
- /// then tries to register it if trace was ever started on the entire
- /// process. Else returns error.
- /// - fetches trace and other necessary information from LLDB (using
- /// ReadTraceDataAndImageInfo()) and decodes the trace (using
- /// DecodeProcessorTrace())
- void FetchAndDecode(lldb::SBProcess &sbprocess, lldb::tid_t tid,
- lldb::SBError &sberror,
- ThreadTraceInfo **threadTraceInfo);
-
- // Helper function of FetchAndDecode() to get raw trace data and memory image
- // info of inferior from LLDB
- void ReadTraceDataAndImageInfo(lldb::SBProcess &sbprocess, lldb::tid_t tid,
- lldb::SBError &sberror,
- ThreadTraceInfo &threadTraceInfo);
-
- // Helper function of FetchAndDecode() to initialize raw trace decoder and
- // start trace decoding
- void DecodeProcessorTrace(lldb::SBProcess &sbprocess, lldb::tid_t tid,
- lldb::SBError &sberror,
- ThreadTraceInfo &threadTraceInfo);
-
- // Helper function of ReadTraceDataAndImageInfo() function for gathering
- // inferior's memory image info along with all dynamic libraries linked with
- // it
- void GetTargetModulesInfo(lldb::SBTarget &sbtarget,
- ReadExecuteSectionInfos &readExecuteSectionInfos,
- lldb::SBError &sberror);
-
- /// Helper functions of DecodeProcessorTrace() function for:
- /// - initializing raw trace decoder (provided by Intel(R) Processor Trace
- /// Decoding library)
- /// - start trace decoding
- void InitializePTInstDecoder(
- struct pt_insn_decoder **decoder, struct pt_config *config,
- const CPUInfo &pt_cpu, Buffer &pt_buffer,
- const ReadExecuteSectionInfos &readExecuteSectionInfos,
- lldb::SBError &sberror) const;
- void DecodeTrace(struct pt_insn_decoder *decoder,
- Instructions &instruction_list, lldb::SBError &sberror);
- int HandlePTInstructionEvents(pt_insn_decoder *decoder, int errcode,
- Instructions &instruction_list,
- lldb::SBError &sberror);
-
- int AppendErrorToInstructionList(int errcode, pt_insn_decoder *decoder,
- Instructions &instruction_list,
- lldb::SBError &sberror);
-
- void AppendErrorWithOffsetToInstructionList(int errcode,
- uint64_t decoder_offset,
- Instructions &instruction_list,
- lldb::SBError &sberror);
-
- void AppendErrorWithoutOffsetToInstructionList(int errcode,
- Instructions &instruction_list,
- lldb::SBError &sberror);
-
- // Function to diagnose and indicate errors during raw trace decoding
- void Diagnose(struct pt_insn_decoder *decoder, int errcode,
- lldb::SBError &sberror, const struct pt_insn *insn = nullptr);
-
- class ThreadTraceInfo {
- public:
- ThreadTraceInfo()
- : m_pt_buffer(), m_readExecuteSectionInfos(), m_thread_stop_id(0),
- m_trace(), m_pt_cpu(), m_instruction_log() {}
-
- ThreadTraceInfo(const ThreadTraceInfo &trace_info) = default;
-
- ~ThreadTraceInfo() {}
-
- Buffer &GetPTBuffer() { return m_pt_buffer; }
-
- void AllocatePTBuffer(uint64_t size) { m_pt_buffer.assign(size, 0); }
-
- ReadExecuteSectionInfos &GetReadExecuteSectionInfos() {
- return m_readExecuteSectionInfos;
- }
-
- CPUInfo &GetCPUInfo() { return m_pt_cpu; }
-
- Instructions &GetInstructionLog() { return m_instruction_log; }
-
- uint32_t GetStopID() const { return m_thread_stop_id; }
-
- void SetStopID(uint32_t stop_id) { m_thread_stop_id = stop_id; }
-
- lldb::SBTrace &GetUniqueTraceInstance() { return m_trace; }
-
- void SetUniqueTraceInstance(lldb::SBTrace &trace) { m_trace = trace; }
-
- friend class Decoder;
-
- private:
- Buffer m_pt_buffer; // raw trace buffer
- ReadExecuteSectionInfos
- m_readExecuteSectionInfos; // inferior's memory image info
- uint32_t m_thread_stop_id; // stop id for thread
- lldb::SBTrace m_trace; // unique tracing instance of a thread/process
- CPUInfo m_pt_cpu; // cpu info of the target on which inferior is running
- Instructions m_instruction_log; // complete instruction log
- };
-
- typedef std::map<lldb::user_id_t, ThreadTraceInfo> MapThreadID_TraceInfo;
- typedef std::map<uint32_t, MapThreadID_TraceInfo>
- MapProcessUID_MapThreadID_TraceInfo;
-
- std::mutex m_mapProcessUID_mapThreadID_TraceInfo_mutex;
- MapProcessUID_MapThreadID_TraceInfo
- m_mapProcessUID_mapThreadID_TraceInfo; // to store trace information for
- // each process and its associated
- // threads
- lldb::user_id_t m_debugger_user_id; // SBDebugger instance which is associated
- // to this Decoder instance
-};
-
-} // namespace ptdecoder_private
-#endif // Decoder_h_
diff --git a/lldb/tools/intel-features/intel-pt/PTDecoder.cpp b/lldb/tools/intel-features/intel-pt/PTDecoder.cpp
deleted file mode 100644
index f09307d0ffed..000000000000
--- a/lldb/tools/intel-features/intel-pt/PTDecoder.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-//===-- PTDecoder.cpp -------------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "PTDecoder.h"
-#include "Decoder.h"
-
-using namespace ptdecoder;
-using namespace ptdecoder_private;
-
-// PTInstruction class member functions definitions
-PTInstruction::PTInstruction(
- const std::shared_ptr<ptdecoder_private::Instruction> &ptr)
- : m_opaque_sp(ptr) {}
-
-PTInstruction::~PTInstruction() {}
-
-uint64_t PTInstruction::GetInsnAddress() const {
- return (m_opaque_sp ? m_opaque_sp->GetInsnAddress() : 0);
-}
-
-size_t PTInstruction::GetRawBytes(void *buf, size_t size) const {
- return (m_opaque_sp ? m_opaque_sp->GetRawBytes(buf, size) : 0);
-}
-
-std::string PTInstruction::GetError() const {
- return (m_opaque_sp ? m_opaque_sp->GetError() : "null pointer");
-}
-
-bool PTInstruction::GetSpeculative() const {
- return (m_opaque_sp ? m_opaque_sp->GetSpeculative() : 0);
-}
-
-// PTInstructionList class member functions definitions
-size_t PTInstructionList::GetSize() const {
- return (m_opaque_sp ? m_opaque_sp->GetSize() : 0);
-}
-
-PTInstruction PTInstructionList::GetInstructionAtIndex(uint32_t idx) {
- if (m_opaque_sp)
- return PTInstruction(std::shared_ptr<ptdecoder_private::Instruction>(
- new Instruction(m_opaque_sp->GetInstructionAtIndex(idx))));
-
- return PTInstruction(std::shared_ptr<ptdecoder_private::Instruction>(
- new Instruction("invalid instruction")));
-}
-
-void PTInstructionList::SetSP(
- const std::shared_ptr<ptdecoder_private::InstructionList> &ptr) {
- m_opaque_sp = ptr;
-}
-void PTInstructionList::Clear() {
- if (!m_opaque_sp)
- return;
- m_opaque_sp.reset();
-}
-
-// PTTraceOptions class member functions definitions
-lldb::TraceType PTTraceOptions::GetType() const {
- return (m_opaque_sp ? m_opaque_sp->getType()
- : lldb::TraceType::eTraceTypeNone);
-}
-
-uint64_t PTTraceOptions::GetTraceBufferSize() const {
- return (m_opaque_sp ? m_opaque_sp->getTraceBufferSize() : 0);
-}
-
-uint64_t PTTraceOptions::GetMetaDataBufferSize() const {
- return (m_opaque_sp ? m_opaque_sp->getMetaDataBufferSize() : 0);
-}
-
-lldb::SBStructuredData PTTraceOptions::GetTraceParams(lldb::SBError &error) {
- if (!m_opaque_sp)
- error.SetErrorString("null pointer");
- return (m_opaque_sp ? m_opaque_sp->getTraceParams(error)
- : lldb::SBStructuredData());
-}
-
-void PTTraceOptions::SetSP(
- const std::shared_ptr<ptdecoder_private::TraceOptions> &ptr) {
- m_opaque_sp = ptr;
-}
-
-// PTDecoder class member functions definitions
-PTDecoder::PTDecoder(lldb::SBDebugger &sbdebugger)
- : m_opaque_sp(new ptdecoder_private::Decoder(sbdebugger)) {}
-
-void PTDecoder::StartProcessorTrace(lldb::SBProcess &sbprocess,
- lldb::SBTraceOptions &sbtraceoptions,
- lldb::SBError &sberror) {
- if (m_opaque_sp == nullptr) {
- sberror.SetErrorStringWithFormat("invalid PTDecoder instance");
- return;
- }
-
- m_opaque_sp->StartProcessorTrace(sbprocess, sbtraceoptions, sberror);
-}
-
-void PTDecoder::StopProcessorTrace(lldb::SBProcess &sbprocess,
- lldb::SBError &sberror, lldb::tid_t tid) {
- if (m_opaque_sp == nullptr) {
- sberror.SetErrorStringWithFormat("invalid PTDecoder instance");
- return;
- }
-
- m_opaque_sp->StopProcessorTrace(sbprocess, sberror, tid);
-}
-
-void PTDecoder::GetInstructionLogAtOffset(lldb::SBProcess &sbprocess,
- lldb::tid_t tid, uint32_t offset,
- uint32_t count,
- PTInstructionList &result_list,
- lldb::SBError &sberror) {
- if (m_opaque_sp == nullptr) {
- sberror.SetErrorStringWithFormat("invalid PTDecoder instance");
- return;
- }
-
- std::shared_ptr<ptdecoder_private::InstructionList> insn_list_ptr(
- new InstructionList());
- m_opaque_sp->GetInstructionLogAtOffset(sbprocess, tid, offset, count,
- *insn_list_ptr, sberror);
- if (!sberror.Success())
- return;
-
- result_list.SetSP(insn_list_ptr);
-}
-
-void PTDecoder::GetProcessorTraceInfo(lldb::SBProcess &sbprocess,
- lldb::tid_t tid, PTTraceOptions &options,
- lldb::SBError &sberror) {
- if (m_opaque_sp == nullptr) {
- sberror.SetErrorStringWithFormat("invalid PTDecoder instance");
- return;
- }
-
- std::shared_ptr<ptdecoder_private::TraceOptions> trace_options_ptr(
- new TraceOptions());
- m_opaque_sp->GetProcessorTraceInfo(sbprocess, tid, *trace_options_ptr,
- sberror);
- if (!sberror.Success())
- return;
-
- options.SetSP(trace_options_ptr);
-}
diff --git a/lldb/tools/intel-features/intel-pt/PTDecoder.h b/lldb/tools/intel-features/intel-pt/PTDecoder.h
deleted file mode 100644
index f44c152747b1..000000000000
--- a/lldb/tools/intel-features/intel-pt/PTDecoder.h
+++ /dev/null
@@ -1,270 +0,0 @@
-//===-- PTDecoder.h ---------------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef PTDecoder_h_
-#define PTDecoder_h_
-
-// C/C++ Includes
-#include <vector>
-
-#include "lldb/API/SBDebugger.h"
-#include "lldb/API/SBError.h"
-#include "lldb/API/SBProcess.h"
-#include "lldb/API/SBStructuredData.h"
-#include "lldb/API/SBTraceOptions.h"
-#include "lldb/lldb-enumerations.h"
-#include "lldb/lldb-types.h"
-
-namespace ptdecoder_private {
-class Instruction;
-class InstructionList;
-class TraceOptions;
-class Decoder;
-} // namespace ptdecoder_private
-
-namespace ptdecoder {
-
-/// \class PTInstruction
-/// Represents an assembly instruction containing raw
-/// instruction bytes, instruction address along with information
-/// regarding execution flow context and Intel(R) Processor Trace
-/// context.
-class PTInstruction {
-public:
- PTInstruction() = default;
-
- PTInstruction(const std::shared_ptr<ptdecoder_private::Instruction> &ptr);
-
- ~PTInstruction();
-
- // Get instruction address in inferior's memory image
- uint64_t GetInsnAddress() const;
-
- /// Get raw bytes of the instruction in the buffer.
- ///
- /// \param[out] buf
- /// The buffer where the raw bytes will be written. This buffer should be
- /// allocated by the caller of this API. Providing an unallocated buffer
- /// is an error. In case of errors, the content of the buffer is not
- /// valid.
- ///
- /// \param[in] size
- /// Number of raw bytes to be written to @buf. Atleast @size bytes of
- /// memory should be allocated to @buf otherwise the behaviour of the API
- /// is undefined. Providing 0 for this argument is an error.
- ///
- /// \return
- /// Number of bytes of the instruction actually written to @buf if API
- /// succeeds. In case of errors, total number of raw bytes of the
- /// instruction is returned.
- size_t GetRawBytes(void *buf, size_t size) const;
-
- // Get error string if it represents an invalid instruction. For a valid
- // instruction, an empty string is returned
- std::string GetError() const;
-
- // Instruction was executed speculatively or not
- bool GetSpeculative() const;
-
-private:
- std::shared_ptr<ptdecoder_private::Instruction> m_opaque_sp;
-};
-
-/// \class PTInstructionList
-/// Represents a list of assembly instructions. Each instruction is of
-/// type PTInstruction.
-class PTInstructionList {
-public:
- // Get number of instructions in the list
- size_t GetSize() const;
-
- // Get instruction at index
- PTInstruction GetInstructionAtIndex(uint32_t idx);
-
- void Clear();
-
-private:
- friend class PTDecoder;
-
- void SetSP(const std::shared_ptr<ptdecoder_private::InstructionList> &ptr);
-
- std::shared_ptr<ptdecoder_private::InstructionList> m_opaque_sp;
-};
-
-/// \class PTTraceOptions
-/// Provides configuration options like trace type, trace buffer size,
-/// meta data buffer size along with other Intel(R) Processor Trace
-/// specific options.
-class PTTraceOptions {
-public:
- lldb::TraceType GetType() const;
-
- uint64_t GetTraceBufferSize() const;
-
- uint64_t GetMetaDataBufferSize() const;
-
- /// Get Intel(R) Processor Trace specific configuration options (apart from
- /// trace buffer size, meta data buffer size and TraceType) formatted as
- /// json text i.e. {"Name":Value,"Name":Value} pairs, where "Value" is a
- /// 64-bit unsigned integer in hex format. For "Name", please refer to
- /// SBProcess::StartTrace API description for setting SBTraceOptions.
- ///
- /// \return
- /// A string formatted as json text {"Name":Value,"Name":Value}
- lldb::SBStructuredData GetTraceParams(lldb::SBError &error);
-
-private:
- friend class PTDecoder;
-
- void SetSP(const std::shared_ptr<ptdecoder_private::TraceOptions> &ptr);
-
- std::shared_ptr<ptdecoder_private::TraceOptions> m_opaque_sp;
-};
-
-/// \class PTDecoder
-/// This class makes use of Intel(R) Processor Trace hardware feature
-/// (implememted inside LLDB) to gather trace data for an inferior (being
-/// debugged with LLDB) to provide meaningful information out of it.
-///
-/// Currently the meaningful information comprises of the execution flow
-/// of the inferior (in terms of assembly instructions executed). The class
-/// enables user to:
-/// - start the trace with configuration options for a thread/process,
-/// - stop the trace for a thread/process,
-/// - get the execution flow (assembly instructions) for a thread and
-/// - get trace specific information for a thread
-class PTDecoder {
-public:
- PTDecoder(lldb::SBDebugger &sbdebugger);
-
- /// Start Intel(R) Processor Trace on a thread or complete process with
- /// Intel(R) Processor Trace specific configuration options
- ///
- /// \param[in] sbprocess
- /// A valid process on which this operation will be performed. An error is
- /// returned in case of an invalid process.
- ///
- /// \param[in] sbtraceoptions
- /// Contains thread id information and configuration options:
- ///
- /// For tracing a single thread, provide a valid thread id. If sbprocess
- /// doesn't contain this thread id, error will be returned. For tracing
- /// complete process, set it to lldb::LLDB_INVALID_THREAD_ID
- /// Configuration options comprises of:
- /// a) trace buffer size, meta data buffer size, TraceType and
- /// b) All other possible Intel(R) Processor Trace specific configuration
- /// options (hereafter collectively referred as CUSTOM_OPTIONS), formatted
- /// as json text i.e. {"Name":Value,"Name":Value,..} inside
- /// sbtraceoptions, where "Value" should be a 64-bit unsigned integer in
- /// hex format. For information regarding what all configuration options
- /// are currently supported by LLDB and detailed information about
- /// CUSTOM_OPTIONS usage, please refer to SBProcess::StartTrace() API
- /// description. To know about all possible configuration options of
- /// Intel(R) Processor Trace, please refer to Intel(R) 64 and IA-32
- /// Architectures Software Developer's Manual.
- ///
- /// TraceType should be set to lldb::TraceType::eTraceTypeProcessorTrace,
- /// else error is returned. To find out any other requirement to start
- /// tracing successfully, please refer to SBProcess::StartTrace() API
- /// description. LLDB's current implementation of Intel(R) Processor Trace
- /// feature may round off invalid values for configuration options.
- /// Therefore, the configuration options with which the trace was actually
- /// started, might be
diff erent to the ones with which trace was asked to
- /// be started by user. The actual used configuration options can be
- /// obtained from GetProcessorTraceInfo() API.
- ///
- /// \param[out] sberror
- /// An error with the failure reason if API fails. Else success.
- void StartProcessorTrace(lldb::SBProcess &sbprocess,
- lldb::SBTraceOptions &sbtraceoptions,
- lldb::SBError &sberror);
-
- /// Stop Intel(R) Processor Trace on a thread or complete process.
- ///
- /// \param[in] sbprocess
- /// A valid process on which this operation will be performed. An error is
- /// returned in case of an invalid process.
- ///
- /// \param[in] tid
- /// Case 1: To stop tracing a single thread, provide a valid thread id. If
- /// sbprocess doesn't contain the thread tid, error will be returned.
- /// Case 2: To stop tracing complete process, use
- /// lldb::LLDB_INVALID_THREAD_ID.
- ///
- /// \param[out] sberror
- /// An error with the failure reason if API fails. Else success.
- void StopProcessorTrace(lldb::SBProcess &sbprocess, lldb::SBError &sberror,
- lldb::tid_t tid = LLDB_INVALID_THREAD_ID);
-
- /// Get instruction log containing the execution flow for a thread of a
- /// process in terms of assembly instructions executed.
- ///
- /// \param[in] sbprocess
- /// A valid process on which this operation will be performed. An error is
- /// returned in case of an invalid process.
- ///
- /// \param[in] tid
- /// A valid thread id of the thread for which instruction log is desired.
- /// If sbprocess doesn't contain the thread tid, error will be returned.
- ///
- /// \param[in] count
- /// The number of instructions requested by the user to be returned from
- /// the complete instruction log. Complete instruction log refers to all
- /// the assembly instructions obtained after decoding the complete raw
- /// trace data obtained from LLDB. The length of the complete instruction
- /// log is dependent on the trace buffer size with which processor tracing
- /// was started for this thread.
- /// The number of instructions actually returned are dependent on 'count'
- /// and 'offset' parameters of this API.
- ///
- /// \param[in] offset
- /// The offset in the complete instruction log from where 'count' number
- /// of instructions are requested by the user. offset is counted from the
- /// end of of this complete instruction log (which means the last executed
- /// instruction is at offset 0 (zero)).
- ///
- /// \param[out] result_list
- /// Depending upon 'count' and 'offset' values, list will be overwritten
- /// with the new instructions.
- ///
- /// \param[out] sberror
- /// An error with the failure reason if API fails. Else success.
- void GetInstructionLogAtOffset(lldb::SBProcess &sbprocess, lldb::tid_t tid,
- uint32_t offset, uint32_t count,
- PTInstructionList &result_list,
- lldb::SBError &sberror);
-
- /// Get Intel(R) Processor Trace specific information for a thread of a
- /// process. The information contains the actual configuration options with
- /// which the trace was started for this thread.
- ///
- /// \param[in] sbprocess
- /// A valid process on which this operation will be performed. An error is
- /// returned in case of an invalid process.
- ///
- /// \param[in] tid
- /// A valid thread id of the thread for which the trace specific
- /// information is required. If sbprocess doesn't contain the thread tid,
- /// an error will be returned.
- ///
- /// \param[out] options
- /// Contains actual configuration options (they may be
diff erent to the
- /// ones with which tracing was asked to be started for this thread during
- /// StartProcessorTrace() API call).
- ///
- /// \param[out] sberror
- /// An error with the failure reason if API fails. Else success.
- void GetProcessorTraceInfo(lldb::SBProcess &sbprocess, lldb::tid_t tid,
- PTTraceOptions &options, lldb::SBError &sberror);
-
-private:
- std::shared_ptr<ptdecoder_private::Decoder> m_opaque_sp;
-};
-
-} // namespace ptdecoder
-#endif // PTDecoder_h_
diff --git a/lldb/tools/intel-features/intel-pt/README_CLI.txt b/lldb/tools/intel-features/intel-pt/README_CLI.txt
deleted file mode 100644
index 2a497c4b3ef1..000000000000
--- a/lldb/tools/intel-features/intel-pt/README_CLI.txt
+++ /dev/null
@@ -1,123 +0,0 @@
-****************************************************************************
-* README *
-* *
-* This file provides all the information regarding 4 new CLI commands that *
-* enable using Intel(R) Processor Trace Tool from LLDB's CLI. *
-****************************************************************************
-
-
-============
-Introduction
-============
-A C++ based cli wrapper has been developed to use Intel(R) Processor Trace Tool
-through LLDB's command line. This also provides an idea to all developers on how
-to integrate the Tool into various IDEs providing LLDB as a debugger.
-
-
-
-============
-How to Build
-============
-The wrapper cli-wrapper-pt.cpp needs to be compiled and linked with the shared
-library of the Intel(R) Processor Trace Tool in order to be used through LLDB's
-CLI. The procedure to build shared library of the Intel(R) Processor Trace Tool
-is given in README_TOOL.txt file.
-
-
-
-============
-How to Use
-============
-All these commands are available via shared library (lldbIntelFeatures)
-obtained after building intel-features folder from top. Please refer to
-cli-wrapper.cpp and README files of "intel-features" folder for this purpose.
-
-
-
-============
-Description
-============
-4 CLI commands have been designed keeping the LLDB's existing CLI command syntax
-in mind.
-
- 1) processor-trace start [-b <buffer-size>] [<thread-index>]
-
- Start Intel(R) Processor Trace on a specific thread or on the whole process
-
- Syntax: processor-trace start <cmd-options>
-
- cmd-options Usage:
- processor-trace start [-b <buffer-size>] [<thread-index>]
-
- -b <buffer-size>
- size of the trace buffer to store the trace data. If not specified
- then a default value (=4KB) will be taken
-
- <thread-index>
- thread index of the thread. If no threads are specified, currently
- selected thread is taken. Use the thread-index 'all' to start
- tracing the whole process
-
-
-
- 2) processor-trace stop [<thread-index>]
-
- Stop Intel(R) Processor Trace on a specific thread or on the whole process
-
- Syntax: processor-trace stop <cmd-options>
-
- cmd-options Usage:
- processor-trace stop [<thread-index>]
-
- <thread-index>
- thread index of the thread. If no threads are specified, currently
- selected thread is taken. Use the thread-index 'all' to stop
- tracing the whole process
-
-
-
- 3) processor-trace show-trace-options [<thread-index>]
-
- Display all the information regarding Intel(R) Processor Trace for a specific
- thread or for the whole process. The information contains trace buffer
- size and configuration options of Intel(R) Processor Trace.
-
- Syntax: processor-trace show-trace-options <cmd-options>
-
- cmd-options Usage:
- processor-trace show-trace-options [<thread-index>]
-
- <thread-index>
- thread index of the thread. If no threads are specified, currently
- selected thread is taken. Use the thread-index 'all' to display
- information for all threads of the process
-
-
-
- 4) processor-trace show-instr-log [-o <offset>] [-c <count>] [<thread-index>]
-
- Display a log of assembly instructions executed for a specific thread or
- for the whole process. The length of the log to be displayed and the
- offset in the whole instruction log from where the log needs to be
- displayed can also be provided. The offset is counted from the end of this
- whole instruction log which means the last executed instruction is at
- offset 0 (zero).
-
- Syntax: processor-trace show-instr-log <cmd-options>
-
- cmd-options Usage:
- processor-trace show-instr-log [-o <offset>] [-c <count>] [<thread-index>]
-
- -c <count>
- number of instructions to be displayed. If not specified then a
- default value (=10) will be taken
-
- -o <offset>
- offset in the whole instruction log from where the log will be
- displayed. If not specified then default value is calculated as
- offset = count -1
-
- <thread-index>
- thread index of the thread. If no threads are specified, currently
- selected thread is taken. Use the thread-index 'all' to show
- instruction log for all the threads of the process
diff --git a/lldb/tools/intel-features/intel-pt/README_TOOL.txt b/lldb/tools/intel-features/intel-pt/README_TOOL.txt
deleted file mode 100644
index d1ec1caf73ca..000000000000
--- a/lldb/tools/intel-features/intel-pt/README_TOOL.txt
+++ /dev/null
@@ -1,311 +0,0 @@
-*******************************************************************************
-* README *
-* *
-* This file provides all the information regarding Intel(R) Processor Trace *
-* Tool. It consists explanation about how Tool internally works, its hardware *
-* and software dependencies, build procedure and usage of the API. *
-*******************************************************************************
-
-
-
-============
-Introduction
-============
-The Intel(R) Processor Trace Tool is developed on top of LLDB and provides its
-its users execution trace of the debugged applications. Tool makes use of
-Intel(R) Processor Trace hardware feature implementation inside LLDB for this
-purpose. This hardware feature generates a set of trace packets that
-encapsulates program flow information. These trace packets along with the binary
-of the application can be decoded with the help of a software decoder to
-construct the execution trace of the application.
-
-More information about Intel(R) Processor Trace feature can be obtained from
-website: https://software.intel.com/en-us/blogs/2013/09/18/processor-tracing
-
-
-
-
-=========
-Details
-=========
-The functionality of the Tool consists three parts:
-
-1. Raw Trace Collection from LLDB
- With the help of API of this Tool (given below), Intel(R) Processor Trace
- can be started on the application being debugged with LLDB. The generated
- trace of the application is gathered inside LLDB and is collected by the
- Tool from LLDB through LLDB's public API.
-
-2. Raw Trace Decoding
- For decoding the raw trace data, the Tool makes use of "libipt", an
- Intel(R) Processor Trace Decoder Library. The library needs binary of
- the application and information about the cpu on which the application is
- running in order to decode the raw trace. The Tool gathers this
- information from LLDB public API and provide it to "libipt". More
- information about "libipt" can be found at:
- https://software.intel.com/en-us/blogs/2013/09/18/processor-tracing and
- https://github.com/01org/processor-trace
-
-3. Decoded Trace Post-processing
- The decoded trace is post-processed to reconstruct the execution flow of
- the application. The execution flow contains the list of assembly
- instructions (called instruction log hereafter).
-
-
-
-
-=============
-Dependencies
-=============
-The Tool has following hardware and software dependencies:
-
- - Hardware dependency: The Tool makes use of this hardware feature to capture
- raw trace of an application from LLDB. This hardware feature may not be
- present in all processors. The hardware feature is supported on Broadwell
- and other succeeding CPUs such as Skylake etc. In order for Tool to provide
- something meaningful, the target machine on which the application is running
- should have this feature.
-
- - Software dependency: The Tool has an indirect dependency on the Operating
- System level software support for Intel(R) Processor Trace on the target
- machine where the application is running and being debugged by LLDB. This
- support is required to enable raw trace generation on the target machine.
- Currently, the Tool works for applications running on Linux OS as till now
- the Operating System level support for the feature is present only in Linux
- (more specifically starting from the 4.1 kernel). In Linux, this feature is
- implemented in perf_events subsystem and is usable through perf_event_open
- system call. In the User space level, the Tool has a direct dependency on
- "libipt" to decode the captured raw trace. This library might be
- pre-installed on host systems. If not then the library can be built from
- its sources (available at): https://github.com/01org/processor-trace
-
-
-
-
-============
-How to Build
-============
-The Tool has a cmake based build and can be built by specifying some extra flags
-while building LLDB with cmake. The following cmake flags need to be provided to
-build the Tool:
-
- - LIBIPT_INCLUDE_PATH - The flag specifies the directory where the header
- file of "libipt" resides. If the library is not pre-installed on the host
- system and is built directly from "libipt" project sources then this file
- may either come as a part of the sources itself or will be generated in
- build folder while building library.
-
- - LIBIPT_LIBRARY_PATH - The flag points to the location of "libipt" shared
- library.
-
-The Tool currently works successfully with following versions of this library:
- - v1.4, v1.5, v1.6
-
-
-
-============
-How to Use
-============
-The Tool's API are exposed as a C++ object oriented interface (file PTDecoder.h)
-in a shared library. The main class that implements the whole functionality is
-PTDecoder. This class makes use of 3 other classes,
- - PTInstruction to represent an assembly instruction
- - PTInstructionList to return instruction log
- - PTTraceOptions to return trace specific information
-The users can use these API to develop their own products. All API are also
-available as python functions through a script bridging interface, allowing
-them to be used directly from python either interactively or to build python
-apps.
-
-Currently, cli wrapper has been developed on top of the Tool to use it through
-LLDB's command line. Please refer to README_CLI.txt file for command line usage.
-
-
-A brief introduction about the classes and their API are given below.
-
- class PTDecoder
- ===============
- This class makes use of Intel(R) Processor Trace hardware feature
- (implemented inside LLDB) to gather trace data for an inferior (being
- debugged with LLDB) to provide meaningful information out of it. Currently
- the meaningful information comprises of the execution flow of the inferior
- (in terms of assembly instructions executed). The class enables user to:
-
- - start the trace with configuration options for a thread/process,
- - stop the trace for a thread/process,
- - get the execution flow (assembly instructions) for a thread and
- - get trace specific information for a thread
-
- Corresponding API are explained below:
- a) void StartProcessorTrace(lldb::SBProcess &sbprocess,
- lldb::SBTraceOptions &sbtraceoptions,
- lldb::SBError &sberror)
- ------------------------------------------------------------------------
- This API allows the user to start trace on a particular thread or on
- the whole process with Intel(R) Processor Trace specific
- configuration options.
-
- @param[in] sbprocess : A valid process on which this operation
- will be performed. An error is returned in case of an invalid
- process.
-
- @param[out] sberror : An error with the failure reason if API
- fails. Else success.
-
- @param[in] sbtraceoptions : Contains thread id information and
- configuration options:
- For tracing a single thread, provide a valid thread id. If
- sbprocess doesn't contain this thread id, error will be returned.
- For tracing complete process, set to lldb::LLDB_INVALID_THREAD_ID
- Configuration options comprises of:
- - trace buffer size, meta data buffer size, TraceType and
- - All other possible Intel(R) Processor Trace specific
- configuration options (hereafter collectively referred as
- CUSTOM_OPTIONS)
-
- Trace buffer, meant to store the trace data read from target
- machine, inside LLDB is configured as a cyclic buffer. Hence,
- depending upon the trace buffer size provided here, buffer
- overwrites may happen while LLDB writes trace data into it.
- CUSTOM_OPTIONS are formatted as json text i.e. {"Name":Value,
- "Name":Value,...} inside sbtraceoptions, where "Value" should be
- a 64-bit unsigned integer in hex format. For information
- regarding what all configuration options are currently supported
- by LLDB and detailed information about CUSTOM_OPTIONS usage,
- please refer to SBProcess::StartTrace() API description. An
- overview of some of the various CUSTOM_OPTIONS are briefly given
- below. Please refer to "Intel(R) 64 and IA-32 Architectures
- Software Developer's Manual" for more details about them.
- - CYCEn Enable/Disable Cycle Count Packet (CYC) Packet
- - OS Packet generation enabled/disabled if
- Current Privilege Level (CPL)=0
- - User Packet generation enabled/disabled if CPL>0
- - CR3Filter Enable/Disable CR3 Filtering
- - MTCEn Enable/disable MTC packets
- - TSCEn Enable/disable TSC packets
- - DisRETC Enable/disable RET Compression
- - BranchEn Enable/disable COFI-based packets
- - MTCFreq Defines MTC Packet Frequency
- - CycThresh CYC Packet threshold
- - PSBFreq Frequency of PSB Packets
-
- TraceType should be set to
- lldb::TraceType::eTraceTypeProcessorTrace, else error is
- returned. To find out any other requirement to start tracing
- successfully, refer to SBProcess::StartTrace() API description.
- LLDB's current implementation of Intel(R) Processor Trace
- feature may round off invalid values for configuration options.
- Therefore, the configuration options with which the trace was
- actually started, might be
diff erent to the ones with which
- trace was asked to be started by user. The actual used
- configuration options can be obtained from
- GetProcessorTraceInfo() API.
-
-
-
- b) void StopProcessorTrace(lldb::SBProcess &sbprocess,
- lldb::SBError &sberror,
- lldb::tid_t tid = LLDB_INVALID_THREAD_ID)
- ------------------------------------------------------------------------
- This API allows the user to Stop trace on a particular thread or on
- the whole process.
-
- @param[in] sbprocess : A valid process on which this operation will
- be performed. An error is returned in case of an invalid process.
-
- @param[in] tid : To stop tracing a single thread, provide a
- valid thread id. If sbprocess doesn't contain the thread tid,
- error will be returned. To stop tracing complete process, use
- lldb::LLDB_INVALID_THREAD_ID
-
- @param[out] sberror : An error with the failure reason if API fails.
- Else success
-
-
-
- c) void GetInstructionLogAtOffset(lldb::SBProcess &sbprocess, lldb::tid_t tid,
- uint32_t offset, uint32_t count,
- PTInstructionList &result_list,
- lldb::SBError &sberror)
- ------------------------------------------------------------------------
- This API provides instruction log that contains the execution flow
- for a thread of a process in terms of assembly instruction executed.
- The API works on only 1 thread at a time. To gather this information
- for whole process, this API needs to be called for each thread.
-
- @param[in] sbprocess : A valid process on which this operation
- will be performed. An error is returned in case of an invalid
- process.
-
- @param[in] tid : A valid thread id of the thread for which
- instruction log is desired. If sbprocess doesn't contain the
- thread tid, error will be returned.
-
- @param[in] count : Number of instructions requested by the
- user to be returned from the complete instruction log. Complete
- instruction log refers to all the assembly instructions obtained
- after decoding the complete raw trace data obtained from LLDB.
- The length of the complete instruction log is dependent on the
- trace buffer size with which processor tracing was started for
- this thread.
- The number of instructions actually returned are dependent on
- 'count' and 'offset' parameters of this API.
-
- @param[in] offset : The offset in the complete instruction log
- from where 'count' number of instructions are requested by the
- user. offset is counted from the end of of this complete
- instruction log (which means the last executed instruction
- is at offset 0 (zero)).
-
- @param[out] result_list : Depending upon 'count' and 'offset' values,
- list will be overwritten with the instructions.
-
- @param[out] sberror : An error with the failure reason if API
- fails. Else success
-
-
-
- d) void GetProcessorTraceInfo(lldb::SBProcess &sbprocess, lldb::tid_t tid,
- PTTraceOptions &options, lldb::SBError &sberror)
- ------------------------------------------------------------------------
- This API provides Intel(R) Processor Trace specific information for
- a thread of a process. The API works on only 1 thread at a time. To
- gather this information for whole process, this API needs to be
- called for each thread. The information contains the actual
- configuration options with which the trace was started for this
- thread.
-
- @param[in] sbprocess : The valid process on which this operation
- will be performed. An error is returned in case of an invalid
- process.
-
- @param[in] tid : A valid thread id of the thread for which the
- trace specific information is required. If sbprocess doesn't
- contain the thread tid, an error will be returned.
-
- @param[out] options : Contains actual configuration options (they
- may be
diff erent to the ones with which tracing was asked to be
- started for this thread during StartProcessorTrace() API call).
-
- @param[out] sberror : An error with the failure reason if API
- fails. Else success
-
-
- class PTInstruction
- ===================
- This class represents an assembly instruction containing raw instruction
- bytes, instruction address along with execution flow context and
- Intel(R) Processor Trace context. For more details, please refer to
- PTDecoder.h file.
-
- class PTInstructionList
- =======================
- This class represents a list of assembly instructions. Each assembly
- instruction is of type PTInstruction.
-
- class PTTraceOptions
- ====================
- This class provides Intel(R) Processor Trace specific configuration
- options like trace type, trace buffer size, meta data buffer size along
- with other trace specific options. For more details, please refer to
- PTDecoder.h file.
diff --git a/lldb/tools/intel-features/intel-pt/cli-wrapper-pt.cpp b/lldb/tools/intel-features/intel-pt/cli-wrapper-pt.cpp
deleted file mode 100644
index 5e409a269fa4..000000000000
--- a/lldb/tools/intel-features/intel-pt/cli-wrapper-pt.cpp
+++ /dev/null
@@ -1,586 +0,0 @@
-//===-- cli-wrapper-pt.cpp -------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-// CLI Wrapper of PTDecoder Tool to enable it to be used through LLDB's CLI. The
-// wrapper provides a new command called processor-trace with 4 child
-// subcommands as follows:
-// processor-trace start
-// processor-trace stop
-// processor-trace show-trace-options
-// processor-trace show-instr-log
-//
-//===----------------------------------------------------------------------===//
-
-#include <cerrno>
-#include <cinttypes>
-#include <cstring>
-#include <string>
-#include <vector>
-
-#include "PTDecoder.h"
-#include "cli-wrapper-pt.h"
-#include "lldb/API/SBCommandInterpreter.h"
-#include "lldb/API/SBCommandReturnObject.h"
-#include "lldb/API/SBDebugger.h"
-#include "lldb/API/SBProcess.h"
-#include "lldb/API/SBStream.h"
-#include "lldb/API/SBStructuredData.h"
-#include "lldb/API/SBTarget.h"
-#include "lldb/API/SBThread.h"
-
-static bool GetProcess(lldb::SBDebugger &debugger,
- lldb::SBCommandReturnObject &result,
- lldb::SBProcess &process) {
- if (!debugger.IsValid()) {
- result.Printf("error: invalid debugger\n");
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
-
- lldb::SBTarget target = debugger.GetSelectedTarget();
- if (!target.IsValid()) {
- result.Printf("error: invalid target inside debugger\n");
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
-
- process = target.GetProcess();
- if (!process.IsValid() ||
- (process.GetState() == lldb::StateType::eStateDetached) ||
- (process.GetState() == lldb::StateType::eStateExited) ||
- (process.GetState() == lldb::StateType::eStateInvalid)) {
- result.Printf("error: invalid process inside debugger's target\n");
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
-
- return true;
-}
-
-static bool ParseCommandOption(char **command,
- lldb::SBCommandReturnObject &result,
- uint32_t &index, const std::string &arg,
- uint32_t &parsed_result) {
- char *endptr;
- if (!command[++index]) {
- result.Printf("error: option \"%s\" requires an argument\n", arg.c_str());
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
-
- errno = 0;
- unsigned long output = strtoul(command[index], &endptr, 0);
- if ((errno != 0) || (*endptr != '\0')) {
- result.Printf("error: invalid value \"%s\" provided for option \"%s\"\n",
- command[index], arg.c_str());
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
- if (output > UINT32_MAX) {
- result.Printf("error: value \"%s\" for option \"%s\" exceeds UINT32_MAX\n",
- command[index], arg.c_str());
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
- parsed_result = (uint32_t)output;
- return true;
-}
-
-static bool ParseCommandArgThread(char **command,
- lldb::SBCommandReturnObject &result,
- lldb::SBProcess &process, uint32_t &index,
- lldb::tid_t &thread_id) {
- char *endptr;
- if (!strcmp(command[index], "all"))
- thread_id = LLDB_INVALID_THREAD_ID;
- else {
- uint32_t thread_index_id;
- errno = 0;
- unsigned long output = strtoul(command[index], &endptr, 0);
- if ((errno != 0) || (*endptr != '\0') || (output > UINT32_MAX)) {
- result.Printf("error: invalid thread specification: \"%s\"\n",
- command[index]);
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
- thread_index_id = (uint32_t)output;
-
- lldb::SBThread thread = process.GetThreadByIndexID(thread_index_id);
- if (!thread.IsValid()) {
- result.Printf(
- "error: process has no thread with thread specification: \"%s\"\n",
- command[index]);
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
- thread_id = thread.GetThreadID();
- }
- return true;
-}
-
-class ProcessorTraceStart : public lldb::SBCommandPluginInterface {
-public:
- ProcessorTraceStart(std::shared_ptr<ptdecoder::PTDecoder> &pt_decoder)
- : SBCommandPluginInterface(), pt_decoder_sp(pt_decoder) {}
-
- ~ProcessorTraceStart() {}
-
- virtual bool DoExecute(lldb::SBDebugger debugger, char **command,
- lldb::SBCommandReturnObject &result) {
- lldb::SBProcess process;
- lldb::SBThread thread;
- if (!GetProcess(debugger, result, process))
- return false;
-
- // Default initialize API's arguments
- lldb::SBTraceOptions lldb_SBTraceOptions;
- uint32_t trace_buffer_size = m_default_trace_buff_size;
- lldb::tid_t thread_id;
-
- // Parse Command line options
- bool thread_argument_provided = false;
- if (command) {
- for (uint32_t i = 0; command[i]; i++) {
- if (!strcmp(command[i], "-b")) {
- if (!ParseCommandOption(command, result, i, "-b", trace_buffer_size))
- return false;
- } else {
- thread_argument_provided = true;
- if (!ParseCommandArgThread(command, result, process, i, thread_id))
- return false;
- }
- }
- }
-
- if (!thread_argument_provided) {
- thread = process.GetSelectedThread();
- if (!thread.IsValid()) {
- result.Printf("error: invalid current selected thread\n");
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
- thread_id = thread.GetThreadID();
- }
-
- if (trace_buffer_size > m_max_trace_buff_size)
- trace_buffer_size = m_max_trace_buff_size;
-
- // Set API's arguments with parsed values
- lldb_SBTraceOptions.setType(lldb::TraceType::eTraceTypeProcessorTrace);
- lldb_SBTraceOptions.setTraceBufferSize(trace_buffer_size);
- lldb_SBTraceOptions.setMetaDataBufferSize(0);
- lldb_SBTraceOptions.setThreadID(thread_id);
- lldb::SBStream sb_stream;
- sb_stream.Printf("{\"trace-tech\":\"intel-pt\"}");
- lldb::SBStructuredData custom_params;
- lldb::SBError error = custom_params.SetFromJSON(sb_stream);
- if (!error.Success()) {
- result.Printf("error: %s\n", error.GetCString());
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
- lldb_SBTraceOptions.setTraceParams(custom_params);
-
- // Start trace
- pt_decoder_sp->StartProcessorTrace(process, lldb_SBTraceOptions, error);
- if (!error.Success()) {
- result.Printf("error: %s\n", error.GetCString());
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
- result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
- return true;
- }
-
-private:
- std::shared_ptr<ptdecoder::PTDecoder> pt_decoder_sp;
- const uint32_t m_max_trace_buff_size = 0x3fff;
- const uint32_t m_default_trace_buff_size = 4096;
-};
-
-class ProcessorTraceInfo : public lldb::SBCommandPluginInterface {
-public:
- ProcessorTraceInfo(std::shared_ptr<ptdecoder::PTDecoder> &pt_decoder)
- : SBCommandPluginInterface(), pt_decoder_sp(pt_decoder) {}
-
- ~ProcessorTraceInfo() {}
-
- virtual bool DoExecute(lldb::SBDebugger debugger, char **command,
- lldb::SBCommandReturnObject &result) {
- lldb::SBProcess process;
- lldb::SBThread thread;
- if (!GetProcess(debugger, result, process))
- return false;
-
- lldb::tid_t thread_id;
-
- // Parse command line options
- bool thread_argument_provided = false;
- if (command) {
- for (uint32_t i = 0; command[i]; i++) {
- thread_argument_provided = true;
- if (!ParseCommandArgThread(command, result, process, i, thread_id))
- return false;
- }
- }
-
- if (!thread_argument_provided) {
- thread = process.GetSelectedThread();
- if (!thread.IsValid()) {
- result.Printf("error: invalid current selected thread\n");
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
- thread_id = thread.GetThreadID();
- }
-
- size_t loop_count = 1;
- bool entire_process_tracing = false;
- if (thread_id == LLDB_INVALID_THREAD_ID) {
- entire_process_tracing = true;
- loop_count = process.GetNumThreads();
- }
-
- // Get trace information
- lldb::SBError error;
- lldb::SBCommandReturnObject res;
- for (size_t i = 0; i < loop_count; i++) {
- error.Clear();
- res.Clear();
-
- if (entire_process_tracing)
- thread = process.GetThreadAtIndex(i);
- else
- thread = process.GetThreadByID(thread_id);
- thread_id = thread.GetThreadID();
-
- ptdecoder::PTTraceOptions options;
- pt_decoder_sp->GetProcessorTraceInfo(process, thread_id, options, error);
- if (!error.Success()) {
- res.Printf("thread #%" PRIu32 ": tid=%" PRIu64 ", error: %s",
- thread.GetIndexID(), thread_id, error.GetCString());
- result.AppendMessage(res.GetOutput());
- continue;
- }
-
- lldb::SBStructuredData data = options.GetTraceParams(error);
- if (!error.Success()) {
- res.Printf("thread #%" PRIu32 ": tid=%" PRIu64 ", error: %s",
- thread.GetIndexID(), thread_id, error.GetCString());
- result.AppendMessage(res.GetOutput());
- continue;
- }
-
- lldb::SBStream s;
- error = data.GetAsJSON(s);
- if (!error.Success()) {
- res.Printf("thread #%" PRIu32 ": tid=%" PRIu64 ", error: %s",
- thread.GetIndexID(), thread_id, error.GetCString());
- result.AppendMessage(res.GetOutput());
- continue;
- }
-
- res.Printf("thread #%" PRIu32 ": tid=%" PRIu64
- ", trace buffer size=%" PRIu64 ", meta buffer size=%" PRIu64
- ", trace type=%" PRIu32 ", custom trace params=%s",
- thread.GetIndexID(), thread_id, options.GetTraceBufferSize(),
- options.GetMetaDataBufferSize(), options.GetType(),
- s.GetData());
- result.AppendMessage(res.GetOutput());
- }
- result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
- return true;
- }
-
-private:
- std::shared_ptr<ptdecoder::PTDecoder> pt_decoder_sp;
-};
-
-class ProcessorTraceShowInstrLog : public lldb::SBCommandPluginInterface {
-public:
- ProcessorTraceShowInstrLog(std::shared_ptr<ptdecoder::PTDecoder> &pt_decoder)
- : SBCommandPluginInterface(), pt_decoder_sp(pt_decoder) {}
-
- ~ProcessorTraceShowInstrLog() {}
-
- virtual bool DoExecute(lldb::SBDebugger debugger, char **command,
- lldb::SBCommandReturnObject &result) {
- lldb::SBProcess process;
- lldb::SBThread thread;
- if (!GetProcess(debugger, result, process))
- return false;
-
- // Default initialize API's arguments
- uint32_t offset;
- bool offset_provided = false;
- uint32_t count = m_default_count;
- lldb::tid_t thread_id;
-
- // Parse command line options
- bool thread_argument_provided = false;
- if (command) {
- for (uint32_t i = 0; command[i]; i++) {
- if (!strcmp(command[i], "-o")) {
- if (!ParseCommandOption(command, result, i, "-o", offset))
- return false;
- offset_provided = true;
- } else if (!strcmp(command[i], "-c")) {
- if (!ParseCommandOption(command, result, i, "-c", count))
- return false;
- } else {
- thread_argument_provided = true;
- if (!ParseCommandArgThread(command, result, process, i, thread_id))
- return false;
- }
- }
- }
-
- if (!thread_argument_provided) {
- thread = process.GetSelectedThread();
- if (!thread.IsValid()) {
- result.Printf("error: invalid current selected thread\n");
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
- thread_id = thread.GetThreadID();
- }
-
- size_t loop_count = 1;
- bool entire_process_tracing = false;
- if (thread_id == LLDB_INVALID_THREAD_ID) {
- entire_process_tracing = true;
- loop_count = process.GetNumThreads();
- }
-
- // Get instruction log and disassemble it
- lldb::SBError error;
- lldb::SBCommandReturnObject res;
- for (size_t i = 0; i < loop_count; i++) {
- error.Clear();
- res.Clear();
-
- if (entire_process_tracing)
- thread = process.GetThreadAtIndex(i);
- else
- thread = process.GetThreadByID(thread_id);
- thread_id = thread.GetThreadID();
-
- // If offset is not provided then calculate a default offset (to display
- // last 'count' number of instructions)
- if (!offset_provided)
- offset = count - 1;
-
- // Get the instruction log
- ptdecoder::PTInstructionList insn_list;
- pt_decoder_sp->GetInstructionLogAtOffset(process, thread_id, offset,
- count, insn_list, error);
- if (!error.Success()) {
- res.Printf("thread #%" PRIu32 ": tid=%" PRIu64 ", error: %s",
- thread.GetIndexID(), thread_id, error.GetCString());
- result.AppendMessage(res.GetOutput());
- continue;
- }
-
- // Disassemble the instruction log
- std::string disassembler_command("dis -c 1 -s ");
- res.Printf("thread #%" PRIu32 ": tid=%" PRIu64 "\n", thread.GetIndexID(),
- thread_id);
- lldb::SBCommandInterpreter sb_cmnd_interpreter(
- debugger.GetCommandInterpreter());
- lldb::SBCommandReturnObject result_obj;
- for (size_t i = 0; i < insn_list.GetSize(); i++) {
- ptdecoder::PTInstruction insn = insn_list.GetInstructionAtIndex(i);
- uint64_t addr = insn.GetInsnAddress();
- std::string error = insn.GetError();
- if (!error.empty()) {
- res.AppendMessage(error.c_str());
- continue;
- }
-
- result_obj.Clear();
- std::string complete_disassembler_command =
- disassembler_command + std::to_string(addr);
- sb_cmnd_interpreter.HandleCommand(complete_disassembler_command.c_str(),
- result_obj, false);
- std::string result_str(result_obj.GetOutput());
- if (result_str.empty()) {
- lldb::SBCommandReturnObject output;
- output.Printf(" Disassembly not found for address: %" PRIu64, addr);
- res.AppendMessage(output.GetOutput());
- continue;
- }
-
- // LLDB's disassemble command displays assembly instructions along with
- // the names of the functions they belong to. Parse this result to
- // display only the assembly instructions and not the function names
- // in an instruction log
- std::size_t first_new_line_index = result_str.find_first_of('\n');
- std::size_t last_new_line_index = result_str.find_last_of('\n');
- if (first_new_line_index != last_new_line_index)
- res.AppendMessage((result_str.substr(first_new_line_index + 1,
- last_new_line_index -
- first_new_line_index - 1))
- .c_str());
- else
- res.AppendMessage(
- (result_str.substr(0, result_str.length() - 1)).c_str());
- }
- result.AppendMessage(res.GetOutput());
- }
- result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
- return true;
- }
-
-private:
- std::shared_ptr<ptdecoder::PTDecoder> pt_decoder_sp;
- const uint32_t m_default_count = 10;
-};
-
-class ProcessorTraceStop : public lldb::SBCommandPluginInterface {
-public:
- ProcessorTraceStop(std::shared_ptr<ptdecoder::PTDecoder> &pt_decoder)
- : SBCommandPluginInterface(), pt_decoder_sp(pt_decoder) {}
-
- ~ProcessorTraceStop() {}
-
- virtual bool DoExecute(lldb::SBDebugger debugger, char **command,
- lldb::SBCommandReturnObject &result) {
- lldb::SBProcess process;
- lldb::SBThread thread;
- if (!GetProcess(debugger, result, process))
- return false;
-
- lldb::tid_t thread_id;
-
- // Parse command line options
- bool thread_argument_provided = false;
- if (command) {
- for (uint32_t i = 0; command[i]; i++) {
- thread_argument_provided = true;
- if (!ParseCommandArgThread(command, result, process, i, thread_id))
- return false;
- }
- }
-
- if (!thread_argument_provided) {
- thread = process.GetSelectedThread();
- if (!thread.IsValid()) {
- result.Printf("error: invalid current selected thread\n");
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
- thread_id = thread.GetThreadID();
- }
-
- // Stop trace
- lldb::SBError error;
- pt_decoder_sp->StopProcessorTrace(process, error, thread_id);
- if (!error.Success()) {
- result.Printf("error: %s\n", error.GetCString());
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
- result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
- return true;
- }
-
-private:
- std::shared_ptr<ptdecoder::PTDecoder> pt_decoder_sp;
-};
-
-bool PTPluginInitialize(lldb::SBDebugger &debugger) {
- lldb::SBCommandInterpreter interpreter = debugger.GetCommandInterpreter();
- lldb::SBCommand proc_trace = interpreter.AddMultiwordCommand(
- "processor-trace", "Intel(R) Processor Trace for thread/process");
-
- std::shared_ptr<ptdecoder::PTDecoder> PTDecoderSP(
- new ptdecoder::PTDecoder(debugger));
-
- lldb::SBCommandPluginInterface *proc_trace_start =
- new ProcessorTraceStart(PTDecoderSP);
- const char *help_proc_trace_start = "start Intel(R) Processor Trace on a "
- "specific thread or on the whole process";
- const char *syntax_proc_trace_start =
- "processor-trace start <cmd-options>\n\n"
- "\rcmd-options Usage:\n"
- "\r processor-trace start [-b <buffer-size>] [<thread-index>]\n\n"
- "\t\b-b <buffer-size>\n"
- "\t size of the trace buffer to store the trace data. If not "
- "specified then a default value will be taken\n\n"
- "\t\b<thread-index>\n"
- "\t thread index of the thread. If no threads are specified, "
- "currently selected thread is taken.\n"
- "\t Use the thread-index 'all' to start tracing the whole process\n";
- proc_trace.AddCommand("start", proc_trace_start, help_proc_trace_start,
- syntax_proc_trace_start);
-
- lldb::SBCommandPluginInterface *proc_trace_stop =
- new ProcessorTraceStop(PTDecoderSP);
- const char *help_proc_trace_stop =
- "stop Intel(R) Processor Trace on a specific thread or on whole process";
- const char *syntax_proc_trace_stop =
- "processor-trace stop <cmd-options>\n\n"
- "\rcmd-options Usage:\n"
- "\r processor-trace stop [<thread-index>]\n\n"
- "\t\b<thread-index>\n"
- "\t thread index of the thread. If no threads are specified, "
- "currently selected thread is taken.\n"
- "\t Use the thread-index 'all' to stop tracing the whole process\n";
- proc_trace.AddCommand("stop", proc_trace_stop, help_proc_trace_stop,
- syntax_proc_trace_stop);
-
- lldb::SBCommandPluginInterface *proc_trace_show_instr_log =
- new ProcessorTraceShowInstrLog(PTDecoderSP);
- const char *help_proc_trace_show_instr_log =
- "display a log of assembly instructions executed for a specific thread "
- "or for the whole process.\n"
- "The length of the log to be displayed and the offset in the whole "
- "instruction log from where the log needs to be displayed can also be "
- "provided. The offset is counted from the end of this whole "
- "instruction log which means the last executed instruction is at offset "
- "0 (zero)";
- const char *syntax_proc_trace_show_instr_log =
- "processor-trace show-instr-log <cmd-options>\n\n"
- "\rcmd-options Usage:\n"
- "\r processor-trace show-instr-log [-o <offset>] [-c <count>] "
- "[<thread-index>]\n\n"
- "\t\b-o <offset>\n"
- "\t offset in the whole instruction log from where the log will be "
- "displayed. If not specified then a default value will be taken\n\n"
- "\t\b-c <count>\n"
- "\t number of instructions to be displayed. If not specified then a "
- "default value will be taken\n\n"
- "\t\b<thread-index>\n"
- "\t thread index of the thread. If no threads are specified, "
- "currently selected thread is taken.\n"
- "\t Use the thread-index 'all' to show instruction log for all the "
- "threads of the process\n";
- proc_trace.AddCommand("show-instr-log", proc_trace_show_instr_log,
- help_proc_trace_show_instr_log,
- syntax_proc_trace_show_instr_log);
-
- lldb::SBCommandPluginInterface *proc_trace_options =
- new ProcessorTraceInfo(PTDecoderSP);
- const char *help_proc_trace_show_options =
- "display all the information regarding Intel(R) Processor Trace for a "
- "specific thread or for the whole process.\n"
- "The information contains trace buffer size and configuration options"
- " of Intel(R) Processor Trace.";
- const char *syntax_proc_trace_show_options =
- "processor-trace show-options <cmd-options>\n\n"
- "\rcmd-options Usage:\n"
- "\r processor-trace show-options [<thread-index>]\n\n"
- "\t\b<thread-index>\n"
- "\t thread index of the thread. If no threads are specified, "
- "currently selected thread is taken.\n"
- "\t Use the thread-index 'all' to display information for all threads "
- "of the process\n";
- proc_trace.AddCommand("show-trace-options", proc_trace_options,
- help_proc_trace_show_options,
- syntax_proc_trace_show_options);
-
- return true;
-}
diff --git a/lldb/tools/intel-features/intel-pt/cli-wrapper-pt.h b/lldb/tools/intel-features/intel-pt/cli-wrapper-pt.h
deleted file mode 100644
index 3d2fe69b0151..000000000000
--- a/lldb/tools/intel-features/intel-pt/cli-wrapper-pt.h
+++ /dev/null
@@ -1,12 +0,0 @@
-//===-- cli-wrapper-pt.h----------------------------------*- C++ -*-==========//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-// CLI Wrapper of PTDecoder Tool to enable it to be used through LLDB's CLI.
-//===----------------------------------------------------------------------===//
-
-#include "lldb/API/SBDebugger.h"
-
-bool PTPluginInitialize(lldb::SBDebugger &debugger);
diff --git a/lldb/tools/intel-features/intel-pt/interface/PTDecoder.i b/lldb/tools/intel-features/intel-pt/interface/PTDecoder.i
deleted file mode 100644
index f662b8ff3599..000000000000
--- a/lldb/tools/intel-features/intel-pt/interface/PTDecoder.i
+++ /dev/null
@@ -1,10 +0,0 @@
-%include "stdint.i"
-
-%include "lldb/lldb-defines.h"
-%include "lldb/lldb-enumerations.h"
-%include "lldb/lldb-forward.h"
-%include "lldb/lldb-types.h"
-
-%include "lldb/API/SBDefines.h"
-
-%include "../PTDecoder.h"
diff --git a/lldb/tools/intel-features/scripts/CMakeLists.txt b/lldb/tools/intel-features/scripts/CMakeLists.txt
deleted file mode 100644
index 6df97a4b006d..000000000000
--- a/lldb/tools/intel-features/scripts/CMakeLists.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-file(GLOB_RECURSE SWIG_SOURCES *.swig)
-
-set(FLAGS
- -c++
- -shadow
- -python
- -D__STDC_LIMIT_MACROS
- -D__STDC_CONSTANT_MACROS
- )
-
-set(INCLUDES
- -I${LLDB_SOURCE_DIR}/include
- -I${LLDB_SOURCE_DIR}/tools/intel-features/intel-pt
- )
-
-set(OUTPUT_PYTHON_WRAPPER
- ${CMAKE_CURRENT_BINARY_DIR}/IntelFeaturesPythonWrap.cpp
- )
-
-set(OUTPUT_PYTHON_SCRIPT_DIR
- ${CMAKE_CURRENT_BINARY_DIR}
- )
-
-find_package(SWIG REQUIRED)
-add_custom_command(
- OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/IntelFeaturesPythonWrap.cpp
- OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lldbIntelFeatures.py
- DEPENDS ${SWIG_SOURCES}
- COMMAND ${SWIG_EXECUTABLE} ${FLAGS} ${INCLUDES} -o ${OUTPUT_PYTHON_WRAPPER} -outdir ${OUTPUT_PYTHON_SCRIPT_DIR} ${SWIG_SOURCES}
- COMMENT "Generating python wrapper for features library")
-
-set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/IntelFeaturesPythonWrap.cpp PROPERTIES GENERATED 1)
-set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/lldbIntelFeatures.py PROPERTIES GENERATED 1)
-
-add_custom_target(intel-features-swig_wrapper ALL
- DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/IntelFeaturesPythonWrap.cpp
- )
diff --git a/lldb/tools/intel-features/scripts/lldb-intel-features.swig b/lldb/tools/intel-features/scripts/lldb-intel-features.swig
deleted file mode 100644
index c035fb6132dd..000000000000
--- a/lldb/tools/intel-features/scripts/lldb-intel-features.swig
+++ /dev/null
@@ -1,16 +0,0 @@
-%module lldbIntelFeatures
-
-%{
-#include "lldb/lldb-public.h"
-#include "intel-pt/PTDecoder.h"
-using namespace ptdecoder;
-%}
-
-/* Undefine GCC keyword to make Swig happy when processing glibc's stdint.h */
-#define __extension__
-
-/* Combined python typemap for all features */
-%include "python-typemaps.txt"
-
-/* Feature specific python interface files*/
-%include "../intel-pt/interface/PTDecoder.i"
diff --git a/lldb/tools/intel-features/scripts/python-typemaps.txt b/lldb/tools/intel-features/scripts/python-typemaps.txt
deleted file mode 100644
index 888d5321393f..000000000000
--- a/lldb/tools/intel-features/scripts/python-typemaps.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Typemap definitions to allow SWIG to properly handle some data types */
-
-// typemap for an incoming buffer
-%typemap(in) (void *buf, size_t size) {
- if (PyInt_Check($input)) {
- $2 = PyInt_AsLong($input);
- } else if (PyLong_Check($input)) {
- $2 = PyLong_AsLong($input);
- } else {
- PyErr_SetString(PyExc_ValueError, "Expecting an integer or long object");
- return NULL;
- }
- if ($2 <= 0) {
- PyErr_SetString(PyExc_ValueError, "Positive integer expected");
- return NULL;
- }
- $1 = (void *) malloc($2);
-}
-
-// Return the buffer. Discarding any previous return result
-%typemap(argout) (void *buf, size_t size) {
- Py_XDECREF($result); /* Blow away any previous result */
- if (result == 0) {
- $result = Py_None;
- Py_INCREF($result);
- } else {
- PyObject *py_bytes = PyBytes_FromStringAndSize(reinterpret_cast<const char*>($1), result);
- $result = py_bytes;
- }
- free($1);
-}
More information about the lldb-commits
mailing list