pretty_disassembler

Function pretty_disassembler 

Source
pub fn pretty_disassembler<W: Write>(
    out: &mut W,
    bitness: usize,
    data: &[u8],
    address: u64,
) -> Result
Examples found in repository?
examples/reloc.rs (lines 60-65)
10fn main() {
11    let mut buf = CodeBuffer::new();
12    let mut asm = Assembler::new(&mut buf);
13
14    let str_constant = asm.add_constant("Hello, World!\0");
15    let puts_sym = asm
16        .buffer
17        .add_symbol(ExternalName::Symbol("puts".into()), RelocDistance::Far);
18
19    asm.lea64rm(RDI, ptr64_label(str_constant, 0));
20    asm.callm(ptr64_sym(puts_sym, 0));
21    asm.ret();
22
23    let result = buf.finish();
24
25    for reloc in result.relocs() {
26        println!("{:?}", reloc);
27    }
28
29    let mut jit = JitAllocator::new(Default::default());
30
31    // allocate memory for GOT table and for code itself
32    let mut span = jit
33        .alloc(result.data().len() + result.relocs().len() * 8)
34        .unwrap();
35
36    let mut got_addr_rx = std::ptr::null();
37
38    unsafe {
39        jit.write(&mut span, |span| {
40            span.rw()
41                .copy_from_nonoverlapping(result.data().as_ptr(), result.data().len());
42            got_addr_rx = span.rx().add(result.data().len());
43            span.rw()
44                .add(result.data().len())
45                .cast::<usize>()
46                .write(puts as *const u8 as usize);
47            // we only link to one symbol in GOT table, don't bother with anything else...
48            perform_relocations(
49                span.rw(),
50                span.rx(),
51                &result.relocs(),
52                |_| unreachable!(),
53                |_| got_addr_rx,
54                |_| unreachable!(),
55            );
56        })
57        .unwrap();
58
59        let mut out = String::new();
60        pretty_disassembler(
61            &mut out,
62            64,
63            std::slice::from_raw_parts(span.rx(), result.data().len()),
64            span.rx() as _,
65        )
66        .unwrap();
67
68        println!("{}", out);
69        #[cfg(target_arch = "x86_64")]
70        {
71            let f: extern "C" fn() = std::mem::transmute(span.rx());
72
73            f();
74        }
75    }
76}
More examples
Hide additional examples
examples/factorial.rs (line 48)
4fn main() {
5    {
6        use asmkit::core::buffer::CodeBuffer;
7        use asmkit::x86::*;
8        use formatter::pretty_disassembler;
9        let mut buf = CodeBuffer::new();
10        let mut asm = Assembler::new(&mut buf);
11
12        let label = asm.get_label();
13        let fac = asm.get_label();
14
15        asm.bind_label(fac);
16        asm.mov64ri(RAX, imm(1));
17        asm.test64rr(RDI, RDI);
18        asm.jnz(label);
19        asm.ret();
20
21        {
22            asm.bind_label(label);
23            asm.pushr(RBX);
24            asm.mov64rr(RBX, RDI);
25            asm.lea64rm(RDI, ptr64(RDI, -1));
26            asm.call(fac);
27            asm.mov64rr(RDX, RAX);
28            asm.mov64rr(RAX, RBX);
29            asm.imul64rr(RAX, RDX);
30            asm.popr(RBX);
31            asm.ret();
32        }
33
34        let result = buf.finish();
35
36        let mut jit = JitAllocator::new(JitAllocatorOptions::default());
37
38        let mut span = jit
39            .alloc(result.data().len())
40            .expect("failed to allocate code");
41        unsafe {
42            jit.write(&mut span, |span| {
43                span.rw()
44                    .copy_from_nonoverlapping(result.data().as_ptr(), result.data().len());
45            })
46            .unwrap();
47            let mut out = String::new();
48            pretty_disassembler(&mut out, 64, result.data(), span.rx() as _).unwrap();
49            println!("{}", out);
50            #[cfg(target_arch = "x86_64")]
51            {
52                let f: extern "C" fn(u64) -> u64 = std::mem::transmute(span.rx());
53
54                println!("X86 factorial(5) = {:?}", f(5));
55            }
56        }
57    }
58
59    {
60        use asmkit::core::buffer::CodeBuffer;
61        use asmkit::riscv::*;
62        use formatter::pretty_disassembler;
63        let mut buf = CodeBuffer::new();
64        let mut asm = Assembler::new(&mut buf);
65
66        let label = asm.get_label();
67        let fac = asm.get_label();
68        asm.bind_label(fac);
69        asm.bnez(A0, label);
70        asm.addi(A0, ZERO, imm(1));
71        asm.ret();
72        {
73            asm.bind_label(label);
74            asm.addi(SP, SP, imm(-16));
75            asm.sd(SP, RA, imm(8));
76            asm.sd(SP, S0, imm(0));
77            asm.mv(S0, A0);
78            asm.addi(A0, A0, imm(-1));
79
80            asm.call(fac);
81            asm.mul(A0, S0, A0);
82            asm.ld(RA, SP, imm(8));
83            asm.ld(S0, SP, imm(0));
84            asm.addi(SP, SP, imm(16));
85            asm.ret();
86        }
87
88        let result = buf.finish();
89
90        let mut jit = JitAllocator::new(JitAllocatorOptions::default());
91
92        let mut span = jit
93            .alloc(result.data().len())
94            .expect("failed to allocate code");
95        unsafe {
96            jit.write(&mut span, |span| {
97                span.rw()
98                    .copy_from_nonoverlapping(result.data().as_ptr(), result.data().len());
99            })
100            .unwrap(); 
101            
102
103            let mut out = String::new();
104            pretty_disassembler(&mut out, 64, result.data(), span.rx() as _).unwrap();
105            println!("{}", out);
106            #[cfg(target_arch = "riscv64")]
107            {
108                let f: extern "C" fn(u64) -> u64 = std::mem::transmute(span.rx());
109
110                println!("RV64 factorial(5) = {:?}", f(5));
111            }
112        }
113    }
114}