From nobody Tue Dec 16 18:33:13 2025 Received: from szxga02-in.huawei.com (szxga02-in.huawei.com [45.249.212.188]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DB1C82E3FE; Sat, 15 Jun 2024 09:20:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.188 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718443245; cv=none; b=qVTgVrjZFuA2BqwqhWvmsJnk6N7kQPwga03VQrpFY8UJi4gmxkReDjWZ4a0OUbCAMQqDR/j7UxH4py0PwGRxAWKIn2ulx7FKjqHgfm57V85JYK7FKeHedi1XHoCuu6TM8DlB7kftQHb8iwaB+YVEUMYlnwzbUu4m+ElkMaBREN4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718443245; c=relaxed/simple; bh=WbNImJGwn8Zxpjs4LOOSeBspcKfX6Jg7eje7LLzEa5g=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=iHXCUukIBzdc+XICU1XKBoJANvu03Tac0GewXxV/W0GAnhiQfTFjpJ/LuPk9ktFz8IdGRcxZLUs/W8d+ueU5dthYooT578XjB06I0kA8FSEJk6Cb5JCm67oKEjBQ44zQQ7yb3qveew66acUzkUckw9lQASWstnRVBottQjUSh94= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=45.249.212.188 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.19.163.48]) by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4W1Vqj4Xw5zVkjr; Sat, 15 Jun 2024 17:15:45 +0800 (CST) Received: from kwepemd100011.china.huawei.com (unknown [7.221.188.204]) by mail.maildlp.com (Postfix) with ESMTPS id E34A3180060; Sat, 15 Jun 2024 17:20:33 +0800 (CST) Received: from M910t.huawei.com (10.110.54.157) by kwepemd100011.china.huawei.com (7.221.188.204) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1258.34; Sat, 15 Jun 2024 17:20:32 +0800 From: Changbin Du To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Nathan Chancellor CC: Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Liang, Kan" , Nick Desaulniers , Bill Wendling , Justin Stitt , , , , Changbin Du Subject: [PATCH v2 1/4] perf: support specify vdso path in cmdline Date: Sat, 15 Jun 2024 17:20:12 +0800 Message-ID: <20240615092015.1820362-2-changbin.du@huawei.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240615092015.1820362-1-changbin.du@huawei.com> References: <20240615092015.1820362-1-changbin.du@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: dggems705-chm.china.huawei.com (10.3.19.182) To kwepemd100011.china.huawei.com (7.221.188.204) The vdso dumped from process memory (in buildid-cache) lacks debugging info. To annotate vdso symbols with source lines we need specify a debugging version. For x86, we can find them from your local build as arch/x86/entry/vdso/vdso{32,64}.so.dbg. Or they may reside in /lib/modules//vdso/vdso{32,64}.so on Ubuntu. But notice that the buildid has to match. $ sudo perf record -a $ sudo perf report --objdump=3Dllvm-objdump \ --vdso arch/x86/entry/vdso/vdso64.so.dbg,arch/x86/entry/vdso/vdso32.so.dbg Samples: 17K of event 'cycles:P', 4000 Hz, Event count (approx.): 1760 __vdso_clock_gettime /work/linux-host/arch/x86/entry/vdso/vdso64.so.d Percent=E2=94=82 movq -48(%rbp),%rsi =E2=94=82 testq %rax,%rax =E2=94=82 ; return vread_hvclock(); =E2=94=82 movq %rax,%rdx =E2=94=82 ; if (unlikely(!vdso_cycles_ok(cycles))) =E2=94=82 =E2=86=91 js eb =E2=94=82 =E2=86=91 jmp 74 =E2=94=82 ; ts->tv_sec =3D vdso_ts->sec; 0.02 =E2=94=82147: leaq 2(%rbx),%rax =E2=94=82 shlq $4, %rax =E2=94=82 addq %r10,%rax =E2=94=82 ; while ((seq =3D READ_ONCE(vd->seq)) & = 1) { 9.38 =E2=94=82152: movl (%r10),%ecx When doing cross platform analysis, we also need specify the vdso path if we are interested in its symbols. Signed-off-by: Changbin Du --- tools/perf/builtin-annotate.c | 2 + tools/perf/builtin-c2c.c | 2 + tools/perf/builtin-inject.c | 2 + tools/perf/builtin-report.c | 2 + tools/perf/builtin-script.c | 2 + tools/perf/builtin-top.c | 2 + tools/perf/util/disasm.c | 5 ++- tools/perf/util/symbol.c | 82 ++++++++++++++++++++++++++++++++++- tools/perf/util/symbol_conf.h | 5 +++ 9 files changed, 100 insertions(+), 4 deletions(-) diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 50d2fb222d48..ff466882065d 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -742,6 +742,8 @@ int cmd_annotate(int argc, const char **argv) "file", "vmlinux pathname"), OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules, "load module symbols - WARNING: use only with -k and LIVE kernel"), + OPT_CALLBACK(0, "vdso", NULL, "vdso1[,vdso2]", "vdso pathnames", + parse_vdso_pathnames), OPT_BOOLEAN('l', "print-line", &annotate_opts.print_lines, "print matching source lines (may be slow)"), OPT_BOOLEAN('P', "full-paths", &annotate_opts.full_path, diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c index c157bd31f2e5..4764f9139661 100644 --- a/tools/perf/builtin-c2c.c +++ b/tools/perf/builtin-c2c.c @@ -3018,6 +3018,8 @@ static int perf_c2c__report(int argc, const char **ar= gv) const struct option options[] =3D { OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, "file", "vmlinux pathname"), + OPT_CALLBACK(0, "vdso", NULL, "vdso1[,vdso2]", "vdso pathnames", + parse_vdso_pathnames), OPT_STRING('i', "input", &input_name, "file", "the input file to process"), OPT_INCR('N', "node-info", &c2c.node_info, diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index a212678d47be..e774e83d0a0f 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -2247,6 +2247,8 @@ int cmd_inject(int argc, const char **argv) "don't load vmlinux even if found"), OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name, "file", "kallsyms pathname"), + OPT_CALLBACK(0, "vdso", NULL, "vdso1[,vdso2]", "vdso pathnames", + parse_vdso_pathnames), OPT_BOOLEAN('f', "force", &data.force, "don't complain, do it"), OPT_CALLBACK_OPTARG(0, "itrace", &inject.itrace_synth_opts, NULL, "opts", "Instruction Tracing options\n" diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 69618fb0110b..a64b48460dce 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -1324,6 +1324,8 @@ int cmd_report(int argc, const char **argv) "don't load vmlinux even if found"), OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name, "file", "kallsyms pathname"), + OPT_CALLBACK(0, "vdso", NULL, "vdso1[,vdso2]", "vdso pathnames", + parse_vdso_pathnames), OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"), OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules, "load module symbols - WARNING: use only with -k and LIVE kernel"), diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index c16224b1fef3..2e358922a8d1 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -3965,6 +3965,8 @@ int cmd_script(int argc, const char **argv) "file", "vmlinux pathname"), OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name, "file", "kallsyms pathname"), + OPT_CALLBACK(0, "vdso", NULL, "vdso1[,vdso2]", "vdso pathnames", + parse_vdso_pathnames), OPT_BOOLEAN('G', "hide-call-graph", &no_callchain, "When printing symbols do not display call chain"), OPT_CALLBACK(0, "symfs", NULL, "directory", diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 1d6aef51c122..a3cce4e76eb9 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -1479,6 +1479,8 @@ int cmd_top(int argc, const char **argv) "file", "kallsyms pathname"), OPT_BOOLEAN('K', "hide_kernel_symbols", &top.hide_kernel_symbols, "hide kernel symbols"), + OPT_CALLBACK(0, "vdso", NULL, "vdso1[,vdso2]", "vdso pathnames", + parse_vdso_pathnames), OPT_CALLBACK('m', "mmap-pages", &opts->mmap_pages, "pages", "number of mmap data pages", evlist__parse_mmap_pages), OPT_INTEGER('r', "realtime", &top.realtime_prio, diff --git a/tools/perf/util/disasm.c b/tools/perf/util/disasm.c index 72aec8f61b94..442e9802a772 100644 --- a/tools/perf/util/disasm.c +++ b/tools/perf/util/disasm.c @@ -16,6 +16,7 @@ #include "debug.h" #include "disasm.h" #include "dso.h" +#include "vdso.h" #include "env.h" #include "evsel.h" #include "map.h" @@ -1134,7 +1135,7 @@ static int dso__disassemble_filename(struct dso *dso,= char *filename, size_t fil goto fallback; =20 linkname[len] =3D '\0'; - if (strstr(linkname, DSO__NAME_KALLSYMS) || + if (strstr(linkname, DSO__NAME_KALLSYMS) || strstr(linkname, DSO__NAME_VD= SO) || access(filename, R_OK)) { fallback: /* @@ -1142,7 +1143,7 @@ static int dso__disassemble_filename(struct dso *dso,= char *filename, size_t fil * cache, or is just a kallsyms file, well, lets hope that this * DSO is the same as when 'perf record' ran. */ - if (dso__kernel(dso) && dso__long_name(dso)[0] =3D=3D '/') + if ((dso__kernel(dso) || dso__is_vdso(dso)) && dso__long_name(dso)[0] = =3D=3D '/') snprintf(filename, filename_size, "%s", dso__long_name(dso)); else __symbol__join_symfs(filename, filename_size, dso__long_name(dso)); diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 9e5940b5bc59..a90c647d37e1 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -19,6 +19,7 @@ #include "build-id.h" #include "cap.h" #include "dso.h" +#include "vdso.h" #include "util.h" // lsdir() #include "debug.h" #include "event.h" @@ -44,6 +45,7 @@ =20 static int dso__load_kernel_sym(struct dso *dso, struct map *map); static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map); +static int dso__load_vdso_sym(struct dso *dso, struct map *map); static bool symbol__is_idle(const char *name); =20 int vmlinux_path__nr_entries; @@ -1833,6 +1835,12 @@ int dso__load(struct dso *dso, struct map *map) goto out; } =20 + if (dso__is_vdso(dso)) { + ret =3D dso__load_vdso_sym(dso, map); + if (ret > 0) + goto out; + } + dso__set_adjust_symbols(dso, false); =20 if (perfmap) { @@ -2017,12 +2025,14 @@ int dso__load_vmlinux(struct dso *dso, struct map *= map, dso__set_binary_type(dso, DSO_BINARY_TYPE__VMLINUX); =20 err =3D dso__load_sym(dso, map, &ss, &ss, 0); - symsrc__destroy(&ss); - if (err > 0) { dso__set_loaded(dso); pr_debug("Using %s for symbols\n", symfs_vmlinux); + + if (symsrc__has_symtab(&ss) && !dso__symsrc_filename(dso)) + dso__set_symsrc_filename(dso, strdup(symfs_vmlinux)); } + symsrc__destroy(&ss); =20 return err; } @@ -2349,6 +2359,74 @@ static int vmlinux_path__init(struct perf_env *env) return -1; } =20 +int parse_vdso_pathnames(const struct option *opt __maybe_unused, + const char *arg, int unset __maybe_unused) +{ + char *tmp, *tok, *str =3D strdup(arg); + unsigned int i =3D 0; + + for (tok =3D strtok_r(str, ",", &tmp); tok && i < ARRAY_SIZE(symbol_conf.= vdso_name); + tok =3D strtok_r(NULL, ",", &tmp)) { + symbol_conf.vdso_name[i++] =3D strdup(tok); + } + + free(str); + return 0; +} + +static int dso__load_vdso(struct dso *dso, struct map *map, + const char *vdso) +{ + int err =3D -1; + struct symsrc ss; + char symfs_vdso[PATH_MAX]; + + if (vdso[0] =3D=3D '/') + snprintf(symfs_vdso, sizeof(symfs_vdso), "%s", vdso); + else + symbol__join_symfs(symfs_vdso, vdso); + + if (symsrc__init(&ss, dso, symfs_vdso, DSO_BINARY_TYPE__SYSTEM_PATH_DSO)) + return -1; + + /* + * dso__load_sym() may copy 'dso' which will result in the copies having + * an incorrect long name unless we set it here first. + */ + dso__set_long_name(dso, vdso, false); + dso__set_binary_type(dso, DSO_BINARY_TYPE__SYSTEM_PATH_DSO); + + err =3D dso__load_sym(dso, map, &ss, &ss, 0); + if (err > 0) { + dso__set_loaded(dso); + pr_debug("Using %s for %s symbols\n", symfs_vdso, dso__short_name(dso)); + + if (symsrc__has_symtab(&ss) && !dso__symsrc_filename(dso)) + dso__set_symsrc_filename(dso, strdup(symfs_vdso)); + } + symsrc__destroy(&ss); + + return err; +} + +static int dso__load_vdso_sym(struct dso *dso, struct map *map) +{ + int ret; + + if (!dso__is_vdso(dso)) + return -1; + + for (unsigned int i =3D 0; i < ARRAY_SIZE(symbol_conf.vdso_name); i++) { + if (symbol_conf.vdso_name[i] !=3D NULL) { + ret =3D dso__load_vdso(dso, map, symbol_conf.vdso_name[i]); + if (ret > 0) + return ret; + } + } + + return -1; +} + int setup_list(struct strlist **list, const char *list_str, const char *list_name) { diff --git a/tools/perf/util/symbol_conf.h b/tools/perf/util/symbol_conf.h index c114bbceef40..108356e3c981 100644 --- a/tools/perf/util/symbol_conf.h +++ b/tools/perf/util/symbol_conf.h @@ -3,6 +3,7 @@ #define __PERF_SYMBOL_CONF 1 =20 #include +#include =20 struct strlist; struct intlist; @@ -55,6 +56,7 @@ struct symbol_conf { const char *default_guest_vmlinux_name, *default_guest_kallsyms, *default_guest_modules; + const char *vdso_name[2]; const char *guestmount; const char *dso_list_str, *comm_list_str, @@ -85,4 +87,7 @@ struct symbol_conf { =20 extern struct symbol_conf symbol_conf; =20 +int parse_vdso_pathnames(const struct option *opt __maybe_unused, + const char *arg, int unset __maybe_unused); + #endif // __PERF_SYMBOL_CONF --=20 2.34.1 From nobody Tue Dec 16 18:33:13 2025 Received: from szxga03-in.huawei.com (szxga03-in.huawei.com [45.249.212.189]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BC8672E3E4; Sat, 15 Jun 2024 09:20:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.189 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718443245; cv=none; b=NLLdqh/3FNBRZq9lH/tXIMVXWOlEueqewwPFKsSvY27D6+pqcq+8S3DUQ8cm2/fhhplRzkhvNpTbfZIjnhY6rLwUMShE/LP+D6BsvERhQkxOWnMy/WCpZRLHueabE6v3hJtpIY+C2mBI9t+MQIXHHBTuHru79jZd3OuhAsVYRY8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718443245; c=relaxed/simple; bh=I/54TK8Eh32J4IC6wgODBKMZiR0HxmWHWcUWSz/7NgU=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=rnT3nugF6xg7B2h0y6CNiczPhOOIRxW5JpAyD0TFmg/bRBhomPwj7DJYM6Bz6vEZU/oy0zXZxGNccPvkBuvyTVxT824QTbxmxZW/ntWsLAoEkPS0sniakgTz6WAMjfF2YkRcuAk9hJBPRgKaBj0PVT8rntCvTrLfv7IF+5UKF2c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=45.249.212.189 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.19.163.174]) by szxga03-in.huawei.com (SkyGuard) with ESMTP id 4W1VsH0CLGzPqv3; Sat, 15 Jun 2024 17:17:07 +0800 (CST) Received: from kwepemd100011.china.huawei.com (unknown [7.221.188.204]) by mail.maildlp.com (Postfix) with ESMTPS id 4F58014011D; Sat, 15 Jun 2024 17:20:35 +0800 (CST) Received: from M910t.huawei.com (10.110.54.157) by kwepemd100011.china.huawei.com (7.221.188.204) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1258.34; Sat, 15 Jun 2024 17:20:33 +0800 From: Changbin Du To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Nathan Chancellor CC: Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Liang, Kan" , Nick Desaulniers , Bill Wendling , Justin Stitt , , , , Changbin Du Subject: [PATCH v2 2/4] perf: disasm: use build_id_path if fallback failed Date: Sat, 15 Jun 2024 17:20:13 +0800 Message-ID: <20240615092015.1820362-3-changbin.du@huawei.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240615092015.1820362-1-changbin.du@huawei.com> References: <20240615092015.1820362-1-changbin.du@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: dggems705-chm.china.huawei.com (10.3.19.182) To kwepemd100011.china.huawei.com (7.221.188.204) Content-Type: text/plain; charset="utf-8" If we can not fallback for special dso (vmlinx and vdso), use the build_id_path found previously. To make change easy, this change first refactors the code by extracting two functions read_buildid_linkname() and fallback_filename(). Signed-off-by: Changbin Du --- tools/perf/util/disasm.c | 121 ++++++++++++++++++++++++--------------- 1 file changed, 75 insertions(+), 46 deletions(-) diff --git a/tools/perf/util/disasm.c b/tools/perf/util/disasm.c index 442e9802a772..3075daa61916 100644 --- a/tools/perf/util/disasm.c +++ b/tools/perf/util/disasm.c @@ -1092,14 +1092,72 @@ int symbol__strerror_disassemble(struct map_symbol = *ms, int errnum, char *buf, s return 0; } =20 -static int dso__disassemble_filename(struct dso *dso, char *filename, size= _t filename_size) +static int read_buildid_linkname(char *filename, char *linkname, size_t li= nkname_size) { - char linkname[PATH_MAX]; - char *build_id_filename; char *build_id_path =3D NULL; char *pos; int len; =20 + build_id_path =3D strdup(filename); + if (!build_id_path) + return ENOMEM; + + /* + * old style build-id cache has name of XX/XXXXXXX.. while + * new style has XX/XXXXXXX../{elf,kallsyms,vdso}. + * extract the build-id part of dirname in the new style only. + */ + pos =3D strrchr(build_id_path, '/'); + if (pos && strlen(pos) < SBUILD_ID_SIZE - 2) + dirname(build_id_path); + + len =3D readlink(build_id_path, linkname, linkname_size); + if (len < 0) { + free(build_id_path); + return -1; + } + + linkname[len] =3D '\0'; + free(build_id_path); + return 0; +} + +static int fallback_filename(struct dso *dso, char *filename, size_t filen= ame_size) +{ + char filepath[PATH_MAX]; + + /* + * If we don't have build-ids or the build-id file isn't in the + * cache, or is just a kallsyms file, well, lets hope that this + * DSO is the same as when 'perf record' ran. + */ + if ((dso__kernel(dso) || dso__is_vdso(dso)) && dso__long_name(dso)[0] =3D= =3D '/') + snprintf(filepath, sizeof(filepath), "%s", dso__long_name(dso)); + else + __symbol__join_symfs(filepath, sizeof(filepath), dso__long_name(dso)); + + mutex_lock(dso__lock(dso)); + if (access(filepath, R_OK) && errno =3D=3D ENOENT && dso__nsinfo(dso)) { + char *new_name =3D dso__filename_with_chroot(dso, filepath); + if (new_name) { + strlcpy(filepath, new_name, sizeof(filepath)); + free(new_name); + } + } + mutex_unlock(dso__lock(dso)); + + if (access(filepath, R_OK) && errno =3D=3D ENOENT) + return ENOENT; + + snprintf(filename, filename_size, "%s", filepath); + return 0; +} + +static int dso__disassemble_filename(struct dso *dso, char *filename, size= _t filename_size) +{ + char linkname[PATH_MAX]; + char *build_id_filename; + if (dso__symtab_type(dso) =3D=3D DSO_BINARY_TYPE__KALLSYMS && !dso__is_kcore(dso)) return SYMBOL_ANNOTATE_ERRNO__NO_VMLINUX; @@ -1111,57 +1169,28 @@ static int dso__disassemble_filename(struct dso *ds= o, char *filename, size_t fil } else { if (dso__has_build_id(dso)) return ENOMEM; - goto fallback; + return fallback_filename(dso, filename, filename_size); } =20 - build_id_path =3D strdup(filename); - if (!build_id_path) - return ENOMEM; - - /* - * old style build-id cache has name of XX/XXXXXXX.. while - * new style has XX/XXXXXXX../{elf,kallsyms,vdso}. - * extract the build-id part of dirname in the new style only. - */ - pos =3D strrchr(build_id_path, '/'); - if (pos && strlen(pos) < SBUILD_ID_SIZE - 2) - dirname(build_id_path); + if (access(filename, R_OK)) + return fallback_filename(dso, filename, filename_size); =20 - if (dso__is_kcore(dso)) + if (dso__is_kcore(dso) || dso__is_vdso(dso)) goto fallback; =20 - len =3D readlink(build_id_path, linkname, sizeof(linkname) - 1); - if (len < 0) - goto fallback; + if (!read_buildid_linkname(filename, linkname, sizeof(linkname) - 1) && + (!strstr(linkname, DSO__NAME_KALLSYMS) && !strstr(linkname, DSO__NAME= _VDSO))) { + /* not kallsysms or vdso, use build_id path found above */ + goto out; + } =20 - linkname[len] =3D '\0'; - if (strstr(linkname, DSO__NAME_KALLSYMS) || strstr(linkname, DSO__NAME_VD= SO) || - access(filename, R_OK)) { fallback: - /* - * If we don't have build-ids or the build-id file isn't in the - * cache, or is just a kallsyms file, well, lets hope that this - * DSO is the same as when 'perf record' ran. - */ - if ((dso__kernel(dso) || dso__is_vdso(dso)) && dso__long_name(dso)[0] = =3D=3D '/') - snprintf(filename, filename_size, "%s", dso__long_name(dso)); - else - __symbol__join_symfs(filename, filename_size, dso__long_name(dso)); - - mutex_lock(dso__lock(dso)); - if (access(filename, R_OK) && errno =3D=3D ENOENT && dso__nsinfo(dso)) { - char *new_name =3D dso__filename_with_chroot(dso, filename); - if (new_name) { - strlcpy(filename, new_name, filename_size); - free(new_name); - } - } - mutex_unlock(dso__lock(dso)); - } else if (dso__binary_type(dso) =3D=3D DSO_BINARY_TYPE__NOT_FOUND) { - dso__set_binary_type(dso, DSO_BINARY_TYPE__BUILD_ID_CACHE); + if (fallback_filename(dso, filename, filename_size)) { + /* if fallback failed, use build_id path found above */ +out: + if (dso__binary_type(dso) =3D=3D DSO_BINARY_TYPE__NOT_FOUND) + dso__set_binary_type(dso, DSO_BINARY_TYPE__BUILD_ID_CACHE); } - - free(build_id_path); return 0; } =20 --=20 2.34.1 From nobody Tue Dec 16 18:33:13 2025 Received: from szxga03-in.huawei.com (szxga03-in.huawei.com [45.249.212.189]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9AAA8156CF; Sat, 15 Jun 2024 09:20:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.189 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718443246; cv=none; b=nApCwdwbgX67dW2JYI/QHnMzmdQw+DHsD/uXuK1dFYUzIOfdOXnZ042ivONfZ3KXTN3qzFO5CL84cgO42FvqYNNk6gmFG4QkEKULPENR4YyvgKPuasN38/CV6wfgVdk9i29gyGxx8W62bI3cywkvvcadnxgPPBdH0X4+gCDkbdw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718443246; c=relaxed/simple; bh=YovWnQCUn5/Lz+pkf0LK7nOx1JZCjeR8Saq7TlagfeY=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=t2a/0iHYpDz0KjcrUc6OY+igWZa3Ek/NTTv/uTnwxz7kQ5d6Jgs83KO4WeuDX7ynE9mV0RJ4+Ipdja0KhQnadLnnE9ROVDvoFOdX3urtY2unGKvvbG5WqupEglp/9iAmMF6Y79FtVG065yLkmr6tFcf5W6q0pMuAiCIKny48EsU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=45.249.212.189 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.19.88.194]) by szxga03-in.huawei.com (SkyGuard) with ESMTP id 4W1VsJ2vh5zPqv5; Sat, 15 Jun 2024 17:17:08 +0800 (CST) Received: from kwepemd100011.china.huawei.com (unknown [7.221.188.204]) by mail.maildlp.com (Postfix) with ESMTPS id AD8F5140258; Sat, 15 Jun 2024 17:20:36 +0800 (CST) Received: from M910t.huawei.com (10.110.54.157) by kwepemd100011.china.huawei.com (7.221.188.204) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1258.34; Sat, 15 Jun 2024 17:20:35 +0800 From: Changbin Du To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Nathan Chancellor CC: Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Liang, Kan" , Nick Desaulniers , Bill Wendling , Justin Stitt , , , , Changbin Du Subject: [PATCH v2 3/4] perf: symbol: generalize vmlinux path searching Date: Sat, 15 Jun 2024 17:20:14 +0800 Message-ID: <20240615092015.1820362-4-changbin.du@huawei.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240615092015.1820362-1-changbin.du@huawei.com> References: <20240615092015.1820362-1-changbin.du@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: dggems705-chm.china.huawei.com (10.3.19.182) To kwepemd100011.china.huawei.com (7.221.188.204) Content-Type: text/plain; charset="utf-8" This generalizes the vmlinux path searching logic. Later we will add another instance for vdso. The search pattern is described by struct dso_filename_pattern, and the formatted paths are hold in struct dso_filename_paths. Signed-off-by: Changbin Du --- tools/perf/util/machine.c | 4 +- tools/perf/util/symbol.c | 112 +++++++++++++++++++++----------------- tools/perf/util/symbol.h | 8 ++- 3 files changed, 70 insertions(+), 54 deletions(-) diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 8477edefc299..68315520f15b 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -896,9 +896,9 @@ size_t machine__fprintf_vmlinux_path(struct machine *ma= chine, FILE *fp) printed +=3D fprintf(fp, "[0] %s\n", filename); } =20 - for (i =3D 0; i < vmlinux_path__nr_entries; ++i) { + for (i =3D 0; i < vmlinux_paths.nr_entries; ++i) { printed +=3D fprintf(fp, "[%d] %s\n", i + dso__has_build_id(kdso), - vmlinux_path[i]); + vmlinux_paths.paths[i]); } return printed; } diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index a90c647d37e1..83e5c3807a2c 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -48,8 +48,7 @@ static int dso__load_guest_kernel_sym(struct dso *dso, st= ruct map *map); static int dso__load_vdso_sym(struct dso *dso, struct map *map); static bool symbol__is_idle(const char *name); =20 -int vmlinux_path__nr_entries; -char **vmlinux_path; +struct dso_filename_paths vmlinux_paths; =20 struct symbol_conf symbol_conf =3D { .nanosecs =3D false, @@ -2043,10 +2042,10 @@ int dso__load_vmlinux_path(struct dso *dso, struct = map *map) char *filename =3D NULL; =20 pr_debug("Looking at the vmlinux_path (%d entries long)\n", - vmlinux_path__nr_entries + 1); + vmlinux_paths.nr_entries + 1); =20 - for (i =3D 0; i < vmlinux_path__nr_entries; ++i) { - err =3D dso__load_vmlinux(dso, map, vmlinux_path[i], false); + for (i =3D 0; i < vmlinux_paths.nr_entries; ++i) { + err =3D dso__load_vmlinux(dso, map, vmlinux_paths.paths[i], false); if (err > 0) goto out; } @@ -2210,7 +2209,7 @@ static int dso__load_kernel_sym(struct dso *dso, stru= ct map *map) return err; } =20 - if (!symbol_conf.ignore_vmlinux && vmlinux_path !=3D NULL) { + if (!symbol_conf.ignore_vmlinux && vmlinux_paths.paths !=3D NULL) { err =3D dso__load_vmlinux_path(dso, map); if (err > 0) return err; @@ -2285,57 +2284,55 @@ static int dso__load_guest_kernel_sym(struct dso *d= so, struct map *map) return err; } =20 -static void vmlinux_path__exit(void) -{ - while (--vmlinux_path__nr_entries >=3D 0) - zfree(&vmlinux_path[vmlinux_path__nr_entries]); - vmlinux_path__nr_entries =3D 0; - - zfree(&vmlinux_path); -} - -static const char * const vmlinux_paths[] =3D { - "vmlinux", - "/boot/vmlinux" +struct dso_filename_pattern { + const char *pattern; + /* + * 0 for matching directly, + * 1 for matching by kernel_version, + * 2 for matching by kernel_version + arch. + */ + int match_type; }; =20 -static const char * const vmlinux_paths_upd[] =3D { - "/boot/vmlinux-%s", - "/usr/lib/debug/boot/vmlinux-%s", - "/lib/modules/%s/build/vmlinux", - "/usr/lib/debug/lib/modules/%s/vmlinux", - "/usr/lib/debug/boot/vmlinux-%s.debug" +struct dso_filename_pattern vmlinux_patterns[] =3D { + {"vmlinux", 0}, + {"/boot/vmlinux", 0}, + {"/boot/vmlinux-%s", 1}, + {"/usr/lib/debug/boot/vmlinux-%s", 1}, + {"/lib/modules/%s/build/vmlinux", 1}, + {"/usr/lib/debug/lib/modules/%s/vmlinux", 1}, + {"/usr/lib/debug/boot/vmlinux-%s.debug", 1}, }; =20 -static int vmlinux_path__add(const char *new_entry) +static int dso_filename_path__add(struct dso_filename_paths *paths, const = char *new_entry) { - vmlinux_path[vmlinux_path__nr_entries] =3D strdup(new_entry); - if (vmlinux_path[vmlinux_path__nr_entries] =3D=3D NULL) + paths->paths[paths->nr_entries] =3D strdup(new_entry); + if (paths->paths[paths->nr_entries] =3D=3D NULL) return -1; - ++vmlinux_path__nr_entries; + ++paths->nr_entries; =20 return 0; } =20 -static int vmlinux_path__init(struct perf_env *env) +static void dso_filename_path__exit(struct dso_filename_paths *paths) { - struct utsname uts; - char bf[PATH_MAX]; - char *kernel_version; - unsigned int i; + while (--paths->nr_entries >=3D 0) + zfree(&paths->paths[paths->nr_entries]); + paths->nr_entries =3D 0; =20 - vmlinux_path =3D malloc(sizeof(char *) * (ARRAY_SIZE(vmlinux_paths) + - ARRAY_SIZE(vmlinux_paths_upd))); - if (vmlinux_path =3D=3D NULL) - return -1; - - for (i =3D 0; i < ARRAY_SIZE(vmlinux_paths); i++) - if (vmlinux_path__add(vmlinux_paths[i]) < 0) - goto out_fail; + zfree(&paths->paths); +} =20 - /* only try kernel version if no symfs was given */ - if (symbol_conf.symfs[0] !=3D 0) - return 0; +static int dso_filename_path__init(struct dso_filename_paths *paths, + struct dso_filename_pattern *patterns, + int nr_patterns, + struct perf_env *env) +{ + struct utsname uts; + char bf[PATH_MAX]; + const char *kernel_version; + const char *arch =3D perf_env__arch(env); + int i; =20 if (env) { kernel_version =3D env->os_release; @@ -2346,16 +2343,28 @@ static int vmlinux_path__init(struct perf_env *env) kernel_version =3D uts.release; } =20 - for (i =3D 0; i < ARRAY_SIZE(vmlinux_paths_upd); i++) { - snprintf(bf, sizeof(bf), vmlinux_paths_upd[i], kernel_version); - if (vmlinux_path__add(bf) < 0) + paths->paths =3D malloc(sizeof(char *) * nr_patterns); + if (paths->paths =3D=3D NULL) + return -1; + + for (i =3D 0; i < nr_patterns; i++) { + if (patterns[i].match_type =3D=3D 0) + strlcpy(bf, patterns[i].pattern, sizeof(bf)); + else if (symbol_conf.symfs[0] =3D=3D 0) { + /* only try kernel version if no symfs was given */ + if (patterns[i].match_type =3D=3D 1) + snprintf(bf, sizeof(bf), patterns[i].pattern, kernel_version); + else if (patterns[i].match_type =3D=3D 2) + snprintf(bf, sizeof(bf), patterns[i].pattern, kernel_version, arch); + } + if (dso_filename_path__add(paths, bf) < 0) goto out_fail; } =20 return 0; =20 out_fail: - vmlinux_path__exit(); + dso_filename_path__exit(paths); return -1; } =20 @@ -2551,8 +2560,11 @@ int symbol__init(struct perf_env *env) =20 symbol__elf_init(); =20 - if (symbol_conf.try_vmlinux_path && vmlinux_path__init(env) < 0) + if (symbol_conf.try_vmlinux_path && + dso_filename_path__init(&vmlinux_paths, vmlinux_patterns, + ARRAY_SIZE(vmlinux_patterns), env) < 0) { return -1; + } =20 if (symbol_conf.field_sep && *symbol_conf.field_sep =3D=3D '.') { pr_err("'.' is the only non valid --field-separator argument\n"); @@ -2629,7 +2641,7 @@ void symbol__exit(void) intlist__delete(symbol_conf.tid_list); intlist__delete(symbol_conf.pid_list); intlist__delete(symbol_conf.addr_list); - vmlinux_path__exit(); + dso_filename_path__exit(&vmlinux_paths); symbol_conf.sym_list =3D symbol_conf.dso_list =3D symbol_conf.comm_list = =3D NULL; symbol_conf.bt_stop_list =3D NULL; symbol_conf.initialized =3D false; diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 3fb5d146d9b1..30056884945b 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -101,8 +101,12 @@ static inline int __symbol__join_symfs(char *bf, size_= t size, const char *path) =20 #define symbol__join_symfs(bf, path) __symbol__join_symfs(bf, sizeof(bf), = path) =20 -extern int vmlinux_path__nr_entries; -extern char **vmlinux_path; +struct dso_filename_paths { + int nr_entries; + char **paths; +}; + +extern struct dso_filename_paths vmlinux_paths; =20 static inline void *symbol__priv(struct symbol *sym) { --=20 2.34.1 From nobody Tue Dec 16 18:33:13 2025 Received: from szxga06-in.huawei.com (szxga06-in.huawei.com [45.249.212.32]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A14892E62C; Sat, 15 Jun 2024 09:20:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.32 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718443247; cv=none; b=HIwAZUTOiFv8LBIiFAUDT1uFYItCKorM6/lU8XGcdYR6+x6Q6Woagjv2Su+c54lVuMYqyMbHqN+4npOtNA7tSaloMNZBqx2Ytp0ofLMLWUNzERlNKS706AyEdPfftpaXQlHVpjtRI9iS9SxNcdyTcDi+jsl9/vnovX/IublVy1o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718443247; c=relaxed/simple; bh=JrKS3CyUqPxaMZBI/KWBgU6EbAGxygnzOr3+O9jwQdo=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=MUr7m8146xzTkjswAQcfUHm/KKauYY+CxE68vEr5vZpjGNQLyL2+mrA9TVKTqQKWmw2Fn2cWK0Fot0lS/laxwwGAcHFN++f0TMxrLks4P2yw+thipziTR/MLvj6qK3K/gVVoj3vI7aOBgcEa4J9pwSEEmzG0DshscuC9Whba6DQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=45.249.212.32 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.19.162.112]) by szxga06-in.huawei.com (SkyGuard) with ESMTP id 4W1Vvj3q5Pz1xsSb; Sat, 15 Jun 2024 17:19:13 +0800 (CST) Received: from kwepemd100011.china.huawei.com (unknown [7.221.188.204]) by mail.maildlp.com (Postfix) with ESMTPS id 1D83E140381; Sat, 15 Jun 2024 17:20:38 +0800 (CST) Received: from M910t.huawei.com (10.110.54.157) by kwepemd100011.china.huawei.com (7.221.188.204) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1258.34; Sat, 15 Jun 2024 17:20:36 +0800 From: Changbin Du To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Nathan Chancellor CC: Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Liang, Kan" , Nick Desaulniers , Bill Wendling , Justin Stitt , , , , Changbin Du Subject: [PATCH v2 4/4] perf: symbol: try to seach vdso path if not given by user Date: Sat, 15 Jun 2024 17:20:15 +0800 Message-ID: <20240615092015.1820362-5-changbin.du@huawei.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240615092015.1820362-1-changbin.du@huawei.com> References: <20240615092015.1820362-1-changbin.du@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: dggems705-chm.china.huawei.com (10.3.19.182) To kwepemd100011.china.huawei.com (7.221.188.204) Content-Type: text/plain; charset="utf-8" Just like vmlinux, try to search vdso in predefined path if it's not given by user. The searched path usually has debugging info. For example, the vdso can be found in /lib/modules//build/arch/x86/entry/vdso/vdso*.so.dbg for local build on x86. Cc: Adrian Hunter Signed-off-by: Changbin Du --- tools/perf/builtin-annotate.c | 1 + tools/perf/builtin-kallsyms.c | 2 ++ tools/perf/builtin-probe.c | 2 ++ tools/perf/builtin-top.c | 2 ++ tools/perf/tests/builtin-test.c | 3 ++- tools/perf/util/symbol.c | 40 +++++++++++++++++++++++++++++++++ tools/perf/util/symbol.h | 1 + tools/perf/util/symbol_conf.h | 1 + 8 files changed, 51 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index ff466882065d..6c5019c39068 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -883,6 +883,7 @@ int cmd_annotate(int argc, const char **argv) goto out_delete; =20 symbol_conf.try_vmlinux_path =3D true; + symbol_conf.try_vdso_path =3D true; =20 ret =3D symbol__init(&annotate.session->header.env); if (ret < 0) diff --git a/tools/perf/builtin-kallsyms.c b/tools/perf/builtin-kallsyms.c index a3c2ffdc1af8..d049025a4959 100644 --- a/tools/perf/builtin-kallsyms.c +++ b/tools/perf/builtin-kallsyms.c @@ -63,6 +63,8 @@ int cmd_kallsyms(int argc, const char **argv) usage_with_options(kallsyms_usage, options); =20 symbol_conf.try_vmlinux_path =3D (symbol_conf.vmlinux_name =3D=3D NULL); + symbol_conf.try_vdso_path =3D (symbol_conf.vdso_name[0] =3D=3D NULL && + symbol_conf.vdso_name[1] =3D=3D NULL); if (symbol__init(NULL) < 0) return -1; =20 diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index 003a3bcebfdf..91770eda37c0 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c @@ -667,6 +667,8 @@ __cmd_probe(int argc, const char **argv) * Only consider the user's kernel image path if given. */ symbol_conf.try_vmlinux_path =3D (symbol_conf.vmlinux_name =3D=3D NULL); + symbol_conf.try_vdso_path =3D (symbol_conf.vdso_name[0] =3D=3D NULL && + symbol_conf.vdso_name[1] =3D=3D NULL); =20 /* * Except for --list, --del and --add, other command doesn't depend diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index a3cce4e76eb9..5a2dc7a0dbb8 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -1792,6 +1792,8 @@ int cmd_top(int argc, const char **argv) annotation_config__init(); =20 symbol_conf.try_vmlinux_path =3D (symbol_conf.vmlinux_name =3D=3D NULL); + symbol_conf.try_vdso_path =3D (symbol_conf.vdso_name[0] =3D=3D NULL && + symbol_conf.vdso_name[1] =3D=3D NULL); status =3D symbol__init(NULL); if (status < 0) goto out_delete_evlist; diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-tes= t.c index c3d84b67ca8e..176196e3c183 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -575,7 +575,8 @@ int cmd_test(int argc, const char **argv) =20 symbol_conf.priv_size =3D sizeof(int); symbol_conf.try_vmlinux_path =3D true; - + symbol_conf.try_vdso_path =3D (symbol_conf.vdso_name[0] =3D=3D NULL && + symbol_conf.vdso_name[1] =3D=3D NULL); if (symbol__init(NULL) < 0) return -1; =20 diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 83e5c3807a2c..93bdaf213d1e 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -49,11 +49,13 @@ static int dso__load_vdso_sym(struct dso *dso, struct m= ap *map); static bool symbol__is_idle(const char *name); =20 struct dso_filename_paths vmlinux_paths; +struct dso_filename_paths vdso_paths; =20 struct symbol_conf symbol_conf =3D { .nanosecs =3D false, .use_modules =3D true, .try_vmlinux_path =3D true, + .try_vdso_path =3D true, .demangle =3D true, .demangle_kernel =3D false, .cumulate_callchain =3D true, @@ -2304,6 +2306,15 @@ struct dso_filename_pattern vmlinux_patterns[] =3D { {"/usr/lib/debug/boot/vmlinux-%s.debug", 1}, }; =20 +struct dso_filename_pattern vdso_patterns[] =3D { + {"/lib/modules/%s/vdso/vdso64.so", 1}, + {"/lib/modules/%s/vdso/vdso32.so", 1}, + {"/lib/modules/%s/build/arch/%s/entry/vdso/vdso32.so.dbg", 2}, + {"/lib/modules/%s/build/arch/%s/entry/vdso/vdso64.so.dbg", 2}, + {"/lib/modules/%s/build/arch/%s/kernel/vdso/vdso.so.dbg", 2}, + {"/lib/modules/%s/build/arch/%s/vdso/vdso.so.dbg", 2}, +}; + static int dso_filename_path__add(struct dso_filename_paths *paths, const = char *new_entry) { paths->paths[paths->nr_entries] =3D strdup(new_entry); @@ -2418,6 +2429,22 @@ static int dso__load_vdso(struct dso *dso, struct ma= p *map, return err; } =20 +static int dso__load_vdso_path(struct dso *dso, struct map *map) +{ + int i, ret =3D 0; + + pr_debug("Looking at the vdso_path (%d entries long)\n", + vdso_paths.nr_entries + 1); + + for (i =3D 0; i < vdso_paths.nr_entries; ++i) { + ret =3D dso__load_vdso(dso, map, vdso_paths.paths[i]); + if (ret > 0) + return ret; + } + + return ret; +} + static int dso__load_vdso_sym(struct dso *dso, struct map *map) { int ret; @@ -2433,6 +2460,12 @@ static int dso__load_vdso_sym(struct dso *dso, struc= t map *map) } } =20 + if (vdso_paths.paths !=3D NULL) { + ret =3D dso__load_vdso_path(dso, map); + if (ret > 0) + return ret; + } + return -1; } =20 @@ -2566,6 +2599,12 @@ int symbol__init(struct perf_env *env) return -1; } =20 + if (symbol_conf.try_vdso_path && + dso_filename_path__init(&vdso_paths, vdso_patterns, + ARRAY_SIZE(vdso_patterns), env) < 0) { + return -1; + } + if (symbol_conf.field_sep && *symbol_conf.field_sep =3D=3D '.') { pr_err("'.' is the only non valid --field-separator argument\n"); return -1; @@ -2642,6 +2681,7 @@ void symbol__exit(void) intlist__delete(symbol_conf.pid_list); intlist__delete(symbol_conf.addr_list); dso_filename_path__exit(&vmlinux_paths); + dso_filename_path__exit(&vdso_paths); symbol_conf.sym_list =3D symbol_conf.dso_list =3D symbol_conf.comm_list = =3D NULL; symbol_conf.bt_stop_list =3D NULL; symbol_conf.initialized =3D false; diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 30056884945b..08c339594d4e 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -107,6 +107,7 @@ struct dso_filename_paths { }; =20 extern struct dso_filename_paths vmlinux_paths; +extern struct dso_filename_paths vdso_paths; =20 static inline void *symbol__priv(struct symbol *sym) { diff --git a/tools/perf/util/symbol_conf.h b/tools/perf/util/symbol_conf.h index 108356e3c981..58c4c4358ece 100644 --- a/tools/perf/util/symbol_conf.h +++ b/tools/perf/util/symbol_conf.h @@ -12,6 +12,7 @@ struct symbol_conf { bool nanosecs; unsigned short priv_size; bool try_vmlinux_path, + try_vdso_path, init_annotation, force, ignore_vmlinux, --=20 2.34.1