test/loader/kernel/loadcheck.rad 3.0 KiB raw
1
//! Execute runtime-loaded native code after releasing its compiler workspace.
2
3
use std::mem;
4
use kernel::abi;
5
use kernel::backing;
6
use kernel::capability;
7
use kernel::pages;
8
use kernel::registry;
9
use kernel::loader;
10
use kernel::loadinput;
11
use kernel::domains;
12
use kernel::slots;
13
14
/// Capability storage for the loading domain.
15
unsafe static TABLE: capability::Table = undefined;
16
17
/// View a validated source Page as mapped bytes.
18
fn memory(address: u64) -> *mut u8;
19
20
/// Call a published entry with one instance's package-state table.
21
fn invoke(address: u64, table: u64) -> i64;
22
23
/// Load the hosted comparison package and execute its retained native instructions.
24
export unsafe fn run() {
25
    let pending = try! slots::reserve(&mut domains::STORE.slots[..]);
26
    let owner = try! slots::commit(&mut domains::STORE.slots[..], pending);
27
    capability::initialize(&mut TABLE, owner);
28
    try! backing::registerDomain(&mut pages::STORE.backings, owner);
29
    let authority = try! capability::install(&mut TABLE, capability::Entry {
30
        kind: abi::Kind::Domain, object: owner, rights: abi::Rights(abi::CREATE | abi::ALLOCATE),
31
    });
32
    let source = try! pages::allocate(&mut pages::STORE, &mut TABLE, authority, 1);
33
    let cap = try! capability::lookup(&TABLE, source, abi::Kind::Page, abi::Rights(abi::READ));
34
    let page = try! pages::get(&pages::STORE, cap.object);
35
    let bytes = @sliceOf(memory(page.base), 4096);
36
    let length = try! mem::copy(&mut bytes[..], &loadinput::INPUT[..]);
37
    let handle = try! loader::load(&mut loader::STATE, &mut pages::STORE, &mut registry::STORE, &mut TABLE,
38
        loader::Request { authority, source, offset: 0, length: length as u64 });
39
    assert not loader::STATE.busy;
40
    let object = try! registry::image(&registry::STORE, &TABLE, handle, abi::Rights(abi::EXECUTE));
41
    let package = try! registry::get(&registry::STORE, object);
42
    let entry = package.entry else panic "loaded entry";
43
    for i in 0..length { set bytes[i] = 0; }
44
    assert package.relocations.len > 0;
45
    let firstHandle = try! domains::create(&mut domains::STORE, &mut pages::STORE.backings, &registry::STORE, &mut TABLE, authority, handle);
46
    let secondHandle = try! domains::create(&mut domains::STORE, &mut pages::STORE.backings, &registry::STORE, &mut TABLE, authority, handle);
47
    let firstEntry = try! capability::get(&TABLE, firstHandle);
48
    let secondEntry = try! capability::get(&TABLE, secondHandle);
49
    let first = try! domains::get(&domains::STORE, firstEntry.object);
50
    let second = try! domains::get(&domains::STORE, secondEntry.object);
51
    assert first.state == domains::Lifecycle::Pending and second.state == domains::Lifecycle::Pending;
52
    assert domains::STORE.contexts[first.initial.index].frame.pc == entry;
53
    assert domains::STORE.contexts[second.initial.index].frame.pc == entry;
54
    assert first.memory.ring.mask == 255 and second.memory.ring.mask == 255;
55
    assert invoke(entry, first.graph.table.ptr as u64) == 43;
56
    assert invoke(entry, first.graph.table.ptr as u64) == 85;
57
    assert invoke(entry, second.graph.table.ptr as u64) == 43;
58
}