|
@@ -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)
|
|
@@ -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;
|
|
@@ -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);
|
|
|
}
|
|
@@ -1660,32 +1677,110 @@ out:
|
|
|
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);
|
|
@@ -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;
|
|
|
|
|
@@ -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);
|
|
@@ -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;
|
|
|
}
|