aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/build-id.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/build-id.c')
-rw-r--r--tools/perf/util/build-id.c50
1 files changed, 49 insertions, 1 deletions
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index 6a7e273a514a..f1479eeef7da 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -166,6 +166,50 @@ char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size)
166 return build_id__filename(build_id_hex, bf, size); 166 return build_id__filename(build_id_hex, bf, size);
167} 167}
168 168
169bool dso__build_id_is_kmod(const struct dso *dso, char *bf, size_t size)
170{
171 char *id_name, *ch;
172 struct stat sb;
173
174 id_name = dso__build_id_filename(dso, bf, size);
175 if (!id_name)
176 goto err;
177 if (access(id_name, F_OK))
178 goto err;
179 if (lstat(id_name, &sb) == -1)
180 goto err;
181 if ((size_t)sb.st_size > size - 1)
182 goto err;
183 if (readlink(id_name, bf, size - 1) < 0)
184 goto err;
185
186 bf[sb.st_size] = '\0';
187
188 /*
189 * link should be:
190 * ../../lib/modules/4.4.0-rc4/kernel/net/ipv4/netfilter/nf_nat_ipv4.ko/a09fe3eb3147dafa4e3b31dbd6257e4d696bdc92
191 */
192 ch = strrchr(bf, '/');
193 if (!ch)
194 goto err;
195 if (ch - 3 < bf)
196 goto err;
197
198 return strncmp(".ko", ch - 3, 3) == 0;
199err:
200 /*
201 * If dso__build_id_filename work, get id_name again,
202 * because id_name points to bf and is broken.
203 */
204 if (id_name)
205 id_name = dso__build_id_filename(dso, bf, size);
206 pr_err("Invalid build id: %s\n", id_name ? :
207 dso->long_name ? :
208 dso->short_name ? :
209 "[unknown]");
210 return false;
211}
212
169#define dsos__for_each_with_build_id(pos, head) \ 213#define dsos__for_each_with_build_id(pos, head) \
170 list_for_each_entry(pos, head, node) \ 214 list_for_each_entry(pos, head, node) \
171 if (!pos->has_build_id) \ 215 if (!pos->has_build_id) \
@@ -211,6 +255,7 @@ static int machine__write_buildid_table(struct machine *machine, int fd)
211 dsos__for_each_with_build_id(pos, &machine->dsos.head) { 255 dsos__for_each_with_build_id(pos, &machine->dsos.head) {
212 const char *name; 256 const char *name;
213 size_t name_len; 257 size_t name_len;
258 bool in_kernel = false;
214 259
215 if (!pos->hit) 260 if (!pos->hit)
216 continue; 261 continue;
@@ -227,8 +272,11 @@ static int machine__write_buildid_table(struct machine *machine, int fd)
227 name_len = pos->long_name_len + 1; 272 name_len = pos->long_name_len + 1;
228 } 273 }
229 274
275 in_kernel = pos->kernel ||
276 is_kernel_module(name,
277 PERF_RECORD_MISC_CPUMODE_UNKNOWN);
230 err = write_buildid(name, name_len, pos->build_id, machine->pid, 278 err = write_buildid(name, name_len, pos->build_id, machine->pid,
231 pos->kernel ? kmisc : umisc, fd); 279 in_kernel ? kmisc : umisc, fd);
232 if (err) 280 if (err)
233 break; 281 break;
234 } 282 }