From: Tao Liu <ltao@redhat.com>
To: yamazaki-msmt@nec.com, k-hagio-ab@nec.com, kexec@lists.infradead.org
Cc: aravinda@linux.vnet.ibm.com, stephen.s.brennan@oracle.com,
Tao Liu <ltao@redhat.com>
Subject: [PATCH v5][makedumpfile 4/9] Implement kernel module's kallsyms resolving
Date: Tue, 14 Apr 2026 22:26:51 +1200 [thread overview]
Message-ID: <20260414102656.55200-5-ltao@redhat.com> (raw)
In-Reply-To: <20260414102656.55200-1-ltao@redhat.com>
With kernel's kallsyms and btf ready, we can get any kernel types and
symbol addresses. So we can iterate kernel modules' linked list, and
parse each one of kernel module's structure to get its kallsyms data.
At this time, kernel modules' kallsyms symbol defined within .init_ksyms
section will be resolved.
Suggested-by: Stephen Brennan <stephen.s.brennan@oracle.com>
Signed-off-by: Tao Liu <ltao@redhat.com>
---
kallsyms.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++++
kallsyms.h | 3 +
2 files changed, 161 insertions(+)
diff --git a/kallsyms.c b/kallsyms.c
index a198de6..f231a06 100644
--- a/kallsyms.c
+++ b/kallsyms.c
@@ -6,6 +6,7 @@
#include <string.h>
#include "makedumpfile.h"
#include "kallsyms.h"
+#include "btf_info.h"
static uint32_t *kallsyms_offsets = NULL;
static uint16_t *kallsyms_token_index = NULL;
@@ -385,6 +386,163 @@ out:
}
return ret;
}
+
+INIT_MOD_SYM(vmlinux, modules);
+
+INIT_MOD_STRUCT_MEMBER(vmlinux, list_head, next);
+INIT_MOD_STRUCT_MEMBER(vmlinux, module, list);
+INIT_MOD_STRUCT_MEMBER(vmlinux, module, name);
+INIT_MOD_STRUCT_MEMBER(vmlinux, module, core_kallsyms);
+INIT_MOD_STRUCT_MEMBER(vmlinux, mod_kallsyms, symtab);
+INIT_MOD_STRUCT_MEMBER(vmlinux, mod_kallsyms, num_symtab);
+INIT_MOD_STRUCT_MEMBER(vmlinux, mod_kallsyms, strtab);
+INIT_MOD_STRUCT_MEMBER(vmlinux, elf64_sym, st_name);
+INIT_MOD_STRUCT_MEMBER(vmlinux, elf64_sym, st_value);
+
+#define MEMBER_OFF(S, M) \
+ GET_MOD_STRUCT_MEMBER_MOFF(vmlinux, S, M) / 8
+#define GET_KERN_STRUCT_MEMBER_MSIZE(S, M) \
+ GET_MOD_STRUCT_MEMBER_MSIZE(vmlinux, S, M)
+#define KERN_STRUCT_MEMBER_EXIST(S, M) \
+ MOD_STRUCT_MEMBER_EXIST(vmlinux, S, M)
+#define GET_KERN_STRUCT_MEMBER_SSIZE(S, M) \
+ GET_MOD_STRUCT_MEMBER_SSIZE(vmlinux, S, M)
+#define GET_KERN_SYM(SYM) GET_MOD_SYM(vmlinux, SYM)
+#define KERN_SYM_EXIST(SYM) MOD_SYM_EXIST(vmlinux, SYM)
+
+uint64_t next_list(uint64_t list)
+{
+ uint64_t next = 0;
+
+ if (!readmem(VADDR, list + MEMBER_OFF(list_head, next),
+ &next, GET_KERN_STRUCT_MEMBER_MSIZE(list_head, next))) {
+ ERRMSG("Can't get next list!\n");
+ }
+ return next;
+}
+
+bool init_module_kallsyms(void)
+{
+ uint64_t modules, list, value = 0, symtab = 0, strtab = 0;
+ uint32_t st_name = 0;
+ int num_symtab, i, j;
+ struct ksym_info **p;
+ char symname[512], ch;
+ char *modname = NULL;
+ bool ret = false;
+
+ modules = GET_KERN_SYM(modules);
+ if (!KERN_SYM_EXIST(modules)) {
+ /* Not a failure if no module enabled */
+ ret = true;
+ goto out;
+ }
+
+ if (!KERN_STRUCT_MEMBER_EXIST(list_head, next) ||
+ !KERN_STRUCT_MEMBER_EXIST(module, list) ||
+ !KERN_STRUCT_MEMBER_EXIST(module, name) ||
+ !KERN_STRUCT_MEMBER_EXIST(module, core_kallsyms) ||
+ !KERN_STRUCT_MEMBER_EXIST(mod_kallsyms, symtab) ||
+ !KERN_STRUCT_MEMBER_EXIST(mod_kallsyms, num_symtab) ||
+ !KERN_STRUCT_MEMBER_EXIST(mod_kallsyms, strtab) ||
+ !KERN_STRUCT_MEMBER_EXIST(elf64_sym, st_name) ||
+ !KERN_STRUCT_MEMBER_EXIST(elf64_sym, st_value)) {
+ /* Fail when module enabled but any required types not found */
+ ERRMSG("Missing required module syms/types!\n");
+ goto out;
+ }
+
+ modname = (char *)malloc(GET_KERN_STRUCT_MEMBER_MSIZE(module, name));
+ if (!modname)
+ goto no_mem;
+
+ for (list = next_list(modules); list != modules; list = next_list(list)) {
+ if (!readmem(VADDR, list - MEMBER_OFF(module, list) +
+ MEMBER_OFF(module, name),
+ modname, GET_KERN_STRUCT_MEMBER_MSIZE(module, name))) {
+ ERRMSG("Can't get module modname!\n");
+ goto out;
+ }
+ if (!check_ksyms_require_modname(modname, NULL))
+ continue;
+ if (!readmem(VADDR, list - MEMBER_OFF(module, list) +
+ MEMBER_OFF(module, core_kallsyms) +
+ MEMBER_OFF(mod_kallsyms, num_symtab),
+ &num_symtab, GET_KERN_STRUCT_MEMBER_MSIZE(mod_kallsyms, num_symtab))) {
+ ERRMSG("Can't get module num_symtab!\n");
+ goto out;
+ }
+ if (!readmem(VADDR, list - MEMBER_OFF(module, list) +
+ MEMBER_OFF(module, core_kallsyms) +
+ MEMBER_OFF(mod_kallsyms, symtab),
+ &symtab, GET_KERN_STRUCT_MEMBER_MSIZE(mod_kallsyms, symtab))) {
+ ERRMSG("Can't get module symtab!\n");
+ goto out;
+ }
+ if (!readmem(VADDR, list - MEMBER_OFF(module, list) +
+ MEMBER_OFF(module, core_kallsyms) +
+ MEMBER_OFF(mod_kallsyms, strtab),
+ &strtab, GET_KERN_STRUCT_MEMBER_MSIZE(mod_kallsyms, strtab))) {
+ ERRMSG("Can't get module strtab!\n");
+ goto out;
+ }
+ for (i = 0; i < num_symtab; i++) {
+ j = 0;
+ if (!readmem(VADDR, symtab + i * GET_KERN_STRUCT_MEMBER_SSIZE(elf64_sym, st_value) +
+ MEMBER_OFF(elf64_sym, st_value),
+ &value, GET_KERN_STRUCT_MEMBER_MSIZE(elf64_sym, st_value))) {
+ ERRMSG("Can't get module st_value!\n");
+ goto out;
+ }
+ if (!readmem(VADDR, symtab + i * GET_KERN_STRUCT_MEMBER_SSIZE(elf64_sym, st_name) +
+ MEMBER_OFF(elf64_sym, st_name),
+ &st_name, GET_KERN_STRUCT_MEMBER_MSIZE(elf64_sym, st_name))) {
+ ERRMSG("Can't get module st_name!\n");
+ goto out;
+ }
+ do {
+ if (!readmem(VADDR, strtab + st_name + j++, &ch, 1)) {
+ ERRMSG("Can't get module symname's next char!\n");
+ goto out;
+ }
+ } while (ch != '\0');
+ if (j == 1 || j > sizeof(symname))
+ /* Skip empty or too long string */
+ continue;
+ if (!readmem(VADDR, strtab + st_name, symname, j)) {
+ ERRMSG("Can't get module symname!\n");
+ goto out;
+ }
+
+ for (j = 0; j < sr_len; j++) {
+ for (p = (struct ksym_info **)(sr[j]->start);
+ p < (struct ksym_info **)(sr[j]->stop);
+ p++) {
+ if (!strcmp((*p)->modname, modname) &&
+ !strcmp((*p)->symname, symname)) {
+ (*p)->value = value;
+ (*p)->index = i;
+ }
+ }
+ }
+ }
+ }
+ ret = true;
+ goto out;
+no_mem:
+ ERRMSG("Not enough memory!\n");
+out:
+ if (modname)
+ free(modname);
+ return ret;
+}
+
+void cleanup_kallsyms(void)
+{
+ cleanup_ksyms_section_range();
+ cleanup_ksyms_modname();
+}
+
#else /* EXTENSION */
bool read_vmcoreinfo_kallsyms(void)
diff --git a/kallsyms.h b/kallsyms.h
index 73e9839..155fa55 100644
--- a/kallsyms.h
+++ b/kallsyms.h
@@ -80,5 +80,8 @@ bool check_ksyms_require_modname(char *modname, int *total);
bool register_ksym_section(char *start, char *stop);
bool read_vmcoreinfo_kallsyms(void);
bool init_kernel_kallsyms(void);
+uint64_t next_list(uint64_t list);
+bool init_module_kallsyms(void);
+void cleanup_kallsyms(void);
#endif /* _KALLSYMS_H */
--
2.47.0
next prev parent reply other threads:[~2026-04-14 10:27 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-14 10:26 [PATCH v5][makedumpfile 0/9] btf/kallsyms based makedumpfile extension for mm page filtering Tao Liu
2026-04-14 10:26 ` [PATCH v5][makedumpfile 1/9] Reserve sections for makedumpfile and extenions Tao Liu
2026-04-14 10:26 ` [PATCH v5][makedumpfile 2/9] Implement kernel kallsyms resolving Tao Liu
2026-04-14 10:26 ` [PATCH v5][makedumpfile 3/9] Implement kernel btf resolving Tao Liu
2026-04-14 10:26 ` Tao Liu [this message]
2026-04-14 10:26 ` [PATCH v5][makedumpfile 5/9] Implement kernel module's " Tao Liu
2026-04-14 10:26 ` [PATCH v5][makedumpfile 6/9] Add makedumpfile extensions support Tao Liu
2026-04-14 10:26 ` [PATCH v5][makedumpfile 7/9] Add sample extension as an example reference Tao Liu
2026-04-14 10:26 ` [PATCH v5][makedumpfile 8/9] Doc: Add --extension option to makedumpfile manual Tao Liu
2026-04-14 10:26 ` [PATCH v5][makedumpfile 9/9] Add amdgpu mm pages filtering extension Tao Liu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260414102656.55200-5-ltao@redhat.com \
--to=ltao@redhat.com \
--cc=aravinda@linux.vnet.ibm.com \
--cc=k-hagio-ab@nec.com \
--cc=kexec@lists.infradead.org \
--cc=stephen.s.brennan@oracle.com \
--cc=yamazaki-msmt@nec.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox