From ad36df54951d562c6a0e2c59d37c85bd7d3c7b6b Mon Sep 17 00:00:00 2001 From: Monadic Cat Date: Fri, 10 Dec 2021 15:15:59 -0600 Subject: [PATCH 1/4] add support for Arm64Call relocations in cranelift-jit --- cranelift/jit/src/compiled_blob.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/cranelift/jit/src/compiled_blob.rs b/cranelift/jit/src/compiled_blob.rs index f00165dbab..5dfa6d4812 100644 --- a/cranelift/jit/src/compiled_blob.rs +++ b/cranelift/jit/src/compiled_blob.rs @@ -81,6 +81,17 @@ impl CompiledBlob { write_unaligned(at as *mut i32, pcrel) }; } + Reloc::Arm64Call => { + let base = get_address(name); + // The instruction is 32 bits long. + let iptr = at as *mut u32; + let diff = (base as isize) - (at as isize); + // The lower 26 bits of the `bl` instruction form the + // immediate offset argument. + let chop = 32 - 26; + let imm26 = ((diff >> 2) as u32) << chop >> chop; + unsafe { *iptr |= imm26; } + } _ => unimplemented!(), } } From dcb64dc311c0b5b99f15340046807d766a044455 Mon Sep 17 00:00:00 2001 From: Monadic Cat Date: Fri, 10 Dec 2021 16:28:09 -0600 Subject: [PATCH 2/4] assert that offset is in bounds for Arm64Call --- cranelift/jit/src/compiled_blob.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/cranelift/jit/src/compiled_blob.rs b/cranelift/jit/src/compiled_blob.rs index 5dfa6d4812..c6c9ad25b6 100644 --- a/cranelift/jit/src/compiled_blob.rs +++ b/cranelift/jit/src/compiled_blob.rs @@ -85,11 +85,18 @@ impl CompiledBlob { let base = get_address(name); // The instruction is 32 bits long. let iptr = at as *mut u32; - let diff = (base as isize) - (at as isize); + // The offset encoded in the `bl` instruction is the + // number of bytes divided by 4. + let diff = ((base as isize) - (at as isize)) >> 2; + // Sign propagating right shift disposes of the + // included bits, so the result is expected to be + // either all sign bits or 0, depending on if the original + // value was negative or positive. + assert!((diff >> 26 == -1) || (diff >> 26 == 0)); // The lower 26 bits of the `bl` instruction form the // immediate offset argument. let chop = 32 - 26; - let imm26 = ((diff >> 2) as u32) << chop >> chop; + let imm26 = (diff as u32) << chop >> chop; unsafe { *iptr |= imm26; } } _ => unimplemented!(), From b6ade800257ad1f2206ff10d76db1081fc057650 Mon Sep 17 00:00:00 2001 From: Monadic Cat Date: Fri, 10 Dec 2021 16:42:55 -0600 Subject: [PATCH 3/4] use an unaligned read and write on compiled blob --- cranelift/jit/src/compiled_blob.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cranelift/jit/src/compiled_blob.rs b/cranelift/jit/src/compiled_blob.rs index c6c9ad25b6..3e36283d1b 100644 --- a/cranelift/jit/src/compiled_blob.rs +++ b/cranelift/jit/src/compiled_blob.rs @@ -97,7 +97,8 @@ impl CompiledBlob { // immediate offset argument. let chop = 32 - 26; let imm26 = (diff as u32) << chop >> chop; - unsafe { *iptr |= imm26; } + let ins = unsafe { iptr.read_unaligned() } | imm26; + unsafe { iptr.write_unaligned(ins); } } _ => unimplemented!(), } From 0d6688f81a9407a86d0b165fb5cd2c3972905585 Mon Sep 17 00:00:00 2001 From: Monadic Cat Date: Fri, 10 Dec 2021 16:55:03 -0600 Subject: [PATCH 4/4] rustfmt compiled_blob.rs --- cranelift/jit/src/compiled_blob.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cranelift/jit/src/compiled_blob.rs b/cranelift/jit/src/compiled_blob.rs index 3e36283d1b..5af0067422 100644 --- a/cranelift/jit/src/compiled_blob.rs +++ b/cranelift/jit/src/compiled_blob.rs @@ -98,7 +98,9 @@ impl CompiledBlob { let chop = 32 - 26; let imm26 = (diff as u32) << chop >> chop; let ins = unsafe { iptr.read_unaligned() } | imm26; - unsafe { iptr.write_unaligned(ins); } + unsafe { + iptr.write_unaligned(ins); + } } _ => unimplemented!(), }