From 537890df9ecf23713295b2021f1bfe601065eeda Mon Sep 17 00:00:00 2001 From: xyou Date: Tue, 28 Jul 2026 14:35:14 +0800 Subject: [PATCH] FUCK2 --- CODE/UTSM/MAKEFILE | 2 +- CODE/UTSM/include/utsm/linux_compat.h | 56 ++ CODE/UTSM/include/utsm/linux_loader.h | 7 +- CODE/UTSM/include/utsm/linux_resume.h | 28 + CODE/UTSM/include/utsm/pe.h | 42 + CODE/UTSM/include/utsm/vmm.h | 24 + CODE/UTSM/kernel/dsk_loader.c | 14 + CODE/UTSM/kernel/dsk_loader.o | Bin 7112 -> 7312 bytes CODE/UTSM/kernel/main.c | 6 +- CODE/UTSM/kernel/main.o | Bin 4464 -> 4544 bytes CODE/UTSM/pe/pe_loader.c | 368 ++++++++ CODE/UTSM/pe/pe_loader.h | 185 ++++ CODE/UTSM/pe/pe_service.c | 290 ++++++ CODE/UTSM/pe/pe_shim.c | 421 +++++++++ CODE/UTSM/pe/pe_shim.h | 65 ++ CODE/UTSM/pe/x86emu32.c | 975 ++++++++++++++++++++ CODE/UTSM/pe/x86emu32.h | 100 ++ CODE/UTSM/vmm/linux_boot.c | 19 +- CODE/UTSM/vmm/linux_compat.c | 198 ++++ CODE/UTSM/vmm/linux_resume.c | 68 ++ CODE/UTSM/vmm/vmexit.c | 18 +- CODE/UTSM/vmm/vmm.c | 6 + CODE/cmd/MAKEFILE | 25 + CODE/cmd/linker.ld | 24 + CODE/cmd/main.c | 961 +++++++++++++++++++ CODE/desktop/main.c | 281 +++--- CODE/dsk/main.c | 14 +- CODE/dsk/main.o | Bin 19816 -> 19504 bytes CODE/linux/build.sh | 11 + CODE/linux/initramfs/bin/utsm_exec_daemon.c | 218 +++++ CODE/linux/initramfs/init | 47 + CODE/linux/patches/utsm_hcall.c | 143 ++- CODE/login/main.c | 119 ++- CODE/shell/main.c | 502 ++++++---- CODE/shell/main.o | Bin 130256 -> 108536 bytes CODE/utsm-ipc/ipc_proto.h | 35 + SYSTEM/boot/utsm.elf | Bin 87120 -> 128216 bytes SYSTEM/limine/limine.conf | 16 +- SYSTEM/system/deshab64/cmd.elf | Bin 0 -> 490864 bytes SYSTEM/system/deshab64/deshab.elf | Bin 20504 -> 20504 bytes SYSTEM/system/deshab64/desktop.elf | Bin 145240 -> 140128 bytes SYSTEM/system/deshab64/shell.elf | Bin 871648 -> 791904 bytes SYSTEM/system/user/use/login.elf | Bin 41936 -> 51600 bytes build.ps1 | 19 + 44 files changed, 4903 insertions(+), 404 deletions(-) create mode 100644 CODE/UTSM/include/utsm/linux_compat.h create mode 100644 CODE/UTSM/include/utsm/linux_resume.h create mode 100644 CODE/UTSM/include/utsm/pe.h create mode 100644 CODE/UTSM/pe/pe_loader.c create mode 100644 CODE/UTSM/pe/pe_loader.h create mode 100644 CODE/UTSM/pe/pe_service.c create mode 100644 CODE/UTSM/pe/pe_shim.c create mode 100644 CODE/UTSM/pe/pe_shim.h create mode 100644 CODE/UTSM/pe/x86emu32.c create mode 100644 CODE/UTSM/pe/x86emu32.h create mode 100644 CODE/UTSM/vmm/linux_compat.c create mode 100644 CODE/UTSM/vmm/linux_resume.c create mode 100644 CODE/cmd/MAKEFILE create mode 100644 CODE/cmd/linker.ld create mode 100644 CODE/cmd/main.c create mode 100644 CODE/linux/initramfs/bin/utsm_exec_daemon.c create mode 100644 CODE/linux/initramfs/init create mode 100644 SYSTEM/system/deshab64/cmd.elf diff --git a/CODE/UTSM/MAKEFILE b/CODE/UTSM/MAKEFILE index 56636d8..6715fb9 100644 --- a/CODE/UTSM/MAKEFILE +++ b/CODE/UTSM/MAKEFILE @@ -9,7 +9,7 @@ CFLAGS := -target x86_64-unknown-none -std=c11 -ffreestanding -fno-builtin -fno- ASFLAGS := -target x86_64-unknown-none -ffreestanding -fno-pic -fno-pie -mcmodel=kernel -mno-red-zone -mno-sse -mno-sse2 -mno-mmx -msoft-float -m64 -Iinclude -I../utsm-ipc LDFLAGS := -nostdlib -static -z max-page-size=0x1000 -T linker.ld -C_SOURCES := $(wildcard arch/x86_64/*.c kernel/*.c runtime/*.c mm/*.c core/*.c crypto/*.c pckc/*.c utrw/*.c drr/*.c dkm/*.c test/*.c vmm/*.c) +C_SOURCES := $(wildcard arch/x86_64/*.c kernel/*.c runtime/*.c mm/*.c core/*.c crypto/*.c pckc/*.c utrw/*.c drr/*.c dkm/*.c test/*.c vmm/*.c pe/*.c) S_SOURCES := $(wildcard arch/x86_64/*.S vmm/*.S) OBJECTS := $(C_SOURCES:.c=.o) $(S_SOURCES:.S=.o) diff --git a/CODE/UTSM/include/utsm/linux_compat.h b/CODE/UTSM/include/utsm/linux_compat.h new file mode 100644 index 0000000..57b525d --- /dev/null +++ b/CODE/UTSM/include/utsm/linux_compat.h @@ -0,0 +1,56 @@ +#ifndef UTSM_LINUX_COMPAT_H +#define UTSM_LINUX_COMPAT_H + +/* linux_compat.h — Deshab Linux 程序兼容层服务接口。 + * + * 依赖 UTSM+Linux 双内核架构:Linux guest 作为 daemon 在 VMX guest 中 + * park-and-resume 驻留。UTSM 侧的 linux_compat_service 通过 IPC 共享内存 + * 向 Linux daemon 发送 exec 请求,并 vmresume 唤醒 guest 执行。 + * + * 执行流程: + * 1. shell.elf / cmd.elf 通过 boot context 获取 linux_compat_service 指针 + * 2. 调用 exec(path, argc, argv, ...) 写 IPC 请求到 utsm_to_linux ring + * 3. exec() 调用 linux_resume() → vmresume → Linux daemon fork+exec + * 4. daemon 通过 linux_to_utsm ring 回传 stdout/stderr/exit,然后 HLT park + * 5. exec() 从 ring 读取输出,返回给调用方 + * + * 服务指针通过 dsk_boot_context.reserved[5] 暴露给 DSK 用户态(shell/cmd/desktop)。 + */ + +#include + +#define LINUX_COMPAT_MAGIC 0x4C4E58434F4D5000ULL /* "LNXCOMP\0" */ + +/* Linux 兼容层服务表 — 通过 boot context reserved[5] 传递 */ +typedef struct linux_compat_service { + u64 magic; /* LINUX_COMPAT_MAGIC */ + + /* 查询 Linux 兼容层是否可用(Linux guest 已 park 且 IPC 就绪)。 + * 返回 1 可用,0 不可用。 */ + int (*is_available)(void); + + /* 执行一个 Linux 程序。 + * path : 程序路径(如 "/bin/ls"),NUL-terminated + * argc/argv : 参数向量(argv[0] 通常为程序名) + * stdout_buf : 接收 stdout 的缓冲区(可为 NULL,此时丢弃 stdout) + * stdout_cap : stdout_buf 容量(字节) + * stdout_len : 输出实际写入的字节数(可为 NULL) + * exit_code : 输出进程退出码(可为 NULL) + * 返回 0 成功,负值失败(-1=服务不可用, -2=IPC 发送失败, + * -3=linux_resume 失败, -4=超时无响应)。 */ + int (*exec)(const char *path, int argc, const char *const *argv, + char *stdout_buf, u64 stdout_cap, u64 *stdout_len, + u64 *exit_code); + + /* 查询 Linux guest 状态字符串(调试用),写入 buf,返回字符串长度。 */ + int (*status)(char *buf, u64 cap); +} linux_compat_service; + +/* 获取全局 Linux 兼容层服务实例指针(UTSM 内部使用, + * 外部通过 boot context reserved[5] 获取)。 */ +const linux_compat_service *linux_compat_get_service(void); + +/* 初始化 Linux 兼容层服务(在 linux_launch 成功后调用)。 */ +void linux_compat_init(void); + +#endif /* UTSM_LINUX_COMPAT_H */ diff --git a/CODE/UTSM/include/utsm/linux_loader.h b/CODE/UTSM/include/utsm/linux_loader.h index 0f6f204..6496f00 100644 --- a/CODE/UTSM/include/utsm/linux_loader.h +++ b/CODE/UTSM/include/utsm/linux_loader.h @@ -162,9 +162,12 @@ const struct linux_guest_info *linux_get_guest_info(void); * Returns 0 on successful guest termination, negative on error. */ int linux_launch(void); -/* Default Linux command line (can be overridden). */ +/* Default Linux command line (can be overridden). + * nohlt: prevent kernel idle loop from using HLT — only the exec daemon's + * explicit ioctl(PARK) HLT should trigger VM-Exit park, so that + * linux_launch() returns only after the daemon is ready. */ #define LINUX_DEFAULT_CMDLINE \ "console=ttyS0,115200 earlyprintk=serial nokaslr " \ - "no_timer_check loglevel=7" + "no_timer_check loglevel=7 nohlt idle=poll" #endif diff --git a/CODE/UTSM/include/utsm/linux_resume.h b/CODE/UTSM/include/utsm/linux_resume.h new file mode 100644 index 0000000..98727f4 --- /dev/null +++ b/CODE/UTSM/include/utsm/linux_resume.h @@ -0,0 +1,28 @@ +#ifndef UTSM_LINUX_RESUME_H +#define UTSM_LINUX_RESUME_H + +#include + +/* linux_resume.h — Linux guest park-and-resume 唤醒接口。 + * + * linux_launch() 启动 Linux guest 后,guest daemon 完成 init 并 HLT 驻留(park)。 + * linux_resume() 通过 vmresume 唤醒 guest,daemon 处理 IPC 请求后再次 HLT park, + * 控制权返回 host。 + * + * 典型流程: + * 1. shell 调用 linux_compat_service->exec(path, argc, argv) + * 2. exec() 写 IPC 请求到 utsm_to_linux ring + * 3. exec() 调用 linux_resume() → vmresume → guest daemon 读取请求 → fork+exec + * 4. daemon 写输出到 linux_to_utsm ring → HLT park → linux_resume() 返回 + * 5. exec() 从 ring 读取输出,返回给 shell + */ + +/* 唤醒已 park 的 Linux guest。 + * 前置条件:g_guest_parked == 1(linux_launch 已完成且 guest 已 HLT)。 + * 返回 0 成功(guest 再次 park),负值失败。 */ +int linux_resume(void); + +/* 查询 Linux guest 是否已 park 就绪。 */ +int linux_is_parked(void); + +#endif /* UTSM_LINUX_RESUME_H */ diff --git a/CODE/UTSM/include/utsm/pe.h b/CODE/UTSM/include/utsm/pe.h new file mode 100644 index 0000000..92a3813 --- /dev/null +++ b/CODE/UTSM/include/utsm/pe.h @@ -0,0 +1,42 @@ +#ifndef UTSM_PE_H +#define UTSM_PE_H + +/* pe.h — Deshab PE/EXE 兼容层公共接口。 + * + * UTSM 内置 PE32+(64位)与 PE32(32位)加载器: + * - PE32+:解析 → 映射节区 → 基址重定位 → import 解析(Windows API shim)→ Ring0 原生执行 + * - PE32 :解析 → 映射节区 → 基址重定位 → import 解析 → x86-32 解释器执行 + * + * pe_service 通过 dsk_boot_context.reserved[4] 暴露给 DSK/cmd.elf, + * 同地址空间 Ring0 直接调用。 + */ + +#include + +#define PE_SERVICE_MAGIC 0x5045535643200000ULL /* "PESVC\0\0" */ + +/* PE 加载结果 */ +typedef struct pe_image_info { + u64 image_base; /* 实际加载基址(kmem_alloc_aligned 返回) */ + u64 image_size; /* 映射后总大小(SizeOfImage) */ + u64 entry_point; /* 绝对入口地址 = image_base + AddressOfEntryPoint */ + int is_pe32_plus; /* 1=PE32+ 64位原生执行, 0=PE32 32位解释执行 */ + int load_ok; /* 1=加载成功 */ +} pe_image_info; + +/* PE 服务表 — 通过 boot context reserved[4] 传递 */ +typedef struct pe_service { + u64 magic; /* PE_SERVICE_MAGIC */ + /* 加载 PE 到内存(不执行)。返回 0 成功,info 填充。 */ + int (*load)(const void *pe_data, u64 size, pe_image_info *out); + /* 加载并执行 PE。cmdline = 命令行字符串(GetCommandLineA 返回值)。 + * 返回 0 成功,*exit_code 为进程退出码。 */ + int (*run)(const void *pe_data, u64 size, const char *cmdline, u64 *exit_code); + /* 释放 pe_load 分配的镜像内存。 */ + void (*unload)(pe_image_info *info); +} pe_service; + +/* 获取全局 PE 服务实例指针(UTSM 内部使用,外部通过 boot context 获取) */ +const pe_service *pe_get_service(void); + +#endif /* UTSM_PE_H */ diff --git a/CODE/UTSM/include/utsm/vmm.h b/CODE/UTSM/include/utsm/vmm.h index d130267..c03f4ca 100644 --- a/CODE/UTSM/include/utsm/vmm.h +++ b/CODE/UTSM/include/utsm/vmm.h @@ -42,6 +42,30 @@ struct vmexit_guest_regs { * Non-static: shared between vmm.c, vmexit.c, hypercall.c, and vmexit_asm.S. */ extern volatile struct vmexit_guest_regs g_guest_regs; +/* ===== Linux guest park-and-resume 状态 ===== + * + * g_linux_guest_active: 1 = 当前运行的 guest 是 Linux guest。 + * handle_hlt 检查此标志:Linux guest HLT 时 park(推进 RIP,exit-to-host), + * self-test guest HLT 时 terminate。 + * g_guest_parked: 1 = Linux guest 已 HLT 驻留,可被 linux_resume() 唤醒。 + * linux_compat_service 通过此标志判断 guest 是否就绪。 */ +extern volatile int g_linux_guest_active; +extern volatile int g_guest_parked; + +/* ===== VM-Exit host 恢复点(vmm.c 定义,vmm.c / linux_boot.c / linux_resume.c 共用) ===== + * + * g_saved_host_rsp: vmlaunch/vmresume 前保存的 host RSP。VM-Exit 处理器 + * 终止 guest 时恢复此 RSP 并 jmp 到 g_saved_return_rip。 + * g_saved_return_rip: vmlaunch/vmresume 后的返回地址(post_guest / post_resume 标签)。 + * g_guest_terminated: 1 = guest 已终止(不再 vmresume)。dispatch 返回 0 时置位。 + * g_last_exit_reason: 最近一次 VM-Exit 的 reason(vmexit_asm.S 路径写入)。 + * + * 这些符号必须是非 static 全局变量,因为 vmexit_asm.S 通过 RIP 相对寻址引用。 */ +extern volatile u64 g_saved_host_rsp; +extern volatile u64 g_saved_return_rip; +extern volatile int g_guest_terminated; +extern volatile u64 g_last_exit_reason; + /* ===== VMM API ===== */ /* 初始化 VMM:VMX root 模式 + EPT 表 + 分配 VMCS。 diff --git a/CODE/UTSM/kernel/dsk_loader.c b/CODE/UTSM/kernel/dsk_loader.c index 837adec..4145b2d 100644 --- a/CODE/UTSM/kernel/dsk_loader.c +++ b/CODE/UTSM/kernel/dsk_loader.c @@ -3,6 +3,8 @@ #include #include #include +#include +#include #include "../arch/x86_64/limine.h" #define DSK_PATH "/system/deshab64/deshab.elf" @@ -319,6 +321,18 @@ static void dsk_fill_boot_context(dsk_boot_context *ctx) { ctx->boot_modules_response = (u64)g_module_request.response; ctx->dkm_kernel_api = (u64)dkm_get_kernel_api(); + /* PE 兼容层服务(PE32+ 原生 + PE32 解释器) */ + const pe_service *pe = pe_get_service(); + if (pe && pe->magic == PE_SERVICE_MAGIC) { + ctx->reserved[4] = (u64)pe; + } + + /* Linux 兼容层服务(依赖双内核 park-and-resume + IPC) */ + const linux_compat_service *lxc = linux_compat_get_service(); + if (lxc && lxc->magic == LINUX_COMPAT_MAGIC) { + ctx->reserved[5] = (u64)lxc; + } + u64 rsp; __asm__ volatile ("movq %%rsp, %0" : "=r"(rsp)); ctx->kernel_stack_top = rsp; diff --git a/CODE/UTSM/kernel/dsk_loader.o b/CODE/UTSM/kernel/dsk_loader.o index 7beab38746c921ad2d8ebb76e8f922f31b87cd6f..0e903127c4b7fd32db754e75211c6cf0b267ae30 100644 GIT binary patch delta 1103 zcmZWoT}TvB6uvX=&&=lTtXMlcYm}{RuD&c8B>PaNQq97emS7Q)ZL-KhKW19{5@l&7 zQVkx7Ac&+0>O~eK*a-5;AL_-Zkb0_@+#bRnQgf5ry*qbknl8+_=YHRJzI*20nVDKG zs)c!PAXELu#@&Qv+e6nY9-*daUK)H3kL-tbb&zFjc%MHWU68I$A%xWEOnvq@##p+x zpK^WESfbNcw1{zh2rm!~QU@lb{vZ!K99M#mIfUx7qyXpc71A}DYK4^g01MI`B#AuUWykFHh`|G`J0p3&;4`Wq2vf@k>i^TO8p=CxWh9yb>TS z+RzV7%go~h%oazuIQ$~97OLEb#gI$qM`6q@!vnW!ZzHu{IH;7`okj+JPnuhyiV=^0 zLi5Z!E@zy2osCQz$U~2VjyV(VGvR9tUq>*Sb`ozoctM}34{gQp@i5%bUt;=l9Y2Z; zqLdL~labqGRAVu!X8PS0yn*2{DDlb4MH5>{y*hmZ>U}ad4(CYxLZkBCqU4aST!k^8 z9CL{J>(Oqhu!yl?3yv7x^dGL*_X8)(%D9zfUA=(qgq^amJY(NNLY7bdw6KV=0{Z}r z^SsZ_!OL)ZF&^?57b9Er5xqgQ(FGsneC4Usncj4J$Jx_eiJtb(WKa9~WcP(sM-p`< z%}aRae`c>FTNTkSO}yjRUDEJGspCT~_@?X>5&1dk(4Z=?SxFHwZLOw&{S8S-1nRgh o7%RljBz}M`WpyPQvve@22pL7TM~DSaw{*=H>qMA`r)8V|0N=XuPyhe` delta 922 zcmZ8fO=uHA6rR~`lik?eHAFJINkB1HV-B_;Soa`tMP-E+ixe#AL5fs*DtZtpNNsH` zQjm}*(u)OuE?$JTc&H$VhbEwC3yOjsT0z|0+8%5$)p2HbB4HoQ%-iq#-ZyV&rf65X ziaE)(=JM}k+yh(klh~+)P>)?Vrmn-&)^o?Q?DNd@X|vn*jPWIekZV_*#cfKdaXZSn zu`)II@)NC7+I^RLOoQCX*T%$m42L7P_6}l%oJCeZs~7zA4^Mmjl>1aq!KcVsoPhS| zTj*4>cpmzc?19U5O5JjqyH&@3Q#w7v)5)*K#I+iwV|9e~AY*C}W|fPQT7zw6MLMzt zAJh{5xG)gACs~_JE~5>~%bMdTs9Fc!2R54x7}CzGKh%J~4{I8MRn5hRz|jeKx(WUI zjd|lsWb{=u(ClCfPp`24dAt$0%<>o;{Ev9N59x0T{b~qL2;6J((VBcV13Zr!8|OvA z-;mJ>fvYf=BvzNgJXr85KiwJ7F03U99)>s}_%WZY=OHCVf$}9dj9m(`ErRv@T1_0> z|6Tk&5jqKvSnY6_6+Mi=3S;ktSV^!Yz$O`Z5n_>GD@`~*fLZa^%L3=uptI4qhR-2= zhv@K|3L|D69$E{n{DHJUJe5#?k$~-mtEqz4cojazUPc0zQ>I$v?kq0BMrt>9Af6_; z9S)`oxD$r_`B}OkJ!oTw$xqhQ7?M+)P_gUK4%ug|{e<8JPi%{sA8> B!_oi% diff --git a/CODE/UTSM/kernel/main.c b/CODE/UTSM/kernel/main.c index 3eabec6..366a89d 100644 --- a/CODE/UTSM/kernel/main.c +++ b/CODE/UTSM/kernel/main.c @@ -8,6 +8,7 @@ #include #include #include +#include void arch_halt_forever(void); @@ -71,7 +72,10 @@ void kernel_main(void) { int lin_st = linux_launch(); if (lin_st == 0) { - log_info("[UTSM] Linux guest terminated"); + log_info("[UTSM] Linux guest parked (daemon ready)"); + /* Phase 3.2: 初始化 Linux 兼容层服务 + * (需在 linux_launch 成功 + guest park 后调用) */ + linux_compat_init(); } else { log_error("[UTSM] Linux launch failed"); log_hex64("[UTSM] Linux st=", (u64)(i64)lin_st); diff --git a/CODE/UTSM/kernel/main.o b/CODE/UTSM/kernel/main.o index 0c4c444a060697767941f94ffba1776e7839c071..47a09e35a0bd89e72b9fd86e85850873adb01760 100644 GIT binary patch delta 395 zcmXX?J4?f06wOUdViH5X2%6~9qC(rn7)0vkB;r^>T!b2IeN^oWq!t(5s*9-?1Q+Sz zA}%F^Yh8LMxr0l$3h84jHLIQJ3Ev}e5pT(pv1ka`@&&z8^g4=_=3D@VC( zERl6{C&fanl5?}Qr2iDz1K2@Bu&0v1apN2x_Aqp)4$;K2V1j@R(Zsr7!86k@A>%vM z+e}v(Uo-wiN3_usEnJo?h|x|P+QX{QWr1b_(Yh5aKo(wQ<~_mk52Qo{F0r9xU=jOD zl~;JotMf32_v#wt@msxtPb`mhp@r+34R2V}Qrhcq)e*YxG(KvZ>hWRW^enSmJSn;U zpLPzgk7eDI1C5=;dDzfbpo1TJO7^5djDCSc>1>CXvNC+b9i~YNns`Oxu!JpQ@}hu_ dK8at1zy|h-2?5GR9E#`|raUSPtm>FHqW>7hXOjQ` delta 368 zcmXw!u}eZx6vp3q`g}a~>Aelz>m=r&O$rT;)l@{ZL{LzOkWoWvA>|~zEeJ~bmTCwb zY7FHq)|7+)K#R21*d_$g5Y&5DJHvtBcfRv+&U1P=)yz`9Gd&>vW79SDTMF08NBesR zrCNF0eG2RltsrIO5`r{sLesVX>U-?hIXZ@*Pru{JkaVN?PVt)|Q8y*>rlh*BTzaq` zlJuiY6=kZ1B)XpVptLd^FGzX|UB#=)bL!1!{E6E%vjIBBW4K6JBqAr)@A!@wcvPSr zVU$2GvOq;x(F=OPb#y@YIJ9%rL(48;XfL_Tu^I(5Z4JG+u-f+Mkp|x5v(!h56|7xz zq%ESvl2n1igk_9>KSPTZsEJpWp)`mK{VND3K8ZYMG>3UEsErMtp)ELESl_`>R240r F`~xccVWt28 diff --git a/CODE/UTSM/pe/pe_loader.c b/CODE/UTSM/pe/pe_loader.c new file mode 100644 index 0000000..faa3d07 --- /dev/null +++ b/CODE/UTSM/pe/pe_loader.c @@ -0,0 +1,368 @@ +/* pe_loader.c — PE32+/PE32 解析、节区映射、重定位、import 解析。 + * + * 加载流程: + * 1. 验证 MZ + PE 签名 + * 2. 区分 PE32(OptionalHeader.Magic=0x10b)/ PE32+(0x20b) + * 3. 分配 SizeOfImage 字节 RWX 内存(kmem_alloc_aligned) + * 4. 复制 SizeOfHeaders + 各节区 raw data 到 virtual_address + * 5. 应用基址重定位(.reloc 节区:DIR64 for PE32+,HIGHLOW for PE32) + * 6. 解析 import 表,用 shim 函数指针填充 IAT + * 7. 构建 IAT 条目表(供 32位解释器 CALL 拦截) + */ + +#include "pe_loader.h" +#include "pe_shim.h" +#include "x86emu32.h" +#include "../include/utsm/pe.h" +#include +#include +#include + +/* 合成 shim 地址范围(32位解释器用):0x00010000..0x0001FFFF */ +#define PE_SHIM_ADDR_BASE 0x00010000u +#define PE_SHIM_ADDR_END 0x00020000u +#define PE_SHIM_UNIMPL 0x0001FFFFu + +/* 全局 IAT 表(pe_loader 填充,x86emu32 读取) */ +static pe_iat_entry g_iat_entries[256]; +static int g_iat_count; + +/* ---- 辅助:RVA → 文件偏移 ---- */ +static u32 rva_to_offset(const image_section_header *sections, int nsec, + u32 rva, u32 *out_size) { + for (int i = 0; i < nsec; i++) { + u32 va = sections[i].virtual_address; + u32 vs = sections[i].virtual_size; + if (vs == 0) vs = sections[i].size_of_raw_data; + if (rva >= va && rva < va + vs) { + if (out_size) *out_size = vs; + return sections[i].pointer_to_raw_data + (rva - va); + } + } + if (out_size) *out_size = 0; + return 0xFFFFFFFF; +} + +/* ---- 解析 NT 头 ---- */ +typedef struct { + const image_file_header *file_hdr; + const void *optional_hdr; + int is_pe32_plus; + u32 image_base; /* 32位截断的加载基址(PE32+ 也截断用于 RVA 计算) */ + u32 size_of_image; + u32 size_of_headers; + u32 entry_rva; + const image_data_directory *data_dir; +} pe_nt_info; + +static int parse_nt_headers(const void *pe_data, u64 size, pe_nt_info *out) { + if (size < sizeof(image_dos_header)) return -1; + const image_dos_header *dos = (const image_dos_header *)pe_data; + if (dos->e_magic != IMAGE_DOS_SIGNATURE) return -2; + if (dos->e_lfanew + 4 + sizeof(image_file_header) > size) return -3; + + const u8 *nt_base = (const u8 *)pe_data + dos->e_lfanew; + u32 sig = *(const u32 *)nt_base; + if (sig != IMAGE_NT_SIGNATURE) return -4; + + const image_file_header *fh = (const image_file_header *)(nt_base + 4); + out->file_hdr = fh; + + const void *opt = (const void *)(nt_base + 4 + sizeof(image_file_header)); + out->optional_hdr = opt; + + u16 magic = *(const u16 *)opt; + if (magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) { + const image_optional_header64 *oh = (const image_optional_header64 *)opt; + out->is_pe32_plus = 1; + out->image_base = (u32)oh->image_base; + out->size_of_image = oh->size_of_image; + out->size_of_headers = oh->size_of_headers; + out->entry_rva = oh->address_of_entry_point; + out->data_dir = oh->data_directory; + } else if (magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + const image_optional_header32 *oh = (const image_optional_header32 *)opt; + out->is_pe32_plus = 0; + out->image_base = oh->image_base; + out->size_of_image = oh->size_of_image; + out->size_of_headers = oh->size_of_headers; + out->entry_rva = oh->address_of_entry_point; + out->data_dir = oh->data_directory; + } else { + return -5; + } + + if (out->size_of_image == 0 || out->size_of_image > 64 * 1024 * 1024) return -6; + if (out->entry_rva == 0 || out->entry_rva >= out->size_of_image) return -7; + return 0; +} + +/* ---- 应用基址重定位 ---- */ +static void apply_relocations(u8 *image, u32 image_size, u64 image_base_actual, u32 image_base_preferred, + const image_data_directory *reloc_dir, + const image_section_header *sections, int nsec, + const void *pe_data, u64 pe_size, int is_pe32_plus) { + if (reloc_dir->virtual_address == 0 || reloc_dir->size == 0) return; + + u32 block_rva = reloc_dir->virtual_address; + u32 block_end = block_rva + reloc_dir->size; + i64 delta = (i64)image_base_actual - (i64)image_base_preferred; + if (delta == 0) return; /* 加载到首选基址,无需重定位 */ + + while (block_rva < block_end) { + u32 dummy_size; + u32 file_off = rva_to_offset(sections, nsec, block_rva, &dummy_size); + if (file_off == 0xFFFFFFFF || file_off + 8 > pe_size) break; + + const u8 *block = (const u8 *)pe_data + file_off; + u32 page_rva = *(const u32 *)block; + u32 block_size = *(const u32 *)(block + 4); + if (block_size < 8 || block_rva + block_size > block_end) break; + + u32 entry_count = (block_size - 8) / 2; + const u16 *entries = (const u16 *)(block + 8); + + for (u32 i = 0; i < entry_count; i++) { + u16 e = entries[i]; + u32 type = (e >> 12) & 0xF; + u32 offset = e & 0xFFF; + + if (type == IMAGE_REL_BASED_ABSOLUTE) continue; + + u32 target_rva = page_rva + offset; + /* image 缓冲区按 RVA 排列(image[0] = RVA 0) */ + if (target_rva >= (u32)image_size) continue; + u8 *target = image + target_rva; + if (type == IMAGE_REL_BASED_DIR64) { + u64 val = *(u64 *)target; + val += (u64)delta; + *(u64 *)target = val; + } else if (type == IMAGE_REL_BASED_HIGHLOW) { + u32 val = *(u32 *)target; + val += (u32)delta; + *(u32 *)target = val; + } else { + /* 其他重定位类型暂不支持 */ + } + } + block_rva += block_size; + } + (void)is_pe32_plus; +} + +/* ---- 解析 imports,填充 IAT ---- */ +static void resolve_imports(u8 *image, u64 image_base_actual, + const image_data_directory *import_dir, + const image_section_header *sections, int nsec, + const void *pe_data, u64 pe_size, int is_pe32_plus) { + (void)image_base_actual; /* PE32 IAT 用合成地址,不依赖 actual_base */ + if (import_dir->virtual_address == 0 || import_dir->size == 0) return; + + g_iat_count = 0; + u32 dummy; + u32 imp_off = rva_to_offset(sections, nsec, import_dir->virtual_address, &dummy); + if (imp_off == 0xFFFFFFFF) return; + + const image_import_descriptor *imp = (const image_import_descriptor *) + ((const u8 *)pe_data + imp_off); + + for (int dll_idx = 0; ; dll_idx++) { + const image_import_descriptor *desc = &imp[dll_idx]; + if (desc->name == 0 && desc->first_thunk == 0) break; + + /* DLL 名 */ + u32 name_off = rva_to_offset(sections, nsec, desc->name, &dummy); + if (name_off == 0xFFFFFFFF || name_off >= pe_size) continue; + const char *dll_name = (const char *)pe_data + name_off; + + /* IAT (first_thunk) 与 INT (original_first_thunk) */ + u32 iat_rva = desc->first_thunk; + u32 int_rva = desc->original_first_thunk; + if (int_rva == 0) int_rva = iat_rva; /* 无 INT,直接用 IAT */ + + u32 iat_off = rva_to_offset(sections, nsec, iat_rva, &dummy); + u32 int_off = rva_to_offset(sections, nsec, int_rva, &dummy); + + for (int fn_idx = 0; ; fn_idx++) { + u32 iat_entry_off = iat_off + (u32)fn_idx * (is_pe32_plus ? 8 : 4); + if (iat_entry_off + (is_pe32_plus ? 8 : 4) > pe_size) break; + + u32 int_entry_off = int_off + (u32)fn_idx * (is_pe32_plus ? 8 : 4); + if (int_entry_off + (is_pe32_plus ? 8 : 4) > pe_size) break; + + /* 读 INT 条目判断函数名/序号 */ + u64 thunk = 0; + if (is_pe32_plus) { + thunk = *(const u64 *)((const u8 *)pe_data + int_entry_off); + } else { + thunk = *(const u32 *)((const u8 *)pe_data + int_entry_off); + } + if (thunk == 0) break; /* 结束 */ + + const char *func_name = 0; + if (thunk & 0x80000000ULL) { + /* 序号导入:暂不支持,记为未实现 */ + func_name = "#ordinal"; + } else { + /* 名称导入:thunk 是 IMAGE_IMPORT_BY_NAME 的 RVA */ + u32 hint_rva = (u32)thunk; + u32 hint_off = rva_to_offset(sections, nsec, hint_rva, &dummy); + if (hint_off != 0xFFFFFFFF && hint_off + 2 < pe_size) { + func_name = (const char *)pe_data + hint_off + 2; /* 跳过 hint(2字节) */ + } + } + + /* 查 shim 表 */ + int shim_idx = -1; + if (func_name && func_name[0] != '#') { + shim_idx = pe_shim_lookup(dll_name, func_name); + } + + /* 填充 IAT(image 缓冲区内) */ + u8 *iat_ptr = image + iat_rva + (u32)fn_idx * (is_pe32_plus ? 8 : 4); + if (is_pe32_plus) { + u64 fn_addr; + if (shim_idx >= 0) { + const pe_shim_entry *se = pe_shim_get(shim_idx); + fn_addr = (u64)se->fn64; + } else { + fn_addr = pe_shim_unimpl_stub(); + } + *(u64 *)iat_ptr = fn_addr; + } else { + /* 32位:填合成地址,解释器拦截 */ + u32 synth_addr; + if (shim_idx >= 0) { + synth_addr = PE_SHIM_ADDR_BASE | (u32)(shim_idx & 0xFFFF); + } else { + synth_addr = PE_SHIM_UNIMPL; + } + *(u32 *)iat_ptr = synth_addr; + + /* 记录 IAT 条目供解释器查询 */ + if (g_iat_count < 255) { + g_iat_entries[g_iat_count].iat_rva = iat_rva + (u32)fn_idx * 4; + g_iat_entries[g_iat_count].shim_index = shim_idx; + g_iat_entries[g_iat_count].target_addr = synth_addr; + g_iat_count++; + } + } + + if (shim_idx < 0 && func_name) { + log_info("[PE] unimplemented import"); + serial_write(dll_name); + serial_write("!"); + serial_write(func_name); + serial_write("\n"); + } + } + } +} + +/* ---- 主加载函数 ---- */ +int pe_load_image(const void *pe_data, u64 size, pe_image_info *out) { + if (!pe_data || !out || size < sizeof(image_dos_header)) return -1; + + pe_nt_info nt; + int rc = parse_nt_headers(pe_data, size, &nt); + if (rc != 0) { + log_error("[PE] NT header parse failed"); + log_hex64("[PE] rc=", (u64)(i64)rc); + return -2; + } + + /* 节区头 */ + int nsec = nt.file_hdr->number_of_sections; + if (nsec <= 0 || nsec > 96) return -3; + usize opt_size = nt.file_hdr->size_of_optional_header; + const image_section_header *sections = (const image_section_header *) + ((const u8 *)nt.optional_hdr + opt_size); + + /* 分配 SizeOfImage RWX 内存 */ + u32 img_size = nt.size_of_image; + u8 *image = (u8 *)kmem_alloc_aligned(img_size, 0x1000); + if (!image) { + log_error("[PE] alloc image failed"); + return -4; + } + /* 清零 */ + for (u32 i = 0; i < img_size; i++) image[i] = 0; + + /* 复制 headers */ + u32 hdr_copy = nt.size_of_headers; + if (hdr_copy > size) hdr_copy = (u32)size; + if (hdr_copy > img_size) hdr_copy = img_size; + for (u32 i = 0; i < hdr_copy; i++) image[i] = ((const u8 *)pe_data)[i]; + + /* 复制各节区 raw data */ + for (int i = 0; i < nsec; i++) { + u32 va = sections[i].virtual_address; + u32 raw_size = sections[i].size_of_raw_data; + u32 raw_off = sections[i].pointer_to_raw_data; + if (va >= img_size) continue; + u32 copy_size = raw_size; + if (va + copy_size > img_size) copy_size = img_size - va; + if (raw_off + copy_size > size) { + copy_size = (u32)(size - raw_off); + } + if (raw_off + copy_size > size) continue; + for (u32 j = 0; j < copy_size; j++) { + image[va + j] = ((const u8 *)pe_data)[raw_off + j]; + } + } + + /* 基址重定位 */ + u64 actual_base = (u64)image; + u32 preferred_base = nt.image_base; + /* image 缓冲区按 RVA 排列(image[0]=RVA 0),重定位写入 image 内 */ + /* 注意:apply_relocations 直接操作 image 缓冲区,delta = actual_base - preferred_base */ + { + const image_data_directory *reloc_dir = &nt.data_dir[IMAGE_DIRECTORY_ENTRY_BASERELOC]; + /* 重定位 target 是 RVA,写入 image[rva]。 + * 但 image 加载在 actual_base,代码中绝对地址 = actual_base + RVA。 + * 重定位修正量 = actual_base - preferred_base。 + * image[rva] 处的值原为 preferred_base + rva_offset(链接时假设), + * 修正后应为 actual_base + rva_offset,即加 delta。 */ + apply_relocations(image, img_size, actual_base, preferred_base, reloc_dir, + sections, nsec, pe_data, size, nt.is_pe32_plus); + } + + /* 解析 imports */ + { + const image_data_directory *import_dir = &nt.data_dir[IMAGE_DIRECTORY_ENTRY_IMPORT]; + resolve_imports(image, actual_base, import_dir, sections, nsec, + pe_data, size, nt.is_pe32_plus); + } + + out->image_base = actual_base; + out->image_size = img_size; + out->entry_point = actual_base + nt.entry_rva; + out->is_pe32_plus = nt.is_pe32_plus; + out->load_ok = 1; + + log_hex64("[PE] loaded base=", actual_base); + log_hex64("[PE] image size=", img_size); + log_hex64("[PE] entry=", out->entry_point); + log_info(nt.is_pe32_plus ? "[PE] PE32+ (64-bit)" : "[PE] PE32 (32-bit)"); + return 0; +} + +void pe_unload_image(pe_image_info *info) { + if (!info || !info->load_ok) return; + /* kmem_alloc_aligned 无对应 free(arena 分配器),标记为未加载即可 */ + info->load_ok = 0; +} + +u64 pe_get_image_base(const pe_image_info *info) { + return info ? info->image_base : 0; +} + +u64 pe_get_image_size(const pe_image_info *info) { + return info ? info->image_size : 0; +} + +/* 供 x86emu32 获取 IAT 表 */ +pe_iat_entry *pe_get_iat_entries(int *count) { + if (count) *count = g_iat_count; + return g_iat_entries; +} diff --git a/CODE/UTSM/pe/pe_loader.h b/CODE/UTSM/pe/pe_loader.h new file mode 100644 index 0000000..759badd --- /dev/null +++ b/CODE/UTSM/pe/pe_loader.h @@ -0,0 +1,185 @@ +#ifndef PE_LOADER_H +#define PE_LOADER_H + +/* pe_loader.h — PE32+/PE32 解析与加载器内部接口。 */ + +#include +#include + +/* ===== PE 常量 ===== */ +#define IMAGE_DOS_SIGNATURE 0x5A4D /* "MZ" */ +#define IMAGE_NT_SIGNATURE 0x00004550 /* "PE\0\0" */ +#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b +#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b + +/* Section characteristics */ +#define IMAGE_SCN_MEM_EXECUTE 0x20000000 +#define IMAGE_SCN_MEM_READ 0x40000000 +#define IMAGE_SCN_MEM_WRITE 0x80000000 + +/* Data directory indices */ +#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 +#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 +#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 +#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 +#define IMAGE_DIRECTORY_ENTRY_IAT 12 + +/* Relocation types */ +#define IMAGE_REL_BASED_ABSOLUTE 0 +#define IMAGE_REL_BASED_HIGHLOW 3 /* 32位: base + offset 写 32位 */ +#define IMAGE_REL_BASED_DIR64 10 /* 64位: base + offset 写 64位 */ + +/* ===== PE 结构体定义(packed) ===== */ + +typedef struct __attribute__((packed)) { + u16 e_magic; /* "MZ" */ + u16 e_cblp; + u16 e_cp; + u16 e_crlc; + u16 e_cparhdr; + u16 e_minalloc; + u16 e_maxalloc; + u16 e_ss; + u16 e_sp; + u16 e_csum; + u16 e_ip; + u16 e_cs; + u16 e_lfarlc; + u16 e_ovno; + u16 e_res[4]; + u16 e_oemid; + u16 e_oeminfo; + u16 e_res2[10]; + u32 e_lfanew; /* PE 头偏移 */ +} image_dos_header; + +typedef struct __attribute__((packed)) { + u16 machine; + u16 number_of_sections; + u32 time_date_stamp; + u32 pointer_to_symbol_table; + u32 number_of_symbols; + u16 size_of_optional_header; + u16 characteristics; +} image_file_header; + +typedef struct __attribute__((packed)) { + u32 virtual_address; + u32 size; +} image_data_directory; + +typedef struct __attribute__((packed)) { + u16 magic; + u8 major_linker_version; + u8 minor_linker_version; + u32 size_of_code; + u32 size_of_initialized_data; + u32 size_of_uninitialized_data; + u32 address_of_entry_point; + u32 base_of_code; + u32 base_of_data; /* PE32 only */ + u32 image_base; /* PE32: 32位 */ + u32 section_alignment; + u32 file_alignment; + u16 major_os_version; + u16 minor_os_version; + u16 major_image_version; + u16 minor_image_version; + u16 major_subsystem_version; + u16 minor_subsystem_version; + u32 win32_version_value; + u32 size_of_image; + u32 size_of_headers; + u32 check_sum; + u16 subsystem; + u16 dll_characteristics; + u32 size_of_stack_reserve; + u32 size_of_stack_commit; + u32 size_of_heap_reserve; + u32 size_of_heap_commit; + u32 loader_flags; + u32 number_of_rva_and_sizes; + image_data_directory data_directory[16]; +} image_optional_header32; + +typedef struct __attribute__((packed)) { + u16 magic; + u8 major_linker_version; + u8 minor_linker_version; + u32 size_of_code; + u32 size_of_initialized_data; + u32 size_of_uninitialized_data; + u32 address_of_entry_point; + u32 base_of_code; + u64 image_base; /* PE32+: 64位 */ + u32 section_alignment; + u32 file_alignment; + u16 major_os_version; + u16 minor_os_version; + u16 major_image_version; + u16 minor_image_version; + u16 major_subsystem_version; + u16 minor_subsystem_version; + u32 win32_version_value; + u32 size_of_image; + u32 size_of_headers; + u32 check_sum; + u16 subsystem; + u16 dll_characteristics; + u64 size_of_stack_reserve; + u64 size_of_stack_commit; + u64 size_of_heap_reserve; + u64 size_of_heap_commit; + u32 loader_flags; + u32 number_of_rva_and_sizes; + image_data_directory data_directory[16]; +} image_optional_header64; + +typedef struct __attribute__((packed)) { + u8 name[8]; + u32 virtual_size; + u32 virtual_address; + u32 size_of_raw_data; + u32 pointer_to_raw_data; + u32 pointer_to_relocations; + u32 pointer_to_linenumbers; + u16 number_of_relocations; + u16 number_of_linenumbers; + u32 characteristics; +} image_section_header; + +typedef struct __attribute__((packed)) { + u32 original_first_thunk; /* INT (Import Name Table) RVA */ + u32 time_date_stamp; + u32 forwarder_chain; + u32 name; /* DLL 名 RVA */ + u32 first_thunk; /* IAT RVA */ +} image_import_descriptor; + +typedef struct __attribute__((packed)) { + u32 original_first_thunk; /* 指向 IMAGE_IMPORT_BY_NAME */ +} image_import_by_name_ref; + +/* ===== 加载器 API ===== */ + +/* 解析并加载 PE 到内存。 + * - 分配 SizeOfImage 字节 RWX 内存 + * - 复制 headers + 各节区 + * - 应用基址重定位 + * - 解析 imports(填 IAT 为 shim 函数指针) + * 返回 0 成功,info 填充;负数失败。 */ +int pe_load_image(const void *pe_data, u64 size, pe_image_info *out); + +/* 释放 pe_load_image 分配的内存 */ +void pe_unload_image(pe_image_info *info); + +/* 获取 PE 内部信息(供 shim/解释器使用) */ +u64 pe_get_image_base(const pe_image_info *info); +u64 pe_get_image_size(const pe_image_info *info); + +/* 获取 IAT 条目表(供 32位解释器 CALL 拦截)。 + * pe_iat_entry 定义在 x86emu32.h。返回表指针,*count 填充条目数。 */ +struct pe_iat_entry; +struct pe_iat_entry *pe_get_iat_entries(int *count); + +#endif /* PE_LOADER_H */ diff --git a/CODE/UTSM/pe/pe_service.c b/CODE/UTSM/pe/pe_service.c new file mode 100644 index 0000000..68f912b --- /dev/null +++ b/CODE/UTSM/pe/pe_service.c @@ -0,0 +1,290 @@ +/* pe_service.c — PE 兼容层服务装配。 + * + * 将 pe_loader + pe_shim + x86emu32 整合为统一的 pe_service, + * 通过 pe_get_service() 暴露给 DSK/cmd.elf(经 dsk_boot_context.reserved[4])。 + * + * 执行策略: + * PE32+ (64位):pe_load_image 加载(actual_base 重定位), + * IAT 填 ms_abi shim 函数地址,Ring0 原生执行入口。 + * ExitProcess 经 __builtin_longjmp 跳回 pe_service_run。 + * PE32 (32位):直接以 preferred_base 加载到一块含栈/堆的大缓冲区, + * 无需重定位。IAT 填合成地址(0x00010000 | shim_idx), + * x86emu32 解释执行,CALL 合成地址时拦截分发到 shim32。 + */ + +#include "pe_loader.h" +#include "pe_shim.h" +#include "x86emu32.h" +#include "../include/utsm/pe.h" +#include +#include +#include + +/* 32位 PE 用的栈与堆 */ +#define PE32_STACK_SIZE (64 * 1024) /* 64KB 栈 */ +#define PE32_HEAP_SIZE (256 * 1024) /* 256KB 堆 */ +#define PE32_MAX_IAT 256 + +/* 合成 shim 地址范围(与 pe_loader.c 一致) */ +#define PE32_SHIM_ADDR_BASE 0x00010000u +#define PE32_SHIM_UNIMPL 0x0001FFFFu + +/* 前向声明(服务表引用) */ +int pe_service_load(const void *pe_data, u64 size, pe_image_info *out); +int pe_service_run(const void *pe_data, u64 size, const char *cmdline, u64 *exit_code); +void pe_service_unload(pe_image_info *info); + +/* 全局服务表实例 */ +static const pe_service g_pe_service = { + PE_SERVICE_MAGIC, + pe_service_load, + pe_service_run, + pe_service_unload, +}; + +const pe_service *pe_get_service(void) { + return &g_pe_service; +} + +/* ===== 加载(不执行)===== */ +int pe_service_load(const void *pe_data, u64 size, pe_image_info *out) { + if (!pe_data || !out) return -1; + return pe_load_image(pe_data, size, out); +} + +void pe_service_unload(pe_image_info *info) { + pe_unload_image(info); +} + +/* ===== PE32 专用加载器(加载到指定缓冲区,base=preferred_base,无重定位)===== */ +typedef struct { + u8 *mem; /* 大缓冲区起始 */ + u32 mem_size; /* 缓冲区总大小 */ + u32 image_base; /* = preferred_base */ + u32 image_size; + u32 entry_point; /* 绝对入口 = image_base + entry_rva */ + pe_iat_entry iat[PE32_MAX_IAT]; + int iat_count; +} pe32_interp_image; + +static int pe32_load_into(const void *pe_data, u64 size, pe32_interp_image *img) { + const u8 *base = (const u8 *)pe_data; + if (size < sizeof(image_dos_header)) return -1; + const image_dos_header *dos = (const image_dos_header *)base; + if (dos->e_magic != IMAGE_DOS_SIGNATURE) return -2; + if ((u64)dos->e_lfanew + 4 + sizeof(image_file_header) > size) return -3; + + const u8 *nt = base + dos->e_lfanew; + if (*(const u32 *)nt != IMAGE_NT_SIGNATURE) return -4; + const image_file_header *fh = (const image_file_header *)(nt + 4); + const void *opt = (const void *)(nt + 4 + sizeof(image_file_header)); + u16 magic = *(const u16 *)opt; + if (magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) return -5; /* 仅 PE32 */ + + const image_optional_header32 *oh = (const image_optional_header32 *)opt; + u32 preferred_base = oh->image_base; + u32 image_size = oh->size_of_image; + u32 entry_rva = oh->address_of_entry_point; + if (image_size == 0 || image_size > 64 * 1024 * 1024) return -6; + if (preferred_base > 0x10000000u) return -7; /* 解释器地址空间限制 */ + + int nsec = fh->number_of_sections; + if (nsec <= 0 || nsec > 96) return -8; + const image_section_header *sections = (const image_section_header *) + ((const u8 *)opt + fh->size_of_optional_header); + + /* 分配大缓冲区:[0 .. preferred_base + image_size + stack + heap] */ + u32 total = preferred_base + image_size + PE32_STACK_SIZE + PE32_HEAP_SIZE; + u8 *mem = (u8 *)kmem_alloc_aligned((u64)total, 0x1000); + if (!mem) return -9; + for (u32 i = 0; i < total; i++) mem[i] = 0; + + /* 复制 headers */ + u32 hdr_copy = oh->size_of_headers; + if (hdr_copy > size) hdr_copy = (u32)size; + if (hdr_copy > image_size) hdr_copy = image_size; + u8 *img_start = mem + preferred_base; + for (u32 i = 0; i < hdr_copy; i++) img_start[i] = base[i]; + + /* 复制各节区 */ + for (int i = 0; i < nsec; i++) { + u32 va = sections[i].virtual_address; + u32 raw_size = sections[i].size_of_raw_data; + u32 raw_off = sections[i].pointer_to_raw_data; + if (va >= image_size) continue; + u32 copy_size = raw_size; + if (va + copy_size > image_size) copy_size = image_size - va; + if ((u64)raw_off + copy_size > size) copy_size = (u32)(size - raw_off); + for (u32 j = 0; j < copy_size; j++) img_start[va + j] = base[raw_off + j]; + } + + /* 解析 imports,填充 IAT(合成地址) */ + img->iat_count = 0; + const image_data_directory *import_dir = &oh->data_directory[IMAGE_DIRECTORY_ENTRY_IMPORT]; + if (import_dir->virtual_address != 0 && import_dir->size != 0) { + /* RVA→offset 辅助 */ + for (int dll_idx = 0; ; dll_idx++) { + u32 imp_rva = import_dir->virtual_address + (u32)dll_idx * sizeof(image_import_descriptor); + /* imp_rva 在 image 内 */ + if (imp_rva + sizeof(image_import_descriptor) > image_size) break; + const image_import_descriptor *desc = (const image_import_descriptor *)(img_start + imp_rva); + if (desc->name == 0 && desc->first_thunk == 0) break; + + /* DLL 名 */ + u32 name_rva = desc->name; + const char *dll_name = 0; + if (name_rva < image_size) dll_name = (const char *)(img_start + name_rva); + + u32 iat_rva = desc->first_thunk; + u32 int_rva = desc->original_first_thunk; + if (int_rva == 0) int_rva = iat_rva; + + for (int fn_idx = 0; ; fn_idx++) { + u32 int_entry_rva = int_rva + (u32)fn_idx * 4; + if (int_entry_rva + 4 > image_size) break; + u32 thunk = *(const u32 *)(img_start + int_entry_rva); + if (thunk == 0) break; + + const char *func_name = 0; + if (thunk & 0x80000000u) { + func_name = "#ordinal"; + } else { + u32 hint_rva = thunk; + if (hint_rva + 2 < image_size) { + func_name = (const char *)(img_start + hint_rva + 2); + } + } + + int shim_idx = -1; + if (func_name && func_name[0] != '#') { + shim_idx = pe_shim_lookup(dll_name, func_name); + } + + u32 synth_addr; + if (shim_idx >= 0) { + synth_addr = PE32_SHIM_ADDR_BASE | (u32)(shim_idx & 0xFFFF); + } else { + synth_addr = PE32_SHIM_UNIMPL; + } + + u32 iat_entry_rva = iat_rva + (u32)fn_idx * 4; + if (iat_entry_rva + 4 <= image_size) { + *(u32 *)(img_start + iat_entry_rva) = synth_addr; + } + + if (img->iat_count < PE32_MAX_IAT) { + img->iat[img->iat_count].iat_rva = iat_entry_rva; + img->iat[img->iat_count].shim_index = shim_idx; + img->iat[img->iat_count].target_addr = synth_addr; + img->iat_count++; + } + + if (shim_idx < 0 && func_name) { + log_info("[PE32] unimplemented import"); + if (dll_name) serial_write(dll_name); + serial_write("!"); + serial_write(func_name); + serial_write("\n"); + } + } + } + } + + img->mem = mem; + img->mem_size = total; + img->image_base = preferred_base; + img->image_size = image_size; + img->entry_point = preferred_base + entry_rva; + return 0; +} + +/* ===== 运行 ===== + * 加载 + 执行 + 卸载。返回 0 成功,*exit_code 为进程退出码。 */ +int pe_service_run(const void *pe_data, u64 size, const char *cmdline, u64 *exit_code) { + if (!pe_data || size == 0) return -1; + + /* 初始化 shim 状态(cmdline for GetCommandLineA) */ + pe_shim_init(cmdline ? cmdline : ""); + + /* 先解析 PE 判断 32/64 位 */ + if (size < sizeof(image_dos_header)) return -2; + const image_dos_header *dos = (const image_dos_header *)pe_data; + if (dos->e_magic != IMAGE_DOS_SIGNATURE) return -3; + const u8 *nt_base = (const u8 *)pe_data + dos->e_lfanew; + if (*(const u32 *)nt_base != IMAGE_NT_SIGNATURE) return -4; + const void *opt = (const void *)(nt_base + 4 + sizeof(image_file_header)); + u16 opt_magic = *(const u16 *)opt; + + if (opt_magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) { + /* ===== PE32+ : Ring0 原生执行 ===== */ + pe_image_info info; + int rc = pe_load_image(pe_data, size, &info); + if (rc != 0) { + log_error("[PE] PE32+ load failed"); + return -5; + } + log_info("[PE] running PE32+ natively"); + + u64 code = 0; + int jumped = pe_shim_setup_exit(); + if (jumped == 0) { + typedef void (*pe_entry_fn)(void); + pe_entry_fn entry = (pe_entry_fn)info.entry_point; + log_hex64("[PE] entry=", (u64)entry); + entry(); + code = 0; + } else { + code = pe_shim_get_exit_code(); + log_hex64("[PE] ExitProcess code=", code); + } + + pe_unload_image(&info); + if (exit_code) *exit_code = code; + return 0; + + } else if (opt_magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + /* ===== PE32 : x86-32 解释器执行 ===== */ + pe32_interp_image img; + int rc = pe32_load_into(pe_data, size, &img); + if (rc != 0) { + log_error("[PE] PE32 interp load failed"); + log_hex64("[PE] rc=", (u64)(i64)rc); + return -6; + } + log_info("[PE] running PE32 via x86emu32"); + + u32 stack_top = img.image_base + img.image_size + PE32_STACK_SIZE - 16; + + x86emu_state emu; + int irc = x86emu32_init(&emu, img.mem, img.mem_size, + img.image_base, img.image_size, + img.iat, img.iat_count, stack_top); + if (irc != 0) { + log_error("[PE32] emu init failed"); + return -7; + } + emu.eip = img.entry_point; + + u64 code = 0; + int jumped = pe_shim_setup_exit(); + if (jumped == 0) { + int rrc = x86emu32_run(&emu, &code); + if (rrc != 0) { + log_error("[PE32] emulator error"); + code = 0xFFFFFFFFULL; + } + } else { + code = pe_shim_get_exit_code(); + log_hex64("[PE32] ExitProcess code=", code); + } + + if (emu.error && !emu.exited) { + log_warn("[PE32] emulator stopped with error"); + } + + if (exit_code) *exit_code = code; + return 0; + } + + return -8; /* 未知 PE magic */ +} diff --git a/CODE/UTSM/pe/pe_shim.c b/CODE/UTSM/pe/pe_shim.c new file mode 100644 index 0000000..a226814 --- /dev/null +++ b/CODE/UTSM/pe/pe_shim.c @@ -0,0 +1,421 @@ +/* pe_shim.c — Windows API shim 实现。 + * + * 所有 64位 shim 用 __attribute__((ms_abi)) 声明,匹配 PE32+ 调用约定。 + * 32位 shim 从模拟栈读参数,供 x86emu32 解释器调用。 + * + * 支持 API:kernel32.dll(GetStdHandle/WriteFile/ReadFile/ExitProcess/ + * HeapAlloc/HeapFree/VirtualAlloc/VirtualFree/GetCommandLineA/...) + * msvcrt.dll(printf/puts/putchar/malloc/free/exit/memcpy/memset/ + * strlen/strcmp/strcpy/_initterm/_initterm_e) + */ + +#include "pe_shim.h" +#include +#include +#include + +/* setjmp/longjmp for ExitProcess — 使用 __builtin_setjmp/__builtin_longjmp + * (clang/gcc 内置,freestanding 可用,无需 libc)。 + * __builtin_setjmp 接受 void** 缓冲区,至少需要 8 个指针槽。 */ +static void *g_exit_jmp[24]; +static int g_exit_jmp_set; +static u64 g_exit_code; +static const char *g_cmdline = ""; + +void pe_shim_init(const char *cmdline) { + g_cmdline = cmdline ? cmdline : ""; + g_exit_jmp_set = 0; + g_exit_code = 0; +} + +/* pe_run 调用:保存上下文,返回 0 = 首次(继续执行),1 = ExitProcess 触发 */ +int pe_shim_setup_exit(void) { + g_exit_jmp_set = 1; + return __builtin_setjmp(g_exit_jmp); +} + +void pe_shim_exit_process(u64 exit_code) { + g_exit_code = exit_code; + if (g_exit_jmp_set) { + __builtin_longjmp(g_exit_jmp, 1); + } + /* 无 jmpbuf:直接返回 */ +} + +int pe_shim_is_exit_call(u64 target) { + /* 64位 ExitProcess shim 地址 */ + extern u64 pe_shim_exitprocess64_addr(void); + if (target == pe_shim_exitprocess64_addr()) return 1; + /* 32位合成地址中 ExitProcess 的标记 */ + return 0; +} + +const char *pe_shim_get_cmdline(void) { return g_cmdline; } + +u64 pe_shim_unimpl_stub(void) { + extern u64 pe_shim_unimpl64_addr(void); + return pe_shim_unimpl64_addr(); +} + +/* ===== 串口/帧缓冲输出(shim 内部复用) ===== */ +static void shim_output(const char *s, u64 len) { + for (u64 i = 0; i < len; i++) { + serial_putc(s[i]); + } +} + +static void shim_output_str(const char *s) { + serial_write(s); +} + +/* ===== kernel32.dll shims (64位, ms_abi) ===== */ + +/* 句柄定义 */ +#define STD_INPUT_HANDLE ((u64)0xFFFFFFF6) +#define STD_OUTPUT_HANDLE ((u64)0xFFFFFFF5) +#define STD_ERROR_HANDLE ((u64)0xFFFFFFF4) +#define SHIM_STDOUT_HANDLE ((u64)0x10000001) +#define SHIM_STDERR_HANDLE ((u64)0x10000002) +#define SHIM_STDIN_HANDLE ((u64)0x10000003) + +static u64 __attribute__((ms_abi)) shim_GetStdHandle(u64 n_std_handle) { + if (n_std_handle == STD_OUTPUT_HANDLE) return SHIM_STDOUT_HANDLE; + if (n_std_handle == STD_ERROR_HANDLE) return SHIM_STDERR_HANDLE; + if (n_std_handle == STD_INPUT_HANDLE) return SHIM_STDIN_HANDLE; + return 0; +} + +static u64 __attribute__((ms_abi)) shim_WriteFile(u64 handle, u64 buffer, u64 length, + u64 bytes_written_ptr, u64 overlapped) { + (void)overlapped; + if (handle == SHIM_STDOUT_HANDLE || handle == SHIM_STDERR_HANDLE) { + const char *buf = (const char *)buffer; + shim_output(buf, length); + if (bytes_written_ptr) *(u64 *)bytes_written_ptr = length; + return 1; /* TRUE */ + } + return 0; +} + +static u64 __attribute__((ms_abi)) shim_ReadFile(u64 handle, u64 buffer, u64 max_length, + u64 bytes_read_ptr, u64 overlapped) { + (void)handle; (void)buffer; (void)max_length; (void)overlapped; + /* 暂不支持输入读取 */ + if (bytes_read_ptr) *(u64 *)bytes_read_ptr = 0; + return 1; +} + +static u64 __attribute__((ms_abi)) shim_ExitProcess(u64 exit_code) { + pe_shim_exit_process(exit_code); + return 0; /* 不返回 */ +} + +static u64 __attribute__((ms_abi)) shim_GetCommandLineA(void) { + return (u64)g_cmdline; +} + +static u64 __attribute__((ms_abi)) shim_GetCommandLineW(void) { + return (u64)g_cmdline; /* 简化:返回 ASCII */ +} + +static u64 __attribute__((ms_abi)) shim_GetLastError(void) { return 0; } +static u64 __attribute__((ms_abi)) shim_SetLastError(u64 code) { (void)code; return 0; } + +static u64 __attribute__((ms_abi)) shim_HeapCreate(u64 fl, u64 init, u64 max) { + (void)fl; (void)init; (void)max; + return 0x10000010; /* 假堆句柄 */ +} +static u64 __attribute__((ms_abi)) shim_HeapAlloc(u64 heap, u64 flags, u64 size) { + (void)heap; (void)flags; + return (u64)kmem_alloc(size); +} +static u64 __attribute__((ms_abi)) shim_HeapFree(u64 heap, u64 flags, u64 ptr) { + (void)heap; (void)flags; (void)ptr; + return 1; /* arena 无 free,返回 TRUE */ +} +static u64 __attribute__((ms_abi)) shim_VirtualAlloc(u64 addr, u64 size, u64 alloc_type, u64 protect) { + (void)addr; (void)alloc_type; (void)protect; + return (u64)kmem_alloc(size); +} +static u64 __attribute__((ms_abi)) shim_VirtualFree(u64 addr, u64 size, u64 free_type) { + (void)addr; (void)size; (void)free_type; + return 1; +} +static u64 __attribute__((ms_abi)) shim_GetModuleHandleA(u64 module_name) { + (void)module_name; + return 0x10000000; /* 假模块基址 */ +} +static u64 __attribute__((ms_abi)) shim_GetModuleHandleW(u64 module_name) { + (void)module_name; + return 0x10000000; +} +static u64 __attribute__((ms_abi)) shim_GetEnvironmentVariableA(u64 name, u64 buf, u64 size) { + (void)name; (void)buf; (void)size; + return 0; +} +static u64 __attribute__((ms_abi)) shim_CreateFileA(u64 filename, u64 access, u64 share, + u64 sa, u64 disp, u64 flags, u64 template) { + (void)filename; (void)access; (void)share; (void)sa; (void)disp; (void)flags; (void)template; + return 0; /* 暂不支持文件 */ +} +static u64 __attribute__((ms_abi)) shim_CloseHandle(u64 handle) { (void)handle; return 1; } +static u64 __attribute__((ms_abi)) shim_GetFileSize(u64 handle, u64 high) { + (void)handle; (void)high; return 0; +} +static u64 __attribute__((ms_abi)) shim_SetFilePointer(u64 handle, i64 dist, u64 high_ptr, u64 method) { + (void)handle; (void)dist; (void)high_ptr; (void)method; return 0; +} + +/* ===== msvcrt.dll shims (64位, ms_abi) ===== */ + +static void shim_msvcrt_output(const char *s) { + shim_output_str(s); +} + +/* printf — 简化版,只支持 %s %d %c %x %u %% */ +static u64 __attribute__((ms_abi)) shim_printf(u64 fmt, u64 a1, u64 a2, u64 a3) { + /* 可变参数:MS x64 ABI 下 a1-a3 在 RDX/R8/R9,更多参数在栈上。 + * 简化处理:只处理前 3 个参数。 */ + const char *f = (const char *)fmt; + u64 args[3] = {a1, a2, a3}; + int argi = 0; + char outbuf[512]; + int oi = 0; + for (int i = 0; f[i] && oi < 510; i++) { + if (f[i] == '%' && f[i+1]) { + i++; + switch (f[i]) { + case 's': { + const char *s = (const char *)(args[argi++ & 3]); + if (s) while (*s && oi < 510) outbuf[oi++] = *s++; + break; + } + case 'd': { + i64 v = (i64)args[argi++ & 3]; + if (v < 0) { outbuf[oi++] = '-'; v = -v; } + char tmp[24]; int ti = 0; + if (v == 0) tmp[ti++] = '0'; + while (v > 0 && ti < 23) { tmp[ti++] = '0' + (v % 10); v /= 10; } + while (ti > 0 && oi < 510) outbuf[oi++] = tmp[--ti]; + break; + } + case 'u': { + u64 v = args[argi++ & 3]; + char tmp[24]; int ti = 0; + if (v == 0) tmp[ti++] = '0'; + while (v > 0 && ti < 23) { tmp[ti++] = '0' + (v % 10); v /= 10; } + while (ti > 0 && oi < 510) outbuf[oi++] = tmp[--ti]; + break; + } + case 'x': { + u64 v = args[argi++ & 3]; + char tmp[24]; int ti = 0; + if (v == 0) tmp[ti++] = '0'; + while (v > 0 && ti < 23) { int d = (int)(v & 0xF); tmp[ti++] = d < 10 ? '0'+d : 'a'+d-10; v >>= 4; } + while (ti > 0 && oi < 510) outbuf[oi++] = tmp[--ti]; + break; + } + case 'c': { + outbuf[oi++] = (char)(args[argi++ & 3] & 0xFF); + break; + } + case '%': outbuf[oi++] = '%'; break; + default: outbuf[oi++] = '%'; outbuf[oi++] = f[i]; break; + } + } else { + outbuf[oi++] = f[i]; + } + } + outbuf[oi] = 0; + shim_msvcrt_output(outbuf); + return (u64)oi; +} + +static u64 __attribute__((ms_abi)) shim_puts(u64 str) { + const char *s = (const char *)str; + shim_msvcrt_output(s); + shim_msvcrt_output("\n"); + return 0; +} + +static u64 __attribute__((ms_abi)) shim_putchar(u64 ch) { + serial_putc((char)(ch & 0xFF)); + return ch & 0xFF; +} + +static u64 __attribute__((ms_abi)) shim_malloc(u64 size) { + return (u64)kmem_alloc(size); +} +static u64 __attribute__((ms_abi)) shim_calloc(u64 count, u64 size) { + u64 total = count * size; + u8 *p = kmem_alloc(total); + if (p) for (u64 i = 0; i < total; i++) p[i] = 0; + return (u64)p; +} +static u64 __attribute__((ms_abi)) shim_free(u64 ptr) { (void)ptr; return 0; } +static u64 __attribute__((ms_abi)) shim_realloc(u64 ptr, u64 size) { + (void)ptr; return (u64)kmem_alloc(size); +} +static u64 __attribute__((ms_abi)) shim_exit(u64 code) { + pe_shim_exit_process(code); + return 0; +} + +static u64 __attribute__((ms_abi)) shim_memcpy(u64 dst, u64 src, u64 n) { + u8 *d = (u8 *)dst; const u8 *s = (const u8 *)src; + for (u64 i = 0; i < n; i++) d[i] = s[i]; + return dst; +} +static u64 __attribute__((ms_abi)) shim_memset(u64 dst, u64 val, u64 n) { + u8 *d = (u8 *)dst; u8 v = (u8)(val & 0xFF); + for (u64 i = 0; i < n; i++) d[i] = v; + return dst; +} +static u64 __attribute__((ms_abi)) shim_memmove(u64 dst, u64 src, u64 n) { + u8 *d = (u8 *)dst; const u8 *s = (const u8 *)src; + if (d < s) { for (u64 i = 0; i < n; i++) d[i] = s[i]; } + else { for (u64 i = n; i > 0; i--) d[i-1] = s[i-1]; } + return dst; +} +static u64 __attribute__((ms_abi)) shim_strlen(u64 str) { + const char *s = (const char *)str; + u64 n = 0; while (s[n]) n++; return n; +} +static u64 __attribute__((ms_abi)) shim_strcmp(u64 a, u64 b) { + const char *pa = (const char *)a; const char *pb = (const char *)b; + while (*pa && *pa == *pb) { pa++; pb++; } + return (u64)(i64)(*pa - *pb); +} +static u64 __attribute__((ms_abi)) shim_strcpy(u64 dst, u64 src) { + char *d = (char *)dst; const char *s = (const char *)src; + while (*s) *d++ = *s++; + *d = 0; + return dst; +} +static u64 __attribute__((ms_abi)) shim_strncmp(u64 a, u64 b, u64 n) { + const char *pa = (const char *)a; const char *pb = (const char *)b; + for (u64 i = 0; i < n; i++) { + if (pa[i] != pb[i]) return (u64)(i64)(pa[i] - pb[i]); + if (pa[i] == 0) return 0; + } + return 0; +} +static u64 __attribute__((ms_abi)) shim_fwrite(u64 ptr, u64 size, u64 nmemb, u64 stream) { + (void)stream; + u64 total = size * nmemb; + shim_output((const char *)ptr, total); + return nmemb; +} +static u64 __attribute__((ms_abi)) shim_fputs(u64 str, u64 stream) { + (void)stream; + shim_output_str((const char *)str); + return 0; +} +static u64 __attribute__((ms_abi)) shim_fputc(u64 ch, u64 stream) { + (void)stream; + serial_putc((char)(ch & 0xFF)); + return ch & 0xFF; +} +/* _initterm / _initterm_e — CRT 初始化,遍历函数指针表调用。 + * 简化:直接跳过(返回 0)。 */ +static u64 __attribute__((ms_abi)) shim_initterm(u64 start, u64 end) { + (void)start; (void)end; + return 0; +} +static u64 __attribute__((ms_abi)) shim_initterm_e(u64 start, u64 end) { + (void)start; (void)end; + return 0; +} + +/* 未实现 stub(64位)— 日志告警并返回 0 */ +static u64 __attribute__((ms_abi)) shim_unimpl64(u64 a0, u64 a1, u64 a2, u64 a3) { + (void)a0; (void)a1; (void)a2; (void)a3; + log_warn("[PE] unimplemented API called"); + return 0; +} + +/* 提供给 pe_shim.h 的地址获取函数 */ +u64 pe_shim_unimpl64_addr(void) { return (u64)shim_unimpl64; } +u64 pe_shim_exitprocess64_addr(void) { return (u64)shim_ExitProcess; } + +/* 获取退出码 */ +u64 pe_shim_get_exit_code(void) { return g_exit_code; } + +/* ===== shim 表 ===== */ +static const pe_shim_entry g_shim_table[] = { + /* kernel32.dll */ + {"kernel32.dll", "GetStdHandle", (void*)shim_GetStdHandle, 0}, + {"kernel32.dll", "WriteFile", (void*)shim_WriteFile, 0}, + {"kernel32.dll", "ReadFile", (void*)shim_ReadFile, 0}, + {"kernel32.dll", "ExitProcess", (void*)shim_ExitProcess, 0}, + {"kernel32.dll", "GetCommandLineA", (void*)shim_GetCommandLineA, 0}, + {"kernel32.dll", "GetCommandLineW", (void*)shim_GetCommandLineW, 0}, + {"kernel32.dll", "GetLastError", (void*)shim_GetLastError, 0}, + {"kernel32.dll", "SetLastError", (void*)shim_SetLastError, 0}, + {"kernel32.dll", "HeapCreate", (void*)shim_HeapCreate, 0}, + {"kernel32.dll", "HeapAlloc", (void*)shim_HeapAlloc, 0}, + {"kernel32.dll", "HeapFree", (void*)shim_HeapFree, 0}, + {"kernel32.dll", "VirtualAlloc", (void*)shim_VirtualAlloc, 0}, + {"kernel32.dll", "VirtualFree", (void*)shim_VirtualFree, 0}, + {"kernel32.dll", "GetModuleHandleA", (void*)shim_GetModuleHandleA, 0}, + {"kernel32.dll", "GetModuleHandleW", (void*)shim_GetModuleHandleW, 0}, + {"kernel32.dll", "GetEnvironmentVariableA",(void*)shim_GetEnvironmentVariableA, 0}, + {"kernel32.dll", "CreateFileA", (void*)shim_CreateFileA, 0}, + {"kernel32.dll", "CloseHandle", (void*)shim_CloseHandle, 0}, + {"kernel32.dll", "GetFileSize", (void*)shim_GetFileSize, 0}, + {"kernel32.dll", "SetFilePointer", (void*)shim_SetFilePointer, 0}, + /* msvcrt.dll */ + {"msvcrt.dll", "printf", (void*)shim_printf, 0}, + {"msvcrt.dll", "puts", (void*)shim_puts, 0}, + {"msvcrt.dll", "putchar", (void*)shim_putchar, 0}, + {"msvcrt.dll", "malloc", (void*)shim_malloc, 0}, + {"msvcrt.dll", "calloc", (void*)shim_calloc, 0}, + {"msvcrt.dll", "free", (void*)shim_free, 0}, + {"msvcrt.dll", "realloc", (void*)shim_realloc, 0}, + {"msvcrt.dll", "exit", (void*)shim_exit, 0}, + {"msvcrt.dll", "memcpy", (void*)shim_memcpy, 0}, + {"msvcrt.dll", "memset", (void*)shim_memset, 0}, + {"msvcrt.dll", "memmove", (void*)shim_memmove, 0}, + {"msvcrt.dll", "strlen", (void*)shim_strlen, 0}, + {"msvcrt.dll", "strcmp", (void*)shim_strcmp, 0}, + {"msvcrt.dll", "strcpy", (void*)shim_strcpy, 0}, + {"msvcrt.dll", "strncmp", (void*)shim_strncmp, 0}, + {"msvcrt.dll", "fwrite", (void*)shim_fwrite, 0}, + {"msvcrt.dll", "fputs", (void*)shim_fputs, 0}, + {"msvcrt.dll", "fputc", (void*)shim_fputc, 0}, + {"msvcrt.dll", "_initterm", (void*)shim_initterm, 0}, + {"msvcrt.dll", "_initterm_e", (void*)shim_initterm_e, 0}, +}; + +int pe_shim_lookup(const char *dll, const char *func) { + if (!dll || !func) return -1; + for (int i = 0; i < (int)(sizeof(g_shim_table)/sizeof(g_shim_table[0])); i++) { + /* 大小写不敏感比较 DLL 名 */ + const char *a = g_shim_table[i].dll; + const char *b = dll; + int match = 1; + while (*a && *b) { + char ca = *a, cb = *b; + if (ca >= 'A' && ca <= 'Z') ca += 32; + if (cb >= 'A' && cb <= 'Z') cb += 32; + if (ca != cb) { match = 0; break; } + a++; b++; + } + if (!match || *a != *b) continue; + /* 精确比较函数名 */ + const char *fa = g_shim_table[i].func; + const char *fb = func; + while (*fa && *fb) { if (*fa != *fb) break; fa++; fb++; } + if (*fa == *fb) return i; + } + return -1; +} + +const pe_shim_entry *pe_shim_get(int index) { + if (index < 0 || index >= (int)(sizeof(g_shim_table)/sizeof(g_shim_table[0]))) return 0; + return &g_shim_table[index]; +} + +int pe_shim_count(void) { + return (int)(sizeof(g_shim_table)/sizeof(g_shim_table[0])); +} diff --git a/CODE/UTSM/pe/pe_shim.h b/CODE/UTSM/pe/pe_shim.h new file mode 100644 index 0000000..3c5ae9b --- /dev/null +++ b/CODE/UTSM/pe/pe_shim.h @@ -0,0 +1,65 @@ +#ifndef PE_SHIM_H +#define PE_SHIM_H + +/* pe_shim.h — Windows API shim 表。 + * + * 将常见 Windows DLL 函数映射到 Deshab 等价实现: + * kernel32.dll!WriteFile → 写串口 + 帧缓冲 + * kernel32.dll!HeapAlloc → kmem_alloc + * msvcrt.dll!printf → 串口输出 + * ... + * + * 64位 PE:shim 用 __attribute__((ms_abi)) 声明,PE 代码以 MS x64 ABI 调用, + * IAT 直接填 shim 函数地址,原生执行。 + * 32位 PE:解释器在 CALL IAT 时拦截,从模拟栈读参数调用 fn32,结果写 EAX。 + */ + +#include + +/* 32位 shim:从模拟栈读取参数(cdecl 语义,调用者清栈)。 + * esp 指向模拟栈(第一个参数在 esp[0])。返回值 = EAX。 */ +typedef u64 (*pe_shim_fn32)(void *esp); + +/* shim 表条目 */ +typedef struct pe_shim_entry { + const char *dll; /* 小写 DLL 名,如 "kernel32.dll" */ + const char *func; /* 函数名,如 "WriteFile" */ + void *fn64; /* 64位 ms_abi 函数地址(可为 NULL) */ + pe_shim_fn32 fn32; /* 32位实现(可为 NULL) */ +} pe_shim_entry; + +/* 按 dll+func 名查找 shim。返回表索引,-1 未找到。 */ +int pe_shim_lookup(const char *dll, const char *func); + +/* 获取 shim 表条目 */ +const pe_shim_entry *pe_shim_get(int index); + +/* 获取 shim 表大小 */ +int pe_shim_count(void); + +/* 生成一个唯一的"未实现 stub"地址。 + * 64位:返回一个固定 stub 函数地址,被调用时日志告警并返回 0。 + * 32位:返回一个特殊标记值,解释器识别后日志告警。 */ +u64 pe_shim_unimpl_stub(void); + +/* 初始化 shim 子系统(注册全局状态,如 cmdline) */ +void pe_shim_init(const char *cmdline); + +/* ExitProcess 实现:通过 __builtin_longjmp 跳回 pe_run。 + * 64位和32位共用。exit_code = 进程退出码。 */ +void pe_shim_exit_process(u64 exit_code); + +/* pe_run 调用:保存上下文(__builtin_setjmp)。 + * 返回 0 = 首次(继续执行 PE),1 = ExitProcess 触发(longjmp 回来)。 */ +int pe_shim_setup_exit(void); + +/* 获取上次 ExitProcess 的退出码 */ +u64 pe_shim_get_exit_code(void); + +/* 判断地址是否为 ExitProcess shim(解释器用) */ +int pe_shim_is_exit_call(u64 target); + +/* 获取 cmdline(shim 内部用) */ +const char *pe_shim_get_cmdline(void); + +#endif /* PE_SHIM_H */ diff --git a/CODE/UTSM/pe/x86emu32.c b/CODE/UTSM/pe/x86emu32.c new file mode 100644 index 0000000..2e7ec93 --- /dev/null +++ b/CODE/UTSM/pe/x86emu32.c @@ -0,0 +1,975 @@ +/* x86emu32.c — x86-32 指令解释器(PE32 执行引擎)。 + * + * 寄存器级解释执行 32位 PE 代码。覆盖 mingw-w64 -O0/-O1 控制台程序常用指令: + * ALU(ADD/OR/ADC/SBB/AND/SUB/XOR/CMP)、MOV(全形式)、PUSH/POP、 + * INC/DEC/NEG/NOT、MUL/IMUL/DIV/IDIV、移位/旋转、LEA、XCHG、MOVSX/MOVZX、 + * JMP/Jcc/CALL/RET/LOOP、字符串指令(+REP)、ENTER/LEAVE、INT(shim 调度)。 + * + * 遇不支持指令时设置 error 并停止。 + */ + +#include "x86emu32.h" +#include "pe_shim.h" +#include +#include + +/* ===== 内存访问(带边界检查) ===== */ +u8 x86emu32_read8(x86emu_state *emu, u32 addr) { + if (addr >= emu->mem_size) { emu->error = 1; emu->error_msg = "read8 OOB"; return 0; } + return emu->mem[addr]; +} +u16 x86emu32_read16(x86emu_state *emu, u32 addr) { + if (addr + 1 >= emu->mem_size) { emu->error = 1; emu->error_msg = "read16 OOB"; return 0; } + return (u16)emu->mem[addr] | ((u16)emu->mem[addr+1] << 8); +} +u32 x86emu32_read32(x86emu_state *emu, u32 addr) { + if (addr + 3 >= emu->mem_size) { emu->error = 1; emu->error_msg = "read32 OOB"; return 0; } + return (u32)emu->mem[addr] | ((u32)emu->mem[addr+1] << 8) | + ((u32)emu->mem[addr+2] << 16) | ((u32)emu->mem[addr+3] << 24); +} +void x86emu32_write8(x86emu_state *emu, u32 addr, u8 val) { + if (addr >= emu->mem_size) { emu->error = 1; emu->error_msg = "write8 OOB"; return; } + emu->mem[addr] = val; +} +void x86emu32_write16(x86emu_state *emu, u32 addr, u16 val) { + if (addr + 1 >= emu->mem_size) { emu->error = 1; emu->error_msg = "write16 OOB"; return; } + emu->mem[addr] = (u8)(val & 0xFF); + emu->mem[addr+1] = (u8)((val >> 8) & 0xFF); +} +void x86emu32_write32(x86emu_state *emu, u32 addr, u32 val) { + if (addr + 3 >= emu->mem_size) { emu->error = 1; emu->error_msg = "write32 OOB"; return; } + emu->mem[addr] = (u8)(val & 0xFF); + emu->mem[addr+1] = (u8)((val >> 8) & 0xFF); + emu->mem[addr+2] = (u8)((val >> 16) & 0xFF); + emu->mem[addr+3] = (u8)((val >> 24) & 0xFF); +} + +/* ===== 栈操作 ===== */ +void x86emu32_push32(x86emu_state *emu, u32 val) { + emu->regs[X86_ESP] -= 4; + x86emu32_write32(emu, emu->regs[X86_ESP], val); +} +u32 x86emu32_pop32(x86emu_state *emu) { + u32 val = x86emu32_read32(emu, emu->regs[X86_ESP]); + emu->regs[X86_ESP] += 4; + return val; +} + +u64 x86emu32_read_arg(x86emu_state *emu, int esp_offset) { + return x86emu32_read32(emu, emu->regs[X86_ESP] + (u32)esp_offset * 4); +} + +/* ===== 寄存器访问 ===== */ +/* 32位寄存器名:EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI(对应 0-7) */ +/* 8位寄存器映射:AL,CL,DL,BL,AH,CH,DH,BH(0-3 = 低8位, 4-7 = 高8位) */ +static u8 get_reg8(x86emu_state *emu, int idx) { + if (idx < 4) return (u8)(emu->regs[idx] & 0xFF); + return (u8)((emu->regs[idx - 4] >> 8) & 0xFF); +} +static void set_reg8(x86emu_state *emu, int idx, u8 val) { + if (idx < 4) { + emu->regs[idx] = (emu->regs[idx] & 0xFFFFFF00) | val; + } else { + emu->regs[idx - 4] = (emu->regs[idx - 4] & 0xFFFF00FF) | ((u32)val << 8); + } +} +static u16 get_reg16(x86emu_state *emu, int idx) { + return (u16)(emu->regs[idx] & 0xFFFF); +} +static void set_reg16(x86emu_state *emu, int idx, u16 val) { + emu->regs[idx] = (emu->regs[idx] & 0xFFFF0000) | val; +} +static u32 get_reg32(x86emu_state *emu, int idx) { return emu->regs[idx]; } +static void set_reg32(x86emu_state *emu, int idx, u32 val) { emu->regs[idx] = val; } + +/* ===== EFLAGS 辅助 ===== */ +static void set_flag(x86emu_state *emu, u32 mask, int on) { + if (on) emu->eflags |= mask; else emu->eflags &= ~mask; +} +static int get_flag(x86emu_state *emu, u32 mask) { return (emu->eflags & mask) ? 1 : 0; } + +static u8 parity8(u8 v) { + v ^= v >> 4; v ^= v >> 2; v ^= v >> 1; + return (v & 1) == 0; +} + +static void set_zf_sf_pf(x86emu_state *emu, u32 result, int size) { + u32 mask = (size == 1) ? 0xFF : (size == 2) ? 0xFFFF : 0xFFFFFFFF; + result &= mask; + set_flag(emu, X86_ZF, result == 0); + if (size == 1) set_flag(emu, X86_SF, (result & 0x80) != 0); + else if (size == 2) set_flag(emu, X86_SF, (result & 0x8000) != 0); + else set_flag(emu, X86_SF, (result & 0x80000000) != 0); + set_flag(emu, X86_PF, parity8((u8)result)); +} + +static void set_cf_add(x86emu_state *emu, u32 a, u32 b, int size) { + u32 mask = (size == 1) ? 0xFF : (size == 2) ? 0xFFFF : 0xFFFFFFFF; + set_flag(emu, X86_CF, ((u64)(a & mask) + (u64)(b & mask)) > mask); +} +static void set_cf_sub(x86emu_state *emu, u32 a, u32 b, int size) { + u32 mask = (size == 1) ? 0xFF : (size == 2) ? 0xFFFF : 0xFFFFFFFF; + set_flag(emu, X86_CF, (a & mask) < (b & mask)); +} +static void set_of_add(x86emu_state *emu, u32 a, u32 b, u32 r, int size) { + u32 sign = (size == 1) ? 0x80 : (size == 2) ? 0x8000 : 0x80000000; + set_flag(emu, X86_OF, (~(a ^ b) & (a ^ r) & sign) != 0); +} +static void set_of_sub(x86emu_state *emu, u32 a, u32 b, u32 r, int size) { + u32 sign = (size == 1) ? 0x80 : (size == 2) ? 0x8000 : 0x80000000; + set_flag(emu, X86_OF, ((a ^ b) & (a ^ r) & sign) != 0); +} + +/* ===== 指令取 ===== */ +static u8 fetch8(x86emu_state *emu) { + u8 v = x86emu32_read8(emu, emu->eip); + emu->eip++; + return v; +} +static u16 fetch16(x86emu_state *emu) { + u16 v = x86emu32_read16(emu, emu->eip); + emu->eip += 2; + return v; +} +static u32 fetch32(x86emu_state *emu) { + u32 v = x86emu32_read32(emu, emu->eip); + emu->eip += 4; + return v; +} + +/* ===== ModR/M 解码 ===== */ +typedef struct { + int mod; + int reg; /* reg 字段(也可作 opcode 扩展) */ + int rm; /* rm 字段 */ + u32 ea; /* 有效地址(若 mod != 3) */ + int has_ea; /* 是否有内存操作数 */ +} modrm_dec; + +static modrm_dec decode_modrm(x86emu_state *emu) { + modrm_dec m; + u8 b = fetch8(emu); + m.mod = (b >> 6) & 3; + m.reg = (b >> 3) & 7; + m.rm = b & 7; + m.has_ea = 0; + m.ea = 0; + + if (m.mod == 3) return m; /* 寄存器直接寻址 */ + + m.has_ea = 1; + u32 base = 0; + int has_sib = (m.rm == 4); + + if (has_sib) { + u8 sib = fetch8(emu); + int scale = 1 << ((sib >> 6) & 3); + int index = (sib >> 3) & 7; + int base_reg = sib & 7; + base = emu->regs[base_reg]; + if (index != 4) { /* ESP 不作 index */ + base += emu->regs[index] * (u32)scale; + } + } else { + base = emu->regs[m.rm]; + } + + /* disp */ + if (m.mod == 0) { + if (!has_sib && m.rm == 5) { + /* disp32 直接地址 */ + base = fetch32(emu); + } + } else if (m.mod == 1) { + base += (u32)(i32)(i8)fetch8(emu); /* disp8 符号扩展 */ + } else { /* mod == 2 */ + base += fetch32(emu); + } + + m.ea = base; + return m; +} + +/* 读/写 modr/m 操作数 */ +static u32 read_rm32(x86emu_state *emu, const modrm_dec *m) { + if (m->mod == 3) return get_reg32(emu, m->rm); + return x86emu32_read32(emu, m->ea); +} +static void write_rm32(x86emu_state *emu, const modrm_dec *m, u32 val) { + if (m->mod == 3) set_reg32(emu, m->rm, val); + else x86emu32_write32(emu, m->ea, val); +} +static u8 read_rm8(x86emu_state *emu, const modrm_dec *m) { + if (m->mod == 3) return get_reg8(emu, m->rm); + return x86emu32_read8(emu, m->ea); +} +static void write_rm8(x86emu_state *emu, const modrm_dec *m, u8 val) { + if (m->mod == 3) set_reg8(emu, m->rm, val); + else x86emu32_write8(emu, m->ea, val); +} +static u16 read_rm16(x86emu_state *emu, const modrm_dec *m) { + if (m->mod == 3) return get_reg16(emu, m->rm); + return x86emu32_read16(emu, m->ea); +} +static void write_rm16(x86emu_state *emu, const modrm_dec *m, u16 val) { + if (m->mod == 3) set_reg16(emu, m->rm, val); + else x86emu32_write16(emu, m->ea, val); +} + +/* ===== ALU 操作(按 op 索引:0=ADD 1=OR 2=ADC 3=SBB 4=AND 5=SUB 6=XOR 7=CMP) ===== */ +static u32 alu_op(x86emu_state *emu, int op, u32 a, u32 b, int size) { + u32 r = 0; + u32 mask = (size == 1) ? 0xFF : (size == 2) ? 0xFFFF : 0xFFFFFFFF; + a &= mask; b &= mask; + switch (op) { + case 0: r = a + b; set_cf_add(emu, a, b, size); set_of_add(emu, a, b, r, size); set_zf_sf_pf(emu, r, size); break; + case 1: r = a | b; set_flag(emu, X86_CF, 0); set_flag(emu, X86_OF, 0); set_zf_sf_pf(emu, r, size); break; + case 2: { int cf = get_flag(emu, X86_CF); r = a + b + cf; set_cf_add(emu, a + cf, b, size); set_of_add(emu, a, b, r, size); set_zf_sf_pf(emu, r, size); break; } + case 3: { int cf = get_flag(emu, X86_CF); r = a - b - cf; set_cf_sub(emu, a - cf, b, size); set_of_sub(emu, a, b, r, size); set_zf_sf_pf(emu, r, size); break; } + case 4: r = a & b; set_flag(emu, X86_CF, 0); set_flag(emu, X86_OF, 0); set_zf_sf_pf(emu, r, size); break; + case 5: r = a - b; set_cf_sub(emu, a, b, size); set_of_sub(emu, a, b, r, size); set_zf_sf_pf(emu, r, size); break; + case 6: r = a ^ b; set_flag(emu, X86_CF, 0); set_flag(emu, X86_OF, 0); set_zf_sf_pf(emu, r, size); break; + case 7: r = a - b; set_cf_sub(emu, a, b, size); set_of_sub(emu, a, b, r, size); set_zf_sf_pf(emu, r, size); break; /* CMP 不写回 */ + } + return r & mask; +} + +/* ===== 移位操作(按 op:ROL/ROR/RCL/RCR/SHL/SHR/SAR/SAL) ===== */ +static u32 shift_op(x86emu_state *emu, int op, u32 val, u8 count, int size) { + u32 mask = (size == 1) ? 0xFF : (size == 2) ? 0xFFFF : 0xFFFFFFFF; + val &= mask; + count &= 0x1F; + if (count == 0) return val; + u32 r = val; + switch (op) { + case 4: case 6: /* SHL / SAL */ + r = val << count; + set_flag(emu, X86_CF, (val >> (32 - count)) & 1); + break; + case 5: /* SHR */ + r = val >> count; + set_flag(emu, X86_CF, (val >> (count - 1)) & 1); + break; + case 7: /* SAR */ + r = (u32)((i32)val >> count); + set_flag(emu, X86_CF, (val >> (count - 1)) & 1); + break; + case 0: /* ROL */ + r = ((val << count) | (val >> (size * 8 - count))) & mask; + set_flag(emu, X86_CF, r & 1); + break; + case 1: /* ROR */ + r = ((val >> count) | (val << (size * 8 - count))) & mask; + set_flag(emu, X86_CF, (r >> (size * 8 - 1)) & 1); + break; + default: break; /* RCL/RCR 暂简化 */ + } + if (op >= 4) set_zf_sf_pf(emu, r, size); /* SHL/SHR/SAR 影响 ZF/SF/PF */ + return r & mask; +} + +/* ===== IAT CALL 拦截 ===== */ +/* stdcall 参数个数表(kernel32.dll 函数:callee 清栈)。 + * msvcrt.dll 函数为 cdecl(caller 清栈),不在此表。 + * key = shim 函数名首字符 + 长度组合的简单 hash,避免 strcmp。 + * 简化:直接用函数指针地址查表。 */ +static int try_iat_call(x86emu_state *emu, u32 target) { + /* 检查是否为合成 shim 地址 */ + if (target >= 0x00010000 && target < 0x00020000) { + int shim_idx = target & 0xFFFF; + if (shim_idx == 0xFFFF) { + /* 未实现 stub */ + log_warn("[PE32] call unimplemented API"); + emu->regs[X86_EAX] = 0; + return 1; + } + const pe_shim_entry *se = pe_shim_get(shim_idx); + if (!se) { + log_warn("[PE32] shim index out of range"); + emu->regs[X86_EAX] = 0; + return 1; + } + + /* 从模拟栈读参数。CALL 被拦截前未 push 返回地址, + * 所以 ESP 指向第一个参数。 */ + u32 esp_val = emu->regs[X86_ESP]; + if (esp_val + 32 > emu->mem_size) { + emu->error = 1; + emu->error_msg = "shim esp OOB"; + return 1; + } + u64 a0 = x86emu32_read32(emu, esp_val); + u64 a1 = x86emu32_read32(emu, esp_val + 4); + u64 a2 = x86emu32_read32(emu, esp_val + 8); + u64 a3 = x86emu32_read32(emu, esp_val + 12); + + u64 ret; + if (se->fn32) { + /* 有专用 32位实现 */ + void *esp_ptr = &emu->mem[esp_val]; + ret = se->fn32(esp_ptr); + } else if (se->fn64) { + /* 回退:调用 64位 shim(最多 4 个参数)。 + * MS x64 ABI 由 C 编译器处理寄存器分配。 */ + typedef u64 (*fn4_t)(u64, u64, u64, u64); + fn4_t f = (fn4_t)se->fn64; + ret = f(a0, a1, a2, a3); + + /* stdcall 清栈:kernel32.dll 函数 callee 清栈。 + * 简化:按已知参数个数调整 ESP。 + * msvcrt.dll (cdecl) 不清栈。 */ + if (se->dll[0] == 'k') { /* kernel32.dll */ + int nargs = 4; /* 默认假设 4 参数 */ + /* 按函数名精化参数个数 */ + const char *fn = se->func; + if (fn[0]=='G' && fn[1]=='e' && fn[2]=='t' && fn[3]=='S') nargs = 1; + else if (fn[0]=='W' && fn[1]=='r' && fn[2]=='i') nargs = 5; + else if (fn[0]=='R' && fn[1]=='e' && fn[2]=='a' && fn[3]=='d') nargs = 5; + else if (fn[0]=='E' && fn[1]=='x' && fn[2]=='i' && fn[3]=='t') nargs = 1; + else if (fn[0]=='G' && fn[1]=='e' && fn[2]=='t' && fn[3]=='C') nargs = 0; + else if (fn[0]=='G' && fn[1]=='e' && fn[2]=='t' && fn[3]=='L') nargs = 0; + else if (fn[0]=='S' && fn[1]=='e' && fn[2]=='t' && fn[3]=='L') nargs = 1; + else if (fn[0]=='H' && fn[1]=='e' && fn[2]=='a' && fn[3]=='p') nargs = 3; + else if (fn[0]=='V' && fn[1]=='i' && fn[2]=='r') nargs = 4; + else if (fn[0]=='G' && fn[1]=='e' && fn[2]=='t' && fn[3]=='M') nargs = 1; + else if (fn[0]=='C' && fn[1]=='l' && fn[2]=='o') nargs = 1; + else if (fn[0]=='C' && fn[1]=='r' && fn[2]=='e') nargs = 7; + emu->regs[X86_ESP] += (u32)(nargs * 4); + } + } else { + log_warn("[PE32] no shim impl"); + ret = 0; + } + emu->regs[X86_EAX] = (u32)ret; + return 1; + } + /* 检查是否为 ExitProcess 特殊地址(64位 ExitProcess shim) */ + if (pe_shim_is_exit_call((u64)target)) { + pe_shim_exit_process(emu->regs[X86_EAX] ? emu->regs[X86_EAX] : 0); + emu->exited = 1; + return 1; + } + return 0; /* 不是 IAT/shim 调用 */ +} + +/* ===== 条件跳转判断 ===== */ +static int check_jcc(x86emu_state *emu, int cond) { + int zf = get_flag(emu, X86_ZF); + int sf = get_flag(emu, X86_SF); + int of = get_flag(emu, X86_OF); + int cf = get_flag(emu, X86_CF); + int pf = get_flag(emu, X86_PF); + switch (cond & 0xF) { + case 0x0: return of; + case 0x1: return !of; + case 0x2: return cf; + case 0x3: return !cf; + case 0x4: return zf; + case 0x5: return !zf; + case 0x6: return cf || zf; + case 0x7: return !cf && !zf; + case 0x8: return sf; + case 0x9: return !sf; + case 0xA: return pf; + case 0xB: return !pf; + case 0xC: return sf != of; + case 0xD: return sf == of; + case 0xE: return zf || (sf != of); + case 0xF: return !zf && (sf == of); + } + return 0; +} + +/* ===== 主执行循环 ===== */ +int x86emu32_run(x86emu_state *emu, u64 *exit_code) { + emu->insn_limit = 500000000ULL; /* 5亿指令上限防死循环 */ + + while (!emu->exited && !emu->error && emu->insn_count < emu->insn_limit) { + emu->insn_count++; + + /* 前缀处理 */ + int operand_size = 4; /* 默认 32位 */ + int rep_prefix = 0; /* 0=无, 1=REP/REPE, 2=REPNE(记录但暂未用于字符串指令) */ + u8 op; + int prefix_done = 0; + while (!prefix_done) { + op = fetch8(emu); + switch (op) { + case 0x66: operand_size = 2; break; + case 0x67: break; /* 地址大小前缀(忽略,32位寻址) */ + case 0xF0: break; /* LOCK */ + case 0xF2: rep_prefix = 2; break; /* REPNE */ + case 0xF3: rep_prefix = 1; break; /* REP/REPE */ + case 0x26: case 0x2E: case 0x36: case 0x3E: case 0x64: case 0x65: break; /* 段前缀忽略 */ + default: prefix_done = 1; break; + } + } + (void)rep_prefix; /* 记录前缀,字符串指令暂未使用 */ + + /* 操作数大小:对 0x66 前缀,32位操作变 16位 */ + int osz = operand_size; /* 4 或 2 */ + + switch (op) { + /* ---- ALU modr/m(0x00-0x3F)---- */ + case 0x00: case 0x01: case 0x02: case 0x03: + case 0x08: case 0x09: case 0x0A: case 0x0B: + case 0x10: case 0x11: case 0x12: case 0x13: + case 0x18: case 0x19: case 0x1A: case 0x1B: + case 0x20: case 0x21: case 0x22: case 0x23: + case 0x28: case 0x29: case 0x2A: case 0x2B: + case 0x30: case 0x31: case 0x32: case 0x33: + case 0x38: case 0x39: case 0x3A: case 0x3B: { + int alu = (op >> 3) & 7; + int dir = op & 1; /* 0: r/m8←r8, 1: r/m32←r32 (或反向) */ + int is8 = !(op & 4); /* 0x00-0x03=8位, 0x04+ =32位 */ + modrm_dec m = decode_modrm(emu); + if (is8) { + u8 a, b; int cmp_only = (alu == 7); + if (dir == 0) { a = read_rm8(emu, &m); b = get_reg8(emu, m.reg); } + else { a = get_reg8(emu, m.reg); b = read_rm8(emu, &m); } + u8 r = (u8)alu_op(emu, alu, a, b, 1); + if (alu != 7) { if (dir == 0) write_rm8(emu, &m, r); else set_reg8(emu, m.reg, r); } + (void)cmp_only; + } else { + u32 a, b; + if (dir == 0) { a = read_rm32(emu, &m); b = get_reg32(emu, m.reg); } + else { a = get_reg32(emu, m.reg); b = read_rm32(emu, &m); } + u32 r = alu_op(emu, alu, a, b, osz); + if (alu != 7) { if (dir == 0) write_rm32(emu, &m, r); else set_reg32(emu, m.reg, r); } + if (osz == 2) { if (alu != 7) { if (dir == 0) write_rm16(emu, &m, (u16)r); else set_reg16(emu, m.reg, (u16)r); } } + } + break; + } + /* ---- ALU AL/EAX, imm ---- */ + case 0x04: case 0x0C: case 0x14: case 0x1C: + case 0x24: case 0x2C: case 0x34: case 0x3C: { + int alu = (op >> 3) & 7; + u8 imm = fetch8(emu); + u8 r = (u8)alu_op(emu, alu, get_reg8(emu, 0), imm, 1); + if (alu != 7) set_reg8(emu, 0, r); + break; + } + case 0x05: case 0x0D: case 0x15: case 0x1D: + case 0x25: case 0x2D: case 0x35: case 0x3D: { + int alu = (op >> 3) & 7; + if (osz == 2) { + u16 imm = fetch16(emu); + u16 r = (u16)alu_op(emu, alu, get_reg16(emu, 0), imm, 2); + if (alu != 7) set_reg16(emu, 0, r); + } else { + u32 imm = fetch32(emu); + u32 r = alu_op(emu, alu, get_reg32(emu, 0), imm, 4); + if (alu != 7) set_reg32(emu, 0, r); + } + break; + } + /* ---- INC/DEC reg(0x40-0x4F)---- */ + case 0x40: case 0x41: case 0x42: case 0x43: + case 0x44: case 0x45: case 0x46: case 0x47: { + int r = op - 0x40; + int cf = get_flag(emu, X86_CF); + if (osz == 2) { u16 v = get_reg16(emu, r); u16 res = (u16)alu_op(emu, 0, v, 1, 2); set_reg16(emu, r, res); } + else { u32 v = get_reg32(emu, r); u32 res = alu_op(emu, 0, v, 1, 4); set_reg32(emu, r, res); } + set_flag(emu, X86_CF, cf); /* INC 不影响 CF */ + break; + } + case 0x48: case 0x49: case 0x4A: case 0x4B: + case 0x4C: case 0x4D: case 0x4E: case 0x4F: { + int r = op - 0x48; + int cf = get_flag(emu, X86_CF); + if (osz == 2) { u16 v = get_reg16(emu, r); u16 res = (u16)alu_op(emu, 5, v, 1, 2); set_reg16(emu, r, res); } + else { u32 v = get_reg32(emu, r); u32 res = alu_op(emu, 5, v, 1, 4); set_reg32(emu, r, res); } + set_flag(emu, X86_CF, cf); + break; + } + /* ---- PUSH/POP reg ---- */ + case 0x50: case 0x51: case 0x52: case 0x53: + case 0x54: case 0x55: case 0x56: case 0x57: + x86emu32_push32(emu, get_reg32(emu, op - 0x50)); + break; + case 0x58: case 0x59: case 0x5A: case 0x5B: + case 0x5C: case 0x5D: case 0x5E: case 0x5F: + set_reg32(emu, op - 0x58, x86emu32_pop32(emu)); + break; + /* ---- PUSHA/POPA ---- */ + case 0x60: { + u32 sp = emu->regs[X86_ESP]; + x86emu32_push32(emu, emu->regs[X86_EAX]); + x86emu32_push32(emu, emu->regs[X86_ECX]); + x86emu32_push32(emu, emu->regs[X86_EDX]); + x86emu32_push32(emu, emu->regs[X86_EBX]); + x86emu32_push32(emu, sp); + x86emu32_push32(emu, emu->regs[X86_EBP]); + x86emu32_push32(emu, emu->regs[X86_ESI]); + x86emu32_push32(emu, emu->regs[X86_EDI]); + break; + } + case 0x61: { + emu->regs[X86_EDI] = x86emu32_pop32(emu); + emu->regs[X86_ESI] = x86emu32_pop32(emu); + emu->regs[X86_EBP] = x86emu32_pop32(emu); + x86emu32_pop32(emu); /* 忽略原始 ESP */ + emu->regs[X86_EBX] = x86emu32_pop32(emu); + emu->regs[X86_EDX] = x86emu32_pop32(emu); + emu->regs[X86_ECX] = x86emu32_pop32(emu); + emu->regs[X86_EAX] = x86emu32_pop32(emu); + break; + } + /* ---- PUSH imm ---- */ + case 0x68: x86emu32_push32(emu, fetch32(emu)); break; + case 0x6A: x86emu32_push32(emu, (u32)(i32)(i8)fetch8(emu)); break; + /* ---- IMUL r, r/m, imm ---- */ + case 0x69: case 0x6B: { + modrm_dec m = decode_modrm(emu); + u32 src = read_rm32(emu, &m); + u32 imm = (op == 0x69) ? fetch32(emu) : (u32)(i32)(i8)fetch8(emu); + i64 result = (i64)(i32)src * (i64)(i32)imm; + set_reg32(emu, m.reg, (u32)result); + set_flag(emu, X86_OF, result > 0x7FFFFFFFLL || result < -0x80000000LL); + set_flag(emu, X86_CF, get_flag(emu, X86_OF)); + break; + } + /* ---- Jcc rel8 ---- */ + case 0x70: case 0x71: case 0x72: case 0x73: + case 0x74: case 0x75: case 0x76: case 0x77: + case 0x78: case 0x79: case 0x7A: case 0x7B: + case 0x7C: case 0x7D: case 0x7E: case 0x7F: { + i8 rel = (i8)fetch8(emu); + if (check_jcc(emu, op & 0xF)) emu->eip += (u32)(i32)rel; + break; + } + /* ---- ALU r/m, imm8 (0x80/0x82) / r/m, imm32 (0x81) ---- */ + case 0x80: case 0x82: { + modrm_dec m = decode_modrm(emu); + u8 imm = fetch8(emu); + u8 a = read_rm8(emu, &m); + u8 r = (u8)alu_op(emu, m.reg, a, imm, 1); + if (m.reg != 7) write_rm8(emu, &m, r); + break; + } + case 0x81: { + modrm_dec m = decode_modrm(emu); + if (osz == 2) { + u16 imm = fetch16(emu); + u16 a = read_rm16(emu, &m); + u16 r = (u16)alu_op(emu, m.reg, a, imm, 2); + if (m.reg != 7) write_rm16(emu, &m, r); + } else { + u32 imm = fetch32(emu); + u32 a = read_rm32(emu, &m); + u32 r = alu_op(emu, m.reg, a, imm, 4); + if (m.reg != 7) write_rm32(emu, &m, r); + } + break; + } + case 0x83: { + modrm_dec m = decode_modrm(emu); + u32 imm = (u32)(i32)(i8)fetch8(emu); + if (osz == 2) { + u16 a = read_rm16(emu, &m); + u16 r = (u16)alu_op(emu, m.reg, a, imm & 0xFFFF, 2); + if (m.reg != 7) write_rm16(emu, &m, r); + } else { + u32 a = read_rm32(emu, &m); + u32 r = alu_op(emu, m.reg, a, imm, 4); + if (m.reg != 7) write_rm32(emu, &m, r); + } + break; + } + /* ---- TEST ---- */ + case 0x84: case 0x85: { + modrm_dec m = decode_modrm(emu); + if (op == 0x84) { + u8 a = read_rm8(emu, &m); u8 b = get_reg8(emu, m.reg); + alu_op(emu, 4, a, b, 1); /* AND 不写回 */ + } else if (osz == 2) { + u16 a = read_rm16(emu, &m); u16 b = get_reg16(emu, m.reg); + alu_op(emu, 4, a, b, 2); + } else { + u32 a = read_rm32(emu, &m); u32 b = get_reg32(emu, m.reg); + alu_op(emu, 4, a, b, 4); + } + break; + } + /* ---- XCHG ---- */ + case 0x86: case 0x87: { + modrm_dec m = decode_modrm(emu); + if (op == 0x86) { + u8 a = read_rm8(emu, &m); u8 b = get_reg8(emu, m.reg); + write_rm8(emu, &m, b); set_reg8(emu, m.reg, a); + } else if (osz == 2) { + u16 a = read_rm16(emu, &m); u16 b = get_reg16(emu, m.reg); + write_rm16(emu, &m, b); set_reg16(emu, m.reg, a); + } else { + u32 a = read_rm32(emu, &m); u32 b = get_reg32(emu, m.reg); + write_rm32(emu, &m, b); set_reg32(emu, m.reg, a); + } + break; + } + /* ---- MOV ---- */ + case 0x88: { modrm_dec m = decode_modrm(emu); write_rm8(emu, &m, get_reg8(emu, m.reg)); break; } + case 0x89: { + modrm_dec m = decode_modrm(emu); + if (osz == 2) write_rm16(emu, &m, get_reg16(emu, m.reg)); + else write_rm32(emu, &m, get_reg32(emu, m.reg)); + break; + } + case 0x8A: { modrm_dec m = decode_modrm(emu); set_reg8(emu, m.reg, read_rm8(emu, &m)); break; } + case 0x8B: { + modrm_dec m = decode_modrm(emu); + if (osz == 2) set_reg16(emu, m.reg, read_rm16(emu, &m)); + else set_reg32(emu, m.reg, read_rm32(emu, &m)); + break; + } + /* ---- LEA ---- */ + case 0x8D: { + modrm_dec m = decode_modrm(emu); + if (osz == 2) set_reg16(emu, m.reg, (u16)m.ea); + else set_reg32(emu, m.reg, m.ea); + break; + } + /* ---- NOP / XCHG EAX,reg ---- */ + case 0x90: break; /* NOP */ + case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97: { + int r = op - 0x90; + u32 tmp = emu->regs[0]; emu->regs[0] = emu->regs[r]; emu->regs[r] = tmp; + break; + } + /* ---- CWDE/CDQ ---- */ + case 0x98: /* CWDE (32位) / CBW (16位) */ + if (osz == 2) set_reg16(emu, 0, (u16)(i16)(i8)get_reg8(emu, 0)); + else emu->regs[0] = (u32)(i32)(i16)get_reg16(emu, 0); + break; + case 0x99: /* CDQ (32位) / CWD (16位) */ + if (osz == 2) set_reg16(emu, 2, (get_reg16(emu, 0) & 0x8000) ? 0xFFFF : 0); + else emu->regs[2] = (emu->regs[0] & 0x80000000) ? 0xFFFFFFFF : 0; + break; + /* ---- MOV moffs ---- */ + case 0xA0: { u32 addr = fetch32(emu); set_reg8(emu, 0, x86emu32_read8(emu, addr)); break; } + case 0xA1: { u32 addr = fetch32(emu); if (osz==2) set_reg16(emu,0,x86emu32_read16(emu,addr)); else set_reg32(emu,0,x86emu32_read32(emu,addr)); break; } + case 0xA2: { u32 addr = fetch32(emu); x86emu32_write8(emu, addr, get_reg8(emu, 0)); break; } + case 0xA3: { u32 addr = fetch32(emu); if (osz==2) x86emu32_write16(emu,addr,get_reg16(emu,0)); else x86emu32_write32(emu,addr,get_reg32(emu,0)); break; } + /* ---- 字符串指令(简化:无 REP 单步)---- */ + case 0xA4: { /* MOVSB */ + u32 si = emu->regs[X86_ESI], di = emu->regs[X86_EDI]; + u8 v = x86emu32_read8(emu, si); + x86emu32_write8(emu, di, v); + int df = get_flag(emu, X86_DF); + si += df ? -1 : 1; di += df ? -1 : 1; + emu->regs[X86_ESI] = si; emu->regs[X86_EDI] = di; + break; + } + case 0xA5: { /* MOVSD/W */ + u32 si = emu->regs[X86_ESI], di = emu->regs[X86_EDI]; + int df = get_flag(emu, X86_DF); int step = (osz==2)?2:4; + if (osz==2) { u16 v=x86emu32_read16(emu,si); x86emu32_write16(emu,di,v); } + else { u32 v=x86emu32_read32(emu,si); x86emu32_write32(emu,di,v); } + si += df ? -step : step; di += df ? -step : step; + emu->regs[X86_ESI]=si; emu->regs[X86_EDI]=di; + break; + } + case 0xAA: { /* STOSB */ + u32 di = emu->regs[X86_EDI]; + x86emu32_write8(emu, di, get_reg8(emu, 0)); + int df = get_flag(emu, X86_DF); + di += df ? -1 : 1; emu->regs[X86_EDI] = di; + break; + } + case 0xAB: { /* STOSD/W */ + u32 di = emu->regs[X86_EDI]; int df = get_flag(emu, X86_DF); int step=(osz==2)?2:4; + if (osz==2) x86emu32_write16(emu,di,get_reg16(emu,0)); + else x86emu32_write32(emu,di,emu->regs[0]); + di += df?-step:step; emu->regs[X86_EDI]=di; + break; + } + case 0xAC: { /* LODSB */ + u32 si = emu->regs[X86_ESI]; + set_reg8(emu, 0, x86emu32_read8(emu, si)); + int df = get_flag(emu, X86_DF); + si += df ? -1 : 1; emu->regs[X86_ESI] = si; + break; + } + case 0xAD: { /* LODSD/W */ + u32 si = emu->regs[X86_ESI]; int df=get_flag(emu,X86_DF); int step=(osz==2)?2:4; + if (osz==2) set_reg16(emu,0,x86emu32_read16(emu,si)); else set_reg32(emu,0,x86emu32_read32(emu,si)); + si += df?-step:step; emu->regs[X86_ESI]=si; + break; + } + /* ---- TEST AL/EAX, imm ---- */ + case 0xA8: { u8 imm = fetch8(emu); alu_op(emu, 4, get_reg8(emu,0), imm, 1); break; } + case 0xA9: { + if (osz==2) { u16 imm=fetch16(emu); alu_op(emu,4,get_reg16(emu,0),imm,2); } + else { u32 imm=fetch32(emu); alu_op(emu,4,emu->regs[0],imm,4); } + break; + } + /* ---- MOV reg, imm ---- */ + case 0xB0: case 0xB1: case 0xB2: case 0xB3: + case 0xB4: case 0xB5: case 0xB6: case 0xB7: + set_reg8(emu, op - 0xB0, fetch8(emu)); + break; + case 0xB8: case 0xB9: case 0xBA: case 0xBB: + case 0xBC: case 0xBD: case 0xBE: case 0xBF: + if (osz==2) set_reg16(emu, op-0xB8, fetch16(emu)); + else set_reg32(emu, op-0xB8, fetch32(emu)); + break; + /* ---- shift r/m, imm8 ---- */ + case 0xC0: case 0xC1: { + modrm_dec m = decode_modrm(emu); + u8 count = fetch8(emu); + if (op == 0xC0) { u8 v = read_rm8(emu,&m); write_rm8(emu,&m,(u8)shift_op(emu,m.reg,v,count,1)); } + else if (osz==2) { u16 v=read_rm16(emu,&m); write_rm16(emu,&m,(u16)shift_op(emu,m.reg,v,count,2)); } + else { u32 v=read_rm32(emu,&m); write_rm32(emu,&m,shift_op(emu,m.reg,v,count,4)); } + break; + } + /* ---- RET ---- */ + case 0xC2: { u16 imm = fetch16(emu); emu->eip = x86emu32_pop32(emu); emu->regs[X86_ESP] += imm; break; } + case 0xC3: { emu->eip = x86emu32_pop32(emu); break; } + /* ---- MOV r/m, imm ---- */ + case 0xC6: { modrm_dec m = decode_modrm(emu); u8 imm = fetch8(emu); write_rm8(emu,&m,imm); break; } + case 0xC7: { + modrm_dec m = decode_modrm(emu); + if (osz==2) { u16 imm=fetch16(emu); write_rm16(emu,&m,imm); } + else { u32 imm=fetch32(emu); write_rm32(emu,&m,imm); } + break; + } + /* ---- LEAVE ---- */ + case 0xC9: + emu->regs[X86_ESP] = emu->regs[X86_EBP]; + emu->regs[X86_EBP] = x86emu32_pop32(emu); + break; + /* ---- INT3 / INT ---- */ + case 0xCC: /* INT3 */ + emu->error = 1; emu->error_msg = "INT3 breakpoint"; + break; + case 0xCD: { /* INT imm8 */ + u8 v = fetch8(emu); (void)v; + /* 简化:忽略软件中断 */ + break; + } + /* ---- shift r/m, 1 / CL ---- */ + case 0xD0: case 0xD1: case 0xD2: case 0xD3: { + modrm_dec m = decode_modrm(emu); + u8 count = (op & 2) ? (get_reg8(emu, 1) & 0x1F) : 1; + int is8 = !(op & 1); + if (is8) { u8 v=read_rm8(emu,&m); write_rm8(emu,&m,(u8)shift_op(emu,m.reg,v,count,1)); } + else if (osz==2) { u16 v=read_rm16(emu,&m); write_rm16(emu,&m,(u16)shift_op(emu,m.reg,v,count,2)); } + else { u32 v=read_rm32(emu,&m); write_rm32(emu,&m,shift_op(emu,m.reg,v,count,4)); } + break; + } + /* ---- CALL rel32 ---- */ + case 0xE8: { + i32 rel = (i32)fetch32(emu); + x86emu32_push32(emu, emu->eip); /* return address */ + emu->eip += (u32)rel; + break; + } + /* ---- JMP rel32 ---- */ + case 0xE9: { i32 rel = (i32)fetch32(emu); emu->eip += (u32)rel; break; } + /* ---- JMP rel8 ---- */ + case 0xEB: { i8 rel = (i8)fetch8(emu); emu->eip += (u32)(i32)rel; break; } + /* ---- LOOP ---- */ + case 0xE0: case 0xE1: case 0xE2: { + i8 rel = (i8)fetch8(emu); + u32 cx = emu->regs[X86_ECX] - 1; + emu->regs[X86_ECX] = cx; + int do_jump = (cx != 0); + if (op == 0xE0 && get_flag(emu, X86_ZF)) do_jump = 0; /* LOOPNE */ + if (op == 0xE1 && !get_flag(emu, X86_ZF)) do_jump = 0; /* LOOPE */ + if (do_jump) emu->eip += (u32)(i32)rel; + break; + } + case 0xE3: { /* JECXZ */ + i8 rel = (i8)fetch8(emu); + if (emu->regs[X86_ECX] == 0) emu->eip += (u32)(i32)rel; + break; + } + /* ---- CALL/JMP r/m ---- */ + case 0xFF: { + modrm_dec m = decode_modrm(emu); + switch (m.reg) { + case 0: { /* INC r/m */ + int cf=get_flag(emu,X86_CF); + if (osz==2) { u16 v=read_rm16(emu,&m); write_rm16(emu,&m,(u16)alu_op(emu,0,v,1,2)); } + else { u32 v=read_rm32(emu,&m); write_rm32(emu,&m,alu_op(emu,0,v,1,4)); } + set_flag(emu,X86_CF,cf); + break; + } + case 1: { /* DEC r/m */ + int cf=get_flag(emu,X86_CF); + if (osz==2) { u16 v=read_rm16(emu,&m); write_rm16(emu,&m,(u16)alu_op(emu,5,v,1,2)); } + else { u32 v=read_rm32(emu,&m); write_rm32(emu,&m,alu_op(emu,5,v,1,4)); } + set_flag(emu,X86_CF,cf); + break; + } + case 2: { /* CALL r/m32 */ + u32 target = read_rm32(emu, &m); + if (try_iat_call(emu, target)) break; + x86emu32_push32(emu, emu->eip); + emu->eip = target; + break; + } + case 4: { /* JMP r/m32 */ + u32 target = read_rm32(emu, &m); + if (try_iat_call(emu, target)) { emu->exited = 1; break; } + emu->eip = target; + break; + } + case 6: { /* PUSH r/m32 */ + x86emu32_push32(emu, read_rm32(emu, &m)); + break; + } + default: + emu->error = 1; emu->error_msg = "FF /reg unsupported"; + break; + } + break; + } + /* ---- F6/F7 组 ---- */ + case 0xF6: { + modrm_dec m = decode_modrm(emu); + if (m.reg == 0 || m.reg == 1) { /* TEST r/m8, imm8 */ + u8 imm = fetch8(emu); + alu_op(emu, 4, read_rm8(emu,&m), imm, 1); + } else if (m.reg == 2) { /* NOT r/m8 */ + write_rm8(emu, &m, ~read_rm8(emu, &m)); + } else if (m.reg == 3) { /* NEG r/m8 */ + u8 v = read_rm8(emu, &m); + u8 r = (u8)(-(i8)v); + set_flag(emu, X86_CF, v != 0); + set_zf_sf_pf(emu, r, 1); + write_rm8(emu, &m, r); + } else if (m.reg == 4) { /* MUL r/m8 */ + u16 result = (u16)get_reg8(emu, 0) * (u16)read_rm8(emu, &m); + set_reg8(emu, 0, (u8)result); + set_reg8(emu, 4, (u8)(result >> 8)); + set_flag(emu, X86_CF, result >> 8 != 0); + set_flag(emu, X86_OF, get_flag(emu, X86_CF)); + } else { + emu->error = 1; emu->error_msg = "F6 /reg unsupported"; + } + break; + } + case 0xF7: { + modrm_dec m = decode_modrm(emu); + if (m.reg == 0 || m.reg == 1) { /* TEST r/m32, imm32 */ + if (osz==2) { u16 imm=fetch16(emu); alu_op(emu,4,read_rm16(emu,&m),imm,2); } + else { u32 imm=fetch32(emu); alu_op(emu,4,read_rm32(emu,&m),imm,4); } + } else if (m.reg == 2) { /* NOT */ + if (osz==2) write_rm16(emu,&m,~read_rm16(emu,&m)); + else write_rm32(emu,&m,~read_rm32(emu,&m)); + } else if (m.reg == 3) { /* NEG */ + if (osz==2) { u16 v=read_rm16(emu,&m); u16 r=(u16)(-(i16)v); set_flag(emu,X86_CF,v!=0); set_zf_sf_pf(emu,r,2); write_rm16(emu,&m,r); } + else { u32 v=read_rm32(emu,&m); u32 r=(u32)(-(i32)v); set_flag(emu,X86_CF,v!=0); set_zf_sf_pf(emu,r,4); write_rm32(emu,&m,r); } + } else if (m.reg == 4) { /* MUL */ + if (osz==2) { u32 result=(u32)get_reg16(emu,0)*(u32)read_rm16(emu,&m); set_reg16(emu,0,(u16)result); set_reg16(emu,2,(u16)(result>>16)); set_flag(emu,X86_CF,result>>16!=0); set_flag(emu,X86_OF,get_flag(emu,X86_CF)); } + else { u64 result=(u64)emu->regs[0]*(u64)read_rm32(emu,&m); emu->regs[0]=(u32)result; emu->regs[2]=(u32)(result>>32); set_flag(emu,X86_CF,result>>32!=0); set_flag(emu,X86_OF,get_flag(emu,X86_CF)); } + } else if (m.reg == 5) { /* IMUL */ + if (osz==2) { i32 result=(i32)(i16)get_reg16(emu,0)*(i32)(i16)read_rm16(emu,&m); set_reg16(emu,0,(u16)result); set_reg16(emu,2,(u16)(result>>16)); set_flag(emu,X86_OF,result>32767||result<-32768); set_flag(emu,X86_CF,get_flag(emu,X86_OF)); } + else { i64 result=(i64)(i32)emu->regs[0]*(i64)(i32)read_rm32(emu,&m); emu->regs[0]=(u32)result; emu->regs[2]=(u32)(result>>32); set_flag(emu,X86_OF,result>0x7FFFFFFFLL||result<-0x80000000LL); set_flag(emu,X86_CF,get_flag(emu,X86_OF)); } + } else if (m.reg == 6) { /* DIV */ + if (osz==2) { u32 dividend=((u32)get_reg16(emu,2)<<16)|get_reg16(emu,0); u16 divisor=read_rm16(emu,&m); if(divisor){set_reg16(emu,0,(u16)(dividend/divisor));set_reg16(emu,2,(u16)(dividend%divisor));} } + else { u64 dividend=((u64)emu->regs[2]<<32)|emu->regs[0]; u32 divisor=read_rm32(emu,&m); if(divisor){emu->regs[0]=(u32)(dividend/divisor);emu->regs[2]=(u32)(dividend%divisor);} } + } else if (m.reg == 7) { /* IDIV */ + if (osz==2) { i32 dividend=((i32)(i16)get_reg16(emu,2)<<16)|(i16)get_reg16(emu,0); i16 divisor=(i16)read_rm16(emu,&m); if(divisor){set_reg16(emu,0,(u16)(dividend/divisor));set_reg16(emu,2,(u16)(dividend%divisor));} } + else { i64 dividend=((i64)(i32)emu->regs[2]<<32)|(i32)emu->regs[0]; i32 divisor=(i32)read_rm32(emu,&m); if(divisor){emu->regs[0]=(u32)(dividend/divisor);emu->regs[2]=(u32)(dividend%divisor);} } + } + break; + } + /* ---- CLC/STC/CLI/STI/CLD/STD ---- */ + case 0xF8: set_flag(emu, X86_CF, 0); break; + case 0xF9: set_flag(emu, X86_CF, 1); break; + case 0xFA: break; /* CLI(忽略) */ + case 0xFB: break; /* STI(忽略) */ + case 0xFC: set_flag(emu, X86_DF, 0); break; + case 0xFD: set_flag(emu, X86_DF, 1); break; + /* ---- INC/DEC r/m8 ---- */ + case 0xFE: { + modrm_dec m = decode_modrm(emu); + int cf = get_flag(emu, X86_CF); + u8 v = read_rm8(emu, &m); + if (m.reg == 0) write_rm8(emu, &m, (u8)alu_op(emu, 0, v, 1, 1)); + else if (m.reg == 1) write_rm8(emu, &m, (u8)alu_op(emu, 5, v, 1, 1)); + set_flag(emu, X86_CF, cf); + break; + } + /* ---- MOVSX/MOVZX 在 0x0F 两字节 opcode 中处理 ---- */ + case 0x0F: { /* 两字节 opcode */ + u8 op2 = fetch8(emu); + if (op2 >= 0x80 && op2 <= 0x8F) { /* Jcc rel32 */ + i32 rel = (i32)fetch32(emu); + if (check_jcc(emu, op2 & 0xF)) emu->eip += (u32)rel; + } else if (op2 == 0xAF) { /* IMUL r32, r/m32 */ + modrm_dec m = decode_modrm(emu); + i64 result = (i64)(i32)get_reg32(emu, m.reg) * (i64)(i32)read_rm32(emu, &m); + set_reg32(emu, m.reg, (u32)result); + set_flag(emu, X86_OF, result > 0x7FFFFFFFLL || result < -0x80000000LL); + set_flag(emu, X86_CF, get_flag(emu, X86_OF)); + } else if (op2 == 0xB6 || op2 == 0xB7) { /* MOVZX r32, r/m8/16 */ + modrm_dec m = decode_modrm(emu); + if (op2 == 0xB6) { set_reg32(emu, m.reg, (u32)read_rm8(emu, &m)); } + else { set_reg32(emu, m.reg, (u32)read_rm16(emu, &m)); } + } else if (op2 == 0xBE || op2 == 0xBF) { /* MOVSX r32, r/m8/16 */ + modrm_dec m = decode_modrm(emu); + if (op2 == 0xBE) { set_reg32(emu, m.reg, (u32)(i32)(i8)read_rm8(emu, &m)); } + else { set_reg32(emu, m.reg, (u32)(i32)(i16)read_rm16(emu, &m)); } + } else if (op2 == 0x1F) { /* NOP r/m(多字节 NOP) */ + decode_modrm(emu); + } else if (op2 == 0x05) { /* SYSCALL(不应出现在32位PE) */ + emu->error = 1; emu->error_msg = "SYSCALL in 32-bit PE"; + } else { + emu->error = 1; emu->error_msg = "0F opcode unsupported"; + } + break; + } + default: + emu->error = 1; emu->error_msg = "unsupported opcode"; + break; + } /* end switch(op) */ + + if (emu->error) { + log_hex64("[PE32] error at EIP=", emu->eip); + log_hex64("[PE32] opcode=", op); + log_info("[PE32] "); + log_info(emu->error_msg ? emu->error_msg : "(null)"); + break; + } + } /* end while */ + + if (emu->insn_count >= emu->insn_limit) { + log_error("[PE32] instruction limit reached"); + emu->error = 1; + } + + if (exit_code) *exit_code = emu->exit_code; + return emu->error ? -1 : 0; +} + +int x86emu32_init(x86emu_state *emu, u8 *mem, u64 mem_size, + u32 image_base, u32 image_size, + pe_iat_entry *iat_entries, int iat_count, + u32 stack_top) { + for (int i = 0; i < 8; i++) emu->regs[i] = 0; + emu->eip = 0; + emu->eflags = 0x2; /* 保留位 = 1 */ + emu->mem = mem; + emu->mem_size = mem_size; + emu->image_base = image_base; + emu->image_size = image_size; + emu->iat_entries = iat_entries; + emu->iat_count = iat_count; + emu->stack_base = stack_top; + emu->stack_size = 0x10000; /* 64KB 栈 */ + emu->heap_base = image_base + image_size; + emu->heap_size = 0x100000; /* 1MB heap */ + emu->heap_next = emu->heap_base; + emu->exited = 0; + emu->exit_code = 0; + emu->error = 0; + emu->error_msg = 0; + emu->insn_count = 0; + + /* 设置 ESP 到栈顶,对齐 16 */ + emu->regs[X86_ESP] = stack_top & ~0xFu; + emu->regs[X86_EBP] = 0; + return 0; +} diff --git a/CODE/UTSM/pe/x86emu32.h b/CODE/UTSM/pe/x86emu32.h new file mode 100644 index 0000000..96793aa --- /dev/null +++ b/CODE/UTSM/pe/x86emu32.h @@ -0,0 +1,100 @@ +#ifndef X86EMU32_H +#define X86EMU32_H + +/* x86emu32.h — x86-32 指令解释器(PE32 执行引擎)。 + * + * 寄存器级解释执行 32位 PE 代码。覆盖 mingw-w64 控制台程序常用指令集。 + * 遇不支持的指令时日志告警并返回错误。 + */ + +#include + +/* x86 通用寄存器索引 */ +enum { + X86_EAX = 0, X86_ECX, X86_EDX, X86_EBX, + X86_ESP, X86_EBP, X86_ESI, X86_EDI +}; + +/* EFLAGS 位 */ +#define X86_CF (1u << 0) +#define X86_PF (1u << 2) +#define X86_AF (1u << 4) +#define X86_ZF (1u << 6) +#define X86_SF (1u << 7) +#define X86_OF (1u << 11) +#define X86_DF (1u << 10) + +/* IAT 条目信息(解释器用于 CALL 拦截) */ +typedef struct pe_iat_entry { + u32 iat_rva; /* IAT 中该条目的 RVA */ + int shim_index; /* 对应 shim 表索引,-1 = 未实现 stub */ + u32 target_addr; /* 模拟地址(iat_rva + image_base) */ +} pe_iat_entry; + +typedef struct x86emu_state { + u32 regs[8]; /* EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI */ + u32 eip; /* 指令指针(相对 mem 基址的偏移) */ + u32 eflags; + + u8 *mem; /* guest 内存基址(= PE image_base) */ + u64 mem_size; /* guest 内存大小 */ + + u32 image_base; /* PE 加载基址(= mem,32位截断) */ + u32 image_size; + + /* IAT 表(用于 CALL 拦截) */ + pe_iat_entry *iat_entries; + int iat_count; + + /* 栈区 */ + u32 stack_base; /* 栈底(高地址) */ + u32 stack_size; + + /* heap 区 */ + u32 heap_base; + u32 heap_size; + u32 heap_next; /* 下次分配偏移 */ + + /* 退出状态 */ + int exited; /* ExitProcess 被调用 */ + u64 exit_code; + int error; /* 解释错误 */ + const char *error_msg; + + /* 指令计数限制(防死循环) */ + u64 insn_count; + u64 insn_limit; +} x86emu_state; + +/* 初始化解释器状态。 + * mem = PE image 加载基址(已映射节区+重定位+IAT 填充)。 + * iat_entries / iat_count = pe_loader 解析的 IAT 表。 + * stack_top = 栈顶 ESP 初始值(相对 mem 的偏移)。 + * 返回 0 成功。 */ +int x86emu32_init(x86emu_state *emu, u8 *mem, u64 mem_size, + u32 image_base, u32 image_size, + pe_iat_entry *iat_entries, int iat_count, + u32 stack_top); + +/* 执行直到 ExitProcess 或错误。 + * 返回 0 正常退出(exit_code 有效),负数错误。 */ +int x86emu32_run(x86emu_state *emu, u64 *exit_code); + +/* 从模拟栈读取 N 个参数(cdecl/stdcall)。 + * esp_offset = 参数相对 ESP 的偏移(0=第一个参数)。 + * 返回参数值。 */ +u64 x86emu32_read_arg(x86emu_state *emu, int esp_offset); + +/* 模拟栈 push/pop(供 shim32 回调使用) */ +void x86emu32_push32(x86emu_state *emu, u32 val); +u32 x86emu32_pop32(x86emu_state *emu); + +/* 读写模拟内存 */ +u8 x86emu32_read8(x86emu_state *emu, u32 addr); +u16 x86emu32_read16(x86emu_state *emu, u32 addr); +u32 x86emu32_read32(x86emu_state *emu, u32 addr); +void x86emu32_write8(x86emu_state *emu, u32 addr, u8 val); +void x86emu32_write16(x86emu_state *emu, u32 addr, u16 val); +void x86emu32_write32(x86emu_state *emu, u32 addr, u32 val); + +#endif /* X86EMU32_H */ diff --git a/CODE/UTSM/vmm/linux_boot.c b/CODE/UTSM/vmm/linux_boot.c index b880620..e8f8cd3 100644 --- a/CODE/UTSM/vmm/linux_boot.c +++ b/CODE/UTSM/vmm/linux_boot.c @@ -27,13 +27,9 @@ extern void vmx_vm_exit_handler(void); extern int vmexit_dispatch(void); extern u64 vmexit_get_count(void); -/* Globals shared with vmexit_asm.S (must match vmm.c) */ -extern volatile u64 g_saved_host_rsp; -extern volatile u64 g_saved_return_rip; -extern volatile int g_guest_terminated; -extern volatile u64 g_last_exit_reason; - -/* Host stack for VM-Exit (reuse the one from vmm.c) */ +/* g_saved_host_rsp / g_saved_return_rip / g_guest_terminated / + * g_last_exit_reason / g_linux_guest_active / g_guest_parked / + * g_guest_regs / g_host_stack 通过 声明(vmm.c 定义)。 */ extern u8 g_host_stack[8192]; /* CR helpers */ @@ -288,6 +284,8 @@ int linux_launch(void) { /* Reset VM-Exit state */ g_guest_terminated = 0; g_last_exit_reason = 0xFFFFFFFFULL; + g_linux_guest_active = 1; /* 标记当前 guest 为 Linux(HLT 时 park) */ + g_guest_parked = 0; /* Configure VMCS */ linux_vmcs_setup_guest_state(gi); @@ -331,11 +329,14 @@ int linux_launch(void) { if (failed) { u64 error = vmx_vmcs_read(VMCS_VMX_INSTRUCTION_ERROR); log_hex64("[LINUX] vmlaunch failed, error=", error); + g_linux_guest_active = 0; return -3; } - /* Guest terminated */ - log_info("[LINUX] guest terminated"); + /* Guest parked (HLT) — Linux daemon 已驻留,等待 linux_resume() 唤醒 */ + g_linux_guest_active = 0; /* 回到 host 上下文,清除 active 标志 */ + g_guest_parked = 1; /* 标记 guest 已 park,linux_resume() 可唤醒 */ + log_info("[LINUX] guest parked (daemon ready)"); log_hex64("[LINUX] last exit reason=", g_last_exit_reason); log_hex64("[LINUX] vmexit count=", vmexit_get_count()); diff --git a/CODE/UTSM/vmm/linux_compat.c b/CODE/UTSM/vmm/linux_compat.c new file mode 100644 index 0000000..34a618a --- /dev/null +++ b/CODE/UTSM/vmm/linux_compat.c @@ -0,0 +1,198 @@ +/* linux_compat.c — Deshab Linux 程序兼容层服务实现。 + * + * 依赖 UTSM+Linux 双内核架构与 IPC 共享内存。Linux guest 作为 daemon + * 在 VMX guest 中 park-and-resume 驻留。UTSM 侧通过 IPC ring 向 daemon + * 发送 exec 请求,并 vmresume 唤醒 guest 执行。 + * + * 执行流程(exec()): + * 1. 构建 ipc_exec_request,通过 ipc_shm_send(UTSM_MSG_EXEC_REQUEST) 入队 + * 2. 调用 linux_resume() → vmresume → Linux daemon 读取请求 → fork+exec + * 3. daemon 通过 linux_to_utsm ring 回传 UTSM_MSG_EXEC_STDOUT/STDERR/EXIT + * 4. daemon HLT park → linux_resume() 返回 + * 5. exec() 从 ring 读取所有响应消息,拼接 stdout,取 exit code + * + * 服务指针通过 dsk_boot_context.reserved[5] 暴露给 shell/cmd/desktop。 + */ + +#include +#include +#include +#include +#include +#include +#include + +/* ===== 内部辅助 ===== */ + +static u64 my_strlen(const char *s) { + u64 n = 0; + if (s) while (s[n]) n++; + return n; +} + +static void my_memcpy(void *d, const void *s, u64 n) { + u8 *dd = (u8 *)d; + const u8 *ss = (const u8 *)s; + while (n--) *dd++ = *ss++; +} + +static void my_memzero(void *d, u64 n) { + u8 *p = (u8 *)d; + while (n--) *p++ = 0; +} + +/* ===== 服务状态 ===== */ + +static int g_compat_ready; /* 1 = linux_launch 已成功,服务可用 */ + +void linux_compat_init(void) { + /* 在 linux_launch 成功(guest parked)后由 kernel_main 调用 */ + if (linux_is_parked() && ipc_shm_is_ready()) { + g_compat_ready = 1; + log_info("[LNXC] service ready (guest parked, IPC ok)"); + } else { + g_compat_ready = 0; + log_warn("[LNXC] service not ready (guest not parked or IPC down)"); + } +} + +/* ===== 服务方法 ===== */ + +static int lxc_is_available(void) { + return (g_compat_ready && linux_is_parked() && ipc_shm_is_ready()) ? 1 : 0; +} + +/* 等待 Linux daemon 的响应消息。 + * linux_resume() 返回后,daemon 已 park,所有响应消息应已在 ring 中。 + * 我们循环 pop 直到拿到 EXEC_EXIT 或 ring 空(超时保护)。 */ +static int lxc_drain_responses(char *out_buf, u64 out_cap, u64 *out_len, + u64 *exit_code) { + u64 written = 0; + int got_exit = 0; + u64 exit_val = 0; + + /* 最多消费 256 条消息(防止异常情况下死循环) */ + for (int i = 0; i < 256; i++) { + struct utsm_ipc_msg msg; + if (ipc_shm_recv(&msg) != 0) { + /* ring 空 */ + break; + } + + switch (msg.type) { + case UTSM_MSG_EXEC_STDOUT: + case UTSM_MSG_EXEC_STDERR: { + /* 拼接到 stdout 缓冲区(stderr 也并入,简化调用方处理) */ + u32 n = msg.data_len; + if (out_buf && out_cap > written) { + u32 space = (u32)(out_cap - written); + u32 to_copy = (n < space) ? n : space; + my_memcpy(out_buf + written, msg.data, to_copy); + written += to_copy; + } + break; + } + case UTSM_MSG_EXEC_EXIT: { + if (msg.data_len >= sizeof(struct ipc_exec_exit)) { + struct ipc_exec_exit ex; + my_memcpy(&ex, msg.data, sizeof(ex)); + exit_val = ex.exit_code; + } + got_exit = 1; + break; + } + default: + /* 忽略其他消息(HELLO/PONG 等) */ + break; + } + + if (got_exit) break; + } + + if (out_len) *out_len = written; + if (exit_code) *exit_code = exit_val; + + return got_exit ? 0 : -4; /* -4 = 超时无 exit 响应 */ +} + +static int lxc_exec(const char *path, int argc, const char *const *argv, + char *stdout_buf, u64 stdout_cap, u64 *stdout_len, + u64 *exit_code) { + if (!lxc_is_available()) { + return -1; + } + if (!path) { + return -1; + } + + /* 1. 构建 exec 请求 */ + struct ipc_exec_request req; + my_memzero(&req, sizeof(req)); + req.argc = (u32)argc; + req.flags = 0; + + u64 plen = my_strlen(path); + if (plen >= UTSM_EXEC_PATH_MAX) plen = UTSM_EXEC_PATH_MAX - 1; + my_memcpy(req.path, path, plen); + req.path[plen] = 0; + + /* 拼接 argv_blob:每个 argv[i] NUL-terminated */ + u64 blob_off = 0; + if (argc > UTSM_EXEC_MAX_ARGS) argc = UTSM_EXEC_MAX_ARGS; + for (int i = 0; i < argc; i++) { + if (!argv[i]) continue; + u64 alen = my_strlen(argv[i]); + if (blob_off + alen + 1 > UTSM_EXEC_ARGV_MAX) break; + my_memcpy(req.argv_blob + blob_off, argv[i], alen); + blob_off += alen; + req.argv_blob[blob_off++] = 0; + } + + /* 2. 发送 EXEC_REQUEST */ + if (ipc_shm_send(UTSM_MSG_EXEC_REQUEST, &req, sizeof(req)) != 0) { + log_warn("[LNXC] exec: failed to enqueue request"); + return -2; + } + + /* 3. 唤醒 Linux guest 执行 */ + int r = linux_resume(); + if (r != 0) { + log_hex64("[LNXC] exec: linux_resume failed=", (u64)(i64)r); + return -3; + } + + /* 4. 读取响应(daemon 已再次 park,响应在 ring 中) */ + return lxc_drain_responses(stdout_buf, stdout_cap, stdout_len, exit_code); +} + +static int lxc_status(char *buf, u64 cap) { + if (!buf || cap == 0) return 0; + const char *s; + if (!g_compat_ready) { + s = "linux_compat: not initialized"; + } else if (!linux_is_parked()) { + s = "linux_compat: guest not parked"; + } else if (!ipc_shm_is_ready()) { + s = "linux_compat: IPC down"; + } else { + s = "linux_compat: ready"; + } + u64 n = my_strlen(s); + if (n >= cap) n = cap - 1; + my_memcpy(buf, s, n); + buf[n] = 0; + return (int)n; +} + +/* ===== 服务表 ===== */ + +static const linux_compat_service g_lxc_service = { + LINUX_COMPAT_MAGIC, + lxc_is_available, + lxc_exec, + lxc_status, +}; + +const linux_compat_service *linux_compat_get_service(void) { + return &g_lxc_service; +} diff --git a/CODE/UTSM/vmm/linux_resume.c b/CODE/UTSM/vmm/linux_resume.c new file mode 100644 index 0000000..d6b5f35 --- /dev/null +++ b/CODE/UTSM/vmm/linux_resume.c @@ -0,0 +1,68 @@ +/* linux_resume.c — Linux guest park-and-resume 唤醒实现。 + * + * linux_resume() 通过 vmresume 唤醒已 HLT park 的 Linux guest。 + * guest daemon 处理 IPC 请求后再次 HLT park,控制权返回 host。 + * + * 控制流与 linux_launch() 的 vmlaunch 对称: + * - 保存 host RSP 和返回 RIP + * - 执行 vmresume(成功则进入 guest,不返回) + * - guest HLT → VM-Exit → handle_hlt park → g_guest_terminated=1 + * - vmexit_asm.S 恢复 host RSP,jmp 到返回 RIP + * - linux_resume() 继续执行,返回 0 + */ + +#include +#include +#include +#include +#include + +int linux_is_parked(void) { + return g_guest_parked ? 1 : 0; +} + +int linux_resume(void) { + if (!g_guest_parked) { + log_warn("[LINUX] resume: guest not parked"); + return -1; + } + + /* 设置 active 标志:handle_hlt 检查此标志决定 park(而非 terminate) */ + g_linux_guest_active = 1; + g_guest_terminated = 0; + g_guest_parked = 0; + + /* vmresume 控制流(与 linux_launch 的 vmlaunch 对称): + * - 失败:执行下一条指令,failed=1 + * - 成功:进入 guest,不返回。VM-Exit 后跳到 vmx_vm_exit_handler。 + * - guest park 时,handler 恢复 saved_rsp 并 jmp 到 post_resume 标签。 */ + int failed; + __asm__ volatile( + "movq %%rsp, g_saved_host_rsp(%%rip)\n\t" /* 保存当前 RSP */ + "leaq 1f(%%rip), %%rax\n\t" /* 取 post_resume 标签地址 */ + "movq %%rax, g_saved_return_rip(%%rip)\n\t" /* 保存返回 RIP */ + "vmresume\n\t" /* 唤醒 guest */ + /* ---- 失败路径 ---- */ + "movl $1, %0\n\t" + "jmp 2f\n\t" + /* ---- post_resume: park 路径 jmp 到这里 ---- */ + "1:\n\t" + "movl $0, %0\n\t" + "2:\n\t" + : "=r"(failed) + :: "rax", "rcx", "rdx", "rsi", "rdi", + "r8", "r9", "r10", "r11", "memory" + ); + + /* 回到 host 上下文 */ + g_linux_guest_active = 0; + g_guest_parked = 1; /* guest 再次 park */ + + if (failed) { + u64 error = vmx_vmcs_read(VMCS_VMX_INSTRUCTION_ERROR); + log_hex64("[LINUX] vmresume failed, error=", error); + return -2; + } + + return 0; +} diff --git a/CODE/UTSM/vmm/vmexit.c b/CODE/UTSM/vmm/vmexit.c index 176bf5f..08eee02 100644 --- a/CODE/UTSM/vmm/vmexit.c +++ b/CODE/UTSM/vmm/vmexit.c @@ -23,11 +23,21 @@ static void log_exit_diagnostics(u64 reason, u64 qualification, u64 rip, u64 len log_hex64("[VMEXIT] ilen=", len); } -/* 处理 HLT:Phase 1.1 自检场景下表示 guest 完成测试,停止 guest。 */ +/* 处理 HLT: + * - self-test guest:终止(guest 完成测试) + * - Linux guest:park(推进 RIP 越过 HLT,exit-to-host,设 g_guest_parked=1) + * host 调用 linux_resume() 时 vmresume 唤醒 guest 从 HLT 之后继续执行。 */ static int handle_hlt(u64 rip, u64 instr_len, int *out_resume) { - *out_resume = 0; /* 不 resume,guest 终止 */ - log_info("[VMEXIT] HLT - guest halted"); - (void)rip; (void)instr_len; + *out_resume = 0; /* 两种情况都 exit-to-host */ + if (g_linux_guest_active) { + /* Linux guest: park — 推进 RIP 越过 HLT 指令 */ + vmx_vmcs_write(VMCS_GUEST_RIP, rip + instr_len); + g_guest_parked = 1; + log_info("[VMEXIT] HLT - Linux guest parked"); + } else { + /* self-test guest: 终止 */ + log_info("[VMEXIT] HLT - guest halted"); + } return 0; } diff --git a/CODE/UTSM/vmm/vmm.c b/CODE/UTSM/vmm/vmm.c index b973286..4561416 100644 --- a/CODE/UTSM/vmm/vmm.c +++ b/CODE/UTSM/vmm/vmm.c @@ -46,6 +46,12 @@ volatile u64 g_saved_return_rip; volatile int g_guest_terminated; volatile u64 g_last_exit_reason; +/* Linux guest park-and-resume 状态。 + * g_linux_guest_active: 1 = 当前运行的 guest 是 Linux(HLT 时 park,不终止) + * g_guest_parked: 1 = Linux guest 已 HLT 驻留,等待 vmresume 唤醒 */ +volatile int g_linux_guest_active; +volatile int g_guest_parked; + /* Guest GPR save area (referenced by vmexit_asm.S). * VM-Exit 时 CPU 不自动保存 guest GPR,由汇编入口保存到此结构。 * C 处理器可读写此结构(如 VMCALL 返回值写入 rax)。 */ diff --git a/CODE/cmd/MAKEFILE b/CODE/cmd/MAKEFILE new file mode 100644 index 0000000..616e02b --- /dev/null +++ b/CODE/cmd/MAKEFILE @@ -0,0 +1,25 @@ +CC := clang +LD := ld.lld + +ROOT := ../.. +OUT := $(ROOT)/SYSTEM/system/deshab64/cmd.elf + +CFLAGS := -target x86_64-unknown-none -std=c11 -ffreestanding -fno-builtin -fno-stack-protector -fpie -mno-red-zone -mno-sse -mno-sse2 -mno-mmx -msoft-float -m64 -Wall -Wextra -I../UTSM/include -O2 +LDFLAGS := -nostdlib -static -pie -z max-page-size=0x1000 -T linker.ld + +C_SOURCES := main.c +OBJECTS := $(C_SOURCES:.c=.o) + +.PHONY: all clean + +all: $(OUT) + +$(OUT): $(OBJECTS) linker.ld + @if not exist "$(ROOT)\SYSTEM\system\deshab64" mkdir "$(ROOT)\SYSTEM\system\deshab64" + $(LD) $(LDFLAGS) -o $@ $(OBJECTS) + +%.o: %.c + $(CC) $(CFLAGS) -c $< -o $@ + +clean: + powershell -NoProfile -Command "Get-ChildItem -Path . -Recurse -Filter *.o | Remove-Item -Force; if (Test-Path '$(OUT)') { Remove-Item '$(OUT)' -Force }" diff --git a/CODE/cmd/linker.ld b/CODE/cmd/linker.ld new file mode 100644 index 0000000..473e5fc --- /dev/null +++ b/CODE/cmd/linker.ld @@ -0,0 +1,24 @@ +ENTRY(dsk_entry) + +PHDRS +{ + text PT_LOAD FLAGS(5); + rodata PT_LOAD FLAGS(4); + data PT_LOAD FLAGS(6); + dynamic PT_DYNAMIC FLAGS(4); +} + +SECTIONS +{ + . = 0x1000; + .text : ALIGN(4K) { *(.text*) } :text + .rodata : ALIGN(4K) { *(.rodata*) } :rodata + .data : ALIGN(4K) { + *(.data*) + *(.data.rel.ro*) + *(COMMON) + *(.bss*) + } :data + .rela.dyn : ALIGN(8) { *(.rela.dyn*) } :data + .dynamic : ALIGN(8) { *(.dynamic*) } :data :dynamic +} diff --git a/CODE/cmd/main.c b/CODE/cmd/main.c new file mode 100644 index 0000000..edef93f --- /dev/null +++ b/CODE/cmd/main.c @@ -0,0 +1,961 @@ +/* Deshab CMD — Windows 风格命令行(PE/EXE 兼容层前端) + * + * 黑底白字 cmd.exe 风格,PS/2 键盘输入。 + * 内置命令:dir/cd/type/copy/del/ren/mkdir/rmdir/echo/cls/ver/set/help/exit + * PE 执行:输入 foo.exe 或 foo → 从 FAT32 根读取 → 调用 UTSM PE 服务执行 + * - PE32+ (64位):UTSM 原生 Ring0 执行 + * - PE32 (32位):UTSM 内嵌 x86-32 解释器执行 + * Esc 返回桌面。 + */ + +#include "../UTSM/include/utsm/dsk.h" +#include "../UTSM/include/utsm/pe.h" + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +typedef unsigned long long u64; +typedef long long i64; + +#define COM1 0x3F8 + +static __inline__ void outb(u16 port, u8 value) { __asm__ volatile("outb %0,%1"::"a"(value),"Nd"(port)); } +static __inline__ u8 inb(u16 port) { u8 v; __asm__ volatile("inb %1,%0":"=a"(v):"Nd"(port)); return v; } + +/* ---- TSC 计时 ---- */ +static u64 g_tsc_per_ms = 0; + +static __inline__ u64 rdtsc_cmd(void) { + u32 lo, hi; + __asm__ volatile("rdtsc" : "=a"(lo), "=d"(hi)); + return ((u64)hi << 32) | lo; +} + +static void tsc_calibrate_cmd(void) { + outb(0x43, 0x30); + outb(0x40, 0x7c); + outb(0x40, 0x2e); + u64 tsc_start = rdtsc_cmd(); + u16 prev = 0; u64 loops = 0; + for (;;) { + outb(0x43, 0x00); + u16 cur = (u16)inb(0x40) | ((u16)inb(0x40) << 8); + if (cur > prev && loops > 10) break; + prev = cur; loops++; + } + u64 tsc_end = rdtsc_cmd(); + g_tsc_per_ms = (tsc_end - tsc_start) / 10; +} + +static void serial_wait_tx(void) { + if (g_tsc_per_ms == 0) tsc_calibrate_cmd(); + if (g_tsc_per_ms == 0) { + for (u32 i = 0; i < 100000; i++) { if (inb(COM1 + 5) & 0x20) break; } + return; + } + u64 deadline = rdtsc_cmd() + g_tsc_per_ms / 10; + while (rdtsc_cmd() < deadline) { + if (inb(COM1 + 5) & 0x20) break; + __asm__ volatile("pause"); + } +} + +static void sputc(char c) { serial_wait_tx(); outb(COM1, (unsigned char)c); } +static void swrite(const char *s) { while (*s) { if (*s == '\n') sputc('\r'); sputc(*s++); } } +static void logl(const char *s) { swrite(s); swrite("\n"); } + +/* ASCII 字体 — 必须在 deshab_ui.h 之前包含 */ +#include "../firstInit/ascii_bitmaps.c" +#include "../UTSM/include/utsm/deshab_ui.h" +/* FAT32 共享读写库 */ +#include "../tools/fat32_io.h" + +/* ============================================================ + * 颜色定义 — Windows cmd.exe 风格(黑底浅灰字) + * ============================================================ */ + +#define CMD_BG 0xFF000000u /* 纯黑背景 */ +#define CMD_TEXT 0xFFC0C0C0u /* 浅灰文字(cmd.exe 默认) */ +#define CMD_PROMPT 0xFFFFFFFFu /* 白色提示符 */ +#define CMD_ERROR 0xFFFF6060u /* 浅红错误 */ +#define CMD_OK 0xFF60FF60u /* 浅绿成功 */ +#define CMD_INFO 0xFF60A0FFu /* 浅蓝信息 */ +#define CMD_DIM 0xFF808080u /* 灰色暗淡 */ +#define CMD_WARN 0xFFFFFF60u /* 黄色警告 */ + +/* ============================================================ + * 终端缓冲区与渲染 + * ============================================================ */ + +#define TERM_COLS 100 +#define TERM_ROWS 40 +#define TERM_MAX_CHARS (TERM_COLS * TERM_ROWS) + +static du_context g_ctx; +static u64 fb_a, fb_w, fb_h, fb_p; + +static u8 term_ch[TERM_MAX_CHARS]; +static u32 term_fg[TERM_MAX_CHARS]; +static int term_w = TERM_COLS; +static int term_h = TERM_ROWS; +static int cur_col = 0; +static int cur_row = 0; +static int cur_visible = 1; +static int term_start_x, term_start_y; + +static const dsk_boot_context *g_boot_ctx = 0; +static u64 g_kernel_api = 0; +static const pe_service *g_pe_svc = 0; + +/* dev_mode 串口镜像 */ +static int g_serial_mirror = 0; + +static void term_init_pos(void) { + int margin = 4; + term_start_x = margin; + term_start_y = margin; + int avail_w = (int)fb_w - margin * 2; + int avail_h = (int)fb_h - margin * 2; + term_w = avail_w / (int)DU_ASCII_STEP; + term_h = avail_h / (int)DU_ASCII_LINE_H; + if (term_w < 10) term_w = 10; + if (term_h < 5) term_h = 5; + if (term_w > TERM_COLS) term_w = TERM_COLS; + if (term_h > TERM_ROWS) term_h = TERM_ROWS; +} + +static void term_clear_buf(void) { + for (int i = 0; i < TERM_MAX_CHARS; i++) { + term_ch[i] = ' '; + term_fg[i] = CMD_TEXT; + } + cur_col = 0; + cur_row = 0; +} + +static void term_scroll(void) { + for (int r = 1; r < term_h; r++) { + for (int c = 0; c < term_w; c++) { + int src = r * TERM_COLS + c; + int dst = (r - 1) * TERM_COLS + c; + term_ch[dst] = term_ch[src]; + term_fg[dst] = term_fg[src]; + } + } + for (int c = 0; c < term_w; c++) { + term_ch[(term_h - 1) * TERM_COLS + c] = ' '; + term_fg[(term_h - 1) * TERM_COLS + c] = CMD_TEXT; + } + cur_row = term_h - 1; + cur_col = 0; +} + +static void term_newline(void) { + cur_col = 0; + cur_row++; + if (cur_row >= term_h) term_scroll(); +} + +static void term_putc_color(char c, u32 color) { + if (g_serial_mirror) { if (c == '\n') sputc('\r'); sputc(c); } + if (c == '\n') { term_newline(); return; } + if (c == '\r') { cur_col = 0; return; } + if (c == '\t') { + int spaces = 8 - (cur_col % 8); + for (int i = 0; i < spaces; i++) term_putc_color(' ', color); + return; + } + if (c < ' ' || c > '~') c = '.'; + if (cur_col >= term_w) term_newline(); + int idx = cur_row * TERM_COLS + cur_col; + term_ch[idx] = (u8)c; + term_fg[idx] = color; + cur_col++; +} + +static void term_putc(char c) { term_putc_color(c, CMD_TEXT); } +static void term_puts_color(const char *s, u32 color) { while (*s) term_putc_color(*s++, color); } +static void term_puts(const char *s) { term_puts_color(s, CMD_TEXT); } + +/* ---- 数字转字符串 ---- */ +static void term_putu(u32 v) { + char buf[12]; + int i = 11; + buf[i--] = 0; + if (v == 0) { buf[i--] = '0'; } + while (v > 0 && i >= 0) { buf[i--] = (char)('0' + (v % 10)); v /= 10; } + term_puts(&buf[i + 1]); +} + +static void term_putx(u32 v) { + static const char hex[] = "0123456789ABCDEF"; + term_putc('0'); term_putc('x'); + for (int i = 28; i >= 0; i -= 4) { + u32 nib = (v >> i) & 0xF; + if (nib != 0 || i <= 12) term_putc(hex[nib]); + } +} + +/* ---- 终端全屏渲染 ---- */ +static void term_redraw_all(void) { + du_fill_rect(&g_ctx, 0, 0, (i64)fb_w, (i64)fb_h, CMD_BG); + for (int r = 0; r < term_h; r++) { + i64 y = term_start_y + (i64)r * (i64)DU_ASCII_LINE_H; + for (int c = 0; c < term_w; c++) { + int idx = r * TERM_COLS + c; + i64 x = term_start_x + (i64)c * (i64)DU_ASCII_STEP; + du_draw_char(&g_ctx, (char)term_ch[idx], x, y, term_fg[idx], CMD_BG); + } + } +} + +static void term_redraw_cursor(void) { + if (cur_col >= term_w) return; + i64 x = term_start_x + (i64)cur_col * (i64)DU_ASCII_STEP; + i64 y = term_start_y + (i64)cur_row * (i64)DU_ASCII_LINE_H; + du_fill_rect(&g_ctx, x, y, (i64)DU_ASCII_STEP - 1, (i64)DU_ASCII_CELL_H, CMD_PROMPT); +} + +static void term_clear_cursor(void) { + if (cur_col >= term_w) return; + i64 x = term_start_x + (i64)cur_col * (i64)DU_ASCII_STEP; + i64 y = term_start_y + (i64)cur_row * (i64)DU_ASCII_LINE_H; + int idx = cur_row * TERM_COLS + cur_col; + du_fill_rect(&g_ctx, x, y, (i64)DU_ASCII_STEP - 1, (i64)DU_ASCII_CELL_H, CMD_BG); + du_draw_char(&g_ctx, (char)term_ch[idx], x, y, term_fg[idx], CMD_BG); +} + +/* ============================================================ + * 键盘输入(PS/2 Scan Code Set 1) + * ============================================================ */ + +static char scan_to_ascii(u8 sc, int shift) { + static const char normal[58] = { + 0, 27, '1','2','3','4','5','6','7','8','9','0','-','=', 8, '\t', + 'q','w','e','r','t','y','u','i','o','p','[',']','\n',0, + 'a','s','d','f','g','h','j','k','l',';','\'', '`',0,'\\', + 'z','x','c','v','b','n','m',',','.','/',0,'*',0,' ' + }; + static const char shifted[58] = { + 0, 27, '!','@','#','$','%','^','&','*','(',')','_','+', 8, '\t', + 'Q','W','E','R','T','Y','U','I','O','P','{','}','\n',0, + 'A','S','D','F','G','H','J','K','L',':','"','~',0,'|', + 'Z','X','C','V','B','N','M','<','>','?',0,'*',0,' ' + }; + if (sc >= 58) return 0; + return shift ? shifted[sc] : normal[sc]; +} + +/* ============================================================ + * 字符串工具 + * ============================================================ */ + +static int str_eq(const char *a, const char *b) { + while (*a && *b) { if (*a != *b) return 0; a++; b++; } + return *a == *b; +} + +static int str_len(const char *s) { + int n = 0; + while (s[n]) n++; + return n; +} + +static void str_copy(char *dst, const char *src, int max) { + int i = 0; + while (src[i] && i < max - 1) { dst[i] = src[i]; i++; } + dst[i] = 0; +} + +static int str_ieq(const char *a, const char *b) { + while (*a && *b) { + char ca = *a, cb = *b; + if (ca >= 'a' && ca <= 'z') ca -= 32; + if (cb >= 'a' && cb <= 'z') cb -= 32; + if (ca != cb) return 0; + a++; b++; + } + return *a == *b; +} + +/* ============================================================ + * 输入行编辑 + * ============================================================ */ + +static char input_buf[256]; +static int input_len = 0; +static int input_cursor = 0; + +static const char *PROMPT = "C:\\> "; + +static void redraw_input_line(void) { + int prompt_len = str_len(PROMPT); + i64 y = term_start_y + (i64)cur_row * (i64)DU_ASCII_LINE_H; + du_fill_rect(&g_ctx, term_start_x, y, + (i64)term_w * (i64)DU_ASCII_STEP, + (i64)DU_ASCII_CELL_H, CMD_BG); + for (int i = 0; i < prompt_len; i++) { + i64 x = term_start_x + (i64)i * (i64)DU_ASCII_STEP; + du_draw_char(&g_ctx, PROMPT[i], x, y, CMD_PROMPT, CMD_BG); + } + for (int i = 0; i < input_len; i++) { + i64 x = term_start_x + (i64)(prompt_len + i) * (i64)DU_ASCII_STEP; + du_draw_char(&g_ctx, input_buf[i], x, y, CMD_TEXT, CMD_BG); + } + cur_col = prompt_len + input_cursor; + term_redraw_cursor(); +} + +static void insert_char(char c) { + if (input_len >= 255) return; + for (int i = input_len; i > input_cursor; i--) + input_buf[i] = input_buf[i - 1]; + input_buf[input_cursor] = c; + input_len++; + input_cursor++; + redraw_input_line(); +} + +static void delete_char_back(void) { + if (input_cursor == 0) return; + for (int i = input_cursor - 1; i < input_len - 1; i++) + input_buf[i] = input_buf[i + 1]; + input_len--; + input_cursor--; + input_buf[input_len] = 0; + redraw_input_line(); +} + +static void cursor_left(void) { + if (input_cursor > 0) { input_cursor--; redraw_input_line(); } +} + +static void cursor_right(void) { + if (input_cursor < input_len) { input_cursor++; redraw_input_line(); } +} + +static void cursor_home(void) { + input_cursor = 0; + redraw_input_line(); +} + +static void cursor_end(void) { + input_cursor = input_len; + redraw_input_line(); +} + +static void kill_line(void) { + input_len = 0; + input_cursor = 0; + input_buf[0] = 0; + redraw_input_line(); +} + +/* ============================================================ + * 内置命令 + * ============================================================ */ + +static void cmd_help(void) { + term_puts_color("Deshab CMD — 命令列表:\r\n", CMD_INFO); + term_puts(" dir 列出文件\r\n"); + term_puts(" cd 显示当前目录\r\n"); + term_puts(" type 显示文件内容\r\n"); + term_puts(" copy 复制文件\r\n"); + term_puts(" del 删除文件\r\n"); + term_puts(" ren 重命名文件\r\n"); + term_puts(" echo 显示文本 (echo text > file 写入)\r\n"); + term_puts(" cls 清屏\r\n"); + term_puts(" ver 显示版本\r\n"); + term_puts(" set 显示环境变量\r\n"); + term_puts(" help 显示此帮助\r\n"); + term_puts(" exit 返回桌面\r\n"); + term_puts_color("\nPE 程序执行:\r\n", CMD_WARN); + term_puts(" .exe 运行 PE32+/PE32 程序 (如 hello.exe)\r\n"); + term_puts(" 自动查找 name.exe 并运行\r\n"); +} + +static void cmd_ver(void) { + term_puts_color("Deshab CMD [Version 0.1.0]\r\n", CMD_OK); + term_puts_color("(c) 2026 Deshab Project. PE/EXE 兼容层 by UTSM.\r\n", CMD_DIM); +} + +static void cmd_cls(void) { + term_clear_buf(); + term_redraw_all(); +} + +static void cmd_cd(void) { + term_puts("C:\\\r\n"); +} + +static void cmd_set(void) { + term_puts_color("环境变量:\r\n", CMD_INFO); + term_puts(" PATH=C:\\;C:\\bin\r\n"); + term_puts(" PROMPT=$P$G\r\n"); + term_puts(" OS=Deshab\r\n"); + term_puts(" PE_COMPAT=UTSM_PE32+_PE32\r\n"); +} + +/* dir — 列出 FAT32 根目录文件 */ +typedef struct { + int count; + u32 total_bytes; +} dir_ctx_static; + +static int dir_list_cb(const char *name, u32 size, u8 attr, void *ud) { + dir_ctx_static *st = (dir_ctx_static *)ud; + if (attr & 0x10) { + term_puts_color(name, CMD_INFO); + term_puts_color(" ", CMD_DIM); + } else { + term_puts(name); + term_puts(" "); + /* 右对齐文件大小 */ + u32 sz = size; + char numbuf[12]; + int ni = 11; + numbuf[ni--] = 0; + if (sz == 0) numbuf[ni--] = '0'; + while (sz > 0 && ni >= 0) { numbuf[ni--] = (char)('0' + sz % 10); sz /= 10; } + while (ni >= 0) numbuf[ni--] = ' '; + term_puts(&numbuf[0]); + st->total_bytes += size; + } + term_puts("\r\n"); + st->count++; + return 0; +} + +static void cmd_dir(void) { + if (!f32_blk_read) { + term_puts_color("dir: 无块设备\r\n", CMD_ERROR); + return; + } + term_puts_color(" C 盘的卷是 DESHAB\r\n", CMD_DIM); + term_puts_color(" 卷序列号为 DE5A-B002\r\n", CMD_DIM); + term_puts("\r\n C:\\ 的目录\r\n\r\n"); + + dir_ctx_static st = {0, 0}; + f32_list_root(dir_list_cb, &st); + + term_puts("\r\n"); + term_putu((u32)st.count); + term_puts(" 个文件 "); + term_putu(st.total_bytes); + term_puts(" 字节\r\n"); +} + +/* type — 显示文件内容 */ +static void cmd_type(const char *args) { + if (!*args) { term_puts_color("type: 缺少文件名\r\n", CMD_ERROR); return; } + if (!f32_blk_read) { term_puts_color("type: 无块设备\r\n", CMD_ERROR); return; } + + char name11[11]; + if (f32_name_to_83(args, name11) != 0) { + term_puts_color("type: 无效文件名\r\n", CMD_ERROR); + return; + } + u8 *data = 0; u32 size = 0; + if (f32_read_root_file(name11, &data, &size) != 0) { + term_puts_color("type: 文件不存在\r\n", CMD_ERROR); + return; + } + /* 输出文件内容(按字符) */ + for (u32 i = 0; i < size; i++) { + char c = (char)data[i]; + if (c == '\n') term_putc('\r'); + term_putc(c); + } + if (size > 0 && data[size - 1] != '\n') term_putc('\r'); + term_putc('\n'); +} + +/* echo — 显示文本或重定向到文件 */ +static void cmd_echo(const char *args) { + /* 检查重定向: echo text > file */ + char text[256]; + str_copy(text, args, sizeof(text)); + + /* 查找 > */ + int redir = -1; + for (int i = 0; text[i]; i++) { + if (text[i] == '>') { redir = i; break; } + } + + if (redir >= 0) { + /* 重定向到文件 */ + text[redir] = 0; + /* 去尾部空格 */ + int tl = str_len(text); + while (tl > 0 && text[tl - 1] == ' ') text[--tl] = 0; + + /* 获取文件名 */ + char *fn = text + redir + 1; + while (*fn == ' ') fn++; + if (!*fn) { term_puts_color("echo: 重定向缺少文件名\r\n", CMD_ERROR); return; } + + char name11[11]; + if (f32_name_to_83(fn, name11) != 0) { + term_puts_color("echo: 无效文件名\r\n", CMD_ERROR); + return; + } + if (!f32_blk_write) { term_puts_color("echo: 无块设备写能力\r\n", CMD_ERROR); return; } + + /* 构造写入内容 */ + char content[256]; + int ci = 0; + for (int i = 0; i < tl && ci < 254; i++) content[ci++] = text[i]; + content[ci++] = '\r'; + content[ci++] = '\n'; + + if (f32_write_root_file(name11, (const u8 *)content, (u32)ci) != 0) { + term_puts_color("echo: 写入失败\r\n", CMD_ERROR); + return; + } + term_puts_color("echo: 已写入 ", CMD_OK); + term_puts(fn); + term_puts("\r\n"); + } else { + /* 直接显示 */ + if (*args) { + term_puts(args); + } + term_puts("\r\n"); + } +} + +/* copy — 复制文件 */ +static void cmd_copy(const char *args) { + char src[64], dst[64]; + int si = 0, di = 0; + const char *p = args; + while (*p == ' ') p++; + while (*p && *p != ' ' && si < 63) src[si++] = *p++; + src[si] = 0; + while (*p == ' ') p++; + while (*p && di < 63) dst[di++] = *p++; + dst[di] = 0; + + if (!src[0] || !dst[0]) { + term_puts_color("copy: 用法 copy <源文件> <目标文件>\r\n", CMD_ERROR); + return; + } + if (!f32_blk_read || !f32_blk_write) { + term_puts_color("copy: 无块设备\r\n", CMD_ERROR); + return; + } + + char s83[11], d83[11]; + if (f32_name_to_83(src, s83) != 0 || f32_name_to_83(dst, d83) != 0) { + term_puts_color("copy: 无效文件名\r\n", CMD_ERROR); + return; + } + + u8 *data = 0; u32 size = 0; + if (f32_read_root_file(s83, &data, &size) != 0) { + term_puts_color("copy: 源文件不存在\r\n", CMD_ERROR); + return; + } + if (f32_write_root_file(d83, data, size) != 0) { + term_puts_color("copy: 写入失败\r\n", CMD_ERROR); + return; + } + term_puts_color(" 1 个文件已复制。\r\n", CMD_OK); +} + +/* del — 删除文件 */ +static void cmd_del(const char *args) { + if (!*args) { term_puts_color("del: 缺少文件名\r\n", CMD_ERROR); return; } + if (!f32_blk_write) { term_puts_color("del: 无块设备写能力\r\n", CMD_ERROR); return; } + + char name11[11]; + if (f32_name_to_83(args, name11) != 0) { + term_puts_color("del: 无效文件名\r\n", CMD_ERROR); + return; + } + if (f32_delete_root_file(name11) != 0) { + term_puts_color("del: 文件不存在或删除失败\r\n", CMD_ERROR); + return; + } + term_puts_color("del: 已删除\r\n", CMD_OK); +} + +/* ren — 重命名文件 */ +static void cmd_ren(const char *args) { + char old[64], nw[64]; + int oi = 0, ni = 0; + const char *p = args; + while (*p == ' ') p++; + while (*p && *p != ' ' && oi < 63) old[oi++] = *p++; + old[oi] = 0; + while (*p == ' ') p++; + while (*p && ni < 63) nw[ni++] = *p++; + nw[ni] = 0; + + if (!old[0] || !nw[0]) { + term_puts_color("ren: 用法 ren <旧名> <新名>\r\n", CMD_ERROR); + return; + } + if (!f32_blk_read || !f32_blk_write) { + term_puts_color("ren: 无块设备\r\n", CMD_ERROR); + return; + } + + char o83[11], n83[11]; + if (f32_name_to_83(old, o83) != 0 || f32_name_to_83(nw, n83) != 0) { + term_puts_color("ren: 无效文件名\r\n", CMD_ERROR); + return; + } + + u8 *data = 0; u32 size = 0; + if (f32_read_root_file(o83, &data, &size) != 0) { + term_puts_color("ren: 源文件不存在\r\n", CMD_ERROR); + return; + } + if (f32_write_root_file(n83, data, size) != 0) { + term_puts_color("ren: 写入新文件失败\r\n", CMD_ERROR); + return; + } + if (f32_delete_root_file(o83) != 0) { + term_puts_color("ren: 删除旧文件失败(警告)\r\n", CMD_WARN); + } + term_puts_color("ren: 已重命名\r\n", CMD_OK); +} + +static void cmd_mkdir(void) { term_puts_color("mkdir: FAT32 根目录不支持子目录\r\n", CMD_WARN); } +static void cmd_rmdir(void) { term_puts_color("rmdir: FAT32 根目录不支持子目录\r\n", CMD_WARN); } + +/* ============================================================ + * PE/EXE 程序执行 + * ============================================================ */ + +/* 检查文件名是否以 .exe/.com/.bat 结尾(不区分大小写) */ +static int has_exec_ext(const char *name) { + int len = str_len(name); + if (len < 4) return 0; + const char *ext = name + len - 4; + if (ext[0] != '.') return 0; + if (str_ieq(ext, ".exe")) return 1; + if (str_ieq(ext, ".com")) return 1; + if (str_ieq(ext, ".bat")) return 2; + return 0; +} + +/* 执行 PE/EXE 程序。 + * prog_name = 程序名(可能带或不带 .exe 后缀) + * full_cmdline = 完整命令行(程序名 + 参数,即 GetCommandLineA 返回值) + */ +static void exec_pe(const char *prog_name, const char *full_cmdline) { + if (!g_pe_svc) { + term_puts_color("PE 兼容层不可用(UTSM PE 服务未初始化)\r\n", CMD_ERROR); + return; + } + if (!f32_blk_read) { + term_puts_color("无块设备,无法读取 PE 文件\r\n", CMD_ERROR); + return; + } + + /* 构造 8.3 文件名 */ + char base[64]; + str_copy(base, prog_name, sizeof(base)); + + /* 如果没有扩展名,自动补 .exe */ + int has_dot = 0; + for (int i = 0; base[i]; i++) { + if (base[i] == '.') { has_dot = 1; break; } + } + if (!has_dot) { + int bl = str_len(base); + if (bl > 59) bl = 59; + base[bl] = '.'; base[bl + 1] = 'e'; base[bl + 2] = 'x'; + base[bl + 3] = 'e'; base[bl + 4] = 0; + } + + char name11[11]; + if (f32_name_to_83(base, name11) != 0) { + term_puts_color("无效文件名\r\n", CMD_ERROR); + return; + } + + /* 从 FAT32 根目录读取 */ + u8 *pe_data = 0; u32 pe_size = 0; + if (f32_read_root_file(name11, &pe_data, &pe_size) != 0) { + term_puts_color("'", CMD_ERROR); + term_puts_color(prog_name, CMD_ERROR); + term_puts_color("' 不是内部或外部命令,也不是可运行的程序。\r\n", CMD_ERROR); + return; + } + + /* 验证 PE 头(MZ 签名) */ + if (pe_size < 2 || pe_data[0] != 'M' || pe_data[1] != 'Z') { + term_puts_color("不是有效的 PE/EXE 文件(缺少 MZ 签名)\r\n", CMD_ERROR); + return; + } + + term_puts_color("正在执行 ", CMD_INFO); + term_puts_color(prog_name, CMD_WARN); + term_puts_color(" ...\r\n", CMD_INFO); + term_redraw_all(); + + /* 调用 UTSM PE 服务执行 */ + logl("[cmd] PE run begin"); + swrite("[cmd] cmdline: "); swrite(full_cmdline); swrite("\n"); + + u64 exit_code = 0; + int rc = g_pe_svc->run(pe_data, (u64)pe_size, full_cmdline, &exit_code); + + if (rc != 0) { + term_puts_color("PE 执行失败,错误码: ", CMD_ERROR); + term_putx((u32)rc); + term_puts("\r\n"); + } else { + term_puts_color("程序退出,返回码: ", CMD_DIM); + term_putu((u32)exit_code); + term_puts("\r\n"); + } + + logl("[cmd] PE run end"); +} + +/* ============================================================ + * 命令解析与分发 + * ============================================================ */ + +static int g_should_exit = 0; + +static void execute_command(const char *cmd) { + while (*cmd == ' ') cmd++; + if (*cmd == 0) return; + + /* 提取命令名 */ + const char *args = cmd; + while (*args && *args != ' ') args++; + int cmd_name_len = (int)(args - cmd); + char name[64]; + if (cmd_name_len >= 64) cmd_name_len = 63; + for (int i = 0; i < cmd_name_len; i++) name[i] = cmd[i]; + name[cmd_name_len] = 0; + while (*args == ' ') args++; + + /* 内置命令(不区分大小写) */ + if (str_ieq(name, "help") || str_eq(name, "?")) { cmd_help(); return; } + if (str_ieq(name, "ver")) { cmd_ver(); return; } + if (str_ieq(name, "cls") || str_ieq(name, "clear")) { cmd_cls(); return; } + if (str_ieq(name, "dir") || str_ieq(name, "ls")) { cmd_dir(); return; } + if (str_ieq(name, "cd")) { cmd_cd(); return; } + if (str_ieq(name, "type") || str_ieq(name, "cat")) { cmd_type(args); return; } + if (str_ieq(name, "copy") || str_ieq(name, "cp")) { cmd_copy(args); return; } + if (str_ieq(name, "del") || str_ieq(name, "rm")) { cmd_del(args); return; } + if (str_ieq(name, "ren") || str_ieq(name, "mv")) { cmd_ren(args); return; } + if (str_ieq(name, "mkdir") || str_ieq(name, "md")) { cmd_mkdir(); return; } + if (str_ieq(name, "rmdir") || str_ieq(name, "rd")) { cmd_rmdir(); return; } + if (str_ieq(name, "echo")) { cmd_echo(args); return; } + if (str_ieq(name, "set")) { cmd_set(); return; } + if (str_ieq(name, "exit") || str_ieq(name, "quit")) { + term_puts_color("返回桌面...\r\n", CMD_DIM); + g_should_exit = 1; + return; + } + if (str_ieq(name, "reboot")) { + term_puts_color("重启中...\r\n", CMD_WARN); + term_redraw_all(); + for (u64 i = 0; i < 100000000ULL; i++) __asm__ volatile("pause"); + /* 触发三重故障重启 */ + __asm__ volatile("int $0x03"); + return; + } + + /* PE/EXE 执行:检查是否为可执行文件 */ + int ext_type = has_exec_ext(name); + if (ext_type == 1) { + /* .exe/.com → PE 执行 */ + exec_pe(name, cmd); + return; + } + if (ext_type == 2) { + /* .bat → 批处理(暂不支持) */ + term_puts_color("批处理文件 (.bat) 暂不支持\r\n", CMD_WARN); + return; + } + /* 无扩展名 → 尝试自动补 .exe 执行 */ + if (cmd_name_len > 0 && name[0] != '.') { + exec_pe(name, cmd); + return; + } + + /* 未知命令 */ + term_puts_color("'", CMD_ERROR); + term_puts_color(name, CMD_ERROR); + term_puts_color("' 不是内部或外部命令,也不是可运行的程序。\r\n", CMD_ERROR); +} + +/* ============================================================ + * 主入口 + * ============================================================ */ + +__attribute__((visibility("default"))) +void dsk_entry(const dsk_boot_context *ctx) { + __asm__ volatile("cli"); + logl("[cmd] boot"); + + if (!ctx || ctx->magic != 0x44534B31424F4F54ULL) { + logl("[cmd] bad context"); + for (;;) __asm__("hlt"); + } + + fb_a = ctx->framebuffer_address; + fb_w = ctx->framebuffer_width; + fb_h = ctx->framebuffer_height; + fb_p = ctx->framebuffer_pitch; + + g_kernel_api = ctx->dkm_kernel_api; + g_boot_ctx = ctx; + + /* 获取 block 设备 read/write */ + { + u64 api = ctx->dkm_kernel_api; + u64 blk = *(u64 *)(api + 0xA8); + f32_block_read_fn bread = blk ? (f32_block_read_fn)*(u64 *)(blk + 16) : 0; + f32_block_write_fn bwrite = blk ? (f32_block_write_fn)*(u64 *)(blk + 24) : 0; + f32_init(bread, bwrite); + } + if (f32_blk_read) logl("[cmd] block_read ok"); + if (f32_blk_write) logl("[cmd] block_write ok"); + + /* 获取 PE 服务(reserved[4]) */ + { + u64 pe_addr = ctx->reserved[4]; + if (pe_addr) { + const pe_service *pe = (const pe_service *)pe_addr; + if (pe->magic == PE_SERVICE_MAGIC) { + g_pe_svc = pe; + logl("[cmd] PE service ok"); + } else { + logl("[cmd] PE service magic mismatch"); + } + } else { + logl("[cmd] PE service not available"); + } + } + + /* dev_mode 串口镜像 */ + if (ctx->reserved[3] == 1) { + g_serial_mirror = 1; + } + + /* 初始化渲染上下文 */ + du_context_init(&g_ctx, fb_a, fb_w, fb_h, fb_p); + term_init_pos(); + term_clear_buf(); + term_redraw_all(); + + /* 启动 banner */ + term_puts_color("Deshab CMD [Version 0.1.0]\r\n", CMD_OK); + term_puts_color("(c) 2026 Deshab Project. PE/EXE 兼容层 by UTSM.\r\n", CMD_DIM); + term_putc('\r'); + term_putc('\n'); + if (g_pe_svc) { + term_puts_color("PE 兼容层已就绪 (PE32+ 原生 + PE32 解释器)\r\n", CMD_OK); + } else { + term_puts_color("警告: PE 兼容层不可用\r\n", CMD_WARN); + } + term_putc('\r'); + term_putc('\n'); + term_redraw_all(); + + /* 主循环 */ + int shift = 0; + int e0 = 0; + u64 blink_start = rdtsc_cmd(); + g_should_exit = 0; + + for (;;) { + /* 绘制提示符 */ + term_puts_color(PROMPT, CMD_PROMPT); + input_len = 0; + input_cursor = 0; + input_buf[0] = 0; + int prompt_len = str_len(PROMPT); + cur_col = prompt_len; + cur_visible = 1; + redraw_input_line(); + + int cmd_done = 0; + while (!cmd_done && !g_should_exit) { + /* 光标闪烁 */ + if (g_tsc_per_ms) { + u64 now = rdtsc_cmd(); + u64 elapsed = now - blink_start; + int want_vis = (elapsed / (g_tsc_per_ms * 530)) & 1; + if (want_vis != cur_visible) { + if (want_vis) term_redraw_cursor(); + else term_clear_cursor(); + cur_visible = want_vis; + } + } + + u8 st = inb(0x64); + if (!(st & 1)) { __asm__("pause"); continue; } + u8 data = inb(0x60); + if (st & 0x20) continue; /* 忽略鼠标数据 */ + u8 sc = data; + + blink_start = rdtsc_cmd(); + if (!cur_visible) { cur_visible = 1; term_redraw_cursor(); } + + if (sc == 0xE0) { e0 = 1; continue; } + if (sc == 0x2A || sc == 0x36) { shift = 1; continue; } + if (sc == 0xAA || sc == 0xB6) { shift = 0; continue; } + + if (sc & 0x80) { + /* 按键释放 */ + e0 = 0; + continue; + } + + if (e0) { + if (sc == 0x4B) cursor_left(); + else if (sc == 0x4D) cursor_right(); + else if (sc == 0x47) cursor_home(); + else if (sc == 0x4F) cursor_end(); + else if (sc == 0x53) { /* Delete */ } + e0 = 0; + continue; + } + + if (sc == 0x1C) { + /* Enter — 提交命令 */ + term_clear_cursor(); + input_buf[input_len] = 0; + term_putc('\r'); + term_putc('\n'); + execute_command(input_buf); + input_len = 0; + input_cursor = 0; + input_buf[0] = 0; + cmd_done = 1; + term_redraw_all(); + continue; + } + + if (sc == 0x0E) { delete_char_back(); continue; } + if (sc == 0x01) { + /* Esc — 返回桌面 */ + logl("[cmd] esc -> return to DSK"); + g_should_exit = 1; + cmd_done = 1; + continue; + } + if (sc == 0x15 && !shift) { kill_line(); continue; } + + char c = scan_to_ascii(sc, shift); + if (c && c >= 32 && c <= 126) { + insert_char(c); + } + } + + if (g_should_exit) break; + } + + logl("[cmd] exit"); +} diff --git a/CODE/desktop/main.c b/CODE/desktop/main.c index bbfffe7..70d2e53 100644 --- a/CODE/desktop/main.c +++ b/CODE/desktop/main.c @@ -3,12 +3,11 @@ * 布局结构与 D:\Code\Winux-Kate 完全一致: * app-shell * ├── topbar (34px):品牌 + 工作区切换 + 页面切换 + PG 时钟 - * ├── page-host + * page-host * │ ├── 1·DASHBOARD:TERM-01 / TERM-02 / EDITOR / FILES 四面板 + StatusBar * │ ├── 2·IDE:标签栏 + 编辑宿主 - * │ ├── 3·IM:栏 + 分屏槽(未检测卡片) - * │ ├── 4·DESKTOP:图标网格 + 窗口 + 任务栏 - * │ └── 5+/CUSTOM:外部 .elf 全屏宿主(双击启动) + * │ ├── 3·DESKTOP:图标网格 + 窗口 + 任务栏 + * │ └── 4+/CUSTOM:外部 .elf 全屏宿主(双击启动) * └── task-view overlay(工作区卡片) * * 新 UI 特性(Kate 之外): @@ -204,6 +203,10 @@ typedef struct { static du_context g_fb; static u64 g_fb_addr, g_fb_w, g_fb_h, g_fb_pitch; static const void *g_kernel_api; + +/* 双缓冲:渲染到 sprite buffer,完成后一次性 flip 到真实 framebuffer */ +#define SPRITE_BUF_ADDR 0x7000000ULL /* 112MB,在 identity-mapped 区域 */ +static u8 *g_real_fb = 0; /* 真实 framebuffer 地址 */ static desktop_block_read_fn g_block_read; static desktop_block_write_fn g_block_write; static const dsk_boot_context *g_boot_ctx = 0; @@ -246,7 +249,7 @@ static int g_icon_count = 0; /* ---- Kate 外壳状态 ---- */ static int g_booted = 0; -static int g_page = 1; /* 1..4 内置, 5..8 自定义 */ +static int g_page = 1; /* 1..3 内置, 4..8 自定义 */ static int g_taskview = 0; static int g_dash_focus = 0; /* 0=t1 1=t2 2=ed 3=files */ @@ -307,7 +310,6 @@ static int g_ctx_item_ws[MAX_WS + 1]; /* 菜单行 → 真实工作区索引 static int g_ide_host[4]; static int g_ide_tabx[4]; /* IDE 标签 × */ static int g_ide_new_rect[4]; /* IDE "+ NEW IDE" 按钮 */ -static int g_im_toggle_rect[4]; /* IM bar 切换视图按钮 */ static int g_cp_host[4]; /* 自定义页宿主 */ /* ============================================================ @@ -511,16 +513,47 @@ static void cursor_draw(int mx, int my) { } } +/* ---- 双缓冲 flip ---- */ + +/* 将 sprite buffer 完整复制到真实 framebuffer */ +static void flip_buffer(void) { + if (!g_real_fb) return; + u64 total = g_fb_h * g_fb_pitch / 4; + u32 *dst = (u32 *)g_real_fb; + u32 *src = (u32 *)SPRITE_BUF_ADDR; + for (u64 i = 0; i < total; i++) dst[i] = src[i]; +} + +/* 仅复制指定矩形区域(用于鼠标移动时的局部更新) */ +static void flip_rect(int x, int y, int w, int h) { + if (!g_real_fb) return; + for (int r = 0; r < h; r++) { + int ry = y + r; + if (ry < 0 || (u64)ry >= g_fb_h) continue; + u32 *dst = (u32 *)(g_real_fb + (u64)ry * g_fb_pitch); + u32 *src = (u32 *)((u8 *)SPRITE_BUF_ADDR + (u64)ry * g_fb_pitch); + for (int c = 0; c < w; c++) { + int rx = x + c; + if (rx < 0 || (u64)rx >= g_fb_w) continue; + dst[rx] = src[rx]; + } + } +} + /* 非阻塞延时:动画期间持续轮询鼠标,保持光标响应。 */ +__attribute__((unused)) static void anim_delay_poll_mouse(u32 ms) { for (u32 i = 0; i < ms; i++) { for (volatile u32 j = 0; j < 50000; j++) { __asm__ volatile("pause"); } if (ps2_mouse_poll()) { + int old_x = g_cursor_old_x, old_y = g_cursor_old_y; cursor_restore_bg(); + flip_rect(old_x, old_y, CURSOR_SIZE, CURSOR_SIZE); cursor_save_bg(g_mouse_x, g_mouse_y); cursor_draw(g_mouse_x, g_mouse_y); + flip_rect(g_mouse_x, g_mouse_y, CURSOR_SIZE, CURSOR_SIZE); } } } @@ -598,28 +631,8 @@ static void win_destroy(desktop_window *w) { } if (idx < 0) return; - /* 窗口关闭动画 — 收缩矩形 */ - { - int wx = w->x, wy = w->y, ww = w->w, wh = w->h; - int was_cur = (w->ws == g_ws_cur); - w->visible = 0; - if (was_cur) { - for (int step = 5; step >= 0; step--) { - int scale = (step + 1) * 100 / 6; - int aw = ww * scale / 100; - int ah = wh * scale / 100; - int ax = wx + (ww - aw) / 2; - int ay = wy + (wh - ah) / 2; - cursor_restore_bg(); - redraw_all(); - cursor_restore_bg(); - du_rect_outline(&g_fb, ax, ay, aw, ah, KS_ACCENT, DU_RADIUS_SM); - cursor_save_bg(g_mouse_x, g_mouse_y); - cursor_draw(g_mouse_x, g_mouse_y); - anim_delay_poll_mouse(16); - } - } - } + /* 直接隐藏窗口(去掉关闭动画以避免卡顿和闪屏) */ + w->visible = 0; if (w->app_id >= 0 && w->app_id < g_app_count && g_apps[w->app_id].on_destroy && w->app_state) { g_apps[w->app_id].on_destroy(w->app_state); @@ -977,21 +990,25 @@ static void bash_draw_to(bash_state *s, int cx, int cy, int cw, int ch) { } /* ---- 窗口适配 ---- */ +__attribute__((unused)) static void *bash_on_create(app_ctx *ctx) { bash_state *s = (bash_state *)ADDR_TERMWIN; bash_reset(s, ctx->client_w, ctx->client_h); bash_puts(s, "Deshab Bash v0.1\nType help for commands\n\n", KS_TEXT_PRIMARY); return s; } +__attribute__((unused)) static void bash_on_event(void *state, app_ctx *ctx, desktop_event *ev) { if (ev->type != EV_KEY_DOWN) return; bash_key((bash_state *)state, ev->scancode, ev->shift); ctx->win->dirty = 1; } +__attribute__((unused)) static void bash_on_draw(void *state, app_ctx *ctx) { bash_draw_to((bash_state *)state, ctx->client_x, ctx->client_y, ctx->client_w, ctx->client_h); } +__attribute__((unused)) static void bash_on_destroy(void *state) { (void)state; } /* ============================================================ @@ -1313,27 +1330,34 @@ static void calc_on_destroy(void *state) { (void)state; } * ============================================================ */ static void register_apps(void) { + /* 命令行1:shell.elf(原生命令行 + 可运行 Linux 程序)*/ g_apps[0] = (app_descriptor){ - "bash", "Terminal", 640, 440, - bash_on_create, bash_on_event, bash_on_draw, bash_on_destroy, 0 + "shell", "Terminal", 720, 480, + 0, 0, 0, 0, "SHELL ELF" }; g_app_count++; + /* 命令行2:cmd.elf(Windows 风格命令行 + PE/EXE 执行)*/ g_apps[1] = (app_descriptor){ + "cmd", "CMD", 720, 480, + 0, 0, 0, 0, "CMD ELF" + }; + g_app_count++; + g_apps[2] = (app_descriptor){ "editor", "Editor", 600, 450, editor_on_create, editor_on_event, editor_on_draw, editor_on_destroy, 0 }; g_app_count++; - g_apps[2] = (app_descriptor){ + g_apps[3] = (app_descriptor){ "fileman", "Files", 500, 400, 0, 0, 0, 0, "FILEMAN ELF" }; g_app_count++; - g_apps[3] = (app_descriptor){ + g_apps[4] = (app_descriptor){ "calc", "Calculator", 280, 400, calc_on_create, calc_on_event, calc_on_draw, calc_on_destroy, 0 }; g_app_count++; - g_apps[4] = (app_descriptor){ + g_apps[5] = (app_descriptor){ "browser", "Browser", 700, 500, 0, 0, 0, 0, "BROWSER ELF" }; @@ -1510,21 +1534,7 @@ static void launch_app(int app_id) { win->app_state = app->on_create(&ctx); win->dirty = 1; - /* 窗口打开动画 — 展开矩形 */ - for (int step = 0; step < 6; step++) { - int scale = (step + 1) * 100 / 6; - int aw = win->w * scale / 100; - int ah = win->h * scale / 100; - int ax = win->x + (win->w - aw) / 2; - int ay = win->y + (win->h - ah) / 2; - cursor_restore_bg(); - redraw_all(); - cursor_restore_bg(); - du_rect_outline(&g_fb, ax, ay, aw, ah, KS_ACCENT, DU_RADIUS_SM); - cursor_save_bg(g_mouse_x, g_mouse_y); - cursor_draw(g_mouse_x, g_mouse_y); - anim_delay_poll_mouse(16); - } + /* 直接显示窗口(去掉打开动画以避免卡顿和闪屏) */ slog("app launched"); } @@ -1537,6 +1547,16 @@ static int files_list_cb(const char *name, u32 size, u8 attr, void *ud) { (void)ud; if (attr & 0x10) return 0; /* 跳过子目录 */ if (g_file_count >= MAX_FILES) return 1; /* 停止 */ + + /* 只显示 user 文件:跳过 .ELF 可执行文件和系统模块 */ + int nl = kstrlen(name); + if (nl >= 4 && name[nl-4] == '.' && name[nl-3] == 'E' && + name[nl-2] == 'L' && name[nl-1] == 'F') return 0; + /* FIRSTINI* (FirstInit.elf,Name83=FIRSTINIT → 显示名 FIRSTINI.T) */ + if (nl >= 8 && name[0] == 'F' && name[1] == 'I' && name[2] == 'R' && + name[3] == 'S' && name[4] == 'T' && name[5] == 'I' && name[6] == 'N' && + name[7] == 'I') return 0; + fentry *f = &g_files[g_file_count]; f->size = size; kstrcpy(f->disp, name, 13); @@ -1614,7 +1634,7 @@ static void draw_centered(const char *s, int cx, int y, u32 fg, u32 bg) { du_draw_string(&g_fb, s, cx - l * (int)DU_ASCII_STEP / 2, y, fg, bg, DU_ASCII_STEP); } -/* 虚线矩形(ide-host / im-slot / custom host) */ +/* 虚线矩形(ide-host / custom host) */ static void draw_dashed_rect(int x, int y, int w, int h, u32 color) { for (int i = x; i < x + w; i += 8) { du_fill_rect(&g_fb, i, y, 4, 1, color); @@ -1651,6 +1671,7 @@ static void busy_delay(u32 cycles) { static void boot_screen(void) { int W = (int)g_fb_w, H = (int)g_fb_h; du_fill_bg_solid(&g_fb, KS_BG_PRIMARY); + flip_buffer(); int lw = 46 * (int)DU_ASCII_STEP; int lx = (W - lw) / 2; @@ -1663,13 +1684,15 @@ static void boot_screen(void) { char t[2] = { title[i], 0 }; du_draw_string(&g_fb, t, W / 2 - tl * (int)DU_ASCII_STEP + i * (int)DU_ASCII_STEP * 2, ty, KS_ACCENT, 0, DU_ASCII_STEP * 2); - busy_delay(8000000); + flip_buffer(); + busy_delay(2000000); } du_divider_h(&g_fb, W / 2 - 120, ty + 30, 240, KS_ACCENT); /* boot-subtitle(对应 Kate "由 Deaicup 工作室制作") */ draw_centered("DEAICUP STUDIO", W / 2, ty + 44, KS_ACCENT2, 0); - busy_delay(10000000); + flip_buffer(); + busy_delay(2500000); /* boot-lines 打字机;进度条固定在全部行下方(对应 Kate .boot-bar) */ int ly = ty + 76; @@ -1683,7 +1706,8 @@ static void boot_screen(void) { char t[2] = { s[ci], 0 }; du_draw_string(&g_fb, t, lx + (ci + 1) * (int)DU_ASCII_STEP, ly, fg, 0, DU_ASCII_STEP); - busy_delay(500000); + flip_buffer(); + busy_delay(125000); } ly += (int)DU_ASCII_LINE_H + 2; /* boot-bar:渐变填充(accent → accent2) */ @@ -1691,12 +1715,14 @@ static void boot_screen(void) { du_rect_outline(&g_fb, W / 2 - bw / 2, bar_y, bw, 6, KS_BORDER, 1); if (fill > 2) du_fill_rect_gradient(&g_fb, W / 2 - bw / 2 + 1, bar_y + 1, fill - 2, 4, KS_ACCENT, KS_ACCENT2); + flip_buffer(); } /* boot-hint + credit(对应 Kate "SYSTEM ONLINE" + "© 2026 Deaicup Studio") */ draw_centered("SYSTEM ONLINE", W / 2, H - 64, KS_ACCENT2, 0); draw_centered("(C) 2026 DEAICUP STUDIO", W / 2, H - 40, KS_TEXT_DIM, 0); - busy_delay(40000000); + flip_buffer(); + busy_delay(10000000); } /* ============================================================ @@ -1778,8 +1804,8 @@ static void draw_topbar(void) { x += 4; /* 页面切换 */ - static const char *pg_names[4] = { "1.DASHBOARD", "2.IDE", "3.IM", "4.DESKTOP" }; - for (int i = 0; i < 4; i++) { + static const char *pg_names[3] = { "1.DASHBOARD", "2.IDE", "3.DESKTOP" }; + for (int i = 0; i < 3; i++) { int bw = kstrlen(pg_names[i]) * (int)DU_ASCII_STEP + 16; int active = (g_page == i + 1); int hover = g_mouse_x >= x && g_mouse_x < x + bw && @@ -1816,10 +1842,10 @@ static void draw_topbar(void) { du_draw_string(&g_fb, label, x + 6, ty, active ? KS_TEXT_INVERT : KS_TEXT_DIM, 0, DU_ASCII_STEP); du_draw_string(&g_fb, "x", x + bw - 14, ty, KS_DANGER, 0, DU_ASCII_STEP); - g_pg_rect[4 + i][0] = x; g_pg_rect[4 + i][1] = 5; - g_pg_rect[4 + i][2] = bw; g_pg_rect[4 + i][3] = 24; - g_pg_rm_rect[4 + i][0] = x + bw - 20; g_pg_rm_rect[4 + i][1] = 5; - g_pg_rm_rect[4 + i][2] = 20; g_pg_rm_rect[4 + i][3] = 24; + g_pg_rect[3 + i][0] = x; g_pg_rect[3 + i][1] = 5; + g_pg_rect[3 + i][2] = bw; g_pg_rect[3 + i][3] = 24; + g_pg_rm_rect[3 + i][0] = x + bw - 20; g_pg_rm_rect[3 + i][1] = 5; + g_pg_rm_rect[3 + i][2] = 20; g_pg_rm_rect[3 + i][3] = 24; x += bw + 6; } /* pg-add "+" */ @@ -1948,7 +1974,7 @@ static void draw_statusbar_full(void) { du_draw_string(&g_fb, "WIFI --", x, ty, KS_TEXT_DIM, 0, DU_ASCII_STEP); /* 右侧 hint */ - const char *hint = "Ctrl+Tab PAGE . Ctrl+Shift+Tab CTX"; + const char *hint = "Ctrl+Tab PAGE"; du_draw_string(&g_fb, hint, W - 12 - kstrlen(hint) * (int)DU_ASCII_STEP, ty, KS_TEXT_DIM, 0, DU_ASCII_STEP); } @@ -2049,7 +2075,7 @@ static void draw_dashboard(void) { du_fill_rect(&g_fb, fx, fy, fw, fh, KS_BG_PRIMARY); char path_buf[32]; - kstrcpy(path_buf, "FAT32:/ROOT (", 32); + kstrcpy(path_buf, "FAT32:/USER (", 32); int pl = kstrlen(path_buf); if (g_file_count >= 10) path_buf[pl++] = '0' + (char)(g_file_count / 10); path_buf[pl++] = '0' + (char)(g_file_count % 10); @@ -2167,93 +2193,7 @@ static void draw_ide(void) { } } -/* ---- 3·IM ---- */ -static int g_im_view = 0; /* 0=split(WECHAT/QQ) 1=full(WECOM),对应 Kate imView */ - -/* Kate .missing-card:h2 + p + a.btn 下载按钮 */ -static void draw_missing_card(int sx, int sy, int sw, int sh, - const char *title, const char *desc, - const char *btn) { - int cw = 340, ch = 150; - int cx = sx + (sw - cw) / 2, cy = sy + (sh - ch) / 2; - du_kate_panel(&g_fb, cx, cy, cw, ch, 0); - draw_centered(title, sx + sw / 2, cy + 28, KS_ACCENT, 0); - draw_centered(desc, sx + sw / 2, cy + 56, KS_TEXT_DIM, 0); - /* .btn 下载按钮(视觉复刻,Deshab 无网络安装渠道) */ - int bw = kstrlen(btn) * (int)DU_ASCII_STEP + 20; - int bx = sx + sw / 2 - bw / 2, by = cy + 88; - int hover = g_mouse_x >= bx && g_mouse_x < bx + bw && - g_mouse_y >= by && g_mouse_y < by + 22; - if (hover) du_fill_rect(&g_fb, bx, by, bw, 22, KS_ACCENT_DIM); - du_rect_outline(&g_fb, bx, by, bw, 22, KS_BORDER, 1); - du_draw_string(&g_fb, btn, bx + 10, by + 3, KS_ACCENT, 0, DU_ASCII_STEP); -} - -static void draw_im(void) { - int W = (int)g_fb_w; - int top = KATE_TOPBAR_H; - - /* im-bar(36px):dot + 视图标签 + page-credit + 切换按钮(margin-left:auto) */ - du_fill_rect(&g_fb, 0, top, W, 36, 0xFF051828u); - du_divider_h(&g_fb, 0, top + 36, W, KS_BORDER); - int ty = top + (36 - (int)DU_ASCII_LINE_H) / 2 + 1; - - /* .dot(8×8 accent2 发光点) */ - du_fill_rect(&g_fb, 12, top + 14, 8, 8, KS_ACCENT2); - - du_draw_string(&g_fb, - g_im_view ? "WECOM FULLSCREEN" : "WECHAT / QQ SPLIT", - 28, ty, KS_ACCENT, 0, DU_ASCII_STEP); - /* page-credit(对应 Kate "由 Deaicup 工作室制作") */ - du_draw_string(&g_fb, "DEAICUP STUDIO", - 28 + (g_im_view ? 16 : 17) * (int)DU_ASCII_STEP + 12, - ty + 1, KS_TEXT_DIM, 0, DU_ASCII_STEP); - - /* 切换按钮(对应 Kate im_toggle,Ctrl+Shift+Tab) */ - { - const char *tb = "CTRL+SHIFT+TAB SWITCH"; - int bw = kstrlen(tb) * (int)DU_ASCII_STEP + 20; - int bx = W - 12 - bw; - g_im_toggle_rect[0] = bx; g_im_toggle_rect[1] = top + 7; - g_im_toggle_rect[2] = bw; g_im_toggle_rect[3] = 22; - int hover = g_mouse_x >= bx && g_mouse_x < bx + bw && - g_mouse_y >= top + 7 && g_mouse_y < top + 29; - if (hover) du_fill_rect(&g_fb, bx, top + 7, bw, 22, KS_ACCENT_DIM); - du_rect_outline(&g_fb, bx, top + 7, bw, 22, KS_BORDER, 1); - du_draw_string(&g_fb, tb, bx + 10, ty, KS_ACCENT, 0, DU_ASCII_STEP); - } - - if (g_im_view == 0) { - /* im-split 双槽(grid 1fr 1fr, gap/padding 8px) */ - int pad = 8, gap = 8; - int hy = top + 36 + pad; - int hh = (int)g_fb_h - hy - pad; - int sw = (W - 2 * pad - gap) / 2; - for (int i = 0; i < 2; i++) { - int sx = pad + i * (sw + gap); - draw_dashed_rect(sx, hy, sw, hh, KS_BORDER); - } - draw_missing_card(pad, hy, sw, hh, - "WECHAT NOT DETECTED", - "IM MODULE NOT AVAILABLE IN DESHAB", - "DOWNLOAD WECHAT"); - draw_missing_card(pad + sw + gap, hy, sw, hh, - "QQ NOT DETECTED", - "IM MODULE NOT AVAILABLE IN DESHAB", - "DOWNLOAD QQ"); - } else { - /* im-full 单槽(margin 8px) */ - int hx = 8, hy = top + 36 + 8; - int hw = W - 16, hh = (int)g_fb_h - hy - 8; - draw_dashed_rect(hx, hy, hw, hh, KS_BORDER); - draw_missing_card(hx, hy, hw, hh, - "WECOM NOT DETECTED", - "IM MODULE NOT AVAILABLE IN DESHAB", - "DOWNLOAD WECOM"); - } -} - -/* ---- 4·DESKTOP ---- */ +/* ---- 3·DESKTOP ---- */ static void draw_desktop_page(void) { /* 图标网格 */ draw_desktop_icons(); @@ -2610,8 +2550,7 @@ static void redraw_all(void) { /* 页面 */ if (g_page == 1) draw_dashboard(); else if (g_page == 2) draw_ide(); - else if (g_page == 3) draw_im(); - else if (g_page == 4) draw_desktop_page(); + else if (g_page == 3) draw_desktop_page(); else { int idx = -1; for (int i = 0; i < g_cpage_count; i++) @@ -2672,7 +2611,7 @@ static void ws_close(int id) { } static void page_switch(int p) { - if (p < 1 || p > 4 + g_cpage_count) return; + if (p < 1 || p > 3 + g_cpage_count) return; g_page = p; } @@ -2691,7 +2630,7 @@ static void cpage_add(void) { for (int i = 0; i < n; i++) cp->name[i] = g_apps[a].display_name[i]; cp->name[n] = 0; for (int i = 0; i < 11; i++) cp->elf11[i] = g_apps[a].elf_name[i]; - cp->id = 5 + g_cpage_count; + cp->id = 4 + g_cpage_count; g_cpage_count++; g_page = cp->id; return; @@ -2703,7 +2642,7 @@ static void cpage_remove(int idx) { int removed_page = g_cpages[idx].id; for (int i = idx; i < g_cpage_count - 1; i++) g_cpages[i] = g_cpages[i + 1]; g_cpage_count--; - for (int i = 0; i < g_cpage_count; i++) g_cpages[i].id = 5 + i; + for (int i = 0; i < g_cpage_count; i++) g_cpages[i].id = 4 + i; if (g_page == removed_page) g_page = 1; else if (g_page > removed_page) g_page--; } @@ -2911,9 +2850,9 @@ static int on_left_press(void) { for (int i = 0; i < g_ws_count; i++) if (rect_hit(g_ws_rect[i], mx, my)) { ws_switch(i); return 1; } if (rect_hit(g_wsadd_rect, mx, my)) { ws_create(); return 1; } - for (int i = 0; i < 4 + g_cpage_count; i++) { - if (i >= 4 && rect_hit(g_pg_rm_rect[i], mx, my)) { - cpage_remove(i - 4); + for (int i = 0; i < 3 + g_cpage_count; i++) { + if (i >= 3 && rect_hit(g_pg_rm_rect[i], mx, my)) { + cpage_remove(i - 3); return 1; } if (rect_hit(g_pg_rect[i], mx, my)) { page_switch(i + 1); return 1; } @@ -2925,13 +2864,8 @@ static int on_left_press(void) { /* 页面内容 */ if (g_page == 1) return dash_click(mx, my, dbl); if (g_page == 2) return ide_click(mx, my, dbl); - if (g_page == 3) { - /* IM 切换视图按钮(对应 Kate im_toggle) */ - if (rect_hit(g_im_toggle_rect, mx, my)) { g_im_view ^= 1; return 1; } - return 0; - } - if (g_page == 4) return desktop_click(mx, my, dbl); - if (g_page >= 5) { + if (g_page == 3) return desktop_click(mx, my, dbl); + if (g_page >= 4) { int launch = 0; if (rect_hit(g_cp_new_rect, mx, my)) launch = 1; if (dbl && rect_hit(g_cp_host, mx, my)) launch = 1; @@ -2954,7 +2888,7 @@ static int on_right_press(void) { if (g_taskview) { g_taskview = 0; return 1; } if (g_ctx_open) { g_ctx_open = 0; return 1; } - if (g_page != 4) return 0; + if (g_page != 3) return 0; int tb_y = (int)g_fb_h - KATE_TASKBAR_H; if (my >= tb_y) { @@ -3002,12 +2936,11 @@ static int handle_key(u8 sc) { } if (g_taskview || g_ctx_open) return 0; /* 模态期间吞掉按键 */ - /* Ctrl+Tab 切页 / Ctrl+Shift+Tab 上下文菜单(IM 页为切换视图,对应 Kate imView) */ + /* Ctrl+Tab 切页 / Ctrl+Shift+Tab 上下文菜单(DESKTOP 页) */ if (g_ctrl && sc == 0x0F) { if (g_shift) { - if (g_page == 3) { g_im_view ^= 1; return 1; } /* Ctrl+Shift+Tab:对当前聚焦窗口打开"移到工作区"菜单 */ - if (g_page == 4 && win_find(g_focused_win)) { + if (g_page == 3 && win_find(g_focused_win)) { g_ctx_win = g_focused_win; g_ctx_x = g_mouse_x; g_ctx_y = g_mouse_y; g_ctx_open = 1; @@ -3015,7 +2948,7 @@ static int handle_key(u8 sc) { } return 0; } - int maxp = 4 + g_cpage_count; + int maxp = 3 + g_cpage_count; int p = g_page + 1; if (p > maxp) p = 1; page_switch(p); @@ -3047,7 +2980,7 @@ static int handle_key(u8 sc) { } return 0; } - if (g_page == 4) { + if (g_page == 3) { desktop_window *fw = win_find(g_focused_win); if (fw && fw->ws == g_ws_cur && fw->app_id >= 0 && fw->app_id < g_app_count && g_apps[fw->app_id].on_event && fw->app_state) { @@ -3095,6 +3028,9 @@ void dsk_entry(const dsk_boot_context *ctx) { } du_context_init(&g_fb, g_fb_addr, g_fb_w, g_fb_h, g_fb_pitch); + /* 双缓冲:保存真实 fb,切换到 sprite buffer 渲染 */ + g_real_fb = (u8 *)g_fb_addr; + g_fb.fb = (du_u32 *)SPRITE_BUF_ADDR; f32_init(g_block_read, g_block_write); tsc_calibrate(); @@ -3201,13 +3137,16 @@ void dsk_entry(const dsk_boot_context *ctx) { } if (need_redraw) { - cursor_restore_bg(); redraw_all(); + flip_buffer(); /* 全屏 flip:无闪烁 */ } else if (moved) { - /* 仅光标移动:局部更新 */ + /* 仅光标移动:局部 flip(双缓冲 → 无闪烁) */ + int old_x = g_cursor_old_x, old_y = g_cursor_old_y; cursor_restore_bg(); + flip_rect(old_x, old_y, CURSOR_SIZE, CURSOR_SIZE); cursor_save_bg(g_mouse_x, g_mouse_y); cursor_draw(g_mouse_x, g_mouse_y); + flip_rect(g_mouse_x, g_mouse_y, CURSOR_SIZE, CURSOR_SIZE); } __asm__("pause"); diff --git a/CODE/dsk/main.c b/CODE/dsk/main.c index c8aa172..73b3988 100644 --- a/CODE/dsk/main.c +++ b/CODE/dsk/main.c @@ -207,7 +207,7 @@ static int fat32_find_entry(const u8 *clus, u32 clus_sectors, const char *target if (dir[e].attr==0x0F) continue; if (dir[e].attr & 0x08) continue; if (neq11(dir[e].name, target)) { - *out_clus = r16((const u8*)&dir[e].clow); + *out_clus = r16((const u8*)&dir[e].clow) | ((u32)r16((const u8*)&dir[e].chigh) << 16); *out_size = dir[e].fsize; return 0; } @@ -436,10 +436,9 @@ static int fat32_write_root_file(const char *name11, const u8 *data, u32 size) { e->ntr = 0; e->ctenth = 0; e->ctime = 0; e->cdate = 0; e->adate = 0; e->chigh = (u16)((first_clus >> 16) & 0xFFFF); e->wtime = 0; e->wdate = 0; e->clow = (u16)(first_clus & 0xFFFF); + e->fsize = size; } else { - dir[free_entry >= 0 ? (u32)free_entry : 0].chigh = (u16)((first_clus >> 16) & 0xFFFF); - dir[free_entry >= 0 ? (u32)free_entry : 0].clow = (u16)(first_clus & 0xFFFF); - /* Find the existing entry again to update it */ + /* 文件已存在:只更新匹配到的条目(不触碰 free_entry!) */ for (u32 e2 = 0; e2 < max_entries; e2++) { if (neq11(dir[e2].name, name11)) { dir[e2].chigh = (u16)((first_clus >> 16) & 0xFFFF); @@ -449,13 +448,6 @@ static int fat32_write_root_file(const char *name11, const u8 *data, u32 size) { } } } - /* Set file size in the directory entry */ - for (u32 e2 = 0; e2 < max_entries; e2++) { - if (neq11(dir[e2].name, name11)) { - dir[e2].fsize = size; - break; - } - } /* 6. Write FAT + root directory + data sectors back to disk */ /* Write FAT (both copies) */ diff --git a/CODE/dsk/main.o b/CODE/dsk/main.o index 267f9d92dbdceae6ca01b3089b6607fad533ce91..839860947ec469604192ebc591d5be22558b0ebb 100644 GIT binary patch delta 3497 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 H$j$!)Rh_Ch diff --git a/CODE/linux/build.sh b/CODE/linux/build.sh index 4dd375b..dcf19b4 100644 --- a/CODE/linux/build.sh +++ b/CODE/linux/build.sh @@ -109,6 +109,17 @@ if [ -d "$INITRAMFS_DIR" ]; then # Copy initramfs contents cp -a "$INITRAMFS_DIR"/* "$INITRAMFS_TMP"/ + # Build utsm_exec_daemon (static binary for initramfs) + DAEMON_SRC="$INITRAMFS_DIR/bin/utsm_exec_daemon.c" + if [ -f "$DAEMON_SRC" ]; then + echo "[build] Compiling utsm_exec_daemon (static)..." + mkdir -p "$INITRAMFS_TMP/bin" + cc -static -O2 -Wall -I"$PROJECT_ROOT/CODE/utsm-ipc" \ + -o "$INITRAMFS_TMP/bin/utsm_exec_daemon" "$DAEMON_SRC" + strip "$INITRAMFS_TMP/bin/utsm_exec_daemon" 2>/dev/null || true + echo "[build] daemon: $(du -h "$INITRAMFS_TMP/bin/utsm_exec_daemon" | cut -f1)" + fi + # Create init script if not present if [ ! -f "$INITRAMFS_TMP/init" ]; then cat > "$INITRAMFS_TMP/init" <<'INITEOF' diff --git a/CODE/linux/initramfs/bin/utsm_exec_daemon.c b/CODE/linux/initramfs/bin/utsm_exec_daemon.c new file mode 100644 index 0000000..dd6d21a --- /dev/null +++ b/CODE/linux/initramfs/bin/utsm_exec_daemon.c @@ -0,0 +1,218 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * utsm_exec_daemon — Linux guest side exec daemon for Deshab Linux compat layer. + * + * Runs as the first userspace process (PID 2, after init) in the Linux guest. + * Communicates with UTSM via /dev/utsm ioctl interface: + * + * 1. Send EXEC_READY, then ioctl(PARK) → HLT → guest parks + * (this is the first HLT; linux_launch() returns to UTSM) + * 2. On vmresume: ioctl(RECV_MSG) → EXEC_REQUEST + * 3. fork + exec the requested program, capture stdout/stderr via pipe + * 4. Stream output back via ioctl(SEND_MSG, EXEC_STDOUT/STDERR) + * 5. Send EXEC_EXIT with waitpid exit code + * 6. Loop: ioctl(PARK) → wait for next request + * + * Build: static musl/glibc binary, stripped, copied into initramfs /bin/. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Shared IPC protocol — must match UTSM side */ +#include "../../../utsm-ipc/ipc_proto.h" + +/* Ioctl definitions — must match utsm_hcall.c driver */ +#define UTSM_IOCTL_RECV_MSG _IOWR('U', 1, struct utsm_ioctl_msg) +#define UTSM_IOCTL_SEND_MSG _IOWR('U', 2, struct utsm_ioctl_msg) +#define UTSM_IOCTL_PARK _IO('U', 3) +#define UTSM_IOCTL_GET_READY _IOR('U', 4, int) + +struct utsm_ioctl_msg { + unsigned int type; + unsigned int data_len; + unsigned int reserved; + unsigned int buf_size; + unsigned char data[UTSM_IPC_MSG_DATA_SIZE]; +}; + +static int g_utsm_fd = -1; + +/* Send a typed message to UTSM via the linux_to_utsm ring */ +static int send_msg(unsigned int type, const void *data, unsigned int len) +{ + struct utsm_ioctl_msg umsg; + memset(&umsg, 0, sizeof(umsg)); + umsg.type = type; + umsg.data_len = len; + umsg.buf_size = UTSM_IPC_MSG_DATA_SIZE; + if (data && len > 0) { + if (len > UTSM_IPC_MSG_DATA_SIZE) + len = UTSM_IPC_MSG_DATA_SIZE; + memcpy(umsg.data, data, len); + umsg.data_len = len; + } + return ioctl(g_utsm_fd, UTSM_IOCTL_SEND_MSG, &umsg); +} + +/* Receive a message from UTSM (non-blocking). Returns 0 on success, -EAGAIN if empty. */ +static int recv_msg(struct utsm_ioctl_msg *umsg) +{ + memset(umsg, 0, sizeof(*umsg)); + umsg->buf_size = UTSM_IPC_MSG_DATA_SIZE; + return ioctl(g_utsm_fd, UTSM_IOCTL_RECV_MSG, umsg); +} + +/* Park: HLT → VM-Exit → UTSM parks guest. Returns on vmresume. */ +static int park(void) +{ + return ioctl(g_utsm_fd, UTSM_IOCTL_PARK); +} + +/* ===== Exec request handler ===== + * + * Fork a child to exec the requested program. Parent reads stdout/stderr + * from a pipe and streams chunks back to UTSM via EXEC_STDOUT/EXEC_STDERR + * messages. Finally sends EXEC_EXIT with the child's exit status. + * + * argv parsing: argv_blob contains NUL-terminated argv[0..argc-1] + * concatenated. We split it into a char* array for execv. */ +static void handle_exec_request(const struct ipc_exec_request *req) +{ + /* Parse argv_blob into argv[] array */ + char *argv[UTSM_EXEC_MAX_ARGS + 1]; + int argc = (int)req->argc; + if (argc > UTSM_EXEC_MAX_ARGS) argc = UTSM_EXEC_MAX_ARGS; + if (argc < 1) { + struct ipc_exec_exit ex = { .exit_code = 1, .reserved = 0 }; + send_msg(UTSM_MSG_EXEC_EXIT, &ex, sizeof(ex)); + return; + } + + const char *blob = req->argv_blob; + int blob_consumed = 0; + for (int i = 0; i < argc; i++) { + if (blob_consumed >= UTSM_EXEC_ARGV_MAX) { + argv[i] = (char *)""; + continue; + } + argv[i] = (char *)(blob + blob_consumed); + int slen = strnlen(blob + blob_consumed, UTSM_EXEC_ARGV_MAX - blob_consumed); + blob_consumed += slen + 1; + } + argv[argc] = NULL; + + /* Create a pipe for child stdout+stderr */ + int pipefd[2]; + if (pipe(pipefd) != 0) { + struct ipc_exec_exit ex = { .exit_code = 126, .reserved = 0 }; + send_msg(UTSM_MSG_EXEC_EXIT, &ex, sizeof(ex)); + return; + } + + pid_t pid = fork(); + if (pid < 0) { + /* fork failed */ + close(pipefd[0]); + close(pipefd[1]); + struct ipc_exec_exit ex = { .exit_code = 127, .reserved = 0 }; + send_msg(UTSM_MSG_EXEC_EXIT, &ex, sizeof(ex)); + return; + } + + if (pid == 0) { + /* Child: redirect stdout + stderr to pipe write end, then exec */ + close(pipefd[0]); + dup2(pipefd[1], STDOUT_FILENO); + dup2(pipefd[1], STDERR_FILENO); + close(pipefd[1]); + + execv(req->path, argv); + /* execv only returns on failure */ + const char *err1 = "utsm_exec_daemon: exec failed: "; + write(STDERR_FILENO, err1, strlen(err1)); + write(STDERR_FILENO, req->path, strnlen(req->path, UTSM_EXEC_PATH_MAX)); + const char *err2 = ": "; + write(STDERR_FILENO, err2, strlen(err2)); + const char *emsg = strerror(errno); + write(STDERR_FILENO, emsg, strlen(emsg)); + write(STDERR_FILENO, "\n", 1); + _exit(127); + } + + /* Parent: read child output from pipe, stream to UTSM */ + close(pipefd[1]); + + char buf[UTSM_IPC_MSG_DATA_SIZE]; + ssize_t n; + while ((n = read(pipefd[0], buf, sizeof(buf))) > 0) { + send_msg(UTSM_MSG_EXEC_STDOUT, buf, (unsigned int)n); + } + close(pipefd[0]); + + /* Wait for child and send exit code */ + int status = 0; + waitpid(pid, &status, 0); + + struct ipc_exec_exit ex; + ex.reserved = 0; + if (WIFEXITED(status)) { + ex.exit_code = (unsigned int)WEXITSTATUS(status); + } else if (WIFSIGNALED(status)) { + ex.exit_code = 128u + (unsigned int)WTERMSIG(status); + } else { + ex.exit_code = 1; + } + send_msg(UTSM_MSG_EXEC_EXIT, &ex, sizeof(ex)); +} + +/* ===== Main loop ===== */ + +int main(void) +{ + g_utsm_fd = open("/dev/utsm", O_RDWR); + if (g_utsm_fd < 0) { + /* Cannot communicate with UTSM — exit */ + return 1; + } + + /* Announce daemon ready. UTSM's linux_launch() will see the subsequent + * HLT (via PARK ioctl) and return, marking the compat layer ready. */ + send_msg(UTSM_MSG_EXEC_READY, NULL, 0); + + /* First park: this is the HLT that causes linux_launch() to return. */ + park(); + + /* Main loop: process exec requests */ + for (;;) { + struct utsm_ioctl_msg umsg; + + /* Drain any pending messages (there may be multiple if UTSM + * queued several before vmresume). */ + int got_request = 0; + while (recv_msg(&umsg) == 0) { + if (umsg.type == UTSM_MSG_EXEC_REQUEST && + umsg.data_len >= sizeof(struct ipc_exec_request)) { + handle_exec_request((const struct ipc_exec_request *)umsg.data); + got_request = 1; + } + /* Ignore other message types (HELLO, PING, etc.) */ + } + + /* If we processed a request, the response is already sent. + * Park to let UTSM read the response and return to shell. + * If no request (spurious wakeup), just park again. */ + park(); + } + + close(g_utsm_fd); + return 0; +} diff --git a/CODE/linux/initramfs/init b/CODE/linux/initramfs/init new file mode 100644 index 0000000..5850368 --- /dev/null +++ b/CODE/linux/initramfs/init @@ -0,0 +1,47 @@ +#!/bin/sh +# +# init — Linux guest init script for UTSM dual-kernel Linux compat layer. +# +# Boot sequence: +# 1. Mount essential filesystems +# 2. Load UTSM driver (built-in, /dev/utsm auto-created) +# 3. Start utsm_exec_daemon (background) +# 4. Daemon sends EXEC_READY, then HLT (park) → linux_launch() returns to UTSM +# 5. UTSM proceeds to load DSK; Linux guest stays parked until shell +# invokes `linux ` which triggers vmresume. +# +# The daemon runs forever, parking between requests. This init script +# should NOT exit (would panic the kernel); it sleeps indefinitely after +# starting the daemon so the kernel has a runnable init task. + +PATH=/bin:/sbin:/usr/bin:/usr/sbin +export PATH + +# Mount essential filesystems +mount -t proc none /proc 2>/dev/null +mount -t sysfs none /sys 2>/dev/null +mount -t devtmpfs none /dev 2>/dev/null + +echo "[utsm-linux] init started" +echo "[utsm-linux] kernel: $(uname -r)" + +# Verify /dev/utsm exists (driver is built-in, should be auto-created) +if [ ! -e /dev/utsm ]; then + echo "[utsm-linux] WARNING: /dev/utsm not found — UTSM driver not loaded" +fi + +# Start the exec daemon in the background. +# The daemon sends EXEC_READY then HLTs (parks the guest). +# UTSM's linux_launch() returns after this first HLT. +echo "[utsm-linux] starting utsm_exec_daemon..." +/bin/utsm_exec_daemon & +DAEMON_PID=$! +echo "[utsm-linux] daemon PID=$DAEMON_PID" + +# init must not exit — sleep forever to keep the kernel happy. +# The daemon handles all UTSM exec requests; init just keeps the +# root task alive so the kernel doesn't panic. +echo "[utsm-linux] init: daemon running, entering idle hold" +while true; do + sleep 3600 +done diff --git a/CODE/linux/patches/utsm_hcall.c b/CODE/linux/patches/utsm_hcall.c index f61b653..231b6a1 100644 --- a/CODE/linux/patches/utsm_hcall.c +++ b/CODE/linux/patches/utsm_hcall.c @@ -23,12 +23,43 @@ #include #include #include +#include +#include +#include /* Shared IPC protocol header (included via build.sh -I flag) */ #include #define UTSM_DEV_NAME "utsm" +/* ===== Ioctl interface for exec daemon ===== + * + * The exec daemon (userspace) uses these ioctls to: + * 1. RECV_MSG: poll utsm_to_linux ring for EXEC_REQUEST (non-blocking) + * 2. SEND_MSG: push STDOUT/STDERR/EXIT to linux_to_utsm ring + * 3. PARK: execute HLT to trigger VM-Exit → UTSM parks guest, + * returning control to the host. vmresume causes the + * ioctl to return, at which point the daemon re-checks + * the ring for new requests. + * + * This explicit-park model avoids the need for timer emulation or + * IRQ injection: the daemon HLTs only when it has nothing to do, + * and UTSM vmresumes only when there is work. */ + +#define UTSM_IOCTL_RECV_MSG _IOWR('U', 1, struct utsm_ioctl_msg) +#define UTSM_IOCTL_SEND_MSG _IOWR('U', 2, struct utsm_ioctl_msg) +#define UTSM_IOCTL_PARK _IO('U', 3) +#define UTSM_IOCTL_GET_READY _IOR('U', 4, int) + +/* Ioctl message wrapper: carries type + data in a single call */ +struct utsm_ioctl_msg { + u32 type; /* message type (in/out) */ + u32 data_len; /* actual bytes in data (in/out) */ + u32 reserved; + u32 buf_size; /* capacity of data buffer (in) */ + u8 data[UTSM_IPC_MSG_DATA_SIZE]; /* payload */ +}; + /* ===== Hypercall ABI ===== * * Linux calls VMCALL with: @@ -169,10 +200,116 @@ static ssize_t utsm_dev_read(struct file *f, char __user *buf, return (ssize_t)msg.data_len; } +/* ===== Ioctl handlers for exec daemon ===== */ + +static long utsm_dev_ioctl(struct file *f, unsigned int cmd, unsigned long arg) +{ + if (!g_shm_mapped) + return -ENODEV; + + switch (cmd) { + case UTSM_IOCTL_RECV_MSG: { + /* Non-blocking dequeue from utsm_to_linux ring */ + struct utsm_ioctl_msg umsg; + struct utsm_ipc_msg msg; + int ret; + + if (copy_from_user(&umsg, (void __user *)arg, sizeof(umsg))) + return -EFAULT; + + ret = utsm_ipc_ring_pop(&g_shm->utsm_to_linux, &msg); + if (ret != 0) + return -EAGAIN; /* ring empty */ + + umsg.type = msg.type; + umsg.data_len = msg.data_len; + if (umsg.buf_size < msg.data_len) + return -EINVAL; + if (msg.data_len > 0) { + if (copy_to_user(umsg.data, msg.data, msg.data_len)) + return -EFAULT; + } + if (copy_to_user((void __user *)arg, &umsg, sizeof(umsg))) + return -EFAULT; + return 0; + } + + case UTSM_IOCTL_SEND_MSG: { + /* Enqueue to linux_to_utsm ring */ + struct utsm_ioctl_msg umsg; + struct utsm_ipc_msg msg; + + if (copy_from_user(&umsg, (void __user *)arg, sizeof(umsg))) + return -EFAULT; + + memset(&msg, 0, sizeof(msg)); + msg.type = umsg.type; + msg.data_len = min_t(u32, umsg.data_len, UTSM_IPC_MSG_DATA_SIZE); + if (msg.data_len > 0) { + if (copy_from_user(msg.data, umsg.data, msg.data_len)) + return -EFAULT; + } + + if (utsm_ipc_ring_push(&g_shm->linux_to_utsm, &msg) != 0) { + pr_warn("[utsm] linux_to_utsm ring full\n"); + return -EAGAIN; + } + return 0; + } + + case UTSM_IOCTL_PARK: { + /* Execute HLT to trigger VM-Exit → UTSM parks guest. + * Interrupts must be enabled so that on vmresume the guest + * can continue (HLT with interrupts disabled would hang). + * + * Flow: + * 1. daemon calls ioctl(PARK) → driver executes HLT + * 2. HLT → VM-Exit (CPU_BASED_HLT_EXITING) → UTSM handle_hlt + * 3. UTSM advances RIP past HLT, exits to host (park) + * 4. UTSM writes request + vmresume + * 5. Guest continues from after HLT → ioctl returns + * 6. Daemon re-checks ring for new EXEC_REQUEST + */ + mb(); /* ensure prior ring writes are visible before HLT */ + asm volatile("hlt" ::: "memory"); + return 0; + } + + case UTSM_IOCTL_GET_READY: { + int ready = (g_shm->header.utsm_ready && g_shm->header.linux_ready) ? 1 : 0; + if (copy_to_user((void __user *)arg, &ready, sizeof(ready))) + return -EFAULT; + return 0; + } + + default: + return -ENOTTY; + } +} + +static __poll_t utsm_dev_poll(struct file *f, struct poll_table_struct *wait) +{ + __poll_t mask = 0; + + if (!g_shm_mapped) + return EPOLLERR; + + /* Report readable if utsm_to_linux ring has messages */ + if (!utsm_ipc_ring_empty(&g_shm->utsm_to_linux)) + mask |= EPOLLIN | EPOLLRDNORM; + + /* Always writable (ring push may still fail with -EAGAIN) */ + mask |= EPOLLOUT | EPOLLWRNORM; + + return mask; +} + static const struct file_operations utsm_fops = { - .owner = THIS_MODULE, - .write = utsm_dev_write, - .read = utsm_dev_read, + .owner = THIS_MODULE, + .write = utsm_dev_write, + .read = utsm_dev_read, + .unlocked_ioctl = utsm_dev_ioctl, + .poll = utsm_dev_poll, }; static struct miscdevice utsm_miscdev = { diff --git a/CODE/login/main.c b/CODE/login/main.c index ab49451..c5e4aef 100644 --- a/CODE/login/main.c +++ b/CODE/login/main.c @@ -226,6 +226,104 @@ static void draw_rounded_input(u32 *fb, i64 x, i64 y, i64 w, i64 h, const char * } } +/* ---- PS/2 鼠标光标 ---- */ +#define CURSZ 16 +static int g_mouse_x = 400, g_mouse_y = 300; +static int g_mouse_btn = 0; +static u32 g_cursor_bg[CURSZ * CURSZ]; +static int g_cursor_saved = 0; +static int g_cursor_old_x = -1, g_cursor_old_y = -1; +static u8 g_mouse_buf[3]; +static int g_mouse_idx = 0; + +/* 16×16 箭头光标(与 desktop 一致) */ +static const u8 cursor_shape[16][16] = { + {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0}, + {1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0}, + {1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0}, + {1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0}, + {1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0}, + {1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0}, + {1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0}, + {1,1,1,1,1,0,1,1,0,0,0,0,0,0,0,0}, + {1,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0}, + {1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, +}; + +static void cursor_save_bg(u32 *fb, int mx, int my) { + for (int r = 0; r < CURSZ; r++) { + for (int c = 0; c < CURSZ; c++) { + int x = mx + c, y = my + r; + if (x >= 0 && (u64)x < fb_w && y >= 0 && (u64)y < fb_h) { + u32 *line = (u32 *)((u8 *)fb + (u64)y * fb_p); + g_cursor_bg[r * CURSZ + c] = line[x]; + } else { + g_cursor_bg[r * CURSZ + c] = 0; + } + } + } + g_cursor_saved = 1; + g_cursor_old_x = mx; + g_cursor_old_y = my; +} + +static void cursor_restore_bg(u32 *fb) { + if (!g_cursor_saved) return; + for (int r = 0; r < CURSZ; r++) { + for (int c = 0; c < CURSZ; c++) { + int x = g_cursor_old_x + c, y = g_cursor_old_y + r; + if (x >= 0 && (u64)x < fb_w && y >= 0 && (u64)y < fb_h) { + u32 *line = (u32 *)((u8 *)fb + (u64)y * fb_p); + line[x] = g_cursor_bg[r * CURSZ + c]; + } + } + } + g_cursor_saved = 0; +} + +static void cursor_draw(u32 *fb, int mx, int my) { + u32 fg = ACCENT; + for (int r = 0; r < CURSZ; r++) { + for (int c = 0; c < CURSZ; c++) { + if (!cursor_shape[r][c]) continue; + int x = mx + c, y = my + r; + if (x >= 0 && (u64)x < fb_w && y >= 0 && (u64)y < fb_h) { + u32 *line = (u32 *)((u8 *)fb + (u64)y * fb_p); + line[x] = fg; + } + } + } +} + +static int ps2_mouse_poll(void) { + u8 st = inb(0x64); + if (!(st & 1)) return 0; + if (!(st & 0x20)) return 0; + u8 data = inb(0x60); + g_mouse_buf[g_mouse_idx++] = data; + if (g_mouse_idx < 3) return 0; + g_mouse_idx = 0; + if (!(g_mouse_buf[0] & 0x08)) return 0; + int dx = (int)(i8)g_mouse_buf[1]; + int dy = -(int)(i8)g_mouse_buf[2]; + g_mouse_x += dx; + g_mouse_y += dy; + if (g_mouse_x < 0) g_mouse_x = 0; + if (g_mouse_y < 0) g_mouse_y = 0; + if (g_mouse_x >= (int)fb_w - CURSZ) g_mouse_x = (int)fb_w - CURSZ; + if (g_mouse_y >= (int)fb_h - CURSZ) g_mouse_y = (int)fb_h - CURSZ; + int old_btn = g_mouse_btn; + g_mouse_btn = g_mouse_buf[0] & 0x03; + if (dx == 0 && dy == 0 && g_mouse_btn == old_btn) return 0; + return 1; +} + /* ---- PS/2 scan code set 1 → ASCII ---- */ static char scan_to_ascii(u8 sc, int shift) { static const char normal[58] = { @@ -406,6 +504,7 @@ static void draw_login_card(u32 *fb, i64 card_x, i64 card_y, const char *pass, i u32 card = CARD_BG; u32 sub_fg = 0xFF9098A0; /* Background + card */ + cursor_restore_bg(fb); fill_gradient_rect(fb, card_x - 24, card_y - 24, CARD_W + 48, CARD_H + 48); draw_card(fb, card_x, card_y, CARD_W, CARD_H, card); /* Title */ @@ -432,14 +531,19 @@ static void draw_login_card(u32 *fb, i64 card_x, i64 card_y, const char *pass, i /* Bottom hint */ fb_text(fb, "Enter=login Esc=skip Backspace=delete", card_x + 40, card_y + CARD_H - 28, DIM_FG, card); + cursor_save_bg(fb, g_mouse_x, g_mouse_y); + cursor_draw(fb, g_mouse_x, g_mouse_y); } /* Redraw only the password input field (avoids full card redraw on each keystroke) */ static void redraw_password_only(u32 *fb, i64 card_x, i64 card_y, const char *pass, u32 fg) { u32 card = CARD_BG; i64 fy = card_y + 240; + cursor_restore_bg(fb); fill_rect(fb, card_x + 40, fy, CARD_W - 80, 44, card); draw_rounded_input(fb, card_x + 40, fy, CARD_W - 80, 44, pass, 1, fg, card, 1); + cursor_save_bg(fb, g_mouse_x, g_mouse_y); + cursor_draw(fb, g_mouse_x, g_mouse_y); } /* ---- verify password against stored hash or encrypted conf ---- @@ -562,15 +666,26 @@ void dsk_entry(const dsk_boot_context *ctx) { /* Draw initial UI */ draw_login_card(fb, card_x, card_y, pass, 1, msg, msg_color, fg); + /* 初始鼠标光标 */ + cursor_save_bg(fb, g_mouse_x, g_mouse_y); + cursor_draw(fb, g_mouse_x, g_mouse_y); + /* Input loop */ int shift = 0; int release = 0; for (;;) { + /* 鼠标轮询:处理鼠标移动并更新光标 */ + if (ps2_mouse_poll()) { + cursor_restore_bg(fb); + cursor_save_bg(fb, g_mouse_x, g_mouse_y); + cursor_draw(fb, g_mouse_x, g_mouse_y); + } + u8 st = inb(0x64); if (!(st & 1)) { __asm__("pause"); continue; } + /* 跳过鼠标数据(由 ps2_mouse_poll 处理) */ + if (st & 0x20) { inb(0x60); continue; } u8 data = inb(0x60); - /* Skip mouse data (bit 5 of status) */ - if (st & 0x20) continue; u8 sc = data; /* Handle extended (E0) sequences — ignore (no arrow keys needed for login) */ diff --git a/CODE/shell/main.c b/CODE/shell/main.c index ecada58..c970248 100644 --- a/CODE/shell/main.c +++ b/CODE/shell/main.c @@ -4,6 +4,8 @@ */ #include "../UTSM/include/utsm/dsk.h" +#include "../UTSM/include/utsm/pe.h" +#include "../UTSM/include/utsm/linux_compat.h" typedef unsigned char u8; typedef unsigned short u16; @@ -72,8 +74,6 @@ static void logl(const char *s) { swrite(s); swrite("\n"); } /* ASCII 字体 — 必须在 deshab_ui.h 之前包含,因为 du_draw_char 引用 g_ascii */ #include "../firstInit/ascii_bitmaps.c" #include "../UTSM/include/utsm/deshab_ui.h" -/* 用户态共享协议栈(ping/curl 内建命令使用) */ -#include "../tools/net_stack.h" /* ============================================================ * Block 设备 + FAT32 读写(移植自 DSK,支持 cp/mv/cat/ls) @@ -190,16 +190,57 @@ static int fat32_find_in_root(const u8 *clus, u32 clus_sectors, const char *targ return -1; } -/* 读取根目录下指定 8.3 名文件到 g_fdata。 +/* 在目录簇链中查找名为 name11 的子目录(attr & 0x10),返回首簇号。 + * dir_clus: 目录起始簇号。返回 0 成功,-1 未找到。 */ +static int fat32_find_dir(u32 dir_clus, const char *name11, u32 *out_clus) { + if (sh_disk_load() != 0) return -2; + const shell_fat32_bpb *bpb = (const shell_fat32_bpb *)g_disk; + u32 data_lba = bpb->rsvd + (u32)bpb->fc * bpb->spf; + u32 fat_byte_off = bpb->rsvd * 512; + u32 spc = bpb->spc; + u32 clus = dir_clus; + while (clus >= 2 && clus < 0x0FFFFFF8) { + u32 lba = data_lba + (clus - 2) * spc; + const u8 *cb; + if ((u64)lba * 512 + (u64)spc * 512 <= 256ULL * 512) + cb = g_disk + (u64)lba * 512; + else { + if (sh_read_sectors(lba, 8, g_cluster) != 0) return -4; + cb = g_cluster; + } + const shell_fat32_de *dir = (const shell_fat32_de *)cb; + for (u32 e = 0; e * 32 < spc * 512; e++) { + if (dir[e].name[0] == 0) goto done_dir; + if ((u8)dir[e].name[0] == 0xE5) continue; + if (dir[e].attr == 0x0F) continue; + if (dir[e].attr & 0x08) continue; + if (!(dir[e].attr & 0x10)) continue; /* 只匹配目录 */ + if (sh_neq11(dir[e].name, name11)) { + *out_clus = (u32)sh_r16((const u8*)&dir[e].clow) + | ((u32)sh_r16((const u8*)&dir[e].chigh) << 16); + return 0; + } + } + u32 fo = fat_byte_off + clus * 4; + if (fo + 4 > sizeof(g_disk)) break; + clus = sh_r32(g_disk + fo) & 0x0FFFFFFF; + } +done_dir: + return -1; +} + +/* 从指定目录首簇读取文件到 g_fdata。 + * dir_clus: 目录起始簇号。name11: 8.3 名。 * 返回 0 成功,*out_data 指向 g_fdata,*out_size 为字节数;非 0 失败。 */ -static int fat32_read_root_file(const char *name11, u8 **out_data, u32 *out_size) { +static int fat32_read_file_in_dir(u32 dir_clus, const char *name11, + u8 **out_data, u32 *out_size) { if (sh_disk_load() != 0) return -1; const shell_fat32_bpb *bpb = (const shell_fat32_bpb *)g_disk; u32 data_lba = bpb->rsvd + (u32)bpb->fc * bpb->spf; u32 fat_byte_off = bpb->rsvd * 512; u32 spc = bpb->spc; - u32 clus = bpb->root_clus; + u32 clus = dir_clus; u32 found_clus = 0, found_size = 0; int found = 0; while (clus >= 2 && clus < 0x0FFFFFF8 && !found) { @@ -241,6 +282,37 @@ static int fat32_read_root_file(const char *name11, u8 **out_data, u32 *out_size return 0; } +/* 读取根目录下指定 8.3 名文件到 g_fdata。 + * 返回 0 成功,*out_data 指向 g_fdata,*out_size 为字节数;非 0 失败。 */ +static int fat32_read_root_file(const char *name11, u8 **out_data, u32 *out_size) { + if (sh_disk_load() != 0) return -1; + const shell_fat32_bpb *bpb = (const shell_fat32_bpb *)g_disk; + return fat32_read_file_in_dir(bpb->root_clus, name11, out_data, out_size); +} + +/* /bin 目录首簇号缓存 */ +static u32 g_bin_clus = 0; +static int g_bin_checked = 0; + +/* 获取 /bin 目录首簇号。返回 0 成功,-1 未找到。 */ +static int get_bin_cluster(u32 *out_clus) { + if (g_bin_checked) { + if (g_bin_clus == 0) return -1; + *out_clus = g_bin_clus; + return 0; + } + g_bin_checked = 1; + if (sh_disk_load() != 0) { g_bin_clus = 0; return -1; } + const shell_fat32_bpb *bpb = (const shell_fat32_bpb *)g_disk; + char bin83[11] = {'B','I','N',' ',' ',' ',' ',' ',' ',' ',' '}; + if (fat32_find_dir(bpb->root_clus, bin83, &g_bin_clus) != 0) { + g_bin_clus = 0; + return -1; + } + *out_clus = g_bin_clus; + return 0; +} + /* 写入根目录下指定 8.3 名文件(存在则替换,不存在则新建)。 * 依赖 g_disk 已加载 BPB+FAT。返回 0 成功。 */ static int fat32_write_root_file(const char *name11, const u8 *data, u32 size) { @@ -804,11 +876,14 @@ static void cmd_help(void) { term_puts(" date 显示当前日期\n"); term_puts(" about 关于 Deshab\n"); term_puts(" pci 列出 PCI 设备\n"); - term_puts(" ping [ip] ICMP echo 测试(缺省网关 10.0.2.2)\n"); - term_puts(" curl HTTP GET 请求(http://host[:port]/path)\n"); term_puts(" run 运行根目录下的工具程序\n"); + term_puts(" linux [args] 通过双内核兼容层运行 Linux 程序\n"); term_puts(" reboot 重启系统\n"); term_puts(" halt 关机(停止 CPU)\n"); + term_putc('\n'); + term_puts_color("外部命令(/bin/ 目录,PATH 自动查找):\n", DIM_FG); + term_puts(" ping ICMP echo 测试工具\n"); + term_puts(" curl HTTP GET 请求工具\n"); } static void cmd_version(void) { @@ -1234,193 +1309,9 @@ static void cmd_pci(void) { term_puts_color(tail, DIM_FG); } -/* ============================================================ - * 网络命令:ping / curl(共享协议栈 net_stack.h) - * ============================================================ */ - static u64 g_kernel_api = 0; static const dsk_boot_context *g_boot_ctx = 0; -static int g_ns_status = 0; /* 0=未尝试, 1=就绪, <0=初始化失败 */ - -static int shell_net_ready(void) { - if (g_ns_status == 1) return 1; - if (g_ns_status < 0) return 0; - int rc = ns_init(g_kernel_api); - g_ns_status = (rc == 0) ? 1 : -1; - if (rc != 0) { - logl("[shell] ns_init failed"); - term_puts_color("网络初始化失败 (rc=", ERROR_FG); - char rcbuf[4]; - rcbuf[0] = (char)('0' + (-rc % 10)); - rcbuf[1] = 0; - term_puts_color(rcbuf, ERROR_FG); - term_puts_color("),无可用网卡或 net API\n", ERROR_FG); - return 0; - } - logl("[shell] ns_init ok"); - return 1; -} - -/* ping [a.b.c.d] — 缺省网关 10.0.2.2,4 次 echo */ -static void cmd_ping(const char *args) { - u32 ip; - if (!args || !*args) { - ip = NS_GATEWAY_IP; - } else if (ns_parse_ip(args, &ip) != 0) { - term_puts_color("用法: ping [a.b.c.d]\n", ERROR_FG); - return; - } - if (!shell_net_ready()) return; - - char ipstr[24]; - ns_fmt_ip(ip, ipstr); - term_puts_color("PING ", PROMPT_FG); - term_puts_color(ipstr, ACCENT_FG); - term_puts_color(" 32 data bytes\n", DIM_FG); - - int sent = 0, recv = 0; - u32 sum = 0, min = 0xFFFFFFFFu, max = 0; - for (u16 seq = 1; seq <= 4; seq++) { - u32 rtt = 0; u8 ttl = 0; - int rc = ns_ping(ip, seq, 2000, &rtt, &ttl); - sent++; - if (rc == 0) { - recv++; - sum += rtt; - if (rtt < min) min = rtt; - if (rtt > max) max = rtt; - term_puts("reply from "); - term_puts(ipstr); - term_puts(": bytes=32 time="); - char nb[12]; ns_u32_dec(nb, rtt); - term_puts(nb); - term_puts("ms TTL="); - ns_u32_dec(nb, ttl); - term_puts(nb); - term_putc('\n'); - } else if (rc == -1) { - term_puts_color("ARP 解析失败,目标不可达\n", ERROR_FG); - break; - } else { - term_puts_color("request timed out\n", DIM_FG); - } - } - /* 统计行 */ - char nb[12]; - ns_u32_dec(nb, (u32)sent); - term_puts_color("--- ", DIM_FG); - term_puts_color(ipstr, DIM_FG); - term_puts_color(" ping statistics ---\n ", DIM_FG); - term_puts(nb); - term_puts(" transmitted, "); - ns_u32_dec(nb, (u32)recv); - term_puts(nb); - term_puts(" received, "); - u32 loss = sent ? (u32)(sent - recv) * 100 / (u32)sent : 100; - ns_u32_dec(nb, loss); - term_puts(nb); - term_puts("% loss"); - if (recv > 0) { - term_puts(", min/avg/max = "); - ns_u32_dec(nb, min); term_puts(nb); term_puts("/"); - ns_u32_dec(nb, sum / (u32)recv); term_puts(nb); term_puts("/"); - ns_u32_dec(nb, max); term_puts(nb); term_puts(" ms"); - } - term_putc('\n'); -} - -/* curl http://host[:port][/path] — HTTP/1.0 GET,打印 status + body */ -static void cmd_curl(const char *args) { - if (!args || !*args) { - term_puts_color("用法: curl http://host[:port][/path]\n", ERROR_FG); - return; - } - if (!shell_net_ready()) return; - - const char *p = args; - if (p[0]=='h'&&p[1]=='t'&&p[2]=='t'&&p[3]=='p'&&p[4]==':'&&p[5]=='/'&&p[6]=='/') p += 7; - - char host[128]; int hl = 0; - while (*p && *p != ':' && *p != '/' && hl < 127) host[hl++] = *p++; - host[hl] = 0; - if (!hl) { term_puts_color("curl: 缺少主机名\n", ERROR_FG); return; } - - u16 port = 80; - if (*p == ':') { - p++; - u32 pv = 0; int digits = 0; - while (*p >= '0' && *p <= '9') { pv = pv * 10 + (u32)(*p - '0'); p++; digits++; } - if (digits && pv <= 65535) port = (u16)pv; - } - char path[128]; int pl = 0; - if (*p == '/') { - while (*p && *p != ' ' && pl < 127) path[pl++] = *p++; - } - if (!pl) { path[0] = '/'; pl = 1; } - path[pl] = 0; - - /* 解析主机 */ - u32 ip; - term_puts_color("-> 解析 ", DIM_FG); - term_puts_color(host, DIM_FG); - term_puts_color("...\n", DIM_FG); - if (ns_dns_resolve(host, &ip) != 0) { - term_puts_color("curl: DNS 解析失败\n", ERROR_FG); - return; - } - char ipstr[24]; ns_fmt_ip(ip, ipstr); - term_puts_color("-> ", DIM_FG); - term_puts_color(ipstr, DIM_FG); - term_putc('\n'); - - /* 连接 */ - term_puts_color("-> TCP 连接...\n", DIM_FG); - if (ns_tcp_connect(ip, port, 2000) != 0) { - term_puts_color("curl: TCP 连接失败(超时/RST)\n", ERROR_FG); - return; - } - term_puts_color("-> 已连接,发送请求\n", DIM_FG); - - /* 构造 HTTP/1.0 请求 */ - static char req[512]; - int r = 0; - const char *m = "GET "; while (*m) req[r++] = *m++; - for (int i = 0; i < pl; i++) req[r++] = path[i]; - m = " HTTP/1.0\r\nHost: "; while (*m) req[r++] = *m++; - for (int i = 0; i < hl; i++) req[r++] = host[i]; - m = "\r\nConnection: close\r\n\r\n"; while (*m) req[r++] = *m++; - req[r] = 0; - - if (ns_tcp_send((const u8 *)req, (u32)r) != 0) { - term_puts_color("curl: 发送失败\n", ERROR_FG); - ns_tcp_close(); - return; - } - - /* 收至 FIN(数据在协议栈 ns_tcp_rx 中累计) */ - int n = ns_tcp_recv(0, 0, 5000); - ns_tcp_close(); - if (n < 0) { - term_puts_color("curl: 连接被重置\n", ERROR_FG); - return; - } - if (n == 0) { - term_puts_color("curl: 无响应数据(超时)\n", ERROR_FG); - return; - } - - /* 打印状态行 + body(截断提示) */ - u32 total = ns_tcp_rx_len; - u32 show = (u32)n; - for (u32 i = 0; i < show; i++) term_putc((char)ns_tcp_rx[i]); - if (total > show) { - term_puts_color("\n[... 已截断,共 ", DIM_FG); - char nb[12]; ns_u32_dec(nb, total); - term_puts_color(nb, DIM_FG); - term_puts_color(" 字节]\n", DIM_FG); - } - term_putc('\n'); -} +static const linux_compat_service *g_lxc_svc = 0; /* ============================================================ * run 命令:从 FAT32 根目录加载并跳转 PIE ELF 工具 @@ -1526,6 +1417,185 @@ static void cmd_run(const char *args) { term_redraw_all(); } +/* ============================================================ + * PATH 查找:在 /bin 子目录中搜索 name.ELF 并执行 + * 返回 1 表示找到并已处理(成功或报错),0 表示未找到 + * ============================================================ */ +static int path_search_and_run(const char *name, const char *args) { + (void)args; /* 参数保留供未来扩展 */ + if (!g_block_read) return 0; + + /* 构造 "NAME.ELF" → 8.3 名 */ + char full[64]; + int nl = 0; + while (name[nl] && nl < 55) nl++; + int p = 0; + for (int i = 0; i < nl; i++) full[p++] = name[i]; + full[p++] = '.'; full[p++] = 'E'; full[p++] = 'L'; + full[p++] = 'F'; full[p] = 0; + char n83[11]; + if (name_to_83(full, n83) != 0) return 0; + + /* 获取 /bin 目录首簇 */ + u32 bin_clus; + if (get_bin_cluster(&bin_clus) != 0) return 0; + + /* 从 /bin 子目录读取 ELF */ + u8 *data = 0; u32 size = 0; + if (fat32_read_file_in_dir(bin_clus, n83, &data, &size) != 0) return 0; + + /* 加载 ELF */ + void *entry = 0; + int rc = sh_load_elf(data, &entry); + if (rc != 0) { + term_puts_color(name, ERROR_FG); + term_puts_color(": ELF 加载失败\n", ERROR_FG); + return 1; + } + + /* 执行 */ + logl("[shell] path: running /bin/ tool"); + void (*fn_entry)(const dsk_boot_context *) = (void (*)(const dsk_boot_context *))entry; + fn_entry(g_boot_ctx); + logl("[shell] path: tool returned"); + g_disk_loaded = 0; + term_redraw_all(); + return 1; +} + +/* ============================================================ + * linux 命令:通过双内核兼容层执行 Linux 程序 + * + * 用法: + * linux 显示兼容层状态 + * linux [args] 执行 /bin/(或完整路径) + * linux ls -la → 执行 /bin/ls -la + * linux uname -a → 执行 /bin/uname -a + * + * 依赖 UTSM+Linux 双内核架构: Linux guest 作为 daemon park 在 VMX + * guest 中,shell 通过 g_lxc_svc->exec 写 IPC 请求并 vmresume 唤醒。 + * ============================================================ */ + +/* 简单 token 分词:将 args 按空格切分为 argv[],返回 argc。 + * 不支持引号转义(保持与 shell 其余部分一致的简单分词)。 */ +static int split_args(const char *args, char argv[16][64], int max_argc) { + int argc = 0; + const char *p = args; + while (*p && argc < max_argc) { + while (*p == ' ') p++; + if (*p == 0) break; + int len = 0; + while (*p && *p != ' ' && len < 63) { + argv[argc][len++] = *p++; + } + argv[argc][len] = 0; + argc++; + } + return argc; +} + +static void cmd_linux(const char *args) { + if (!g_lxc_svc) { + term_puts_color("linux: 兼容层服务未初始化(boot context 未提供)\n", ERROR_FG); + return; + } + if (!g_lxc_svc->is_available()) { + term_puts_color("linux: 兼容层不可用(Linux guest 未驻留或 IPC 未就绪)\n", ERROR_FG); + char status[128]; + g_lxc_svc->status(status, sizeof(status)); + term_puts_color(status, ERROR_FG); + term_putc('\n'); + return; + } + + /* 无参数:显示状态 */ + while (*args == ' ') args++; + if (*args == 0) { + term_puts_color("Linux 兼容层已就绪 (双内核 park-and-resume)\n", OK_FG); + term_puts_color("用法: linux <程序> [参数...]\n", DIM_FG); + term_puts_color("示例: linux ls -la / linux uname -a / linux cat /etc/hostname\n", DIM_FG); + return; + } + + /* 分词参数 */ + char argv_buf[16][64]; + int argc = split_args(args, argv_buf, 16); + if (argc == 0) { + term_puts_color("linux: 参数解析失败\n", ERROR_FG); + return; + } + + /* 构造程序路径: + * - 以 '/' 开头视为绝对路径 + * - 否则前缀 "/bin/" */ + char path[160]; + const char *prog = argv_buf[0]; + if (prog[0] == '/') { + int i = 0; + while (prog[i] && i < 159) { path[i] = prog[i]; i++; } + path[i] = 0; + } else { + const char *prefix = "/bin/"; + int i = 0; + while (prefix[i]) { path[i] = prefix[i]; i++; } + int j = 0; + while (prog[j] && i < 159) { path[i++] = prog[j++]; } + path[i] = 0; + } + + /* 构造 argv 指针数组(argv[0] = 程序名) */ + const char *argv_ptrs[16]; + argv_ptrs[0] = prog; /* argv[0] 用程序名(不带 /bin/ 前缀) */ + for (int i = 1; i < argc; i++) argv_ptrs[i] = argv_buf[i]; + + /* 执行:stdout 缓冲区 */ + static char stdout_buf[8192]; + u64 stdout_len = 0; + u64 exit_code = 0; + + logl("[shell] linux: exec "); + logl(path); + int rc = g_lxc_svc->exec(path, argc, argv_ptrs, + stdout_buf, sizeof(stdout_buf) - 1, + &stdout_len, &exit_code); + + if (rc != 0) { + term_puts_color("linux: 执行失败 (code=", ERROR_FG); + char num[16]; + int neg = rc < 0; + unsigned int v = neg ? (unsigned int)(-rc) : (unsigned int)rc; + int n = 0; + if (v == 0) num[n++] = '0'; + while (v) { num[n++] = '0' + (v % 10); v /= 10; } + if (neg) term_putc('-'); + for (int i = n - 1; i >= 0; i--) term_putc(num[i]); + term_puts_color(")\n", ERROR_FG); + return; + } + + /* 输出 stdout */ + if (stdout_len > 0) { + stdout_buf[stdout_len] = 0; + term_puts(stdout_buf); + /* 确保末尾换行 */ + if (stdout_buf[stdout_len - 1] != '\n') { + term_putc('\n'); + } + } + + /* 非零退出码提示 */ + if (exit_code != 0) { + term_puts_color("[exit ", DIM_FG); + char ec[16]; + unsigned int ev = (unsigned int)exit_code; + int en = 0; + if (ev == 0) ec[en++] = '0'; + while (ev) { ec[en++] = '0' + (ev % 10); ev /= 10; } + for (int i = en - 1; i >= 0; i--) term_putc(ec[i]); + term_puts_color("]\n", DIM_FG); + } +} + static void execute_command(const char *cmd) { while (*cmd == ' ') cmd++; if (*cmd == 0) return; @@ -1552,14 +1622,16 @@ static void execute_command(const char *cmd) { else if (str_eq(name, "cp")) cmd_cp(args); else if (str_eq(name, "mv")) cmd_mv(args); else if (str_eq(name, "rm") || str_eq(name, "del")) cmd_rm(args); - else if (str_eq(name, "ping")) cmd_ping(args); - else if (str_eq(name, "curl")) cmd_curl(args); else if (str_eq(name, "run")) cmd_run(args); + else if (str_eq(name, "linux")) cmd_linux(args); else if (str_eq(name, "cd")) cmd_not_impl("cd"); else if (str_eq(name, "pwd")) { term_puts("/\n"); } else if (str_eq(name, "whoami")) { term_puts("root\n"); } else if (str_eq(name, "id")) { term_puts("uid=0(root) gid=0(root)\n"); } - else cmd_unknown(name); + /* ---- PATH 查找:未匹配内建时搜索 /bin/ ---- */ + else if (!path_search_and_run(name, args)) { + cmd_unknown(name); + } } /* ---- CMOS RTC 读取 ---- */ @@ -1721,8 +1793,7 @@ static void run_dev_tests(void) { term_puts_color("[10] ls — 确认清理\n", ACCENT_FG); cmd_ls(); - term_puts_color("[11] ping 10.0.2.2 — 网络回归(失败不阻断)\n", ACCENT_FG); - cmd_ping("10.0.2.2"); + term_puts_color("[11] ping — 外部命令(/bin/ping.elf),跳过内联测试\n", ACCENT_FG); term_putc('\n'); term_puts_color("=== 自动测试完成 ===\n", OK_FG); @@ -1760,6 +1831,22 @@ void dsk_entry(const dsk_boot_context *ctx) { if (g_block_read) logl("[shell] block_read ok"); if (g_block_write) logl("[shell] block_write ok"); + /* 获取 Linux 兼容层服务(reserved[5])—— 双内核 park-and-resume */ + { + u64 lxc_addr = ctx->reserved[5]; + if (lxc_addr) { + const linux_compat_service *lxc = (const linux_compat_service *)lxc_addr; + if (lxc->magic == LINUX_COMPAT_MAGIC) { + g_lxc_svc = lxc; + logl("[shell] linux_compat service ok"); + } else { + logl("[shell] linux_compat magic mismatch"); + } + } else { + logl("[shell] linux_compat service not available"); + } + } + /* 初始化风格系统渲染上下文 */ du_context_init(&g_ctx, fb_a, fb_w, fb_h, fb_p); @@ -1782,9 +1869,13 @@ void dsk_entry(const dsk_boot_context *ctx) { run_dev_tests(); } + /* 将 banner + dev test 输出刷新到 framebuffer */ + term_redraw_all(); + /* 主循环 */ int shift = 0; int e0 = 0; + u64 blink_start = rdtsc_shell(); for (;;) { draw_prompt(); input_len = 0; @@ -1793,15 +1884,30 @@ void dsk_entry(const dsk_boot_context *ctx) { int prompt_len = 0; while (PROMPT[prompt_len]) prompt_len++; cur_col = prompt_len; - term_redraw_cursor(); + cur_visible = 1; + redraw_input_line(); int cmd_done = 0; while (!cmd_done) { + /* 光标闪烁:每 ~530ms 切换一次可见性 */ + if (g_tsc_per_ms) { + u64 now = rdtsc_shell(); + u64 elapsed = now - blink_start; + int want_vis = (elapsed / (g_tsc_per_ms * 530)) & 1; + if (want_vis != cur_visible) { + if (want_vis) term_redraw_cursor(); + else term_clear_cursor(); + cur_visible = want_vis; + } + } u8 st = inb(0x64); if (!(st & 1)) { __asm__("pause"); continue; } u8 data = inb(0x60); if (st & 0x20) continue; u8 sc = data; + /* 有键盘输入时重置闪烁,让光标保持可见 */ + blink_start = rdtsc_shell(); + if (!cur_visible) { cur_visible = 1; term_redraw_cursor(); } if (sc == 0xE0) { e0 = 1; continue; } if (sc == 0x2A || sc == 0x36) { shift = 1; continue; } if (sc == 0xAA || sc == 0xB6) { shift = 0; continue; } diff --git a/CODE/shell/main.o b/CODE/shell/main.o index aa4542f4bc41d232b74b69c39e8f37b91c7f1265..d24563a683b4c7feb38389126491443fe877d3d1 100644 GIT binary patch literal 108536 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

x-%u{$C5KnO&x+ihy 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 LvC{6K`t$z)&EDK4 literal 130256 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�D`W0yKQ-n3l7uP_>WMN=ZOZJB2P#_ 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 V$IwMr&-Z;@G|$t3@IdzS{|BmmaL@n% delta 25280 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 diff --git a/SYSTEM/limine/limine.conf b/SYSTEM/limine/limine.conf index 35a874b..a71b13a 100644 --- a/SYSTEM/limine/limine.conf +++ b/SYSTEM/limine/limine.conf @@ -43,8 +43,20 @@ verbose: yes module_path: boot():/driver/test.fat32 module_cmdline: dkm:test_fat32 - # Linux 6.6 LTS guest kernel (for UTSM+Linux dual-kernel architecture) - # Uncomment after building Linux via CODE/linux/build.sh + # Linux 6.6 LTS guest kernel (UTSM+Linux dual-kernel Linux compat layer) + # Uncomment after building Linux via CODE/linux/build.sh (requires WSL/Linux). + # + # Boot flow with these modules: + # 1. Limine loads utsm.elf + all .drv modules + bzImage + initrd + # 2. UTSM boots, init VMM/EPT, self-test + # 3. UTSM linux_loader_init() finds bzImage module, parses + maps guest + # 4. UTSM ipc_shm_init() allocates 1MB IPC shared memory (EPT-mapped) + # 5. UTSM linux_launch() → vmlaunch → Linux boots → init starts daemon + # 6. Daemon sends EXEC_READY, then ioctl(PARK) → HLT → VM-Exit → park + # 7. UTSM linux_compat_init() marks Linux compat layer ready + # 8. UTSM loads DSK (deshab.elf) → shell.elf → `linux ` command + # invokes linux_compat_service->exec() → vmresume → daemon runs prog + # # module_path: boot():/boot/linux-bzImage # module_cmdline: linux:bzImage # module_path: boot():/boot/linux-initrd.img diff --git a/SYSTEM/system/deshab64/cmd.elf b/SYSTEM/system/deshab64/cmd.elf new file mode 100644 index 0000000000000000000000000000000000000000..97689a0c442d4409b3ef38846930113a07729102 GIT binary patch literal 490864 zcmeFa349b)+V9_;q#-P!P!l#$f`Wnz5(OndFr9Q`#px)5xPqcA<1UhJaU7NoooLFo z1sxYgQE_)r1V@eRBmp}iAOu7fQ4GkEHlTnSLV(o${Z4h)=~CvM`_4Q6|GjfRHXl;w zd-ijl=PY&VRGsN=&(H+B-4^>L+J@K!wKr_CqYix^Z5i`o%eD=$CE;(1t&Q;Opi9*M zudg}tj9{^A%$;c@(W#7o@GBF4&Fk`O431sn!?mDO`)Hnjb)7gyxY}aZShxfPVS2R> z8s+%)br$2qFLq5f@b|yJ*TC;J@OusXUIV|^!0$Eidky?v1Hae6?=|py4g6jMzt_P3 z6E!eW)%H4Xbl%_`>AZe~T6ka)N~LPYn>?ZZDaUQL`koWSuaDBLNR)SF3NCfeUuLuA z>0zg`La%!QX17v0#2L_Adu!drx^FK6*D!FW39}6U6XN{e@>~CE@eZYE6mIC%Mb}?@ zZBE7?M!3|>M5Q>7R>9m}s^%D{3u9jx?=Xx5V7$#RX2WZVQ}}e`;1YJc#1#y+c#U@wGJReXGJP%!{HyZ5eW@((i!lGTytNE! zmiOT}|M&dXzZ!I`ZjNRS^<+cRuQ$erzdSDd1-}gs{}V0gwTScIl<}MVMV@C>gwC4E zL{3${Fv6(%D#)|BZVAjTrSvjqpjpVX!M7JdZI<+&kMsY;Z~e#B-_P|Y)k;V8No0U| zsB~0DjbTSR1OV{{%6KU*^G;J2+idB%H;ix(Q!|s5;%&6o9Iqn)3ViP|N!{v&IV6w-L`=s&2Rx8uUU_}lOZT5FNt!*Txa`K|x@ z+YsWj1|-(OXdgr4{15!CfB5!W;_ndWzx8kZtAVA9P$IjpW!Q1g2^iF1%DK3z!L%OY z;^-+Z{m)Wz9(GLOC3JOTXkw!}c8z-Xn)l|-yFk@8 zsO3Lisg@t>Za=1_d;(Qg$2O>UH~bMTNY#!Sj?L%Vo3;LP;23C{KK+79hX!M7WN$J5 z1RC$1c4pw%_$hFh2#0aBYwkTYy}lQmrthtE+y+~&Fs|Sq_?)^0?o(PyDJ?f2*h8d zW5w0z3Gl1SJJ)7g>4Is+7=4UhSA7X^yopPR1tz{vyvxLwiFcUz6!A_IrxVjnoJhM7eenouH#I?i+Ok74x zH*r1@3K*@cSBUr@#hFAj&nWt>t`8Aq*gJ`%P0u5U9Bd3JxQJ931N#FP_HwSE$ULE} z187SVly0akWkur(zu&LdodF-YN@>y%^b>i3=Kj9D{;b>3DcF6jjW)OGB1*jk{ThEp z+|-!5?H5Cj0$IJ`*`^e=IU6YrGgIpQ3sQ>f-ce&WvJ!5)1BI9d9A(-JGLV*I?UpUy3UR=swn`y?h1rhIS_U$1ok41GO;sp zh>5L<=_Vc*+2BaPU!`Mm)D(8Gi-E<%C^ws0rQ>UKhpgbbj%X47ES2s`adtQKpBa0U zZhjyuie0VEd#90mt<2NAPQ5#204z_(qPuFZQMC%SRkd3FeY*Fwj7{p%!+Bb`zFjnY z#-^i(om$u#*k^YQ>i+;z^mcL=H~3oCRh*Ch(NVXyCx#=f|MhU$Gwxlxuia0xA}=7p zXn3uB&zOetbfq`|J4B>pp#GfN)<9Nwgs}OPN=F(Dq8NTel~=w$-K`zWZ*|hCl!mkZ z20zoz%Hl%`Z=bAEUe0%}r0=X+!e#YC1C1AW9f8KneS;U#Ue$y|>N~`VCQcvR+J1l5 z*-X)`oluIuY1Z{fJE)L5Lw6T7Jo25pc#l%N7x6g#&Fws)o^9b(DWZS_ja`+ZMkEnv zv@1oE&k|nJl;_F=%Y_Ok&s8K>D@Ehs17R~K&yL!o=R5xp@)b&}{Sg<%RSm7ThtyjC zvD=i#AB2XeV^f|+15pc)H6tBm=B>gmtq^vZ8$F?v5*VgsYa4oRRkihj{fXW*T!$*9 zu6Fv+lB9O3zFyTg_*CLe*ZS*H$`Cpe^wip<=m$jzeHKCu~dL z-5JW(gDKl#<?;lu1ZNb4S~I4Rv$|Hn$l zORO}=iN>iwqy_REbX*MQL5_3rR|)-m67^hG-zn(m2u8V{+D)6P z`W8Wl9X6Un{~2*DL3@f+!KJRI2h(@#g{{bgKWjdWW(U$8gI%R#D?;)Y*J1VQEjqz6 zc+S`ML9g2dj-~sO+41R>^*m3gOx)K^2p&=|TXrDaNKwUS%qKc@O7!?_U7cbv-E?YjxiGvGY*RL&k> zCY%FszVKAe!+c1}U6iq=zTJm+)wlj|e0_@#@2gMvaN>X}Z%?Jv=T}3H3lBp6hl?A$ z?E}qM`Z_D6`Gv6U0Na7dzSeb*q0f%Ie>y7OD8${TO6LZp*oht%URaQ;Pvym}6rXK) zVPQ_0+u=&_akNwx2sv*3;ls%7c;t4{fGVYU7hK}zAS=%Uj)%;RA#Wj3&LdtU%Bj#Z z#5+vS0iv7=d5P(!>v*D^3f(}=H(jqH%Bj!*YuMgIITh+cyul3HhA8uVq9;&Jg$@#B z5q1*gRA>WHPKC;d51283NK7~Jb)uZk{Dp`)NVKksh;l0Av${^OhP{y}r$Q>wpY<9# zd9yD_LswDhSbG@p;}I%Pc6QeJnQRbA$2Di8=3Z_I6wY{lhqfezkxuPXdzj99H zY_tUG*7>J$9wAzSp;u$0t)KvURkQ<{HdI?F`V{6<1aRGyslG|TW*1Wy^K@-$p)_C1KCiqTk7KO9@%9!rxeg|Uk5lF0vZPa-EA~{?ze| zh_g*hvwChpe9?40+8tPAVjXd>iQ9=G6RU}znz)p>&&2nMGToPn3ryFih_VRNiJ~79 z1)NB9n+3dsIKsr?MAgJxqSM5F#2gcQ0{vOj4#ag4N4im)-epbWXLJ!F*<G^Y_to0Sdi%r)BL@9*1#J;BM(^i~8 z#5!Fx8wEgr*1GTGB$j?+}RZoJ=A;kVl2SKPgx$z;+IeucocMA4=M zoEEMd}NpS)+(hF?MqNiHd=fC46AjpN?4K*v$_jbpTjC~2@)}UjfB;D zSS2kk?Siz^cU()Q(}*6;>Nz)p7}U0*Vw{!D^GJIi>WGn`(&3)>5n`;(u$5gN1!61{!H3^j{B5E*te#=w>9o#XuDS1q8$ml z($+#jMy_orZ?6>3M_R$`u9|yw(I)R%p3wMp%8DkVG2DG7@48A;d*FtwXp?XM%5?ZO zoUVaW99{_w7ypq03`|`OA>M{cThy9S=dX4y`h4BGby{^Ev=NIf=Z5;79_m+$yZWQq z{tbPzOO`oCQP6=hy`W{_SSxMg|*9 zY>E-(9XJ`;6gZnWn1v9i5#^}&C^64;y_Y!L#8Jc{Cgu~)80MZQ?Pe85pUDOI@Sx;KI7CyQ~)v9sB+S1!eFALPR1ci&zSjXwAUajg? zzC(dyEhn9>YRl3_ikh#$4RVw2`#~u!rZ-HU(mkQKM#IP{y66ceB-J*h#_Tl<8qSq)9a?P>po-(vpx+Sy#S@V2fSa5+*t z8_g{0dZHGt0paTF6tx?%6Lt>@JEf=x{CYIK?pg-iize$_F=h<%K8}K9wG2d;#?HPNT@AQj5NaaWJlo3rt1$x8TMOZ zo#|Rb6oZxsTTWbIy8fLgV}679rs?`D@$nc&KBPQ?j___=P^WjHx5vMRC0v+zW5%Z9MN%%Ec=K&wDU{%lz=Wf&kT&%m(+<(cy2 za_0(Ekvy zW$aj7+M&hlS5##|xmsR#Zm6v-)K+t8M|xNLtNZ4ZT;FqTUSPFekcP*Ft+4(&d3}BB zu=~rt&Sh*dIavAWxsHmihVnnpv!m0CD!La*#VfiYU(p6`hLbV56L>X|8f>(XLBx3` zUPKhiAUvN%eBN|zM-);Jt~v@H7xN+FQq%J;VyTIni0LSVk?txhehf6KN=H?#U{$SP zJ-M_-R8=^>s+wX|)gM(A7FDIAswyXc5v{5fv8w9Ns_JG`)q1n4@{km&ss+~bipqR- zPLZFuob_hTc&S&Y

    !WyMyRI(Y{g`;xspU9}bq$ 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 zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5J2GnqCl}_rI_uG z)Waqf5Neq5N%bP^sE!$LW`@bxcg0;CysQ4Wx|od4ryKZ`YWZ zxE`_H;$pkR$H#Z=d{tb0ub5ulyY%SZsatF>Z%nuD-Fx)xc~v{*O^it%>zUvSr1?{l z&(%W8w&)il?Nd!1wJJ{3JE4k-P@iApOu5)V)|1f)RZ}%+;3VvwCAsrWzFCF5-aop& zr$YW>lW$ug-^%1WRmgWR`JNT>y-j{Vh5U6UzoenFo@VvcNRz*=Lj4$%A8zt){qZJ0 zvO@jICO@V^{(h5BsE~iyB>1^q=es)@YZ1QtWeYgEDO#bs|r@ov2R`U8d8Pn65e|HsUc);Xy z2RY-PnJ;LOjOyi1GVAHIrc_M{bbe}u_1CMR^V2HiFERPKCNGuj($?fvh5B73uh(-x zA5*WYGaO>-XPE7EkLO!W{V@ZadL2!DpUI~huY)qK%Oty@}mM(9G^JYaFIQ8E%?Y#R3XMBt^P#>H8m{=z<+~hwu z`86irs-`pHTa(}8cgCyNb%y&)J~!PNZ*S`VWb&RrIr+}#Im2TnKW4Tw9$`+z#U`Kn zl#?H2j)$tUdG>i`fs^m$Y_4ix@(mU``I1`Bu$jr{_Hf3>IRkaEb<~(M0zq-=o*F5jkYi$nb{wBX?m6PvkE;P5Ayl1VGzu4@C1d|`2zi3jb$ad-y zF!=_ief@pbWvb-$@w_L+G$3bRU1r$%Dr$_m9yPSHN-dJSsuC&n4ZO+!S@MmfC1s9- ztjo=WsGx6BP(=k&;$ng^Dk^Sra@yo16*V?FJt`q4EkT)2oeu_Nx?3wI$?sMAl9uF4 zmic9-U`(tG6Qr6GIYX5c<4=zAs$H1JOxoX3Y|PF|tBVGxj!_xlAg}8spbbn`(Sz=|@#&vu0_2{p^E^fcq z9lHHqy?%N*?sdz}>&wXr=~KJ&yZv5w*g~f3;+}=v`JJp%EhW&WXm@_MpX?6Z)ph50 z`vdM!pN{l2cYe2D?hf@jmoF8^JIX|zbK7^X=k9P%ba>A=&A2OM8to=SUBjKz}^N>Sejh qclX~-l5^L+{QPYvI`hYrPfF}A*G=Cc!7t7Ku$lk)3M*G}{{IJH?~;`O literal 0 HcmV?d00001 diff --git a/SYSTEM/system/deshab64/deshab.elf b/SYSTEM/system/deshab64/deshab.elf index dab2acb574145021b909813a8f0be8543d7c2002..7d1e60ae517100de47b8467f8e09de67c5cbd219 100644 GIT binary patch delta 3027 zcmaJ@e{56N6@JftNt}dm(=MZopGjAKqzq=KRA53ho_UX4GrJwE*^ox6N>g2JYbBQW zDN;q`m}jrKdOVgcr9+ddW!jLuwG+^+iOXP#9Y~y@5+|$Z3K}D5Kun~TY+VQe^7h^5 zW~!!X`6KVUzs^1PeCK?}$GXI0U1G-zCCAqZ_TTY!r+(;I^G(tlC|stH-j@q2_z|_Q~F=ttrdVi%LP)!C#OHP3r!7j=~YN#E68Rmime_kaBlXG`1OZ8Z}ugzOlsH5Ax?jKU5 z52h^=f2TwcSVITtE%^XQG((v(HFR*#&H6!7S-5 zOWWu}qihs_vS1tOS$PsrF*csZ2Oj?nACKjkIW34hI-k4#bOgr8iN-dg^+WMKn@wFS zrU;v%W@VO=QxnCqetupdCnnij2XVhF{x!gUzaGe+x=|cpuXH_YN}E_JH6g|O11xxw znJ@F_#KO3Q4gV3?@?aqyFdB|cEhVdk_!UC`LalzPrz@#9MIy2N*h+e8qVqQp+VHjb z42k(LHRCIFX&=ekYP50E(Iki6kNkEeJJD>uf0<8Mn>sv;8U#&>pDlZ-agZiwfXDvm{ zcxITI@r=uNr3> z{Nys?oV2rv#Sg%k>KRUA3TYGHhhc1(#2zaU1idwjJc+-6DKMKPu>nlVq^HC<$~i`M zcLl^dQ%ggkO=NWp=OZwo_g7MDgv5?v?^c)gDd{@3 z6ZNJP4eeyx-7>o;!~gpBfZLJBOXao+!pF{BBagIMclJ?1$Z3Tj#S+5=PfM6m(l;cz zkyiwz%gG2XGo?aUKFL!8vJ+s9N!i>v4_Xg&j=5JxNPHDuloX*YN_7U)TVWgl378w7 z4RY18vw;o5Sdyg_qqT#a(6Y|=c;TzwQH71j#P<`W5q-|te84lFJB4}Z+q=+4x$i!=${9Ea4n4>( z`yQhq8(_Hrdus=l^K!c%>x$8ESdEYK=aSeo5ID3+M$0+fQiDMfe-lNrc z@+JLNQFtl7Wc3b+spQ@{C>09S8l={!_9?9%q59k`d5ypZYNB(Z=JCi)+#J2mZ}bdz zplmiT^0jZS1_&<_eeL0D(S{BV9X51w=%ji|qTUhh1B4>H(r;EQ^2~%fNYC~fTeplSbdSQk%)e?D7*w9L{=+;;2V^l#KAPR zE^7az)hVjqn{9by_Yh_|2YT8?y;;1(C^)@>lVNvAn+&APf01Ej1BOip?|u8RZp1m) z$Z3k4uH#B)v__DV!LFbwEnY}TB-G)SO+I6hJBi(-DrNq7K00qJ;8NKdP&Tw?0?y-h z0@XI2BZn44=-OJ}5O6+8;yHLkzkh+ICJOwfUMcZX3x1Q_~H`282N&9h7?AZ8Nm)lSG3i|{791UcRW|*zI%wnf_U16ATP&< zN4*&BUuF*&igy}ME)Iy(oP>t9d>V7pIpvKU1x5{%t9;(}PqB#KC=i{m;FWD>_hCUGv1Uxm zXSsF+t8d6>FcOT$gltoZ^SqCc6Tz(03KRp*_eV9Uj<;)bfN6EmNuLr%X+vXMWx?7b~?do|8@G2~lR}nqGsmuarR{ zN8yzn+a delta 3275 zcmY*be{dAl9pAmXaI$ z?tR|(?fbs(ulM=B?LG4L9=ZGBvcWpZ`wiB;^q8-$q@fB zgudh4U#49bqQRRaiHnoxy3)_p-XQNx_t)Mm{~&#=wt2yX-#Wlplo)Vm5INu)sksm5AxbI@sx+%S8$y4$V(?^#y+`af0eu>+W9xh~V>)n9E zq67z?x>=IW6;HaZuDD~3Gp^fCzuVculxOy?hNTw+v3)qkW!8J;k|f%;vi_nkzAsBH zl24MDwI4#5)W2Ag)P30RdWQW2(y;h~^;N!wPq~O>Sbt>}P(-%am4`i<^E-U4vA)}0 zz|_8pRt=}+DGZ9MOze?lip~^ViNTj2L!riYzDRp)eTym&W=BgoB4^loMi*H%d%84v zU`Ay-k89$^C~21ST>P~TC@ekH+IK#YeHjuoVyvG99YCdS(f?@cCo(YiJ6ZPr|3y*f~D?-Xri^e z#C%^}d8awT`Z{EFrJ$a#on{8KSL+^|#Jv{cEeUr>jb{w!SsJ|F#<%_a>)& zZ1bT~Dy_E?Un1FzJ)J=Xgd)9c+rXlM-IVM2v}`sh6L#B<{iI$M$J6Zgxv@I6X41{+ z4xdpIQ~$-n#-b*3Z^sD!Sn@T}X+J|r$({)&&ct2!J1DIkiEOzv53u1b+SgJn;U8@>b%r-w~eVb+@p`EgMh9EN9=`-Iah?I8v z&3_R@PCEl;mLQVaS!DJRL{>YC%@+tFt(`$i^`_Y+fF#ak9Ix0-M&W7FAgUfoWVMlsnbO$xte9vy{M#UQ9_rt1l&kV9n zxo?>u)1J<#p@VE&c2SlKhl(IRB}c@0W`PW)-7!#ZTHi?bJ-vLBPd0_b8|>E{^dgPdS#j zx8yWp*sxd^pX%13Rd@hNgJs!??YiK zF1HJ({K{_2aHsO8hF>a>dLx!~k%wLi50=(oiKVvU2<)Nb#dvb`>yucr0!uoMYr~lM zCUd`c_n{T`S4}qSdn66)lrJ=p*R!pr4>WjG8n;Bj(!(UUb1ar@C61 zXzyly&C4TBV0mj-vrJZm#?8<4&|4cKnmC1=!=o5nnuJS}suKt;)8isnkE)tZeiDo_ zjJZG=%pc(HVe<=KKg5&n22vSN~a-f8V-i2d!QPTp-9xhKId$oaUvxnprvNj81 z+oGxfJ8~zGXoN9nw#*f)Nw)vjpVjUB8e>#Uzi%y{HG*FB&udpvIVpQlte zJ-C-`{`fLzZv>1w%&hG&B>b}+DzgaWR^C++#IR28GJ-MzAApa5zbj@0{e%J#1qc)Y z(57|80L27?0N(x*fD)3F0+bRc11M`B(t_oSq?{J4lmKT@Xh?>;Ek4MORkaHvSdIBy zZ$Uf|Bzu$mO$?wtD-#+Tdwx#))wc&v=Fn>|Mq`Z?4dz8~V?%*{ z&k`)q??(g+^m~M0fqruY3-tRs!2-7H>lJm zaiDj^er)%MqK+iQ6ShMyn?l7shgDsf0N45}(cIs-9}D0K3*y&_5@SaFztz2%Ng%x) zd$7u||4|xuMlybfNRJEZoTWVU!3KJE-shcvi5AGkRoMKMS5)Sn3dpTG$ib$la*Lv3 z$md{33zhrE#jSRrvF2Sa^x+s@6kk0kW@$~2>{T7@o3bk2>`1`mdn?c$KEh@<2g3H+ zRvt5Jgr(*{J9=B8ciEA+Dh?T9>}va}zqWln;i{Jc<>V2%)X>%Tb;N65hw-R`4};K3 z4;H66ksJynTrbwPCkZ4(rhSbF)M;WUd%mi*Yg3)igEy{Q#P8w#{LB!HDB%R_Z=nR%(Fxay)3yEj&vdX*~VWUAL%9yi==7z-NhR&yL6Z z`VKLG&Uh!Ja%Zct8c9ta5`qvk-HZJ@2H^-ccg!NclFXc z;M}zo<26*WD=bb?OMO`$yMk=)s*#(5FR$t@lQ*aTy!Ia7V8yNv*FNO)4c6^i89C|u EA3DcsegFUf diff --git a/SYSTEM/system/deshab64/desktop.elf b/SYSTEM/system/deshab64/desktop.elf index 297d5507c40b825121dec81456d8b0842f18454b..61bf351c0cb03f625f9a707a916213ba2a7516d9 100644 GIT binary patch delta 53925 zcma(434BvU_dkv&X#xcrZo!7Ng(77WMGI63CD1@BH;}TUAmBn3K^7}Cg4&XnB+$#{ zLSa}H1Rs46S5N^9Dl`R~77$uc7EwV!Z44@#Sl0aBXYOqakDu@V_2;FTIm>KkX3m^B zGjn_V&*;;o(S@B28`>_t?_p2%0=uM4b8!ynLC8!NQGw53iBjeBLbyaJ}>2#w1WcGNmXw=Z5{gVfe zbcog{cZMh>1R{E!C=ci?%7Y&gCG$=Wj_f5$md|-~R+=cKY~|6{#)y*blZc+ph;3E> zzF&~m>8;^C)g#!e>42$u)Qex7O=|Ch3MMVo|Zp zISJ}7qtQskwD?D=hG{mafVTg{p_d5SQ2`O1Mk3U5G9iMd=Md08L?_lopQ?+FuZb$A zU20a3-SFsjvZ)2CB`TJ-rzn5RAg}=%eu6^|f+TY~1wm8)nk<5*es$44bx~_gR58EC zD{t-rjHsA9tIz`~bl(p=*G^QvxMK|3Qlhq{jYg-*du7l}&$~LmLR%@g)RFjYFQR2oW?bN1(N9XB+?|#rzYJ z+jkN=Jav-L*1`I=7#216hMp~Lk>s)Oj=`J>ng%1U$45SpTxt>#!weXNfT|ia?ftbT z_9l_=uZWaFp}o{s|3V~kGtnOOEqFFYck9Mqha!Z$Sc9B=2l7%4a@rlp%gHs^tUIt* zYLM9)QuG#^M4Jyab<1pU%b}hxs2(mQWe?_ru=C^; zdb&^Z%3|sZZGB+V>C|cqx3p@<-cfB0IXR{dc`2eHr`>_G3HT1XD_FnQoyUk^s(NZTjgod4fTEPX#U-b-p{Q&gN`b#zSiB$N5M|3F z9G%jc2R17LXVL8l|L1YGt8ghpjOodTozjtTSGK#gCH|kwRIxk~rZZCF)L(O2_hrv? zrCNTytY;TnH`5of==h|l4S*huw~Qf2#RnQy#di^z zxumP2usP)+!bz9J!0!gZcLI2+!h1SO^xlr0H7WUO=sjRqeo{wI^GSt~QivgzgcAvf z)-u7j3ialZ#faGRz7$9{4c*5gB~o067%(PZ4IdD9-BerGPi%K7`RbixL(cj9iqz*5 zJHl!y=My7EZXyzGm-~Eb`+SS^iO17VF? zdlL}|D{d`92y2hgX+7@#E(7*~ClSJ0lc5;bI=#hL(v!;z2gq>+{iQg`83|-q_q#6y z{WR=QC!MTNEdQFv*G4BSh(laxo2I*57~vc>)I3mU{vP`K77eBJEvDm$K;HRZk+|=N z_=H7oBQsIXD9R7K;326)##Zwme_{O2mpEzkCT~fBn0Xij&-^3skl!u@yDo65Z71U4 zrZuVqy==e$xSc&r^dGhhYl=ndb-S=Eke(Q@=Uvmg8wZU`BfscS8(TgSI;9F{q!@ew zr?uMd5tbFFCzjdss`c*AgN~&}jdKhYu@RNrqQvX-_fR9ynj)oe4pmsOIV({s*}Z8; zT*MlwdcQY8=2Rr&^QM5;GbQ{dV9cG96smJ4JF9Nq7%}WU1O8{+lSnbXw`v1^Yt4Y) zS~K9c-aX*&81GyE@9|!FqC{i0pyusG_OdRp9iv- zc~X=|Z&DV{)p|=(9-`Q4QS$dfM49KQ0n-SapHGQEP2b=xUG2*JQ&f!WfPxVGB5?wI zNCjD8Tcf9lua1)cY0#k4L}^`T#KMVn%Y)PVbu-b+8Cp5L*Bc5x1?DlVy^*jh2FXTD zQ2!XpSvGz02la(z83j=*cyTrJuo4E_!>jc=$o*b2Jhl9zP!$%N*fwhPA9~h3aj5GC zOwUDt*t_4e7tx>y2WtkLOIk4*WjUxP>wBy9J829QZCdzZL~vAyGOviRUFRzn zeE9~pKe2=7{<^}b*(wVL*J`YZ(JqWDOumPRKN+S8R0?v}k@A!>R%3cPT}qtnf{qdu zg@#}FfjcUX{G8sB7#gX%_I zUqr?g8TwLJR7w!Y^yG8lR(HrfvNuD25DP>jr}t*l>^ztBvr8YEQzfRF-vjroQ!r-2 z&FlCFNHOyYWtWBznWl`ef?j^|e-n@Y)klq&OYkZ`jPIiwT9=KXEvu{Ss*Z2l?#tWM|A^;cq2^8?_Hgg2mr?Z`p&7pv-0l=)Z@e56xc zvgO?GTx(jsMVNt^4y`Hp7J!y61w3}|&rqG$V`rH#%EC@@N1g600|r)@PB%byEx*!V zih&+dbIxJIG`vqB|pg8htyBP^CL)11ZX1 z@!2SEqq%4=df^FO#J&SmUDbweG#5+_APfu;%LXW;GU(DXAJt97#z?+`IdY-{mU%^!pjq1aN<{Hlf6#pKyGqaix7uWZA=0n!bmn7_9( zkmKy*?Gx-z+Mk-R$EDcLN1}A$__`r+xiHT*3u*PBRe+ZL)wyS{R-`9iwSNU^=r*+z z{5zoe&OI$=nv1}v4A)B@3zY_qom0=KD=;<@z1Ivm&4Q*CR0sSMwp%8GaPpt4@x#8LMg?7U!kBW68WzR z1#J*IWYaHjbwFDbS2?V~oca#QbOKhtY&!rFzX6d7x!^%0_XNb5<6_HJo;NL<5!{{KT< zNnj&sEr+xq{loz5zU&t@G5OBIQVn-344Rsv67(-Qg33z{Oz@z|P=mV~>Otyrn?BE0 ziJI#@*?mHXnvuwUIC5vQGtk6A(}5b?)lel6NHz&$d<`WO{Hu|y)U*fyq+@;ytPs+h z2t=>#C}FdQ3dv&NOrlgQHmDH0n%<8xLP49q08Ok6(N<|$vBx2mcQyNw${VQfy(Yk- zbx0*$Ewc$zQr~+Wn3BYOi6z4JePKg#IX2!u=+S|9WGtCRAY+GQ?nhOSOnngK*;3R> z9)cib)2+jL9rRI$^Fgyq@FuSJod$SBOSZAG;K z+>WCPZ2(}m284A1QyHifU0a-3)&~qfat1GFC>9nS1Q=z?(LiN4r@jIZ?OFVr8JU?g zIkB8|>?sTv{N;o*Icw7I1Q=!NUz7d=fXT(7z5)vMR<{$Cgs#`4$er;H>gt)3XKSz4 z`ES(fs;Tj{C|1}hDW2*mY&ZQ<9i>x@d3G!6wT(CG`|2oG(W#kdC7@E%gYe1fL!o=9 z0$?~k%I4z$?ACH&U5Pi)iXv+RiIub|n<;EJ?*>tck?hv8oXk915g^@8q*9$_ zLi*7L`%vlJmf{^l>&d1yLo4OrDYm3br!m$;XiWz~XPTT>QG0LoZDG+7WTS`%e>u-k z7_u)C*hwQhITCKJIZ4Dw5MvqR_?qB*2PDxOiJCb`&Te(ne|2tu2b+6ei-*(lZtLCc zfvdJ#FXXg}>WMa75EjkD7`fX7?=NR}r*x|xl}B}F`S)2olvMC%L!}Un(xX=hit5>& z0A(zI2=waogJ?i%6IiIpSMzMIs?tjaESo3&Kcpx4n}7}pI%_2;EV>=5WsypP^!!_r zg7O1cYJ?djEcphYm}yD=na03jVewah9n$n7WPI&Pl&&D70ND03O?qSZ^Nt2C-xw zJLJGr?u95q3!#MVwyr9ekfeqWBye;}a~_zRASj@1oH?4uHXs(c44g-y?I@tj1Sy?W z;5QD?HaC>qh^EtIILVbqkCWa|%4kQMY4QJ!DI*=`J#vfB>ee_Ea4N6rGp1h38mh$i zb$a&{hMN|OkwX;2xYY~ukATzeeJxIxU4tS~|wEiKk-hP5wAT8rT75Okd z2LxcbF^8|34iLNpvq-ly3qL|SrfxYqcmF+OpHNxyZ0o_IQ&~FIu#^dldV`*4TS!D@ zcq_qCNs4OGuP7+gR!!=yHVTXG;cS~p1-r+}mi17-a z&7i+*S@8eJAl2Pbw!En2&^pR8jdFmMOF85=l1y2ELxUg;*)jo9(gRniZnl9}qu2|{ ztsJCE9kQhphz_aL(dDSHsF)Z`3BWw6#K)#vj|<92Km|<=fr7Mk4&^C>D$R8331QI> zESTJ;@mG+c^4PE5>ruj@Pa3hy$=0-&fl9Ugg-IYNFCb1n=jXc-Zb=z%{&9#`jUNpK z=>krL!G7%Cy33DL8%s}+xMU9kjIunSfy!=PvD-NR(X)0v5w}8v(}vyDEPn8cUqPl*D`<^ zAe*NGiP=OAdVshrBaTypIyU4$4^Vl7ZeUrBvfQtM%6Wi6(;vrJn;z|-JXea=YzM|# zHn#^>z<1!6ww7ggmQxObqAk?Tf#eId*^ijq|E6Tx0xEeLOHDg~(uHR6rP~D6gLdA7 z;USwYUWsDe9&R?^3d!1Z6zYvzH?XuZUk?Jr0vj(l%J^);B8?3?i>*Uw}RJ1*VsP2z3Pj znf;fBiZ=CO3ALsil`$JdX^$8^+@wPW@gUk=zZ9J7Ai`4nP)) zZ3ohZ#)3P~_8l6D?tGGWXMl@<>}qfEvv*q6{Wy6eC&O}l2wOdZp`=Rq*1Xq^g7e2lEX~3W> za^j-QQxGk}z~No9=y5*Io~cbRR7+s3OYkryKuy#HaXbNy9<_vcEkV7y1W}X#Em0Fx zA|jh^plND?5XKOy>P|-ZOu=pk5WV83*S$MbsKa!KDsQCzs8~~%t6DcpO?7aTUL%?D5 z3Df5DMsAx(kRFAH`7?B#&q+sbY~(l;vW zuPD~9m(|k~+N|nD^k1k8k~_VDG?#Us;QOIH@>0z6vG;Szt_HnOK=v8hYq-#Hu&~-W zdOcU+eqPwVj;zbxWA*NFh?8;Id#u4d6mhaGdykEB4-mFb*wlNh(cK%7y}iep+{uWP z_8wc$-C5Y~nNZeyY<+iIp!W418|`j}$bsHt8@SDg9PB+7hXqrR5pA%1hapQ8yT$zi zvL~-875gOOWLr|PBM>Lkl8S{D!M%VrC4XI0a!@OILOB)ep_2F4l>ALi$%lB!7vOuq z(vUqNz1L~?7)S5ndiRL5-me(kE(b5d(R+%~otD=7B@=JlYRZ`!w}Em-o(6;96~Tc_-a!DRsoRa^1-pGu zPj#oCGVTy<$3~Yzkzyd;_)Qy#uY+AqISp*>K%7H4kRzdHAifMlRTmoyeg&}()sct? zThY@PH@tqke`B81$IXo>S>TKb>hHBmb~d$J*9x>C%A9{*)$Qv7J`B1kmtk9f4nj>f zZFn{;KXoKq(x;)mg1z47UJo|0K}Y=-$PsQzD1%0kGI45oR)5K1om^`AFOWFTwuR^Q znAc<5OqrFMHc%j}2t=1{f@{>$a003D1U4QT-}e>gm`5BzlkZEt4jm51(@a9(pIX1r zD#}1T^>-vz$>yiPh?QndNn%Ofb;@%)GDDvIC{OYm{=WV028qUOx+)43|E_()uRo%h{8C`*`Lfxnw%KN|)pmy;>vdrMV`KlP&-3L*kOX*2=lDlxZ~iy&u*(5hgkDLscvfI1)qTskmP@ zmFz^JreaX07C*b@AKNa(pxHj#$%ghz7~fkqNt|I-EyD_xVJ^`AV$B6n;;nvm=d)Dd zj1oz&cHg;Y!)** zGe&mlPY^W`R6VF4=HEVzQnJ_jis#VA^ctFrMe2#G0pvIvJ(g!1{WBk^1mI>70A1)g z9zPf2d1%mK74n20=fpCAC_d!m&~^<<1=P@NLMFU`B!DP%4XDz-yi58%LYlB5m==A^ zosnmoOBuSSd2PdY@bU8xX|7E3mc>_qCDnT!-n#KT0%7(hj)WYHbngwl zuw*yz$%p+XF`xT17JM#9%X>Q>CmV>6Tcu!M;7pvDzYm>b#C?*Ak z3Ec&#x)FPaAUP(aVYnbU=9q@zg5;R5H4K*{$9$$?xEwj=Ee(@cTb5^uh8kLn%GEF< zYcW&*m29krd7zeO;JUk$?tD3=El=+Xj&KeLu8Ut^k4i+S;1$tGx+X|+6qfw2dTNkHiAk$RNn z<3!{ac)DrqQ))5s8fFGAAZSbtHI%!Ssk*URw>h<#Uo{LD4bS>p4Z|DBF(n$NZaQtz zFxj>Fys2Rz2#;3$A`O*T%k-*-8C{E+tYMtBn8*H=%AsNS;NcbOu3_qmPt-6ZbdM^c z#u}=w^*7CG>oaQ$`(4A-WprG_)TJubFuXr`@mp1lOS)XAm_jo5B8aEq%7v=^9!4Q{ z{e#ce*O5cVRMqYR7Oj?aQlFWU@&m0OSB1q}!6n<;e1;W3x{k%e+B%K70xTH)sPvhWQ&WcQAzQ06KrwSBE~Vk1v^9X#l#jj!K@o@$_!awj+gfnC zWJlk`3@k*xtN(x?zdDBR=|cd5{yA7q`;o4bQxd3}+j4-AQ!EsB=LOS!An6Ly3t(a< zqmEMgA}ON~!2KLp4qLft$+7`1&(;8SmH#wWEZhhAScR%os8EGyry?rb=!&1Hte}GJ zk%~|jD%&R>S2!UF@9klN56(D5M6`a>aNhc41cLwaRn*Ir@kxyuD0PpN zOVJSeb0GUY@I9qsDGUulDYX7g6a4+u=!DJ(8=j>HJ4kNg8wW`AzE7}3;yF2_2kWsV4eMj;==aE z-fM}1|039(ky2;m>u{Kif?M9|X9VABuz0Icr?<2$P}7xaG?Ik_2SlCHEvNLumPG6X z$PJgGU`y(P{QxrpdrVbXwQF$K&23MT`%GPe^XnnTJDC5DzKi)@_Zj4~D-pS?nSBTP z-IzTZCaad`6Ad%F7PDT%JPVAbLY04I^xD5LQ~rf{{9l;#e_?uPn7ZQIX&7#Oc(|Sw zG}Mc=b-YzyZP_!mn6QSKUW+-QVd|E~poU4T<=OTx%-eTiJakER>Ay1aXc!WaD(dOL z*n{bSF;Zk>QluFEht5Z_Ta}DSpPou$fiP{Z)Wi}QS`VYpB^=KX(RR(muQUl%#k zd=1m3HtTE+lUR$Hs9~P3#SGIhbuH_wVd@%ozlN!6SgU%P302p!XpO0^WmipV>+4!} zPQ%o-?C`%Z#TurrVIQj)TFj|!AwOm*&Hr1o1wXvjTrHsguqj3V-6p$#*Mqg~n~B8s zAQS@&48cE7BSCe|=2^mEuN@MOnv6YFEwze1SA(jm zuVJ{s&imwVqbdSEWjN-nhIytoRi%od=8?@F+Jqmimep$XHgxA7h;DIk1;sZv9_()T z6l9cKG0oio4Yb`zyBs`+>EJ#Y+N8GQ7BuE3T0T&i8xg&Gl-G5SsMW2mdmjE5CP}NU z2i2|XA_3T1OIWTK>VmSd4%Mz!wTqRQUrvjjJyPtD4E+m?jU#X{gcARPX#nLu&D{t= zBwO%JM1Mdli_(M*HG57z8>eSPB2{li;VvCbM{cfj)DoZwGZoF-$uYSarjBQ-hT+ZQ zJYzKs*Kr&(@L#D?G)(W>oZAz|gTfMPQB8oN6^FK=Nj2^}>L=-xTAK?7&R|S(M)qPC zdagzzp>Z4JD6G9v$;IAW+Ljj6CGH^Pr_*5*AIziWp8(Cnz+ZG={T{bOYQ6qs8h$g>SQ1{+E6FGdR7#2a|55&HNVU7T*u@4npOfQWcX@LB}7pP$C< zYFs0LnWD>3;(Oz9QxjyxZ<$A>{J9-c-3=15o1_o7xFZAaUW3yc#Q%|&*`LBOAV&7j zNpe|F*oBo}A9{rs?`bYOhyk;pHAjNGAuf5Y{Qgsq;NwhZyRpQr!m&zp@x+_c~?HnvcR7aLpXi4wio*g{W~@M2@j9Z!_#ATXZFQ;b`1 z9l7S!#$B#geqnbDf3bAYeJS+ELGsjs zqY6=p`*esBb05xPj2TK?9ImTZr{lR$i&}5BGqNW`AIQ*`IK4MoWWVH+z8Ce^g*AKN zU=voABz_O)vHK)aG^suN+=E9pU@dh@SDpHw;9+)IFW7}uL3`pc==X@;-4HL0UdJWu zQEP6(uB&AzwI?36(>>bXkAqL+YGeSd9lo zXz9v;J-RYII>33{CN%a_8iOCeGjz!VfA*ZsNCUQFj7cQI%eM;TfCNb9W_CIL)39<^ zAD5c`K7twMkZdJyLkgpdB+FNb3{i|@_3!li;gug9qm;IA zdNA#>vuMhRa>5Gie{tD(fz} z4eR;3OMhlg6(-W0v!eCL%RjlS2}6@B#*nndU#`MHk#27q`6O%g6C7lA4U>vGy!%TVL1%m!IUT0w>UQ82K zl{ylC;%lZ(eXz@ItRVr^gIpJj70frfl;+nXf(Jq&_~P*_GU${Cw&2>9 zZWC}RBp{M8wImA{jm@GrfJ5$GL z$5=%P<0;~>;sX16zL&&(&f=^L>vh~)>kUnre+JKcaFS>nUB-%BLp{pR)VW8qT>9(i z$I1MN;i_cp9&~iy3W4B!p%mu}7jZJ42~N9o&7S`=oFN`a(~r8)OQ(D65}uzG8=Uzi zr;#GV8puvgm!Bxa!ff52-3UK(8`>lL9nwj=^h9C0+)5>s6QNsBrG&psyBgGIw|7ph z&U#dK^qXv#F5Ig)J{8Y3G&-e9JQk~O_g=?IIj*;$_fLjWL4aH$)+2)Nzij$r&HJCS9+^AEAzkZI z>6E_3`B(NmE@dM8N?BPu8lx?u6ud0{*QpG|>*tE>G?#S4)#a>n>R#vn<4~2`?r)t_BUz}$Tu?9o)ErcY9CFcmo4+1KwTyTvRUUrcAstqSIhMENa+(co zWt705yy{kEzLH{k4MWxV-#buxA=Fu_Oj>&2!w;z2~@@r*uNgX9!930(!UwM z&^iF|st>wBSN#10OekAtlo`5!s6F3v27X1%&4kf=Xl9*+w!**Q0CK44g5J{<;9t-S z$Cnl>u8q+ZCHfciZm5mL@(eJ1ynCX>{5^R9Gpygc-=+6??K7qx$;!}Qhw;!N12RB) zEPi;C*5uBTEUVUFxl}BL?~(Pig4~}j>Ay@I{>Y$Ij#5;osX0Z3RHv!AxeBRH)2}F1 z1gAufq%roOBk5VHDilx3A~g620A_xy=ffW$QfgX=gqTGMOIBk}oBV(rl4TwORq*Kl zuL79B6HX$>eGcn&_QGQc_Um(Bz&lAtmupy}`7m=TkNBYwkns;VCe2&{_QgBTaI&}gHHgn)GwI!tK3+O6osww$>@>~8+LJ6F%2Ys4|?d}kH zR4n}7hXo(q%M#^*@O#4vz88S%_olveND6tp9a4H;u!rjHE=@0>+e282>VurVh~nGS zcp=3}Mb!Xq>0?qe3k5=i3f-s(mwM>GB;+tCT5V-Z1%2bC5YZ$&?=R7Ag4EOqQ zOi;t{?J~z~(=gmu#4&Gcm~Lbot94vjgQ~@N{)L$ij9vBV;*@O5?O&h05{AF^&PI#1 z$X|5U~BY;8urYM5@dm~Vlps~KvgZB0gt z(l0QU8!x~!R5N{=1K*!0o3yh!>QC-!Zpa=QTV)u$fVFx;n$Z&bT>2L@?SUr=BMWPT z?Th~aDfpVeh``NOnBXv7HkvT_WLpCG9dd^@2<%FB((TXm`M2Rv7lZ}B5QFe}!Y>#= z7 zTPJR0)5djq_>qltMN#ng05P4mcq@%`I1q=Np!8dkAr?)=(zQJ62|Dl>e6x&f|G0R= z0^?_)aozQvkx+mRxqrMEETLAaw@UJIEC*1`2)+Ank?u6i-+*GJV|h8YU^jP51ZC;& zrU=Si?nVgqJu3Ld(s2;2f(-A>a`)pR^rLvH7_cW+@^33lLPIlf{otBY^}prielx;- zZ(gqF;7E6TUhbh$?q+$p6;5|-UT)J#!D(W7>e9JK(tC%>#e8(~Gs2B@jj&jWFDyEs8 zzgr3|1!(_7pG@CJ2rVE0cZ+cUEXTf+^kg{uZh?}~`st@!qP-!}-Xzi9nnXjtLjLxh z7$CZEU;9oBEnWCw`%a8CUAUWlCuV^z+|j-h7PKzh#?FUk7}aP%aAW(fCm+I1QXi5-)HnvS?Z?gu z_seduZ=P)Fc^^;29R>ZPIpsh)eGFlhifRDs&h||j^{pS6w1QU~hH?<8%}YA%RE%C* zB%;^NPQomD4cjG$oD^MzfiKwG?d3B!|29tS1YzC|oEd+n4?m4b*yv3@3A0Bajb|Vd zC7(==BwyW0KC(!Kzu4UeA5_V=b-`R6{l5D_;d9diV6x%+Wjc2|D2HBv(y`%LUJMn{ z1AyIo(|~81(Shvd$tMdE&cn+qdiS=t<85@QX(J42edxDqd`_yuAO&`x{c-za_R;oH zBgOplb5H?nrrl&{%jTC6U_bv94{TX$S>vZ2hI`ktQBQwndF~Ce#b4Dst%qj)AQ>5) zcO%|l@y~Sa)B%(bU)E$x6U6cLlY0?_qg+w|Z9fQG3LiecJ@+{)*k;4ImsMe2b*jp2m@co<8i4PmH*09?Xn;FKe zVa+l-H|VHxJhFxj%~Zc@%&+3`FCZ6~VL%8X^FMFmrb> z?TUuj0z~Z0kArE|8e%;VO=hkOrrp#Ki&wK#nQaX-a+f`u-u&IJaCq?VTs#22Axd1i zE6UPvH5>nI*Lr`zh?#YE)mv@!53@bbHZ`nT#g0Aukm2Q5ScB&tY`yh9h(I5N@Oy&~ z>Lw4H4yP;1e9tO2^0_3#t(EMR=bq}hd?hmZS^b2Cd+isrgoO`6_KSdrBP$od&efP$ zVwB|>jxtSL$zmow(V(#kMOLsECw26kT0!il3IyTBrKU$d!bZN-)Kd+T)u0;%a>5*( zqvYSXpBAb`3o(K6Zw#dPg1Lyx<|je*25xw-HJ_b@YAm6Al{g8-PeT-*lNfR(>i2PH z$q-SQYZ6m!&*)b$%k%eJx)QfFIO}N8xN}hNR&+t2#R~S=^Bp=bJ%J{8Z5Nm8burR} zB4OSbC<%}&fj}{5D9E=3m$SE@zt`~ga`xc#R)z)3*w#>(oPB}d24gP*d5SR^!5+qh8LbTOGS(G=%vjd6W`wxA)Ij&U=zX=HaYM7xYCRfcW{?$hUnBS_-FSs^EM+NE+ZmcJWf6$_Y9VX=Vk^V< zg{*LDE5oir_924*6tWkAoL|Uf1TPdWo7T!Oq>#lU=w8T90oSaM-9T`C3Gb*gOL#}^ zTf#f)(3T zI#Emb(D`jKA3FON^P#hOF&{c?F&{d!7xSSrZZRJ^{TB0~(|$3pQKQA|!K~(bg;(gL z!k*#)22Pvpa7;B5=Dkj3<6Q{wtao6hvo)-u~+IkFm(}^Rr^J}YK<0gSzVUz zkkw(C*Xb+;UfU4_&4qcNBP-N!r_8owbuciQ%W5`0xreDVPUf=eCv#b~m$|I!%Uo9B zgQ0~;c@vcsT^-QeOPz6H4Q8dS@H{3P+f%W!?0ym^oSCV z8$1Oo2m-+Xff}+4S2DY)vnpUuaVn7N& z3M#T|!3v5A+tXr!j3s1ocC!LM#eisnpmqaPihcjv`O-ukfzC?PyD#BcN%PsA z+zpe<qgX!g!JuUqUT)qf7t~p2@tvt@e%5rh)sXCG8M8YY8u*!ec9+Hn;mNS?ZfG>X zg*3gGeK@;S%g4&OvCC%zx9k7rUl&R*W~XL9fR8Mg=L~JVp}8LJ@oUJnqYvhXG@$~o zypOn|5+YtUdrqR^4=-CYrKAFe9d8K1d3Fz><_AhCwI;0LyKqZ!%9>*`t zk5OtcoC1gSte`y6kwkQpJt)UNZ~~*yt~iqFCY%o9y1bNwCM)WYN{m1^9(!I|k!L)lGOr1mzPJ zCl!iv#wL2*2Jct?YWT(E(Zy1nKIqVMrSpJ1dW$ql9}PH$yx<_Orfo7*kV}3JUro#1 zAozCC;-Q!Zyu`ZYv@}eb#2(G*-79@{Zalf(679RGUSH6F!v~`(LbR(SeTPTF{(*d? z-Gtb_hKYiacGSa)avp574iN96MILr3$7&evVGrbXG<5N>(YamBf9}`mzEDThbHz-~ zZPje{9ykSr?ddqi#~!H*?WJW5r!R6}ZoVJ-Mzwo~&*gUSA=tg$<}z_^TSLNJHf65W z@O>_OXYLSvA-g=cOM@}FR1x!(T-L$Uz0m`JctzrK*+fsO;ZzP=@9AXNp2NyKZJW6n z1SVw^@P`_s+L4Mkzr@%rPrE0EET^a8+0hRL9nn2WeLJL_=w1N&kQgC|V!JZrS7`bF zf>CnCJ|ylSt~mUU+k~+_q4hZ@Y*ZI|2rmBkbm@wi>Mme&^5XA1z6`65L*GIXA1dJU zXj0Hm>Y^KzNZ>poyYHc#lodL*D-Z2vw)~Fi#V#oWYfO4x?!9(vFuSAnSv0N-LdU^> z=Q$!c1b=<>tTS^jX47}Cav)K@Thn@|94!`ToEx_j)4zwoU_Mc1m?AS)_6!|$0KJ*$v zcM)RPz*4_~z3cBN&+#-(e^o!|t6gHec3&FUs5Iur3RdFbsw)us5F`U9+FN zoJ}(#CV;(MMK;^Gpq=5XY*xM?(=!Z&SwCufxz*}kZXeFY$)|?%DZZ!o9c{&9c=NU; z0f(EmK@dGmkYfOZ#mDikk`C58*RCxN>2_5$Mj7tEEFE8L`~#2QUHT()ei2g>?34oX z=HF{{ueE3BbaDc^)y(G`8bS- zoW{it46jpJ`g+vp3t8-^!ftIJZcO^%s7rsFzAu^b9`rb5(3#7?%(7V5rTq;`R9840BFWm94n`*^9f$&W80;aPi;n$lAGBCB57!?5&4_Q0}^ZKr@3 zes?F)cF>RdZBILWeNI<({xddnnXCEj8RW_dyn(wEVMIm!WsJvbGuU^_oR4h;;^hOl zgY^b&yTT>d?R$wwwk=11kND!dvgk4o032rHCPGPi;yycW(+K|0%+#Cd6?SiNmyFC} zTxq$6zJh~i&Yn=P?AGc|eJSl-t>l)F+RC+`P(3D8*cJQ@fXr&U@+fY%;{}%GWg+qJ!bSX>9q5#PQMK0?&6jEnLd%D5v$O zSpsg$omTw_3BOO})NeTzA01Yy=QQd8m3o9zO*Paijr#Fa7P~UuP&k!!TiN2_msQ@1 zoH(cT2VTY%jc>e4Ig}G8TEFL%YK_u=D$7~f!q9mtTe;F|P&Tv5mCYL*c!4+a#~0Ye zl@G_R12pUGE;@%suPu0iJ+dmrFzf|3V^v2(=NH(@RqfLL3vVq1e{~9_v(!fdT>Y!U zcNEa|7lCwHf5knOU|QlK^(!H#;3&l%tZzkq1^9zg*gvb<>px|!S9dYYnZh1joz!9k zQsGOcHKR9`=WKFKVe?j}G%*9ZqgSs^X5#Xm`pGPJc_-WC|Ls*8gWA}Q$2NfGp0~Io z|MG5;Q<)u$xiKDzQ2ptX*)wZ;H|qju)~VfUd(HO%qOZ@gPuBD?9D1JpwWiY(8=prZ z@9ZRw9ntu~?yJaNL>?|}ZR>#JKNwOKqVh_g3}s+bWc~uuU>v`OKvZ6`iOTT4u$}wa zy^%kKMf^gF)%4i&EbH||!~M^*VQ;iEG2^v6&mvCqwrZqZi{a<_y#vx|vw%)jp5 z5yjXxtj4{Mp4=PGtrmP0xwuAY&~Bt^=_W4tGBHBj6*yxh#TS*m7MbGhMqDxGTG3#o zPb&!OyG+*L&4&&COlE)cz9v)Pj+%9fraZ1K$+i)hEa%MxLyt`M#+yk7b0!PCnbi8X ziIAx`ax3Q^m-Y6n#`a(o4Q_BBoVaX#i}2g=lVW|n;Y58 z_5D2U|D-KJ{5Dh=7GfCsxB*;DVkW+d?!T%whkx4CAvmDE%;%n=4z>J^0GGj_(`f#m z0_3y;S{6)C{Kw8eiL(s(p)y~BBuY0#@7dcK(BQ)6OZaLq-@N&#L>+r*Ls!E~&#(y_ z+O`}9-tfo&vwX-2_Gj3N4Q&lAo?+WJJZh+Tn%&+I-}cj|!HaL?qf;!HZf^jDru`5B zX6w4Anf0v^9y_3y57~nTnhZc&Da~$gZp8s%(E~6KF$&KJi`pZG7wp3PR*29wqxnq; zqw3(GaXt<3(Csj!gg&IgOg}$Gg;_4~AmuCqyE6DbF|*u-eF8qmm4I6qXYB%O_@B;w zUneH(K2;C=LwbO|I$l7TB8wbK%XK7XhaPvwW(h&O0Me*WKE<;B6K_a+iY-QP?^EnU z1jeV>L;tm~Q~#-N`1MIv^`H3hWl!=<4&}5!CiQDFiPtiDU!@-8)aV*&qDEb$QorHU z1~t?qjXL8=_VnBFhG9>#xo^kE-UnXPIh6+~_dm(rfBQkhQ&VP!-H;&Q=vgjtKsv7MRnDS1% zq5TB*!8=_H)#D)sOS-yOw|oyT3`B;d0j-Uysd0=({ZgeK=2U#-R~2ZiMtyTUWEXG9 z8_$Lym^hwIL*N+C7XCNh(@{xC4{4=6I7J$aE=-}BC#8oX&Z;#9Qhy<@#0U8;a@5(%=^+r6pR;g-{CofV&0I7 z6R=MBjH!q(`iY8&W4>#hgaxMrG}v3+8K1W3gJ^PjXg30EA$4=x;*!m%>G12~QbW4+ zdEDRL3VRu^0`Sefi~{%hpsCHHI5|aoL#4@V>AP`;O}*H=@Ahr=e2A7b`l$UMqp@5~ ztsLRh?}OhXIGRP??QHmHH0!eIiS|y=W}UX@-{!l<_4Zvf)x-N8vgyGY5RYQ&HG^&3 zl+@b*$Yl)x5sjFjv}s6P1Z!vNi7anURJ_i81hn(0sEFH>^u5JB@_@;yrkSIe@x5fj zg16Ws@3kG!5$mEnz$g!nfl)wz2cb-qCKQXAuSH`TIg}~bp;-ov;%n?U1h^yVJ$>7i zdE6ycKtBdWX><`=^ImsDgHi08_eLAuAIXy57Y$F3WHa7xZ@`yq*!vGPF2a+zl_C1J zF`OpFtn&Tlt;#$5wHqgvNOEb@OMAf z6~p{E<AJo2wjr#^=KC700bbopPhz>7N2lMhmlk~V<=5K% zbV!u;(|-DA?57)1s^i*zTJX;VpZyEIncPinV<$IT9~p`9}C zIfEwUQH+m^SZ(HuQ7QEOZ(PHB3_c{foNOs%!?v_FJeR><+LGV)dzV_wbsF&aJ}?!- zUpIx-Vw!x?+LN{vP0SpCC+fJWM|OIu=_8V+@-E_ZRSz?HEfpd=qB|3lZ!r;M{8>2K zr{)u&m`9)_QR1FC{N)Z(4)S1QBp~ra0C{jU+us!Q-*sw7^+Oi3bq$ zC*l{mA#d{)thLClGcbVuRH27ds6vH$5u|L>vG6CoVs`+SAqDWj;Q)L)Y%uHbX{Xp% zft+>Pdpjxzf4Ri`>|pl7r;COk9Rv;T1H1we%#M{5Nd9V4bAi)|;%=(JampJfTB1HE z1|o_0xC%TqiKx&pB4lFxndc)NJOZl*v4NjC49-DJ`OIzD=VZpMJ)13e!bqksuvjZ+ zog5$;m!RkJoNUNeyQ5GjSULbrOtqzg2}70u`fR~#6p>99V9~p_4iw7f#uO-zMd*8O zzJXwI$;vQxWNU}V=<{57u;aAu=PTDTZRIk52_^2ry=@}U%C$^gxyCL&I$ z)EW2{4N9-zYcO92oSdV4?E{;%~m4)|~hchZPm z0?AivuKVEXcXwO{${yfSjNP31#kBPFFUY}xfzsz8vbwyHPVVo+9r-5}j?p_WZ@>`R z?LiEefdyZjolqr)(9JZgotR6i-%wv!>WHQ_jIVMS7PK#CYQYRM-Q#0xM(d(N65(~ z{f&eUW#nM= zMD}MF;kxgf%TBmy{-i&PB5eN=x4nK2gz!DP^89PJkg@$M{woalCjZ6_z`N*281NI^ zy+lYC2K)kzXbAiqn;+2OB39sRbp9TCa_MMrw!!{<9G2)Jc-U2lnjCjv{LF_<>7b6k z>cO9Z0UtJqMIc~tDCa>2?iEgns1H5xc#d}Wn1kq_^fI&>H|Fq1*2=@N^t@4DjX%2u zyW}(q$&mIr^_S*U;m@nRf_!G3f&g@LPe9TW0pej)b`Ea)e<$M9UP3=g|r zr<_8hhwtoj@9ipKQ4meVF&IYC%ocFT7NRV{`zesrTwyUhAN;vw9`IO?o}oatO+=7< z7&36T2v4hZiO15M!vh@yG-LKKr&P>tz1`9?zsBlrMQQzbK((e=#GmEDExMXN-}M=G z=b8!rcYn0?ZE9e2AlwOR2jZS4~ zLp(_PsxxYhQy6OOs_41;7z?;x*5mmgYWNUORUfIy2Jrm$9g=e!U^$bxlrIq8^swpY6Jqdo9Tbb6N`)AhgD z1Ajz2l%zM(r=0u+^&6-poy9AObGnEgW4wVwi63XrKZ~iLOK)&Cy+PQn4)wb%j@QtG z|EIUya3a=OkAKs<$z`fd-f*&moZq1My{qa3z|Yil<(N@?!lAWoUGU z@^}OM;Xw%F1Wu~I$k6YBEtW(NGF#u7AwKS*KZ3WI_0&0oYh(#RbUxk21k%!s?$E@)g|s$ADOSMYzi zu4r5!qP_77Qk&rEq6B~S2FrqG**qEeRE!xFkWV zsFuv$+&>KO11F7wlV%#m2vw1(1%#RpV4%w zlT3{I9WKk_0LM1ulSiN;LXZ$pN|NeyoLnzuQCU+ua0z zrrjB!kEYTc12cBV9gR;yX5)^#74+sSWxTDDFS1YBC86d503&W3)x|K~Hd7 zTcV{hK^u2G{VJN=W;jdvol453=5lihL&; zG=NaYf)Q9*E>8WQh{=ETj$ogf~Fk`@s>CN{MAbg&FmLxMxe6J-gP|u%s($3C5Vs*>;HdhuLlO zF4J-vwyr~;r#F?DZ+95z8?ZKTsh0HK4BN{RusWnL7fPS`tO3Y__qGVS4(SPIFD2=S zP&fZHHv1n3lD(jUrQznf%T)_;6Wefk+1?mwK`;5l-k@f$!@6q2Jtgf}w;lk03EGXr zWqnC^FKCzNl73Wq?q>WCiF+*oBAn0V5hWcw2nNRssm*N^#Em}ks**tHPkmF;uG11& zVLNfi&oP;0;pWvbd0*?u^`!C~-N!IPPTc7`mtz`*H5kVFd z%H8($@E!dKlf z&oC!d;7-uTJ-~1*R)n1@F$_z-Axm5fdJR^%%I*jm*65=!6#CT1(c|;r1WgRw+eHXk zlwwP;4Q3JdK(=)Gvv0dd(|gDlz76n5fUl~prh9gVJI%B^hsz#zUuKs(+JoN7H!LkA z_8$5u*`=MW#uM!jk7Zb))%Y3StR++{qH5^Ge_GOwW##BJ3vkERoxGLDVTBI;J-Ev* ze_&CZV%Y$9J&C!dMZJ~M*7rJ)e7VH#m$91s*h~`W2~m+c*MzbS_>16Ybpwf6tsI;j zmxs$R<0`z&y=*jj#ZlW(K*3s;1xq|x$gwh2Wnf?rfW2RB?v+@WU{&asVBJWS82860 zb=G*N8&OZMZPuM~R{^@l+~72?DTd?oZM$S13%2E|IhBa)&w zmXe`JzLeORh}{-$uA~Sf*TkAV?*%H8H;`J6dl~jwNvj_3Dtt*MtkRuyKf#l|c8*V6W z6h(p1?WC?bzd(5r#NZ7ZF>k;3p@#%139|0dnX*2NvVH>7A_!lvM9727I=Dwr!O@u0 zTi#vPX(Z$!iyY(4hqxWor9QSL--@^VOvB9;3^$X=!*9`bNJ-i!%8ja3M>C_}L-}j4 zQ3(IpCDcXW<0056)Z8cG6mxWKxa?6L=Bj+?+#=+-@&N{X(BkUJg=gXJlW_Ti^3E(= zK33ig|5wU;_sZ^u5PIo+;Leaehd$_BhH3O-js6Eb5n6*zrv`b8K5Z{U76So7R5y84 zML!hD#}!^au&6qS#<;l~rWPBCggairS^BodUQu57g{!|e0ou_qLNjiY>(XujsztjT`N#to{uV6iK=5`x#^KU zep5;vQT-L>994OkJmW}57AAjqBoqJsN5fn@P}_^F=^zh18lHiVl&erV-;Njk?BB{` zE)!o1;6nh7W`9>6Qz-x&0K@EWuzN=U^8t9w-iqBj0+<4z@$5C&y(54T0GiCs!|ojc z!~L)q7s~& zr&P4VAnsybt-1A?J#q_2p1_=_xUPbqmSb2IX1|gE&u1F zzwra0SgxdfFkg~X1=S!gRK9Yui_|Y&_W7}`baaN?@5fkaY$Mt7V{gB9`vhMWxeYyC z;*=|);K^{4F7ag9?d3~921?V~%WkJ4rH<|8m{W0n=R=6%x@t0}91kT0B>W&){_&@d#wiqrpc(PnpxN+X+3V*Z?-SSoT)Ya7O*=w&4@Yaoz0S7C zU?Z@Z473emYnxXiEz|QdCByqMlf&+MuWcc zvR}OF-v`s5xu977{1<;|)-d_|U;O$Es?Rj)eX#d2FUX7@i?}e4dZb6>R$VB9MTgXZ z4C+l*EA%wR;u{R3Z=f7<_Cx8ndh+43y<1$}ML9hId|DgI=~<+g^uh@CXe-&P$RL~T*H6kLK7MFU`5 zJ|>Rh3U7M4ZE+ z>pQCE(EReb875{WXt)|vRynb%=&0#5JlxNf$_dPR-GNxJ1*WY16m?eI zYSk!KjZD?ZQ;p5udTPhLl-oKCIql`MzqjxIdo<<`y(LSkDZ z8EXEq#9QRngOz%lGdWOott!W5QY!R4{pFX>cL=zP*`vwE3t(@d!Q~d301c}?qQ{f- z&-+M+{p4-ulU{lYZmBetg`YHTQnvo%+$P5q8;4vFe`a}r(khIzTr*kzfrP~mz7St0 zKY7rF0S$ilMHrVcbNSv^{`f-sP9Nht5j#T@p?h}*^Xla!w}!O^I4KSzu}Hb?J$Gb< zRw-&O1bY%U7*!gJ+YX{0#u^f^{!oxEce@xWeKt-`y4bqy>14_w=275Yz^Az)D5xQ1 zf!``bpYM{TsJAzfKfCDDV%X}C8eIJ$CEKa!vhDAHmxeZeRf~MN`eKytkJ}v`!kgeS zN${rdAvDB>x0L(;(Ms}dDJTCiP^$2ecl{CQyVgg^>t|#{>DIw8EdCGyqiVnBBj5j{ z4SEfqOD&`awQ~1M5ni5(yP6c}7`gmgNFp^p^1@5a!-)H)^R(bK@%teASv78RMUPnXmqs>TZY#yNkfSe;kp65guelu3 z_DE+eCSVFv_12E?YfC6?HsjJRbbB0b`=%Cw(=9f2mMbsMeTAlF*!zNibXSuWm~0`1{8W}pYTEFz ziMTPdt%TNDo(t|t5~0zlPT^c3m`b&m((Z9O(GElIoCj#awn39X;67+DAl4vn`K2p? zp$jrY%5nK%U6p}oNE#+kp{Z+>Ist1t1_&(}T&G+`|5x2iUV0_0MQJmthi{@D{;1T$ z_lZq_^_FJxPgmNpJo(9$_RY3E1h=>=wKH+^SndeNC|2K)GePci)!+9cG%F{2e>7zGTu(Tz~kjR9!8;4sHn zbv0gchsx+~L?p;?>QaA;wV7CA(s!o1gZ(Wz%Hn9%VVb*p;X32g#yB`i4<#blT9$z5 zA65Eg)OCdbF!BlhZF^|Oiy3*Uk%pkWu0;8$@>pDBYV)j@y}uh|?65Ie9+^V0KzyJq zss?ty+)1gPpKGXsyF5q+N zmkGCC&n4()0IeEquw__&)*tYhfo?hAyMwR=~L;mKbNy_(-Yj3vg{Wk2XHmTWFq~EcYv|>_g!tekc3Wn)Exu+LBj=-1*s41aoM1k|ELa;EP7f0*GMT) zFTe9w3ucyc|7xY3a7!a^`O6g4x{xL?f1&%_+|a32WdOk1B_>qz57%2t$qnVOJEJAm zP`2G^)-VB8nx1mq)=+uJ9WQrkZq!JY4U&)FY2NCy2GravaDfuugb%d3{b+I7^lFXF zX&}4*-Cye6Kz{A-zzi>dRU53jvo+*gw5+T$rDav4W#yC_a?T+rt8On`#70%3;hAh{ zUTA^T?0Tas-mAnEm#L^)StIv?2|*3}o(#(mh`WY5d{v-@#fE2sc^YoyfBtUL*aoMh za<5h~;~aO{`)(J>!w|A?`bH{V<3+XDWrMsFpQXg9^N zzO(A5UwwJxeP1cCojmXU`quwyiz7!Z`uKZrA6H?~#o`66#YVXTH!|yzM(*<f$gH7@)jUmAB3M-Dav$yGk?h?3&+EmFT2MXx^C7jKz#Vm1yc7 z!;3{}4`7{4#jbFVO^9#$ft(?>=vP}~oU<8^z@Yu+HhlmrENOWOmIe8-qN{}DRbKwE zGwUuNdI*7weD`6ij5>tcv146nl@xKQP zSNDf>)RbM;Iy>E4V_A@i6H_7T!|;l|hNE^QSkej&Id*u6$6AtA?+LCSZ6F8+&gVl_ zti}aIU`a?vSmk)i%<_hsrVVatsRp8ef7QzSYoer&wepjiww>kzM%^n>hD>GPyasB5 z!zSYOvQaOIR)Bjk3QCD9lwW%k>86Jt#Oa6Y=^yoK@Cyc{l=CRR3Q7L?Q8y`Hk{dk^ zib@7t^{L?7chg=E?3){oe2ankT7Q(CVVA> z0=vBVaZ3{xaQ8jTF29gnH^!tCr^(RoK|=Bm)Ud!SMy;d{hxR#t%cwe!qW>O9DH05KJa zjG9t5YJtjFP!Ff{23U2%wR&L2QL$RVpyhOBAqh^`@)hK-$ z*m~+X%J3O)DXnUdFBi@Y)&9FyBOjX^6p{?M>Qk{|kZs>{1Dt*$zP z3TKIqZvl2?Sf0fgiqeS>?M9i%i2h>XZaH? z3+Y++6OO4e?5k6of}!6-b8;QE0Sp@F(9^1!ABXYmS>|cX?vCKby08vfZ@esXVMDdM zA8Pm&7xon^-sQG$SjW~94fX#DxY{+q!@VwklfRyEK;AeEKb&HMoP*wv>A*H6w z((u?k+a|^SQ|?)hwQfTTfWqEx%Cy5icMBlQ`?kUe=vbEfIe)Vrd!PNzFV|xs_0KDw zFL2NLETH8@d_Ys?0jsn1{x&AKCUbvy-b!Ls%W^OA!S$KXu*>*}G3+|cP9l9V!OGHM zOy15v6*qL~m}ZY2R50y(AH9h~9Fdn}q_$(&m18^!6LU6nuMKhP{uRq{9Q#nn?e&?T z&Th7?EaaE!vq65>!C4TGV>Qmi*oAYSsS}|Ea>&K*Y4~7Q7OD-w%R*Q7X5b-=H7OU> z1%>s>F1D&4h{FrjAB9c1vNpmWxU%`~boU?)Imy-BV;F1RFQl5tOQ%GZviy4W+l-V>D&9{%~;}cF1&@Lf7E^3RS8UUpM$!H`XHKCO!j8N?bUM&n_u=59M9V|aTQHd`|JHD+0SnR2 z#Y@KqY>1x^oIE`k>r=J09y8k%Ivf1?M-5nbgJMKWayoQ2{A>f}D;+w;A2wi-ez$U| zWbIfhNxefc)jaD~2Hrv2YsfljL-4Y&A)3aKzcl=(hN$#&FH)lQ)8WNzNjqL?Ou$Q$ zar{LMZ>(pz@7QP|4C`9sVZ<8}4`aks2vsuybyKBZ2{}PyASY-HNic%ctIExW1PG{< zE5PSKS!^>(7@xWHN0;l&?^Kl z(;Kl-+S1z^eykCTlDePbZU)xH@Ax7I4PM8X@RSB5%L;?r5eC*u+Z-{nm~Sz*ZXC54_Hul8W=TK$ws!~&xSb}4%JP0I0uXF7JBZfbas#u#~;<7ISXHlh7iOfR2p zMqg=Cx9gW9O1p^Cw4*Qh*n*S%Mq~Dh-+wUcSF2PH_y(1$ z8eio#4bSkzXmJ=XUwE<++6j1RU}O>Q!Ph`lYh)C@`x{wU2E(_qymz}&^WyT}?*Lv{ z-uoWF3(I?Z0lcuh_Zff}miN{Icwu?Z0^s@OJy&HVF||^|Ym987kL_QMJT-;G#3>b6 z{GqY`=2eZn^*i4NzgAMfe`@&G-mFbV0bt51w6~O$Bd1%T z#0BlG2C3iS*7KIZlvC(NB(Tc#D_E_bKpw8fgtW?j;NF=Pjz z5>1L%U(zkN8Tu~u0d#1^*-N1B(^a{zF&8~>Ca`Y-P>L1{ye1{y=d@l^k3Q9S zy@~5_9A{RHCohgOD^d@02<5wERILTOUyUj0)jx>yFT={-RHoF8WHMqcVUu8D>tzy* zZ(Wh%eXrmTBJx8`D=%4@qt}0*} z_DVl<07fL`04y58-7*mv26>%^pYmb7n1*|_Wd1P1TQZ!{3~#C=J|~PA6XJ>D68iVV zaI^uh0i@DAs9}UX6IbWutVck3wz0qo)fc1F)hHGg#bTVWXjCkz7OAOuw($Zq6l(=I zCeKE998(Y;8O1IFeL2rIL7;49K%h5@1v1qCg}ewLzY3GC*Z= zj*#E*%&ZAWeaTWK{iNV51Wuzd8f$|3f)gBBK z1po#rqX$@ot{%#YL2Wy5P?80+&6Q*e!KAV?1p5wf2AWbZjsyUz$?T!V|2O8#YN?U( z(a~=(hdVF=8@Oommd(=!n!(*p3J?v@-!XYEr9+7!Fy`(3ScBgA@b$bVsGPl;dDxuv1mGP*OqmbhD_xn+p?CDZd%dYwoEU%HTnhiR=xi(d|5E- z<#85s?vx7<_ANXI2K?X|em0oJNej;KRv{QSUq8dmAuNp<`96HImi%%Eo8?>n4)rh9 z=r|M6>%Nfgz|(wodln+Oo#qAY*-UBK&qan%){U{IynhGQ#TM1x`C&tBVI}Dve^>10~`aS;Va+9XFMZTsp%=69mXQ0>L2;8Fp%Y&ANi#)R-m`_ zzmxr-@4M5$8nKBSlKOYuR!^ij^d}}3=?5_8;bV+DQk#FFH4ny({@08BIx}qu2%?CI65IK^ayZ*V-QCGhaa>+>Y{s zSJ*6R=@ITRh_&&UdxS`9d`B^KLyqu%gV-yL8{l)!FXi<}HyO4rNBH_d?0dg$Z^1Db zC9AQ^Vdn_k4s)nCc9#CE;H87vTxom-@BJ!EbGuZoWaVx--}5S)mbd_)DVLNZY9P@w zPQqt=)DZ(e5F2og?!swQK0rB57j`eh4y#!6cP3zO{f_ebB!H^IHYQ_;8f4FMp86Vl z!-I~4gMt^Ra~8X_50vq9uc4|fDC4b$u(r~$G9EvKCAMn>SBAw0(E{MouvC#|;F7I6 z3`W>Ba)Au1{^B8CGK3A2-ao`Whhi>0@la9JP-c{TkG)Q$rTN~_18`}n!0HtAd#WK( z4n4r9yw1WUw*$Q3b(SS9+|L8vVC&sZmQs+umrD83H`rhg3qDiMLzjwD>6=o@Lx;1W zl5Z)`8je){W9M6jv*B*Cov7uz!Oq>W!045TPq7nDIiUk$_MiwmpY|qNM^ihuzKLpE z`7Pf?X34kw;+v@dtG?x~BVf+>mUkl4{4IZ-%vRs>1tVCrbY~ymJA%C-W$ok8_-Wl^ z+P~XebG=NTlO~mfKAM)uzk`EKP4sJ7wwG6qcR#@fjmgpQL?!-AIh1 zCrbGDBSEpxOZXi!-z(wGAg+azrenrW=~a&=mmRu#3(jHa@ot* zk7BJ`T|lv<)JG)!EL~S2CFw1o50`FCjH*oWF!wT+e#8G9g{-dnhI@==7EdjlqtqIb zVc32Q`a{?D@NJ_}80CBT`O)Zt()RF(G0ea7&^-uv4^$~m^|yFtRqep)cgL4)4Lh3a zaPOV5BW#hV?qnFSp+Kwi+`|`*VXY<29=>S|i zH;Va7;}BQBVxBaPjg~GI@dM*fV0(-B^>M7oxbJUK?*Yh#Bow()@^L zzd}vy>#z9w2_Wj4ulV;9SXXJ}S4G;1>^eOSC<1U^$PHEz* zq90r4ySEp4!RniD-_3~5asVB`xdiAoYkiw<=D+m=OZo6qu8(CI(#%i!(pc8VE%;L+ zM0C`r{HItJ*{x=il9`j(B~p&sdR{rvEAm&M@likHj4tdhd93U%!J#cO^>xV5zD+zP z4u!mW6Q4xp>`i=09P^QeZQ@&C_U-}S*$*Gl*;Vs&iBb1yN4e}NJo_k?HHu|Dho!f$ ztlhY(KLWbAk^92*Ik=Gmx=)*q{!s!66z)FT$cOZ2VSMaN7UnqsuF&3w!%%nX7~?kb zk7uG(TW;k0XQFfYZ3AbsSepjL8z9r&gj!p)fp?mPB3Q72kDJB%NYRReKzE0Ivkm-* zS?JCF`h?@OxW3Z1Pk6*^^cQ)b@YiRfdemIyIkQ=STlgmwwa)Yj-!_}!kn2zQVY0ru zp5LF%rb=_y^NA@S(2(`qn!>tBZP#;q3dY{5kNMvzsBM;y`LI;jCwH>E9wJTeXT*@b*$8VhxMrBI1(Od(&E#-=vD_7TeNd@k73H4qtxo&1P5 zoP$Jv{Sj|J2Z>$w5g!Dz^E+^sU4vti5~HrCG%7bK2gSqvYYP6D@G8Q^2p87#Bfen{ z>n5$g#DAT`)_9Ehkg9*!OvNyc`;g;0*#N2gha5*C`b%CP@``uSoBUnCtKLNe{Gosw z(wVo%wgSc1KE*I@FW}wNG5ve5K=n1LK=sv6`0_8{-=?!c($DL-$6OYWv0)wg4%!I= z(!TU|3D`5Tkt|`M_wlJ@=?YpI58|v!G{N;xtqxDBN`6BAs_IPd8`9>%U~XE=hh-lY>8RR zTW7FHk8SwG{683D4e^F+`DCElv1>K*57&aE9&34725S|v^LNaqvJbkFVo&z%yXx75 z57tmf(QXKV4yQo7ytjsXWTH}izlKL-q6%+b!}nyPLy*_-luY!02XAzP8keJJy53E#>~}xA-Ns7n#UvJ=KbN;meSCibT1D3;jPha@l9j$YJNHk!<*}B zevh1A;@pRVKE{=xZ_gi2dtOo4gF(oO1O~ynaVzIT7r|{V=X2q<=}fqdvs5F!uj372 zPv-p7MF_M9SJT^+tLd#>r38AD0=36S9ZwmIfuTG>;dsxkQq#M0m6G0wLbz3=n)=0f zL)aWf_U#+kbA{|i)yx@!D>>26Kj1drQk>7m2Y#cSNzgu2^EMP%Xt+q1(2CznY7XRPrJw@S=IEs7=LhGjj6r4lzRm&knfVvHX>xAF~((HRDBF!k}ihJp7x^-|CaStn#&naKTqoP42!(^HHd7SN4U7Tfb z1AjCaz00{5NT$M!m|eRa8qi+*Bw!#w8G<(VFb#WRZZ{BTZC zRBhTFtA2GBl*&jV5>+~KRBFA2?sZt!w-~ds_?vmGSEKYf*m>&)83xd%ve_~u&ye#5#4}jOzA=LwM%N&8fKv#x z>i)!+q5v`y-wC!z-{rj366PQ7wj7R%j9M7D8nFp|?b6@Jf-H7o9%d&jD@psm^ba>P z)|suwntvC~T*59g<0ng$sFqGsLQVC;jQ7kkK4~dy+oc*SbGYSZBf`KfH^1VRn=MG5 zddtnR?C7s4t*M8yqrbw7G<$EEuK$vvZ0lGyBi`JRu)VWzLkM+4-z3lO|aB+JCbVMgz&J%3XpyaYz*2h!BmFx!ZD#vU`(x zhvn>Lsm#jLm$QXZ?R!NJmb0TwidtNBXa&g8|3gYYgtR5AF_#vx+5^K zgVkTG^Hpn+_C?uz?^@P9fFY3bxKlKDP>Nfk734Ns&LVlG0OFuRv%+rm zEx~*CBlT9Hv@gnZ=7qdu9cEXz*KtDu>n&|rz!M8tOYa{uCEQsA5$_Sa-7DCaw*_-H~ZGuVIT879t+U-~Y9IfG0?e^_~HAf>3(bUb?rC=LH?0aY!cz4Vn)- zoE#KRRA?3t1(4PQ8e7jh?4 zuX<@C%XKsHO4NpGt~7rjR6J@C{lCCUO*uZ3*1c@{ca#85R5jv08(5o{+QLJ*iIn>_ zbbHfi)0j~QUhKhQt@Y6W>%klLOfT$ClpJEtzCnp$GGDL(9PT&C{Id;gl$5%hyKlrA zU(|9Qw-IwB_vJiwBbz3D@Na%;BWve3;%!PvDZJ_@|69_O$GU#5&^7zu%#ouGeASA% zx@Jt-R9n~K|MS=Uf9QS`{58XGFZ2n-FT?Tje>APnJp3QsIRbXLcSB^Op`7r?&f2=w z+g0PYU`TT*4A}rb#-6kI*to? z-z8)3sU&jBd!~YL=kC1>k;r>lwHu-P-XZ+t%O1Z(@wXOoc0{k}P=lVfi-NgUF z@6rG6C*yw<(ElXz|JqN?f1i^-)}agwp4opV-hUOjNPxY(u4u$pEHy#fFEN&XU&lJH zbdx%*93ahK`HOVSeNyt&i2*6&=1iQxH!-OVKgFajtP}4bNelTmlJt^WmyWSq^^9hR*Kj6OPxJ6bm+M80fS8g;`nNU z$+rQb4WI`rI{XJ0>8A!m%y9_`0@$pR-q9vao4~u(lcGc3i0>aC5EiBxKW;)m(v0b; z6Vp>Q_)VNWecaT5iBl&9%$}Hjj?fgja}!W;)^bg!?=v{PWvt`1vp3 z85+$h;bHX)78*?-k@Kf{&yHGv{U0naRyh%AD1!A|(A0uOh>{}CDJ;e-zp;m0`P^X}keJ$eQ^S-3lD zwG;l8$no1wc+DLqw_?6L(^DGWc&3x3nP2mi{F}5az^{6cv6~O|V9fPo{B)M#hU};w^AjC){7)9!_{$fqOgQ z5duedfj86>S_P-44}KJJu#<;@0uOh>-xPQcfd}B5p3(SGIK!RXg9B3V9*v*R80txy zu!woV0z9$6%>ow$(qKZX1T@&m{l@|yDI?D*fe#K*YfmQCKRka6yhFH(V?UPq)Cr4f zr-0}rP)ezX6Y0DK-p~ohs+vO4a1ntTjYiW^;16C5KSR?;SloTlLi38idx(G>{lpjr z*P_zm1&iXT!WW2ec63x-&Q$ZOc~8MJ+%@4&?R&ZKP}olO;2>#%z*l#A5#K8C ze1SU>R3z{fPWVBAuOpn=pTolmVNobNI8yqnz;^_zE;B_At_eKc3IAK*#ZDQJP}Wr0 zcRYtH?Z2_G`1&~uiX%Yad!6u33a-_(bRu;(;XXJ_O{jx%u>ubexFf@_X_0?QQJ|B> zSmB|AQ$RQ`8&M+IMQYIhV4R|7o^Wp$2_37T8cmMCg9U{g36cdK5S*c=#gU@*!XnVg z!?YaEP6Qta>C65k9ER_2|U3GA20CLqWL)}F~tI?bnc&gLjL|5@rj~VRLI_?8kDz8nY!8jDH(*7m%@suJD(Ghuwi1h;32;32| zkAiD)yB!)j9tYk^xDOEh$5_P{!@C1_3covWoV};jcsm6YBRu3ek?vK2XA0aA@pysf zIN>P*U*Z%_j=+b9iTdxT6g1iqB?dcHqD=xH>Vy{w{4FQELf~&Z71>V$AN$n3Xn%hQ ziwRFHRNCDZ_*AEWXy+l7W#K|K={Uzvc|5=mPzKVSa@<XLjHk8tfbfv%G+Z7Pc#aePqrhF9TE_)}yE@@F z1s)TwauRAbQ2zf23-b#W8qFht$2#FseKiL?oJj2foG2F{nAj>&Cwvt5k|sv*hCM|Q zgcDBuU#62qe-S}|Qv|~V9_WNmP;hrmf>T22MrEZng*Q~AbW@Ei1(!5qZwmfDM(sy5 zOGN~|og!EVT&e9VRHBK|SF>3}fZ3_YlWKnX6c;^&=+R0Xc%X_G3ORx1kg!M>0f{=N zIR#v)jH6T}2+fY3O2xfaYWM+#Yt z9j{sp6d^ZK~Uh&m1p-z=*vo{>P;Rqd*ZmMd~1l5S~R@9 z)RZ-SH+lMm8SkcOCXbmmBQ0g(nDJ?ocz&ql-F@y;DE;Z%_|)lmpE_|;D#DpMaa_v8 z3HY9!Jo)X^F*9dROu;w*DpcxRKXuNSq;az+@Ef7haL<`=G7TP*QsJ0B@WxFYqzk-9 znAFb=DHxM9BW-#rPY;v&^MH=hG(8+n7?<+)m`O8|(o%RvCn?UAf}A=dWg;)_BsJr2 zhf96=txi%p-x@BBHYTN}k4a9QIBkrQ6Z%4^To)n5xK5ZoZt~>h>67`i2x%ZMjgXr2 zh%QnnKN}&1vI+ctgw&1q>nttc$2v=$>!nOho-lDXAK67(AcwPhBw=yo7rIE^(u4PS zO&6(C<3hE_G{Ri>I`7$4>g1RQQN5vOCZ7xRscgm}qcQW{fZdCQ>;*EJJ6)x2?haYZ zaTne>65o);D52bN;j{7G__6qQn2gWzl$!GIBBhq@Pm5m1??g)79Rio*qDBnnQQf5O zZjR5xs?R0eq(Ea~JvEkUgA$ph5sWSTP&X;mE#J$L4JD$6-K9WxO*0i+TDU`wA{aL=i>WB5F%o(qONb zi@*qifZ&dzvP0R^f=yY3f{G~04z`9}1;3%? z%JnMj-Pq)wpn6p4O-iInZ}GsA#{+9V57H;{z&-@MLdu~C%BA~b+1c0;D;{h7h9EW) z+4ba|Xm>IP{bOtumlT3@B(oLjie}pp=P_{%Mko_9?oh z`x(k>aq!fZ_NO`2o1nFiA!!+}*3!)&YrHT^X9F73h$n7mK<^q*iUECOK#2qerDh0B zCNK5VvfZenv60T`r==l5YyU=N(~Js5BV)LM(Oi^q?Pj#*X7plRRJUw43O)x6s@cN_ z(DJ7NJ$edF^{STR1g=fESj)oubz~R0 zRS{zB!-SzxyBdOL6H>kFfiMT9dG$ooqYvJhRxZs!3=BIL0Y(h5wwHuR>@1P+uY^|Y z$Z6%ysB0;~BH!2;lj-W&-C@Aj3C_6**AhJ8CLAU>uMRdxr8EOv5P=n6KvL{QfO0=$ z-!&iNb!?&*cy#+;e+s6NM&nH;dDFSgK%3W5omDN{2&Vq>YI9$AxZLfl?U8%fXkA@r zO{VgqsB2-_WVAHaXlYT@^$02_<_4-Zf|?LPbwkc@1ebR+8ObgxtRRBArP(vtcZox~ z-)Q#u|890{U9)fhSF@SDMW4G5o)AoOE0dCCZfi0L7>aNhz14@+H<|RYg4%;)i{Fbv z=LLCnVIUB(E^`YtZrk>pah~4R zN6aF7HYr|M!zLu9M#TbJkYs(}a+GKam0v6qa;9T!M2~HMc5(G{C|}WB#cFA3bt|EC zPmQ8xF4YS?Ks(h7rGK{asJSIh;liFP`h6wJY$azVc%*T*|-PW>w(oqmtr zfbpDM?B)2u#ne@KiF629B}xh)Sa%L2%+LnJLvc4bS@D&Mim$9TXDFsKL!J{^qnRGPY52?rhWoPc7xlp)UuI#Yrf1z{m~P0(3v4&Py< ze2gmje9u*f{$A+LPQjtwM}z-Ed%tiYqL z>Pe~9jTs0+ZAbEd5ou*IxqaWoyM0>|J=(*w-M%Xg zOvKk#7X?u>6%=)Y4fZIywfou-7#*$=lTMOjTEyKwuE`__jAQ}%C;!pp=9 zxnDX;XbeNaI+pjS&oA_-56^b0mA=FEe3ylFG%h8J-gz}FJ1fD{i{#a&qJUiVgTVAQ zZH2qo`NeTwEpr;AQnW{NEp__>U5f&WHmpD{DgbwYanUvt)-PCmnxeGzI|O7xk(EY~a?yF32o1}xtsk0BI9S9}d(l&=0GfxR`QG8b$=4^4I#|bWfAm_A4-GjB~op1vA?x1|X zse2*=ob$a?{ly_KsVJ?EcBo;OyyUW@@DCHl-cf(IQ(jW;C_GGRLw`M{XJILN6AsP2 zrNUblEnl4WRv*>Fn)UNF>onb5w4i#!VS5V5<3iOVLB|e)1WMR7dz~56u$B~7Mcc?3 zS6ju|w&bNJOku}bP)$|Yy)k&2ly_agdgh$zQERYLD>a(vO!Ys7^6JVGrEVR}bo%RaR!R*+p-_j>?3@^s=ux!uB_S(!helZ z`0?k&*OTj7c|*1tgJ^o@Vkd_)R1G(>qq zgWUb$GBvJk4AOxOzxU|rKQ=d;LaER#q~}{iV-k+{qA4w~|9lln2h8Z??4djFy1g@wSnENAx+tMdzc#^$y;~GdrNtDW#OfNh;Lh8-yoi0YdMMBZ_Uc$O zAKV#~)V~#33+$&8fRp{rkU*1uNnmI0Z0@~iC13+64qHH;@&~{uX;lQ&_jBrUfau56 zK4`yYna7FS7IsNZ+6G8oEuE0fCf!`X z+rFB2@>ki+4tI(7zRyd(3ndHH)p69c6sYq0(6H}Hl>GKf5EP1@e*SInMwWS&BAg2! z_VsC-0Imfu-dB%?D-_4;wFA(kp8-&B=a=~cJ^s~gPTs)D7(kh4T^ZLG+nGMJ33d~Q zty0!&P+yfZ3)3?kZBeqMJUR=|puUH8q9v*52%UDIn5XRxC9@TGJ?upsd5aV*8ZEsk zWk6T4Vm%TDL1FTg%P34&qWs%ngWPrwoT_;^v0fPs>R}CGym4$eaPJRa$}< zrTHSI$$mG`l!nTZr}QQ$ss{$~oUC^N5Du#L2cXwi$2LKa4iwmjqAD+8XzK*<5C=$G1EBB>#gNRmxgbJUTY7TD zcZl7^V?o5)@z^#mqRBkE1F<+B`yR1|JO))_wY3SN2qi)xOg1BwSKDhFa4`K6LV0!i zc^+6o2#QI|vK-~HrHK8)V^Hucl{{8}SdhnNSGNyg6GP!ILFAB3%jF9z+YmtOK}$Pu zQF;m@Xk3rB-hX6c^16a-;!4`O_F!k(h1F9bPuT}@fxQJ0_4^ZL=N=LSQx2iT>h+PF zy^Mmt2B=Bx0B{LYD#1{}qY$kX)C?_>{x&MC1a+9!b|fo|>?-Aw@8t;nEQCm;C6Mvd zlKMzcA?t&Xpa3>A@M(1ysxAF-7~%8*`zgErINAg@8;Oy0sCzl5eFBswT|*+b{-)p_ z{p(n)kcW}LEgW$BwoD5pk4(HpgHyu035%61$dgA!v$NgfN4m6Zv&(iqZ?7vVI|h;b zZNNmkusj36#3GWv#-+7@#6OME_o(O6_Bw3|a?v9xXbluDUtp};wl_CaeHn(v{&}8z`mqpS$5Vl8_SQMtv@6rjC(-Z2FA!mw1+9aV3HEvmV2hU z08~wS08+yrnD_uV^InUYJ=?3P+YFIU+hRt_xjsVf9pC|^F$8SM9lUPZ6Y?5ISsQ|o z7T|pGH3*t?n^78!AJ)HOcxm2$m)1hFR>lyYROZD-S-(e=?1>zH8rl$G+Ecm$r&(9< zgnKgN`Q^f`O_Ke@Uj_DAp#N91DYJhD_DwDmYaqIDUOmLms}Jj zU~Lr>@4{}hiV{}jq-yDBpyMlytz^p82CUybwmt!9d%f*lu=r$s zCE~F26xmx6Zr|^~`O^@u8a)C#&@50j%c3*TGq+8AUbD_R!*=#;-YR#1W_=4tVw2uc z)(J*5zbnkfhzcy$mXbUaMODZ1{B9uA4v;me8Nt>xDy2oczhQvVtWAu}@{|(*!Lkuh z-v=-#?L5sawl)br{D#72QhI3ucmxZ=rddXUgU9x1)_Eu}q-w-PSu%;MXx_Mld=xQF za^1+#J(3~$W`;z{Ko&}#A&zHgawCH&lHpI9DWirz5G|px<{9=NqDhBPDGyzLP^CjODW9j8r>2wCw7kF* z{V&o~&0HZ7es33`4X~Ep>;OM=rfsv`BNu%`NpLvx1;;A3?YXC_KLet`-UzEx$bIIbbiJOL{bB1k z^e0HPh{o3uRYT(=PH9nK-%5l{K$$ih8_1>lAf3z0=Ip`sV$Je35)rfXLE#WoGg0WX zz1lP+&6jkUmjF-e71!+?dKG1P1c`aqjsWZ-6ifAisNMpgz@AI(lKrsuVv?SXHnXX= zcrP8}HE94yd~2hnSYYo95DI0I?8K1+<3!@9TpES*l~6qrWntAH#;pNgTU@K&fabgO z$3AzfTyzy20vq(#xJ?+K<=u;YswVHK!xtRo^4eMpeAHki5Epy_Tc@3x+bA9H*FYIIe~{U|~Arq>7TXIDM4*0wW@)4`>FtnVQsylLC4D3hWIKy*WzxUBNB$P*`MCz%qkTswQ>CDN)_y zI}%0q4BsW3N761<55|ED8{o@!WJo)}x4+g%t&|=yI2-M``oQ0Rup>>*(rvDt96x`3s%B-Vk!L5#31IEg&)Xd4fp21r(M0C_$v( z0y5{i33@E-<)DW)%bUUKaxrr3riD>;?nWDQ8g+cN`ln2Y8 zTyz}WboLxmnfn%~+_Z!QLhcxXNZ|z}<~~gjX}o}|CE@lzm_5TTgNG|?qp-n^ znI;$Yl38&^>YyYjjbUg%>bgVZqymN z9%Yh!Kkz10-vwG#jRzGMA=dVCIPAr_@GuyRw{J7j1}CRrijW*JHs9g4PiL6mpnIW!6{}QN-VHX=M@a} z*{4wj%HRhGJGydgTHw|m_p`-xm5aVZQKaE3wzAyQ)g6%1 zXHQ0{X4&sV18^A%K(mDR;5WSnrcht`e$5(-@@?m3J&BYe$g}2@H2veF;G@x3>W#&z z!6RH^L!HS&6??_m$2%3-Rq2$;j0^lf@mpQP^_xe5?qszgTR-)ou4c`0A0aHAf$-I| z*>pSFCVO`EQ$1ayH+2BeuTxIf7~6&Xdi~U#u4eUumfqNCk?q1niQ_bDJ;Ic2we6W0 zONB<$;plFDHA^CQJ5eD^-Ya#cRFf5^vnK7WM5R&yl+l3^b1vC8AqIiCrIJ1EN`A_w zNppCD_irSaX(X5mv_B9rtd#jKk61T?8k||C3ViI3j|jz=ORplaF&D>2)ES6VThn23 zq?zq^C3`iG@Jskexis7aJp_5S-?Wdovtm?_u#Ko0pbDUVU08b-s(p=SOpN(SCh@9 zT-q0b$mY_(BB2mo!R-K1=~__L?FAQvK5~XUGnf(mbMBo5_7ADRT#qI_x0?ppEEfgQ zQs3n$+5abGT0y#g4GpXQ1#u&DE6VJp+z(d$a35b~Nv~3n>_`@<X+tYL`Hrpc@O#dH?`ztwr;x9aqGhTpulx z;k?|B!NNGa$liAsgPInmOTU@H(m&#q!refap-@%U)-zRIJ%#b}Z~}`T{O4F(s%BHJ<>0awni%I-*EbADRWPsrojI zs*;u7kCzT>*k&Zt?A=kiN4;R{mGdYsF1#!Euj)@h^3{m4{}pf*it2KssE44hReuJo zD*f|47OS)yzp9i8VXH|&9(N&LF7^6{X5kU4W8A3T>E0ZizGS}#u#zR}tH3>4SKD z6yibu%lJhCQ?Y+6Vi1k5w7w2r^5+0j^$7+pi=*-YU^lq?ca}QX+`AffGUM|@O-lY8ghZ1i_P-lDiHXbma64hgg*Ot{0j2S zKm+MD^pZA;`j}(?0ogAgboo!qMLiDlF|i%M2x*pH2ynA>6>CxUW8`UPAB;l4V1p=t zK}WYgf3=~>t)7D!Fw~m#$Q#$8UU#_E9S%U5e8%mofe~m5O32jX(mYynYm|&T&i$UK z3BwD*wVc-GcT|6YeY`#X>AGN7O< z`h+X`dTs-!mbc*AKs9g0wM@VF;)G2`;-HautH*W@iN8Ziq|g1xsr6YfQ0=oK^nPR? zEU?eK!uxv1Aq+#7G-5mT)$%L_nzbDoiW~d(6rfwWeasc=c?I>nIlr>}cZa=l(QgOC zVf45@dYp!Aksdd?+2iv6e?8v!uO46dzk19&Olf(Cz4C1I_`?5Zk2UKf+h{j_2)`c9 zlKTq<*2xHzti5pbP_i!KO1;t}FWHwV?17$dhUMq=nugFB4}_YHoaPR1@kC|fn!5~h zd=+y%7Yov@Cy{RrbQcWIPob8#&gnokbvgV5M4DUNTsP0z$8ik{d=_8?@N}K+K z(CMeebyKbL%CV2erTNOX`>xzBd-kZ(88lV3p2BarbmTPc4%47#!o;h$7gvbKk%;SO1DS-9our8<0SDhN4vL(0qv6Ba%6~Y%CVI1snj=HSWdX zh66US|AT%wZ64du+!MY$Tbv1dpC-M5bB^k?jdE%+HbuP*pADxi8b@eosBn8D-54_t z>-Rh8rbDf96du6_LnhV&G>kZ|sY~q!pAperSaz63!d9Bo-K9M-&7od&*mmSJ#LvVA zj_?kbdeEhgo95CIBb1;TPq&nSm_9_Jq_rDCGR z5w38lrKDRoe(pXo>PI&0xjwC5+=33I--AP3xikU4rt1FZ;4O6&8yn7D_K#07>$5`| zo;XXaxo@mTxWHb0wpGS@z^KiPk*C9D^JCX^gz|wH>SVp z=^N|bfPR_i{~_v#zH$A7&b~?9|8*d!Lk9tT3^bE_E&UqFJbj;WYL?H@C`vPGh#u1y zvak*2cc8qwPj^>QI45IZabDVWfO*{og1Zu2%VCk=6oSKG^3FL{j*TL0gMr0;(jW`X zA@6FBmbuVT?igb5-n+zvaK^!r+~K=|GdWDVBz3v|=+d7HJ8VC~TLVpWsb|;X3I$BL zk?SjJ`CrOsF7+f5OnlL)p6|E^QWz?CPE(KmlA!2g#~R7iAkw+@0dV)I%*lw$RR7NG zc*;HcJ4hT$+dr{Tgo^hIW(pl1-CCRbqkD8MZi~`G)fju>QlvhvAMwhrbEm5)wA7q! z#&UVpsqQtn#-meWILggQB?Z_c zoM)q+PidDFz)3FX>`umZvK=^Wt#X=@VT!9l?(lXTF-uOdCC|ruH^Qc+o6~%OD`Z8} zza_BWZQRoMF^}UWA|UIt5U)C(3Ar%*6f{Kp99%Y3k3iH>c$Dl4XvU^0T80N4L6{%0 zLW2Xw8sX%_6yl#FIC&_sgb_s(@oxY}cg1|sKcrZAGa5@)Yy5+>i*^^57XZw({hGS~ z(m&^p%+Wv44O}-=nkoFs-Wr+ILbYDsM7xo-md*p}Oqx)Smb=iSu42na-sAm@qjf`d zwJb0oLv^(j8jzv7a#jdey43-Xp&KKpp+VPDY6{&ohvcfPhoBPXFTG7JY6&$P-f;^x zB}UDhttqi;<{~9aF~eW2K*`F8R#aC>fqnQH?3!NLPr?$a(Vb|fCri46TB}*lLOFzL zbdCb-mvCHzu;_NCAto+B>QUUkH6yu*{28Da3D`8RB2z>$+K*_&DOVd)8EQh#o&Qo6 zyd`|g-#ww7$5y8k$+Js6Hm(vmqmMYFYjPX((>!agVW}^M5_o#TW+atol^QA_G>Si= zQEYWY?{r09%l)LE7PF?m8nZYwr(BwN8mHE(>$nN?Xz4A{6!@sNLQr5I0SYwWZDfu? z-@9)_H?z{aQb3BJ^}f>$F*|vOuD~>=|5~LSG=Y0#1SO)-}t}uw*J%Ub4#* zWjO`?-m#8m#;tCFGF7LcfLEXzmEr#@&2yG!s)tDJZI@~L&LMkA?+u{GnUIUncy8(O z4C?V5^!UJp%}C383~gX`Fw=JMKYBa^J)RSq1CK}Sm#(F-RLE-rFIFu6%4907ZldMS zRxis-O5plG@s+(l?UxstxP&7f{Ks5NbcJspGU6}Sis zSN2>{vaTpm`2`(!ai?MO7gn+^C{d(RRwB3Iyy;j=N4%<2IEQG`a;$94vJ}5yr9C)b z;P`)(pEfEvN7i^$ud4(crKtIp@b3#MdY{`M5ulPvJ8;KOjMl>N9R$0f@)GQ%k)y}E zd=}tO37&Is38JW#p~Si&@2~cljoleTPD78=#-_B3jt$5IZ6PqBeWvXv8f_dY=*+Rz zZ7av{g4HnmMyg!Nsf~CWO6iE%*W7B5l+tgI=?2?vjm%es?WSuz-VRMEml}t-Ci(}M z0N$ypbQF=BnrM2nMKl!ol~4?5TZJO+y>YmzQ%lPuYH1I0U<8{%HH9y$bv{3`Sf)}S zz!Noj9%6=Sx`RAP>l9oty>gNFZlY)dVbXv`*%5$Y(x9!usp@3SaH{@) z8#2ndA%i=@)c#Qq$+#&4Hx1HX21qsy0;>!#4x}YgiZzk^=>25JGHi(5IFRl z)Y=t7VJ(J8mf!x463AtF@Ng0hI)SkfyU@BXk)&&?=)vmu)8+UX+K^KXE07Wa!G%=aAgiGi^YW*5iIF))n?vzuc` zdLftWge#S+lB4_vDwY!M0VcFg{oudTX zs43LaQ9`31LTPXzFoha9N^lA?g>G|{&>62^xl@Goq$DNs&!dVXgZ-jYQp)=^NWtLc z+>P3AOf9@iy5zKS``D;)Db~w30XKHJ=)^TPe_V6#c8CCUAevK*0bgUF z>O(KLf6pi7Ghi?&4XWoMQnvv()x&Px?6Zf%g6Z{CuuN}ol2c2KE&(sgj@DZ_n- zCt8*#{Q^7N3L*3iIBrKN=eV2)kjGmOnbHoVh0`vsqk}`Z(jUm}lXhTap}iXH|L|A2 zcgbs{(_00T9iKj!a$931Tn6OAiS#{)__lumaQLo?@L-NE&1sf)pg8$!pcLQMgj*cA z%cYU1RH&|pR@@jNT9$V>9(6q8c-ZmKgG%8k1r5Lk>Vl36wPOGR=xKNHz@8Cc2eX~x zh0QEAXN5H#da#Ea!fdY5{N28poyzId{vT*})m%bo)+1cgvtK|Eit?zX==+C+ zf)HbUb6w)}P0XJ=$tnTo(Vs(MJL?L&u#qK=@0nZzb*Z|kAsSX7-UcPiBNa-sezTFi zHa=At#b%AaTg=$Vc8!l0J8Wbp$9JfI5r;LTsJD?dd%fo~-vP=FLAIM zOh9}LM5A$)!Hjbe#B?C!ahrn~e@74nK*WywHkffaf_N2(#^dG(GpZ_;fJFKnP;=8z3DHiv@$}+mR^Cv30D?8>!;=>zMnEr+bXRZl8Um@M;*# zA$Q(-`dB5j3xod@X#rY#CW3XdA*z%pYZ^yM-PW<+-gu(^L2RuUyxnWry>GVjE-|2m z2trfKrAw7Cx|BtoT3r>R^$PDS;75QWkZLyE1iUGdc>-C2QD|2-q5S2*}shu&W53 zT*ER7;>G@J*j^!(ddXBB&G zVtisDlH7|V;~qpMmv53^T*W>D`F@ZcL~aAJ2@?|OrEL}4GcmqpXOJ7qlg1b`B?H1t zrBG04msT;!+gd!jlI@<9D3-5eAp~EoWY2gL#i=V<9)fWz*}c9*@sXA6Nd&!CvPvLZ zu4JbWh%4C=AWyDfI}mJN!Dnju3O-XGtl%>>X$7CDmsYTa1=iF+s1dluy@I#l2?~7n z`w%pdCuzp)rLADU6r_p`S8(1ryPWgR56e04tXa-^XYO*&JKp7-ce0jq-Wj-@^G>Jb zoOk5qoOk|O##?k?8E?^+WxPd;m+=;{WyCuzCodCB@$#e(sCG?y5fDb_O$rL_PcLJO zC*3agUdBhK)iORhQOo$~{IQge&W@#gbe1gTqr;Z+(RqC-ADt(c^3l0>DUD8Io27!O zFU``#U{UPfHz%>-QZ%lau!Ohmz!J2LfSZH$@eic`o+wwm9C%tK$ki>NdC#7tNwU z(=9TvIG7a{&!mRPtB1mjrZ+~E(u_lz;+X`2AcD{&LU^1LnuNWa5(Nrvf0QMIQwTy9 zGYD}JLVHdi2n0B==++3K5hoA?0-VkC_y~b~>569(1VTL!nneh|aRNbJP@+Leh)}k0 z3PB*$2Z3BJs97)ope%wwXaGWDgfN{G2m+xY2rW1vC$D%W#ej?fGRZ)`P&|`jKw5xI zM*S!}=Yisxh!VCDuq}Wo+*QwSNzX37!a)yK<#nj zu!%_t1^`Cjf(;VQ0%j^h$h`pXq-L+T&ux&lEh*GAlA%bV`OCw0hG`Y5mBP|kcD(p5 zv2-i5s_)cW3Z5(XFJqspgN3E+AN9ot<`Zw`bZ~6q-y3eGulDe*UuE?f6kwF;>CMx~ z{s*DbxwEcA6g-QK6oO$K1$tb8BJ9ECfmzAghdnfwEq$k1Lpw;>$8b*X{3YA_j!itj zh*`9D;%dh6pT&Q!(DBk$!WL+E z3bE{aZAgoP-tf8;YEbIQFQ9;^!zzd9Nk8C*b@LbOo+&BfH(#*Fr}Pv@f5F(4=aMH} zhmAhJxS9O+D~P$XzJrz(`kWeWx%N40qTdmp2E0cfD0zBI8$sah{rYqEfNm3C`<&@| zyB=c%BQwUXiqfFo^Wf%C~M89 z?E2Jx-i@EaY9aRvnnjv4BwGoD+g6hugl>I251%S zzem=nf%t{odIs}vNG152LF|MEjhv=vFp$EB5=Mx$4KPk<50|KMLeMFgv0s|HY7Z|} z9}=Pg$0SgXw3#G+=tEP8Abe_$&wTS2%0=sG`_LuROcr{#Ijc9#){_g#{N}j7%t>}^ zrlzeYhJ*dLvic8{1cK}z$l2@~hRy#84T3c56Eq#rA^&=Vqny5QIQGFn0nX>_^w#w8%@(KEX}*m==9=$r zXufAYV$m~NiNAluI?k|(AAH0{%or>bvlTNs)=&6|8e-}A5j!!XTf@@}BMtd&A-kRR z78fjJPqX&o_=T*PwTf@M1_MThWpXxl;zWqUbL%y1BWwLcEl5r^CprUWO(%_{Q_YK3 z0C;E^F$yIPeeg+0^@ni+RXwp8%34YVms6DJiFF2@u{2P9Z^8x)$?wG&1NXanS`rq!hOR;mvT^#f;31WfR|?`7%*3AJ zCoz!U%3%xUv~d{U9&=ex{S&g>ID>&K`|Dv^-C0|)nr42;hvoAR*{GR!H5>zo&(BjI zvX5ul#MU3O-)FWHYvwa)R!XODh(+94KW(BOt)>1(K5pIw*TsJ=d^^jW)uRE4u}~Y5 zKy2!)zAY-d)-C-Ug6X>QsdyLK(+09KUr)(kDY%1@#NKW(Ib40U&9YDA34^J z$wV@Ij*okVVwN@gj`}Yk1sG$(TsCWVT0=XfhtNyzJeTdA-Ag?80c$j;ZI5jqkPz|Z z7ntQK8=&KqOCPS_OJfyvQsK97xC#$rx(G3JV7b2udtpvHnYPbzKkb#M1gFq>bDZME zJa%-B(rnzFG#*z_*Zw(pdO%M)s6-{Nn!_9)v=isgVK06#{PuJZsP)&36^#`e7gGO^5%`$OjGEQ_WX48s@DaC1S+H5v*Zfh}rHdE(jd1FDy{ylP< zn{Axtwv&v5lP|ta#i(G+Egy8Cu{IatZY_LRvn+leqQ*KOzoX0Uke-3SC9C^6!>)cw zDLo6Tdu?0Y+*hc@=foY$d}USYZeQu=^fX5e!aX(RQv6Diw_d3!g{ssTfohTQTQ0>A zN`Ir9YOhCFN#e99`b`(`TQ1dNsNoB74S{O8Lci&k>DPXdeyx9V{000f>s(IvLqi@& z>4IA+ng>h=X%H!JOwf9?P4MC)TlBGDgO!Nr>I2w<{TIPZpXLds&Fw)}WM{3SkAozv zZ7;ul>`n}b?@9;R{|I7mR^Nhv#w*dbMb;OcBb9LKWUdloBbVQv1&pz-7D6clS1qGJ z@1ZIJw)(OzW^AraAe(O-QRSi$$PziG<|A?TvCWC#cvwSTn8m(WdAE4iEOuyR`?T9Y z3w??UQ`{~8`Ynyh&-ld__M;K(p}=YTOP*4J?8MvmtZG?*$xPmgz)UuLRmWHz(9QB+ zpUKO=cP5oD#?NGzSG9TIJU%YM?RGtPRykV#7i}+koS(138++b&9GhN+<&3+ecGAI|c};t7EPo>AJZ_m%<)RPKj!gZD+daLLzel$0W6;$n9`tB!*8n0f{%2fir$g3% zsoU=GcerTE>4q!0Oxuaz#s$LK2!0gsp>nujW9CQmmAme({v(8sa}id0~=;w==A$x#k!LH1Ke`d2>w&xLuEeudaw-64OPwYJGB~I1t+FZ$D6Ki zPPMkG=Xv6_=NG!eTXARj4sy6{TV;JcQj>RryY#q39_r&}vX|$j)=x#r*v!*susQR( z#nw#6930v-inFV9Y&ttIub;SJI%_o_8|ieW%)ecHU^jbtexf*FA1j{US&ZJzR?lCM zTrU-+2(=i2G1E|=T7iKKl7%`-a!zC8KJ3`9Bk-VWudL{FhJSI93>t2;8_PuWfK;5 z7aLDy-z;p`s#-_RFV+!lE&bG8Lqe%CRqfotE-dskn}{?HU+G-9c8x|<5&ptH@`lbH z{>c4EJ0QmIyy2)-1}==EG@3mQfqxqw@xg7I6o#uKoP`|n`(>__?GElwzr{lQ;Hq@^ z0v$860=U4e!BnAd+o!OulAq4B>r`*<-N??M(r3@>Co{SA0GSB2gE5^=dh}tL@reE zvc{hK$>-i-yFN)4_q@YSf6`X`>KzvMY06W@@6cFX{V6ZO zqrV>IwjIot9YNP&!vdK6l0p5EQ_XeM;}NRIp#H$AQXRD_LhbSnoAzmv82b+U_S1yB zFRHwr%DgzY?KfV>-;s2`8I;|5af`DPfyM0g&)W!PZ0_eB#mjHA z^3PKf_P&kTS$Jb+*8@ZaJKtvF7wL_4K)1~5__tZb$329%+4Yax+bQ4w#k<$GQZrqZ zzCb&u5UMNS)?bgs+V~AyC`vy)nH~9}SNxZNvJY)G`fFi;z>xu#wy2LdWHNhoQTr#_ z0T=po9i>SxQo>L5PtXHS2bBHI0|@XIcu7054>#WO`b z$&MnP>f_0h7dH`S`dHfHMDaBr%Us-A z9PDFb7k3of_}JXVNuuOqYZs@q2*9M{r>ic-uuo;G*Xgsk{H39`?C-_hpDR%`ZaKm= znB!m4ZXMll@xzBgrxN}SRb+Uc4e)uWAjc3aGPp037>vr9f;oZvc3c2UFEB{&lZbJ1 zO=53+eYf~eAzSwK9gTk}q`4spFbBS*_Oe2D>g#0jlS0<;n^ZBskfnW-+Tu~9fg*4{ zuc^mYo88C}j3Qn~>b`|+>^BKXsRsROUR);5yI6|-qaz6#6tYjh=_Bsk#EyP*uea$L zQX`U9p&Pj42thp08HSRx`YeObzR@49M>u6C#F^!x0-9j!^9bNy0vSj0Ufht_lkNl~vVzGJnScvMMVav@XL#f>mURHKP4{I-*L#LK?_wpH^0Ozoj> z|6@1Nl9zdzw4{|->}Bni3=lKC?3E=+t!}5ZOL2T&8nR;fH3SIBn}h(X*WzVgE_uMa zY$7D|Zbwigi#E_-0uF8VMrzDfJmoI!&p3)RCe5NE%Zh#26bxsxtW60#7c``A4 z^_dVx36n^bN%x~1Ea>NWkp3V7hd$^Ic(UNNv!!@XAsN1J#~d z)e|4dXOAsQda9>U$nLxZ6jHCQkfcZp><37THZSHu`n)`rxcn|LD~}CY?i7>r*!1OX+?U_N2!D^*|Y8v*kR5x6L@S*PHAsoKCj~+3=kpFCm%4Kh{>&ufw_7-cgqN6zKEewOz zWfVyi%Jqv~256QOoCsCzlpTt|(KP#e94u}c!qy~#Eq*!w2?4Z+Gc*_9PZ zo>^}iBOyNOsL|<{-e51RNf!feun*V7i;Lc1tJn1Ek^P3D&OU_@MT|ip zPnvlL1PH0KQz&Anv;8Rnsk4vY!BR_7UpypZnf(v7_1Xlig#V$o9tR$3Ykq-gVhWsO zSG^0PHyKb}win=`wi1d7baA|Zky(&?Dkx1Ih1+GU(&~}Wx7Wpq%bsM-*7Z%i)UeJf zGz`UMj^6WtTi6c6&^;5_tLr+5$rIR|bx*We`#QRP*il%^kJSqtn`jI}JDi&I?lhbt zb!qlA7Qa5V*K>e8wo)KQAtviBVG6>yRw|=^8SBf7N;2jC0GfyL2wQw_#hG%pX#Gd^ zmiE5Ra@MDb%{H(v*0<_^@f%zw^fzmRVjym5+pAF2Vel|}D;ftUr~V=|Ve7i_TzKt3 z;8d%8hig4q`#q}RK&Cz%VD&e26W>C~y6UVdnHYj3cE<3oPjkq|MMQ!ZbDBw`d zv#O85KnAN)33F_0miSaI=EL>_)^|CcjsSD?CWL19ZEsY~pj9A3~_}N*tNV~5d%vUb3UvsN3!x6jI&KNu%R%vE?qk@1uTf2!Gr9vMDw;|J4KHCs9VjX!K(~~=LapPbOGTYe#usgn zIb5ppD-vx`H0+(Kp32cNzS3IbrB7{8tS_VVn5uUMA;{nSL}@77GQudXC-8uV8&HM; zWf+h`kiIIGJ-M}KY)9ZS)l#_X?u79x>J|3M*7mV~j-lo5tBuM#fI@y8!+za5<^BOc zhKc}7h+uWxMuF;&rqW6erzo4L1^Wr2cW;HDQW{Qit2=QbPC@@3BSIGV&vNl)TDi&f z#;`TtImNXvv+LjGioITDIpsa#&7irllJI3@_JRJY`CUxkxzTJ>xx-m37vB%z2Iqvu zqlsmm1klT1y(yweeqb@h_L&rFmWdSTkA&%S^`d%6;?eZSSpQ(#M_S{&J7>z|t8xJo*!`4(#C8ff{<$rAu^N{R+Z4gDkhsyY2Tj{tDoF4fg4)%bUdaj~vIS<2e zwgWy&A>-bFVo#GWY@i~1Q1M}3``lkbHu6d?8bGf<;OX0HZx_Tk>M2+|ILe6#d`sn` zQU_tm#Of~*!FNIUYJm!c1SofQgW(XuIqN*U8jmV48`2466ZS!{&#!plv?>{k$En>p z%a3bd|LNS;|Cu17ihGTd?$XbZF)P`Q)Sj&LUOcehLxC<$@kEMO)PwLq#fza;rOU}c zcU{PB#f!Z`sMGKH>G>(6%zuh_nHPCr|BC{ho2Pkey^4A$Qs@|?P%*bvq#qH&zY2{u z3SDLt`mIsuVji?z#LJd?4#EUesrVl6ibp+C6=xJ2m79Dk+9=i=IqEO_4BMkL2qkEi zO#JFef>7ZLl&jJUfbbvye(%KS;)8L-VDWsCg1RRY`5UEF_9A zSnz5|nVx+G-|f%CL3kCvB`f~{FVW)p;_{3!Df==~b{Q8X#=}ZK&>Ut}U;)IxK&)(S zPl4WNFaF<5(jT9|koP?Iy(F9GKEvKwgnYPzyc71$(<5oQI7)gDO0(_*=vKFd8ct(f zS!%Ys4hh1_|I$j$3hi z_5kc1a8>Ljz|4j%fzE_oVQ#~tMJL*NAFaU#D_q4PYvc2zRn@@0KCIF$9P&ij88Bp6 zWuH(sHd~#&& z#Gm}-mc0(N6ho024 za0~hu4t=Ou3JU3y`fJed-b4(xt>Yx!&6}Xknbtv=nyOY$0@qkaP`a{282xT!cpNcr zBuA`~qv{<>obIGF<)UWke#_TXME`Dt4)@tbb#6mBg!IQ0LSx(OY}F7lVvOm zil4Q?2)-A!Kw!+_v08F9!86Dn7Jq4 zD}-E$rgNf4^FPD9KW2zyvRLVlZJP}MIrQm8-d?yI4@5ps)MwAI>p$KT{{WgxZVARS z!9#{Tl!A+w4eY+3I>!xOtwd1~wg7U7)?2O`- z5~Us)ERyIYgpQc921*v5wRRQDtNlxvurI+g4R(Z;PDgsO0W;yi?wyVh% zfFpw;Pgzeyd5Ps0knlY7Itn!VdIWrY>fs*fO(cP)jcEJd=M}m1TV$>3qS3OYb7|ThSdNh7;!xLxI5+H+;%F-CT`|rjMnJ^pcmWARa#z@k(!< zlp?$ZB%!ssS%poe5Pjw z^|1nj>necqijU^GL~TBjjryfc<1axaYc3e_7uarQ3}^Fxaf+Vd?C3A4V!Poi`qx1Z zQorN{fd>3x1lfNFFW+$7>g`%67c~b0-YyGimZ!#Ws%1WzjWp}G6!0?@uUv>!p2$A` zwQa)}L4;vTOMYw^+xP2zV$3jJ>&d5>a^OCR_m91IpiR4v$I|+pIf0t7+8NuB{1W<7 zHM-?(B59n&em>B4G#_y-vpAG84cY}BU4IzQf%e0r>t$rm#AiQv$6YQuLd>RuRQKrm zIv`AP|1#yp{pCc{rHPQ_{M&8I@h544KVJd;mR?>D7%#7{ev*y-t&=$CNjCqt9^#Wv zvLAlSXyJa9T4P+83#FPnLETkYLw_4(TsPL~_g1278XNL^qR^SW^n1ss9BCSx^Lz56 z9%|HJ?Q9#CT30xC7_dK zF_Bm0F|@pM)o=hp$KK!2N=Rt=)oJPmF8wUAPf#}=rf%$U3m0%cKlwNtda$$oahe1= z!!+S9;zMPg#Pzq!4Rb2`VRNYG59FM|$LX0u`Gk|6-s#gQ!|!%F)#QB7CLg@3L+GOd z`|FrX6JGkkuWuu*cK|g|jKF}`AETP>wU4pbLw81VK&t;Za~&Ee10c)h-if~=-6xN+ zxre$5kFi~cn&J24p+3Ej^+5@}r4~ph`}Pq)AEN=Fk zIepl$!~KOv*++-tTYwPSigmTI3MT66D18ra1hwVLlZ_6EjqCEN-%94hp z7^FqUAnnB<)q9lPb)<{%2pfK6g8dOR7iUMqgfXdvALc6fS3TC=C;~fE_4Qs9xwWbe zMpZV}^l0CfT6JAj=O6yhs)7%*SC4iP9%dgNEx>Q9V|PYBgf406R~}*y9qZ}^ko^ZP zJC`708TWfI<2XM)`|KYA(P-SxU`AC0p#ve0TMsAr2qF)N*l}OM2|j`t4MgK{bKnFY zK|BFOlX1mxf{!5FKs1#nWny?(AHbSC zW}}Iaa_*+-ahA%fd-BgK;Amu8OVHmUe}=LnFCpJ3BKW(fiQJy56jNfcK`eTfkQZmiGXW_K5c;3aC^l zikbAM34+k{t~AM+hMW1$u)yRanbB8=>%~)xkkIJpHEv)sR5e%qv*JOGo7PdH zwed78xBhvEAE72HCBT}_pbrrCO6k=UY_{_Wm9eIO+BUe9bxY%4IN&du-1x#0YC2do zFW#8Q08OOTc!ugGv&!E7H8+{HAqL!F*4NM~gIUQ@Xb>QpUU~@SmJ0sIEO){z--*;W zIQkDq=^x-|1ZV$?qiJ5f=)?cT(r)$lOyTzlCos2rq0ZcNcKR~H)J+okWN zKsS%)&f;8y_pI%TK8KQSog&iKgmZY9xTo>(7ye4hbY$f6*^7w9d#iwc1(<&c=wU$o zOF(;o_?Lk04aC0$^c_I_OF%aV;$H%qsw;&2$Y#I?Y^oA4vD=3LMFT**jJ^uK~GNj1;pFoQM zqcH4#N?|Ptznm=|oxOX!iFGuUj{8V_`?HMXB{uEHGTG|m-No)RSm<~=@#;IQ=?SN} zsw;c^M4y(;4o8l>>G?3iWR5=B$pgbb{+bQ`(#?Y&w&FypX!o#RPNa*qgIMfISIZ@2 z`_QBS1*0oFk(9t+bi!iC!X4CxWuL_T=pZ)dZ?Z;y+zc>CVDVHH$dOi(-k>j4GNsHCJQ ztBdX$tCU)nni^u7ClpXBbx}as)-80^(Mq$jGApGlHA@8#pq8hygQwCCKf%rO`NY28 zYwp7sVm#j6@Zvv*Ldb2HW5F^q?_3A4!Tw3bKL znhLP`xwOV+=k4;gimQ`TUy;;w;AwAQ2-gr8!;c7Ta#|~*m8mA$!BGNDPVI%3SV=`+ zh*X|w=QLmF+_d{C6kN#Y-x`SCIJpcVi=kAMIncTELX7mYJW-<-{B}Zw$Q_HV5#N%ROc91quMWl|K`jscFu7{D(|H`SGywmY=~hR^DFKNOzPI6xUH(GgUbT+wYQ9d#{Cthr;eBQ>ns34UNw07h5Y2`#YOl8rghhf7CKYO3Z$7a_?P(Pz82b+x6f)@yphoCLo-IVlvk)n7?Dpmnn*r`BH7;6ZUr1kV_>a|)dX!E)|*Ij9+ zY#ZY|dZk%R0g1tkw0O(cfJnUv3Zo3hcAAfte~+tR&>H*=&XB7en(j=**yZ48QW_i0 z_yojX3DBW=iIBQeLH}PzMI&p$>IiaKbY%#Z&9)Mq~*Wu4!+CUBwK~S zb`uH&m-^C24088%MqV3OcO%|1{>HAv>b}ky*V=WSfp-heyIP=@^c&6`ERBAw4%X=5 z&jBZ0=p1ATSzA;Gg`jcl&sS@CJ-o6pr=y-3UyO#m=3;!ijWwN-pv(L>Y z9ZAmNY5)ykjJ->U%pUYU9Fo7_4mva`6frbiwCx>doq0DCLW&JB#e*FF3oroVIw!Ee zlMR{k=bLSmz~0V>H=kEN?B#s!R!o~$he7rZagl3OQJ0Fvls89cpW(2VhFTEP8%$T8 z8RlGn>y^Rscn>}?_|t^B2FJUYeSm%kc^GZ~!L?kXZ4I4Alafuv!ZTq^IJI{u2VYQm zQyhFr7u`Aic8BqF)T=a~G|>^_BjN{gKciZ7XXX-`u*)Z&QiAC#_YyrG7Cwq#$Mp_6 zuVcsrRB$D&uk3NUC!Frvt=sRQ-UIV0cOWIlIb2A{q4n&ppE(|O2y_qvmw-CsJQ!Y4 zymRoKj!oy|-Qsu-?eZtlE?=jT!Fy7?bNQXNEXTRyPP@i`HKVmkW>-vccdKiad$o0W z!==V0&9lGm;cM9i>_17*KoybBky(U;?Fem|noK@eq} z-AVZa6ZuL6*^%N*x!+q!f86=T{Wb$lz+4|C+eWV!r2rQo#^Bk_x$D^>Lf6ogH_rqQ zq_}*%%NxGtynjE^uWnQ341Zt>?{UC0h^@v<-E8|F9sHy^hGoV%7d(hjo{MvS{@^L4 zvis79EjvNT1vE8|`O zYr!*VZi;#mQdF}eiNvzFdGc!#p2C-;4dhFl9wS7mU`ca}V69Iq1*BNd5&G-X5OvhU z!emOYzv&ywJ*_P1pb?HzTD37l(FQHWwt6r!w676$NV_`5l3*k0C`7wLa;?i7?N6b| z^x{`ygHR}4=Rg$)c}S<~&%2IzlY4zGB*ANn@kE7#C1QOErt!M`?Ami; z+7L;t?q_eSOSZ438mzk8(3$9N7Q70i(4a1*=6;j?8G(tYwQ4RGX-8S1U2? zCE17Ff{Uh}0xyAxZTPn3Ls|Ql_4gqR=9u<`Of0bJARF4_?PLt=7WPZBU)+G$Cqce-FzxzVWE8o5ql>LTLSdq zh1Xk*^;dLe{s&`^H>O<rlV_jw0ScVQpCxK1^Zyh%jtoB{N8jwezr?r7;AV zgV3Fp?87?qr3#Bt;yd#l3LB{$@5Gz>v8F7A$N8}qe!0PnKj+5`QP;o|%xfQ1 z{jDEM6Z~1@di5-R_%N7>XaAY+?7o~nlhQz-S$%)CKP^q%VO+dV8f3rLA z`C8V{A7i+YuhFt54HDo%8?tHx3vJVZ@7J^g@dMm*lha|V~mtq_ixWXsKug{nD+coEjC5j+>ZCE z&7#^qFw^u`l+M;2_9UkS_?rZiReNV<0D5QKz(G8(He1zmT@%W>b~)A+xpz}_Z_)%; zsMmZhN*THi9{6-~;b6d>0EZ@xVH5a>0Jb9hAZDlb(Ea!i&u_3dh*j60!U??|&FcoT zaOH0kZx_hkZ`sR4hP;9rP>7`cHf=o$Ozc9s`Gkyyh5!;G{t#S|$+3uxoFN zXX+4+8NWLW_f)>B%D#RFg_)I^p=x77H<+5VUJhcf=p)c~SY1NXN`9># ziwpd`wMczuYu+V@^{V>{UNio{~CqwAh($^CTf z`Sx$Nq;d@>9Z6is9I^n1M8^~42oJr7C8FDok8j7v$012xphGY1-jaW*V`G%>TkwX# ztbL8kd6qrCJOA zLs&hC9DC^AV8-~lU>2Hu0%>A08Vsp5O;8X!^|ajG_v9pnm?6y-pd^5m{02SMNYJ-% zaHLfV*-J?K9+mD zxy9eXwkEogxa~nS47Kf*e>sakXuw+ejZ+wJ`55aT*%+En>dI|yBz?-^^eMqBNq#dl zlJUI9ShQbHJZyT54e|Ruf^pW64e)D&;tp!aIz{?JT}YKpzZ^l~J%b%>KO};hH)K(M z(RkR^kUekMgSCqHFzZ@z3f*-OtvGb`dxG-gpvzC@EsVm}Uage*129QE%~kiQv7Y5rF{ zyD@9o^lQAZVoaM1F(rnak}k#q#}?tgm45~QR%F3d`WG8=is7IC4Ir!_x5LqQD$W0n z-)+oZXP0lWWSp>eqzY1ge=2!6o&7(Wa4K=C6=zBT4yA&+HCMd4+D`BkJ@EdqZ z)NT2d{fPV}Mhk_H#DcGH3YuH^uh|}inl$Wu9W2Eo(<#Ucr6sR!OI|3=pRxJ_&#jkN zob?~u(b7C^5g*%xMQC9_WqA?LZNi2`Z1|KI3FdX7!5G;rw)@0KNNve4{Cs1^uQXxp z{SM$EqA7c>MOtHgz;j~fIO}~Ot#KWp$zl7TRQQx774o;6vN`NF4{OGv6Yhwd-o^hX zChvX;hDde0u9TGPN-ot&)RZ~~pt|qD4@E2$wHUoy)WLlb>H(kIj5W1B#EWjrZq>g8 z-=M%zDg52|PpA8@pl3_&n=>b9Ef|@ZW!;1nF%wq051MYDB!x#++@;&{mG(A*CFb4A z)I&Kf8oO|Xi3OSQFi_GRb6d>rE8Wm|tObd$LShO3b_w9gg{4NO!&G^0q1e(yyNA$c zVHc!pD}j{`kmUzZb9W3cbYYXJnp}pbG-ur-?yQF=yN$W%3!zlOcTvG|DjFBc`1{RS zj9(Kx9B$5rMtmDW6)YFrAFI9du*s2BD252$H=K2;Ta4sMtOx$WUk%4p<)2%8RXB@_ z*a)3t65iT_LJ*C`cCU($xEi9bg|p6n2k;OPfxhrE99vOOQ5N+)U31MPU2!wOZUbn7G$C3<}NW7BrTm#mgJ05Z>KZqk|Ehj zDm3Y6y)Y+KtuZZ)c&Wo-c=#G_2vJ;m&j;aaBT+xwFnbgV4%&#vs@2a`bl{r}7{3;Y z`ZpW$y)u39LY2*J4X7Y7fU`l@g51m@D;XNi{ zNRWyTSsw~r3D@`N9)qE?s1cPAhB%Bi96Uumj2cVX4hqsRzP$xoG$d(hvcs|j^`PE- zad&*da8U=S3t0y=!Nvi>h8a&nw2n$}r%FlQU7zuQRv0TP@X)Ch8{h8L`Y6F^k3?pq@E1@4IW;IVx#0*%^x0A9V>m5rE_tAbkWZ`)JbSUV zp_7B@n_ivpm~;2~Zo{_J(I?Th`Hf4DVvMZxLC7CAc`imA!q>K5vXcI^!gmI zx_A7TSk*%X)T`|91GIdaN8)VvrNNHY*zk|aCSu7(GLQ0^(HKl!MZ7GU>AUB*rO|x> z{$q5vs?Hp8>_NZWfgp$Uf5{}~6`=vFKZfbkSl%p#Mb+6GKsBiSIRIITVI3Q+#yd9f zzeB4>6IldUY~T;U18v~@wZTJ042x9!2k<)WScKv_&)cdLK+ z*-ksws_s<4RM?BI_WVBxX+~)`cobeYOfHLy8s~7*R zJ?qpH8F?Stx=_=toB07WZ#(Fd@-NCW^?wP?+olu*UG$+F^^*0T%ER~bfDWv)GNGKu z!)5HDkR z$Dk$)vq<|$0br}YssMls=UR#HZYIZQ>o@=|Y-99?Q+*fzLX~#FoRLtaFl{pq8Qw2B zsbhaEFKNwU+LmnY|D=A{5Iuk}6)+4R+~1@p;g=qO_n-kxcVWrck@dpL@oYyH$%0pO zVx6oMiz;=`97wxZG;2vp9`FQaPha6tkM+)$A@yR5bMESOc?(gM1(rgBg0_K`YJg^D z7Fd=LQeRv+OUR1_mZgN~gdJN#QVJ|iLV~yX%TRp^EX#mchcwuxl~9KQ%W@)mOqjW) zU`-1wD+p;Q4BiqFP+;N0>Mh`BLvrrvGrQSJN{vBCUrEymiKufVw z^&_|u(FQ_`7+|5T#J0cGs4djQS}`qwNfn{Hi{V#THFKE267II0{WOjhM`zJp3-Q8| zfhndW_D7P%VLYKR^;TvirZ4SG^UJ8xFoWp{>1X#~A?dHAGaHHxYrEy-2{~e^F~AKe z?q1kt6P2t^P5n8@Vry_eHdP5(NUsp?lC1D zEqfQkI|(|9Sj(M-s2{g!_Aj$cDi-o0M-UXU<%;Gqqg7S4y{J;GT4r>CU=Z$_E-Zyy zsDbFMe~-U)H1@#y7P|Z>eBi&wVhYkiff#uvv&Dts0lin-!cSA+-xWLXif%FWt}^XC z#7{rmaduvh+vj%UN|t}4iuQ$=QC*J@02r7>UQkTcylE7J&11XTls`=y`;4H6m2E3|h(eun&?2YkZ-Rfz5YPv&Lwu z&Tw(e=7GK}@5^+Yd?y1Scz;OmnN{zV^qyVy?xy!So_GJQ^qM1Ip%9{lLP#E7v(`DD zg4WlMChMdhKi#mQ9UY}BxdanN_gb)PwvectK6-ygIw)?LCf#}olVDu4ByAkEVwJY; zQF$PkfA7a6~$RslQbul$YLsXisw?Yy#!YHvGLPx;2CuvU$2*KQ^^UF6g* z>ntQKdjFAz7e?~7uS&Rc|$)Z?yp4XGj2wwz2w3%JO7=H04o~n1(y*K$|@er1O za+4>-vvj5N&8?f_+2f31Tz-PJ3W%l5X%GFy8}wrT>5vaTE$qZ-UDs$%Amn}~+(UsW zE%s@aldRs%X!5!F8gJE`#VUo@_%pr14Mtw$xxLwHex)1pw+dU=uyk#^FBB~Iq6Oqu zHrM4p28L})%`NPUV@-K}g?&)V$&Ss-;8v;j8FJ=5&|4g{SmsUar|ldM8lekN?uWff zLejj*Rji%~$?zh72*j#d=TUzip?LJ(P%|Ym#EXmt zLPzX&4)sEV9|_i5A|1Un?H-{ClSoxOwIpKjhPok3Uq$mLAyy<`74=a`^t3nFPKk8! zBA-b_??v8{$dg{AKq8|3iTao&k(pka@d82no92a{ek53;M5cIYIsvI_DQ?k1s1Bbc z3ZeE;PllP~Mecz|5sgSm(3DFg3oKR!`$a<8USzLCME!_hUrOXjFU?wsRCSp*Btm-v zYKG=Wq^dW*ED=2o#VXMV2@UrK8z2$07wPT|<_XnOBI2uxECx%YD*4Jlwe+Iu1lYRn$u*LS?O3qouyQ3@nWHd*a|_w-ZByof5}R z5a14Kt0N@LG=KLJ;%n8UNxCg{3I@4VYWD$5_T0tsCDsZxvWk3!#d*wl-J(A+1m;7p zQ2RD25`vxMCuJ}GnC^`; zwW_mL-Iir_-$bSgmenQRYjPj33rdpf#9y_Zt@r}u?gKUvB`!u4rK}hxvZKp0z^xcn zn;25xDZ2cp#nZfpX)t@LK30y?<@csXYtB6POkI8~p2hUr^o?Hruto287b3X;Q^F$j z=B&$At)A}s6Y=yNugkxMj8Nmo$JD5twE-0t$RsaFOjN} zwUtO!$wDPkRWLt^R2A&1tg~p*|3r@dkWf|04oRe{WZyo5d?Jyml5vT|Ak!7yFDdx$j1dOp&q#0dBg zJ?gd$#>L2bUH%7E+WWmUH*O<1dV5h70;BJ&XnCn6svAa?c6)#U~&*Ixp&ZH z-;(5L$Zx8TmFc?tJUkZZ zK9ERN@=GK#(VM)dvPFv$1)J)Ds>Y9zGT2maFtbENs~5p~NJQ_YiFyQ~+ktA9l|2&A zWk2GVsOs^ah$BqHWOB9}`gQdQiX zM-b~Y2~`afG==|oZGf5ulI zjBdCdqT@`{<*yKRGw&gow;hjEej_C(`Y=_Ow?+iAOd=UxngtROO+wIE(6july>BL*XEwT>8-^=Cy90%06;!?55o zD@MP9ylyncxy53mVvUR)-F-cBKnw+wXGm;C=}eR<@pVZwMdcmmMLv>$SMUc?wk=N!wS5h`*gnv6goB^JnJ%CA7M zdQ|7%RYd;)qKHJ36+}NtMD%Nclt`p1)Fz2M0auOMQ(by5V#kwM6Jb3RKA}+Z%Bfb$ zEHN?SySQ%;3!#6i3R-g^WGWM12*et?M(G8^n9+N%_t!$V^D6SJw!$bis`_BNc?Yuo zQ6s2|(6!kkKEeE{PF91mt&3p)h4J(kS#;p(b3(R#@f?2-7a!@~!fVFa`~&k&L+>sB z9KZV_8>sX?$NQy1)uQ3Kt&>yPT2`+CTDOUP4?DfH|KN?&SVyJHAACR>Yo~<#!Dpti zF3QQ@`MNZ=O<7;eUzotm;aM|i;ru=HhfbZL6?iEY%-7BA7WC-8Jj3@+Kl1kNw~xzjv+BI~5YpXQc{%&HWf;)f@) zK7kYIsE0k_l~X))5{rBM3A~~(xc6{X8Pq}k5Y|xRngcb{4V-*$lKz1q=K;%tfjcLy zSWuwKlRRe@w|DkQjF5Nllikl(wU+qXWF*QNA_I>U zp7(@jEstlI^z3tzC%%lBTAbvg;WqOZ#J9=Z;Y|@sYf0!j!JRL&jzNwA*K+Uln>`g% z+>*(>V*;BUI0D@auS=$E{XBs&|G+js)7R7X_?d4tu>Qdpj;pefizFLKIDVYh=?5jd z#mD*6{ZPTF$G5)LkIhyhUPnhXGrBb43Uum8DFt8Spn9CM^cW9Lg1q9BV;sj%W+|)Xl9)#t3@VB;JfZ9?>B%QikO-TVr=@^Lw`Er zo4_YWc*lW|^W-1l;|8)<6y*p%J&s|;dssXOBkhvMaj@wcs0i# z)bTw={i&S$^vMQ_tFPd9;Sfz)+;hIhWvLlOWwogqUF+d-03N8FlZSYSnLQi)3SM!H zJpbanllai7hxlt|NTtFL@e(s@qul&~SD2Zl?M7m!3-_W+fl~Lzw|GF?iF+3?Y-;6@ zV-K4D10Owz4OiOzz`q)VttagdTTcvPp-T80qp501+2FeK z4Wb!)`P8RTW668@QgYkw)VM^@NiUzK0(h%BCypcJqG2 zpuwB78+oaXL~!}(3gjfaDNfyIhg#yxGlEUMLdWgq`NL4u$9MChVayit0oXUb+Gpg@ z1+acWwi0d`j*szD3AYZ1kUq489~;ghyWS{9#M^Ne==cCz$b453_IEoCa@6aDwIEva zVfdm!{Ys8*6EtwNUlsF~&#;!t+G0N78D>_77xN|0U_-EbG5_)z);g>fNKJOFjvPn5 z9UAcC&DoiA^OUhEbjhtvr|;^3yH8Mjwd|w?JVAHZs3P zW#sOAhz$YMi52Y!ojEQ7C}{R$tzKz@jwkN#HEer`fQIe&@gMq|o-r5Zpe*qf7HI9j zLu}deFesJF3{q(QSg0O*N=(=LvfJj|JFw3QW(G9|FxV5><;lH*?rx?MTOhnA z=Jprf%#P&NWDg@V-D0~*8^ZMq)%&CODap9neGqQJhD~8h{2ATS68(uB>s^)=jH}f* zJ?I%-i_WU8MI89jP~0ce!|^9nGEi;DfwoPO=rs_zJ~7jppjzqa!en`#2uEFRz zZZ!w<+GEgvZ@|z3Aq~9IzYoJ)Lw_6wqev>Efx(cQ)s%aoT(=mb8qWTOc0jzkT<{{8 zhr{s^QjbBUgp#EB?Bg_vrRe!pO z2UPAXe-{oT;C^~Re^ppI)0dKcv#i?kd^zlV!CW48M%yyVH`+h;bj^-gbzqU?>u40s z)pCN)DmUV=b5;)l2Er~_85zS60WX6HO1=AYOU~xr9Ruct+Ub8Jc~S{RCz`hKB-Dg@ zE9Dn>s=f_#902JhR9TV0S?_}|h65`S_hChX*bzIOU2cW$$2XuQb1;9qp7{nli5g=} z#pDw`jke1$H(-pp%>IDA0Y`IN(xi+3P=*|%&S>WUrExP&$++1LI804`L*SKn*UpB7VC*vsxGOsT+oDZD{_Uk75k zUA`uju&)BDDJm7LM}Z1Ave%>%Mpr;JK&84nCnP!EouNxcGQ#`{ygH~}FqUeGze5JQ z`;iS6bjpOsRG-_hN``I&bKbh#NIbx>H4(^*RQHDQ7NfB@c=%-&8S?QaQEl7c2+PW_ z$+3yE$t+Sg2N3MRvt7@lQe1WUk;yEU!EXv{T?bxdyg9V-CjRDRjA>^!@{-A{kFt6r zA2%6VHrX2`!R(E^^Aya5p4!MQQ!vT|ZRAU)V75{IIo~n`qsw*||9cA42Nr%#+0efC zIS-o3nksWY=P^^^J@9k>>{J}&IPn?ZHx*;)=FhlmDs;{le#Z6Fu*vu2XME^13|1AN z@~@}Cf6u4<)HICmZ+*(^O-K0gpYkWBv*(n+Px5;T{rM4>Bw}*2L5_FGJE+Gz6oyEgP&l&dk=QhE%6sJ>X#YBov@() zQs55=cM&e<#~t7Lg!|8cM*oZFdG8r)Rq(F$G+=i;DxA=g_57b1Ot0|uy!K2CytCHx z=$V*{3|-HkoQd(f^LjpgCJPG=QbR?kp>*pxp9zJh^B=3BN|C5)zM35)rn)MpwUjjDSaFE?qIS0{K(Jz6AmE!jaut3Cr*qnRm;hfeM zEFB_|pJvF;`TY-NGN&!2Ov}`aVTRzPxR(+QWG-&SEJ8%&{d5-y8egd zz++~2unu`;9kr%vdO9iVFqx^we5(&PYc00Z*ybnZ8x@a$>Sz;dv{jUx!w^$ZQUQZD z>ga;8#Eo>>A;bKA$Uu#O{V&yK9K~!QgP9rO|=nC!Hv3>H{)F zoO(1V{;Y0s1$nTuhWKKgg9aD7wmoR9*ppjblH|xI1xF+NJO}B-qSqeO1vv#bG{8~M zP~+eT%!AM!M8%I91j3}R1e3l-y1Y4vPE7i)s*}F=sRl7uE60Nwrr&M%TytY&Hs?Ng7k`ka8;V5uQbpE=4;IKmZ&CE z!xw_kweC?vO4H8bq@`|)pO~jWe-Snz_I=VE`NZXs&=IRsO$SW0wLjvVZypM@B1nHI z&O>)bPI0KFeAL29rCONU&T5G=R%>Tx-cx5bxU#Colm=}K*F=?44aFS*4YjdbWC-km zq2zCvO@i~Uv-8E~ExuHDQ|e}ZjONt43r=%qUWCPI3%fz)k)o!(x1u3yR6n=IHS4^4 z7K;jOhG_BqI=shU%wloD7uO<{zl1&yEn?U5kAeEFU8`}vc|S_YUdwCEVl85Z|4wJy z_Xg0p_1w!h)LV*rA}9oFW;kR$9YgNpYkA5n3>QIb`HWdKlD^CDy#ndhPw(>0vmk7G z|6P8X@VW1DHk&nzocOLr<9HH=I}gDAM((9+rc@}0#`Ob=ybOJp_nHmjh#I>;o-@Mi#zgyAMhaNu{$z&J9-$Xj^JPT4 zZ#Dl0v<-_^;}hC&%~0G5JR$CnSM&1}Y4&P0ze886`RxO5-#Lymi!hm&i3n?C`!cUy$Yz3(E~rU`=25)xT1kb+Nb z9pQOFctY^0dP>2k_TpQ73B~l=TYTedtYz)b-lCYU@N=_RV}9v1R$E#07Qg)(k{A$zgn z*zXS@i@k;2hidu?M#o@nlFjrP+*)w=!>tYXZ@2+Twg4=V{IP&ZH^pDeI*z4UW&+j& z5a-+);_&B#=CS5oz2@3%A@O9y0@ql?S7u$a2mJ=-za2~py6PiGXV#im2TBJAZJ{NL z_^NrVSN&0Qu{9Lvhp*^JcwsL8a~?aQxVG@kRtSUkZrOU$%J#D7D!-})8SEaATzLi3 zk9QAMVs)QTunc3=Po>&Z@P&5i=XrR=uT1-~d@8?nxYAv2I1Xw@Lig8@Mh(tV@$4af zdp?Vc8@L?VgQ!5ET!gds@WS)-Mx59H!QN;0!A4n!i~aZ7moLbS$_%XsQSu(Cf3`QnA>C{Z)Fez}mfVal>M z`N>7>`Ov;^A}~}XLvTSPo~R;rPUq$V%$_Hw^C<;vkaBAY-&VlpDV^Tf+SA6qXUe3- zTeWtkRg@JDUeAFU^n%sAg9CdR-%i>(%E2xuk6n9Tp^VeVEt!NbcWWmfQOIH&UBJu$ z!in=}7Z~H?U&kmO-s^S#ZXs*l%x$Ae)ZT*wYuCjFb`#cdH>SJ9~814 z`dCC#mUNsXisI9ZMQpKd(v(4ZK_hK^=o0MWbhdHp66S93A2bS(Wi~O{aHC03WC4G3 zDeGwX7s*gPBO=7(Ms-)9!OH4}kObMg3V;rLFDtf(U&M3neFY+lfRe0@rP}N~{%|Q| zu6;k?L!7L)aw3;IoUD16-y%ih#__7SdkYmP4;k%A-{B zWgmD;5e@5&^QiXW&`K8ilyWj_vg5Q{+!m0iD&_I@GaCrS@ly1}qghuf)*+Ay79-HS zaHMFUzsZ)g7H$CC_4a}FY)L=Z2L{9JhJ7HeY^k+?i02lS4Gf_#tjo9d^A|NpADq_h ziJJ0WwNbvQ$C++H8~EiUJo8>H`cN*a(^PHL403{6l4B1&pF>VuIXMuMITAX(R|j*V z{g5AeF6f}~2wu5mV{t(NL}=To%m8C*1u%av};8IdRWmX-dJ@efM18tcfJb)l8 zd#6gPPRv%8CCC3sA(H}bCIvjSX1!;$cYk-Ft@{TqE=823+O)M`C*^3tc*_{BRICqDsY;2759AlRhYwg(c|st90bUQwlp_e2f+A!@)9zZc~|sfrD{mHU$8@8b?T$HUt%lw*`DNkI;ZellF}Q;Us43s|9a&V!p9T&Q zl#BmpckAYn6ZbWoP-Sje~fhRuc?D&(E$kis*iPOl*qzL zbFQ^mHcO27qFEYLRdidqSP^&|VSii5N(d0~8R%1>A?}R*(Xb0)sOM%!TjGza-vU$r zm6+P?NyL{i2HY|RRH{^2TBCi=B7BiKD<7C4@^_bIe}+JbR`CTX6xy)(f`))w)P~=* zhb(fvUeyLlwLh;$)58&<4O3AOWZB|FJYYo$84q&d(4K@uNo{+OI-)(QjjlLMZFC*L zBW0tTf$U??Ig(XXbBl47Nx>4Z&>EmemT9vG?`bDZLVZ?D!ZJv zr~Wd>pP2PKt`h8wfU|yvRQWBjONkBf(M9rho$Tmd+OQmrX09H_eCSr4y5gG|1G*3k zt}AcUc|KEdqw#2uELUJO$^>cK=xs^yC+1B{vK=(q4j5xjm>o}J6XdsBB`h<k{pMr~i{IW)s zY2)!kTpovDlsU;bCQ^xwiaDr>$w$+PPdS3xix`f%bQ8F1IcwGT60|MK3}G~X!Q{b2 zY73)P#Rbm}fze(YBY!D$Ws;z3(1Td`P*d)|l%0}g+_C~9v)sx2wH0i%(tQ~}xdO*w z?>c!XhoZqjCpU67RT=5zn>lN1ZTT`~r368P+By|YnK9rqq)Q2>j~up9T~&?cg}#n4+>{!(h#XAv90~8OB94EB`dGMkm*~G?`mtzs;}EIj z`F-$c*hLkK{V&1stez4Q)2B;`&AD#D^8RCXAI@$A`4llOvj4pjQeJE)P%m>C1FmP) z>1Q9c>p_3pD3#~$0;z7r9`EpQmckhV&VWB=ebCR|d>76Ie&AZ=&9FUm;Y8GuH7*Yh zCYB#&Qy;{AR1-BPBrrV2Qi{*or#9&V026!J1vnSclQVg~Y z26G==Uu7_@yBT&+fpK$8O$G!0yTO!e-Hj6O!{0-27%ZSAhxw6;ehxgPj5cOg?!m~9 z@)R2a?id1o6Es;`gMH2tlz+~K2PWJO0sgWPL5Ru|52JA@;xSzE&$=-d5YjJg! z2nNGzbs!Ftu;C?YFh{{*@PIAj9n^x*B2Ny3W4k79Oxy2jhrFIOrPTV?PZCS0{kQj3q#~30qYEHH&Ei7GtqhTG;QB#aQC63KkQIfHhc5jR`#4 zv$+NPu9h_{yVAXBPNh3;Zl(JR{5@G%>8|&`{JZ<+|1OM&KB2JE>b{M@@BA⋘?tGxBY#x7ufvQ)`gvsLY^D2YT!FUl|Hq&8ze$7x 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 W&PMZlAgPlQqmm4)!#}yiBK{9J_U8Ej diff --git a/SYSTEM/system/deshab64/shell.elf b/SYSTEM/system/deshab64/shell.elf index e0d0856b4a77cc372b11870ca44655da97905e89..596fc603f50de51333bdb1b9b7c2cef631795f93 100644 GIT binary patch literal 791904 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 W8+5)>3codcnLm8T{d(>{{Qn1|giPQ7 literal 871648 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 diff --git a/SYSTEM/system/user/use/login.elf b/SYSTEM/system/user/use/login.elf index b95c3dcfa95c00d1b00cd7c4270464aacb1d3beb..dfbc081f0dd6f5d06d2d54f505ab407008bcb505 100644 GIT binary patch delta 10739 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 JBd>2C^MCeL?==7b delta 7455 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