Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 169527
b: refs/heads/master
c: ed52ce2
h: refs/heads/master
i:
  169525: d38c0ea
  169523: a82d833
  169519: 841b23b
v: v3
  • Loading branch information
Arnaldo Carvalho de Melo authored and Ingo Molnar committed Oct 20, 2009
1 parent f1a817f commit a77a42e
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 27 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: bbe2987bea26a684ff11d887dfc4cf39b22c27a2
refs/heads/master: ed52ce2e3c33dc7626a40fa2da766d1a6460e543
62 changes: 42 additions & 20 deletions trunk/tools/perf/builtin-annotate.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,12 @@ static void hist_hit(struct hist_entry *he, u64 ip)
return;

sym_size = sym->end - sym->start;
ip = he->map->map_ip(he->map, ip);
offset = ip - sym->start;

if (verbose)
fprintf(stderr, "%s: ip=%Lx\n", __func__,
he->map->unmap_ip(he->map, ip));

if (offset >= sym_size)
return;

Expand All @@ -83,8 +86,7 @@ static int hist_entry__add(struct thread *thread, struct map *map,
count, level, &hit);
if (he == NULL)
return -ENOMEM;
if (hit)
hist_hit(he, ip);
hist_hit(he, ip);
return 0;
}

Expand Down Expand Up @@ -260,14 +262,15 @@ process_event(event_t *event, unsigned long offset, unsigned long head)
return 0;
}

static int
parse_line(FILE *file, struct symbol *sym, u64 len)
static int parse_line(FILE *file, struct hist_entry *he, u64 len)
{
struct symbol *sym = he->sym;
char *line = NULL, *tmp, *tmp2;
static const char *prev_line;
static const char *prev_color;
unsigned int offset;
size_t line_len;
u64 start;
s64 line_ip;
int ret;
char *c;
Expand Down Expand Up @@ -304,14 +307,16 @@ parse_line(FILE *file, struct symbol *sym, u64 len)
line_ip = -1;
}

start = he->map->unmap_ip(he->map, sym->start);

if (line_ip != -1) {
const char *path = NULL;
unsigned int hits = 0;
double percent = 0.0;
const char *color;
struct sym_ext *sym_ext = sym->priv;

offset = line_ip - sym->start;
offset = line_ip - start;
if (offset < len)
hits = sym->hist[offset];

Expand Down Expand Up @@ -390,8 +395,10 @@ static void free_source_line(struct symbol *sym, int len)

/* Get the filename:line for the colored entries */
static void
get_source_line(struct symbol *sym, int len, const char *filename)
get_source_line(struct hist_entry *he, int len, const char *filename)
{
struct symbol *sym = he->sym;
u64 start;
int i;
char cmd[PATH_MAX * 2];
struct sym_ext *sym_ext;
Expand All @@ -404,6 +411,7 @@ get_source_line(struct symbol *sym, int len, const char *filename)
return;

sym_ext = sym->priv;
start = he->map->unmap_ip(he->map, sym->start);

for (i = 0; i < len; i++) {
char *path = NULL;
Expand All @@ -415,7 +423,7 @@ get_source_line(struct symbol *sym, int len, const char *filename)
if (sym_ext[i].percent <= 0.5)
continue;

offset = sym->start + i;
offset = start + i;
sprintf(cmd, "addr2line -e %s %016llx", filename, offset);
fp = popen(cmd, "r");
if (!fp)
Expand Down Expand Up @@ -465,8 +473,11 @@ static void print_summary(const char *filename)
}
}

static void annotate_sym(struct dso *dso, struct symbol *sym)
static void annotate_sym(struct hist_entry *he)
{
struct map *map = he->map;
struct dso *dso = map->dso;
struct symbol *sym = he->sym;
const char *filename = dso->long_name, *d_filename;
u64 len;
char command[PATH_MAX*2];
Expand All @@ -475,6 +486,12 @@ static void annotate_sym(struct dso *dso, struct symbol *sym)
if (!filename)
return;

if (verbose)
fprintf(stderr, "%s: filename=%s, sym=%s, start=%Lx, end=%Lx\n",
__func__, filename, sym->name,
map->unmap_ip(map, sym->start),
map->unmap_ip(map, sym->end));

if (full_paths)
d_filename = filename;
else
Expand All @@ -483,7 +500,7 @@ static void annotate_sym(struct dso *dso, struct symbol *sym)
len = sym->end - sym->start;

if (print_line) {
get_source_line(sym, len, filename);
get_source_line(he, len, filename);
print_summary(filename);
}

Expand All @@ -496,7 +513,8 @@ static void annotate_sym(struct dso *dso, struct symbol *sym)
dso, dso->long_name, sym, sym->name);

sprintf(command, "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS %s|grep -v %s",
sym->start, sym->end, filename, filename);
map->unmap_ip(map, sym->start), map->unmap_ip(map, sym->end),
filename, filename);

if (verbose >= 3)
printf("doing: %s\n", command);
Expand All @@ -506,7 +524,7 @@ static void annotate_sym(struct dso *dso, struct symbol *sym)
return;

while (!feof(file)) {
if (parse_line(file, sym, len) < 0)
if (parse_line(file, he, len) < 0)
break;
}

Expand All @@ -518,18 +536,22 @@ static void annotate_sym(struct dso *dso, struct symbol *sym)
static void find_annotations(void)
{
struct rb_node *nd;
struct dso *dso;
int count = 0;

list_for_each_entry(dso, &dsos, node) {
for (nd = rb_first(&output_hists); nd; nd = rb_next(nd)) {
struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node);

for (nd = rb_first(&dso->syms); nd; nd = rb_next(nd)) {
struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
if (he->sym && he->sym->hist) {
annotate_sym(he);
count++;
/*
* Since we have a hist_entry per IP for the same
* symbol, free he->sym->hist to signal we already
* processed this symbol.
*/
free(he->sym->hist);
he->sym->hist = NULL;

if (sym->hist) {
annotate_sym(dso, sym);
count++;
}
}
}

Expand Down
8 changes: 7 additions & 1 deletion trunk/tools/perf/util/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ struct map {
u64 end;
u64 pgoff;
u64 (*map_ip)(struct map *, u64);
u64 (*unmap_ip)(struct map *, u64);
struct dso *dso;
};

Expand All @@ -90,7 +91,12 @@ 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)
static inline u64 map__unmap_ip(struct map *map, u64 ip)
{
return ip + map->start - map->pgoff;
}

static inline u64 identity__map_ip(struct map *map __used, u64 ip)
{
return ip;
}
Expand Down
6 changes: 4 additions & 2 deletions trunk/tools/perf/util/map.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,11 @@ static int strcommon(const char *pathname, char *cwd, int cwdlen)
goto out_delete;

if (self->dso == vdso || anon)
self->map_ip = vdso__map_ip;
else
self->map_ip = self->unmap_ip = identity__map_ip;
else {
self->map_ip = map__map_ip;
self->unmap_ip = map__unmap_ip;
}
}
return self;
out_delete:
Expand Down
8 changes: 5 additions & 3 deletions trunk/tools/perf/util/symbol.c
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ static int kernel_maps__split_kallsyms(symbol_filter_t filter, int use_modules)
return -1;
}

map->map_ip = vdso__map_ip;
map->map_ip = map->unmap_ip = identity__map_ip;
kernel_maps__insert(map);
++kernel_range;
}
Expand Down Expand Up @@ -790,7 +790,8 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
dso__delete(curr_dso);
goto out_elf_end;
}
curr_map->map_ip = vdso__map_ip;
curr_map->map_ip = identity__map_ip;
curr_map->unmap_ip = identity__map_ip;
curr_dso->origin = DSO__ORIG_KERNEL;
kernel_maps__insert(curr_map);
dsos__add(curr_dso);
Expand Down Expand Up @@ -1158,6 +1159,7 @@ static struct map *map__new2(u64 start, struct dso *dso)
self->pgoff = 0;
self->dso = dso;
self->map_ip = map__map_ip;
self->unmap_ip = map__unmap_ip;
RB_CLEAR_NODE(&self->rb_node);
}
return self;
Expand Down Expand Up @@ -1259,7 +1261,7 @@ int dsos__load_kernel(const char *vmlinux, unsigned int sym_priv_size,
if (kernel_map == NULL)
goto out_delete_dso;

kernel_map->map_ip = vdso__map_ip;
kernel_map->map_ip = kernel_map->unmap_ip = identity__map_ip;

if (use_modules && dsos__load_modules(sym_priv_size) < 0) {
fprintf(stderr, "Failed to load list of modules in use! "
Expand Down

0 comments on commit a77a42e

Please sign in to comment.