diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index eb95ab90f974..02233ef0eaff 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -586,9 +586,9 @@ static char *build_id_cache__find_debug(const char *sbuild_id, const char *dirname = "/usr/lib/debug/.build-id/"; char *realname = NULL; char dirbuf[PATH_MAX]; + char pathbuf[PATH_MAX]; char *debugfile; struct nscookie nsc; - size_t len = 0; debugfile = calloc(1, PATH_MAX); if (!debugfile) @@ -599,9 +599,13 @@ static char *build_id_cache__find_debug(const char *sbuild_id, dirname = dirbuf; } - len = __symbol__join_symfs(debugfile, PATH_MAX, dirname); - snprintf(debugfile + len, PATH_MAX - len, "%.2s/%s.debug", sbuild_id, - sbuild_id + 2); + /* See the build id note in dso__read_binary_type_filename(). */ + if (symbol_conf.symfs_layout_flat) + scnprintf(pathbuf, PATH_MAX, "/%s.debug", sbuild_id); + else + scnprintf(pathbuf, PATH_MAX, "%s%.2s/%s.debug", dirname, + sbuild_id, sbuild_id + 2); + __symbol__join_symfs(debugfile, PATH_MAX, pathbuf); nsinfo__mountns_enter(nsi, &nsc); realname = realpath(debugfile, NULL); diff --git a/tools/perf/util/disasm.c b/tools/perf/util/disasm.c index b39636ec35c1..5478c134e7e3 100644 --- a/tools/perf/util/disasm.c +++ b/tools/perf/util/disasm.c @@ -31,6 +31,7 @@ #include "map.h" #include "maps.h" #include "namespaces.h" +#include "path.h" #include "srcline.h" #include "symbol.h" #include "thread.h" @@ -1189,7 +1190,12 @@ static int dso__disassemble_filename(struct dso *dso, char *filename, size_t fil build_id_filename = dso__build_id_filename(dso, NULL, 0, false); if (build_id_filename) { - __symbol__join_symfs(filename, filename_size, build_id_filename); + /* + * This is a path in perf's own build id cache, not a path on + * the profiled system, so the symfs layout does not apply. + */ + path__join(filename, filename_size, symbol_conf.symfs, + build_id_filename); free(build_id_filename); } else { if (dso__has_build_id(dso)) diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 9e90de92fcfa..11db461f2032 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -121,6 +121,7 @@ int dso__read_binary_type_filename(const struct dso *dso, const char *root_dir, char *filename, size_t size) { char build_id_hex[SBUILD_ID_SIZE]; + char relative[PATH_MAX]; int ret = 0; size_t len; @@ -173,13 +174,15 @@ int dso__read_binary_type_filename(const struct dso *dso, break; case DSO_BINARY_TYPE__FEDORA_DEBUGINFO: - len = __symbol__join_symfs(filename, size, "/usr/lib/debug"); - snprintf(filename + len, size - len, "%s.debug", dso__long_name(dso)); + snprintf(relative, sizeof(relative), "/usr/lib/debug%s.debug", + dso__long_name(dso)); + __symbol__join_symfs(filename, size, relative); break; case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO: - len = __symbol__join_symfs(filename, size, "/usr/lib/debug"); - snprintf(filename + len, size - len, "%s", dso__long_name(dso)); + snprintf(relative, sizeof(relative), "/usr/lib/debug%s", + dso__long_name(dso)); + __symbol__join_symfs(filename, size, relative); break; case DSO_BINARY_TYPE__MIXEDUP_UBUNTU_DEBUGINFO: @@ -193,8 +196,9 @@ int dso__read_binary_type_filename(const struct dso *dso, ret = -1; break; } - len = __symbol__join_symfs(filename, size, "/usr/lib/debug"); - snprintf(filename + len, size - len, "%s", dso__long_name(dso) + 4); + snprintf(relative, sizeof(relative), "/usr/lib/debug%s", + dso__long_name(dso) + 4); + __symbol__join_symfs(filename, size, relative); break; case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO: @@ -206,15 +210,15 @@ int dso__read_binary_type_filename(const struct dso *dso, while (last_slash != dso__long_name(dso) && *last_slash != '/') last_slash--; - len = __symbol__join_symfs(filename, size, ""); dir_size = last_slash - dso__long_name(dso) + 2; - if (dir_size > (size - len)) { + if (dir_size > sizeof(relative)) { ret = -1; break; } - len += scnprintf(filename + len, dir_size, "%s", dso__long_name(dso)); - len += scnprintf(filename + len , size - len, ".debug%s", - last_slash); + len = scnprintf(relative, dir_size, "%s", dso__long_name(dso)); + scnprintf(relative + len, sizeof(relative) - len, ".debug%s", + last_slash); + __symbol__join_symfs(filename, size, relative); break; } @@ -225,9 +229,20 @@ int dso__read_binary_type_filename(const struct dso *dso, } build_id__snprintf(dso__bid(dso), build_id_hex, sizeof(build_id_hex)); - len = __symbol__join_symfs(filename, size, "/usr/lib/debug/.build-id/"); - snprintf(filename + len, size - len, "%.2s/%s.debug", - build_id_hex, build_id_hex + 2); + /* + * The build id cache layout splits the first two characters off + * into a directory name, so the basename of the hierarchy path + * is only part of the build id. Name the flat file after the + * whole build id instead. + */ + if (symbol_conf.symfs_layout_flat) + snprintf(relative, sizeof(relative), "/%s.debug", + build_id_hex); + else + snprintf(relative, sizeof(relative), + "/usr/lib/debug/.build-id/%.2s/%s.debug", + build_id_hex, build_id_hex + 2); + __symbol__join_symfs(filename, size, relative); break; case DSO_BINARY_TYPE__VMLINUX: