cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

evsel_fprintf.c (6350B)


      1// SPDX-License-Identifier: GPL-2.0
      2#include <inttypes.h>
      3#include <stdio.h>
      4#include <stdbool.h>
      5#include <traceevent/event-parse.h>
      6#include "evsel.h"
      7#include "util/evsel_fprintf.h"
      8#include "util/event.h"
      9#include "callchain.h"
     10#include "map.h"
     11#include "strlist.h"
     12#include "symbol.h"
     13#include "srcline.h"
     14#include "dso.h"
     15
     16static int comma_fprintf(FILE *fp, bool *first, const char *fmt, ...)
     17{
     18	va_list args;
     19	int ret = 0;
     20
     21	if (!*first) {
     22		ret += fprintf(fp, ",");
     23	} else {
     24		ret += fprintf(fp, ":");
     25		*first = false;
     26	}
     27
     28	va_start(args, fmt);
     29	ret += vfprintf(fp, fmt, args);
     30	va_end(args);
     31	return ret;
     32}
     33
     34static int __print_attr__fprintf(FILE *fp, const char *name, const char *val, void *priv)
     35{
     36	return comma_fprintf(fp, (bool *)priv, " %s: %s", name, val);
     37}
     38
     39int evsel__fprintf(struct evsel *evsel, struct perf_attr_details *details, FILE *fp)
     40{
     41	bool first = true;
     42	int printed = 0;
     43
     44	if (details->event_group) {
     45		struct evsel *pos;
     46
     47		if (!evsel__is_group_leader(evsel))
     48			return 0;
     49
     50		if (evsel->core.nr_members > 1)
     51			printed += fprintf(fp, "%s{", evsel->group_name ?: "");
     52
     53		printed += fprintf(fp, "%s", evsel__name(evsel));
     54		for_each_group_member(pos, evsel)
     55			printed += fprintf(fp, ",%s", evsel__name(pos));
     56
     57		if (evsel->core.nr_members > 1)
     58			printed += fprintf(fp, "}");
     59		goto out;
     60	}
     61
     62	printed += fprintf(fp, "%s", evsel__name(evsel));
     63
     64	if (details->verbose) {
     65		printed += perf_event_attr__fprintf(fp, &evsel->core.attr,
     66						    __print_attr__fprintf, &first);
     67	} else if (details->freq) {
     68		const char *term = "sample_freq";
     69
     70		if (!evsel->core.attr.freq)
     71			term = "sample_period";
     72
     73		printed += comma_fprintf(fp, &first, " %s=%" PRIu64,
     74					 term, (u64)evsel->core.attr.sample_freq);
     75	}
     76
     77	if (details->trace_fields) {
     78		struct tep_format_field *field;
     79
     80		if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT) {
     81			printed += comma_fprintf(fp, &first, " (not a tracepoint)");
     82			goto out;
     83		}
     84
     85		field = evsel->tp_format->format.fields;
     86		if (field == NULL) {
     87			printed += comma_fprintf(fp, &first, " (no trace field)");
     88			goto out;
     89		}
     90
     91		printed += comma_fprintf(fp, &first, " trace_fields: %s", field->name);
     92
     93		field = field->next;
     94		while (field) {
     95			printed += comma_fprintf(fp, &first, "%s", field->name);
     96			field = field->next;
     97		}
     98	}
     99out:
    100	fputc('\n', fp);
    101	return ++printed;
    102}
    103
    104#ifndef PYTHON_PERF
    105int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment,
    106			      unsigned int print_opts, struct callchain_cursor *cursor,
    107			      struct strlist *bt_stop_list, FILE *fp)
    108{
    109	int printed = 0;
    110	struct callchain_cursor_node *node;
    111	int print_ip = print_opts & EVSEL__PRINT_IP;
    112	int print_sym = print_opts & EVSEL__PRINT_SYM;
    113	int print_dso = print_opts & EVSEL__PRINT_DSO;
    114	int print_symoffset = print_opts & EVSEL__PRINT_SYMOFFSET;
    115	int print_oneline = print_opts & EVSEL__PRINT_ONELINE;
    116	int print_srcline = print_opts & EVSEL__PRINT_SRCLINE;
    117	int print_unknown_as_addr = print_opts & EVSEL__PRINT_UNKNOWN_AS_ADDR;
    118	int print_arrow = print_opts & EVSEL__PRINT_CALLCHAIN_ARROW;
    119	int print_skip_ignored = print_opts & EVSEL__PRINT_SKIP_IGNORED;
    120	char s = print_oneline ? ' ' : '\t';
    121	bool first = true;
    122
    123	if (sample->callchain) {
    124		struct addr_location node_al;
    125
    126		callchain_cursor_commit(cursor);
    127
    128		while (1) {
    129			struct symbol *sym;
    130			struct map *map;
    131			u64 addr = 0;
    132
    133			node = callchain_cursor_current(cursor);
    134			if (!node)
    135				break;
    136
    137			sym = node->ms.sym;
    138			map = node->ms.map;
    139
    140			if (sym && sym->ignore && print_skip_ignored)
    141				goto next;
    142
    143			printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");
    144
    145			if (print_arrow && !first)
    146				printed += fprintf(fp, " <-");
    147
    148			if (map)
    149				addr = map->map_ip(map, node->ip);
    150
    151			if (print_ip) {
    152				/* Show binary offset for userspace addr */
    153				if (map && !map->dso->kernel)
    154					printed += fprintf(fp, "%c%16" PRIx64, s, addr);
    155				else
    156					printed += fprintf(fp, "%c%16" PRIx64, s, node->ip);
    157			}
    158
    159			if (print_sym) {
    160				printed += fprintf(fp, " ");
    161				node_al.addr = addr;
    162				node_al.map  = map;
    163
    164				if (print_symoffset) {
    165					printed += __symbol__fprintf_symname_offs(sym, &node_al,
    166										  print_unknown_as_addr,
    167										  true, fp);
    168				} else {
    169					printed += __symbol__fprintf_symname(sym, &node_al,
    170									     print_unknown_as_addr, fp);
    171				}
    172			}
    173
    174			if (print_dso && (!sym || !sym->inlined)) {
    175				printed += fprintf(fp, " (");
    176				printed += map__fprintf_dsoname(map, fp);
    177				printed += fprintf(fp, ")");
    178			}
    179
    180			if (print_srcline)
    181				printed += map__fprintf_srcline(map, addr, "\n  ", fp);
    182
    183			if (sym && sym->inlined)
    184				printed += fprintf(fp, " (inlined)");
    185
    186			if (!print_oneline)
    187				printed += fprintf(fp, "\n");
    188
    189			/* Add srccode here too? */
    190			if (bt_stop_list && sym &&
    191			    strlist__has_entry(bt_stop_list, sym->name)) {
    192				break;
    193			}
    194
    195			first = false;
    196next:
    197			callchain_cursor_advance(cursor);
    198		}
    199	}
    200
    201	return printed;
    202}
    203
    204int sample__fprintf_sym(struct perf_sample *sample, struct addr_location *al,
    205			int left_alignment, unsigned int print_opts,
    206			struct callchain_cursor *cursor, struct strlist *bt_stop_list, FILE *fp)
    207{
    208	int printed = 0;
    209	int print_ip = print_opts & EVSEL__PRINT_IP;
    210	int print_sym = print_opts & EVSEL__PRINT_SYM;
    211	int print_dso = print_opts & EVSEL__PRINT_DSO;
    212	int print_symoffset = print_opts & EVSEL__PRINT_SYMOFFSET;
    213	int print_srcline = print_opts & EVSEL__PRINT_SRCLINE;
    214	int print_unknown_as_addr = print_opts & EVSEL__PRINT_UNKNOWN_AS_ADDR;
    215
    216	if (cursor != NULL) {
    217		printed += sample__fprintf_callchain(sample, left_alignment, print_opts,
    218						     cursor, bt_stop_list, fp);
    219	} else {
    220		printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");
    221
    222		if (print_ip)
    223			printed += fprintf(fp, "%16" PRIx64, sample->ip);
    224
    225		if (print_sym) {
    226			printed += fprintf(fp, " ");
    227			if (print_symoffset) {
    228				printed += __symbol__fprintf_symname_offs(al->sym, al,
    229									  print_unknown_as_addr,
    230									  true, fp);
    231			} else {
    232				printed += __symbol__fprintf_symname(al->sym, al,
    233								     print_unknown_as_addr, fp);
    234			}
    235		}
    236
    237		if (print_dso) {
    238			printed += fprintf(fp, " (");
    239			printed += map__fprintf_dsoname(al->map, fp);
    240			printed += fprintf(fp, ")");
    241		}
    242
    243		if (print_srcline)
    244			printed += map__fprintf_srcline(al->map, al->addr, "\n  ", fp);
    245	}
    246
    247	return printed;
    248}
    249#endif /* PYTHON_PERF */