test/sync/build.rad 2.0 KiB raw
1
//! Build a native image from the synchronization machine fixture.
2
3
use std::sys;
4
use std::io;
5
use std::sys::unix;
6
use std::lang::alloc;
7
use std::lang::strings;
8
use std::arch::rv64::asm;
9
use std::arch::rv64::image;
10
11
/// Assembly input storage.
12
static SOURCE: [u8; 65536] = [0; 65536];
13
/// Encoded text words.
14
static TEXT: [u32; 4096] = [0; 4096];
15
/// Assembly name and fixup storage.
16
static MEMORY: [u8; 16777216] = [0; 16777216];
17
/// Interned assembly identifiers.
18
unsafe static STRINGS: strings::Pool = strings::Pool { table: undefined, count: 0 };
19
20
/// Assemble startup and synchronization routines into one native code segment.
21
@default unsafe fn main(env: *sys::Env) -> i32 {
22
    assert env.args.len == 3;
23
    let length = unix::readFile(env.args[1], &mut SOURCE[..]) else panic "missing assembly";
24
    let mut arena = alloc::new(&mut MEMORY[..]);
25
    let data: *mut [u8] = &mut [];
26
    let program = try asm::assemble(asm::scanner::SourceKind::String, &SOURCE[..length],
27
        &mut TEXT[..], &mut data[..], &mut arena, &mut STRINGS, 0) catch err {
28
        match err {
29
            case asm::Error::Invalid { offset, message } => {
30
                io::printU32(offset); io::print(": "); io::printLn(message);
31
            },
32
            else => io::printLn("assembly output full"),
33
        }
34
        return 1;
35
    };
36
    assert program.externalFixups.len == 0;
37
    let size = program.text.len * 4;
38
    let header = try! image::header(image::Layout {
39
        entry: 0x80010000,
40
        code: image::Segment { address: 0x80010000, initialized: size, memory: size },
41
        roData: image::Segment { address: 0, initialized: 0, memory: 0 },
42
        rwData: image::Segment { address: 0x80020000, initialized: 0, memory: 4096 },
43
    });
44
    let fd = unix::openOpts(env.args[2], unix::OpenFlags(*unix::O_WRONLY | *unix::O_CREAT | *unix::O_TRUNC), 420);
45
    assert fd >= 0;
46
    let written = unix::writeAll(fd, &header[..]) and unix::writeAll(fd, @sliceOf(program.text.ptr as *u8, size));
47
    let closed = unix::close(fd) == 0;
48
    assert written and closed;
49
    return 0;
50
}