Adding upstream version 6.12.33.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
This commit is contained in:
parent
89eabb05c2
commit
79d69e5050
86698 changed files with 39662057 additions and 0 deletions
267
tools/perf/util/intel-pt-decoder/intel-pt-log.c
Normal file
267
tools/perf/util/intel-pt-decoder/intel-pt-log.c
Normal file
|
@ -0,0 +1,267 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* intel_pt_log.c: Intel Processor Trace support
|
||||
* Copyright (c) 2013-2014, Intel Corporation.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <linux/zalloc.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include "intel-pt-log.h"
|
||||
#include "intel-pt-insn-decoder.h"
|
||||
|
||||
#include "intel-pt-pkt-decoder.h"
|
||||
|
||||
#define MAX_LOG_NAME 256
|
||||
|
||||
#define DFLT_BUF_SZ (16 * 1024)
|
||||
|
||||
struct log_buf {
|
||||
char *buf;
|
||||
size_t buf_sz;
|
||||
size_t head;
|
||||
bool wrapped;
|
||||
FILE *backend;
|
||||
};
|
||||
|
||||
static FILE *f;
|
||||
static char log_name[MAX_LOG_NAME];
|
||||
bool intel_pt_enable_logging;
|
||||
static bool intel_pt_dump_log_on_error;
|
||||
static unsigned int intel_pt_log_on_error_size;
|
||||
static struct log_buf log_buf;
|
||||
|
||||
void *intel_pt_log_fp(void)
|
||||
{
|
||||
return f;
|
||||
}
|
||||
|
||||
void intel_pt_log_enable(bool dump_log_on_error, unsigned int log_on_error_size)
|
||||
{
|
||||
intel_pt_enable_logging = true;
|
||||
intel_pt_dump_log_on_error = dump_log_on_error;
|
||||
intel_pt_log_on_error_size = log_on_error_size;
|
||||
}
|
||||
|
||||
void intel_pt_log_disable(void)
|
||||
{
|
||||
if (f)
|
||||
fflush(f);
|
||||
intel_pt_enable_logging = false;
|
||||
}
|
||||
|
||||
void intel_pt_log_set_name(const char *name)
|
||||
{
|
||||
strncpy(log_name, name, MAX_LOG_NAME - 5);
|
||||
strcat(log_name, ".log");
|
||||
}
|
||||
|
||||
static void intel_pt_print_data(const unsigned char *buf, int len, uint64_t pos,
|
||||
int indent)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < indent; i++)
|
||||
fprintf(f, " ");
|
||||
|
||||
fprintf(f, " %08" PRIx64 ": ", pos);
|
||||
for (i = 0; i < len; i++)
|
||||
fprintf(f, " %02x", buf[i]);
|
||||
for (; i < 16; i++)
|
||||
fprintf(f, " ");
|
||||
fprintf(f, " ");
|
||||
}
|
||||
|
||||
static void intel_pt_print_no_data(uint64_t pos, int indent)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < indent; i++)
|
||||
fprintf(f, " ");
|
||||
|
||||
fprintf(f, " %08" PRIx64 ": ", pos);
|
||||
for (i = 0; i < 16; i++)
|
||||
fprintf(f, " ");
|
||||
fprintf(f, " ");
|
||||
}
|
||||
|
||||
static ssize_t log_buf__write(void *cookie, const char *buf, size_t size)
|
||||
{
|
||||
struct log_buf *b = cookie;
|
||||
size_t sz = size;
|
||||
|
||||
if (!b->buf)
|
||||
return size;
|
||||
|
||||
while (sz) {
|
||||
size_t space = b->buf_sz - b->head;
|
||||
size_t n = min(space, sz);
|
||||
|
||||
memcpy(b->buf + b->head, buf, n);
|
||||
sz -= n;
|
||||
buf += n;
|
||||
b->head += n;
|
||||
if (sz && b->head >= b->buf_sz) {
|
||||
b->head = 0;
|
||||
b->wrapped = true;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
static int log_buf__close(void *cookie)
|
||||
{
|
||||
struct log_buf *b = cookie;
|
||||
|
||||
zfree(&b->buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FILE *log_buf__open(struct log_buf *b, FILE *backend, unsigned int sz)
|
||||
{
|
||||
cookie_io_functions_t fns = {
|
||||
.write = log_buf__write,
|
||||
.close = log_buf__close,
|
||||
};
|
||||
FILE *file;
|
||||
|
||||
memset(b, 0, sizeof(*b));
|
||||
b->buf_sz = sz;
|
||||
b->buf = malloc(b->buf_sz);
|
||||
b->backend = backend;
|
||||
file = fopencookie(b, "a", fns);
|
||||
if (!file)
|
||||
zfree(&b->buf);
|
||||
return file;
|
||||
}
|
||||
|
||||
static bool remove_first_line(const char **p, size_t *n)
|
||||
{
|
||||
for (; *n && **p != '\n'; ++*p, --*n)
|
||||
;
|
||||
if (*n) {
|
||||
*p += 1;
|
||||
*n -= 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void write_lines(const char *p, size_t n, FILE *fp, bool *remove_first)
|
||||
{
|
||||
if (*remove_first)
|
||||
*remove_first = !remove_first_line(&p, &n);
|
||||
fwrite(p, n, 1, fp);
|
||||
}
|
||||
|
||||
static void log_buf__dump(struct log_buf *b)
|
||||
{
|
||||
bool remove_first = false;
|
||||
|
||||
if (!b->buf)
|
||||
return;
|
||||
|
||||
fflush(f); /* Could update b->head and b->wrapped */
|
||||
fprintf(b->backend, "Dumping debug log buffer\n");
|
||||
if (b->wrapped) {
|
||||
remove_first = true;
|
||||
write_lines(b->buf + b->head, b->buf_sz - b->head, b->backend, &remove_first);
|
||||
}
|
||||
write_lines(b->buf, b->head, b->backend, &remove_first);
|
||||
fprintf(b->backend, "End of debug log buffer dump\n");
|
||||
|
||||
b->head = 0;
|
||||
b->wrapped = false;
|
||||
}
|
||||
|
||||
void intel_pt_log_dump_buf(void)
|
||||
{
|
||||
log_buf__dump(&log_buf);
|
||||
}
|
||||
|
||||
static int intel_pt_log_open(void)
|
||||
{
|
||||
if (!intel_pt_enable_logging)
|
||||
return -1;
|
||||
|
||||
if (f)
|
||||
return 0;
|
||||
|
||||
if (log_name[0])
|
||||
f = fopen(log_name, "w+");
|
||||
else
|
||||
f = stdout;
|
||||
if (f && intel_pt_dump_log_on_error)
|
||||
f = log_buf__open(&log_buf, f, intel_pt_log_on_error_size);
|
||||
if (!f) {
|
||||
intel_pt_enable_logging = false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __intel_pt_log_packet(const struct intel_pt_pkt *packet, int pkt_len,
|
||||
uint64_t pos, const unsigned char *buf)
|
||||
{
|
||||
char desc[INTEL_PT_PKT_DESC_MAX];
|
||||
|
||||
if (intel_pt_log_open())
|
||||
return;
|
||||
|
||||
intel_pt_print_data(buf, pkt_len, pos, 0);
|
||||
intel_pt_pkt_desc(packet, desc, INTEL_PT_PKT_DESC_MAX);
|
||||
fprintf(f, "%s\n", desc);
|
||||
}
|
||||
|
||||
void __intel_pt_log_insn(struct intel_pt_insn *intel_pt_insn, uint64_t ip)
|
||||
{
|
||||
char desc[INTEL_PT_INSN_DESC_MAX];
|
||||
size_t len = intel_pt_insn->length;
|
||||
|
||||
if (intel_pt_log_open())
|
||||
return;
|
||||
|
||||
if (len > INTEL_PT_INSN_BUF_SZ)
|
||||
len = INTEL_PT_INSN_BUF_SZ;
|
||||
intel_pt_print_data(intel_pt_insn->buf, len, ip, 8);
|
||||
if (intel_pt_insn_desc(intel_pt_insn, desc, INTEL_PT_INSN_DESC_MAX) > 0)
|
||||
fprintf(f, "%s\n", desc);
|
||||
else
|
||||
fprintf(f, "Bad instruction!\n");
|
||||
}
|
||||
|
||||
void __intel_pt_log_insn_no_data(struct intel_pt_insn *intel_pt_insn,
|
||||
uint64_t ip)
|
||||
{
|
||||
char desc[INTEL_PT_INSN_DESC_MAX];
|
||||
|
||||
if (intel_pt_log_open())
|
||||
return;
|
||||
|
||||
intel_pt_print_no_data(ip, 8);
|
||||
if (intel_pt_insn_desc(intel_pt_insn, desc, INTEL_PT_INSN_DESC_MAX) > 0)
|
||||
fprintf(f, "%s\n", desc);
|
||||
else
|
||||
fprintf(f, "Bad instruction!\n");
|
||||
}
|
||||
|
||||
void __intel_pt_log(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
if (intel_pt_log_open())
|
||||
return;
|
||||
|
||||
va_start(args, fmt);
|
||||
vfprintf(f, fmt, args);
|
||||
va_end(args);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue