summaryrefslogtreecommitdiffstats
path: root/tools/perf/util/map.h
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-08-23 13:28:57 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-08-23 13:28:57 -0700
commit4352b8aee98005853aa63f57d6377282de17a33f (patch)
tree27614d7a9ef05c32d089004e104364ce42324837 /tools/perf/util/map.h
downloadlinux-stable-4352b8aee98005853aa63f57d6377282de17a33f.tar.gz
linux-stable-4352b8aee98005853aa63f57d6377282de17a33f.zip
Merge tag 'i3c/for-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linuxgrafted
Pull I3C updates from Alexandre Belloni: "A new driver this cycle, for the AMD AXI I3C controller. There are also new features such as IBI wakeup support, SETAASA device discovery and ACPI support for the the DAA methods, meaning we can now communicate with the SPD devices on DDR5 modules. New driver: - AMD AXI I3C master controller Subsystem: - I3C Common Command Code (CCC) handling improvements, especially around GET CCCs - SETAASA device discovery support - ACPI support for all existing DAA methods like SETDASA, SETNEWDA as well as I2C devices on I3C bus - IBI-based wakeup support Drivers: - dw: SETAASA support - mipi-i3c-hci: advertise IBI wakeup capability, AMD_PT I3C controller support, PIO queue management support for HCI v1.2 - renesas: improve suspend to RAM support, add runtime PM support" * tag 'i3c/for-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux: (70 commits) i3c: dw: reduce do_daa time if there's no client i3c: mipi-i3c-hci: Add support for AMD_PT I3C controller i3c: mipi-i3c-hci: Add PIO queue management support for HCI v1.2 i3c: mipi-i3c-hci: Fix missing STAT_IBI_STATUS_THLD in PIO mode i3c: dw: rename "pclk" to "apb" to match dt-binding i3c: dw: make struct dw_i3c_cmd smaller i3c: dw: use COMMAND_PORT_TRANSFER_ARG instead of hardcoding i3c: renesas: Don't register devices when ENTDAA times out i3c: master: dw-i3c-master: fix OD timing for first broadcast i3c: mipi-i3c-hci: Advertise IBI wakeup capability i3c: mipi-i3c-hci: Factor out i3c_hci_sysdev() i3c: mipi-i3c-hci-pci: Propagate I3C wakeup requirements to PCI i3c: master: Reject IBI requests from non-IBI-capable devices i3c: master: Add helper to query bus wakeup requirements i3c: master: Report wakeup events for IBIs i3c: master: Support IBI-based wakeup capability i3c: master: Fix potential UAF in i3c_device_match() i3c: master: Fix potential UAF in i3c_device_uevent() i3c: Make dev->desc locking assumptions explicit i3c: master: Fix use-after-free of master->this ...
Diffstat (limited to 'tools/perf/util/map.h')
-rw-r--r--tools/perf/util/map.h318
1 files changed, 318 insertions, 0 deletions
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
new file mode 100644
index 000000000..fb0279810
--- /dev/null
+++ b/tools/perf/util/map.h
@@ -0,0 +1,318 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __PERF_MAP_H
+#define __PERF_MAP_H
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <linux/refcount.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 */