linux/tools/perf/util/intel-pt-decoder/intel-pt-log.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * intel_pt_log.c: Intel Processor Trace support
   4 * Copyright (c) 2013-2014, Intel Corporation.
   5 */
   6
   7#include <stdio.h>
   8#include <stdint.h>
   9#include <inttypes.h>
  10#include <stdarg.h>
  11#include <stdbool.h>
  12#include <string.h>
  13
  14#include "intel-pt-log.h"
  15#include "intel-pt-insn-decoder.h"
  16
  17#include "intel-pt-pkt-decoder.h"
  18
  19#define MAX_LOG_NAME 256
  20
  21static FILE *f;
  22static char log_name[MAX_LOG_NAME];
  23bool intel_pt_enable_logging;
  24
  25void *intel_pt_log_fp(void)
  26{
  27        return f;
  28}
  29
  30void intel_pt_log_enable(void)
  31{
  32        intel_pt_enable_logging = true;
  33}
  34
  35void intel_pt_log_disable(void)
  36{
  37        if (f)
  38                fflush(f);
  39        intel_pt_enable_logging = false;
  40}
  41
  42void intel_pt_log_set_name(const char *name)
  43{
  44        strncpy(log_name, name, MAX_LOG_NAME - 5);
  45        strcat(log_name, ".log");
  46}
  47
  48static void intel_pt_print_data(const unsigned char *buf, int len, uint64_t pos,
  49                                int indent)
  50{
  51        int i;
  52
  53        for (i = 0; i < indent; i++)
  54                fprintf(f, " ");
  55
  56        fprintf(f, "  %08" PRIx64 ": ", pos);
  57        for (i = 0; i < len; i++)
  58                fprintf(f, " %02x", buf[i]);
  59        for (; i < 16; i++)
  60                fprintf(f, "   ");
  61        fprintf(f, " ");
  62}
  63
  64static void intel_pt_print_no_data(uint64_t pos, int indent)
  65{
  66        int i;
  67
  68        for (i = 0; i < indent; i++)
  69                fprintf(f, " ");
  70
  71        fprintf(f, "  %08" PRIx64 ": ", pos);
  72        for (i = 0; i < 16; i++)
  73                fprintf(f, "   ");
  74        fprintf(f, " ");
  75}
  76
  77static int intel_pt_log_open(void)
  78{
  79        if (!intel_pt_enable_logging)
  80                return -1;
  81
  82        if (f)
  83                return 0;
  84
  85        if (!log_name[0])
  86                return -1;
  87
  88        f = fopen(log_name, "w+");
  89        if (!f) {
  90                intel_pt_enable_logging = false;
  91                return -1;
  92        }
  93
  94        return 0;
  95}
  96
  97void __intel_pt_log_packet(const struct intel_pt_pkt *packet, int pkt_len,
  98                           uint64_t pos, const unsigned char *buf)
  99{
 100        char desc[INTEL_PT_PKT_DESC_MAX];
 101
 102        if (intel_pt_log_open())
 103                return;
 104
 105        intel_pt_print_data(buf, pkt_len, pos, 0);
 106        intel_pt_pkt_desc(packet, desc, INTEL_PT_PKT_DESC_MAX);
 107        fprintf(f, "%s\n", desc);
 108}
 109
 110void __intel_pt_log_insn(struct intel_pt_insn *intel_pt_insn, uint64_t ip)
 111{
 112        char desc[INTEL_PT_INSN_DESC_MAX];
 113        size_t len = intel_pt_insn->length;
 114
 115        if (intel_pt_log_open())
 116                return;
 117
 118        if (len > INTEL_PT_INSN_BUF_SZ)
 119                len = INTEL_PT_INSN_BUF_SZ;
 120        intel_pt_print_data(intel_pt_insn->buf, len, ip, 8);
 121        if (intel_pt_insn_desc(intel_pt_insn, desc, INTEL_PT_INSN_DESC_MAX) > 0)
 122                fprintf(f, "%s\n", desc);
 123        else
 124                fprintf(f, "Bad instruction!\n");
 125}
 126
 127void __intel_pt_log_insn_no_data(struct intel_pt_insn *intel_pt_insn,
 128                                 uint64_t ip)
 129{
 130        char desc[INTEL_PT_INSN_DESC_MAX];
 131
 132        if (intel_pt_log_open())
 133                return;
 134
 135        intel_pt_print_no_data(ip, 8);
 136        if (intel_pt_insn_desc(intel_pt_insn, desc, INTEL_PT_INSN_DESC_MAX) > 0)
 137                fprintf(f, "%s\n", desc);
 138        else
 139                fprintf(f, "Bad instruction!\n");
 140}
 141
 142void __intel_pt_log(const char *fmt, ...)
 143{
 144        va_list args;
 145
 146        if (intel_pt_log_open())
 147                return;
 148
 149        va_start(args, fmt);
 150        vfprintf(f, fmt, args);
 151        va_end(args);
 152}
 153