assert that offset is in bounds for Arm64Call
This commit is contained in:
@@ -85,11 +85,18 @@ impl CompiledBlob {
|
|||||||
let base = get_address(name);
|
let base = get_address(name);
|
||||||
// The instruction is 32 bits long.
|
// The instruction is 32 bits long.
|
||||||
let iptr = at as *mut u32;
|
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
|
// The lower 26 bits of the `bl` instruction form the
|
||||||
// immediate offset argument.
|
// immediate offset argument.
|
||||||
let chop = 32 - 26;
|
let chop = 32 - 26;
|
||||||
let imm26 = ((diff >> 2) as u32) << chop >> chop;
|
let imm26 = (diff as u32) << chop >> chop;
|
||||||
unsafe { *iptr |= imm26; }
|
unsafe { *iptr |= imm26; }
|
||||||
}
|
}
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
|
|||||||
Reference in New Issue
Block a user