Skip to content

Commit

Permalink
perf symbols: Factor DSO symtab types to generic binary types
Browse files Browse the repository at this point in the history
Adding interface to access DSOs so it could be used
from another place.

New DSO binary type is added - making current SYMTAB__*
types more general:
   DSO_BINARY_TYPE__* = SYMTAB__*

Following function is added to return path based on the specified
binary type:
   dso__binary_type_file

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Arun Sharma <asharma@fb.com>
Cc: Benjamin Redelings <benjamin.redelings@nescent.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Cyrill Gorcunov <gorcunov@openvz.org>
Cc: Frank Ch. Eigler <fche@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
Cc: Ulrich Drepper <drepper@gmail.com>
Link: http://lkml.kernel.org/r/1342959280-5361-10-git-send-email-jolsa@redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
  • Loading branch information
Jiri Olsa authored and Arnaldo Carvalho de Melo committed Jul 25, 2012
1 parent 6654f5d commit 44f24cb
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 102 deletions.
2 changes: 1 addition & 1 deletion tools/perf/builtin-top.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he)
/*
* We can't annotate with just /proc/kallsyms
*/
if (map->dso->symtab_type == SYMTAB__KALLSYMS) {
if (map->dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS) {
pr_err("Can't annotate %s: No vmlinux file was found in the "
"path\n", sym->name);
sleep(1);
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/util/annotate.c
Original file line number Diff line number Diff line change
Expand Up @@ -777,7 +777,7 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize)
free_filename = false;
}

if (dso->symtab_type == SYMTAB__KALLSYMS) {
if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS) {
char bf[BUILD_ID_SIZE * 2 + 16] = " with build id ";
char *build_id_msg = NULL;

Expand Down
209 changes: 125 additions & 84 deletions tools/perf/util/symbol.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,23 @@ struct symbol_conf symbol_conf = {
.symfs = "",
};

static enum dso_binary_type binary_type_symtab[] = {
DSO_BINARY_TYPE__KALLSYMS,
DSO_BINARY_TYPE__GUEST_KALLSYMS,
DSO_BINARY_TYPE__JAVA_JIT,
DSO_BINARY_TYPE__DEBUGLINK,
DSO_BINARY_TYPE__BUILD_ID_CACHE,
DSO_BINARY_TYPE__FEDORA_DEBUGINFO,
DSO_BINARY_TYPE__UBUNTU_DEBUGINFO,
DSO_BINARY_TYPE__BUILDID_DEBUGINFO,
DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
DSO_BINARY_TYPE__GUEST_KMODULE,
DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE,
DSO_BINARY_TYPE__NOT_FOUND,
};

#define DSO_BINARY_TYPE__SYMTAB_CNT sizeof(binary_type_symtab)

int dso__name_len(const struct dso *dso)
{
if (!dso)
Expand Down Expand Up @@ -318,7 +335,7 @@ struct dso *dso__new(const char *name)
dso__set_short_name(dso, dso->name);
for (i = 0; i < MAP__NR_TYPES; ++i)
dso->symbols[i] = dso->symbol_names[i] = RB_ROOT;
dso->symtab_type = SYMTAB__NOT_FOUND;
dso->symtab_type = DSO_BINARY_TYPE__NOT_FOUND;
dso->loaded = 0;
dso->sorted_by_name = 0;
dso->has_build_id = 0;
Expand Down Expand Up @@ -806,9 +823,9 @@ int dso__load_kallsyms(struct dso *dso, const char *filename,
symbols__fixup_end(&dso->symbols[map->type]);

if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
dso->symtab_type = SYMTAB__GUEST_KALLSYMS;
dso->symtab_type = DSO_BINARY_TYPE__GUEST_KALLSYMS;
else
dso->symtab_type = SYMTAB__KALLSYMS;
dso->symtab_type = DSO_BINARY_TYPE__KALLSYMS;

return dso__split_kallsyms(dso, map, filter);
}
Expand Down Expand Up @@ -1660,32 +1677,110 @@ static int filename__read_debuglink(const char *filename,
char dso__symtab_origin(const struct dso *dso)
{
static const char origin[] = {
[SYMTAB__KALLSYMS] = 'k',
[SYMTAB__JAVA_JIT] = 'j',
[SYMTAB__DEBUGLINK] = 'l',
[SYMTAB__BUILD_ID_CACHE] = 'B',
[SYMTAB__FEDORA_DEBUGINFO] = 'f',
[SYMTAB__UBUNTU_DEBUGINFO] = 'u',
[SYMTAB__BUILDID_DEBUGINFO] = 'b',
[SYMTAB__SYSTEM_PATH_DSO] = 'd',
[SYMTAB__SYSTEM_PATH_KMODULE] = 'K',
[SYMTAB__GUEST_KALLSYMS] = 'g',
[SYMTAB__GUEST_KMODULE] = 'G',
[DSO_BINARY_TYPE__KALLSYMS] = 'k',
[DSO_BINARY_TYPE__JAVA_JIT] = 'j',
[DSO_BINARY_TYPE__DEBUGLINK] = 'l',
[DSO_BINARY_TYPE__BUILD_ID_CACHE] = 'B',
[DSO_BINARY_TYPE__FEDORA_DEBUGINFO] = 'f',
[DSO_BINARY_TYPE__UBUNTU_DEBUGINFO] = 'u',
[DSO_BINARY_TYPE__BUILDID_DEBUGINFO] = 'b',
[DSO_BINARY_TYPE__SYSTEM_PATH_DSO] = 'd',
[DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE] = 'K',
[DSO_BINARY_TYPE__GUEST_KALLSYMS] = 'g',
[DSO_BINARY_TYPE__GUEST_KMODULE] = 'G',
};

if (dso == NULL || dso->symtab_type == SYMTAB__NOT_FOUND)
if (dso == NULL || dso->symtab_type == DSO_BINARY_TYPE__NOT_FOUND)
return '!';
return origin[dso->symtab_type];
}

int dso__binary_type_file(struct dso *dso, enum dso_binary_type type,
char *root_dir, char *file, size_t size)
{
char build_id_hex[BUILD_ID_SIZE * 2 + 1];
int ret = 0;

switch (type) {
case DSO_BINARY_TYPE__DEBUGLINK: {
char *debuglink;

strncpy(file, dso->long_name, size);
debuglink = file + dso->long_name_len;
while (debuglink != file && *debuglink != '/')
debuglink--;
if (*debuglink == '/')
debuglink++;
filename__read_debuglink(dso->long_name, debuglink,
size - (debuglink - file));
}
break;
case DSO_BINARY_TYPE__BUILD_ID_CACHE:
/* skip the locally configured cache if a symfs is given */
if (symbol_conf.symfs[0] ||
(dso__build_id_filename(dso, file, size) == NULL))
ret = -1;
break;

case DSO_BINARY_TYPE__FEDORA_DEBUGINFO:
snprintf(file, size, "%s/usr/lib/debug%s.debug",
symbol_conf.symfs, dso->long_name);
break;

case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO:
snprintf(file, size, "%s/usr/lib/debug%s",
symbol_conf.symfs, dso->long_name);
break;

case DSO_BINARY_TYPE__BUILDID_DEBUGINFO:
if (!dso->has_build_id) {
ret = -1;
break;
}

build_id__sprintf(dso->build_id,
sizeof(dso->build_id),
build_id_hex);
snprintf(file, size,
"%s/usr/lib/debug/.build-id/%.2s/%s.debug",
symbol_conf.symfs, build_id_hex, build_id_hex + 2);
break;

case DSO_BINARY_TYPE__SYSTEM_PATH_DSO:
snprintf(file, size, "%s%s",
symbol_conf.symfs, dso->long_name);
break;

case DSO_BINARY_TYPE__GUEST_KMODULE:
snprintf(file, size, "%s%s%s", symbol_conf.symfs,
root_dir, dso->long_name);
break;

case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE:
snprintf(file, size, "%s%s", symbol_conf.symfs,
dso->long_name);
break;

default:
case DSO_BINARY_TYPE__KALLSYMS:
case DSO_BINARY_TYPE__GUEST_KALLSYMS:
case DSO_BINARY_TYPE__JAVA_JIT:
case DSO_BINARY_TYPE__NOT_FOUND:
ret = -1;
break;
}

return ret;
}

int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter)
{
int size = PATH_MAX;
char *name;
int ret = -1;
int fd;
u_int i;
struct machine *machine;
const char *root_dir;
char *root_dir = (char *) "";
int want_symtab;

dso__set_loaded(dso, map->type);
Expand All @@ -1700,7 +1795,7 @@ int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter)
else
machine = NULL;

name = malloc(size);
name = malloc(PATH_MAX);
if (!name)
return -1;

Expand All @@ -1719,81 +1814,27 @@ int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter)
}

ret = dso__load_perf_map(dso, map, filter);
dso->symtab_type = ret > 0 ? SYMTAB__JAVA_JIT :
SYMTAB__NOT_FOUND;
dso->symtab_type = ret > 0 ? DSO_BINARY_TYPE__JAVA_JIT :
DSO_BINARY_TYPE__NOT_FOUND;
return ret;
}

if (machine)
root_dir = machine->root_dir;

/* Iterate over candidate debug images.
* On the first pass, only load images if they have a full symtab.
* Failing that, do a second pass where we accept .dynsym also
*/
want_symtab = 1;
restart:
for (dso->symtab_type = SYMTAB__DEBUGLINK;
dso->symtab_type != SYMTAB__NOT_FOUND;
dso->symtab_type++) {
switch (dso->symtab_type) {
case SYMTAB__DEBUGLINK: {
char *debuglink;
strncpy(name, dso->long_name, size);
debuglink = name + dso->long_name_len;
while (debuglink != name && *debuglink != '/')
debuglink--;
if (*debuglink == '/')
debuglink++;
filename__read_debuglink(dso->long_name, debuglink,
size - (debuglink - name));
}
break;
case SYMTAB__BUILD_ID_CACHE:
/* skip the locally configured cache if a symfs is given */
if (symbol_conf.symfs[0] ||
(dso__build_id_filename(dso, name, size) == NULL)) {
continue;
}
break;
case SYMTAB__FEDORA_DEBUGINFO:
snprintf(name, size, "%s/usr/lib/debug%s.debug",
symbol_conf.symfs, dso->long_name);
break;
case SYMTAB__UBUNTU_DEBUGINFO:
snprintf(name, size, "%s/usr/lib/debug%s",
symbol_conf.symfs, dso->long_name);
break;
case SYMTAB__BUILDID_DEBUGINFO: {
char build_id_hex[BUILD_ID_SIZE * 2 + 1];

if (!dso->has_build_id)
continue;
for (i = 0; i < DSO_BINARY_TYPE__SYMTAB_CNT; i++) {

build_id__sprintf(dso->build_id,
sizeof(dso->build_id),
build_id_hex);
snprintf(name, size,
"%s/usr/lib/debug/.build-id/%.2s/%s.debug",
symbol_conf.symfs, build_id_hex, build_id_hex + 2);
}
break;
case SYMTAB__SYSTEM_PATH_DSO:
snprintf(name, size, "%s%s",
symbol_conf.symfs, dso->long_name);
break;
case SYMTAB__GUEST_KMODULE:
if (map->groups && machine)
root_dir = machine->root_dir;
else
root_dir = "";
snprintf(name, size, "%s%s%s", symbol_conf.symfs,
root_dir, dso->long_name);
break;
dso->symtab_type = binary_type_symtab[i];

case SYMTAB__SYSTEM_PATH_KMODULE:
snprintf(name, size, "%s%s", symbol_conf.symfs,
dso->long_name);
break;
default:;
}
if (dso__binary_type_file(dso, dso->symtab_type,
root_dir, name, PATH_MAX))
continue;

/* Name is now the name of the next image to try */
fd = open(name, O_RDONLY);
Expand Down Expand Up @@ -2010,9 +2051,9 @@ struct map *machine__new_module(struct machine *machine, u64 start,
return NULL;

if (machine__is_host(machine))
dso->symtab_type = SYMTAB__SYSTEM_PATH_KMODULE;
dso->symtab_type = DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE;
else
dso->symtab_type = SYMTAB__GUEST_KMODULE;
dso->symtab_type = DSO_BINARY_TYPE__GUEST_KMODULE;
map_groups__insert(&machine->kmaps, map);
return map;
}
Expand Down
34 changes: 18 additions & 16 deletions tools/perf/util/symbol.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,21 @@ struct addr_location {
s32 cpu;
};

enum dso_binary_type {
DSO_BINARY_TYPE__KALLSYMS = 0,
DSO_BINARY_TYPE__GUEST_KALLSYMS,
DSO_BINARY_TYPE__JAVA_JIT,
DSO_BINARY_TYPE__DEBUGLINK,
DSO_BINARY_TYPE__BUILD_ID_CACHE,
DSO_BINARY_TYPE__FEDORA_DEBUGINFO,
DSO_BINARY_TYPE__UBUNTU_DEBUGINFO,
DSO_BINARY_TYPE__BUILDID_DEBUGINFO,
DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
DSO_BINARY_TYPE__GUEST_KMODULE,
DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE,
DSO_BINARY_TYPE__NOT_FOUND,
};

enum dso_kernel_type {
DSO_TYPE_USER = 0,
DSO_TYPE_KERNEL,
Expand All @@ -173,13 +188,13 @@ struct dso {
struct rb_root symbol_names[MAP__NR_TYPES];
enum dso_kernel_type kernel;
enum dso_swap_type needs_swap;
enum dso_binary_type symtab_type;
u8 adjust_symbols:1;
u8 has_build_id:1;
u8 hit:1;
u8 annotate_warned:1;
u8 sname_alloc:1;
u8 lname_alloc:1;
unsigned char symtab_type;
u8 sorted_by_name;
u8 loaded;
u8 build_id[BUILD_ID_SIZE];
Expand Down Expand Up @@ -253,21 +268,6 @@ size_t dso__fprintf_symbols_by_name(struct dso *dso,
enum map_type type, FILE *fp);
size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp);

enum symtab_type {
SYMTAB__KALLSYMS = 0,
SYMTAB__GUEST_KALLSYMS,
SYMTAB__JAVA_JIT,
SYMTAB__DEBUGLINK,
SYMTAB__BUILD_ID_CACHE,
SYMTAB__FEDORA_DEBUGINFO,
SYMTAB__UBUNTU_DEBUGINFO,
SYMTAB__BUILDID_DEBUGINFO,
SYMTAB__SYSTEM_PATH_DSO,
SYMTAB__GUEST_KMODULE,
SYMTAB__SYSTEM_PATH_KMODULE,
SYMTAB__NOT_FOUND,
};

char dso__symtab_origin(const struct dso *dso);
void dso__set_long_name(struct dso *dso, char *name);
void dso__set_build_id(struct dso *dso, void *build_id);
Expand Down Expand Up @@ -304,4 +304,6 @@ bool symbol_type__is_a(char symbol_type, enum map_type map_type);

size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp);

int dso__binary_type_file(struct dso *dso, enum dso_binary_type type,
char *root_dir, char *file, size_t size);
#endif /* __PERF_SYMBOL */

0 comments on commit 44f24cb

Please sign in to comment.