|
@@ -24,6 +24,16 @@ const char *sym_hist_filter;
|
|
|
#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
|
|
|
#endif
|
|
|
|
|
|
+enum dso_origin {
|
|
|
+ DSO__ORIG_KERNEL = 0,
|
|
|
+ DSO__ORIG_JAVA_JIT,
|
|
|
+ DSO__ORIG_FEDORA,
|
|
|
+ DSO__ORIG_UBUNTU,
|
|
|
+ DSO__ORIG_BUILDID,
|
|
|
+ DSO__ORIG_DSO,
|
|
|
+ DSO__ORIG_NOT_FOUND,
|
|
|
+};
|
|
|
+
|
|
|
static struct symbol *symbol__new(u64 start, u64 len,
|
|
|
const char *name, unsigned int priv_size,
|
|
|
u64 obj_start, int verbose)
|
|
@@ -81,6 +91,7 @@ struct dso *dso__new(const char *name, unsigned int sym_priv_size)
|
|
|
self->sym_priv_size = sym_priv_size;
|
|
|
self->find_symbol = dso__find_symbol;
|
|
|
self->slen_calculated = 0;
|
|
|
+ self->origin = DSO__ORIG_NOT_FOUND;
|
|
|
}
|
|
|
|
|
|
return self;
|
|
@@ -710,7 +721,7 @@ static char *dso__read_build_id(struct dso *self, int verbose)
|
|
|
++raw;
|
|
|
bid += 2;
|
|
|
}
|
|
|
- if (verbose)
|
|
|
+ if (verbose >= 2)
|
|
|
printf("%s(%s): %s\n", __func__, self->name, build_id);
|
|
|
out_elf_end:
|
|
|
elf_end(elf);
|
|
@@ -720,11 +731,26 @@ out:
|
|
|
return build_id;
|
|
|
}
|
|
|
|
|
|
+char dso__symtab_origin(const struct dso *self)
|
|
|
+{
|
|
|
+ static const char origin[] = {
|
|
|
+ [DSO__ORIG_KERNEL] = 'k',
|
|
|
+ [DSO__ORIG_JAVA_JIT] = 'j',
|
|
|
+ [DSO__ORIG_FEDORA] = 'f',
|
|
|
+ [DSO__ORIG_UBUNTU] = 'u',
|
|
|
+ [DSO__ORIG_BUILDID] = 'b',
|
|
|
+ [DSO__ORIG_DSO] = 'd',
|
|
|
+ };
|
|
|
+
|
|
|
+ if (self == NULL || self->origin == DSO__ORIG_NOT_FOUND)
|
|
|
+ return '!';
|
|
|
+ return origin[self->origin];
|
|
|
+}
|
|
|
+
|
|
|
int dso__load(struct dso *self, symbol_filter_t filter, int verbose)
|
|
|
{
|
|
|
int size = PATH_MAX;
|
|
|
char *name = malloc(size), *build_id = NULL;
|
|
|
- int variant = 0;
|
|
|
int ret = -1;
|
|
|
int fd;
|
|
|
|
|
@@ -733,19 +759,26 @@ int dso__load(struct dso *self, symbol_filter_t filter, int verbose)
|
|
|
|
|
|
self->adjust_symbols = 0;
|
|
|
|
|
|
- if (strncmp(self->name, "/tmp/perf-", 10) == 0)
|
|
|
- return dso__load_perf_map(self, filter, verbose);
|
|
|
+ if (strncmp(self->name, "/tmp/perf-", 10) == 0) {
|
|
|
+ ret = dso__load_perf_map(self, filter, verbose);
|
|
|
+ self->origin = ret > 0 ? DSO__ORIG_JAVA_JIT :
|
|
|
+ DSO__ORIG_NOT_FOUND;
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ self->origin = DSO__ORIG_FEDORA - 1;
|
|
|
|
|
|
more:
|
|
|
do {
|
|
|
- switch (variant) {
|
|
|
- case 0: /* Fedora */
|
|
|
+ self->origin++;
|
|
|
+ switch (self->origin) {
|
|
|
+ case DSO__ORIG_FEDORA:
|
|
|
snprintf(name, size, "/usr/lib/debug%s.debug", self->name);
|
|
|
break;
|
|
|
- case 1: /* Ubuntu */
|
|
|
+ case DSO__ORIG_UBUNTU:
|
|
|
snprintf(name, size, "/usr/lib/debug%s", self->name);
|
|
|
break;
|
|
|
- case 2:
|
|
|
+ case DSO__ORIG_BUILDID:
|
|
|
build_id = dso__read_build_id(self, verbose);
|
|
|
if (build_id != NULL) {
|
|
|
snprintf(name, size,
|
|
@@ -754,16 +787,15 @@ more:
|
|
|
free(build_id);
|
|
|
break;
|
|
|
}
|
|
|
- variant++;
|
|
|
+ self->origin++;
|
|
|
/* Fall thru */
|
|
|
- case 3: /* Sane people */
|
|
|
+ case DSO__ORIG_DSO:
|
|
|
snprintf(name, size, "%s", self->name);
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
goto out;
|
|
|
}
|
|
|
- variant++;
|
|
|
|
|
|
fd = open(name, O_RDONLY);
|
|
|
} while (fd < 0);
|
|
@@ -899,6 +931,9 @@ int dso__load_kernel(struct dso *self, const char *vmlinux,
|
|
|
if (err <= 0)
|
|
|
err = dso__load_kallsyms(self, filter, verbose);
|
|
|
|
|
|
+ if (err > 0)
|
|
|
+ self->origin = DSO__ORIG_KERNEL;
|
|
|
+
|
|
|
return err;
|
|
|
}
|
|
|
|