Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.1-rc5 161 lines 3.3 kB view raw
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_fp(void) 35{ 36 return f; 37} 38 39void intel_pt_log_enable(void) 40{ 41 intel_pt_enable_logging = true; 42} 43 44void intel_pt_log_disable(void) 45{ 46 if (f) 47 fflush(f); 48 intel_pt_enable_logging = false; 49} 50 51void intel_pt_log_set_name(const char *name) 52{ 53 strncpy(log_name, name, MAX_LOG_NAME - 5); 54 strcat(log_name, ".log"); 55} 56 57static void intel_pt_print_data(const unsigned char *buf, int len, uint64_t pos, 58 int indent) 59{ 60 int i; 61 62 for (i = 0; i < indent; i++) 63 fprintf(f, " "); 64 65 fprintf(f, " %08" PRIx64 ": ", pos); 66 for (i = 0; i < len; i++) 67 fprintf(f, " %02x", buf[i]); 68 for (; i < 16; i++) 69 fprintf(f, " "); 70 fprintf(f, " "); 71} 72 73static void intel_pt_print_no_data(uint64_t pos, int indent) 74{ 75 int i; 76 77 for (i = 0; i < indent; i++) 78 fprintf(f, " "); 79 80 fprintf(f, " %08" PRIx64 ": ", pos); 81 for (i = 0; i < 16; i++) 82 fprintf(f, " "); 83 fprintf(f, " "); 84} 85 86static int intel_pt_log_open(void) 87{ 88 if (!intel_pt_enable_logging) 89 return -1; 90 91 if (f) 92 return 0; 93 94 if (!log_name[0]) 95 return -1; 96 97 f = fopen(log_name, "w+"); 98 if (!f) { 99 intel_pt_enable_logging = false; 100 return -1; 101 } 102 103 return 0; 104} 105 106void __intel_pt_log_packet(const struct intel_pt_pkt *packet, int pkt_len, 107 uint64_t pos, const unsigned char *buf) 108{ 109 char desc[INTEL_PT_PKT_DESC_MAX]; 110 111 if (intel_pt_log_open()) 112 return; 113 114 intel_pt_print_data(buf, pkt_len, pos, 0); 115 intel_pt_pkt_desc(packet, desc, INTEL_PT_PKT_DESC_MAX); 116 fprintf(f, "%s\n", desc); 117} 118 119void __intel_pt_log_insn(struct intel_pt_insn *intel_pt_insn, uint64_t ip) 120{ 121 char desc[INTEL_PT_INSN_DESC_MAX]; 122 size_t len = intel_pt_insn->length; 123 124 if (intel_pt_log_open()) 125 return; 126 127 if (len > INTEL_PT_INSN_BUF_SZ) 128 len = INTEL_PT_INSN_BUF_SZ; 129 intel_pt_print_data(intel_pt_insn->buf, len, ip, 8); 130 if (intel_pt_insn_desc(intel_pt_insn, desc, INTEL_PT_INSN_DESC_MAX) > 0) 131 fprintf(f, "%s\n", desc); 132 else 133 fprintf(f, "Bad instruction!\n"); 134} 135 136void __intel_pt_log_insn_no_data(struct intel_pt_insn *intel_pt_insn, 137 uint64_t ip) 138{ 139 char desc[INTEL_PT_INSN_DESC_MAX]; 140 141 if (intel_pt_log_open()) 142 return; 143 144 intel_pt_print_no_data(ip, 8); 145 if (intel_pt_insn_desc(intel_pt_insn, desc, INTEL_PT_INSN_DESC_MAX) > 0) 146 fprintf(f, "%s\n", desc); 147 else 148 fprintf(f, "Bad instruction!\n"); 149} 150 151void __intel_pt_log(const char *fmt, ...) 152{ 153 va_list args; 154 155 if (intel_pt_log_open()) 156 return; 157 158 va_start(args, fmt); 159 vfprintf(f, fmt, args); 160 va_end(args); 161}