[PATCH v2][makedumpfile 12/14] Enable page filtering for btf/kallsyms eppic
Tao Liu
ltao at redhat.com
Mon Oct 20 15:24:08 PDT 2025
This patch mainly replicate extension_eppic.c, implements the eppic interfaces
using btf/kallsyms functions rather than dwarf functions.
Signed-off-by: Tao Liu <ltao at redhat.com>
---
Makefile | 4 +-
erase_info.c | 22 ++++
extension_btf.c | 258 ++++++++++++++++++++++++++++++++++++++++++++++
extension_eppic.c | 2 +-
4 files changed, 283 insertions(+), 3 deletions(-)
create mode 100644 extension_btf.c
diff --git a/Makefile b/Makefile
index fbc9f5b..8201bde 100644
--- a/Makefile
+++ b/Makefile
@@ -121,8 +121,8 @@ 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
- $(CC) $(CFLAGS) $(LDFLAGS) -shared -rdynamic -o $@ extension_eppic.c -fPIC -leppic -ltinfo
+eppic_makedumpfile.so: extension_eppic.c extension_btf.c
+ $(CC) $(CFLAGS) $(LDFLAGS) -shared -rdynamic -o $@ $^ -fPIC -leppic -ltinfo
clean:
rm -f $(OBJ) $(OBJ_PART) $(OBJ_ARCH) makedumpfile makedumpfile.8 makedumpfile.conf.5
diff --git a/erase_info.c b/erase_info.c
index 7c637c2..786f603 100644
--- a/erase_info.c
+++ b/erase_info.c
@@ -2220,6 +2220,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");
@@ -2348,6 +2350,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..aee2ad8
--- /dev/null
+++ b/extension_btf.c
@@ -0,0 +1,258 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "btf.h"
+#include "kallsyms.h"
+
+#include "makedumpfile.h"
+#include "extension_eppic.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,
+};
+
+void
+eppic_setupidx(TYPE_S *, int, int, int *);
+
+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;
+ /* Following 2 are for array */
+ struct btf_array ba;
+ int nidx = 0, *idxlst = NULL;
+
+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 if (btf_kind(bt.info) == BTF_KIND_TYPE_TAG) {
+ if (bt.type != 0) {
+ 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: kind %d pointing to type 0\n", en->name,
+ btf_kind(bt.info));
+ if (ref)
+ /* Finish up with pointer type */
+ eppic_parsetype("char", t, ref);
+ }
+ } else if (btf_kind(bt.info) == BTF_KIND_ARRAY) {
+ if (!idxlst) {
+ idxlst = eppic_calloc(sizeof(int) * (MAXIDX + 1));
+ if (!idxlst) {
+ printf("Out of memory for eppic array\n");
+ goto out;
+ }
+ }
+ cb->read_file_at_offset(en->bf->file_name,
+ en->btf_type_offset + en->bf->types_data_offset + sizeof(bt),
+ sizeof(struct btf_array), &ba);
+ idxlst[nidx++] = ba.nelems;
+ /* Dive and resolve array's elements */
+ cb->get_btf_type_by_type_id(en->bf, ba.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));
+ }
+
+ if (nidx > 0) {
+ /* Finish up array */
+ eppic_setupidx(t, ref, nidx, idxlst);
+ eppic_pushref(t, ref + 1);
+ }
+out:
+ return eppic_strdup("");
+}
+
+int eppic_btf_init(void *fun_ptr)
+{
+ return eppic_init(fun_ptr, &btf_icops, true);
+}
\ No newline at end of file
diff --git a/extension_eppic.c b/extension_eppic.c
index 00d19fa..17bed17 100644
--- a/extension_eppic.c
+++ b/extension_eppic.c
@@ -83,7 +83,7 @@ reg_callback(char *name, int load)
*
* set idx value to actual array indexes from specified size
*/
-static void
+void
eppic_setupidx(TYPE_S *t, int ref, int nidx, int *idxlst)
{
/* put the idxlst in index size format */
--
2.47.0
More information about the kexec
mailing list