[PATCH 04/10] vmcore_tasks: Add common definitions and project infrastructure

Pnina Feder <[email protected]>
Newsgroups org.infradead.lists.kexec
Message-ID <[email protected]>
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 <[email protected]>
---
 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.