diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-19 10:09:22 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-19 10:09:22 -0700 |
| commit | f4cdf7ca9a1fdcca413157df19753f388a5a224e (patch) | |
| tree | 60a31895b2446cd7fa27514e8c2843534a0de0da /tools/perf/util/map.h | |
| download | linux-stable-f4cdf7ca9a1fdcca413157df19753f388a5a224e.tar.gz linux-stable-f4cdf7ca9a1fdcca413157df19753f388a5a224e.zip | |
Merge tag 'media/v7.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-mediagrafted
Pull media updates from Mauro Carvalho Chehab:
- v4l2-core: added ISP statistics support and per-block validation
- v4l2-core: Allow unknown HDR10 white point and luminance
- New camera sensors: Sony IMX678 and IMX471m, Himax HM1092 IR sensor
- New codec: Milos: VPU v2.0 codec support
- isp driver: gained support for Dreamchip RPPX1 ISP framework
- vsp1 driver: gained support for RZ/T2H and RZ/N2H
- Novalake driver: gained CVS support for new NVL hardware
- dvb-core: fix feed leak on failed DMX_ADD_PID
- several driver fixes, cleanups and minor improvements
* tag 'media/v7.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (308 commits)
media: ipu-bridge: check all DMI entries when overriding sensor rotation
media: v4l2-async: avoid deleting unlinked ASC entry on link error
media: rzg2l-cru: Align bytesperline to hardware DMA stride requirement
media: intel/ipu6: fix async notifier cleanup leak on parse error
media: staging/ipu7: fix async notifier UAF on probe error path
media: amd: isp4: fix self-deadlock in isp4sd_pwron_and_init() error path
media: amd: isp4: release partial allocations in isp4if_alloc_fw_gpumem()
media: rcar-isp: Fix VSPX reference leaks
media: rcar-isp: Release ISPCORE resources
media: i2c: imx415: Release runtime PM reference on VBLANK error
media: i2c: imx415: Return test pattern write errors
media: renesas: vsp1: Declare index variables in for loop statement
media: renesas: vsp1: Make reset control optional to support platforms without a reset line
media: dt-bindings: media: renesas,vsp1: Document RZ/T2H and RZ/N2H SoCs
media: dt-bindings: media: renesas,fcp: Document RZ/T2H and RZ/N2H SoCs
media: nxp: imx8-isi: Add additional 32-bit RGB format support
media: nxp: imx8-isi: Add 16-bit raw Bayer format support
media: nxp: imx8-isi: Implement per-stream reference counting for multiplexed streams
media: nxp: imx8-isi: Use BIT_ULL() for 64-bit stream masks
media: nxp: imx8-isi: Correct color map between V4L2 and ISI
...
Diffstat (limited to 'tools/perf/util/map.h')
| -rw-r--r-- | tools/perf/util/map.h | 319 |
1 files changed, 319 insertions, 0 deletions
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h new file mode 100644 index 000000000..979b3e11b --- /dev/null +++ b/tools/perf/util/map.h @@ -0,0 +1,319 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __PERF_MAP_H +#define __PERF_MAP_H + +#include <linux/refcount.h> +#include <linux/compiler.h> +#include <linux/list.h> +#include <linux/rbtree.h> +#include <stdio.h> +#include <string.h> +#include <stdbool.h> +#include <linux/types.h> +#include <internal/rc_check.h> + +struct dso; +struct maps; +struct machine; + +enum mapping_type { + /* map__map_ip/map__unmap_ip are given as offsets in the DSO. */ + MAPPING_TYPE__DSO, + /* map__map_ip/map__unmap_ip are just the given ip value. */ + MAPPING_TYPE__IDENTITY, +}; + +DECLARE_RC_STRUCT(map) { + u64 start; + u64 end; + u64 pgoff; + u64 reloc; + struct dso *dso; + refcount_t refcnt; + u32 prot; + u32 flags; + enum mapping_type mapping_type:8; + bool erange_warned; + bool priv; + bool hit; +}; + +struct kmap; + +struct kmap *__map__kmap(struct map *map); +struct kmap *map__kmap(struct map *map); +struct maps *map__kmaps(struct map *map); + +static inline struct dso *map__dso(const struct map *map) +{ + return RC_CHK_ACCESS(map)->dso; +} + +static inline u64 map__start(const struct map *map) +{ + return RC_CHK_ACCESS(map)->start; +} + +static inline u64 map__end(const struct map *map) +{ + return RC_CHK_ACCESS(map)->end; +} + +static inline u64 map__pgoff(const struct map *map) +{ + return RC_CHK_ACCESS(map)->pgoff; +} + +static inline u64 map__reloc(const struct map *map) +{ + return RC_CHK_ACCESS(map)->reloc; +} + +static inline u32 map__flags(const struct map *map) +{ + return RC_CHK_ACCESS(map)->flags; +} + +static inline u32 map__prot(const struct map *map) +{ + return RC_CHK_ACCESS(map)->prot; +} + +static inline bool map__priv(const struct map *map) +{ + return RC_CHK_ACCESS(map)->priv; +} + +static inline bool map__hit(const struct map *map) +{ + return RC_CHK_ACCESS(map)->hit; +} + +static inline refcount_t *map__refcnt(struct map *map) +{ + return &RC_CHK_ACCESS(map)->refcnt; +} + +static inline bool map__erange_warned(struct map *map) +{ + return RC_CHK_ACCESS(map)->erange_warned; +} + +static inline size_t map__size(const struct map *map) +{ + return map__end(map) - map__start(map); +} + +/* ip -> dso rip */ +static inline u64 map__dso_map_ip(const struct map *map, u64 ip) +{ + return ip - map__start(map) + map__pgoff(map); +} + +/* dso rip -> ip */ +static inline u64 map__dso_unmap_ip(const struct map *map, u64 rip) +{ + return rip + map__start(map) - map__pgoff(map); +} + +static inline u64 map__map_ip(const struct map *map, u64 ip_or_rip) +{ + if ((RC_CHK_ACCESS(map)->mapping_type) == MAPPING_TYPE__DSO) + return map__dso_map_ip(map, ip_or_rip); + else + return ip_or_rip; +} + +static inline u64 map__unmap_ip(const struct map *map, u64 ip_or_rip) +{ + if ((RC_CHK_ACCESS(map)->mapping_type) == MAPPING_TYPE__DSO) + return map__dso_unmap_ip(map, ip_or_rip); + else + return ip_or_rip; +} + +/* rip/ip <-> addr suitable for passing to `objdump --start-address=` */ +u64 map__rip_2objdump(const struct map *map, u64 rip); + +/* objdump address -> memory address */ +u64 map__objdump_2mem(const struct map *map, u64 ip); + +/* objdump address -> rip */ +u64 map__objdump_2rip(const struct map *map, u64 ip); + +struct symbol; +struct thread; + +/* map__for_each_symbol - iterate over the symbols in the given map + * + * @map: the 'struct map *' in which symbols are iterated + * @pos: the 'struct symbol *' to use as a loop cursor + * @n: the 'struct rb_node *' to use as a temporary storage + * Note: caller must ensure map->dso is not NULL (map is loaded). + */ +#define map__for_each_symbol(map, pos, n) \ + dso__for_each_symbol(map__dso(map), pos, n) + +/* map__for_each_symbol_with_name - iterate over the symbols in the given map + * that have the given name + * + * @map: the 'struct map *' in which symbols are iterated + * @sym_name: the symbol name + * @pos: the 'struct symbol *' to use as a loop cursor + * @idx: the cursor index in the symbol names array + */ +#define __map__for_each_symbol_by_name(map, sym_name, pos, idx) \ + for (pos = map__find_symbol_by_name_idx(map, sym_name, &idx); \ + pos && \ + !symbol__match_symbol_name(pos->name, sym_name, \ + SYMBOL_TAG_INCLUDE__DEFAULT_ONLY); \ + pos = dso__next_symbol_by_name(map__dso(map), &idx)) + +#define map__for_each_symbol_by_name(map, sym_name, pos, idx) \ + __map__for_each_symbol_by_name(map, sym_name, (pos), idx) + +struct dso_id; + +struct map *map__new(struct machine *machine, u64 start, u64 len, + u64 pgoff, const struct dso_id *id, u32 prot, u32 flags, + char *filename, struct thread *thread); +struct map *map__new2(u64 start, struct dso *dso); +void map__delete(struct map *map); +struct map *map__clone(struct map *map); + +static inline struct map *map__get(struct map *map) +{ + struct map *result; + + if (RC_CHK_GET(result, map)) + refcount_inc(map__refcnt(map)); + + return result; +} + +void map__put(struct map *map); + +static inline void __map__zput(struct map **map) +{ + map__put(*map); + *map = NULL; +} + +#define map__zput(map) __map__zput(&map) + +size_t map__fprintf(struct map *map, FILE *fp); +size_t map__fprintf_dsoname(struct map *map, FILE *fp); +size_t map__fprintf_dsoname_dsoff(struct map *map, bool print_off, u64 addr, FILE *fp); +char *map__srcline(struct map *map, u64 addr, struct symbol *sym); +int map__fprintf_srcline(struct map *map, u64 addr, const char *prefix, + FILE *fp); + +int map__load(struct map *map); +struct symbol *map__find_symbol(struct map *map, u64 addr); +struct symbol *map__find_symbol_by_name(struct map *map, const char *name); +struct symbol *map__find_symbol_by_name_idx(struct map *map, const char *name, size_t *idx); +void map__fixup_start(struct map *map); +void map__fixup_end(struct map *map); + +int map__set_kallsyms_ref_reloc_sym(struct map *map, const char *symbol_name, + u64 addr); + +bool __map__is_kernel(const struct map *map); +bool __map__is_extra_kernel_map(const struct map *map); +bool __map__is_bpf_prog(const struct map *map); +bool __map__is_bpf_image(const struct map *map); +bool __map__is_ool(const struct map *map); + +static inline bool __map__is_kmodule(const struct map *map) +{ + return !__map__is_kernel(map) && !__map__is_extra_kernel_map(map) && + !__map__is_bpf_prog(map) && !__map__is_ool(map) && + !__map__is_bpf_image(map); +} + +bool map__has_symbols(const struct map *map); + +bool map__contains_symbol(const struct map *map, const struct symbol *sym); + +#define ENTRY_TRAMPOLINE_NAME "__entry_SYSCALL_64_trampoline" + +static inline bool is_entry_trampoline(const char *name) +{ + return !strcmp(name, ENTRY_TRAMPOLINE_NAME); +} + +static inline bool is_bpf_image(const char *name) +{ + return strncmp(name, "bpf_trampoline_", sizeof("bpf_trampoline_") - 1) == 0 || + strncmp(name, "bpf_dispatcher_", sizeof("bpf_dispatcher_") - 1) == 0; +} + +static inline int is_anon_memory(const char *filename) +{ + return !strcmp(filename, "//anon") || + !strncmp(filename, "/dev/zero", sizeof("/dev/zero") - 1) || + !strncmp(filename, "/anon_hugepage", sizeof("/anon_hugepage") - 1); +} + +static inline int is_no_dso_memory(const char *filename) +{ + return !strncmp(filename, "[stack", 6) || + !strncmp(filename, "/SYSV", 5) || + !strcmp(filename, "[heap]"); +} + +static inline void map__set_start(struct map *map, u64 start) +{ + RC_CHK_ACCESS(map)->start = start; +} + +static inline void map__set_end(struct map *map, u64 end) +{ + RC_CHK_ACCESS(map)->end = end; +} + +static inline void map__set_pgoff(struct map *map, u64 pgoff) +{ + RC_CHK_ACCESS(map)->pgoff = pgoff; +} + +static inline void map__add_pgoff(struct map *map, u64 inc) +{ + RC_CHK_ACCESS(map)->pgoff += inc; +} + +static inline void map__set_reloc(struct map *map, u64 reloc) +{ + RC_CHK_ACCESS(map)->reloc = reloc; +} + +static inline void map__set_priv(struct map *map) +{ + RC_CHK_ACCESS(map)->priv = true; +} + +static inline void map__set_hit(struct map *map) +{ + RC_CHK_ACCESS(map)->hit = true; +} + +static inline void map__set_erange_warned(struct map *map) +{ + RC_CHK_ACCESS(map)->erange_warned = true; +} + +static inline void map__set_dso(struct map *map, struct dso *dso) +{ + RC_CHK_ACCESS(map)->dso = dso; +} + +static inline void map__set_mapping_type(struct map *map, enum mapping_type type) +{ + RC_CHK_ACCESS(map)->mapping_type = type; +} + +static inline enum mapping_type map__mapping_type(struct map *map) +{ + return RC_CHK_ACCESS(map)->mapping_type; +} +#endif /* __PERF_MAP_H */ |
