feat: exhaustive STUB instrumentation - 241 panic sites across VMM/kernel + whitelist alignment

- VMM cluster: XJ3-E/LIN-E/VMM-E/VMX-E/EPT-E/IPC-E/VVB-E (124 sites)

- kernel cluster: TST-E/MM-E/UTRW-E/LAPIC-E/IDT-E/SAS-E/PRB-E/NETST-E/DKM-E (117 sites)

- whitelist fixes: vmm_init env probes E10-E14 fallback, disk_log read-only block path, DSL-E05 non-FAT32 device 0 probe

- QEMU smoke: wizard -> USER.CONF -> login -> desktop ready, zero spurious panic
This commit is contained in:
Linehu
2026-10-03 21:26:04 +08:00
parent 506d1b18c6
commit 174af71b39
62 changed files with 667 additions and 36 deletions
+13
View File
@@ -18,6 +18,7 @@
#include <utsm/log.h>
#include <utsm/types.h>
#include <utsm/pe.h>
#include <utsm/panic.h>
/* ---- PE 导出目录结构(packed,与 pe_loader.h 风格一致) ---- */
typedef struct __attribute__((packed)) {
@@ -263,6 +264,8 @@ static u64 resolve_export_by_name(u64 image_base, u32 export_dir_rva,
static u64 resolve_forwarded_export(u64 image_base, u32 func_rva, int depth) {
if (depth > PE_DLL_FWD_DEPTH_MAX) {
log_warn("[PE] forwarded export chain too deep");
panic_full("PE-E20 FORWARD CHAIN TOO DEEP",
"resolve_forwarded_export: forwarded export chain too deep", 0);
return 0;
}
const char *fwd = (const char *)(image_base + func_rva);
@@ -280,6 +283,8 @@ static u64 resolve_forwarded_export(u64 image_base, u32 func_rva, int depth) {
while (buf[dot] && buf[dot] != '.') dot++;
if (buf[dot] != '.' || dot == 0 || buf[dot + 1] == 0) {
log_warn("[PE] malformed forwarder string");
panic_full("PE-E21 MALFORMED FORWARDER STRING",
"resolve_forwarded_export: malformed forwarder string", 0);
return 0;
}
buf[dot] = 0;
@@ -318,6 +323,8 @@ static u64 resolve_forwarded_export(u64 image_base, u32 func_rva, int depth) {
u64 addr = resolve_export_by_ordinal(base, g_dll_cache[idx].export_dir_rva, ord);
if (addr == 0) {
log_warn("[PE] ordinal forward target not found");
panic_full("PE-E22 ORDINAL FORWARD NOT FOUND",
"resolve_forwarded_export: ordinal forward target missing", 0);
}
return addr;
}
@@ -368,6 +375,8 @@ int pe_dll_load(const char *dll_name, u64 *out_base) {
idx = dll_cache_alloc();
if (idx < 0) {
log_warn("[PE] DLL cache full, cannot load");
panic_full("PE-E23 DLL CACHE FULL",
"pe_dll_load: DLL cache exhausted", 0);
if (out_base) *out_base = 0;
return -2;
}
@@ -402,6 +411,8 @@ int pe_dll_load(const char *dll_name, u64 *out_base) {
if (pe_load_image(file_copy, file_size, &info) != 0) {
log_warn("[PE] DLL load failed: pe_load_image error");
log_info(dll_name);
panic_full("PE-E24 DLL IMAGE LOAD FAILED",
"pe_dll_load: pe_load_image failed for DLL", 0);
entry->state = DLL_STATE_NONE;
if (out_base) *out_base = 0;
return -5;
@@ -436,6 +447,8 @@ int pe_dll_load(const char *dll_name, u64 *out_base) {
log_info("[PE] DllMain deferred");
} else {
log_warn("[PE] DllMain pending queue full, skipped");
panic_full("PE-E25 DLLMAIN PENDING QUEUE FULL",
"pe_dll_load: DllMain pending queue full", 0);
}
} else {
typedef int (__attribute__((ms_abi)) *dllmain_fn)(u64, u32, u64);
+2 -1
View File
@@ -1,6 +1,6 @@
pe/pe_dll_manager.o: pe\pe_dll_manager.c pe\pe_dll_manager.h \
include\utsm\types.h pe\pe_loader.h include\utsm\pe.h pe\pe_shim.h \
include\utsm\arena.h include\utsm\log.h
include\utsm\arena.h include\utsm\log.h include\utsm\panic.h
pe\pe_dll_manager.h:
include\utsm\types.h:
pe\pe_loader.h:
@@ -8,3 +8,4 @@ include\utsm\pe.h:
pe\pe_shim.h:
include\utsm\arena.h:
include\utsm\log.h:
include\utsm\panic.h:
+13
View File
@@ -21,6 +21,7 @@
#include <utsm/idt.h>
#include <utsm/log.h>
#include <utsm/types.h>
#include <utsm/panic.h>
/* 32位 PE 用的栈与堆 */
#define PE32_STACK_SIZE (64 * 1024) /* 64KB 栈 */
@@ -293,6 +294,8 @@ int pe_service_run(const void *pe_data, u64 size, const char *cmdline, u64 *exit
if (rc != 0) {
pe_dll_defer_dllmain(0);
log_error("[PE] PE32+ load failed");
panic_full("PE-E10 PE32+ LOAD FAILED",
"pe_service_run: PE32+ image load failed", 0);
return -5;
}
log_info("[PE] running PE32+ natively");
@@ -307,6 +310,8 @@ int pe_service_run(const void *pe_data, u64 size, const char *cmdline, u64 *exit
u8 *pe_stack = (u8 *)kmem_alloc_aligned(PE_STACK_BYTES, 4096);
if (!pe_stack) {
log_error("[PE] stack alloc failed");
panic_full("PE-E11 PE STACK ALLOC FAILED",
"pe_service_run: 1MB PE stack allocation failed", 0);
return -9;
}
u64 stack_top = (u64)pe_stack + PE_STACK_BYTES; /* 4096 对齐 -> 16 对齐 */
@@ -339,6 +344,8 @@ int pe_service_run(const void *pe_data, u64 size, const char *cmdline, u64 *exit
if (rc != 0) {
log_error("[PE] PE32 interp load failed");
log_hex64("[PE] rc=", (u64)(i64)rc);
panic_full("PE-E12 PE32 INTERP LOAD FAILED",
"pe_service_run: PE32 interpreter load failed", 0);
return -6;
}
log_info("[PE] running PE32 via x86emu32");
@@ -351,6 +358,8 @@ int pe_service_run(const void *pe_data, u64 size, const char *cmdline, u64 *exit
img.iat, img.iat_count, stack_top);
if (irc != 0) {
log_error("[PE32] emu init failed");
panic_full("PE-E13 EMU INIT FAILED",
"pe_service_run: x86emu32 init failed", 0);
return -7;
}
emu.eip = img.entry_point;
@@ -367,12 +376,16 @@ int pe_service_run(const void *pe_data, u64 size, const char *cmdline, u64 *exit
int rrc = x86emu32_run(&emu, &code);
if (rrc != 0) {
log_error("[PE32] emulator error");
panic_full("PE-E14 EMULATOR ERROR",
"pe_service_run: x86emu32_run returned error", 0);
code = 0xFFFFFFFFULL;
}
/* emu 字段只在未发生 longjmp 的正常返回路径读取
* (setjmp 语义:longjmp 后被修改的自动变量值不确定) */
if (emu.error && !emu.exited) {
log_warn("[PE32] emulator stopped with error");
panic_full("PE-E15 EMULATOR STOPPED WITH ERROR",
"pe_service_run: emulator stopped in error state", 0);
}
} else {
code = pe_shim_get_exit_code();
+15
View File
@@ -0,0 +1,15 @@
pe/pe_service.o: pe\pe_service.c pe\pe_loader.h include\utsm\types.h \
include\utsm\pe.h pe\pe_shim.h pe\pe_dll_manager.h pe\x86emu32.h \
pe\..\include\utsm\pe.h include\utsm\arena.h include\utsm\idt.h \
include\utsm\log.h include\utsm\panic.h
pe\pe_loader.h:
include\utsm\types.h:
include\utsm\pe.h:
pe\pe_shim.h:
pe\pe_dll_manager.h:
pe\x86emu32.h:
pe\..\include\utsm\pe.h:
include\utsm\arena.h:
include\utsm\idt.h:
include\utsm\log.h:
include\utsm\panic.h: