diff options
Diffstat (limited to 'tools/perf/builtin-buildid-cache.c')
-rw-r--r-- | tools/perf/builtin-buildid-cache.c | 96 |
1 files changed, 94 insertions, 2 deletions
diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c index fae8b250b2ca..c96c8fa38243 100644 --- a/tools/perf/builtin-buildid-cache.c +++ b/tools/perf/builtin-buildid-cache.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include "util/parse-options.h" | 14 | #include "util/parse-options.h" |
15 | #include "util/strlist.h" | 15 | #include "util/strlist.h" |
16 | #include "util/build-id.h" | 16 | #include "util/build-id.h" |
17 | #include "util/session.h" | ||
17 | #include "util/symbol.h" | 18 | #include "util/symbol.h" |
18 | 19 | ||
19 | static int build_id_cache__add_file(const char *filename, const char *debugdir) | 20 | static int build_id_cache__add_file(const char *filename, const char *debugdir) |
@@ -58,19 +59,89 @@ static int build_id_cache__remove_file(const char *filename, | |||
58 | return err; | 59 | return err; |
59 | } | 60 | } |
60 | 61 | ||
62 | static bool dso__missing_buildid_cache(struct dso *dso, int parm __maybe_unused) | ||
63 | { | ||
64 | char filename[PATH_MAX]; | ||
65 | u8 build_id[BUILD_ID_SIZE]; | ||
66 | |||
67 | if (dso__build_id_filename(dso, filename, sizeof(filename)) && | ||
68 | filename__read_build_id(filename, build_id, | ||
69 | sizeof(build_id)) != sizeof(build_id)) { | ||
70 | if (errno == ENOENT) | ||
71 | return false; | ||
72 | |||
73 | pr_warning("Problems with %s file, consider removing it from the cache\n", | ||
74 | filename); | ||
75 | } else if (memcmp(dso->build_id, build_id, sizeof(dso->build_id))) { | ||
76 | pr_warning("Problems with %s file, consider removing it from the cache\n", | ||
77 | filename); | ||
78 | } | ||
79 | |||
80 | return true; | ||
81 | } | ||
82 | |||
83 | static int build_id_cache__fprintf_missing(const char *filename, bool force, FILE *fp) | ||
84 | { | ||
85 | struct perf_session *session = perf_session__new(filename, O_RDONLY, | ||
86 | force, false, NULL); | ||
87 | if (session == NULL) | ||
88 | return -1; | ||
89 | |||
90 | perf_session__fprintf_dsos_buildid(session, fp, dso__missing_buildid_cache, 0); | ||
91 | perf_session__delete(session); | ||
92 | |||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | static int build_id_cache__update_file(const char *filename, | ||
97 | const char *debugdir) | ||
98 | { | ||
99 | u8 build_id[BUILD_ID_SIZE]; | ||
100 | char sbuild_id[BUILD_ID_SIZE * 2 + 1]; | ||
101 | |||
102 | int err; | ||
103 | |||
104 | if (filename__read_build_id(filename, &build_id, sizeof(build_id)) < 0) { | ||
105 | pr_debug("Couldn't read a build-id in %s\n", filename); | ||
106 | return -1; | ||
107 | } | ||
108 | |||
109 | build_id__sprintf(build_id, sizeof(build_id), sbuild_id); | ||
110 | err = build_id_cache__remove_s(sbuild_id, debugdir); | ||
111 | if (!err) { | ||
112 | err = build_id_cache__add_s(sbuild_id, debugdir, filename, | ||
113 | false, false); | ||
114 | } | ||
115 | if (verbose) | ||
116 | pr_info("Updating %s %s: %s\n", sbuild_id, filename, | ||
117 | err ? "FAIL" : "Ok"); | ||
118 | |||
119 | return err; | ||
120 | } | ||
121 | |||
61 | int cmd_buildid_cache(int argc, const char **argv, | 122 | int cmd_buildid_cache(int argc, const char **argv, |
62 | const char *prefix __maybe_unused) | 123 | const char *prefix __maybe_unused) |
63 | { | 124 | { |
64 | struct strlist *list; | 125 | struct strlist *list; |
65 | struct str_node *pos; | 126 | struct str_node *pos; |
127 | int ret = 0; | ||
128 | bool force = false; | ||
66 | char debugdir[PATH_MAX]; | 129 | char debugdir[PATH_MAX]; |
67 | char const *add_name_list_str = NULL, | 130 | char const *add_name_list_str = NULL, |
68 | *remove_name_list_str = NULL; | 131 | *remove_name_list_str = NULL, |
132 | *missing_filename = NULL, | ||
133 | *update_name_list_str = NULL; | ||
134 | |||
69 | const struct option buildid_cache_options[] = { | 135 | const struct option buildid_cache_options[] = { |
70 | OPT_STRING('a', "add", &add_name_list_str, | 136 | OPT_STRING('a', "add", &add_name_list_str, |
71 | "file list", "file(s) to add"), | 137 | "file list", "file(s) to add"), |
72 | OPT_STRING('r', "remove", &remove_name_list_str, "file list", | 138 | OPT_STRING('r', "remove", &remove_name_list_str, "file list", |
73 | "file(s) to remove"), | 139 | "file(s) to remove"), |
140 | OPT_STRING('M', "missing", &missing_filename, "file", | ||
141 | "to find missing build ids in the cache"), | ||
142 | OPT_BOOLEAN('f', "force", &force, "don't complain, do it"), | ||
143 | OPT_STRING('u', "update", &update_name_list_str, "file list", | ||
144 | "file(s) to update"), | ||
74 | OPT_INCR('v', "verbose", &verbose, "be more verbose"), | 145 | OPT_INCR('v', "verbose", &verbose, "be more verbose"), |
75 | OPT_END() | 146 | OPT_END() |
76 | }; | 147 | }; |
@@ -125,5 +196,26 @@ int cmd_buildid_cache(int argc, const char **argv, | |||
125 | } | 196 | } |
126 | } | 197 | } |
127 | 198 | ||
128 | return 0; | 199 | if (missing_filename) |
200 | ret = build_id_cache__fprintf_missing(missing_filename, force, stdout); | ||
201 | |||
202 | if (update_name_list_str) { | ||
203 | list = strlist__new(true, update_name_list_str); | ||
204 | if (list) { | ||
205 | strlist__for_each(pos, list) | ||
206 | if (build_id_cache__update_file(pos->s, debugdir)) { | ||
207 | if (errno == ENOENT) { | ||
208 | pr_debug("%s wasn't in the cache\n", | ||
209 | pos->s); | ||
210 | continue; | ||
211 | } | ||
212 | pr_warning("Couldn't update %s: %s\n", | ||
213 | pos->s, strerror(errno)); | ||
214 | } | ||
215 | |||
216 | strlist__delete(list); | ||
217 | } | ||
218 | } | ||
219 | |||
220 | return ret; | ||
129 | } | 221 | } |