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

perf-dlfilter.txt (8489B)


      1perf-dlfilter(1)
      2================
      3
      4NAME
      5----
      6perf-dlfilter - Filter sample events using a dynamically loaded shared
      7object file
      8
      9SYNOPSIS
     10--------
     11[verse]
     12'perf script' [--dlfilter file.so ] [ --dlarg arg ]...
     13
     14DESCRIPTION
     15-----------
     16
     17This option is used to process data through a custom filter provided by a
     18dynamically loaded shared object file. Arguments can be passed using --dlarg
     19and retrieved using perf_dlfilter_fns.args().
     20
     21If 'file.so' does not contain "/", then it will be found either in the current
     22directory, or perf tools exec path which is ~/libexec/perf-core/dlfilters for
     23a local build and install (refer perf --exec-path), or the dynamic linker
     24paths.
     25
     26API
     27---
     28
     29The API for filtering consists of the following:
     30
     31[source,c]
     32----
     33#include <perf/perf_dlfilter.h>
     34
     35struct perf_dlfilter_fns perf_dlfilter_fns;
     36
     37int start(void **data, void *ctx);
     38int stop(void *data, void *ctx);
     39int filter_event(void *data, const struct perf_dlfilter_sample *sample, void *ctx);
     40int filter_event_early(void *data, const struct perf_dlfilter_sample *sample, void *ctx);
     41const char *filter_description(const char **long_description);
     42----
     43
     44If implemented, 'start' will be called at the beginning, before any
     45calls to 'filter_event' or 'filter_event_early'. Return 0 to indicate success,
     46or return a negative error code. '*data' can be assigned for use by other
     47functions. 'ctx' is needed for calls to perf_dlfilter_fns, but most
     48perf_dlfilter_fns are not valid when called from 'start'.
     49
     50If implemented, 'stop' will be called at the end, after any calls to
     51'filter_event' or 'filter_event_early'. Return 0 to indicate success, or
     52return a negative error code. 'data' is set by 'start'. 'ctx' is needed
     53for calls to perf_dlfilter_fns, but most perf_dlfilter_fns are not valid
     54when called from 'stop'.
     55
     56If implemented, 'filter_event' will be called for each sample event.
     57Return 0 to keep the sample event, 1 to filter it out, or return a negative
     58error code. 'data' is set by 'start'. 'ctx' is needed for calls to
     59'perf_dlfilter_fns'.
     60
     61'filter_event_early' is the same as 'filter_event' except it is called before
     62internal filtering.
     63
     64If implemented, 'filter_description' should return a one-line description
     65of the filter, and optionally a longer description.
     66
     67The perf_dlfilter_sample structure
     68~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     69
     70'filter_event' and 'filter_event_early' are passed a perf_dlfilter_sample
     71structure, which contains the following fields:
     72[source,c]
     73----
     74/*
     75 * perf sample event information (as per perf script and <linux/perf_event.h>)
     76 */
     77struct perf_dlfilter_sample {
     78	__u32 size; /* Size of this structure (for compatibility checking) */
     79	__u16 ins_lat;		/* Refer PERF_SAMPLE_WEIGHT_TYPE in <linux/perf_event.h> */
     80	__u16 p_stage_cyc;	/* Refer PERF_SAMPLE_WEIGHT_TYPE in <linux/perf_event.h> */
     81	__u64 ip;
     82	__s32 pid;
     83	__s32 tid;
     84	__u64 time;
     85	__u64 addr;
     86	__u64 id;
     87	__u64 stream_id;
     88	__u64 period;
     89	__u64 weight;		/* Refer PERF_SAMPLE_WEIGHT_TYPE in <linux/perf_event.h> */
     90	__u64 transaction;	/* Refer PERF_SAMPLE_TRANSACTION in <linux/perf_event.h> */
     91	__u64 insn_cnt;	/* For instructions-per-cycle (IPC) */
     92	__u64 cyc_cnt;		/* For instructions-per-cycle (IPC) */
     93	__s32 cpu;
     94	__u32 flags;		/* Refer PERF_DLFILTER_FLAG_* above */
     95	__u64 data_src;		/* Refer PERF_SAMPLE_DATA_SRC in <linux/perf_event.h> */
     96	__u64 phys_addr;	/* Refer PERF_SAMPLE_PHYS_ADDR in <linux/perf_event.h> */
     97	__u64 data_page_size;	/* Refer PERF_SAMPLE_DATA_PAGE_SIZE in <linux/perf_event.h> */
     98	__u64 code_page_size;	/* Refer PERF_SAMPLE_CODE_PAGE_SIZE in <linux/perf_event.h> */
     99	__u64 cgroup;		/* Refer PERF_SAMPLE_CGROUP in <linux/perf_event.h> */
    100	__u8  cpumode;		/* Refer CPUMODE_MASK etc in <linux/perf_event.h> */
    101	__u8  addr_correlates_sym; /* True => resolve_addr() can be called */
    102	__u16 misc;		/* Refer perf_event_header in <linux/perf_event.h> */
    103	__u32 raw_size;		/* Refer PERF_SAMPLE_RAW in <linux/perf_event.h> */
    104	const void *raw_data;	/* Refer PERF_SAMPLE_RAW in <linux/perf_event.h> */
    105	__u64 brstack_nr;	/* Number of brstack entries */
    106	const struct perf_branch_entry *brstack; /* Refer <linux/perf_event.h> */
    107	__u64 raw_callchain_nr;	/* Number of raw_callchain entries */
    108	const __u64 *raw_callchain; /* Refer <linux/perf_event.h> */
    109	const char *event;
    110};
    111----
    112
    113The perf_dlfilter_fns structure
    114~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    115
    116The 'perf_dlfilter_fns' structure is populated with function pointers when the
    117file is loaded. The functions can be called by 'filter_event' or
    118'filter_event_early'.
    119
    120[source,c]
    121----
    122struct perf_dlfilter_fns {
    123	const struct perf_dlfilter_al *(*resolve_ip)(void *ctx);
    124	const struct perf_dlfilter_al *(*resolve_addr)(void *ctx);
    125	char **(*args)(void *ctx, int *dlargc);
    126	__s32 (*resolve_address)(void *ctx, __u64 address, struct perf_dlfilter_al *al);
    127	const __u8 *(*insn)(void *ctx, __u32 *length);
    128	const char *(*srcline)(void *ctx, __u32 *line_number);
    129	struct perf_event_attr *(*attr)(void *ctx);
    130	__s32 (*object_code)(void *ctx, __u64 ip, void *buf, __u32 len);
    131	void *(*reserved[120])(void *);
    132};
    133----
    134
    135'resolve_ip' returns information about ip.
    136
    137'resolve_addr' returns information about addr (if addr_correlates_sym).
    138
    139'args' returns arguments from --dlarg options.
    140
    141'resolve_address' provides information about 'address'. al->size must be set
    142before calling. Returns 0 on success, -1 otherwise.
    143
    144'insn' returns instruction bytes and length.
    145
    146'srcline' return source file name and line number.
    147
    148'attr' returns perf_event_attr, refer <linux/perf_event.h>.
    149
    150'object_code' reads object code and returns the number of bytes read.
    151
    152The perf_dlfilter_al structure
    153~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    154
    155The 'perf_dlfilter_al' structure contains information about an address.
    156
    157[source,c]
    158----
    159/*
    160 * Address location (as per perf script)
    161 */
    162struct perf_dlfilter_al {
    163	__u32 size; /* Size of this structure (for compatibility checking) */
    164	__u32 symoff;
    165	const char *sym;
    166	__u64 addr; /* Mapped address (from dso) */
    167	__u64 sym_start;
    168	__u64 sym_end;
    169	const char *dso;
    170	__u8  sym_binding; /* STB_LOCAL, STB_GLOBAL or STB_WEAK, refer <elf.h> */
    171	__u8  is_64_bit; /* Only valid if dso is not NULL */
    172	__u8  is_kernel_ip; /* True if in kernel space */
    173	__u32 buildid_size;
    174	__u8 *buildid;
    175	/* Below members are only populated by resolve_ip() */
    176	__u8 filtered; /* true if this sample event will be filtered out */
    177	const char *comm;
    178};
    179----
    180
    181perf_dlfilter_sample flags
    182~~~~~~~~~~~~~~~~~~~~~~~~~~
    183
    184The 'flags' member of 'perf_dlfilter_sample' corresponds with the flags field
    185of perf script. The bits of the flags are as follows:
    186
    187[source,c]
    188----
    189/* Definitions for perf_dlfilter_sample flags */
    190enum {
    191	PERF_DLFILTER_FLAG_BRANCH	= 1ULL << 0,
    192	PERF_DLFILTER_FLAG_CALL		= 1ULL << 1,
    193	PERF_DLFILTER_FLAG_RETURN	= 1ULL << 2,
    194	PERF_DLFILTER_FLAG_CONDITIONAL	= 1ULL << 3,
    195	PERF_DLFILTER_FLAG_SYSCALLRET	= 1ULL << 4,
    196	PERF_DLFILTER_FLAG_ASYNC	= 1ULL << 5,
    197	PERF_DLFILTER_FLAG_INTERRUPT	= 1ULL << 6,
    198	PERF_DLFILTER_FLAG_TX_ABORT	= 1ULL << 7,
    199	PERF_DLFILTER_FLAG_TRACE_BEGIN	= 1ULL << 8,
    200	PERF_DLFILTER_FLAG_TRACE_END	= 1ULL << 9,
    201	PERF_DLFILTER_FLAG_IN_TX	= 1ULL << 10,
    202	PERF_DLFILTER_FLAG_VMENTRY	= 1ULL << 11,
    203	PERF_DLFILTER_FLAG_VMEXIT	= 1ULL << 12,
    204};
    205----
    206
    207EXAMPLE
    208-------
    209
    210Filter out everything except branches from "foo" to "bar":
    211
    212[source,c]
    213----
    214#include <perf/perf_dlfilter.h>
    215#include <string.h>
    216
    217struct perf_dlfilter_fns perf_dlfilter_fns;
    218
    219int filter_event(void *data, const struct perf_dlfilter_sample *sample, void *ctx)
    220{
    221	const struct perf_dlfilter_al *al;
    222	const struct perf_dlfilter_al *addr_al;
    223
    224	if (!sample->ip || !sample->addr_correlates_sym)
    225		return 1;
    226
    227	al = perf_dlfilter_fns.resolve_ip(ctx);
    228	if (!al || !al->sym || strcmp(al->sym, "foo"))
    229		return 1;
    230
    231	addr_al = perf_dlfilter_fns.resolve_addr(ctx);
    232	if (!addr_al || !addr_al->sym || strcmp(addr_al->sym, "bar"))
    233		return 1;
    234
    235	return 0;
    236}
    237----
    238
    239To build the shared object, assuming perf has been installed for the local user
    240i.e. perf_dlfilter.h is in ~/include/perf :
    241
    242	gcc -c -I ~/include -fpic dlfilter-example.c
    243	gcc -shared -o dlfilter-example.so dlfilter-example.o
    244
    245To use the filter with perf script:
    246
    247	perf script --dlfilter dlfilter-example.so
    248
    249NOTES
    250-----
    251
    252The dlfilter .so file will be dependent on shared libraries. If those change,
    253it may be necessary to rebuild the .so. Also there may be unexpected results
    254if the .so uses different versions of the shared libraries that perf uses.
    255Versions can be checked using the ldd command.
    256
    257SEE ALSO
    258--------
    259linkperf:perf-script[1]