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


Reply via email to