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!(),