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}