compiler/
kernel/
lib/
scripts/
seed/
sublime/
test/
acceptance/
boot/
bootstrap/
cycles/
dispatch/
loader/
kernel/
loadcheck.rad
3.0 KiB
loaded.rad
513 B
machine.ras
711 B
run
1.7 KiB
mmio/
native/
packages/
pages/
runtime/
scheduling/
shared/
slots/
smp/
support/
sync/
termination/
tests/
trap/
package-golden
1.6 KiB
run
3.1 KiB
runner.rad
10.5 KiB
vim/
.gitignore
336 B
.gitsigners
112 B
CONTRIBUTING
2.1 KiB
LICENSE
1.1 KiB
Makefile
9.2 KiB
README
2.5 KiB
STYLE
2.5 KiB
std.lib
1.5 KiB
std.lib.test
662 B
test/loader/kernel/loadcheck.rad
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(®istry::STORE, &TABLE, handle, abi::Rights(abi::EXECUTE)); |
| 41 | let package = try! registry::get(®istry::STORE, object); |
| 42 | let entry = package.entry else panic "loaded entry"; |
| 43 | for i in 0..length { |
| 44 | set bytes[i] = 0; |
| 45 | } |
| 46 | assert package.relocations.len > 0; |
| 47 | let firstHandle = try! domains::create(&mut domains::STORE, &mut pages::STORE.backings, ®istry::STORE, &mut TABLE, authority, handle); |
| 48 | let secondHandle = try! domains::create(&mut domains::STORE, &mut pages::STORE.backings, ®istry::STORE, &mut TABLE, authority, handle); |
| 49 | let firstEntry = try! capability::get(&TABLE, firstHandle); |
| 50 | let secondEntry = try! capability::get(&TABLE, secondHandle); |
| 51 | let first = try! domains::get(&domains::STORE, firstEntry.object); |
| 52 | let second = try! domains::get(&domains::STORE, secondEntry.object); |
| 53 | assert first.state == domains::Lifecycle::Pending and second.state == domains::Lifecycle::Pending; |
| 54 | assert domains::STORE.contexts[first.initial.index].frame.pc == entry; |
| 55 | assert domains::STORE.contexts[second.initial.index].frame.pc == entry; |
| 56 | assert first.memory.ring.mask == 255 and second.memory.ring.mask == 255; |
| 57 | assert invoke(entry, first.graph.table.ptr as u64) == 43; |
| 58 | assert invoke(entry, first.graph.table.ptr as u64) == 85; |
| 59 | assert invoke(entry, second.graph.table.ptr as u64) == 43; |
| 60 | } |