From 6b2b24ccdf00496e9d794b27fd95402a1e323df7 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Wed, 14 Oct 2026 18:41:45 +0800 Subject: [PATCH] =?UTF-8?q?fix(vkernel/elf):=20.so=20=E7=AC=A6=E5=8F=B7?= =?UTF-8?q?=E2=80=9C=E5=B7=B2=E5=AE=9A=E4=B9=89=E2=80=9D=E5=88=A4=E6=8D=AE?= =?UTF-8?q?=E6=94=B9=E7=94=A8=20st=5Fshndx=EF=BC=8C=E4=BF=AE=20log=5Finfo?= =?UTF-8?q?=20=E6=81=92=20not=20found?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 根因:get_so_symbol 与两处重定位回退都以 `st_value != 0` 当“已定义”,但导出函数在自身段内偏移可以为 0(实测 slog.so:log_info 的 st_value=0x0、st_shndx=.text)→ 该符号被整条跳过 → 恒报 “[so] symbol not found”,内核自动启动里的 log_info 冒烟调用因此失败 - 改为只看 `st_shndx != SHN_UNDEF(0)`;同样修 R_X86_64_* 与 JMPREL/PLT 两处重定位回退(否则段内偏移 0 的内部符号不会被重定位) --- VKernel/Kernel/execrunner/elf.vp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/VKernel/Kernel/execrunner/elf.vp b/VKernel/Kernel/execrunner/elf.vp index fe0d0f2..231d7ab 100644 --- a/VKernel/Kernel/execrunner/elf.vp +++ b/VKernel/Kernel/execrunner/elf.vp @@ -710,7 +710,9 @@ def load_so(path: const str) -> rawptr: if resolved is not None: val2: uint64 = uint64(resolved) + uint64(rela.r_addend) string.memcpy(target_addr, &val2, 8) - elif sym.st_value != 0: + elif sym.st_shndx != 0: + # 本 .so 内定义的符号:按 st_value 定位。用 st_shndx 判定义(st_value 可为 0, + # 见 get_so_symbol 的说明)—— 否则指向段内偏移 0 的符号不会被重定位。 val3: uint64 = sym.st_value + so_load_addr + uint64(rela.r_addend) string.memcpy(target_addr, &val3, 8) @@ -728,7 +730,8 @@ def load_so(path: const str) -> rawptr: if resolved2 is not None: val4: uint64 = uint64(resolved2) + uint64(rela2.r_addend) string.memcpy(target2, &val4, 8) - elif sym2.st_value != 0: + elif sym2.st_shndx != 0: + # 同上:本 .so 内定义的符号按 st_value 定位(st_value 可以为 0) val5: uint64 = sym2.st_value + so_load_addr + uint64(rela2.r_addend) string.memcpy(target2, &val5, 8) else: @@ -768,7 +771,10 @@ def get_so_symbol(so_base: rawptr, name: const str, so_path: const str) -> rawpt return None for symi in range(_so_sym_count): sb2: Elf64_Sym* = Elf64_Sym*(uint64(_so_symtab) + uint64(symi) * _so_syment) - if sb2.st_value != 0 and sb2.st_shndx != 0: + # 判“已定义”只能看 st_shndx(SHN_UNDEF=0 才是未定义)。**不能**把 st_value==0 当未定义: + # 导出函数在自己的段内偏移可以为 0(实测 slog.so 的 log_info:st_value=0x0、st_shndx=.text), + # 用 st_value!=0 过滤会把它整条跳过 → 恒报 “[so] symbol not found”。 + if sb2.st_shndx != 0: sym_name_off2: uint32 = sb2.st_name cmp_off2: uint32 = sym_name_off2 match2: int = 0