@@ -777,7 +777,7 @@ static int do_show(int argc, char **argv)
__u32 *lens;
__u32 i;
if (info->nr_jited_ksyms) {
- kernel_syms_load(&dd);
+ kernel_syms_load(&dd, NULL, 0);
ksyms = u64_to_ptr(info->jited_ksyms);
}
@@ -841,7 +841,7 @@ static int do_show(int argc, char **argv)
goto exit_free;
}
} else {
- kernel_syms_load(&dd);
+ kernel_syms_load(&dd, NULL, 0);
dd.nr_jited_ksyms = info->nr_jited_ksyms;
dd.jited_ksyms = u64_to_ptr(info->jited_ksyms);
dd.btf = btf;
@@ -1927,7 +1927,7 @@ static int do_loader(int argc, char **argv)
if (verifier_logs) {
struct dump_data dd = {};
- kernel_syms_load(&dd);
+ kernel_syms_load(&dd, NULL, 0);
dump_xlated_plain(&dd, (void *)gen.insns, gen.insns_sz, false, false);
kernel_syms_destroy(&dd);
}
@@ -23,46 +23,88 @@ static int kernel_syms_cmp(const void *sym_a, const void *sym_b)
((struct kernel_sym *)sym_b)->address;
}
-void kernel_syms_load(struct dump_data *dd)
+static int cmp_u64(const void *A, const void *B)
+{
+ const __u64 *a = A, *b = B;
+
+ return *a - *b;
+}
+
+/* Set @filter_addrs to filter out the interested addresses.
+ * The addresses in @filter_addrs must be in /proc/kallsyms.
+ * The number of addresses in @filter_addrs must be @filter_cnt.
+ * Each address in @filter_addrs must be unique.
+ *
+ * Return 0 on success, -1 on invalid filter, 1 on no symbols.
+ */
+int kernel_syms_load(struct dump_data *dd, const __u64 *filter_addrs,
+ __u32 filter_cnt)
{
struct kernel_sym *sym;
char buff[256];
- void *tmp, *address;
+ void *tmp = NULL, *address;
+ bool realloc = true;
+ __u32 i = 0;
FILE *fp;
fp = fopen("/proc/kallsyms", "r");
if (!fp)
- return;
+ return 1;
+ if (filter_addrs && filter_cnt)
+ qsort((void *)filter_addrs, filter_cnt, sizeof(__u64),
+ cmp_u64);
while (fgets(buff, sizeof(buff), fp)) {
- tmp = libbpf_reallocarray(dd->sym_mapping, dd->sym_count + 1,
- sizeof(*dd->sym_mapping));
- if (!tmp) {
+ if (realloc) {
+ tmp = libbpf_reallocarray(dd->sym_mapping,
+ dd->sym_count + 1,
+ sizeof(*dd->sym_mapping));
+ if (!tmp) {
out:
- free(dd->sym_mapping);
- dd->sym_mapping = NULL;
- fclose(fp);
- return;
+ free(dd->sym_mapping);
+ dd->sym_mapping = NULL;
+ fclose(fp);
+ return 1;
+ }
+ dd->sym_mapping = tmp;
+ sym = &dd->sym_mapping[dd->sym_count];
}
- dd->sym_mapping = tmp;
- sym = &dd->sym_mapping[dd->sym_count];
if (sscanf(buff, "%p %*c %s", &address, sym->name) != 2)
continue;
- sym->address = (unsigned long)address;
if (!strcmp(sym->name, "__bpf_call_base")) {
- dd->address_call_base = sym->address;
+ dd->address_call_base = (unsigned long)address;
/* sysctl kernel.kptr_restrict was set */
- if (!sym->address)
+ if (!address)
goto out;
}
+ if (filter_addrs && filter_cnt) {
+ if ((__u64)address != filter_addrs[i]) {
+ if (realloc)
+ realloc = false;
+ continue;
+ }
+ if (i++ == filter_cnt)
+ break;
+ if (!realloc)
+ realloc = true;
+ }
+ sym->address = (unsigned long)address;
if (sym->address)
dd->sym_count++;
}
fclose(fp);
+ /* invalid filter address found */
+ if (filter_addrs && filter_cnt && i != filter_cnt) {
+ free(dd->sym_mapping);
+ dd->sym_mapping = NULL;
+ return -1;
+ }
+
qsort(dd->sym_mapping, dd->sym_count,
sizeof(*dd->sym_mapping), kernel_syms_cmp);
+ return 0;
}
void kernel_syms_destroy(struct dump_data *dd)
@@ -26,7 +26,8 @@ struct dump_data {
char scratch_buff[SYM_MAX_NAME + 8];
};
-void kernel_syms_load(struct dump_data *dd);
+int kernel_syms_load(struct dump_data *dd, const __u64 *filter_addrs,
+ __u32 filter_cnt);
void kernel_syms_destroy(struct dump_data *dd);
struct kernel_sym *kernel_syms_search(struct dump_data *dd, unsigned long key);
void dump_xlated_json(struct dump_data *dd, void *buf, unsigned int len,
To enhance the functionality of kernel_syms_load(), an extension is proposed to allow filtering of specific addresses of interest. The extension will ensure that the addresses being filtered are present in the /proc/kallsyms file, which serves as a reference for valid kernel symbols. If an address is found to be invalid or not present in /proc/kallsyms, the function will return a value of -1, indicating an error condition. Signed-off-by: Yafang Shao <laoar.shao@gmail.com> --- tools/bpf/bpftool/prog.c | 6 ++-- tools/bpf/bpftool/xlated_dumper.c | 72 +++++++++++++++++++++++++++++++-------- tools/bpf/bpftool/xlated_dumper.h | 3 +- 3 files changed, 62 insertions(+), 19 deletions(-)