[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