pub(crate) struct Assembler<R: Relocation, const S: usize> {
buffer: ArrayVec<u8, S>,
target: Option<AssemblyOffset>,
phantom: PhantomData<R>,
}
compiler
and (x86-64 or AArch64) only.Expand description
Our own simple replacement for [dynasmrt::Assembler
]
The default assembler in [dynasmrt
] has a ton of features we don’t need,
but more importantly it will panic if it can’t make its memory region
executable. This is a no-go for us, since there is a fallback available.
Our needs are simple: a single un-named label, no relocations, and no modification after finalization. However, we do need to handle runtime mmap errors thoroughly.
Fields§
§buffer: ArrayVec<u8, S>
Temporary fixed capacity buffer for assembling code
target: Option<AssemblyOffset>
Address of the last “target” label, if any
phantom: PhantomData<R>
Relocations are applied immediately and not stored.
Implementations§
Source§impl<R: Relocation, const S: usize> Assembler<R, S>
impl<R: Relocation, const S: usize> Assembler<R, S>
Sourcepub(crate) fn new() -> Self
pub(crate) fn new() -> Self
Make a new assembler with a temporary buffer but no executable buffer.
Sourcepub(crate) fn finalize(&self) -> Result<Executable, CompilerError>
pub(crate) fn finalize(&self) -> Result<Executable, CompilerError>
Return a new Executable
with the code that’s been written so far.
This may fail if we can’t allocate some memory, fill it, and mark
it as executable. For example, a Linux platform with policy to restrict
mprotect
will show runtime errors at this point.
Performance note: Semantically it makes more sense to consume the
Assembler
instance here, passing it by value. This can result in a
memcpy that doesn’t optimize out, which is a dramatic increase to
the memory bandwidth required in compilation. We avoid that extra
copy by only passing a reference.
Trait Implementations§
Source§impl<R: Relocation, const S: usize> DynasmApi for Assembler<R, S>
impl<R: Relocation, const S: usize> DynasmApi for Assembler<R, S>
Source§impl<R: Relocation, const S: usize> DynasmLabelApi for Assembler<R, S>
impl<R: Relocation, const S: usize> DynasmLabelApi for Assembler<R, S>
Source§type Relocation = R
type Relocation = R
Source§fn local_label(&mut self, name: &'static str)
fn local_label(&mut self, name: &'static str)
Source§fn backward_relocation(
&mut self,
name: &'static str,
target_offset: isize,
field_offset: u8,
ref_offset: u8,
kind: R,
)
fn backward_relocation( &mut self, name: &'static str, target_offset: isize, field_offset: u8, ref_offset: u8, kind: R, )
Source§fn global_label(&mut self, _name: &'static str)
fn global_label(&mut self, _name: &'static str)
Source§fn dynamic_label(&mut self, _id: DynamicLabel)
fn dynamic_label(&mut self, _id: DynamicLabel)
Source§fn bare_relocation(
&mut self,
_target: usize,
_field_offset: u8,
_ref_offset: u8,
_kind: R,
)
fn bare_relocation( &mut self, _target: usize, _field_offset: u8, _ref_offset: u8, _kind: R, )
Source§fn global_relocation(
&mut self,
_name: &'static str,
_target_offset: isize,
_field_offset: u8,
_ref_offset: u8,
_kind: R,
)
fn global_relocation( &mut self, _name: &'static str, _target_offset: isize, _field_offset: u8, _ref_offset: u8, _kind: R, )
Source§fn dynamic_relocation(
&mut self,
_id: DynamicLabel,
_target_offset: isize,
_field_offset: u8,
_ref_offset: u8,
_kind: R,
)
fn dynamic_relocation( &mut self, _id: DynamicLabel, _target_offset: isize, _field_offset: u8, _ref_offset: u8, _kind: R, )
Source§fn forward_relocation(
&mut self,
_name: &'static str,
_target_offset: isize,
_field_offset: u8,
_ref_offset: u8,
_kind: R,
)
fn forward_relocation( &mut self, _name: &'static str, _target_offset: isize, _field_offset: u8, _ref_offset: u8, _kind: R, )
§fn forward_reloc(
&mut self,
name: &'static str,
target_offset: isize,
field_offset: u8,
ref_offset: u8,
kind: <Self::Relocation as Relocation>::Encoding,
)
fn forward_reloc( &mut self, name: &'static str, target_offset: isize, field_offset: u8, ref_offset: u8, kind: <Self::Relocation as Relocation>::Encoding, )
§fn backward_reloc(
&mut self,
name: &'static str,
target_offset: isize,
field_offset: u8,
ref_offset: u8,
kind: <Self::Relocation as Relocation>::Encoding,
)
fn backward_reloc( &mut self, name: &'static str, target_offset: isize, field_offset: u8, ref_offset: u8, kind: <Self::Relocation as Relocation>::Encoding, )
§fn global_reloc(
&mut self,
name: &'static str,
target_offset: isize,
field_offset: u8,
ref_offset: u8,
kind: <Self::Relocation as Relocation>::Encoding,
)
fn global_reloc( &mut self, name: &'static str, target_offset: isize, field_offset: u8, ref_offset: u8, kind: <Self::Relocation as Relocation>::Encoding, )
§fn dynamic_reloc(
&mut self,
id: DynamicLabel,
target_offset: isize,
field_offset: u8,
ref_offset: u8,
kind: <Self::Relocation as Relocation>::Encoding,
)
fn dynamic_reloc( &mut self, id: DynamicLabel, target_offset: isize, field_offset: u8, ref_offset: u8, kind: <Self::Relocation as Relocation>::Encoding, )
§fn bare_reloc(
&mut self,
target: usize,
field_offset: u8,
ref_offset: u8,
kind: <Self::Relocation as Relocation>::Encoding,
)
fn bare_reloc( &mut self, target: usize, field_offset: u8, ref_offset: u8, kind: <Self::Relocation as Relocation>::Encoding, )
Source§impl<'a, R: Relocation, const S: usize> Extend<&'a u8> for Assembler<R, S>
impl<'a, R: Relocation, const S: usize> Extend<&'a u8> for Assembler<R, S>
Source§fn extend<T: IntoIterator<Item = &'a u8>>(&mut self, iter: T)
fn extend<T: IntoIterator<Item = &'a u8>>(&mut self, iter: T)
Source§fn extend_one(&mut self, item: A)
fn extend_one(&mut self, item: A)
extend_one
)Source§fn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
extend_one
)Source§impl<R: Relocation, const S: usize> Extend<u8> for Assembler<R, S>
impl<R: Relocation, const S: usize> Extend<u8> for Assembler<R, S>
Source§fn extend<T: IntoIterator<Item = u8>>(&mut self, iter: T)
fn extend<T: IntoIterator<Item = u8>>(&mut self, iter: T)
Source§fn extend_one(&mut self, item: A)
fn extend_one(&mut self, item: A)
extend_one
)Source§fn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
extend_one
)