[PATCH 04/10] vmcore_tasks: Add common definitions and project infrastructure
Pnina Feder
pnina.feder at mobileye.com
Mon Jun 22 13:54:42 PDT 2026
Add the shared header and build system for the vmcore-tasks tool:
- vmcore_tasks_defs.h: Core data structures for task extraction
(task_data, thread_data, vma_metadata, stackframe, system_minicore),
architecture dispatch via compile-time RISCV64/MIPS64 selection,
unwind_arch_ops callbacks for arch-specific instruction decode,
and VM flag constants.
- Makefile: Standalone build system with auto-detection of target
architecture from cross-compiler triplet, or explicit TARGET=
selection. Supports out-of-tree builds via O= parameter.
Compiles sources from both vmcore_tasks/ and util_lib/.
Signed-off-by: Pnina Feder <pnina.feder at mobileye.com>
---
vmcore_tasks/Makefile | 103 +++++++++++++++++++++++++
vmcore_tasks/vmcore_tasks_defs.h | 124 +++++++++++++++++++++++++++++++
2 files changed, 227 insertions(+)
create mode 100644 vmcore_tasks/Makefile
create mode 100644 vmcore_tasks/vmcore_tasks_defs.h
diff --git a/vmcore_tasks/Makefile b/vmcore_tasks/Makefile
new file mode 100644
index 00000000..0219c6d4
--- /dev/null
+++ b/vmcore_tasks/Makefile
@@ -0,0 +1,103 @@
+# Simple Makefile to build vmcore-tasks: task lister similar to vmcore-dmesg
+# Produces binary: vmcore-tasks
+
+CC ?= gcc
+CFLAGS ?= -O2 -g
+CFLAGS += -Wall -Wextra
+CFLAGS += -I$(SRC_DIR) -I$(SRC_DIR)/../util_lib/include
+
+# Support out-of-tree builds via O= parameter
+# Usage: make O=/path/to/build/dir
+SRC_DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
+ifdef O
+ BUILD_DIR := $(O)
+else
+ BUILD_DIR := $(SRC_DIR)
+endif
+
+# Auto-detect target architecture from compiler, unless TARGET is specified
+# Usage: make # auto-detect from gcc
+# make TARGET=RISCV64 # force specific target
+# make TARGET=MIPS64 # force specific target
+
+ifndef TARGET
+ # Get compiler's target triplet (e.g., riscv64-unknown-linux-gnu, x86_64-linux-gnu)
+ CC_TARGET := $(shell $(CC) -dumpmachine)
+
+ ifneq (,$(findstring riscv64,$(CC_TARGET)))
+ TARGET := RISCV64
+ else ifneq (,$(findstring riscv32,$(CC_TARGET)))
+ TARGET := RISCV32
+ else ifneq (,$(findstring mips,$(CC_TARGET)))
+ TARGET := MIPS64
+ else ifneq (,$(findstring mips32,$(CC_TARGET)))
+ TARGET := MIPS32
+ else ifneq (,$(findstring aarch64,$(CC_TARGET)))
+ TARGET := ARM64
+ else ifneq (,$(findstring x86_64,$(CC_TARGET)))
+ TARGET := X86_64
+ else
+ $(error Unsupported architecture: $(CC_TARGET). Use TARGET=<arch> to specify.)
+ endif
+endif
+
+# Add architecture define
+CFLAGS += -D$(TARGET)
+
+# Arch-specific sources based on target
+ifeq ($(TARGET),RISCV64)
+ CFLAGS += -I$(SRC_DIR)/arch/riscv64
+ ARCH_SRC = $(wildcard $(SRC_DIR)/arch/riscv64/*.c)
+else ifeq ($(TARGET),MIPS64)
+ CFLAGS += -I$(SRC_DIR)/arch/mips64
+ # MIPS ABI/endian flags only when using a MIPS cross-compiler
+ ifneq (,$(findstring mips,$(shell $(CC) -dumpmachine)))
+ CFLAGS += -EL -mabi=64 -march=mips64r6 -fPIC
+ LDFLAGS += -static
+ endif
+ ARCH_SRC = $(wildcard $(SRC_DIR)/arch/mips64/*.c)
+else
+ ARCH_SRC =
+endif
+
+$(info Building for target: $(TARGET) (compiler: $(CC)))
+
+# Sources (relative to SRC_DIR)
+MAIN_SRC = $(wildcard $(SRC_DIR)/*.c)
+UTIL_SRC = $(addprefix $(SRC_DIR)/../,util_lib/elf_info.c util_lib/maple_tree.c util_lib/memory.c util_lib/vmcore_info.c)
+
+# Headers (for dependency tracking)
+HEADERS = $(wildcard $(SRC_DIR)/*.h) $(wildcard $(SRC_DIR)/../util_lib/include/*.h) $(wildcard $(SRC_DIR)/arch/$(TARGET)/*.h)
+
+# Objects (placed in BUILD_DIR, mirroring source structure)
+MAIN_OBJ = $(patsubst $(SRC_DIR)/%.c,$(BUILD_DIR)/%.o,$(MAIN_SRC))
+ARCH_OBJ = $(patsubst $(SRC_DIR)/%.c,$(BUILD_DIR)/%.o,$(ARCH_SRC))
+UTIL_OBJ = $(patsubst $(SRC_DIR)/../%.c,$(BUILD_DIR)/%.o,$(UTIL_SRC))
+ALL_OBJ = $(MAIN_OBJ) $(ARCH_OBJ) $(UTIL_OBJ)
+
+BIN = $(BUILD_DIR)/vmcore-tasks
+
+.PHONY: all clean
+
+all: $(BIN)
+
+$(BIN): $(ALL_OBJ)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
+
+# All objects depend on all headers
+$(ALL_OBJ) : $(HEADERS)
+
+.SECONDEXPANSION:
+
+# Create build subdirectories as needed
+$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c | $$(dir $$@)
+ $(CC) $(CFLAGS) -c $< -o $@
+
+$(BUILD_DIR)/%.o: $(SRC_DIR)/../%.c | $$(dir $$@)
+ $(CC) $(CFLAGS) -c $< -o $@
+
+%/:
+ mkdir -p $@
+
+clean:
+ rm -f $(ALL_OBJ) $(BIN)
diff --git a/vmcore_tasks/vmcore_tasks_defs.h b/vmcore_tasks/vmcore_tasks_defs.h
new file mode 100644
index 00000000..cfc5864d
--- /dev/null
+++ b/vmcore_tasks/vmcore_tasks_defs.h
@@ -0,0 +1,124 @@
+#ifndef VMCORE_TASKS_DEFS_H
+#define VMCORE_TASKS_DEFS_H
+
+#include <stdbool.h>
+#include "vmcore_tasks_util.h"
+
+#ifdef MIPS64
+#include "arch/mips64/mips64_defs.h"
+#elif defined(RISCV64)
+#include "arch/riscv64/riscv64_defs.h"
+#else
+#error "No architecture defined."
+#endif
+
+#define CODE_BUF_SIZE 4096
+#define MAX_TASK_NAME 16
+#define MAX_MAPPING_FILENAME 48
+#define MAX_MAPPING_TYPE 16
+#define BACKTRACE_DEPTH 30
+
+/* VM flags from linux/mm.h */
+#define VM_READ 0x00000001
+#define VM_WRITE 0x00000002
+#define VM_EXEC 0x00000004
+
+
+struct stackframe {
+ unsigned long pc;
+ unsigned long sp;
+ unsigned long ra;
+};
+
+struct signal_unwind_layout {
+ const char *rt_sigframe_uc_key;
+ const char *ucontext_mcontext_key;
+ const char *sigcontext_regs_key;
+ const char *sigcontext_pc_key;
+ unsigned int reg_width;
+ int sp_reg_index;
+ int ra_reg_index;
+ int pc_reg_index;
+ int pc_reg_alt_index;
+};
+
+struct backtrace_entries {
+ unsigned long abs_addr;
+ unsigned long vm_start;
+ unsigned long vm_end;
+ char filename[MAX_MAPPING_FILENAME];
+};
+
+struct vma_metadata {
+ unsigned long start;
+ unsigned long end;
+ unsigned long flags;
+ unsigned long file;
+ char filename[MAX_MAPPING_FILENAME];
+ char type[MAX_MAPPING_TYPE];
+};
+
+struct task_vmas {
+ int vma_count;
+ struct vma_metadata *vma_meta;
+};
+
+struct thread_data {
+ char comm[MAX_TASK_NAME];
+ pid_t tid;
+ int state;
+ int state_idx;
+ uint32_t flags;
+ struct pt_regs regs;
+ struct backtrace_entries bt_entry[BACKTRACE_DEPTH];
+};
+
+struct task_data{
+ char comm[MAX_TASK_NAME];
+ pid_t pid;
+ uint8_t is_user_task;
+ uint64_t mm_pgd;
+ struct task_vmas vmas;
+ int num_threads;
+ uint32_t flags;
+ int state;
+ int state_idx;
+ struct thread_data *threads;
+};
+
+struct system_minicore {
+ int task_count;
+ struct task_data *tasks;
+};
+
+struct unwind_arch_ops {
+ unsigned int insn_size;
+ unsigned int ra_width;
+ bool (*is_sp_move_ins)(uint32_t insn, int *stack_adj);
+ bool (*is_ra_save_ins)(uint32_t insn, unsigned long *ra_offset);
+ bool (*is_end_of_backtrace)(uint32_t insn); /* NULL = not used */
+ int (*post_unwind_fixup)(struct stackframe *frame, unsigned int max_check); /* NULL = not used */
+ bool (*likely_signal_pc)(uint64_t pc);
+ const struct signal_unwind_layout *signal_layout;
+};
+
+int unwind_user_frame(struct stackframe *old_frame,
+ const unsigned int max_check);
+
+struct arch_deps {
+ bool (*vtop)(uint64_t, uint64_t, uint64_t *);
+ struct unwind_arch_ops unwind_ops;
+};
+extern struct arch_deps arch;
+
+#ifdef MIPS64
+void mips64_init();
+#define arch_init() mips64_init()
+#elif defined(RISCV64)
+void riscv64_init();
+#define arch_init() riscv64_init()
+#else
+#error "No architecture defined."
+#endif
+
+#endif /* VMCORE_TASKS_DEFS_H */
\ No newline at end of file
--
2.43.0
More information about the kexec
mailing list