内核 MMAP(addr,length,prot,flags,fd,offset):fd=-1 + MAP_ANONYMOUS 走匿名映射(分配物理页、清零后映射到本进程新 VA,对齐 Linux"匿名必为零"语义);fd 是带 mmap_info 的 devfs 设备(当前仅 /dev/fb0)则把 [phys+offset, phys+offset+len) 按页映射进调用者地址空间(PTE_USER|WRITE)。addr/MAP_FIXED 暂未实现,一律由内核挑 VA 并返回真实起始地址。新增 PROT_*/MAP_*/MMAP_FD_ANON 常量。 参数次序与 Linux mmap 完全一致(rdi/rsi/rdx/r10/r8/r9),syscall_entry 的搬运顺序本就是这个约定,SDK 侧 vpsdk/syscall.vp 加 mmap() 助手走 _syscall6。stdlib.malloc 随之改为匿名映射调用(fd=-1、MAP_PRIVATE|MAP_ANONYMOUS、PROT_READ|PROT_WRITE),行为与原 MMAP(size) 一致且多一层清零。
62 lines
2.1 KiB
Plaintext
62 lines
2.1 KiB
Plaintext
import vpsdk.syscall as _sc
|
||
import string
|
||
|
||
|
||
define HEAP_BLOCK_MAGIC = 0x48454150
|
||
|
||
class _heap_hdr:
|
||
magic: uint32
|
||
size: uint32
|
||
|
||
_heap_inited: int = 0
|
||
|
||
def _heap_init():
|
||
global _heap_inited
|
||
_heap_inited = 1
|
||
|
||
export def malloc(size: sizet) -> rawptr:
|
||
global _heap_inited
|
||
if size == 0: return None
|
||
if _heap_inited == 0: _heap_init()
|
||
hdr_size: sizet = _heap_hdr.__sizeof__()
|
||
total: sizet = hdr_size + size
|
||
# mmap 已按 Linux 六参形态对齐:匿名映射 = fd -1 + MAP_ANONYMOUS + PROT_READ|WRITE
|
||
ptr: uint64 = _sc.mmap(0, uint64(total), uint64(_sc.PROT_READ | _sc.PROT_WRITE),
|
||
uint64(_sc.MAP_PRIVATE | _sc.MAP_ANONYMOUS), _sc.MMAP_FD_ANON, 0)
|
||
if ptr == 0: return None
|
||
# 块头必须落在**映射区内部**(映射起点 ptr 处),不能写 ptr - hdr_size:
|
||
# 那 8 字节在映射之外 —— 第一次 malloc 时 mmap 返回的正是用户堆起点 0x20000000,
|
||
# 写 0x1ffffff8 就是映射区外 ⇒ #PF(err=0x7 用户态写),四个 app 启动即崩的现场。
|
||
hdr: _heap_hdr* = _heap_hdr*(uint64(ptr))
|
||
hdr.magic = HEAP_BLOCK_MAGIC
|
||
hdr.size = uint32(size)
|
||
return rawptr(ptr + hdr_size)
|
||
|
||
export def free(ptr: rawptr):
|
||
if ptr is None: return
|
||
hdr_size: sizet = _heap_hdr.__sizeof__()
|
||
hdr: _heap_hdr* = _heap_hdr*(uint64(ptr) - hdr_size)
|
||
if hdr.magic != HEAP_BLOCK_MAGIC: return
|
||
|
||
export def calloc(nmemb: sizet, size: sizet) -> rawptr:
|
||
total: sizet = nmemb * size
|
||
p: rawptr = malloc(total)
|
||
if p: string.memset(p, 0, total)
|
||
return p
|
||
|
||
export def realloc(ptr: rawptr, size: sizet) -> rawptr:
|
||
if ptr is None: return malloc(size)
|
||
if size == 0:
|
||
free(ptr)
|
||
return None
|
||
hdr_size: sizet = _heap_hdr.__sizeof__()
|
||
hdr: _heap_hdr* = _heap_hdr*(uint64(ptr) - hdr_size)
|
||
if hdr.magic != HEAP_BLOCK_MAGIC: return None
|
||
old_size: sizet = hdr.size
|
||
new_ptr: rawptr = malloc(size)
|
||
if new_ptr is None: return None
|
||
copy_size: sizet = old_size if old_size < size else size
|
||
string.memcpy(new_ptr, ptr, copy_size)
|
||
free(ptr)
|
||
return new_ptr
|