1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
# load an embedded elf into a fresh address space and run it in ring 3
const PT_LOAD = 1
const PAGE_FLAGS = 6 # write | user
fn load_elf(base) do
if mem_read(base, 4) != 0x464c457f do
puts("not an ELF\n")
return :nil
end
const entry = mem_read(base + 24, 8)
const phoff = mem_read(base + 32, 8)
const phnum = mem_read(base + 56, 2)
const phentsize = mem_read(base + 54, 2)
const space = as_create()
for i in 0..phnum do
const phdr = base + phoff + i * phentsize
if mem_read(phdr, 4) == PT_LOAD do
const offset = mem_read(phdr + 8, 8)
const vaddr = mem_read(phdr + 16, 8)
const filesz = mem_read(phdr + 32, 8)
const memsz = mem_read(phdr + 40, 8)
let seg_off = 0
while seg_off < memsz do
const frame = frame_alloc()
mem_zero(frame, 4096)
if seg_off < filesz do
const left = filesz - seg_off
mem_copy(frame, base + offset + seg_off, if left > 4096 4096 else left)
end
as_map(space, vaddr + seg_off, frame, PAGE_FLAGS)
seg_off = seg_off + 4096
end
end
end
const stack_top = 0x7fff0000
as_map(space, stack_top - 4096, frame_alloc(), PAGE_FLAGS)
proc_run(space, entry, stack_top)
end
# launch a program by name, :true if one matched
fn run_prog(name) do
for i in 0..prog_count() do
if prog_name(i) == name do load_elf(prog_phys(i)) return :true end
end
puts("no such program: #{name}\n")
return :false
end
fn list_progs() do
puts("programs:")
for i in 0..prog_count() do puts(" #{prog_name(i)}") end
puts("\n")
end
|