Beispiel #1
0
def assemble(argv=None):
    """Assembles an ELFHex source program into an executable, with the provided
    arguments taken from the command line by default.
    """

    # Parse arguments.
    args = _parse_args(argv)

    # Preprocess source (resolves includes and fragment references).
    preprocessed = elfhex.Preprocessor(elfhex.FileLoader(
        args.include_path)).preprocess(args.input_path,
                                       args.max_fragment_depth)

    # Transform the syntax into a Program instance.
    program = elfhex.Transformer().transform(preprocessed)

    if not args.no_header:
        # Add the ELF header.
        header = elfhex.elf.get_header(args.entry_label)
        if args.header_segment:
            program.prepend_header_segment(header)
        else:
            program.prepend_header_to_first_segment(header)

    # Generate the binary output.
    output = program.render(args.memory_start)

    # Output the resulting blob.
    open(args.output_path, "wb").write(output)
    _set_executable(args.output_path)
    print(f"Assembled. Total size: {len(output)} bytes.")
Beispiel #2
0
def test_preprocessor_incompatiblemetadata():
    files = {
        MAIN_FILE: 'program 3 < 4096 include "other.eh" ' + _segment(""),
        "other.eh": "program 2 < 4096",
    }

    with pytest.raises(elfhex.ElfhexError):
        elfhex.Preprocessor(files).preprocess(MAIN_FILE, 1)

    files = {
        MAIN_FILE: 'program 3 < 4096 include "other.eh" ' + _segment(""),
        "other.eh": "program 3 > 4096",
    }

    with pytest.raises(elfhex.ElfhexError):
        elfhex.Preprocessor(files).preprocess(MAIN_FILE, 1)
Beispiel #3
0
def test_preprocessor_includeonce():
    files = {
        MAIN_FILE: f'{METADATA} include "other.eh" {_segment("")}',
        "other.eh": f'{METADATA} include "{MAIN_FILE}"',
    }

    elfhex.Preprocessor(files).preprocess(MAIN_FILE, 2)
Beispiel #4
0
def test_preprocessor_uniqueref():
    files = {
        MAIN_FILE: METADATA + _segment("@!a() @!a() @a()") + " fragment a() { 00 }"
    }

    output = elfhex.Preprocessor(files).preprocess(MAIN_FILE, 2)

    assert output == _flattened("00 00")
Beispiel #5
0
def test_preprocessor_maxrecursion():
    files = {
        MAIN_FILE: METADATA
        + _segment("@a()")
        + " fragment a() { @b() } fragment b() { @c() } fragment c() { ff }"
    }

    with pytest.raises(elfhex.ElfhexError):
        elfhex.Preprocessor(files).preprocess(MAIN_FILE, 0)
Beispiel #6
0
def test_preprocessor_fragmentsonly():
    files = {
        MAIN_FILE: f'{METADATA} include fragments "other.eh" {_segment("ff @f()")}',
        "other.eh": METADATA + "segment a() { ee } fragment f() { 11 }",
    }

    output = elfhex.Preprocessor(files).preprocess(MAIN_FILE, 2)

    assert output == _flattened("ff 11")
Beispiel #7
0
def test_preprocessor_extendalign():
    files = {
        MAIN_FILE: 'program 3 < 16 include "other.eh" ' + _segment(""),
        "other.eh": "program 3 < 32",
    }

    output = elfhex.Preprocessor(files).preprocess(MAIN_FILE, 1)

    assert output == _flattened("", metadata="program 3 < 32")
Beispiel #8
0
def test_preprocessor_fragments():
    files = {
        MAIN_FILE: METADATA
        + _segment("ff @a(11)")
        + "fragment a(a) { $a @b($a) } fragment b(a) { $a }"
    }

    output = elfhex.Preprocessor(files).preprocess(MAIN_FILE, 3)

    assert output == _flattened("ff 11 11")
Beispiel #9
0
def test_preprocessor_locallabels():
    files = {MAIN_FILE: METADATA + _segment("@a()") + " fragment a() { [__a] }"}

    output = elfhex.Preprocessor(files).preprocess(MAIN_FILE, 2)

    assert output == _flattened("[__0__a]")
Beispiel #10
0
def test_preprocessor_aliases():
    files = {MAIN_FILE: METADATA + _segment("@a()(test)") + " fragment a() { [a] }"}

    output = elfhex.Preprocessor(files).preprocess(MAIN_FILE, 2)

    assert output == _flattened("[test.a]")
Beispiel #11
0
def test_preprocessor_invalidfragmentdepth():
    with pytest.raises(ValueError):
        elfhex.Preprocessor({}).preprocess(MAIN_FILE, -1)
Beispiel #12
0
def test_preprocessor_nofragment():
    files = {MAIN_FILE: METADATA + _segment("@!b()") + " fragment a() { 00 }"}

    with pytest.raises(elfhex.ElfhexError):
        elfhex.Preprocessor(files).preprocess(MAIN_FILE, 2)