Linux Audio

Check our new training course

Buildroot integration, development and maintenance

Need a Buildroot system for your embedded project?
Loading...
v5.4
  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}
v6.8
  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 <stdlib.h>
  9#include <stdint.h>
 10#include <inttypes.h>
 11#include <stdarg.h>
 12#include <stdbool.h>
 13#include <string.h>
 14
 15#include <linux/zalloc.h>
 16#include <linux/kernel.h>
 17
 18#include "intel-pt-log.h"
 19#include "intel-pt-insn-decoder.h"
 20
 21#include "intel-pt-pkt-decoder.h"
 22
 23#define MAX_LOG_NAME 256
 24
 25#define DFLT_BUF_SZ	(16 * 1024)
 26
 27struct log_buf {
 28	char			*buf;
 29	size_t			buf_sz;
 30	size_t			head;
 31	bool			wrapped;
 32	FILE			*backend;
 33};
 34
 35static FILE *f;
 36static char log_name[MAX_LOG_NAME];
 37bool intel_pt_enable_logging;
 38static bool intel_pt_dump_log_on_error;
 39static unsigned int intel_pt_log_on_error_size;
 40static struct log_buf log_buf;
 41
 42void *intel_pt_log_fp(void)
 43{
 44	return f;
 45}
 46
 47void intel_pt_log_enable(bool dump_log_on_error, unsigned int log_on_error_size)
 48{
 49	intel_pt_enable_logging = true;
 50	intel_pt_dump_log_on_error = dump_log_on_error;
 51	intel_pt_log_on_error_size = log_on_error_size;
 52}
 53
 54void intel_pt_log_disable(void)
 55{
 56	if (f)
 57		fflush(f);
 58	intel_pt_enable_logging = false;
 59}
 60
 61void intel_pt_log_set_name(const char *name)
 62{
 63	strncpy(log_name, name, MAX_LOG_NAME - 5);
 64	strcat(log_name, ".log");
 65}
 66
 67static void intel_pt_print_data(const unsigned char *buf, int len, uint64_t pos,
 68				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 < len; i++)
 77		fprintf(f, " %02x", buf[i]);
 78	for (; i < 16; i++)
 79		fprintf(f, "   ");
 80	fprintf(f, " ");
 81}
 82
 83static void intel_pt_print_no_data(uint64_t pos, int indent)
 84{
 85	int i;
 86
 87	for (i = 0; i < indent; i++)
 88		fprintf(f, " ");
 89
 90	fprintf(f, "  %08" PRIx64 ": ", pos);
 91	for (i = 0; i < 16; i++)
 92		fprintf(f, "   ");
 93	fprintf(f, " ");
 94}
 95
 96static ssize_t log_buf__write(void *cookie, const char *buf, size_t size)
 97{
 98	struct log_buf *b = cookie;
 99	size_t sz = size;
100
101	if (!b->buf)
102		return size;
103
104	while (sz) {
105		size_t space = b->buf_sz - b->head;
106		size_t n = min(space, sz);
107
108		memcpy(b->buf + b->head, buf, n);
109		sz -= n;
110		buf += n;
111		b->head += n;
112		if (sz && b->head >= b->buf_sz) {
113			b->head = 0;
114			b->wrapped = true;
115		}
116	}
117	return size;
118}
119
120static int log_buf__close(void *cookie)
121{
122	struct log_buf *b = cookie;
123
124	zfree(&b->buf);
125	return 0;
126}
127
128static FILE *log_buf__open(struct log_buf *b, FILE *backend, unsigned int sz)
129{
130	cookie_io_functions_t fns = {
131		.write = log_buf__write,
132		.close = log_buf__close,
133	};
134	FILE *file;
135
136	memset(b, 0, sizeof(*b));
137	b->buf_sz = sz;
138	b->buf = malloc(b->buf_sz);
139	b->backend = backend;
140	file = fopencookie(b, "a", fns);
141	if (!file)
142		zfree(&b->buf);
143	return file;
144}
145
146static bool remove_first_line(const char **p, size_t *n)
147{
148	for (; *n && **p != '\n'; ++*p, --*n)
149		;
150	if (*n) {
151		*p += 1;
152		*n -= 1;
153		return true;
154	}
155	return false;
156}
157
158static void write_lines(const char *p, size_t n, FILE *fp, bool *remove_first)
159{
160	if (*remove_first)
161		*remove_first = !remove_first_line(&p, &n);
162	fwrite(p, n, 1, fp);
163}
164
165static void log_buf__dump(struct log_buf *b)
166{
167	bool remove_first = false;
168
169	if (!b->buf)
170		return;
171
172	fflush(f); /* Could update b->head and b->wrapped */
173	fprintf(b->backend, "Dumping debug log buffer\n");
174	if (b->wrapped) {
175		remove_first = true;
176		write_lines(b->buf + b->head, b->buf_sz - b->head, b->backend, &remove_first);
177	}
178	write_lines(b->buf, b->head, b->backend, &remove_first);
179	fprintf(b->backend, "End of debug log buffer dump\n");
180
181	b->head = 0;
182	b->wrapped = false;
183}
184
185void intel_pt_log_dump_buf(void)
186{
187	log_buf__dump(&log_buf);
188}
189
190static int intel_pt_log_open(void)
191{
192	if (!intel_pt_enable_logging)
193		return -1;
194
195	if (f)
196		return 0;
197
198	if (log_name[0])
199		f = fopen(log_name, "w+");
200	else
201		f = stdout;
202	if (f && intel_pt_dump_log_on_error)
203		f = log_buf__open(&log_buf, f, intel_pt_log_on_error_size);
204	if (!f) {
205		intel_pt_enable_logging = false;
206		return -1;
207	}
208
209	return 0;
210}
211
212void __intel_pt_log_packet(const struct intel_pt_pkt *packet, int pkt_len,
213			   uint64_t pos, const unsigned char *buf)
214{
215	char desc[INTEL_PT_PKT_DESC_MAX];
216
217	if (intel_pt_log_open())
218		return;
219
220	intel_pt_print_data(buf, pkt_len, pos, 0);
221	intel_pt_pkt_desc(packet, desc, INTEL_PT_PKT_DESC_MAX);
222	fprintf(f, "%s\n", desc);
223}
224
225void __intel_pt_log_insn(struct intel_pt_insn *intel_pt_insn, uint64_t ip)
226{
227	char desc[INTEL_PT_INSN_DESC_MAX];
228	size_t len = intel_pt_insn->length;
229
230	if (intel_pt_log_open())
231		return;
232
233	if (len > INTEL_PT_INSN_BUF_SZ)
234		len = INTEL_PT_INSN_BUF_SZ;
235	intel_pt_print_data(intel_pt_insn->buf, len, ip, 8);
236	if (intel_pt_insn_desc(intel_pt_insn, desc, INTEL_PT_INSN_DESC_MAX) > 0)
237		fprintf(f, "%s\n", desc);
238	else
239		fprintf(f, "Bad instruction!\n");
240}
241
242void __intel_pt_log_insn_no_data(struct intel_pt_insn *intel_pt_insn,
243				 uint64_t ip)
244{
245	char desc[INTEL_PT_INSN_DESC_MAX];
246
247	if (intel_pt_log_open())
248		return;
249
250	intel_pt_print_no_data(ip, 8);
251	if (intel_pt_insn_desc(intel_pt_insn, desc, INTEL_PT_INSN_DESC_MAX) > 0)
252		fprintf(f, "%s\n", desc);
253	else
254		fprintf(f, "Bad instruction!\n");
255}
256
257void __intel_pt_log(const char *fmt, ...)
258{
259	va_list args;
260
261	if (intel_pt_log_open())
262		return;
263
264	va_start(args, fmt);
265	vfprintf(f, fmt, args);
266	va_end(args);
267}