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

dso.h (10817B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2#ifndef __PERF_DSO
      3#define __PERF_DSO
      4
      5#include <pthread.h>
      6#include <linux/refcount.h>
      7#include <linux/types.h>
      8#include <linux/rbtree.h>
      9#include <sys/types.h>
     10#include <stdbool.h>
     11#include <stdio.h>
     12#include <linux/bitops.h>
     13#include "build-id.h"
     14
     15struct machine;
     16struct map;
     17struct perf_env;
     18
     19#define DSO__NAME_KALLSYMS	"[kernel.kallsyms]"
     20#define DSO__NAME_KCORE		"[kernel.kcore]"
     21
     22enum dso_binary_type {
     23	DSO_BINARY_TYPE__KALLSYMS = 0,
     24	DSO_BINARY_TYPE__GUEST_KALLSYMS,
     25	DSO_BINARY_TYPE__VMLINUX,
     26	DSO_BINARY_TYPE__GUEST_VMLINUX,
     27	DSO_BINARY_TYPE__JAVA_JIT,
     28	DSO_BINARY_TYPE__DEBUGLINK,
     29	DSO_BINARY_TYPE__BUILD_ID_CACHE,
     30	DSO_BINARY_TYPE__BUILD_ID_CACHE_DEBUGINFO,
     31	DSO_BINARY_TYPE__FEDORA_DEBUGINFO,
     32	DSO_BINARY_TYPE__UBUNTU_DEBUGINFO,
     33	DSO_BINARY_TYPE__MIXEDUP_UBUNTU_DEBUGINFO,
     34	DSO_BINARY_TYPE__BUILDID_DEBUGINFO,
     35	DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
     36	DSO_BINARY_TYPE__GUEST_KMODULE,
     37	DSO_BINARY_TYPE__GUEST_KMODULE_COMP,
     38	DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE,
     39	DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP,
     40	DSO_BINARY_TYPE__KCORE,
     41	DSO_BINARY_TYPE__GUEST_KCORE,
     42	DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO,
     43	DSO_BINARY_TYPE__BPF_PROG_INFO,
     44	DSO_BINARY_TYPE__BPF_IMAGE,
     45	DSO_BINARY_TYPE__OOL,
     46	DSO_BINARY_TYPE__NOT_FOUND,
     47};
     48
     49enum dso_space_type {
     50	DSO_SPACE__USER = 0,
     51	DSO_SPACE__KERNEL,
     52	DSO_SPACE__KERNEL_GUEST
     53};
     54
     55enum dso_swap_type {
     56	DSO_SWAP__UNSET,
     57	DSO_SWAP__NO,
     58	DSO_SWAP__YES,
     59};
     60
     61enum dso_data_status {
     62	DSO_DATA_STATUS_ERROR	= -1,
     63	DSO_DATA_STATUS_UNKNOWN	= 0,
     64	DSO_DATA_STATUS_OK	= 1,
     65};
     66
     67enum dso_data_status_seen {
     68	DSO_DATA_STATUS_SEEN_ITRACE,
     69};
     70
     71enum dso_type {
     72	DSO__TYPE_UNKNOWN,
     73	DSO__TYPE_64BIT,
     74	DSO__TYPE_32BIT,
     75	DSO__TYPE_X32BIT,
     76};
     77
     78enum dso_load_errno {
     79	DSO_LOAD_ERRNO__SUCCESS		= 0,
     80
     81	/*
     82	 * Choose an arbitrary negative big number not to clash with standard
     83	 * errno since SUS requires the errno has distinct positive values.
     84	 * See 'Issue 6' in the link below.
     85	 *
     86	 * http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html
     87	 */
     88	__DSO_LOAD_ERRNO__START		= -10000,
     89
     90	DSO_LOAD_ERRNO__INTERNAL_ERROR	= __DSO_LOAD_ERRNO__START,
     91
     92	/* for symsrc__init() */
     93	DSO_LOAD_ERRNO__INVALID_ELF,
     94	DSO_LOAD_ERRNO__CANNOT_READ_BUILDID,
     95	DSO_LOAD_ERRNO__MISMATCHING_BUILDID,
     96
     97	/* for decompress_kmodule */
     98	DSO_LOAD_ERRNO__DECOMPRESSION_FAILURE,
     99
    100	__DSO_LOAD_ERRNO__END,
    101};
    102
    103#define DSO__SWAP(dso, type, val)			\
    104({							\
    105	type ____r = val;				\
    106	BUG_ON(dso->needs_swap == DSO_SWAP__UNSET);	\
    107	if (dso->needs_swap == DSO_SWAP__YES) {		\
    108		switch (sizeof(____r)) {		\
    109		case 2:					\
    110			____r = bswap_16(val);		\
    111			break;				\
    112		case 4:					\
    113			____r = bswap_32(val);		\
    114			break;				\
    115		case 8:					\
    116			____r = bswap_64(val);		\
    117			break;				\
    118		default:				\
    119			BUG_ON(1);			\
    120		}					\
    121	}						\
    122	____r;						\
    123})
    124
    125#define DSO__DATA_CACHE_SIZE 4096
    126#define DSO__DATA_CACHE_MASK ~(DSO__DATA_CACHE_SIZE - 1)
    127
    128/*
    129 * Data about backing storage DSO, comes from PERF_RECORD_MMAP2 meta events
    130 */
    131struct dso_id {
    132	u32	maj;
    133	u32	min;
    134	u64	ino;
    135	u64	ino_generation;
    136};
    137
    138struct dso_cache {
    139	struct rb_node	rb_node;
    140	u64 offset;
    141	u64 size;
    142	char data[];
    143};
    144
    145struct auxtrace_cache;
    146
    147struct dso {
    148	pthread_mutex_t	 lock;
    149	struct list_head node;
    150	struct rb_node	 rb_node;	/* rbtree node sorted by long name */
    151	struct rb_root	 *root;		/* root of rbtree that rb_node is in */
    152	struct rb_root_cached symbols;
    153	struct rb_root_cached symbol_names;
    154	struct rb_root_cached inlined_nodes;
    155	struct rb_root_cached srclines;
    156	struct {
    157		u64		addr;
    158		struct symbol	*symbol;
    159	} last_find_result;
    160	void		 *a2l;
    161	char		 *symsrc_filename;
    162	unsigned int	 a2l_fails;
    163	enum dso_space_type	kernel;
    164	enum dso_swap_type	needs_swap;
    165	enum dso_binary_type	symtab_type;
    166	enum dso_binary_type	binary_type;
    167	enum dso_load_errno	load_errno;
    168	u8		 adjust_symbols:1;
    169	u8		 has_build_id:1;
    170	u8		 header_build_id:1;
    171	u8		 has_srcline:1;
    172	u8		 hit:1;
    173	u8		 annotate_warned:1;
    174	u8		 auxtrace_warned:1;
    175	u8		 short_name_allocated:1;
    176	u8		 long_name_allocated:1;
    177	u8		 is_64_bit:1;
    178	bool		 sorted_by_name;
    179	bool		 loaded;
    180	u8		 rel;
    181	struct build_id	 bid;
    182	u64		 text_offset;
    183	const char	 *short_name;
    184	const char	 *long_name;
    185	u16		 long_name_len;
    186	u16		 short_name_len;
    187	void		*dwfl;			/* DWARF debug info */
    188	struct auxtrace_cache *auxtrace_cache;
    189	int		 comp;
    190
    191	/* dso data file */
    192	struct {
    193		struct rb_root	 cache;
    194		int		 fd;
    195		int		 status;
    196		u32		 status_seen;
    197		u64		 file_size;
    198		struct list_head open_entry;
    199		u64		 elf_base_addr;
    200		u64		 debug_frame_offset;
    201		u64		 eh_frame_hdr_addr;
    202		u64		 eh_frame_hdr_offset;
    203	} data;
    204	/* bpf prog information */
    205	struct {
    206		u32		id;
    207		u32		sub_id;
    208		struct perf_env	*env;
    209	} bpf_prog;
    210
    211	union { /* Tool specific area */
    212		void	 *priv;
    213		u64	 db_id;
    214	};
    215	struct nsinfo	*nsinfo;
    216	struct dso_id	 id;
    217	refcount_t	 refcnt;
    218	char		 name[];
    219};
    220
    221/* dso__for_each_symbol - iterate over the symbols of given type
    222 *
    223 * @dso: the 'struct dso *' in which symbols are iterated
    224 * @pos: the 'struct symbol *' to use as a loop cursor
    225 * @n: the 'struct rb_node *' to use as a temporary storage
    226 */
    227#define dso__for_each_symbol(dso, pos, n)	\
    228	symbols__for_each_entry(&(dso)->symbols, pos, n)
    229
    230static inline void dso__set_loaded(struct dso *dso)
    231{
    232	dso->loaded = true;
    233}
    234
    235struct dso *dso__new_id(const char *name, struct dso_id *id);
    236struct dso *dso__new(const char *name);
    237void dso__delete(struct dso *dso);
    238
    239int dso__cmp_id(struct dso *a, struct dso *b);
    240void dso__set_short_name(struct dso *dso, const char *name, bool name_allocated);
    241void dso__set_long_name(struct dso *dso, const char *name, bool name_allocated);
    242
    243int dso__name_len(const struct dso *dso);
    244
    245struct dso *dso__get(struct dso *dso);
    246void dso__put(struct dso *dso);
    247
    248static inline void __dso__zput(struct dso **dso)
    249{
    250	dso__put(*dso);
    251	*dso = NULL;
    252}
    253
    254#define dso__zput(dso) __dso__zput(&dso)
    255
    256bool dso__loaded(const struct dso *dso);
    257
    258static inline bool dso__has_symbols(const struct dso *dso)
    259{
    260	return !RB_EMPTY_ROOT(&dso->symbols.rb_root);
    261}
    262
    263bool dso__sorted_by_name(const struct dso *dso);
    264void dso__set_sorted_by_name(struct dso *dso);
    265void dso__sort_by_name(struct dso *dso);
    266
    267void dso__set_build_id(struct dso *dso, struct build_id *bid);
    268bool dso__build_id_equal(const struct dso *dso, struct build_id *bid);
    269void dso__read_running_kernel_build_id(struct dso *dso,
    270				       struct machine *machine);
    271int dso__kernel_module_get_build_id(struct dso *dso, const char *root_dir);
    272
    273char dso__symtab_origin(const struct dso *dso);
    274int dso__read_binary_type_filename(const struct dso *dso, enum dso_binary_type type,
    275				   char *root_dir, char *filename, size_t size);
    276bool is_kernel_module(const char *pathname, int cpumode);
    277bool dso__needs_decompress(struct dso *dso);
    278int dso__decompress_kmodule_fd(struct dso *dso, const char *name);
    279int dso__decompress_kmodule_path(struct dso *dso, const char *name,
    280				 char *pathname, size_t len);
    281int filename__decompress(const char *name, char *pathname,
    282			 size_t len, int comp, int *err);
    283
    284#define KMOD_DECOMP_NAME  "/tmp/perf-kmod-XXXXXX"
    285#define KMOD_DECOMP_LEN   sizeof(KMOD_DECOMP_NAME)
    286
    287struct kmod_path {
    288	char *name;
    289	int   comp;
    290	bool  kmod;
    291};
    292
    293int __kmod_path__parse(struct kmod_path *m, const char *path,
    294		     bool alloc_name);
    295
    296#define kmod_path__parse(__m, __p)      __kmod_path__parse(__m, __p, false)
    297#define kmod_path__parse_name(__m, __p) __kmod_path__parse(__m, __p, true)
    298
    299void dso__set_module_info(struct dso *dso, struct kmod_path *m,
    300			  struct machine *machine);
    301
    302/*
    303 * The dso__data_* external interface provides following functions:
    304 *   dso__data_get_fd
    305 *   dso__data_put_fd
    306 *   dso__data_close
    307 *   dso__data_size
    308 *   dso__data_read_offset
    309 *   dso__data_read_addr
    310 *   dso__data_write_cache_offs
    311 *   dso__data_write_cache_addr
    312 *
    313 * Please refer to the dso.c object code for each function and
    314 * arguments documentation. Following text tries to explain the
    315 * dso file descriptor caching.
    316 *
    317 * The dso__data* interface allows caching of opened file descriptors
    318 * to speed up the dso data accesses. The idea is to leave the file
    319 * descriptor opened ideally for the whole life of the dso object.
    320 *
    321 * The current usage of the dso__data_* interface is as follows:
    322 *
    323 * Get DSO's fd:
    324 *   int fd = dso__data_get_fd(dso, machine);
    325 *   if (fd >= 0) {
    326 *       USE 'fd' SOMEHOW
    327 *       dso__data_put_fd(dso);
    328 *   }
    329 *
    330 * Read DSO's data:
    331 *   n = dso__data_read_offset(dso_0, &machine, 0, buf, BUFSIZE);
    332 *   n = dso__data_read_addr(dso_0, &machine, 0, buf, BUFSIZE);
    333 *
    334 * Eventually close DSO's fd:
    335 *   dso__data_close(dso);
    336 *
    337 * It is not necessary to close the DSO object data file. Each time new
    338 * DSO data file is opened, the limit (RLIMIT_NOFILE/2) is checked. Once
    339 * it is crossed, the oldest opened DSO object is closed.
    340 *
    341 * The dso__delete function calls close_dso function to ensure the
    342 * data file descriptor gets closed/unmapped before the dso object
    343 * is freed.
    344 *
    345 * TODO
    346*/
    347int dso__data_get_fd(struct dso *dso, struct machine *machine);
    348void dso__data_put_fd(struct dso *dso);
    349void dso__data_close(struct dso *dso);
    350
    351int dso__data_file_size(struct dso *dso, struct machine *machine);
    352off_t dso__data_size(struct dso *dso, struct machine *machine);
    353ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
    354			      u64 offset, u8 *data, ssize_t size);
    355ssize_t dso__data_read_addr(struct dso *dso, struct map *map,
    356			    struct machine *machine, u64 addr,
    357			    u8 *data, ssize_t size);
    358bool dso__data_status_seen(struct dso *dso, enum dso_data_status_seen by);
    359ssize_t dso__data_write_cache_offs(struct dso *dso, struct machine *machine,
    360				   u64 offset, const u8 *data, ssize_t size);
    361ssize_t dso__data_write_cache_addr(struct dso *dso, struct map *map,
    362				   struct machine *machine, u64 addr,
    363				   const u8 *data, ssize_t size);
    364
    365struct map *dso__new_map(const char *name);
    366struct dso *machine__findnew_kernel(struct machine *machine, const char *name,
    367				    const char *short_name, int dso_type);
    368
    369void dso__reset_find_symbol_cache(struct dso *dso);
    370
    371size_t dso__fprintf_symbols_by_name(struct dso *dso, FILE *fp);
    372size_t dso__fprintf(struct dso *dso, FILE *fp);
    373
    374static inline bool dso__is_vmlinux(struct dso *dso)
    375{
    376	return dso->binary_type == DSO_BINARY_TYPE__VMLINUX ||
    377	       dso->binary_type == DSO_BINARY_TYPE__GUEST_VMLINUX;
    378}
    379
    380static inline bool dso__is_kcore(struct dso *dso)
    381{
    382	return dso->binary_type == DSO_BINARY_TYPE__KCORE ||
    383	       dso->binary_type == DSO_BINARY_TYPE__GUEST_KCORE;
    384}
    385
    386static inline bool dso__is_kallsyms(struct dso *dso)
    387{
    388	return dso->kernel && dso->long_name[0] != '/';
    389}
    390
    391void dso__free_a2l(struct dso *dso);
    392
    393enum dso_type dso__type(struct dso *dso, struct machine *machine);
    394
    395int dso__strerror_load(struct dso *dso, char *buf, size_t buflen);
    396
    397void reset_fd_limit(void);
    398
    399#endif /* __PERF_DSO */