env_posix.h (4894B)
1 #ifndef KIT_DRIVER_ENV_POSIX_H 2 #define KIT_DRIVER_ENV_POSIX_H 3 4 /* POSIX-shared internal surface used by the POSIX env TUs: 5 * driver/env/posix.c, posix_dbg.c 6 * driver/env/macos.c, linux.c, freebsd.c 7 * driver/env/linux_exec_hint_<arch>.c 8 * driver/env/uctx_<arch>_<os>.c 9 * 10 * Holds the bits that are common to every POSIX-shaped host but absent on 11 * Windows: the exec_dual write/runtime alias registry, the dual-mapping 12 * token bookkeeping, the single-mapping execmem helper, the POSIX-vs- 13 * kit protection translation, the per-OS hooks the shared POSIX TUs 14 * call into, ucontext marshalling, and the dbg interrupt signo. 15 * 16 * Anything that would compile on Windows belongs in env_internal.h 17 * (which this header pulls in); anything that needs <ucontext.h>, 18 * <signal.h>, or <sys/stat.h>'s POSIX `struct stat` belongs here. */ 19 20 #include <signal.h> 21 #include <sys/stat.h> 22 #include <ucontext.h> 23 24 #include "env_internal.h" 25 26 /* ---- exec_dual registry (defined in posix.c) --------------------------- 27 * Apple/Linux/FreeBSD dual-mapping execmem produces a write alias and a 28 * runtime alias at distinct virtual addresses. The dbg code_write_begin 29 * path needs to translate a runtime address into the corresponding write 30 * alias. Single-mapping reservations (write == runtime) are not registered. 31 */ 32 void exec_dual_register(void* write_base, void* runtime_base, size_t size); 33 void exec_dual_unregister(void* runtime_base); 34 int exec_dual_lookup(void* runtime_addr, size_t n, void** write_out); 35 36 /* Per-region bookkeeping carried on KitExecMemRegion.token. 37 * EXEC reservations carry a token; single-mapping ones leave token NULL. */ 38 typedef struct ExecMemToken { 39 void* write_addr; 40 void* runtime_addr; 41 size_t size; 42 } ExecMemToken; 43 44 /* Page size & single-mapping helpers (posix.c). */ 45 size_t driver_host_page_size(void); 46 KitStatus execmem_reserve_single(size_t size, KitExecMemRegion* out); 47 int kit_to_posix_prot(int prot); 48 49 /* Cache directory storage (posix.c). */ 50 extern char g_cache_dir[4096]; 51 52 /* ---- Linux x86_64 runtime-alias hint (linux_exec_hint_<arch>.c) --------- 53 * On x86_64 Linux the runtime alias is placed in the low 2 GiB so that 54 * direct call/jmp displacements from text reach without thunks. Other 55 * arches return 0/NULL and treat this as a no-op. Selected by mk/env.mk 56 * via HOST_ARCH on Linux builds. */ 57 int env_execmem_runtime_extra_flags(void); 58 void* env_execmem_low_runtime_hint(size_t size); 59 60 /* ---- ucontext marshalling (uctx_<arch>_<os>.c) --------------------------- 61 * Provided per (arch, OS) combo. The signal handler in posix_dbg.c calls 62 * these to snapshot register state into a KitUnwindFrame and write 63 * (potentially session-edited) state back. */ 64 void dbg_ucontext_to_frame(const ucontext_t* uc, KitUnwindFrame* f); 65 void dbg_frame_to_ucontext(const KitUnwindFrame* f, ucontext_t* uc); 66 67 /* ---- per-OS hooks (macos.c / linux.c / freebsd.c) ------------------------ 68 * Each hook has exactly one definition per POSIX build, selected by 69 * mk/env.mk. */ 70 71 /* Reserve `size` bytes of W^X execute memory. May install a dual mapping 72 * (Apple mach_vm_remap, Linux memfd, FreeBSD SHM_ANON) or fall back to the 73 * single-mapping path on hosts without a dual primitive. */ 74 KitStatus os_execmem_reserve_exec(size_t size, KitExecMemRegion* out); 75 76 /* dbg W^X transitions. begin yields a writable address (the alias on 77 * dual-mapped, runtime_addr with mprotect on single-mapped). end pairs 78 * with begin and may be a no-op (Apple) or mprotect-back-to-RX (Linux). 79 * Signatures match the KitDbgOs vtable shape for direct wiring. */ 80 KitStatus os_dbg_code_write_begin(void* user, void* runtime_addr, size_t n, 81 void** write_out); 82 void os_dbg_code_write_end(void* user, void* runtime_addr, size_t n); 83 84 /* Instruction-cache flush after dbg writes. Apple aarch64 calls 85 * sys_icache_invalidate; others delegate to env_flush_icache. */ 86 void os_dbg_flush_icache(void* user, void* runtime_addr, size_t n); 87 88 /* Read st_mtim/st_mtimespec into nanoseconds. Returns 0 on success. */ 89 int os_stat_mtime_ns(const struct stat* sb, int64_t* out); 90 91 /* Symbol resolver with platform name-mangling rules (Apple strips leading 92 * underscore for dlsym; ELF passes through). */ 93 void* os_dlsym(const char* name); 94 95 /* Fill the OS/object-format slots of KitTargetSpec for the host. */ 96 void os_host_target_fill(KitTargetSpec* t); 97 98 /* ---- vtable singletons wired into DriverEnv on POSIX -------------------- */ 99 extern KitExecMem g_execmem_posix; /* posix.c — page_size set in init */ 100 extern KitDbgOs g_dbg_os_posix; /* posix_dbg.c */ 101 102 /* posix_dbg.c exposes a worker-thread check for the signal handler. */ 103 int posix_dbg_caller_is_worker(void); 104 105 /* dbg interrupt signal: posix_dbg.c's signal handler treats this signo as 106 * "interrupt from the REPL" (vs SIGTRAP/SEGV/etc, which are faults). */ 107 #define DBG_INTERRUPT_SIGNO SIGUSR2 108 109 #endif