diff --git a/src/read/coff/relocation.rs b/src/read/coff/relocation.rs index 41a1fbcc..dfc5b176 100644 --- a/src/read/coff/relocation.rs +++ b/src/read/coff/relocation.rs @@ -34,58 +34,64 @@ impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> Iterator self.iter.next().map(|relocation| { let typ = relocation.typ.get(LE); let flags = RelocationFlags::Coff { typ }; - let (kind, size, addend) = match self.file.header.machine() { + let (kind, encoding, size, addend) = match self.file.header.machine() { pe::IMAGE_FILE_MACHINE_ARMNT => match typ { - pe::IMAGE_REL_ARM_ADDR32 => (RelocationKind::Absolute, 32, 0), - pe::IMAGE_REL_ARM_ADDR32NB => (RelocationKind::ImageOffset, 32, 0), - pe::IMAGE_REL_ARM_REL32 => (RelocationKind::Relative, 32, -4), - pe::IMAGE_REL_ARM_SECTION => (RelocationKind::SectionIndex, 16, 0), - pe::IMAGE_REL_ARM_SECREL => (RelocationKind::SectionOffset, 32, 0), - _ => (RelocationKind::Unknown, 0, 0), + pe::IMAGE_REL_ARM_ADDR32 => (RelocationKind::Absolute, None, 32, 0), + pe::IMAGE_REL_ARM_ADDR32NB => (RelocationKind::ImageOffset, None, 32, 0), + pe::IMAGE_REL_ARM_REL32 => (RelocationKind::Relative, None, 32, -4), + pe::IMAGE_REL_ARM_SECTION => (RelocationKind::SectionIndex, None, 16, 0), + pe::IMAGE_REL_ARM_SECREL => (RelocationKind::SectionOffset, None, 32, 0), + _ => (RelocationKind::Unknown, None, 0, 0), }, pe::IMAGE_FILE_MACHINE_ARM64 | pe::IMAGE_FILE_MACHINE_ARM64EC => match typ { - pe::IMAGE_REL_ARM64_ADDR32 => (RelocationKind::Absolute, 32, 0), - pe::IMAGE_REL_ARM64_ADDR32NB => (RelocationKind::ImageOffset, 32, 0), - pe::IMAGE_REL_ARM64_SECREL => (RelocationKind::SectionOffset, 32, 0), - pe::IMAGE_REL_ARM64_SECTION => (RelocationKind::SectionIndex, 16, 0), - pe::IMAGE_REL_ARM64_ADDR64 => (RelocationKind::Absolute, 64, 0), - pe::IMAGE_REL_ARM64_REL32 => (RelocationKind::Relative, 32, -4), - _ => (RelocationKind::Unknown, 0, 0), + pe::IMAGE_REL_ARM64_ADDR32 => (RelocationKind::Absolute, None, 32, 0), + pe::IMAGE_REL_ARM64_ADDR32NB => (RelocationKind::ImageOffset, None, 32, 0), + pe::IMAGE_REL_ARM64_SECREL => (RelocationKind::SectionOffset, None, 32, 0), + pe::IMAGE_REL_ARM64_SECTION => (RelocationKind::SectionIndex, None, 16, 0), + pe::IMAGE_REL_ARM64_ADDR64 => (RelocationKind::Absolute, None, 64, 0), + pe::IMAGE_REL_ARM64_REL32 => (RelocationKind::Relative, None, 32, -4), + pe::IMAGE_REL_ARM64_BRANCH26 => ( + RelocationKind::Relative, + Some(RelocationEncoding::AArch64Call), + 26, + 0, + ), + _ => (RelocationKind::Unknown, None, 0, 0), }, pe::IMAGE_FILE_MACHINE_I386 => match typ { - pe::IMAGE_REL_I386_DIR16 => (RelocationKind::Absolute, 16, 0), - pe::IMAGE_REL_I386_REL16 => (RelocationKind::Relative, 16, 0), - pe::IMAGE_REL_I386_DIR32 => (RelocationKind::Absolute, 32, 0), - pe::IMAGE_REL_I386_DIR32NB => (RelocationKind::ImageOffset, 32, 0), - pe::IMAGE_REL_I386_SECTION => (RelocationKind::SectionIndex, 16, 0), - pe::IMAGE_REL_I386_SECREL => (RelocationKind::SectionOffset, 32, 0), - pe::IMAGE_REL_I386_SECREL7 => (RelocationKind::SectionOffset, 7, 0), - pe::IMAGE_REL_I386_REL32 => (RelocationKind::Relative, 32, -4), - _ => (RelocationKind::Unknown, 0, 0), + pe::IMAGE_REL_I386_DIR16 => (RelocationKind::Absolute, None, 16, 0), + pe::IMAGE_REL_I386_REL16 => (RelocationKind::Relative, None, 16, 0), + pe::IMAGE_REL_I386_DIR32 => (RelocationKind::Absolute, None, 32, 0), + pe::IMAGE_REL_I386_DIR32NB => (RelocationKind::ImageOffset, None, 32, 0), + pe::IMAGE_REL_I386_SECTION => (RelocationKind::SectionIndex, None, 16, 0), + pe::IMAGE_REL_I386_SECREL => (RelocationKind::SectionOffset, None, 32, 0), + pe::IMAGE_REL_I386_SECREL7 => (RelocationKind::SectionOffset, None, 7, 0), + pe::IMAGE_REL_I386_REL32 => (RelocationKind::Relative, None, 32, -4), + _ => (RelocationKind::Unknown, None, 0, 0), }, pe::IMAGE_FILE_MACHINE_AMD64 => match typ { - pe::IMAGE_REL_AMD64_ADDR64 => (RelocationKind::Absolute, 64, 0), - pe::IMAGE_REL_AMD64_ADDR32 => (RelocationKind::Absolute, 32, 0), - pe::IMAGE_REL_AMD64_ADDR32NB => (RelocationKind::ImageOffset, 32, 0), - pe::IMAGE_REL_AMD64_REL32 => (RelocationKind::Relative, 32, -4), - pe::IMAGE_REL_AMD64_REL32_1 => (RelocationKind::Relative, 32, -5), - pe::IMAGE_REL_AMD64_REL32_2 => (RelocationKind::Relative, 32, -6), - pe::IMAGE_REL_AMD64_REL32_3 => (RelocationKind::Relative, 32, -7), - pe::IMAGE_REL_AMD64_REL32_4 => (RelocationKind::Relative, 32, -8), - pe::IMAGE_REL_AMD64_REL32_5 => (RelocationKind::Relative, 32, -9), - pe::IMAGE_REL_AMD64_SECTION => (RelocationKind::SectionIndex, 16, 0), - pe::IMAGE_REL_AMD64_SECREL => (RelocationKind::SectionOffset, 32, 0), - pe::IMAGE_REL_AMD64_SECREL7 => (RelocationKind::SectionOffset, 7, 0), - _ => (RelocationKind::Unknown, 0, 0), + pe::IMAGE_REL_AMD64_ADDR64 => (RelocationKind::Absolute, None, 64, 0), + pe::IMAGE_REL_AMD64_ADDR32 => (RelocationKind::Absolute, None, 32, 0), + pe::IMAGE_REL_AMD64_ADDR32NB => (RelocationKind::ImageOffset, None, 32, 0), + pe::IMAGE_REL_AMD64_REL32 => (RelocationKind::Relative, None, 32, -4), + pe::IMAGE_REL_AMD64_REL32_1 => (RelocationKind::Relative, None, 32, -5), + pe::IMAGE_REL_AMD64_REL32_2 => (RelocationKind::Relative, None, 32, -6), + pe::IMAGE_REL_AMD64_REL32_3 => (RelocationKind::Relative, None, 32, -7), + pe::IMAGE_REL_AMD64_REL32_4 => (RelocationKind::Relative, None, 32, -8), + pe::IMAGE_REL_AMD64_REL32_5 => (RelocationKind::Relative, None, 32, -9), + pe::IMAGE_REL_AMD64_SECTION => (RelocationKind::SectionIndex, None, 16, 0), + pe::IMAGE_REL_AMD64_SECREL => (RelocationKind::SectionOffset, None, 32, 0), + pe::IMAGE_REL_AMD64_SECREL7 => (RelocationKind::SectionOffset, None, 7, 0), + _ => (RelocationKind::Unknown, None, 0, 0), }, - _ => (RelocationKind::Unknown, 0, 0), + _ => (RelocationKind::Unknown, None, 0, 0), }; let target = RelocationTarget::Symbol(relocation.symbol()); ( u64::from(relocation.virtual_address.get(LE)), Relocation { kind, - encoding: RelocationEncoding::Generic, + encoding: encoding.unwrap_or(RelocationEncoding::Generic), size, target, addend, diff --git a/src/write/coff/object.rs b/src/write/coff/object.rs index 77f1fbb4..017ece64 100644 --- a/src/write/coff/object.rs +++ b/src/write/coff/object.rs @@ -82,7 +82,7 @@ impl<'a> Object<'a> { } pub(crate) fn coff_translate_relocation(&mut self, reloc: &mut Relocation) -> Result<()> { - let (mut kind, _encoding, size) = if let RelocationFlags::Generic { + let (mut kind, encoding, size) = if let RelocationFlags::Generic { kind, encoding, size, @@ -148,13 +148,16 @@ impl<'a> Object<'a> { return Err(Error(format!("unimplemented relocation {:?}", reloc))); } }, - Architecture::Aarch64 => match (kind, size) { - (RelocationKind::Absolute, 32) => coff::IMAGE_REL_ARM64_ADDR32, - (RelocationKind::ImageOffset, 32) => coff::IMAGE_REL_ARM64_ADDR32NB, - (RelocationKind::SectionIndex, 16) => coff::IMAGE_REL_ARM64_SECTION, - (RelocationKind::SectionOffset, 32) => coff::IMAGE_REL_ARM64_SECREL, - (RelocationKind::Absolute, 64) => coff::IMAGE_REL_ARM64_ADDR64, - (RelocationKind::Relative, 32) => coff::IMAGE_REL_ARM64_REL32, + Architecture::Aarch64 => match (kind, encoding, size) { + (RelocationKind::Absolute, _, 32) => coff::IMAGE_REL_ARM64_ADDR32, + (RelocationKind::ImageOffset, _, 32) => coff::IMAGE_REL_ARM64_ADDR32NB, + (RelocationKind::SectionIndex, _, 16) => coff::IMAGE_REL_ARM64_SECTION, + (RelocationKind::SectionOffset, _, 32) => coff::IMAGE_REL_ARM64_SECREL, + (RelocationKind::Absolute, _, 64) => coff::IMAGE_REL_ARM64_ADDR64, + (RelocationKind::Relative, _, 32) => coff::IMAGE_REL_ARM64_REL32, + (RelocationKind::Relative, RelocationEncoding::AArch64Call, 26) => { + coff::IMAGE_REL_ARM64_BRANCH26 + } _ => { return Err(Error(format!("unimplemented relocation {:?}", reloc))); }