actually understand this jmp address bug

This commit is contained in:
Folkert 2023-09-16 15:57:03 +02:00
parent 99873f948d
commit a8c8834a3c
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
3 changed files with 20 additions and 43 deletions

View file

@ -1116,27 +1116,8 @@ impl Assembler<AArch64GeneralReg, AArch64FloatReg> for AArch64Assembler {
todo!("jump offsets over 27 bits for AArch64: {:#x}", offset); todo!("jump offsets over 27 bits for AArch64: {:#x}", offset);
} }
buf.len() // on aarch64, jumps are calculated from the start of the jmp instruction
} buf.len() - 4
/// Updates a jump instruction to a new offset and returns the number of bytes written.
fn update_jmp_imm32_offset(
buf: &mut Vec<'_, u8>,
jmp_location: u64,
base_offset: u64,
target_offset: u64,
) {
let old_buf_len = buf.len();
// write the jmp at the back of buf
let jmp_offset = target_offset as i32 - base_offset as i32 + 4;
Self::jmp_imm32(buf, jmp_offset);
// move the new jmp instruction into position
buf.copy_within(old_buf_len.., jmp_location as usize);
// wipe the jmp we created at the end
buf.truncate(old_buf_len)
} }
#[inline(always)] #[inline(always)]
@ -1172,7 +1153,8 @@ impl Assembler<AArch64GeneralReg, AArch64FloatReg> for AArch64Assembler {
todo!("jump offsets over 20 bits for AArch64: {:#x}", offset); todo!("jump offsets over 20 bits for AArch64: {:#x}", offset);
} }
buf.len() // on aarch64, jumps are calculated from the start of the jmp instruction
buf.len() - 4
} }
#[inline(always)] #[inline(always)]

View file

@ -263,7 +263,19 @@ pub trait Assembler<GeneralReg: RegTrait, FloatReg: RegTrait>: Sized + Copy {
jmp_location: u64, jmp_location: u64,
base_offset: u64, base_offset: u64,
target_offset: u64, target_offset: u64,
); ) {
let old_buf_len = buf.len();
// write the jmp at the back of buf
let jmp_offset = target_offset as i32 - base_offset as i32;
Self::jmp_imm32(buf, jmp_offset);
// move the new jmp instruction into position
buf.copy_within(old_buf_len.., jmp_location as usize);
// wipe the jmp we created at the end
buf.truncate(old_buf_len)
}
fn tail_call(buf: &mut Vec<'_, u8>) -> u64; fn tail_call(buf: &mut Vec<'_, u8>) -> u64;

View file

@ -2111,29 +2111,11 @@ impl Assembler<X86_64GeneralReg, X86_64FloatReg> for X86_64Assembler {
#[inline(always)] #[inline(always)]
fn jmp_imm32(buf: &mut Vec<'_, u8>, offset: i32) -> usize { fn jmp_imm32(buf: &mut Vec<'_, u8>, offset: i32) -> usize {
jmp_imm32(buf, offset); jmp_imm32(buf, offset);
// on x86_64, jumps are calculated from the end of the jmp instruction
buf.len() buf.len()
} }
/// Updates a jump instruction to a new offset and returns the number of bytes written.
fn update_jmp_imm32_offset(
buf: &mut Vec<'_, u8>,
jmp_location: u64,
base_offset: u64,
target_offset: u64,
) {
let old_buf_len = buf.len();
// write the jmp at the back of buf
let jmp_offset = target_offset as i32 - base_offset as i32;
Self::jmp_imm32(buf, jmp_offset);
// move the new jmp instruction into position
buf.copy_within(old_buf_len.., jmp_location as usize);
// wipe the jmp we created at the end
buf.truncate(old_buf_len)
}
#[inline(always)] #[inline(always)]
fn tail_call(buf: &mut Vec<'_, u8>) -> u64 { fn tail_call(buf: &mut Vec<'_, u8>) -> u64 {
Self::jmp_imm32(buf, 0); Self::jmp_imm32(buf, 0);
@ -2164,6 +2146,7 @@ impl Assembler<X86_64GeneralReg, X86_64FloatReg> for X86_64Assembler {
jne_imm32(buf, offset); jne_imm32(buf, offset);
// on x86_64, jumps are calculated from the end of the jmp instruction
buf.len() buf.len()
} }