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
