Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add no_std support again #105

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions plugin/src/serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ pub fn expr_size_of_scale(ty: &syn::Path, value: &TokenTree, size: Size) -> Toke
let size = size.as_literal();

delimited(quote_spanned! { span=>
(::std::mem::size_of::<#ty>() as #size) * #value
(::core::mem::size_of::<#ty>() as #size) * #value
})
}

Expand Down Expand Up @@ -303,17 +303,17 @@ pub fn expr_offset_of(path: &syn::Path, attr: &syn::Ident, size: Size) -> TokenT
let size = size.as_literal();

delimited(quote_spanned! { span=>
::std::mem::offset_of!(#path, #attr) as #size
::core::mem::offset_of!(#path, #attr) as #size
})
}

// returns std::mem::size_of<path>()
// returns core::mem::size_of<path>()
pub fn expr_size_of(path: &syn::Path) -> TokenTree {
// generate a P<Expr> that returns the size of type at path
let span = path.span();

delimited(quote_spanned! { span=>
::std::mem::size_of::<#path>()
::core::mem::size_of::<#path>()
})
}

Expand Down
11 changes: 8 additions & 3 deletions runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ license.workspace = true


[dependencies]
memmap2 = "0.9.5"
byteorder = "1.5.0"
fnv = "1.0.7"
memmap2 = { version = "0.9.5", optional = true }
byteorder = { version = "1.5.0", default-features = false }
fnv = { version = "1.0.7", default-features = false }
dynasm = { version = "=3.0.1", path = "../plugin" }
hashbrown = "0.15.1"

[features]
default = []
std = ["fnv/std", "byteorder/std", "memmap2"]
3 changes: 2 additions & 1 deletion runtime/src/aarch64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
use crate::Register;
use crate::relocations::{Relocation, RelocationSize, RelocationKind, ImpossibleRelocation, fits_signed_bitfield};
use byteorder::{ByteOrder, LittleEndian};
use std::convert::TryFrom;
use core::convert::TryFrom;

/// Relocation implementation for the aarch64 architecture.
#[derive(Debug, Clone)]
Expand Down Expand Up @@ -188,6 +188,7 @@ impl Relocation for Aarch64Relocation {
}

/// An aarch64 Assembler. This is aliased here for backwards compatability.
#[cfg(feature = "std")]
pub type Assembler = crate::Assembler<Aarch64Relocation>;
/// An aarch64 AssemblyModifier. This is aliased here for backwards compatability.
pub type AssemblyModifier<'a> = crate::Modifier<'a, Aarch64Relocation>;
Expand Down
2 changes: 1 addition & 1 deletion runtime/src/cache_control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub fn synchronize_icache(slice: &[u8]) {

#[cfg(target_arch="aarch64")]
mod aarch64 {
use std::arch::asm;
use core::arch::asm;

/// return the cache line sizes as reported by the processor as a tuple of (dcache, icache)
fn get_cacheline_sizes() -> (usize, usize) {
Expand Down
35 changes: 28 additions & 7 deletions runtime/src/components.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,37 @@
//! This module provides several reusable compoments for implementing assemblers

use std::io;
#[cfg(feature = "std")]
use std::collections::hash_map::Entry;
use std::collections::BTreeMap;
use std::sync::{Arc, RwLock, RwLockWriteGuard};
use std::mem;
use alloc::collections::BTreeMap;
#[cfg(feature = "std")]
use alloc::sync::Arc;
use alloc::vec::Vec;
#[cfg(feature = "std")]
use core::mem;

#[cfg(feature = "std")]
use std::io;
#[cfg(feature = "std")]
use std::sync::{RwLock, RwLockWriteGuard};

#[cfg(feature = "std")]
use fnv::FnvHashMap;

#[cfg(not(feature = "std"))]
type FnvHashMap<K, V> = hashbrown::HashMap<K, V, fnv::FnvBuildHasher>;

#[cfg(not(feature = "std"))]
use hashbrown::hash_map::Entry;

use crate::{DynamicLabel, AssemblyOffset, DynasmError, LabelKind, DynasmLabelApi};
use crate::mmap::{ExecutableBuffer, MutableBuffer};
use crate::relocations::{Relocation, RelocationKind, RelocationSize, ImpossibleRelocation};

#[cfg(feature = "std")]
use crate::cache_control;

#[cfg(feature = "std")]
use crate::mmap::{ExecutableBuffer, MutableBuffer};

/// A static label represents either a local label or a global label reference.
///
/// Global labels are unique names, which can be referenced multiple times, but only defined once
Expand Down Expand Up @@ -79,6 +98,7 @@ impl StaticLabel {

/// This struct implements a protection-swapping assembling buffer
#[derive(Debug)]
#[cfg(feature = "std")]
pub struct MemoryManager {
// buffer where the end result is copied into
execbuffer: Arc<RwLock<ExecutableBuffer>>,
Expand All @@ -92,6 +112,7 @@ pub struct MemoryManager {
execbuffer_addr: usize
}

#[cfg(feature = "std")]
impl MemoryManager {
/// Create a new memory manager, with `initial_mmap_size` data allocated
pub fn new(initial_mmap_size: usize) -> io::Result<Self> {
Expand Down Expand Up @@ -333,7 +354,7 @@ impl<R: Relocation> PatchLoc<R> {
/// Returns a range that covers the entire relocation in its assembling buffer
/// `buf_offset` is a value that is subtracted from this range when the buffer you want to slice
/// with this range is only a part of a bigger buffer.
pub fn range(&self, buf_offset: usize) -> std::ops::Range<usize> {
pub fn range(&self, buf_offset: usize) -> core::ops::Range<usize> {
let field_offset = self.location.0 - buf_offset - self.field_offset as usize;
field_offset .. field_offset + self.relocation.size()
}
Expand Down Expand Up @@ -646,7 +667,7 @@ mod tests {
}

fn test_litpool<R: Relocation + Debug>() {
let mut ops = Assembler::<R>::new().unwrap();
let mut ops = VecAssembler::<R>::new(0x0);
let dynamic1 = ops.new_dynamic_label();

let mut pool = components::LitPool::new();
Expand Down
45 changes: 38 additions & 7 deletions runtime/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
#![cfg_attr(not(any(feature = "std", test)), no_std)]
#![warn(missing_docs)]
#![warn(
clippy::alloc_instead_of_core,
clippy::std_instead_of_core,
clippy::std_instead_of_alloc
)]

//! This crate provides runtime support for dynasm-rs. It contains traits that document the interface used by the dynasm proc_macro to generate code,
//! Assemblers that implement these traits, and relocation models for the various supported architectures. Additionally, it also provides the tools
//! to write your own Assemblers using these components.

extern crate alloc;

#[cfg(test)]
extern crate std;

#[cfg(feature = "std")]
pub mod mmap;
pub mod components;
pub mod relocations;
Expand All @@ -30,18 +42,28 @@ pub mod x64;
pub mod x86;
pub mod aarch64;

#[cfg(feature = "std")]
pub use crate::mmap::ExecutableBuffer;
pub use dynasm::{dynasm, dynasm_backwards};

use crate::components::{MemoryManager, LabelRegistry, RelocRegistry, ManagedRelocs, PatchLoc, StaticLabel};
use crate::components::{LabelRegistry, RelocRegistry, ManagedRelocs, PatchLoc, StaticLabel};
#[cfg(feature = "std")]
use crate::components::MemoryManager;
use crate::relocations::Relocation;

use std::hash::Hash;
use std::sync::{Arc, RwLock, RwLockReadGuard};
use core::hash::Hash;
use core::error;
use core::fmt::{self, Debug};
#[cfg(feature = "std")]
use core::mem;
#[cfg(feature = "std")]
use alloc::sync::Arc;
use alloc::vec::Vec;

#[cfg(feature = "std")]
use std::sync::{RwLock, RwLockReadGuard};
#[cfg(feature = "std")]
use std::io;
use std::error;
use std::fmt::{self, Debug};
use std::mem;

/// This macro takes a *const pointer from the source operand, and then casts it to the desired return type.
/// this allows it to be used as an easy shorthand for passing pointers as dynasm immediate arguments.
Expand Down Expand Up @@ -78,12 +100,14 @@ impl DynamicLabel {
/// A read-only shared reference to the executable buffer inside an `Assembler`. By
/// locking it the internal `ExecutableBuffer` can be accessed and executed.
#[derive(Debug, Clone)]
#[cfg(feature = "std")]
pub struct Executor {
execbuffer: Arc<RwLock<ExecutableBuffer>>
}

/// A read-only lockable reference to the internal `ExecutableBuffer` of an `Assembler`.
/// To gain access to this buffer, it must be locked.
#[cfg(feature = "std")]
impl Executor {
/// Gain read-access to the internal `ExecutableBuffer`. While the returned guard
/// is alive, it can be used to read and execute from the `ExecutableBuffer`.
Expand Down Expand Up @@ -458,7 +482,7 @@ impl<R: Relocation> VecAssembler<R> {
pub fn take(&mut self) -> Result<Vec<u8>, DynasmError> {
self.commit()?;
self.labels.clear();
Ok(std::mem::take(&mut self.ops))
Ok(core::mem::take(&mut self.ops))
}

/// Equivalent of take, but instead of allocating a new vector it simply provides a draining iterator over the internal contents.
Expand Down Expand Up @@ -560,6 +584,7 @@ impl<R: Relocation> DynasmLabelApi for VecAssembler<R> {
/// incremental compilation and multithreaded execution with simultaneous compilation.
/// Its implementation guarantees no memory is executable and writable at the same time.
#[derive(Debug)]
#[cfg(feature = "std")]
pub struct Assembler<R: Relocation> {
ops: Vec<u8>,
memory: MemoryManager,
Expand All @@ -569,6 +594,7 @@ pub struct Assembler<R: Relocation> {
error: Option<DynasmError>,
}

#[cfg(feature = "std")]
impl<R: Relocation> Assembler<R> {
/// Create a new, empty assembler, with initial allocation size `page_size`.
pub fn new() -> io::Result<Self> {
Expand Down Expand Up @@ -740,18 +766,21 @@ impl<R: Relocation> Assembler<R> {
}
}

#[cfg(feature = "std")]
impl<R: Relocation> Extend<u8> for Assembler<R> {
fn extend<T>(&mut self, iter: T) where T: IntoIterator<Item=u8> {
self.ops.extend(iter)
}
}

#[cfg(feature = "std")]
impl<'a, R: Relocation> Extend<&'a u8> for Assembler<R> {
fn extend<T>(&mut self, iter: T) where T: IntoIterator<Item=&'a u8> {
self.ops.extend(iter)
}
}

#[cfg(feature = "std")]
impl<R: Relocation> DynasmApi for Assembler<R> {
fn offset(&self) -> AssemblyOffset {
AssemblyOffset(self.memory.committed() + self.ops.len())
Expand All @@ -771,6 +800,7 @@ impl<R: Relocation> DynasmApi for Assembler<R> {
}
}

#[cfg(feature = "std")]
impl<R: Relocation> DynasmLabelApi for Assembler<R> {
type Relocation = R;

Expand Down Expand Up @@ -881,6 +911,7 @@ impl<'a, R: Relocation> Modifier<'a, R> {
}

// encode uncommited relocations. also, invalidate the icache
#[allow(unused)]
fn encode_relocs(&mut self) -> Result<(), DynasmError> {
let buf_addr = self.buffer.as_ptr() as usize;

Expand Down
2 changes: 1 addition & 1 deletion runtime/src/relocations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use byteorder::{ByteOrder, LittleEndian};

use std::convert::TryFrom;
use core::convert::TryFrom;

/// Error returned when encoding a relocation failed
#[derive(Debug)]
Expand Down
3 changes: 2 additions & 1 deletion runtime/src/x64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
use crate::relocations::{Relocation, RelocationSize, RelocationKind, ImpossibleRelocation};
use crate::Register;

use std::hash::Hash;
use core::hash::Hash;


/// Relocation implementation for the x64 architecture.
Expand Down Expand Up @@ -61,6 +61,7 @@ impl Relocation for X64Relocation {
}

/// An x64 Assembler. This is aliased here for backwards compatability.
#[cfg(feature = "std")]
pub type Assembler = crate::Assembler<X64Relocation>;
/// An x64 AssemblyModifier. This is aliased here for backwards compatability.
pub type AssemblyModifier<'a> = crate::Modifier<'a, X64Relocation>;
Expand Down
1 change: 1 addition & 0 deletions runtime/src/x86.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ impl Relocation for X86Relocation {


/// An x86 Assembler. This is aliased here for backwards compatability.
#[cfg(feature = "std")]
pub type Assembler = crate::Assembler<X86Relocation>;
/// An x86 AssemblyModifier. This is aliased here for backwards compatability.
pub type AssemblyModifier<'a> = crate::Modifier<'a, X86Relocation>;
Expand Down
1 change: 1 addition & 0 deletions testing/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ itertools = "0.13.0"

[dependencies.dynasmrt]
path = "../runtime"
features = ["std"]
Loading