chore(ViperOS): 落库内核侧进行中的改动(26 文件,+1573/-1805)
内容由用户产出,本次仅代为提交、未做任何语义修改;含 static 修饰符前置迁移等(新增 static 前缀 16 行)。提交消息为中性描述——如需更精确的说明请 amend。
This commit is contained in:
1 parent
1c3fcd6e1e
commit
dcb7c5c2c0
26 files changed
+1558
-1790
No files matched your search
+194
-197
@@ -7,53 +7,51 @@ import paging.paging as paging
|
||||
import sched.process as proc
|
||||
import sched.sched as sched
|
||||
import intr.gdt as gdt
|
||||
import t, c
|
||||
import viperlib
|
||||
import string
|
||||
import asm
|
||||
|
||||
|
||||
# Do NOT import KERN_STACK_SIZE/USER_STACK_SIZE from process - CDefine cross-module import is broken
|
||||
# Redefine them here to ensure correct values
|
||||
KERN_STACK_SIZE: t.CDefine = 8192
|
||||
USER_STACK_SIZE: t.CDefine = 65536
|
||||
import viperlib
|
||||
import string
|
||||
import asm
|
||||
import t, c
|
||||
define KERN_STACK_SIZE = 8192
|
||||
define USER_STACK_SIZE = 65536
|
||||
|
||||
ELFMAG0: t.CDefine = 0x7F
|
||||
ELFMAG1: t.CDefine = 0x45
|
||||
ELFMAG2: t.CDefine = 0x4C
|
||||
ELFMAG3: t.CDefine = 0x46
|
||||
ELFCLASS64: t.CDefine = 2
|
||||
ELFDATA2LSB: t.CDefine = 1
|
||||
ET_EXEC: t.CDefine = 2
|
||||
ET_DYN: t.CDefine = 3
|
||||
EM_X86_64: t.CDefine = 62
|
||||
PT_LOAD: t.CDefine = 1
|
||||
PT_DYNAMIC: t.CDefine = 2
|
||||
PF_X: t.CDefine = 1
|
||||
PF_W: t.CDefine = 2
|
||||
PF_R: t.CDefine = 4
|
||||
DT_NULL: t.CDefine = 0
|
||||
DT_HASH: t.CDefine = 4
|
||||
DT_STRTAB: t.CDefine = 5
|
||||
DT_SYMTAB: t.CDefine = 6
|
||||
DT_STRSZ: t.CDefine = 10
|
||||
DT_SYMENT: t.CDefine = 11
|
||||
DT_RELA: t.CDefine = 7
|
||||
DT_RELASZ: t.CDefine = 8
|
||||
DT_RELAENT: t.CDefine = 9
|
||||
DT_PLTRELSZ: t.CDefine = 2
|
||||
DT_JMPREL: t.CDefine = 23
|
||||
R_X86_64_64: t.CDefine = 1
|
||||
R_X86_64_GLOB_DAT: t.CDefine = 6
|
||||
R_X86_64_JUMP_SLOT: t.CDefine = 7
|
||||
R_X86_64_RELATIVE: t.CDefine = 8
|
||||
STB_GLOBAL: t.CDefine = 1
|
||||
STB_WEAK: t.CDefine = 2
|
||||
define ELFMAG0 = 0x7F
|
||||
define ELFMAG1 = 0x45
|
||||
define ELFMAG2 = 0x4C
|
||||
define ELFMAG3 = 0x46
|
||||
define ELFCLASS64 = 2
|
||||
define ELFDATA2LSB = 1
|
||||
define ET_EXEC = 2
|
||||
define ET_DYN = 3
|
||||
define EM_X86_64 = 62
|
||||
define PT_LOAD = 1
|
||||
define PT_DYNAMIC = 2
|
||||
define PF_X = 1
|
||||
define PF_W = 2
|
||||
define PF_R = 4
|
||||
define DT_NULL = 0
|
||||
define DT_HASH = 4
|
||||
define DT_STRTAB = 5
|
||||
define DT_SYMTAB = 6
|
||||
define DT_STRSZ = 10
|
||||
define DT_SYMENT = 11
|
||||
define DT_RELA = 7
|
||||
define DT_RELASZ = 8
|
||||
define DT_RELAENT = 9
|
||||
define DT_PLTRELSZ = 2
|
||||
define DT_JMPREL = 23
|
||||
define R_X86_64_64 = 1
|
||||
define R_X86_64_GLOB_DAT = 6
|
||||
define R_X86_64_JUMP_SLOT = 7
|
||||
define R_X86_64_RELATIVE = 8
|
||||
define STB_GLOBAL = 1
|
||||
define STB_WEAK = 2
|
||||
|
||||
@c.Attribute(t.attr.packed)
|
||||
@__attribute__(packed)
|
||||
class Elf64_Ehdr:
|
||||
e_ident: t.CArray[uint8, 16]
|
||||
e_ident: [16]uint8
|
||||
e_type: uint16
|
||||
e_machine: uint16
|
||||
e_version: uint32
|
||||
@@ -68,7 +66,7 @@ class Elf64_Ehdr:
|
||||
e_shnum: uint16
|
||||
e_shstrndx: uint16
|
||||
|
||||
@c.Attribute(t.attr.packed)
|
||||
@__attribute__(packed)
|
||||
class Elf64_Phdr:
|
||||
p_type: uint32
|
||||
p_flags: uint32
|
||||
@@ -79,9 +77,9 @@ class Elf64_Phdr:
|
||||
p_memsz: uint64
|
||||
p_align: uint64
|
||||
|
||||
MAX_PHDRS: t.CDefine = 16
|
||||
define MAX_PHDRS = 16
|
||||
|
||||
@c.Attribute(t.attr.packed)
|
||||
@__attribute__(packed)
|
||||
class Elf64_Shdr:
|
||||
sh_name: uint32
|
||||
sh_type: uint32
|
||||
@@ -94,7 +92,7 @@ class Elf64_Shdr:
|
||||
sh_addralign: uint64
|
||||
sh_entsize: uint64
|
||||
|
||||
@c.Attribute(t.attr.packed)
|
||||
@__attribute__(packed)
|
||||
class Elf64_Sym:
|
||||
st_name: uint32
|
||||
st_info: uint8
|
||||
@@ -103,64 +101,64 @@ class Elf64_Sym:
|
||||
st_value: uint64
|
||||
st_size: uint64
|
||||
|
||||
@c.Attribute(t.attr.packed)
|
||||
@__attribute__(packed)
|
||||
class Elf64_Rela:
|
||||
r_offset: uint64
|
||||
r_info: uint64
|
||||
r_addend: int64
|
||||
|
||||
@c.Attribute(t.attr.packed)
|
||||
@__attribute__(packed)
|
||||
class Elf64_Dyn:
|
||||
d_tag: int64
|
||||
d_val: uint64
|
||||
|
||||
MAX_SHDRS: t.CDefine = 64
|
||||
MAX_DYNS: t.CDefine = 64
|
||||
MAX_RELAS: t.CDefine = 256
|
||||
define MAX_SHDRS = 64
|
||||
define MAX_DYNS = 64
|
||||
define MAX_RELAS = 256
|
||||
|
||||
def load_elf(path: t.CConst | str, do_map: int = 1) -> t.CPtr:
|
||||
fp: fat32_types.fileobj | t.CPtr = fat32.open(path, fat32_types.FA_READ)
|
||||
def load_elf(path: const str, do_map: int = 1) -> rawptr:
|
||||
fp: fat32_types.fileobj* = fat32.open(path, fat32_types.FA_READ)
|
||||
if fp is None:
|
||||
err: uint32 = fat32.last_error()
|
||||
eb: t.CArray[t.CChar, 64]
|
||||
viperlib.snprintf(c.Addr(eb), 64, "[elf] failed to open file err=%d\n", err)
|
||||
eb: [64]char
|
||||
viperlib.snprintf(&eb, 64, "[elf] failed to open file err=%d\n", err)
|
||||
serial.puts(eb)
|
||||
return None
|
||||
|
||||
ehdr_buf: t.CArray[uint8, 64]
|
||||
string.memset(c.Addr(ehdr_buf), 0, 64)
|
||||
read_len: uint32 = fat32.read(fp, c.Addr(ehdr_buf), 64)
|
||||
ehdr_buf: [64]uint8
|
||||
string.memset(&ehdr_buf, 0, 64)
|
||||
read_len: uint32 = fat32.read(fp, &ehdr_buf, 64)
|
||||
# [DIAG] read_len 实际值 + call 后 RAX 快照:区分"call 返回错"(rl=0 rax=0)
|
||||
# vs "store 后 RAX 被覆盖"(rl=0 rax=64)
|
||||
_rax_v2: uint64 = 0
|
||||
# 读 RAX 未声明输入:至少须声明 CLOBBER_RAX,让编译器知道本块不保留
|
||||
# RAX(此前只声明 ~{memory},编译器可假设 RAX 存活 → 读到的值不保证是
|
||||
# 紧邻 call 的返回值)。N16。(本块为 [DIAG] 探针,问题定位后建议删除。)
|
||||
c.Asm(f"""mov {c.AsmOut(_rax_v2, t.ASM_DESCR.OUTPUT_REG)}, rax""",
|
||||
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX])
|
||||
_dbrl: t.CArray[t.CChar, 96]
|
||||
viperlib.snprintf(c.Addr(_dbrl), 96, "[elf] rl=%lu rax=0x%lx\n", read_len, _rax_v2)
|
||||
serial.puts(c.Addr(_dbrl))
|
||||
__asm__(f"""mov {asmout(_rax_v2, ASM_DESCR.OUTPUT_REG)}, rax""",
|
||||
op=[ASM_DESCR.CLOBBER_MEMORY, ASM_DESCR.CLOBBER_RAX])
|
||||
_dbrl: [96]char
|
||||
viperlib.snprintf(&_dbrl, 96, "[elf] rl=%lu rax=0x%lx\n", read_len, _rax_v2)
|
||||
serial.puts(&_dbrl)
|
||||
if read_len < 64:
|
||||
serial.puts("[elf] failed to read ehdr\n")
|
||||
fat32.close(fp)
|
||||
return None
|
||||
|
||||
ehdr: Elf64_Ehdr | t.CPtr = c.Addr(ehdr_buf)
|
||||
ehdr: Elf64_Ehdr* = &ehdr_buf
|
||||
|
||||
if ehdr.e_ident[0] != ELFMAG0 or ehdr.e_ident[1] != ELFMAG1 or ehdr.e_ident[2] != ELFMAG2 or ehdr.e_ident[3] != ELFMAG3:
|
||||
serial.puts("[elf] bad magic\n")
|
||||
# [DIAG] 一次性定位 bad magic:dump ehdr_buf 前 16 字节 + read_len,
|
||||
# 区分全 0(read 未写)/ 目录数据(sector 错)/ 垃圾(seek 或缓冲错)。
|
||||
_dbg_mg: t.CArray[t.CChar, 120]
|
||||
viperlib.snprintf(c.Addr(_dbg_mg), 120,
|
||||
_dbg_mg: [120]char
|
||||
viperlib.snprintf(&_dbg_mg, 120,
|
||||
"[elf] mg=%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x rl=%lu fp=%lu/%lu/%lu/%lu\n",
|
||||
ehdr_buf[0], ehdr_buf[1], ehdr_buf[2], ehdr_buf[3],
|
||||
ehdr_buf[4], ehdr_buf[5], ehdr_buf[6], ehdr_buf[7],
|
||||
ehdr_buf[8], ehdr_buf[9], ehdr_buf[10], ehdr_buf[11],
|
||||
ehdr_buf[12], ehdr_buf[13], ehdr_buf[14], ehdr_buf[15],
|
||||
read_len, fp.first_cluster, fp.current_cluster, fp.file_pos, fp.file_size)
|
||||
serial.puts(c.Addr(_dbg_mg))
|
||||
serial.puts(&_dbg_mg)
|
||||
fat32.close(fp)
|
||||
return None
|
||||
|
||||
@@ -182,15 +180,15 @@ def load_elf(path: t.CConst | str, do_map: int = 1) -> t.CPtr:
|
||||
if ehdr.e_machine != EM_X86_64:
|
||||
serial.puts("[elf] not x86_64\n")
|
||||
# [DIAG] e_machine 错:dump ehdr 前 24 字节(read_len=64 正确但内容错)
|
||||
_dbg_em: t.CArray[t.CChar, 128]
|
||||
viperlib.snprintf(c.Addr(_dbg_em), 128,
|
||||
_dbg_em: [128]char
|
||||
viperlib.snprintf(&_dbg_em, 128,
|
||||
"[elf] ehdr=%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x rl=%lu\n",
|
||||
ehdr_buf[0], ehdr_buf[1], ehdr_buf[2], ehdr_buf[3],
|
||||
ehdr_buf[4], ehdr_buf[5], ehdr_buf[6], ehdr_buf[7],
|
||||
ehdr_buf[8], ehdr_buf[9], ehdr_buf[10], ehdr_buf[11],
|
||||
ehdr_buf[12], ehdr_buf[13], ehdr_buf[14], ehdr_buf[15],
|
||||
ehdr_buf[16], ehdr_buf[17], ehdr_buf[18], ehdr_buf[19], read_len)
|
||||
serial.puts(c.Addr(_dbg_em))
|
||||
serial.puts(&_dbg_em)
|
||||
fat32.close(fp)
|
||||
return None
|
||||
|
||||
@@ -204,17 +202,17 @@ def load_elf(path: t.CConst | str, do_map: int = 1) -> t.CPtr:
|
||||
fat32.close(fp)
|
||||
return None
|
||||
|
||||
cr: t.CArray[t.CChar, 80]
|
||||
viperlib.snprintf(c.Addr(cr), 80, "[elf] entry=0x%lx phoff=%lu phentsize=%u phnum=%u\n", entry_point, phoff, phentsize, phnum)
|
||||
cr: [80]char
|
||||
viperlib.snprintf(&cr, 80, "[elf] entry=0x%lx phoff=%lu phentsize=%u phnum=%u\n", entry_point, phoff, phentsize, phnum)
|
||||
serial.puts(cr)
|
||||
|
||||
phdr_bufs: t.CArray[Elf64_Phdr, MAX_PHDRS]
|
||||
string.memset(c.Addr(phdr_bufs), 0, MAX_PHDRS * 56)
|
||||
phdr_bufs: [MAX_PHDRS]Elf64_Phdr
|
||||
string.memset(&phdr_bufs, 0, MAX_PHDRS * 56)
|
||||
|
||||
for pi in range(phnum):
|
||||
phdr_off: uint64 = phoff + uint64(pi) * uint64(phentsize)
|
||||
fat32.seek(fp, uint32(phdr_off))
|
||||
fat32.read(fp, c.Addr(phdr_bufs[pi]), 56)
|
||||
fat32.read(fp, &phdr_bufs[pi], 56)
|
||||
|
||||
found_load: int = 0
|
||||
lowest_vaddr: uint64 = 0
|
||||
@@ -240,13 +238,13 @@ def load_elf(path: t.CConst | str, do_map: int = 1) -> t.CPtr:
|
||||
total_memsz: uint64 = highest_vaddr_end - lowest_vaddr
|
||||
total_pages: uint64 = (total_memsz + 0xFFF) // 0x1000
|
||||
|
||||
cr2: t.CArray[t.CChar, 80]
|
||||
viperlib.snprintf(c.Addr(cr2), 80, "[elf] vaddr 0x%lx-0x%lx pages=%lu\n", lowest_vaddr, highest_vaddr_end, total_pages)
|
||||
cr2: [80]char
|
||||
viperlib.snprintf(&cr2, 80, "[elf] vaddr 0x%lx-0x%lx pages=%lu\n", lowest_vaddr, highest_vaddr_end, total_pages)
|
||||
serial.puts(cr2)
|
||||
|
||||
raw_alloc: t.CPtr = mm.malloc(total_pages * 0x1000 + 0x1000)
|
||||
_db_ra: t.CArray[t.CChar, 80]
|
||||
viperlib.snprintf(c.Addr(_db_ra), 80, "[elf] malloc ret raw_alloc=0x%lx\n", uint64(raw_alloc))
|
||||
raw_alloc: rawptr = mm.malloc(total_pages * 0x1000 + 0x1000)
|
||||
_db_ra: [80]char
|
||||
viperlib.snprintf(&_db_ra, 80, "[elf] malloc ret raw_alloc=0x%lx\n", uint64(raw_alloc))
|
||||
serial.puts(_db_ra)
|
||||
if not raw_alloc:
|
||||
serial.puts("[elf] malloc failed\n")
|
||||
@@ -254,7 +252,7 @@ def load_elf(path: t.CConst | str, do_map: int = 1) -> t.CPtr:
|
||||
return None
|
||||
|
||||
phys_base_aligned: uint64 = (uint64(raw_alloc) + uint64(0xFFF)) & ~uint64(0xFFF)
|
||||
phys_base: t.CPtr = t.CPtr(phys_base_aligned)
|
||||
phys_base: rawptr = rawptr(phys_base_aligned)
|
||||
|
||||
string.memset(phys_base, 0, total_pages * 0x1000)
|
||||
|
||||
@@ -265,14 +263,14 @@ def load_elf(path: t.CConst | str, do_map: int = 1) -> t.CPtr:
|
||||
filesz: uint64 = phdr_bufs[pi].p_filesz
|
||||
memsz: uint64 = phdr_bufs[pi].p_memsz
|
||||
dest_off: uint64 = vaddr - lowest_vaddr
|
||||
dest: t.CPtr = t.CPtr(uint64(phys_base) + dest_off)
|
||||
dest: rawptr = rawptr(uint64(phys_base) + dest_off)
|
||||
|
||||
if filesz > 0:
|
||||
fat32.seek(fp, uint32(file_off))
|
||||
fat32.read(fp, dest, uint32(filesz))
|
||||
|
||||
if memsz > filesz:
|
||||
bss_start: t.CPtr = t.CPtr(uint64(dest) + filesz)
|
||||
bss_start: rawptr = rawptr(uint64(dest) + filesz)
|
||||
bss_len: uint64 = memsz - filesz
|
||||
string.memset(bss_start, 0, bss_len)
|
||||
|
||||
@@ -296,32 +294,32 @@ def load_elf(path: t.CConst | str, do_map: int = 1) -> t.CPtr:
|
||||
page_flags: uint64 = paging.PTE_PRESENT | paging.PTE_WRITABLE | paging.PTE_USER
|
||||
paging.MapPage(virt_addr, phys_addr, page_flags)
|
||||
|
||||
entry_addr: t.CPtr = t.CPtr(entry_point)
|
||||
entry_addr: rawptr = rawptr(entry_point)
|
||||
|
||||
return entry_addr
|
||||
|
||||
def run_elf(path: t.CConst | str) -> int:
|
||||
entry: t.CPtr = load_elf(path)
|
||||
def run_elf(path: const str) -> int:
|
||||
entry: rawptr = load_elf(path)
|
||||
if entry is None:
|
||||
serial.puts("[elf] load failed\n")
|
||||
return -1
|
||||
serial.puts("[elf] jumping to entry...\n")
|
||||
# 被调方是任意 ELF 入口(外部代码):`call` 破坏全部 caller-saved 寄存器,
|
||||
# 除 rax/rcx/rdx/r8~r11 外必须声明 rsi/rdi(N20)。
|
||||
c.Asm(f"""call {c.AsmInp(entry, t.ASM_DESCR.REG_ANY)}""",
|
||||
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
|
||||
t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX,
|
||||
t.ASM_DESCR.CLOBBER_RSI, t.ASM_DESCR.CLOBBER_RDI,
|
||||
t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9,
|
||||
t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11])
|
||||
__asm__(f"""call {asminp(entry, ASM_DESCR.REG_ANY)}""",
|
||||
op=[ASM_DESCR.CLOBBER_MEMORY, ASM_DESCR.CLOBBER_RAX,
|
||||
ASM_DESCR.CLOBBER_RCX, ASM_DESCR.CLOBBER_RDX,
|
||||
ASM_DESCR.CLOBBER_RSI, ASM_DESCR.CLOBBER_RDI,
|
||||
ASM_DESCR.CLOBBER_R8, ASM_DESCR.CLOBBER_R9,
|
||||
ASM_DESCR.CLOBBER_R10, ASM_DESCR.CLOBBER_R11])
|
||||
serial.puts("[elf] returned from entry\n")
|
||||
return 0
|
||||
|
||||
MAX_SPAWNED: t.CDefine = 8
|
||||
_elf_entries: t.CArray[t.CPtr, MAX_SPAWNED]
|
||||
define MAX_SPAWNED = 8
|
||||
_elf_entries: [MAX_SPAWNED]rawptr
|
||||
|
||||
# User stack virtual address: top of 48-bit user space, 64KB below
|
||||
USER_STACK_VTOP: t.CDefine = 0x7FFFFFE00000
|
||||
define USER_STACK_VTOP = 0x7FFFFFE00000
|
||||
|
||||
# Globals for ELF mapping info (set by load_elf when do_map=0, used by spawn_elf
|
||||
# to map ELF pages in the cloned PML4 instead of kernel PML4).
|
||||
@@ -332,26 +330,26 @@ USER_STACK_VTOP: t.CDefine = 0x7FFFFFE00000
|
||||
# in the cloned PML4 after clone_for_process.
|
||||
_last_elf_phys_page_start: uint64 = 0
|
||||
_last_elf_virt_page_start: uint64 = 0
|
||||
_last_elf_num_map_pages: uint64 = 0
|
||||
_last_elf_num_map_pages: uint64 = 0
|
||||
|
||||
def _elf_entry_wrapper(arg: t.CPtr) -> int:
|
||||
def _elf_entry_wrapper(arg: rawptr) -> int:
|
||||
pid: int = int(uint64(arg))
|
||||
_db1: t.CArray[t.CChar, 64]
|
||||
viperlib.snprintf(c.Addr(_db1), 64, "[elf] wrapper pid=%d\n", pid)
|
||||
_db1: [64]char
|
||||
viperlib.snprintf(&_db1, 64, "[elf] wrapper pid=%d\n", pid)
|
||||
serial.puts(_db1)
|
||||
# Disable interrupts around switch_pid + MapPage + TSS setup: @pml4 is a global
|
||||
# that switch_pid modifies. A timer interrupt mid-section would make the scheduler
|
||||
# call switch_pid for another thread, corrupting @pml4 for our MapPage calls.
|
||||
asm.cli()
|
||||
proc.switch_pid(pid)
|
||||
cur_p: proc.Process | t.CPtr = proc.ProcessManager.current()
|
||||
entry_fn: t.CPtr = cur_p.entry
|
||||
cur_p: proc.Process* = proc.ProcessManager.current()
|
||||
entry_fn: rawptr = cur_p.entry
|
||||
# [DIAG] 定位用户进程首个指令 PF:打印 entry 实际值(PF cr2=ELF 物理区最后一页,
|
||||
# 疑似 entry 被写成 phys 地址而非虚拟 0x400000)。
|
||||
_dbw: t.CArray[t.CChar, 160]
|
||||
viperlib.snprintf(c.Addr(_dbw), 160, "[wrap] pid=%d cur=0x%lx ent=0x%lx ebase=0x%lx ks=0x%lx us=0x%lx\n",
|
||||
_dbw: [160]char
|
||||
viperlib.snprintf(&_dbw, 160, "[wrap] pid=%d cur=0x%lx ent=0x%lx ebase=0x%lx ks=0x%lx us=0x%lx\n",
|
||||
pid, uint64(cur_p), uint64(entry_fn), cur_p.elf_base, cur_p.kern_stack, cur_p.user_stack)
|
||||
serial.puts(c.Addr(_dbw))
|
||||
serial.puts(&_dbw)
|
||||
if entry_fn is not None:
|
||||
user_stack_vtop: uint64 = USER_STACK_VTOP
|
||||
us_sz: uint64 = USER_STACK_SIZE
|
||||
@@ -375,47 +373,46 @@ def _elf_entry_wrapper(arg: t.CPtr) -> int:
|
||||
# This prevents timer interrupt preemption between TSS setup and iretq.
|
||||
# Drop to Ring 3 user mode via iretq
|
||||
proc.drop_to_user_mode(entry_fn, user_stack_vtop, cur_p.kern_stack)
|
||||
cur: proc.Process | t.CPtr = proc.ProcessManager.current()
|
||||
cur: proc.Process* = proc.ProcessManager.current()
|
||||
cur.exit()
|
||||
return 0
|
||||
|
||||
def spawn_elf(path: t.CConst | str) -> int:
|
||||
def spawn_elf(path: const str) -> int:
|
||||
fat32.lock()
|
||||
name_start: int = 0
|
||||
si: int = 0
|
||||
while True:
|
||||
ch: t.CChar = path[si]
|
||||
if ch == 0: break
|
||||
if ch == 47:
|
||||
name_start = si + 1
|
||||
ch: char = path[si]
|
||||
if ch == 0: break
|
||||
if ch == 47: name_start = si + 1
|
||||
si += 1
|
||||
|
||||
lowest_vaddr: uint64 = 0
|
||||
highest_vaddr_end: uint64 = 0
|
||||
fp_scan: fat32_types.fileobj | t.CPtr = fat32.open(path, fat32_types.FA_READ)
|
||||
fp_scan: fat32_types.fileobj* = fat32.open(path, fat32_types.FA_READ)
|
||||
if fp_scan is None:
|
||||
serr: uint32 = fat32.last_error()
|
||||
seb: t.CArray[t.CChar, 64]
|
||||
viperlib.snprintf(c.Addr(seb), 64, "[elf] spawn scan open failed err=%d\n", serr)
|
||||
serial.puts(seb)
|
||||
seb: [64]char
|
||||
viperlib.snprintf(&seb, 64, "[elf] spawn scan open failed err=%d\n", serr)
|
||||
serial.puts(&seb)
|
||||
fat32.unlock()
|
||||
return -1
|
||||
if fp_scan is not None:
|
||||
ehdr_buf_s: t.CArray[uint8, 64]
|
||||
string.memset(c.Addr(ehdr_buf_s), 0, 64)
|
||||
fat32.read(fp_scan, c.Addr(ehdr_buf_s), 64)
|
||||
ehdr_s: Elf64_Ehdr | t.CPtr = c.Addr(ehdr_buf_s)
|
||||
ehdr_buf_s: [64]uint8
|
||||
string.memset(&ehdr_buf_s, 0, 64)
|
||||
fat32.read(fp_scan, &ehdr_buf_s, 64)
|
||||
ehdr_s: Elf64_Ehdr* = &ehdr_buf_s
|
||||
if ehdr_s.e_type == ET_EXEC or ehdr_s.e_type == ET_DYN:
|
||||
phoff_s: uint64 = ehdr_s.e_phoff
|
||||
phentsize_s: uint16 = ehdr_s.e_phentsize
|
||||
phnum_s: uint16 = ehdr_s.e_phnum
|
||||
if phentsize_s > 0 and phnum_s > 0 and phnum_s <= MAX_PHDRS:
|
||||
phdr_bufs_s: t.CArray[Elf64_Phdr, MAX_PHDRS]
|
||||
string.memset(c.Addr(phdr_bufs_s), 0, MAX_PHDRS * 56)
|
||||
phdr_bufs_s: [MAX_PHDRS]Elf64_Phdr
|
||||
string.memset(&phdr_bufs_s, 0, MAX_PHDRS * 56)
|
||||
found_load_s: int = 0
|
||||
for pi_s in range(phnum_s):
|
||||
fat32.seek(fp_scan, uint32(phoff_s + uint64(pi_s) * uint64(phentsize_s)))
|
||||
fat32.read(fp_scan, c.Addr(phdr_bufs_s[pi_s]), 56)
|
||||
fat32.read(fp_scan, &phdr_bufs_s[pi_s], 56)
|
||||
if phdr_bufs_s[pi_s].p_type == PT_LOAD:
|
||||
seg_end_s: uint64 = phdr_bufs_s[pi_s].p_vaddr + phdr_bufs_s[pi_s].p_memsz
|
||||
if found_load_s == 0:
|
||||
@@ -437,7 +434,7 @@ def spawn_elf(path: t.CConst | str) -> int:
|
||||
# do_map=0: load_elf stores mapping info in globals for spawn_elf to use.
|
||||
# ROOT CAUSE FIX: previously load_elf mapped ELF vaddr (e.g. 0x400000) into
|
||||
# kernel PML4, overwriting identity mapping of buddy memory_block headers.
|
||||
entry: t.CPtr = load_elf(path, 0)
|
||||
entry: rawptr = load_elf(path, 0)
|
||||
if entry is None:
|
||||
serial.puts("[elf] spawn: load failed\n")
|
||||
fat32.unlock()
|
||||
@@ -445,9 +442,9 @@ def spawn_elf(path: t.CConst | str) -> int:
|
||||
|
||||
# Clone kernel PML4 (identity mapping intact, no ELF mapping yet)
|
||||
proc_pml4: uint64 = paging.clone_for_process(isolate_va)
|
||||
slog1: t.CArray[t.CChar, 80]
|
||||
viperlib.snprintf(c.Addr(slog1), 80, "[elf] spawn: clone pml4=0x%lx va=0x%lx\n", proc_pml4, isolate_va)
|
||||
serial.puts(slog1)
|
||||
slog1: [80]char
|
||||
viperlib.snprintf(&slog1, 80, "[elf] spawn: clone pml4=0x%lx va=0x%lx\n", proc_pml4, isolate_va)
|
||||
serial.puts(&slog1)
|
||||
if proc_pml4 == 0:
|
||||
serial.puts("[elf] spawn: clone_for_process failed\n")
|
||||
fat32.unlock()
|
||||
@@ -460,22 +457,22 @@ def spawn_elf(path: t.CConst | str) -> int:
|
||||
# interrupt mid-section would call switch_pid, corrupting @pml4.
|
||||
asm.cli()
|
||||
_kernel_cr3: uint64 = 0
|
||||
c.Asm(f"""mov {c.AsmOut(_kernel_cr3, t.ASM_DESCR.OUTPUT_REG)}, cr3""", op=[t.ASM_DESCR.CLOBBER_MEMORY])
|
||||
c.Asm(f"mov cr3, {c.AsmInp(proc_pml4, t.ASM_DESCR.REG_ANY)}", op=[t.ASM_DESCR.CLOBBER_MEMORY])
|
||||
__asm__(f"""mov {asmout(_kernel_cr3, ASM_DESCR.OUTPUT_REG)}, cr3""", op=[ASM_DESCR.CLOBBER_MEMORY])
|
||||
__asm__(f"mov cr3, {asminp(proc_pml4, ASM_DESCR.REG_ANY)}", op=[ASM_DESCR.CLOBBER_MEMORY])
|
||||
paging.set_active_pml4(proc_pml4)
|
||||
mi: uint64
|
||||
for mi in range(_last_elf_num_map_pages):
|
||||
_va: uint64 = _last_elf_virt_page_start + mi * 0x1000
|
||||
_pa: uint64 = _last_elf_phys_page_start + mi * 0x1000
|
||||
paging.MapPage(_va, _pa, paging.PTE_PRESENT | paging.PTE_WRITABLE | paging.PTE_USER)
|
||||
c.Asm(f"mov cr3, {c.AsmInp(_kernel_cr3, t.ASM_DESCR.REG_ANY)}", op=[t.ASM_DESCR.CLOBBER_MEMORY])
|
||||
__asm__(f"mov cr3, {asminp(_kernel_cr3, ASM_DESCR.REG_ANY)}", op=[ASM_DESCR.CLOBBER_MEMORY])
|
||||
paging.set_active_pml4(_kernel_cr3)
|
||||
asm.sti()
|
||||
|
||||
# path[name_start:] 切片表达式 translate_subscript 不支持 Slice(返回 None)→
|
||||
# 作为实参丢 name、entry 错位成第一参数(TPV 已修,此处指针算术双保险)
|
||||
nm_ptr: t.CConst | t.CChar | t.CPtr = t.CConst(uint64(path) + uint64(name_start), t.CPtr)
|
||||
p: proc.Process | t.CPtr = proc.ProcessManager.create_process(nm_ptr, entry)
|
||||
nm_ptr: const str = str(uint64(path) + uint64(name_start))
|
||||
p: proc.Process* = proc.ProcessManager.create_process(nm_ptr, entry)
|
||||
if p is None:
|
||||
serial.puts("[elf] spawn: create_process failed\n")
|
||||
fat32.unlock()
|
||||
@@ -485,7 +482,7 @@ def spawn_elf(path: t.CConst | str) -> int:
|
||||
if p.pid >= 0 and p.pid < MAX_SPAWNED:
|
||||
_elf_entries[p.pid] = entry
|
||||
|
||||
th: sched.Thread | t.CPtr = sched.Scheduler.create_thread(t.CPtr(_elf_entry_wrapper), t.CPtr(uint64(p.pid)), p.pid)
|
||||
th: sched.Thread* = sched.Scheduler.create_thread(&_elf_entry_wrapper, rawptr(uint64(p.pid)), p.pid)
|
||||
if th is None:
|
||||
serial.puts("[elf] spawn: create_thread failed\n")
|
||||
p.exit()
|
||||
@@ -493,26 +490,26 @@ def spawn_elf(path: t.CConst | str) -> int:
|
||||
return -3
|
||||
tid: int = th.tid
|
||||
p.addThread(tid)
|
||||
slog: t.CArray[t.CChar, 80]
|
||||
viperlib.snprintf(c.Addr(slog), 80, "[elf] spawn: pid=%d tid=%d entry=0x%lx pml4=0x%lx\n", p.pid, tid, uint64(entry), p.pml4_root)
|
||||
serial.puts(slog)
|
||||
slog: [80]char
|
||||
viperlib.snprintf(&slog, 80, "[elf] spawn: pid=%d tid=%d entry=0x%lx pml4=0x%lx\n", p.pid, tid, uint64(entry), p.pml4_root)
|
||||
serial.puts(&slog)
|
||||
# [DIAG] 确认 return p.pid 的实际值(main 收到 pid=0 而此处打印 3)
|
||||
_dbw2: t.CArray[t.CChar, 64]
|
||||
viperlib.snprintf(c.Addr(_dbw2), 64, "[elf] spawn ret pid=%d\n", p.pid)
|
||||
serial.puts(c.Addr(_dbw2))
|
||||
_dbw2: [64]char
|
||||
viperlib.snprintf(&_dbw2, 64, "[elf] spawn ret pid=%d\n", p.pid)
|
||||
serial.puts(&_dbw2)
|
||||
fat32.unlock()
|
||||
return p.pid
|
||||
|
||||
def _resolve_symbol(name: t.CConst | t.CChar | t.CPtr) -> t.CPtr:
|
||||
def _resolve_symbol(name: const str) -> rawptr:
|
||||
nm: int = 0
|
||||
while c.Deref(name + nm) != 0:
|
||||
while name[nm] != 0:
|
||||
nm += 1
|
||||
cmp_name: t.CConst | t.CChar | t.CPtr = name
|
||||
cmp_name: const str = name
|
||||
cmp_len: int = nm
|
||||
if nm > 9:
|
||||
sha1_len2: int = 0
|
||||
for si2 in range(nm):
|
||||
ch2: t.CChar = c.Deref(name + si2)
|
||||
ch2: char = name[si2]
|
||||
if ch2 == 46:
|
||||
if sha1_len2 >= 8:
|
||||
cmp_name = str(uint64(name) + si2 + 1)
|
||||
@@ -527,35 +524,35 @@ def _resolve_symbol(name: t.CConst | t.CChar | t.CPtr) -> t.CPtr:
|
||||
if cmp_len == 11:
|
||||
match: int = 1
|
||||
for i in range(cmp_len):
|
||||
if c.Deref(cmp_name + i) != c.Deref("serial_puts" + i):
|
||||
if cmp_name[i] != "serial_puts"[i]:
|
||||
match = 0
|
||||
if match:
|
||||
return c.Addr(serial.puts)
|
||||
return &serial.puts
|
||||
return None
|
||||
|
||||
_so_strtab: t.CPtr
|
||||
_so_symtab: t.CPtr
|
||||
_so_strtab: rawptr
|
||||
_so_symtab: rawptr
|
||||
_so_syment: uint64
|
||||
_so_sym_count: int
|
||||
|
||||
def load_so(path: t.CConst | str) -> t.CPtr:
|
||||
def load_so(path: const str) -> rawptr:
|
||||
fat32.lock()
|
||||
fp: fat32_types.fileobj | t.CPtr = fat32.open(path, fat32_types.FA_READ)
|
||||
fp: fat32_types.fileobj* = fat32.open(path, fat32_types.FA_READ)
|
||||
if fp is None:
|
||||
serial.puts("[so] failed to open file\n")
|
||||
fat32.unlock()
|
||||
return None
|
||||
|
||||
ehdr_buf: t.CArray[uint8, 64]
|
||||
string.memset(c.Addr(ehdr_buf), 0, 64)
|
||||
read_len: uint32 = fat32.read(fp, c.Addr(ehdr_buf), 64)
|
||||
ehdr_buf: [64]uint8
|
||||
string.memset(&ehdr_buf, 0, 64)
|
||||
read_len: uint32 = fat32.read(fp, &ehdr_buf, 64)
|
||||
if read_len < 64:
|
||||
serial.puts("[so] failed to read ehdr\n")
|
||||
fat32.close(fp)
|
||||
fat32.unlock()
|
||||
return None
|
||||
|
||||
ehdr: Elf64_Ehdr | t.CPtr = c.Addr(ehdr_buf)
|
||||
ehdr: Elf64_Ehdr* = &ehdr_buf
|
||||
if ehdr.e_ident[0] != ELFMAG0 or ehdr.e_ident[1] != ELFMAG1 or ehdr.e_ident[2] != ELFMAG2 or ehdr.e_ident[3] != ELFMAG3:
|
||||
serial.puts("[so] bad magic\n")
|
||||
fat32.close(fp)
|
||||
@@ -588,12 +585,12 @@ def load_so(path: t.CConst | str) -> t.CPtr:
|
||||
fat32.unlock()
|
||||
return None
|
||||
|
||||
phdr_bufs: t.CArray[Elf64_Phdr, MAX_PHDRS]
|
||||
string.memset(c.Addr(phdr_bufs), 0, MAX_PHDRS * 56)
|
||||
phdr_bufs: [MAX_PHDRS]Elf64_Phdr
|
||||
string.memset(&phdr_bufs, 0, MAX_PHDRS * 56)
|
||||
for pi in range(phnum):
|
||||
phdr_off: uint64 = phoff + uint64(pi) * uint64(phentsize)
|
||||
fat32.seek(fp, uint32(phdr_off))
|
||||
fat32.read(fp, c.Addr(phdr_bufs[pi]), 56)
|
||||
fat32.read(fp, &phdr_bufs[pi], 56)
|
||||
|
||||
found_load: int = 0
|
||||
lowest_vaddr: uint64 = 0
|
||||
@@ -621,7 +618,7 @@ def load_so(path: t.CConst | str) -> t.CPtr:
|
||||
total_pages: uint64 = (total_memsz + 0xFFF) // 0x1000
|
||||
|
||||
so_load_addr: uint64 = 0x600000
|
||||
raw_alloc: t.CPtr = mm.malloc(total_pages * 0x1000 + 0x1000)
|
||||
raw_alloc: rawptr = mm.malloc(total_pages * 0x1000 + 0x1000)
|
||||
if not raw_alloc:
|
||||
serial.puts("[so] malloc failed\n")
|
||||
fat32.close(fp)
|
||||
@@ -629,7 +626,7 @@ def load_so(path: t.CConst | str) -> t.CPtr:
|
||||
return None
|
||||
|
||||
phys_base_aligned: uint64 = (uint64(raw_alloc) + 0xFFF) & ~uint64(0xFFF)
|
||||
phys_base: t.CPtr = t.CPtr(phys_base_aligned)
|
||||
phys_base: rawptr = rawptr(phys_base_aligned)
|
||||
string.memset(phys_base, 0, total_pages * 0x1000)
|
||||
|
||||
for pi in range(phnum):
|
||||
@@ -639,12 +636,12 @@ def load_so(path: t.CConst | str) -> t.CPtr:
|
||||
filesz: uint64 = phdr_bufs[pi].p_filesz
|
||||
memsz: uint64 = phdr_bufs[pi].p_memsz
|
||||
dest_off: uint64 = vaddr - lowest_vaddr
|
||||
dest: t.CPtr = t.CPtr(uint64(phys_base) + dest_off)
|
||||
dest: rawptr = rawptr(uint64(phys_base) + dest_off)
|
||||
if filesz > 0:
|
||||
fat32.seek(fp, uint32(file_off))
|
||||
fat32.read(fp, dest, uint32(filesz))
|
||||
if memsz > filesz:
|
||||
bss_start: t.CPtr = t.CPtr(uint64(dest) + filesz)
|
||||
bss_start: rawptr = rawptr(uint64(dest) + filesz)
|
||||
bss_len: uint64 = memsz - filesz
|
||||
string.memset(bss_start, 0, bss_len)
|
||||
|
||||
@@ -660,8 +657,8 @@ def load_so(path: t.CConst | str) -> t.CPtr:
|
||||
|
||||
base_vaddr: uint64 = so_load_addr + lowest_vaddr
|
||||
|
||||
dyn_buf: t.CArray[Elf64_Dyn, MAX_DYNS]
|
||||
string.memset(c.Addr(dyn_buf), 0, MAX_DYNS * 16)
|
||||
dyn_buf: [MAX_DYNS]Elf64_Dyn
|
||||
string.memset(&dyn_buf, 0, MAX_DYNS * 16)
|
||||
dyn_count: int = 0
|
||||
for pi in range(phnum):
|
||||
if phdr_bufs[pi].p_type == PT_DYNAMIC:
|
||||
@@ -671,7 +668,7 @@ def load_so(path: t.CConst | str) -> t.CPtr:
|
||||
max_dyn_bytes: uint32 = uint32(MAX_DYNS * 16)
|
||||
if filesz_d > max_dyn_bytes:
|
||||
filesz_d = max_dyn_bytes
|
||||
dyn_read: uint32 = fat32.read(fp, c.Addr(dyn_buf), filesz_d)
|
||||
dyn_read: uint32 = fat32.read(fp, &dyn_buf, filesz_d)
|
||||
dyn_count = int(dyn_read) // 16
|
||||
|
||||
strtab_vaddr: uint64 = 0
|
||||
@@ -693,51 +690,51 @@ def load_so(path: t.CConst | str) -> t.CPtr:
|
||||
elif dyn_buf[di].d_tag == DT_JMPREL: jmprel_vaddr = dyn_buf[di].d_val
|
||||
elif dyn_buf[di].d_tag == DT_PLTRELSZ: pltrelsz = dyn_buf[di].d_val
|
||||
|
||||
strtab_ptr: t.CPtr = t.CPtr(strtab_vaddr + so_load_addr)
|
||||
symtab_ptr: t.CPtr = t.CPtr(symtab_vaddr + so_load_addr)
|
||||
strtab_ptr: rawptr = rawptr(strtab_vaddr + so_load_addr)
|
||||
symtab_ptr: rawptr = rawptr(symtab_vaddr + so_load_addr)
|
||||
|
||||
if rela_vaddr != 0 and relasz > 0:
|
||||
rela_count: uint64 = relasz // 24
|
||||
for ri in range(rela_count):
|
||||
rela: Elf64_Rela | t.CPtr = t.CPtr(uint64(rela_vaddr) + so_load_addr + ri * 24)
|
||||
rela: Elf64_Rela* = Elf64_Rela*(uint64(rela_vaddr) + so_load_addr + ri * 24)
|
||||
r_type: uint32 = uint32(rela.r_info & 0xFFFFFFFF)
|
||||
r_sym: uint32 = uint32(rela.r_info >> 32)
|
||||
target_addr: t.CPtr = t.CPtr(rela.r_offset + so_load_addr)
|
||||
target_addr: rawptr = rawptr(rela.r_offset + so_load_addr)
|
||||
if r_type == R_X86_64_RELATIVE:
|
||||
val: uint64 = uint64(rela.r_addend) + so_load_addr
|
||||
string.memcpy(target_addr, c.Addr(val), 8)
|
||||
string.memcpy(target_addr, &val, 8)
|
||||
elif r_type == R_X86_64_64 or r_type == R_X86_64_GLOB_DAT or r_type == R_X86_64_JUMP_SLOT:
|
||||
sym: Elf64_Sym | t.CPtr = t.CPtr(uint64(symtab_ptr) + uint64(r_sym) * syment)
|
||||
sym_name: t.CConst | str = t.CPtr(uint64(strtab_ptr) + sym.st_name)
|
||||
resolved: t.CPtr = _resolve_symbol(sym_name)
|
||||
sym: Elf64_Sym* = Elf64_Sym*(uint64(symtab_ptr) + uint64(r_sym) * syment)
|
||||
sym_name: const str = str(uint64(strtab_ptr) + sym.st_name)
|
||||
resolved: rawptr = _resolve_symbol(sym_name)
|
||||
if resolved is not None:
|
||||
val2: uint64 = uint64(resolved) + uint64(rela.r_addend)
|
||||
string.memcpy(target_addr, c.Addr(val2), 8)
|
||||
string.memcpy(target_addr, &val2, 8)
|
||||
elif sym.st_value != 0:
|
||||
val3: uint64 = sym.st_value + so_load_addr + uint64(rela.r_addend)
|
||||
string.memcpy(target_addr, c.Addr(val3), 8)
|
||||
string.memcpy(target_addr, &val3, 8)
|
||||
|
||||
if jmprel_vaddr != 0 and pltrelsz > 0:
|
||||
jmprel_count: uint64 = pltrelsz // 24
|
||||
for ji in range(jmprel_count):
|
||||
rela2: Elf64_Rela | t.CPtr = t.CPtr(jmprel_vaddr + so_load_addr + ji * 24)
|
||||
rela2: Elf64_Rela* = Elf64_Rela*(jmprel_vaddr + so_load_addr + ji * 24)
|
||||
r_type2: uint32 = uint32(rela2.r_info & 0xFFFFFFFF)
|
||||
r_sym2: uint32 = uint32(rela2.r_info >> 32)
|
||||
target2: t.CPtr = t.CPtr(rela2.r_offset + so_load_addr)
|
||||
target2: rawptr = rawptr(rela2.r_offset + so_load_addr)
|
||||
if r_type2 == R_X86_64_JUMP_SLOT or r_type2 == R_X86_64_GLOB_DAT:
|
||||
sym2: Elf64_Sym | t.CPtr = t.CPtr(uint64(symtab_ptr) + uint64(r_sym2) * syment)
|
||||
sym_name2: t.CConst | str = t.CPtr(uint64(strtab_ptr) + sym2.st_name)
|
||||
resolved2: t.CPtr = _resolve_symbol(sym_name2)
|
||||
sym2: Elf64_Sym* = Elf64_Sym*(uint64(symtab_ptr) + uint64(r_sym2) * syment)
|
||||
sym_name2: const str = str(uint64(strtab_ptr) + sym2.st_name)
|
||||
resolved2: rawptr = _resolve_symbol(sym_name2)
|
||||
if resolved2 is not None:
|
||||
val4: uint64 = uint64(resolved2) + uint64(rela2.r_addend)
|
||||
string.memcpy(target2, c.Addr(val4), 8)
|
||||
string.memcpy(target2, &val4, 8)
|
||||
elif sym2.st_value != 0:
|
||||
val5: uint64 = sym2.st_value + so_load_addr + uint64(rela2.r_addend)
|
||||
string.memcpy(target2, c.Addr(val5), 8)
|
||||
string.memcpy(target2, &val5, 8)
|
||||
else:
|
||||
cr3: t.CArray[t.CChar, 80]
|
||||
viperlib.snprintf(c.Addr(cr3), 80, "[so] WARN: unresolved PLT sym offset=%lu\n", sym2.st_name)
|
||||
serial.puts(cr3)
|
||||
cr3: [80]char
|
||||
viperlib.snprintf(&cr3, 80, "[so] WARN: unresolved PLT sym offset=%lu\n", sym2.st_name)
|
||||
serial.puts(&cr3)
|
||||
|
||||
fat32.close(fp)
|
||||
|
||||
@@ -748,37 +745,37 @@ def load_so(path: t.CConst | str) -> t.CPtr:
|
||||
_so_syment = syment
|
||||
_so_sym_count = 0
|
||||
if hash_vaddr != 0:
|
||||
hash_ptr: t.CPtr = t.CPtr(hash_vaddr + so_load_addr)
|
||||
# 宽度只由指针的元素类型决定:nchain 是 4 字节字段,必须给出 u32*
|
||||
# (i8* 现在恒读 1 字节)。地址口径不变(hash_ptr + 4 字节)。
|
||||
nchain: uint32 = c.Deref(uint32(uint64(hash_ptr) + 4, t.CPtr))
|
||||
hash_ptr: rawptr = rawptr(hash_vaddr + so_load_addr)
|
||||
# 宽度只由指针的元素类型决定:nchain 是 4 字节字段,必须给出 u32*
|
||||
# (i8* 现在恒读 1 字节)。地址口径不变(hash_ptr + 4 字节)。
|
||||
nchain: uint32 = *(uint32*(uint64(hash_ptr) + 4))
|
||||
_so_sym_count = int(nchain)
|
||||
elif syment > 0 and strtab_vaddr > symtab_vaddr and symtab_vaddr != 0:
|
||||
sym_tab_size: uint64 = strtab_vaddr - symtab_vaddr
|
||||
_so_sym_count = int(sym_tab_size // syment)
|
||||
|
||||
cr: t.CArray[t.CChar, 80]
|
||||
viperlib.snprintf(c.Addr(cr), 80, "[so] loaded at 0x%lx\n", base_vaddr)
|
||||
cr: [80]char
|
||||
viperlib.snprintf(&cr, 80, "[so] loaded at 0x%lx\n", base_vaddr)
|
||||
serial.puts(cr)
|
||||
|
||||
fat32.unlock()
|
||||
return t.CPtr(base_vaddr)
|
||||
return rawptr(base_vaddr)
|
||||
|
||||
def get_so_symbol(so_base: t.CPtr, name: t.CConst | str, so_path: t.CConst | t.CChar | t.CPtr) -> t.CPtr:
|
||||
def get_so_symbol(so_base: rawptr, name: const str, so_path: const str) -> rawptr:
|
||||
if _so_symtab is None or _so_strtab is None or _so_syment == 0:
|
||||
return None
|
||||
if name is None:
|
||||
return None
|
||||
for symi in range(_so_sym_count):
|
||||
sb2: Elf64_Sym | t.CPtr = t.CPtr(uint64(_so_symtab) + uint64(symi) * _so_syment)
|
||||
sb2: Elf64_Sym* = Elf64_Sym*(uint64(_so_symtab) + uint64(symi) * _so_syment)
|
||||
if sb2.st_value != 0 and sb2.st_shndx != 0:
|
||||
sym_name_off2: uint32 = sb2.st_name
|
||||
cmp_off2: uint32 = sym_name_off2
|
||||
match2: int = 0
|
||||
ni2: int = 0
|
||||
while True:
|
||||
sc3: t.CChar = c.Deref(t.CPtr(uint64(_so_strtab) + cmp_off2 + ni2))
|
||||
nc3: t.CChar = c.Deref(name + ni2)
|
||||
sc3: char = *(char*(uint64(_so_strtab) + cmp_off2 + ni2))
|
||||
nc3: char = *(name + ni2)
|
||||
if sc3 != nc3:
|
||||
break
|
||||
if sc3 == 0:
|
||||
@@ -790,7 +787,7 @@ def get_so_symbol(so_base: t.CPtr, name: t.CConst | str, so_path: t.CConst | t.C
|
||||
is_sha1_2: int = 0
|
||||
sha1_len_2: uint32 = 0
|
||||
while True:
|
||||
dc4: t.CChar = c.Deref(t.CPtr(uint64(_so_strtab) + dot_pos3))
|
||||
dc4: char = *(char*(uint64(_so_strtab) + dot_pos3))
|
||||
if dc4 == 46:
|
||||
if sha1_len_2 >= 8:
|
||||
is_sha1_2 = 1
|
||||
@@ -807,8 +804,8 @@ def get_so_symbol(so_base: t.CPtr, name: t.CConst | str, so_path: t.CConst | t.C
|
||||
match2 = 1
|
||||
ni2 = 0
|
||||
while True:
|
||||
sc4: t.CChar = c.Deref(t.CPtr(uint64(_so_strtab) + cmp_off2 + ni2))
|
||||
nc4: t.CChar = c.Deref(name + ni2)
|
||||
sc4: char = *(char*(uint64(_so_strtab) + cmp_off2 + ni2))
|
||||
nc4: char = *(name + ni2)
|
||||
if sc4 != nc4:
|
||||
match2 = 0
|
||||
break
|
||||
@@ -817,9 +814,9 @@ def get_so_symbol(so_base: t.CPtr, name: t.CConst | str, so_path: t.CConst | t.C
|
||||
ni2 += 1
|
||||
if match2:
|
||||
result_addr: uint64 = uint64(so_base) + sb2.st_value
|
||||
dbg2: t.CArray[t.CChar, 80]
|
||||
viperlib.snprintf(c.Addr(dbg2), 80, "[so] found '%s' at 0x%lx\n", t.CPtr(uint64(_so_strtab) + sym_name_off2), result_addr)
|
||||
serial.puts(dbg2)
|
||||
return t.CPtr(result_addr)
|
||||
dbg2: [80]char
|
||||
viperlib.snprintf(&dbg2, 80, "[so] found '%s' at 0x%lx\n", rawptr(uint64(_so_strtab) + sym_name_off2), result_addr)
|
||||
serial.puts(&dbg2)
|
||||
return rawptr(result_addr)
|
||||
serial.puts("[so] symbol not found\n")
|
||||
return None
|
||||
Reference in new issue
Block a user