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