Skip to content

Commit

Permalink
perf tools: Factorize the map helpers
Browse files Browse the repository at this point in the history
Factorize the dso mapping helpers into a single purpose common file
"util/map.c"

Signed-off-by: Frederic 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>
  • Loading branch information
Frederic Weisbecker committed Aug 12, 2009
1 parent 1fe2c10 commit 66e274f
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 198 deletions.
1 change: 1 addition & 0 deletions tools/perf/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
79 changes: 1 addition & 78 deletions tools/perf/builtin-annotate.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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),
Expand Down
1 change: 1 addition & 0 deletions tools/perf/builtin-record.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "util/string.h"

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

#include <unistd.h>
#include <sched.h>
Expand Down
124 changes: 5 additions & 119 deletions tools/perf/builtin-report.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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),
Expand Down
1 change: 1 addition & 0 deletions tools/perf/util/callchain.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "../perf.h"
#include <linux/list.h>
#include <linux/rbtree.h>
#include "util.h"
#include "symbol.h"

enum chain_mode {
Expand Down
30 changes: 30 additions & 0 deletions tools/perf/util/event.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
#ifndef __PERF_EVENT_H
#define __PERF_EVENT_H
#include "../perf.h"
#include "util.h"
#include <linux/list.h>

struct ip_event {
struct perf_event_header header;
Expand Down Expand Up @@ -52,3 +56,29 @@ typedef union event_union {
struct lost_event lost;
struct read_event read;
} event_t;

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

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

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

struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen);
struct map *map__clone(struct map *self);
int map__overlap(struct map *l, struct map *r);
size_t map__fprintf(struct map *self, FILE *fp);

#endif
97 changes: 97 additions & 0 deletions tools/perf/util/map.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#include "event.h"
#include "symbol.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

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

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

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

return n;
}

struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen)
{
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, cwd, cwdlen);

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;
}

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

if (!map)
return NULL;

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

return map;
}

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;
}

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);
}
Loading

0 comments on commit 66e274f

Please sign in to comment.