Skip to content

Commit

Permalink
coff: support some ARM relocations (#428)
Browse files Browse the repository at this point in the history
  • Loading branch information
carey authored Mar 21, 2022
1 parent 3ff2b10 commit 389c43a
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 2 deletions.
6 changes: 6 additions & 0 deletions src/pe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1277,6 +1277,8 @@ pub const IMAGE_REL_ARM_GPREL12: u16 = 0x0006;
pub const IMAGE_REL_ARM_GPREL7: u16 = 0x0007;
pub const IMAGE_REL_ARM_BLX24: u16 = 0x0008;
pub const IMAGE_REL_ARM_BLX11: u16 = 0x0009;
/// 32-bit relative address from byte following reloc
pub const IMAGE_REL_ARM_REL32: u16 = 0x000A;
/// Section table index
pub const IMAGE_REL_ARM_SECTION: u16 = 0x000E;
/// Offset within section
Expand Down Expand Up @@ -1348,6 +1350,10 @@ pub const IMAGE_REL_ARM64_SECTION: u16 = 0x000D;
pub const IMAGE_REL_ARM64_ADDR64: u16 = 0x000E;
/// 19 bit offset << 2 & sign ext. for conditional B
pub const IMAGE_REL_ARM64_BRANCH19: u16 = 0x000F;
/// TBZ/TBNZ
pub const IMAGE_REL_ARM64_BRANCH14: u16 = 0x0010;
/// 32-bit relative address from byte following reloc
pub const IMAGE_REL_ARM64_REL32: u16 = 0x0011;

//
// x64 relocations
Expand Down
6 changes: 6 additions & 0 deletions src/read/coff/relocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,19 @@ impl<'data, 'file, R: ReadRef<'data>> Iterator for CoffRelocationIterator<'data,
let (kind, size, addend) = match self.file.header.machine.get(LE) {
pe::IMAGE_FILE_MACHINE_ARMNT => match relocation.typ.get(LE) {
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),
typ => (RelocationKind::Coff(typ), 0, 0),
},
pe::IMAGE_FILE_MACHINE_ARM64 => match relocation.typ.get(LE) {
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),
typ => (RelocationKind::Coff(typ), 0, 0),
},
pe::IMAGE_FILE_MACHINE_I386 => match relocation.typ.get(LE) {
Expand Down
28 changes: 26 additions & 2 deletions src/write/coff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,10 @@ impl<'a> Object<'a> {
}

let constant = match self.architecture {
Architecture::I386 => match relocation.kind {
Architecture::I386 | Architecture::Arm | Architecture::Aarch64 => match relocation.kind
{
RelocationKind::Relative => {
// IMAGE_REL_I386_REL32
// IMAGE_REL_I386_REL32, IMAGE_REL_ARM_REL32, IMAGE_REL_ARM64_REL32
relocation.addend + 4
}
_ => relocation.addend,
Expand Down Expand Up @@ -523,6 +524,29 @@ impl<'a> Object<'a> {
return Err(Error(format!("unimplemented relocation {:?}", reloc)));
}
},
Architecture::Arm => match (reloc.kind, reloc.size, reloc.addend) {
(RelocationKind::Absolute, 32, 0) => coff::IMAGE_REL_ARM_ADDR32,
(RelocationKind::ImageOffset, 32, 0) => coff::IMAGE_REL_ARM_ADDR32NB,
(RelocationKind::Relative, 32, -4) => coff::IMAGE_REL_ARM_REL32,
(RelocationKind::SectionIndex, 16, 0) => coff::IMAGE_REL_ARM_SECTION,
(RelocationKind::SectionOffset, 32, 0) => coff::IMAGE_REL_ARM_SECREL,
(RelocationKind::Coff(x), _, _) => x,
_ => {
return Err(Error(format!("unimplemented relocation {:?}", reloc)));
}
},
Architecture::Aarch64 => match (reloc.kind, reloc.size, reloc.addend) {
(RelocationKind::Absolute, 32, 0) => coff::IMAGE_REL_ARM64_ADDR32,
(RelocationKind::ImageOffset, 32, 0) => coff::IMAGE_REL_ARM64_ADDR32NB,
(RelocationKind::SectionIndex, 16, 0) => coff::IMAGE_REL_ARM64_SECTION,
(RelocationKind::SectionOffset, 32, 0) => coff::IMAGE_REL_ARM64_SECREL,
(RelocationKind::Absolute, 64, 0) => coff::IMAGE_REL_ARM64_ADDR64,
(RelocationKind::Relative, 32, -4) => coff::IMAGE_REL_ARM64_REL32,
(RelocationKind::Coff(x), _, _) => x,
_ => {
return Err(Error(format!("unimplemented relocation {:?}", reloc)));
}
},
_ => {
return Err(Error(format!(
"unimplemented architecture {:?}",
Expand Down

0 comments on commit 389c43a

Please sign in to comment.