[PATCH RFC][makedumpfile 09/10] Enable page filtering for btf/kallsyms eppic

Tao Liu ltao at redhat.com
Tue Jun 10 02:57:42 PDT 2025


This patch mainly implements the eppic interfaces using btf/kallsyms functions.

Signed-off-by: Tao Liu <ltao at redhat.com>
---
 Makefile        |   2 +-
 erase_info.c    |  22 +++++
 extension_btf.c | 218 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 241 insertions(+), 1 deletion(-)
 create mode 100644 extension_btf.c

diff --git a/Makefile b/Makefile
index 216749f..a2d37b1 100644
--- a/Makefile
+++ b/Makefile
@@ -121,7 +121,7 @@ makedumpfile: $(SRC_BASE) $(OBJ_PART) $(OBJ_ARCH)
 	     -e "s/@VERSION@/$(VERSION)/" \
 	     $(VPATH)makedumpfile.conf.5.in > $(VPATH)makedumpfile.conf.5
 
-eppic_makedumpfile.so: extension_eppic.c eppic_maple.c
+eppic_makedumpfile.so: extension_eppic.c eppic_maple.c extension_btf.c
 	$(CC) $(CFLAGS) $(LDFLAGS) -shared -rdynamic -o $@ $^ -fPIC -leppic -ltinfo
 
 clean:
diff --git a/erase_info.c b/erase_info.c
index eeb2c3b..e0fed6b 100644
--- a/erase_info.c
+++ b/erase_info.c
@@ -2223,6 +2223,8 @@ process_eppic_file(char *name_config, bool is_btf)
 
 	if (!is_btf) {
 		eppic_init = dlsym(handle, "eppic_dwarf_init");
+	} else {
+		eppic_init = dlsym(handle, "eppic_btf_init");
 	}
 	if (!eppic_init) {
 		ERRMSG("Could not find eppic_init function\n");
@@ -2351,6 +2353,26 @@ gather_filter_info(void)
 {
 	int ret = TRUE;
 
+	if (!info->name_vmlinux && info->name_eppic_config) {
+		/* No vmlinux is present, use btf & kallsyms instead. */
+		if (init_kernel_kallsyms())
+			goto fail;
+		if (init_kernel_btf())
+			goto fail;
+		if (init_module_kallsyms())
+			goto fail;
+		if (init_module_btf())
+			goto fail;
+		ret = process_eppic_file(info->name_eppic_config, true);
+		goto out;
+fail:
+		ret = FALSE;
+out:
+		cleanup_btf();
+		cleanup_kallsyms();
+		return ret;
+	}
+
 	/*
 	 * Before processing filter config file, load the symbol data of
 	 * loaded modules from vmcore.
diff --git a/extension_btf.c b/extension_btf.c
new file mode 100644
index 0000000..c09625f
--- /dev/null
+++ b/extension_btf.c
@@ -0,0 +1,218 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "btf.h"
+#include "kallsyms.h"
+
+#include "makedumpfile.h"
+#include "extension_eppic.h"
+#include "eppic_maple.h"
+
+static def_t *
+apigetdefs(void)
+{
+	return 0;
+}
+
+static int
+apigetval(char *name, ull *val, VALUE_S *value)
+{
+	uint64_t v = cb->get_kallsyms_value_by_name(name);
+	if (!v)
+		return 0;
+	*val = v;
+	if (!value)
+		return 1;
+	eppic_setmemaddr(value, *val);
+	return 1;
+}
+
+static char *drilldown(ull, type_t *);
+static char *
+apimember(char *mname, ull idx, type_t *tm, member_t *m, ull *last_index)
+{
+	struct member_info mi = {0};
+
+	if (cb->get_type_member_by_index(idx, ++(*last_index), &mi) == false)
+		return NULL;
+	eppic_member_soffset(m, mi.bit_pos / 8);
+	eppic_member_ssize(m, mi.size);
+	eppic_member_snbits(m, mi.bits);
+	eppic_member_sfbit(m, mi.bit_pos % 8);
+	eppic_member_sname(m, mi.sname);
+
+	return drilldown(mi.uniq_id, tm);
+}
+
+static int
+apigetmem(ull iaddr, void *p, int nbytes)
+{
+	return cb->readmem(VADDR, iaddr, p, nbytes);
+}
+
+static int
+apigetctype(int ctype, char *name, type_t *tout)
+{
+	long size = 0;
+	uint32_t idx = 0;
+
+	switch (ctype) {
+	case V_STRUCT:
+		size = cb->get_type_size_by_name(name, BTF_KIND_STRUCT, &idx);
+		break;
+	case V_UNION:
+		size = cb->get_type_size_by_name(name, BTF_KIND_UNION, &idx);
+		break;
+	}
+
+	if (size <= 0 || !idx)
+		return 0;
+
+	/* populate */
+	eppic_type_settype(tout, ctype);
+	eppic_type_setsize(tout, size);
+	eppic_type_setidx(tout, (ull)idx);
+	eppic_pushref(tout, 0);
+	return 1;
+}
+
+static char *
+apigetrtype(ull idx, TYPE_S *t)
+{
+	return 0;
+}
+
+static uint8_t
+apigetuint8(void *ptr)
+{
+	uint8_t val;
+	if (!READMEM(VADDR, (unsigned long)ptr, (char *)&val, sizeof(val)))
+		return (uint8_t) -1;
+	return val;
+}
+
+static uint16_t
+apigetuint16(void *ptr)
+{
+	uint16_t val;
+	if (!READMEM(VADDR, (unsigned long)ptr, (char *)&val, sizeof(val)))
+		return (uint16_t) -1;
+	return val;
+}
+
+static uint32_t
+apigetuint32(void *ptr)
+{
+	uint32_t val;
+	if (!READMEM(VADDR, (unsigned long)ptr, (char *)&val, sizeof(val)))
+		return (uint32_t) -1;
+	return val;
+}
+
+static uint64_t
+apigetuint64(void *ptr)
+{
+	uint64_t val;
+	if (!READMEM(VADDR, (unsigned long)ptr, (char *)&val, sizeof(val)))
+		return (uint64_t) -1;
+	return val;
+}
+
+static char *
+apifindsym(char *p)
+{
+	return NULL;
+}
+
+static enum_t *
+apigetenum(char *name)
+{
+	return 0;
+}
+
+static int
+apialignment(ull idx)
+{
+	return 0;
+}
+
+static int
+apiputmem(ull iaddr, void *p, int nbytes)
+{
+	return 1;
+}
+
+static apiops btf_icops = {
+	apigetmem, 
+	apiputmem,
+	apimember,
+	apigetctype,
+	apigetrtype,
+	apialignment,
+	apigetval,
+	apigetenum,
+	apigetdefs,
+	apigetuint8,
+	apigetuint16,
+	apigetuint32,
+	apigetuint64,
+	apifindsym,
+};
+
+static char *drilldown(ull idx, type_t *t)
+{
+	struct btf_type bt, sub_bt;
+	struct name_entry *en, *sub_en;
+	int ref = 0;
+	int tmp = idx;
+
+dive_ptr:
+	en = cb->get_en_by_uniq_id(tmp, &bt);
+	if (btf_kind(bt.info) == BTF_KIND_PTR) {
+		ref++;
+		if (!bt.type)
+			eppic_parsetype("char", t, ref);
+		else {
+			cb->get_btf_type_by_type_id(en->bf, bt.type, &sub_bt, &sub_en);
+			tmp = cb->id_to_uniq_id(sub_en->id, sub_en->bf);
+			goto dive_ptr;
+		}
+	} else if (btf_kind(bt.info) == BTF_KIND_INT) {
+		eppic_parsetype("int", t, ref);
+		eppic_type_setsize(t, bt.size);
+	} else if (btf_kind(bt.info) == BTF_KIND_STRUCT) {
+		eppic_type_mkstruct(t);
+		eppic_type_setsize(t, bt.size);
+		eppic_type_setidx(t, (ull)idx);
+		if (en->name && en->name[0])
+			apigetctype(V_STRUCT, en->name, t);
+		eppic_pushref(t, ref);
+	} else if (btf_kind(bt.info) == BTF_KIND_UNION) {
+		eppic_type_mkunion(t);
+		eppic_type_setsize(t, bt.size);
+		eppic_type_setidx(t, (ull)idx);
+		if (en->name && en->name[0])
+			apigetctype(V_UNION, en->name, t);
+		eppic_pushref(t, ref);
+	} else if (btf_kind(bt.info) == BTF_KIND_ENUM) {
+		eppic_type_mkenum(t);
+		eppic_type_setsize(t, bt.size);
+		eppic_type_setidx(t, (ull)idx);
+		if (en->name && en->name[0])
+			apigetctype(V_UNION, en->name, t);
+		eppic_pushref(t, ref);
+	} else if (btf_kind(bt.info) == BTF_KIND_CONST) {
+		cb->get_btf_type_by_type_id(en->bf, bt.type, &sub_bt, &sub_en);
+		tmp = cb->id_to_uniq_id(sub_en->id, sub_en->bf);
+		goto dive_ptr;		
+	} else {
+		printf("%s: Drilldown unsupported btf kind %d\n",
+			en->name, btf_kind(bt.info));
+	}
+	return eppic_strdup("");
+}
+
+int eppic_btf_init(void *fun_ptr)
+{
+	return eppic_init(fun_ptr, &btf_icops, true);
+}
\ No newline at end of file
-- 
2.47.0




More information about the kexec mailing list