66 lines
2.8 KiB
Rust
66 lines
2.8 KiB
Rust
//! Utilities for working with Faerie container formats.
|
|
|
|
use cranelift_codegen::binemit::Reloc;
|
|
use target_lexicon::{Architecture, BinaryFormat, Triple};
|
|
|
|
/// An object file format.
|
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
|
pub enum Format {
|
|
/// The ELF object file format.
|
|
ELF,
|
|
/// The Mach-O object file format.
|
|
MachO,
|
|
}
|
|
|
|
/// Translate from a Cranelift `Reloc` to a raw object-file-format-specific
|
|
/// relocation code and relocation-implied addend.
|
|
pub fn raw_relocation(reloc: Reloc, triple: &Triple) -> (u32, i64) {
|
|
match triple.binary_format {
|
|
BinaryFormat::Elf => {
|
|
use goblin::elf;
|
|
(
|
|
match triple.architecture {
|
|
Architecture::X86_64 => {
|
|
match reloc {
|
|
Reloc::Abs4 => elf::reloc::R_X86_64_32,
|
|
Reloc::Abs8 => elf::reloc::R_X86_64_64,
|
|
Reloc::X86PCRel4 | Reloc::X86CallPCRel4 => elf::reloc::R_X86_64_PC32,
|
|
// TODO: Get Cranelift to tell us when we can use
|
|
// R_X86_64_GOTPCRELX/R_X86_64_REX_GOTPCRELX.
|
|
Reloc::X86CallPLTRel4 => elf::reloc::R_X86_64_PLT32,
|
|
Reloc::X86GOTPCRel4 => elf::reloc::R_X86_64_GOTPCREL,
|
|
_ => unimplemented!(),
|
|
}
|
|
}
|
|
_ => unimplemented!("unsupported architecture: {}", triple),
|
|
},
|
|
// Most ELF relocations do not include an implicit addend.
|
|
0,
|
|
)
|
|
}
|
|
BinaryFormat::Macho => {
|
|
use goblin::mach;
|
|
match triple.architecture {
|
|
Architecture::X86_64 => {
|
|
match reloc {
|
|
Reloc::Abs8 => (u32::from(mach::relocation::R_ABS), 0),
|
|
// Mach-O doesn't need us to distinguish between PC-relative calls
|
|
// and PLT calls, but it does need us to distinguish between calls
|
|
// and non-calls. And, it includes the 4-byte addend implicitly.
|
|
Reloc::X86PCRel4 => (u32::from(mach::relocation::X86_64_RELOC_SIGNED), 4),
|
|
Reloc::X86CallPCRel4 | Reloc::X86CallPLTRel4 => {
|
|
(u32::from(mach::relocation::X86_64_RELOC_BRANCH), 4)
|
|
}
|
|
Reloc::X86GOTPCRel4 => {
|
|
(u32::from(mach::relocation::X86_64_RELOC_GOT_LOAD), 4)
|
|
}
|
|
_ => unimplemented!("unsupported mach-o reloc: {}", reloc),
|
|
}
|
|
}
|
|
_ => unimplemented!("unsupported architecture: {}", triple),
|
|
}
|
|
}
|
|
_ => unimplemented!("unsupported format"),
|
|
}
|
|
}
|