Home | History | Annotate | Download | only in util
      1 #ifndef __PERF_ANNOTATE_H
      2 #define __PERF_ANNOTATE_H
      3 
      4 #include <stdbool.h>
      5 #include <stdint.h>
      6 #include "types.h"
      7 #include "symbol.h"
      8 #include "hist.h"
      9 #include "sort.h"
     10 #include <linux/list.h>
     11 #include <linux/rbtree.h>
     12 #include <pthread.h>
     13 
     14 struct ins;
     15 
     16 struct ins_operands {
     17 	char	*raw;
     18 	struct {
     19 		char	*raw;
     20 		char	*name;
     21 		u64	addr;
     22 		u64	offset;
     23 	} target;
     24 	union {
     25 		struct {
     26 			char	*raw;
     27 			char	*name;
     28 			u64	addr;
     29 		} source;
     30 		struct {
     31 			struct ins *ins;
     32 			struct ins_operands *ops;
     33 		} locked;
     34 	};
     35 };
     36 
     37 struct ins_ops {
     38 	void (*free)(struct ins_operands *ops);
     39 	int (*parse)(struct ins_operands *ops);
     40 	int (*scnprintf)(struct ins *ins, char *bf, size_t size,
     41 			 struct ins_operands *ops);
     42 };
     43 
     44 struct ins {
     45 	const char     *name;
     46 	struct ins_ops *ops;
     47 };
     48 
     49 bool ins__is_jump(const struct ins *ins);
     50 bool ins__is_call(const struct ins *ins);
     51 int ins__scnprintf(struct ins *ins, char *bf, size_t size, struct ins_operands *ops);
     52 
     53 struct annotation;
     54 
     55 struct disasm_line {
     56 	struct list_head    node;
     57 	s64		    offset;
     58 	char		    *line;
     59 	char		    *name;
     60 	struct ins	    *ins;
     61 	struct ins_operands ops;
     62 };
     63 
     64 static inline bool disasm_line__has_offset(const struct disasm_line *dl)
     65 {
     66 	return dl->ops.target.offset != UINT64_MAX;
     67 }
     68 
     69 void disasm_line__free(struct disasm_line *dl);
     70 struct disasm_line *disasm__get_next_ip_line(struct list_head *head, struct disasm_line *pos);
     71 int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw);
     72 size_t disasm__fprintf(struct list_head *head, FILE *fp);
     73 double disasm__calc_percent(struct annotation *notes, int evidx, s64 offset,
     74 			    s64 end, const char **path);
     75 
     76 struct sym_hist {
     77 	u64		sum;
     78 	u64		addr[0];
     79 };
     80 
     81 struct source_line_percent {
     82 	double		percent;
     83 	double		percent_sum;
     84 };
     85 
     86 struct source_line {
     87 	struct rb_node	node;
     88 	char		*path;
     89 	int		nr_pcnt;
     90 	struct source_line_percent p[1];
     91 };
     92 
     93 /** struct annotated_source - symbols with hits have this attached as in sannotation
     94  *
     95  * @histogram: Array of addr hit histograms per event being monitored
     96  * @lines: If 'print_lines' is specified, per source code line percentages
     97  * @source: source parsed from a disassembler like objdump -dS
     98  *
     99  * lines is allocated, percentages calculated and all sorted by percentage
    100  * when the annotation is about to be presented, so the percentages are for
    101  * one of the entries in the histogram array, i.e. for the event/counter being
    102  * presented. It is deallocated right after symbol__{tui,tty,etc}_annotate
    103  * returns.
    104  */
    105 struct annotated_source {
    106 	struct list_head   source;
    107 	struct source_line *lines;
    108 	int    		   nr_histograms;
    109 	int    		   sizeof_sym_hist;
    110 	struct sym_hist	   histograms[0];
    111 };
    112 
    113 struct annotation {
    114 	pthread_mutex_t		lock;
    115 	struct annotated_source *src;
    116 };
    117 
    118 struct sannotation {
    119 	struct annotation annotation;
    120 	struct symbol	  symbol;
    121 };
    122 
    123 static inline struct sym_hist *annotation__histogram(struct annotation *notes, int idx)
    124 {
    125 	return (((void *)&notes->src->histograms) +
    126 	 	(notes->src->sizeof_sym_hist * idx));
    127 }
    128 
    129 static inline struct annotation *symbol__annotation(struct symbol *sym)
    130 {
    131 	struct sannotation *a = container_of(sym, struct sannotation, symbol);
    132 	return &a->annotation;
    133 }
    134 
    135 int symbol__inc_addr_samples(struct symbol *sym, struct map *map,
    136 			     int evidx, u64 addr);
    137 int symbol__alloc_hist(struct symbol *sym);
    138 void symbol__annotate_zero_histograms(struct symbol *sym);
    139 
    140 int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize);
    141 int symbol__annotate_init(struct map *map __maybe_unused, struct symbol *sym);
    142 int symbol__annotate_printf(struct symbol *sym, struct map *map,
    143 			    struct perf_evsel *evsel, bool full_paths,
    144 			    int min_pcnt, int max_lines, int context);
    145 void symbol__annotate_zero_histogram(struct symbol *sym, int evidx);
    146 void symbol__annotate_decay_histogram(struct symbol *sym, int evidx);
    147 void disasm__purge(struct list_head *head);
    148 
    149 int symbol__tty_annotate(struct symbol *sym, struct map *map,
    150 			 struct perf_evsel *evsel, bool print_lines,
    151 			 bool full_paths, int min_pcnt, int max_lines);
    152 
    153 #ifdef SLANG_SUPPORT
    154 int symbol__tui_annotate(struct symbol *sym, struct map *map,
    155 			 struct perf_evsel *evsel,
    156 			 struct hist_browser_timer *hbt);
    157 #else
    158 static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused,
    159 				struct map *map __maybe_unused,
    160 				struct perf_evsel *evsel  __maybe_unused,
    161 				struct hist_browser_timer *hbt
    162 				__maybe_unused)
    163 {
    164 	return 0;
    165 }
    166 #endif
    167 
    168 #ifdef GTK2_SUPPORT
    169 int symbol__gtk_annotate(struct symbol *sym, struct map *map,
    170 			 struct perf_evsel *evsel,
    171 			 struct hist_browser_timer *hbt);
    172 
    173 static inline int hist_entry__gtk_annotate(struct hist_entry *he,
    174 					   struct perf_evsel *evsel,
    175 					   struct hist_browser_timer *hbt)
    176 {
    177 	return symbol__gtk_annotate(he->ms.sym, he->ms.map, evsel, hbt);
    178 }
    179 
    180 void perf_gtk__show_annotations(void);
    181 #else
    182 static inline int hist_entry__gtk_annotate(struct hist_entry *he __maybe_unused,
    183 				struct perf_evsel *evsel __maybe_unused,
    184 				struct hist_browser_timer *hbt __maybe_unused)
    185 {
    186 	return 0;
    187 }
    188 
    189 static inline void perf_gtk__show_annotations(void) {}
    190 #endif
    191 
    192 extern const char	*disassembler_style;
    193 
    194 #endif	/* __PERF_ANNOTATE_H */
    195