fix(vkernel/elf): .so 符号“已定义”判据改用 st_shndx,修 log_info 恒 not found

- 根因: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 的内部符号不会被重定位)
This commit is contained in:
TermiNexus committed 2026-10-14 18:41:45 +08:00
1 parent 09b72614d9
commit 6b2b24ccdf
1 file changed
+9 -3
+9 -3
View File
@@ -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