|
@@ -166,6 +166,50 @@ char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size)
|
|
|
return build_id__filename(build_id_hex, bf, size);
|
|
return build_id__filename(build_id_hex, bf, size);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+bool dso__build_id_is_kmod(const struct dso *dso, char *bf, size_t size)
|
|
|
|
|
+{
|
|
|
|
|
+ char *id_name, *ch;
|
|
|
|
|
+ struct stat sb;
|
|
|
|
|
+
|
|
|
|
|
+ id_name = dso__build_id_filename(dso, bf, size);
|
|
|
|
|
+ if (!id_name)
|
|
|
|
|
+ goto err;
|
|
|
|
|
+ if (access(id_name, F_OK))
|
|
|
|
|
+ goto err;
|
|
|
|
|
+ if (lstat(id_name, &sb) == -1)
|
|
|
|
|
+ goto err;
|
|
|
|
|
+ if ((size_t)sb.st_size > size - 1)
|
|
|
|
|
+ goto err;
|
|
|
|
|
+ if (readlink(id_name, bf, size - 1) < 0)
|
|
|
|
|
+ goto err;
|
|
|
|
|
+
|
|
|
|
|
+ bf[sb.st_size] = '\0';
|
|
|
|
|
+
|
|
|
|
|
+ /*
|
|
|
|
|
+ * link should be:
|
|
|
|
|
+ * ../../lib/modules/4.4.0-rc4/kernel/net/ipv4/netfilter/nf_nat_ipv4.ko/a09fe3eb3147dafa4e3b31dbd6257e4d696bdc92
|
|
|
|
|
+ */
|
|
|
|
|
+ ch = strrchr(bf, '/');
|
|
|
|
|
+ if (!ch)
|
|
|
|
|
+ goto err;
|
|
|
|
|
+ if (ch - 3 < bf)
|
|
|
|
|
+ goto err;
|
|
|
|
|
+
|
|
|
|
|
+ return strncmp(".ko", ch - 3, 3) == 0;
|
|
|
|
|
+err:
|
|
|
|
|
+ /*
|
|
|
|
|
+ * If dso__build_id_filename work, get id_name again,
|
|
|
|
|
+ * because id_name points to bf and is broken.
|
|
|
|
|
+ */
|
|
|
|
|
+ if (id_name)
|
|
|
|
|
+ id_name = dso__build_id_filename(dso, bf, size);
|
|
|
|
|
+ pr_err("Invalid build id: %s\n", id_name ? :
|
|
|
|
|
+ dso->long_name ? :
|
|
|
|
|
+ dso->short_name ? :
|
|
|
|
|
+ "[unknown]");
|
|
|
|
|
+ return false;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
#define dsos__for_each_with_build_id(pos, head) \
|
|
#define dsos__for_each_with_build_id(pos, head) \
|
|
|
list_for_each_entry(pos, head, node) \
|
|
list_for_each_entry(pos, head, node) \
|
|
|
if (!pos->has_build_id) \
|
|
if (!pos->has_build_id) \
|