Line data Source code
1 : use lief_ffi as ffi;
2 : use std::sync::Arc;
3 :
4 0 : #[derive(Clone)]
5 : /// This structure exposes the different elements that can be configured to assemble
6 : /// code.
7 : pub struct AssemblerConfig {
8 : /// Default configuration
9 : pub dialect: Dialect,
10 :
11 : /// This attribute aims to store a function for resolving symbols in the assembly listing.
12 : ///
13 : /// For instance, given this assembly code:
14 : ///
15 : /// ```text
16 : /// 0x1000: mov rdi, rbx
17 : /// 0x1003: call _my_function
18 : /// ```
19 : ///
20 : /// The function `_my_function` will remain undefined unless we return its address
21 : /// in a callback defined in this attribute [`AssemblerConfig::symbol_resolver`]:
22 : ///
23 : /// ```rust
24 : /// let mut config = AssemblerConfig::default();
25 : ///
26 : /// let resolver = Arc::new(move |symbol: &str| {
27 : /// return Some(0x4000);
28 : /// });
29 : ///
30 : /// config.symbol_resolver = Some(resolver);
31 : /// ```
32 : pub symbol_resolver: Option<Arc<dyn Fn(&str) -> Option<u64> + Send + Sync + 'static>>
33 : }
34 :
35 : impl Default for AssemblerConfig {
36 0 : fn default() -> AssemblerConfig {
37 0 : AssemblerConfig {
38 0 : dialect: Dialect::DEFAULT_DIALECT,
39 0 : symbol_resolver: None,
40 0 : }
41 0 : }
42 : }
43 :
44 : impl AssemblerConfig {
45 : #[doc(hidden)]
46 : pub fn into_ffi(&self) -> Box<ffi::AssemblerConfig_r> {
47 0 : if let Some(ref resolver) = self.symbol_resolver {
48 0 : let closure = resolver.clone();
49 0 : ffi::AssemblerConfig_r::new(move |s| closure(s))
50 : } else {
51 0 : ffi::AssemblerConfig_r::new(|_| None)
52 : }
53 0 : }
54 : }
55 :
56 : #[allow(non_camel_case_types)]
57 0 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
58 : /// The different supported dialects
59 : pub enum Dialect {
60 : DEFAULT_DIALECT,
61 :
62 : /// Intel syntax
63 : X86_INTEL,
64 :
65 : /// Intel syntax
66 : X86_ATT,
67 : UNKNOWN(u32),
68 : }
69 :
70 : impl From<u32> for Dialect {
71 0 : fn from(value: u32) -> Self {
72 0 : match value {
73 0 : 0x00000000 => Dialect::DEFAULT_DIALECT,
74 0 : 0x00000001 => Dialect::X86_INTEL,
75 0 : 0x00000002 => Dialect::X86_ATT,
76 0 : _ => Dialect::UNKNOWN(value),
77 :
78 : }
79 0 : }
80 : }
81 :
82 : impl From<Dialect> for u32 {
83 0 : fn from(value: Dialect) -> u32 {
84 0 : match value {
85 0 : Dialect::DEFAULT_DIALECT => 0x00000000,
86 0 : Dialect::X86_INTEL => 0x00000001,
87 0 : Dialect::X86_ATT => 0x00000002,
88 0 : Dialect::UNKNOWN(value) => value,
89 :
90 : }
91 0 : }
92 : }
|