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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// This file is part of assembler. It is subject to the license terms in the COPYRIGHT file found in the top-level directory of this distribution and at https://raw.githubusercontent.com/lemonrock/assembler/master/COPYRIGHT. No part of assembler, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the COPYRIGHT file.
// Copyright © 2018 The developers of assembler. See the COPYRIGHT file in the top-level directory of this distribution and at https://raw.githubusercontent.com/lemonrock/assembler/master/COPYRIGHT.


#![allow(non_snake_case)]
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![deny(missing_docs)]
#![deny(unreachable_patterns)]
#![feature(core_intrinsics)]


//! #assembler
//!
//! This is a new code base to efficiently assemble 64-bit x86 (AMD64 long mode) machine code at runtime.
//!
//! Instructions are emitted by using the mnemonic-like methods on the `InstructionStream`.
//! These are designed to work with Rust's release build optimizations to compile down to just a sequence of byte stores to memory.
//!
//! In addition, labels are supported; use of short (8-bit) labelled jumps is supported, and, where possible, are used.
//!
//! ## Example Usage
//!
//! ```
//! extern crate assembler;
//!
//! use ::assembler::*;
//! use ::assembler::mnemonic_parameter_types::BranchHint;
//! use ::assembler::mnemonic_parameter_types::Label;
//! use ::assembler::mnemonic_parameter_types::memory_operands::*;
//! use ::assembler::mnemonic_parameter_types::immediates::*;
//! use ::assembler::mnemonic_parameter_types::registers::*;
//!
//! fn main()
//! {
//! 	// SOME_LENGTH will be rounded up to the nearest power of two, with a minimum of the page size (4Kb).
//! 	const SOME_LENGTH: usize = 4096;
//! 	let memory_map = ExecutableAnonymousMemoryMap::new(SOME_LENGTH).unwrap();
//!
//! 	const SOME_LIKELY_NUMBER_OF_LABELS: usize = 512;
//!		let instruction_stream = memory_map.instruction_stream(SOME_LIKELY_NUMBER_OF_LABELS);
//!
//! 	instruction_stream.mov_...();
//!
//! 	let label = instruction_stream.create_and_attach_label();
//!
//! 	instruction_stream.jmp_Label(label)?;
//!
//! 	let function_pointer = instruction_stream.nullary_function::<()>():
//!
//! 	instruction_stream.finish();
//!
//! 	function_pointer();
//! }
//!
//! ```


extern crate libc;
#[macro_use] extern crate likely;


use self::mnemonic_parameter_types::*;
use self::mnemonic_parameter_types::immediates::*;
use self::mnemonic_parameter_types::memory::*;
use self::mnemonic_parameter_types::memory_offsets::*;
use self::mnemonic_parameter_types::registers::*;
use self::mnemonic_parameter_types::relative_addresses::*;
use ::libc::*;
use ::std::alloc::alloc;
use ::std::alloc::realloc;
use ::std::alloc::dealloc;
use ::std::alloc::Layout;
use ::std::error::Error;
use ::std::fmt;
use ::std::fmt::Display;
use ::std::fmt::Formatter;
use ::std::io;
use ::std::mem::align_of;
use ::std::mem::size_of;
use ::std::mem::transmute;
use ::std::ops::Add;
use ::std::ops::AddAssign;
use ::std::ops::BitAnd;
use ::std::ops::BitAndAssign;
use ::std::ops::BitOr;
use ::std::ops::BitOrAssign;
use ::std::ops::BitXor;
use ::std::ops::BitXorAssign;
use ::std::ops::Div;
use ::std::ops::DivAssign;
use ::std::ops::Mul;
use ::std::ops::MulAssign;
use ::std::ops::Neg;
use ::std::ops::Not;
use ::std::ops::Rem;
use ::std::ops::RemAssign;
use ::std::ops::Shl;
use ::std::ops::ShlAssign;
use ::std::ops::Shr;
use ::std::ops::ShrAssign;
use ::std::ops::Sub;
use ::std::ops::SubAssign;
use ::std::ptr::copy_nonoverlapping;
use ::std::ptr::NonNull;
use ::std::ptr::null_mut;
use ::std::slice::from_raw_parts;


/// Mnemonic parameter types.
pub mod mnemonic_parameter_types;

#[cfg(test)]
mod tests;


include!("ByteEmitter.rs");
include!("Displacement.rs");
include!("ExecutableAnonymousMemoryMap.rs");
include!("ExecutableAnonymousMemoryMapCreationError.rs");
include!("InstructionPointer.rs");
include!("InstructionPointerValidity.rs");
include!("InstructionStream.rs");
include!("InstructionStreamHints.rs");
include!("LabelledLocations.rs");
include!("NearJmpResult.rs");
include!("ShortJmpResult.rs");