/** @file * DBGF - Debugger Facility, Guest execution flow tracing. */ /* * Copyright (C) 2020-2024 Oracle and/or its affiliates. * * This file is part of VirtualBox base platform packages, as * available from https://www.virtualbox.org. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, in version 3 of the * License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * The contents of this file may alternatively be used under the terms * of the Common Development and Distribution License Version 1.0 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included * in the VirtualBox distribution, in which case the provisions of the * CDDL are applicable instead of those of the GPL. * * You may elect to license modified versions of this file under the * terms and conditions of either the GPL or the CDDL or both. * * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 */ #ifndef VBOX_INCLUDED_vmm_dbgfflowtrace_h #define VBOX_INCLUDED_vmm_dbgfflowtrace_h #ifndef RT_WITHOUT_PRAGMA_ONCE # pragma once #endif #include #include RT_C_DECLS_BEGIN /** @defgroup grp_dbgf_flowtrace Guest Execution Flow Tracing * @ingroup grp_dbgf * * @{ */ /** A DBGF flow trace module handle. */ typedef struct DBGFFLOWTRACEMODINT *DBGFFLOWTRACEMOD; /** Pointer to a DBGF flow trace module handle. */ typedef DBGFFLOWTRACEMOD *PDBGFFLOWTRACEMOD; /** A DBGF flow trace probe handle. */ typedef struct DBGFFLOWTRACEPROBEINT *DBGFFLOWTRACEPROBE; /** Pointer to a DBGF flow trace state probe handle. */ typedef DBGFFLOWTRACEPROBE *PDBGFFLOWTRACEPROBE; /** A DBGF flow trace report handle. */ typedef struct DBGFFLOWTRACEREPORTINT *DBGFFLOWTRACEREPORT; /** Pointer to a DBGF flow trace report handle. */ typedef DBGFFLOWTRACEREPORT *PDBGFFLOWTRACEREPORT; /** A DBGF flow trace record handle. */ typedef struct DBGFFLOWTRACERECORDINT *DBGFFLOWTRACERECORD; /** Pointer to a DBGF flow trace record handle. */ typedef DBGFFLOWTRACERECORD *PDBGFFLOWTRACERECORD; /** Pointer to a flow trace probe entry. */ typedef struct DBGFFLOWTRACEPROBEENTRY *PDBGFFLOWTRACEPROBEENTRY; /** Pointer to a const flow trace probe entry. */ typedef const struct DBGFFLOWTRACEPROBEENTRY *PCDBGFFLOWTRACEPROBEENTRY; /** @name Flags controlling the type of the addition of a single probe. * @{ */ /** Default options. */ #define DBGF_FLOW_TRACE_PROBE_ADD_F_DEFAULT DBGF_FLOW_TRACE_PROBE_ADD_F_BEFORE_EXEC /** Collects the data specified by the data probe before the instruction is executed. */ #define DBGF_FLOW_TRACE_PROBE_ADD_F_BEFORE_EXEC RT_BIT_32(0) /** Collects the data specified by the data probe after the instruction was executed. */ #define DBGF_FLOW_TRACE_PROBE_ADD_F_AFTER_EXEC RT_BIT_32(1) /** Mask of all valid flags. */ #define DBGF_FLOW_TRACE_PROBE_ADD_F_VALID_MASK ( DBGF_FLOW_TRACE_PROBE_ADD_F_BEFORE_EXEC \ | DBGF_FLOW_TRACE_PROBE_ADD_F_AFTER_EXEC) /** @} */ /** * Probe entry type. */ typedef enum DBGFFLOWTRACEPROBEENTRYTYPE { /** Invalid type. */ DBGFFLOWTRACEPROBEENTRYTYPE_INVALID = 0, /** Register. */ DBGFFLOWTRACEPROBEENTRYTYPE_REG, /** Constant memory buffer pointer. */ DBGFFLOWTRACEPROBEENTRYTYPE_CONST_MEM, /** Indirect memory buffer pointer, obtained from the base and index register * and a constant scale. */ DBGFFLOWTRACEPROBEENTRYTYPE_INDIRECT_MEM, /** Callback. */ DBGFFLOWTRACEPROBEENTRYTYPE_CALLBACK, /** Halt in the debugger when the entry is collected. */ DBGFFLOWTRACEPROBEENTRYTYPE_DEBUGGER, /** 32bit hack. */ DBGFFLOWTRACEPROBEENTRYTYPE_32BIT_HACK = 0x7fffffff } DBGFFLOWTRACEPROBEENTRYTYPE; /** * Register descriptor for a probe entry. */ typedef struct DBGFFLOWTRACEPROBEENTRYREG { /** The register name - see DBGFR3RegNm*. */ const char *pszName; /** The size of the value in bytes. */ DBGFREGVALTYPE enmType; } DBGFFLOWTRACEPROBEENTRYREG; /** Pointer to data probe register entry. */ typedef DBGFFLOWTRACEPROBEENTRYREG *PDBGFFLOWTRACEPROBEENTRYREG; /** Pointer to a const probe register entry. */ typedef const DBGFFLOWTRACEPROBEENTRYREG *PCDBGFFLOWTRACEPROBEENTRYREG; /** * Flow trace probe callback. * * @returns VBox status code, any error aborts continuing fetching the data for the * probe containing this callback. * @param pUVM The usermode VM handle. * @param idCpu The ID of the vCPU the probe as fired. * @param hFlowTraceMod The handle to the flow trace module the probe was fired for. * @param pAddrProbe The guest address the probe was fired at. * @param hFlowTraceProbe The flow trace probe handle.this callback is in. * @param pProbeEntry The probe entry this callback is part of. * @param pvUser The opaque user data for the callback. */ typedef DECLCALLBACKTYPE(int, FNDBGFFLOWTRACEPROBECALLBACK, (PUVM pUVM, VMCPUID idCpu, DBGFFLOWTRACEMOD hFlowTraceMod, PCDBGFADDRESS pAddrProbe, DBGFFLOWTRACEPROBE hFlowTraceProbe, PCDBGFFLOWTRACEPROBEENTRY pProbeEntry, void *pvUser)); /** Pointer to a flow trace probe callback. */ typedef FNDBGFFLOWTRACEPROBECALLBACK *PFNDBGFFLOWTRACEPROBECALLBACK; /** * Trace flow probe entry. */ typedef struct DBGFFLOWTRACEPROBEENTRY { /** Entry type. */ DBGFFLOWTRACEPROBEENTRYTYPE enmType; /** Description for this entry, optional. */ const char *pszDesc; /** The data based on the entry type. */ union { /** Register. */ DBGFFLOWTRACEPROBEENTRYREG Reg; /** Constant memory pointer. */ struct { /** The address of the memory buffer. */ DBGFADDRESS AddrMem; /** Number of bytes to log. */ size_t cbMem; } ConstMem; /** Indirect memory */ struct { /** The base register. */ DBGFFLOWTRACEPROBEENTRYREG RegBase; /** The index register. */ DBGFFLOWTRACEPROBEENTRYREG RegIndex; /** The scale to apply to the index. */ uint8_t uScale; /** A constant offset which is applied at the end. */ RTGCINTPTR iOffset; /** Number of bytes to log. */ size_t cbMem; } IndirectMem; /** Callback. */ struct { /** The callback to call. */ PFNDBGFFLOWTRACEPROBECALLBACK pfnCallback; /** The opaque user data to provide. */ void *pvUser; } Callback; } Type; } DBGFFLOWTRACEPROBEENTRY; /** * Flow trace probe value. */ typedef struct DBGFFLOWTRACEPROBEVAL { /** Pointer to the flow trace probe entry this value is for. */ PCDBGFFLOWTRACEPROBEENTRY pProbeEntry; /** Data based on the type in the entry. */ union { /** Register value. */ DBGFREGENTRYNM Reg; /** Memory value (constant pointer or indirect). */ struct { /** The guest address logged. */ DBGFADDRESS Addr; /** Pointer to the data logged. */ const void *pvBuf; /** Number of bytes logged. */ size_t cbBuf; } Mem; } Type; } DBGFFLOWTRACEPROBEVAL; /** Pointer to a flow trace probe value. */ typedef DBGFFLOWTRACEPROBEVAL *PDBGFFLOWTRACEPROBEVAL; /** Pointer to a const flow trace probe value. */ typedef const DBGFFLOWTRACEPROBEVAL *PCDBGFFLOWTRACEPROBEVAL; /** * Flow trace report filter operation. */ typedef enum DBGFFLOWTRACEREPORTFILTEROP { /** Invalid filter operation. */ DBGFFLOWTRACEREPORTFILTEROP_INVALID = 0, /** All filters must match with the record. */ DBGFFLOWTRACEREPORTFILTEROP_AND, /** Only one filter must match with the record. */ DBGFFLOWTRACEREPORTFILTEROP_OR, /** 32bit hack. */ DBGFFLOWTRACEREPORTFILTEROP_32BIT_HACK = 0x7fffffff } DBGFFLOWTRACEREPORTFILTEROP; /** * Flow trace report filter type. */ typedef enum DBGFFLOWTRACEREPORTFILTERTYPE { /** Invalid filter type. */ DBGFFLOWTRACEREPORTFILTERTYPE_INVALID = 0, /** Filter by sequence number. */ DBGFFLOWTRACEREPORTFILTERTYPE_SEQ_NUM, /** Filter by timestamp. */ DBGFFLOWTRACEREPORTFILTERTYPE_TIMESTAMP, /** Filter by probe address. */ DBGFFLOWTRACEREPORTFILTERTYPE_ADDR, /** Filter by CPU ID. */ DBGFFLOWTRACEREPORTFILTERTYPE_VMCPU_ID, /** Filter by specific probe data. */ DBGFFLOWTRACEREPORTFILTERTYPE_PROBE_DATA, /** 32bit hack. */ DBGFFLOWTRACEREPORTFILTERTYPE_32BIT_HACK = 0x7fffffff } DBGFFLOWTRACEREPORTFILTERTYPE; /** * Flow trace report filter. */ typedef struct DBGFFLOWTRACEREPORTFILTER { /** Filter type. */ DBGFFLOWTRACEREPORTFILTERTYPE enmType; /** Filter data, type dependent. */ struct { /** Sequence number filtering. */ struct { /** Sequence number filtering, start value. */ uint64_t u64SeqNoFirst; /** Sequence number filtering, last value. */ uint64_t u64SeqNoLast; } SeqNo; /** Timestamp filtering. */ struct { /** Start value. */ uint64_t u64TsFirst; /** Last value. */ uint64_t u64TsLast; } Timestamp; /** Probe address filtering. */ struct { /** Start address. */ DBGFADDRESS AddrStart; /** Last address. */ DBGFADDRESS AddrLast; } Addr; /** vCPU id filtering. */ struct { /** Start CPU id. */ VMCPUID idCpuStart; /** Last CPU id. */ VMCPUID idCpuLast; } VCpuId; /** Probe data filtering. */ struct { /** Pointer to the probe value array. */ PCDBGFFLOWTRACEPROBEVAL paVal; /** Number of entries in the array for filtering. */ uint32_t cVals; /** Flag whether to look into the common values or the probe specific ones. */ bool fValCmn; } ProbeData; } Type; } DBGFFLOWTRACEREPORTFILTER; /** Pointer to a flow trace report filter. */ typedef DBGFFLOWTRACEREPORTFILTER *PDBGFFLOWTRACEREPORTFILTER; /** @name Flags controlling filtering records. * @{ */ /** Add records which don't match the filter. */ #define DBGF_FLOW_TRACE_REPORT_FILTER_F_REVERSE RT_BIT_32(0) /** Mask of all valid flags. */ #define DBGF_FLOW_TRACE_REPORT_FILTER_F_VALID (DBGF_FLOW_TRACE_REPORT_FILTER_F_REVERSE) /** @} */ /** * Flow trace report enumeration callback. * * @returns VBox status code, any non VINF_SUCCESS code aborts the enumeration and is returned * by DBGFR3FlowTraceReportEnumRecords(). * @param hFlowTraceReport The flow trace report handle being enumerated. * @param hFlowTraceRecord The flow trace record handle. * @param pvUser Opaque user data given in DBGFR3FlowTraceReportEnumRecords(). */ typedef DECLCALLBACKTYPE(int, FNDBGFFLOWTRACEREPORTENUMCLBK,(DBGFFLOWTRACEREPORT hFlowTraceReport, DBGFFLOWTRACERECORD hFlowTraceRecord, void *pvUser)); /** Pointer to a record enumeration callback. */ typedef FNDBGFFLOWTRACEREPORTENUMCLBK *PFNDBGFFLOWTRACEREPORTENUMCLBK; VMMR3DECL(int) DBGFR3FlowTraceModCreate(PUVM pUVM, VMCPUID idCpu, DBGFFLOWTRACEPROBE hFlowTraceProbeCommon, PDBGFFLOWTRACEMOD phFlowTraceMod); VMMR3DECL(int) DBGFR3FlowTraceModCreateFromFlowGraph(PUVM pUVM, VMCPUID idCpu, DBGFFLOW hFlow, DBGFFLOWTRACEPROBE hFlowTraceProbeCommon, DBGFFLOWTRACEPROBE hFlowTraceProbeEntry, DBGFFLOWTRACEPROBE hFlowTraceProbeRegular, DBGFFLOWTRACEPROBE hFlowTraceProbeExit, PDBGFFLOWTRACEMOD phFlowTraceMod); VMMR3DECL(uint32_t) DBGFR3FlowTraceModRetain(DBGFFLOWTRACEMOD hFlowTraceMod); VMMR3DECL(uint32_t) DBGFR3FlowTraceModRelease(DBGFFLOWTRACEMOD hFlowTraceMod); VMMR3DECL(int) DBGFR3FlowTraceModEnable(DBGFFLOWTRACEMOD hFlowTraceMod, uint32_t cHits, uint32_t cRecordsMax); VMMR3DECL(int) DBGFR3FlowTraceModDisable(DBGFFLOWTRACEMOD hFlowTraceMod); VMMR3DECL(int) DBGFR3FlowTraceModQueryReport(DBGFFLOWTRACEMOD hFlowTraceMod, PDBGFFLOWTRACEREPORT phFlowTraceReport); VMMR3DECL(int) DBGFR3FlowTraceModClear(DBGFFLOWTRACEMOD hFlowTraceMod); VMMR3DECL(int) DBGFR3FlowTraceModAddProbe(DBGFFLOWTRACEMOD hFlowTraceMod, PCDBGFADDRESS pAddrProbe, DBGFFLOWTRACEPROBE hFlowTraceProbe, uint32_t fFlags); VMMR3DECL(int) DBGFR3FlowTraceProbeCreate(PUVM pUVM, const char *pszDescr, PDBGFFLOWTRACEPROBE phFlowTraceProbe); VMMR3DECL(uint32_t) DBGFR3FlowTraceProbeRetain(DBGFFLOWTRACEPROBE hFlowTraceProbe); VMMR3DECL(uint32_t) DBGFR3FlowTraceProbeRelease(DBGFFLOWTRACEPROBE hFlowTraceProbe); VMMR3DECL(int) DBGFR3FlowTraceProbeEntriesAdd(DBGFFLOWTRACEPROBE hFlowTraceProbe, PCDBGFFLOWTRACEPROBEENTRY paEntries, uint32_t cEntries); VMMR3DECL(uint32_t) DBGFR3FlowTraceReportRetain(DBGFFLOWTRACEREPORT hFlowTraceReport); VMMR3DECL(uint32_t) DBGFR3FlowTraceReportRelease(DBGFFLOWTRACEREPORT hFlowTraceReport); VMMR3DECL(uint32_t) DBGFR3FlowTraceReportGetRecordCount(DBGFFLOWTRACEREPORT hFlowTraceReport); VMMR3DECL(int) DBGFR3FlowTraceReportQueryRecord(DBGFFLOWTRACEREPORT hFlowTraceReport, uint32_t idxRec, PDBGFFLOWTRACERECORD phFlowTraceRec); VMMR3DECL(int) DBGFR3FlowTraceReportQueryFiltered(DBGFFLOWTRACEREPORT hFlowTraceReport, uint32_t fFlags, PDBGFFLOWTRACEREPORTFILTER paFilters, uint32_t cFilters, DBGFFLOWTRACEREPORTFILTEROP enmOp, PDBGFFLOWTRACEREPORT phFlowTraceReportFiltered); VMMR3DECL(int) DBGFR3FlowTraceReportEnumRecords(DBGFFLOWTRACEREPORT hFlowTraceReport, PFNDBGFFLOWTRACEREPORTENUMCLBK pfnEnum, void *pvUser); VMMR3DECL(uint32_t) DBGFR3FlowTraceRecordRetain(DBGFFLOWTRACERECORD hFlowTraceRecord); VMMR3DECL(uint32_t) DBGFR3FlowTraceRecordRelease(DBGFFLOWTRACERECORD hFlowTraceRecord); VMMR3DECL(uint64_t) DBGFR3FlowTraceRecordGetSeqNo(DBGFFLOWTRACERECORD hFlowTraceRecord); VMMR3DECL(uint64_t) DBGFR3FlowTraceRecordGetTimestamp(DBGFFLOWTRACERECORD hFlowTraceRecord); VMMR3DECL(PDBGFADDRESS) DBGFR3FlowTraceRecordGetAddr(DBGFFLOWTRACERECORD hFlowTraceRecord, PDBGFADDRESS pAddr); VMMR3DECL(DBGFFLOWTRACEPROBE) DBGFR3FlowTraceRecordGetProbe(DBGFFLOWTRACERECORD hFlowTraceRecord); VMMR3DECL(uint32_t) DBGFR3FlowTraceRecordGetValCount(DBGFFLOWTRACERECORD hFlowTraceRecord); VMMR3DECL(uint32_t) DBGFR3FlowTraceRecordGetValCommonCount(DBGFFLOWTRACERECORD hFlowTraceRecord); VMMR3DECL(PCDBGFFLOWTRACEPROBEVAL) DBGFR3FlowTraceRecordGetVals(DBGFFLOWTRACERECORD hFlowTraceRecord); VMMR3DECL(PCDBGFFLOWTRACEPROBEVAL) DBGFR3FlowTraceRecordGetValsCommon(DBGFFLOWTRACERECORD hFlowTraceRecord); VMMR3DECL(VMCPUID) DBGFR3FlowTraceRecordGetCpuId(DBGFFLOWTRACERECORD hFlowTraceRecord); /** @} */ RT_C_DECLS_END #endif /* !VBOX_INCLUDED_vmm_dbgfflowtrace_h */