dynasm\arch\aarch64/
mod.rs

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
use syn::parse;
use proc_macro_error2::emit_error;

mod ast;
mod parser;
mod matching;
mod compiler;
mod aarch64data;
mod encoding_helpers;
mod debug;

use crate::State;
use crate::common::{Size, Stmt, Jump};
use crate::arch::Arch;
use self::aarch64data::Relocation;

#[cfg(feature = "dynasm_opmap")]
pub use debug::create_opmap;
#[cfg(feature = "dynasm_extract")]
pub use debug::extract_opmap;

struct Context<'a, 'b: 'a> {
    pub state: &'a mut State<'b>
}

#[derive(Clone, Debug, Default)]
pub struct ArchAarch64 {

}

impl Arch for ArchAarch64 {
    fn set_features(&mut self, features: &[syn::Ident]) {
        if let Some(feature) = features.first() {
            emit_error!(feature, "Arch aarch64 has no known features");
        }
    }

    fn handle_static_reloc(&self, stmts: &mut Vec<Stmt>, reloc: Jump, size: Size) {
        let span = reloc.span();

        let relocation = match size {
            Size::BYTE => Relocation::LITERAL8,
            Size::B_2 => Relocation::LITERAL16,
            Size::B_4 => Relocation::LITERAL32,
            Size::B_8 => Relocation::LITERAL64,
            _ => {
                emit_error!(span, "Relocation of unsupported size for the current target architecture");
                return;
            }
        };

        stmts.push(Stmt::Const(0, size));
        stmts.push(reloc.encode(size.in_bytes(), size.in_bytes(), &[relocation.to_id()]));
    }

    fn default_align(&self) -> u8 {
        0
    }

    fn compile_instruction(&self, state: &mut State, input: parse::ParseStream) -> parse::Result<()> {
        let mut ctx = Context {
            state
        };

        let (instruction, args) = parser::parse_instruction(&mut ctx, input)?;
        let span = instruction.span;

        let match_data = match matching::match_instruction(&mut ctx, &instruction, args) {
            Err(None) => return Ok(()),
            Err(Some(e)) => {
                emit_error!(span, e);
                return Ok(())
            }
            Ok(m) => m
        };

        match compiler::compile_instruction(&mut ctx, match_data) {
            Err(None) => return Ok(()),
            Err(Some(e)) => {
                emit_error!(span, e);
                return Ok(())
            }
            Ok(()) => ()
        }

        Ok(())
    }
}