Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 66e274f3 authored by Frederic Weisbecker's avatar Frederic Weisbecker
Browse files

perf tools: Factorize the map helpers



Factorize the dso mapping helpers into a single purpose common file
"util/map.c"

Signed-off-by: default avatarFrederic Weisbecker <fweisbec@gmail.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Brice Goglin <Brice.Goglin@inria.fr>
parent 1fe2c106
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -340,6 +340,7 @@ LIB_OBJS += util/header.o
LIB_OBJS += util/callchain.o
LIB_OBJS += util/values.o
LIB_OBJS += util/debug.o
LIB_OBJS += util/map.o

BUILTIN_OBJS += builtin-annotate.o
BUILTIN_OBJS += builtin-help.o
+1 −78
Original line number Diff line number Diff line
@@ -51,83 +51,6 @@ struct sym_ext {
	char		*path;
};

struct map {
	struct list_head node;
	u64	 start;
	u64	 end;
	u64	 pgoff;
	u64	 (*map_ip)(struct map *, u64);
	struct dso	 *dso;
};

static u64 map__map_ip(struct map *map, u64 ip)
{
	return ip - map->start + map->pgoff;
}

static u64 vdso__map_ip(struct map *map __used, u64 ip)
{
	return ip;
}

static struct map *map__new(struct mmap_event *event)
{
	struct map *self = malloc(sizeof(*self));

	if (self != NULL) {
		const char *filename = event->filename;

		self->start = event->start;
		self->end   = event->start + event->len;
		self->pgoff = event->pgoff;

		self->dso = dsos__findnew(filename);
		if (self->dso == NULL)
			goto out_delete;

		if (self->dso == vdso)
			self->map_ip = vdso__map_ip;
		else
			self->map_ip = map__map_ip;
	}
	return self;
out_delete:
	free(self);
	return NULL;
}

static struct map *map__clone(struct map *self)
{
	struct map *map = malloc(sizeof(*self));

	if (!map)
		return NULL;

	memcpy(map, self, sizeof(*self));

	return map;
}

static int map__overlap(struct map *l, struct map *r)
{
	if (l->start > r->start) {
		struct map *t = l;
		l = r;
		r = t;
	}

	if (l->end > r->start)
		return 1;

	return 0;
}

static size_t map__fprintf(struct map *self, FILE *fp)
{
	return fprintf(fp, " %Lx-%Lx %Lx %s\n",
		       self->start, self->end, self->pgoff, self->dso->name);
}


struct thread {
	struct rb_node	 rb_node;
@@ -797,7 +720,7 @@ static int
process_mmap_event(event_t *event, unsigned long offset, unsigned long head)
{
	struct thread *thread = threads__findnew(event->mmap.pid);
	struct map *map = map__new(&event->mmap);
	struct map *map = map__new(&event->mmap, NULL, 0);

	dprintf("%p [%p]: PERF_EVENT_MMAP %d: [%p(%p) @ %p]: %s\n",
		(void *)(offset + head),
+1 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
#include "util/string.h"

#include "util/header.h"
#include "util/event.h"

#include <unistd.h>
#include <sched.h>
+5 −119
Original line number Diff line number Diff line
@@ -67,6 +67,10 @@ static char callchain_default_opt[] = "fractal,0.5";

static int		callchain;

static char		__cwd[PATH_MAX];
static char		*cwd = __cwd;
static int		cwdlen;

static
struct callchain_param	callchain_param = {
	.mode	= CHAIN_GRAPH_REL,
@@ -102,124 +106,6 @@ static int repsep_fprintf(FILE *fp, const char *fmt, ...)
	return n;
}



static char __cwd[PATH_MAX];
static char *cwd = __cwd;
static int cwdlen;

static int strcommon(const char *pathname)
{
	int n = 0;

	while (n < cwdlen && pathname[n] == cwd[n])
		++n;

	return n;
}

struct map {
	struct list_head node;
	u64	 start;
	u64	 end;
	u64	 pgoff;
	u64	 (*map_ip)(struct map *, u64);
	struct dso	 *dso;
};

static u64 map__map_ip(struct map *map, u64 ip)
{
	return ip - map->start + map->pgoff;
}

static u64 vdso__map_ip(struct map *map __used, u64 ip)
{
	return ip;
}

static inline int is_anon_memory(const char *filename)
{
	return strcmp(filename, "//anon") == 0;
}

static struct map *map__new(struct mmap_event *event)
{
	struct map *self = malloc(sizeof(*self));

	if (self != NULL) {
		const char *filename = event->filename;
		char newfilename[PATH_MAX];
		int anon;

		if (cwd) {
			int n = strcommon(filename);

			if (n == cwdlen) {
				snprintf(newfilename, sizeof(newfilename),
					 ".%s", filename + n);
				filename = newfilename;
			}
		}

		anon = is_anon_memory(filename);

		if (anon) {
			snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", event->pid);
			filename = newfilename;
		}

		self->start = event->start;
		self->end   = event->start + event->len;
		self->pgoff = event->pgoff;

		self->dso = dsos__findnew(filename);
		if (self->dso == NULL)
			goto out_delete;

		if (self->dso == vdso || anon)
			self->map_ip = vdso__map_ip;
		else
			self->map_ip = map__map_ip;
	}
	return self;
out_delete:
	free(self);
	return NULL;
}

static struct map *map__clone(struct map *self)
{
	struct map *map = malloc(sizeof(*self));

	if (!map)
		return NULL;

	memcpy(map, self, sizeof(*self));

	return map;
}

static int map__overlap(struct map *l, struct map *r)
{
	if (l->start > r->start) {
		struct map *t = l;
		l = r;
		r = t;
	}

	if (l->end > r->start)
		return 1;

	return 0;
}

static size_t map__fprintf(struct map *self, FILE *fp)
{
	return fprintf(fp, " %Lx-%Lx %Lx %s\n",
		       self->start, self->end, self->pgoff, self->dso->name);
}


struct thread {
	struct rb_node	 rb_node;
	struct list_head maps;
@@ -1474,7 +1360,7 @@ static int
process_mmap_event(event_t *event, unsigned long offset, unsigned long head)
{
	struct thread *thread = threads__findnew(event->mmap.pid);
	struct map *map = map__new(&event->mmap);
	struct map *map = map__new(&event->mmap, cwd, cwdlen);

	dprintf("%p [%p]: PERF_EVENT_MMAP %d: [%p(%p) @ %p]: %s\n",
		(void *)(offset + head),
+1 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@
#include "../perf.h"
#include <linux/list.h>
#include <linux/rbtree.h>
#include "util.h"
#include "symbol.h"

enum chain_mode {
Loading