This patch mainly implements the eppic interfaces using btf/kallsyms functions.
Signed-off-by: Tao Liu <ltao(a)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