Skip to content

Commit

Permalink
[FIX][X64] fixing rip relatives (links + printing)
Browse files Browse the repository at this point in the history
  • Loading branch information
Cr0a3 committed Oct 24, 2024
1 parent 10ec8d1 commit 60c4893
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 23 deletions.
5 changes: 3 additions & 2 deletions examples/obj.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::{error::Error, fs::OpenOptions, path::Path};

use object::RelocationEncoding;
use ygen::debug::{DebugLocation, DebugRegistry};
use ygen::{Obj::*, Target::Triple};
use ygen::Target::x64::{instr::*, X64Reg};
Expand Down Expand Up @@ -35,7 +36,7 @@ fn main() -> Result<(), Box<dyn Error>> {

data.extend_from_slice(&X64MCInstr::with2(Mnemonic::Lea, Operand::Reg(X64Reg::Rax), rip_relativ).compile()?);

obj.link( Link { from: "main".into(), to: "string".into(), at: data.len(), addend: -4, special: false });
obj.link( Link { from: "main".into(), to: "string".into(), at: data.len(), addend: -4, special: false, kind: RelocationEncoding::X86Branch });

if cfg!(target_os = "windows") {
data.extend_from_slice(&X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::Rcx), Operand::Reg(X64Reg::Rax)).compile()?);
Expand All @@ -47,7 +48,7 @@ fn main() -> Result<(), Box<dyn Error>> {
debug.add_location(&"main".to_string(), DebugLocation { line: 4, col: 4, epilog: false, prolog: false, adr: data.len() as u64 });
data.extend_from_slice(&X64MCInstr::with1(Mnemonic::Call, Operand::Imm(0)).compile()?); // call printf

obj.link( Link { from: "main".into(), to: "printf".into(), at: data.len(), addend: -4, special: false });
obj.link( Link { from: "main".into(), to: "printf".into(), at: data.len(), addend: -4, special: false, kind: RelocationEncoding::X86Branch });


debug.add_location(&"main".to_string(), DebugLocation { line: 5, col: 4, epilog: false, prolog: false, adr: data.len() as u64 });
Expand Down
1 change: 1 addition & 0 deletions src/IR/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ impl Module {
at: link.at + prev_len - 1,
addend: link.addend,
special: false,
kind: link.kind,
});
}
}
Expand Down
12 changes: 3 additions & 9 deletions src/Obj/wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ pub struct Link {
pub addend: i64,
/// If it is a special relocation (only internal usage)
pub special: bool,
/// the type
pub kind: RelocationEncoding,
}

/// The linkage of the target symbol
Expand Down Expand Up @@ -355,15 +357,7 @@ impl ObjectBuilder {
addend: link.addend + addend,
flags: RelocationFlags::Generic {
kind: RelocationKind::PltRelative,
encoding: {
match &self.triple.arch {
Target::Arch::Aarch64 => RelocationEncoding::AArch64Call,
Target::Arch::Aarch64BE => RelocationEncoding::AArch64Call,
Target::Arch::X86 => RelocationEncoding::X86Branch,
Target::Arch::X86_64 => RelocationEncoding::X86Branch,
_ => RelocationEncoding::Generic,
}
},
encoding: link.kind,
size: 32,
},
})?;
Expand Down
5 changes: 4 additions & 1 deletion src/Target/wasm/asm/instr.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::fmt::Display;

use object::RelocationEncoding;

use crate::CodeGen::MCInstr;

/// A wasm instruction
Expand Down Expand Up @@ -38,7 +40,8 @@ impl WasmMCInstr {
to: target.to_owned(),
at: 0,
addend: -4,
special: true
special: true,
kind: RelocationEncoding::Generic
})))
}

Expand Down
36 changes: 34 additions & 2 deletions src/Target/x64/asm/instr.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::{fmt::Display, ops::{Add, Sub}, str::FromStr};
use iced_x86::{BlockEncoder, BlockEncoderOptions, Code, Instruction, InstructionBlock, MemoryOperand, Register};
use object::RelocationEncoding;

use crate::CodeGen::MCInstr;
use crate::Obj::Link;
Expand Down Expand Up @@ -68,9 +69,21 @@ impl X64MCInstr {

if self.mnemonic == Mnemonic::Link {
if let Some(Operand::LinkDestination(dst, addend)) = &self.op1 {
return Ok((vec![], Some(Link { from: "".into(), to: dst.to_string(), at: 0, addend: *addend, special: false })));
return Ok((vec![], Some(Link {
from: "".into(),
to: dst.to_string(),
at: 0, addend: *addend,
special: false,
kind: RelocationEncoding::X86Branch,
})));
} else if let Some(Operand::BlockLinkDestination(dst, addend)) = &self.op1 {
return Ok((vec![], Some(Link { from: "".into(), to: dst.to_string(), at: 0, addend: *addend, special: true })));
return Ok((vec![], Some(Link {
from: "".into(),
to: dst.to_string(),
at: 0, addend: *addend,
special: true,
kind: RelocationEncoding::Generic,
})));
} else {
return Ok((vec![], None));
}
Expand Down Expand Up @@ -436,6 +449,8 @@ impl X64MCInstr {
} else if op1.is_gr64() {
Instruction::with2::<Register, MemoryOperand>(Code::Lea_r64_m, (*op1).into(), op2.into())?
} else { todo!("{}", self) }
} else if let Some(Operand::RipRelative(_)) = &self.op2 {
Instruction::with2::<Register, MemoryOperand>(Code::Lea_r64_m, (*op1).into(), MemoryOperand::with_base_displ(Register::RIP, 7))?
} else { todo!("{}", self) }
} else { todo!("{}", self) }
},
Expand Down Expand Up @@ -1088,6 +1103,7 @@ impl X64MCInstr {
at: 0,
addend: *addend,
special: false,
kind: RelocationEncoding::X86Branch,
})
} else if let Some(Operand::BlockLinkDestination(target, addend)) = &self.op1 {
links = Some(Link {
Expand All @@ -1096,6 +1112,16 @@ impl X64MCInstr {
at: 0,
addend: *addend,
special: true,
kind: RelocationEncoding::Generic,
})
} else if let Some(Operand::RipRelative(target)) = &self.op2 {
links = Some(Link {
from: "".into(),
to: target.to_owned(),
at: 0,
addend: -4,
special: false,
kind: RelocationEncoding::X86RipRelative,
})
}

Expand Down Expand Up @@ -1279,6 +1305,7 @@ impl X64MCInstr {
Operand::Imm(num) => profile.markup(&num.to_string(), ColorClass::Value),
Operand::Reg(reg) => profile.markup(&reg.to_string(), ColorClass::Var),
Operand::Mem(mem) => profile.markup(&format!("{}", mem), ColorClass::Var),
Operand::RipRelative(rip) => profile.markup(&format!("[rel {}]", rip), ColorClass::Var),
Operand::LinkDestination(_, _) => "".to_string(),
Operand::BlockLinkDestination(_, _) => "".to_string(),
Operand::Debug(s) => s.to_string(),
Expand All @@ -1287,6 +1314,7 @@ impl X64MCInstr {
string.push_str(&format!(", {}", match op2 {
Operand::Imm(num) => profile.markup(&format!("{}", num.to_string()), ColorClass::Value),
Operand::Reg(reg) => profile.markup(&format!(", {}", reg.to_string()), ColorClass::Var),
Operand::RipRelative(rip) => profile.markup(&format!("[rel {}]", rip), ColorClass::Var),
Operand::Mem(mem) => profile.markup(&format!("{}", mem), ColorClass::Var),
Operand::LinkDestination(_, _) => "".to_string(),
Operand::BlockLinkDestination(_, _) => "".to_string(),
Expand Down Expand Up @@ -1595,6 +1623,8 @@ pub enum Operand {
BlockLinkDestination(String, i64),
/// For debugging
Debug(String),
/// A rip relative
RipRelative(String),
}

impl PartialEq for Operand {
Expand All @@ -1605,6 +1635,7 @@ impl PartialEq for Operand {
(Self::Mem(l0), Self::Mem(r0)) => l0 == r0,
(Self::LinkDestination(l0, l1), Self::LinkDestination(r0, r1)) => l0 == r0 && l1 == r1,
(Self::Debug(l0), Self::Debug(r0)) => l0 == r0,
(Self::RipRelative(l0), Self::RipRelative(r0)) => l0 == r0,
_ => false,
}
}
Expand All @@ -1619,6 +1650,7 @@ impl Display for Operand {
Operand::LinkDestination(target, _) => target.to_string(),
Operand::BlockLinkDestination(target, _) =>target.to_string(),
Operand::Debug(s) => s.to_string(),
Operand::RipRelative(target) => format!("[rel {}]", target),
})
}
}
Expand Down
13 changes: 4 additions & 9 deletions src/Target/x64/lower/adr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,10 @@ pub(crate) fn x64_lower_adr_load(sink: &mut Vec<X64MCInstr>, instr: &MachineInst

let out = out.into();

sink.push(
X64MCInstr::with2(Mnemonic::Lea, Operand::Reg(X64Reg::Rax.sub_ty(instr.meta)), Operand::Mem(MemOp { base: None, index: None, scale: 1, displ: 7, rip: true })).into()
);
sink.push(
X64MCInstr::with1(Mnemonic::Link, Operand::LinkDestination(symbol.to_string(), -4)).into()
);
sink.push(
X64MCInstr::with2(Mnemonic::Mov, out, Operand::Reg(X64Reg::Rax.sub_ty(instr.meta))).into()
);
sink.extend_from_slice(&[
X64MCInstr::with2(Mnemonic::Lea, Operand::Reg(X64Reg::Rax.sub_ty(instr.meta)), Operand::RipRelative(symbol.to_owned())),
X64MCInstr::with2(Mnemonic::Mov, out, Operand::Reg(X64Reg::Rax.sub_ty(instr.meta)))
]);
}

pub(crate) fn x64_lower_adrm(sink: &mut Vec<X64MCInstr>, instr: &MachineInstr) {
Expand Down

0 comments on commit 60c4893

Please sign in to comment.