pub fn perform_relocations(
    code: *mut u8,
    code_rx: *const u8,
    relocs: &[AsmReloc],
    get_address: impl Fn(&RelocTarget) -> *const u8,
    get_got_entry: impl Fn(&RelocTarget) -> *const u8,
    get_plt_entry: impl Fn(&RelocTarget) -> *const u8,
)Expand description
A generic implementation of relocation resolving.
ยงNOTE
Very simple and incomplete. At the moment only Abs4, Abs8, X86 and RISC-V GOT relocations are supported.
Examples found in repository?
examples/reloc.rs (lines 48-55)
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}