| 1 | use alloc::fmt; | 
| 2 | use core::slice; | 
| 3 |  | 
| 4 | use crate::endian::LittleEndian as LE; | 
| 5 | use crate::pe; | 
| 6 | use crate::read::{ | 
| 7 |     ReadRef, Relocation, RelocationEncoding, RelocationKind, RelocationTarget, SymbolIndex, | 
| 8 | }; | 
| 9 |  | 
| 10 | use super::{CoffFile, CoffHeader}; | 
| 11 |  | 
| 12 | /// An iterator for the relocations in a [`CoffBigSection`](super::CoffBigSection). | 
| 13 | pub type CoffBigRelocationIterator<'data, 'file, R = &'data [u8]> = | 
| 14 |     CoffRelocationIterator<'data, 'file, R, pe::AnonObjectHeaderBigobj>; | 
| 15 |  | 
| 16 | /// An iterator for the relocations in a [`CoffSection`](super::CoffSection). | 
| 17 | pub struct CoffRelocationIterator< | 
| 18 |     'data, | 
| 19 |     'file, | 
| 20 |     R: ReadRef<'data> = &'data [u8], | 
| 21 |     Coff: CoffHeader = pe::ImageFileHeader, | 
| 22 | > { | 
| 23 |     pub(super) file: &'file CoffFile<'data, R, Coff>, | 
| 24 |     pub(super) iter: slice::Iter<'data, pe::ImageRelocation>, | 
| 25 | } | 
| 26 |  | 
| 27 | impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> Iterator | 
| 28 |     for CoffRelocationIterator<'data, 'file, R, Coff> | 
| 29 | { | 
| 30 |     type Item = (u64, Relocation); | 
| 31 |  | 
| 32 |     fn next(&mut self) -> Option<Self::Item> { | 
| 33 |         self.iter.next().map(|relocation| { | 
| 34 |             let (kind, size, addend) = match self.file.header.machine() { | 
| 35 |                 pe::IMAGE_FILE_MACHINE_ARMNT => match relocation.typ.get(LE) { | 
| 36 |                     pe::IMAGE_REL_ARM_ADDR32 => (RelocationKind::Absolute, 32, 0), | 
| 37 |                     pe::IMAGE_REL_ARM_ADDR32NB => (RelocationKind::ImageOffset, 32, 0), | 
| 38 |                     pe::IMAGE_REL_ARM_REL32 => (RelocationKind::Relative, 32, -4), | 
| 39 |                     pe::IMAGE_REL_ARM_SECTION => (RelocationKind::SectionIndex, 16, 0), | 
| 40 |                     pe::IMAGE_REL_ARM_SECREL => (RelocationKind::SectionOffset, 32, 0), | 
| 41 |                     typ => (RelocationKind::Coff(typ), 0, 0), | 
| 42 |                 }, | 
| 43 |                 pe::IMAGE_FILE_MACHINE_ARM64 | pe::IMAGE_FILE_MACHINE_ARM64EC => { | 
| 44 |                     match relocation.typ.get(LE) { | 
| 45 |                         pe::IMAGE_REL_ARM64_ADDR32 => (RelocationKind::Absolute, 32, 0), | 
| 46 |                         pe::IMAGE_REL_ARM64_ADDR32NB => (RelocationKind::ImageOffset, 32, 0), | 
| 47 |                         pe::IMAGE_REL_ARM64_SECREL => (RelocationKind::SectionOffset, 32, 0), | 
| 48 |                         pe::IMAGE_REL_ARM64_SECTION => (RelocationKind::SectionIndex, 16, 0), | 
| 49 |                         pe::IMAGE_REL_ARM64_ADDR64 => (RelocationKind::Absolute, 64, 0), | 
| 50 |                         pe::IMAGE_REL_ARM64_REL32 => (RelocationKind::Relative, 32, -4), | 
| 51 |                         typ => (RelocationKind::Coff(typ), 0, 0), | 
| 52 |                     } | 
| 53 |                 } | 
| 54 |                 pe::IMAGE_FILE_MACHINE_I386 => match relocation.typ.get(LE) { | 
| 55 |                     pe::IMAGE_REL_I386_DIR16 => (RelocationKind::Absolute, 16, 0), | 
| 56 |                     pe::IMAGE_REL_I386_REL16 => (RelocationKind::Relative, 16, 0), | 
| 57 |                     pe::IMAGE_REL_I386_DIR32 => (RelocationKind::Absolute, 32, 0), | 
| 58 |                     pe::IMAGE_REL_I386_DIR32NB => (RelocationKind::ImageOffset, 32, 0), | 
| 59 |                     pe::IMAGE_REL_I386_SECTION => (RelocationKind::SectionIndex, 16, 0), | 
| 60 |                     pe::IMAGE_REL_I386_SECREL => (RelocationKind::SectionOffset, 32, 0), | 
| 61 |                     pe::IMAGE_REL_I386_SECREL7 => (RelocationKind::SectionOffset, 7, 0), | 
| 62 |                     pe::IMAGE_REL_I386_REL32 => (RelocationKind::Relative, 32, -4), | 
| 63 |                     typ => (RelocationKind::Coff(typ), 0, 0), | 
| 64 |                 }, | 
| 65 |                 pe::IMAGE_FILE_MACHINE_AMD64 => match relocation.typ.get(LE) { | 
| 66 |                     pe::IMAGE_REL_AMD64_ADDR64 => (RelocationKind::Absolute, 64, 0), | 
| 67 |                     pe::IMAGE_REL_AMD64_ADDR32 => (RelocationKind::Absolute, 32, 0), | 
| 68 |                     pe::IMAGE_REL_AMD64_ADDR32NB => (RelocationKind::ImageOffset, 32, 0), | 
| 69 |                     pe::IMAGE_REL_AMD64_REL32 => (RelocationKind::Relative, 32, -4), | 
| 70 |                     pe::IMAGE_REL_AMD64_REL32_1 => (RelocationKind::Relative, 32, -5), | 
| 71 |                     pe::IMAGE_REL_AMD64_REL32_2 => (RelocationKind::Relative, 32, -6), | 
| 72 |                     pe::IMAGE_REL_AMD64_REL32_3 => (RelocationKind::Relative, 32, -7), | 
| 73 |                     pe::IMAGE_REL_AMD64_REL32_4 => (RelocationKind::Relative, 32, -8), | 
| 74 |                     pe::IMAGE_REL_AMD64_REL32_5 => (RelocationKind::Relative, 32, -9), | 
| 75 |                     pe::IMAGE_REL_AMD64_SECTION => (RelocationKind::SectionIndex, 16, 0), | 
| 76 |                     pe::IMAGE_REL_AMD64_SECREL => (RelocationKind::SectionOffset, 32, 0), | 
| 77 |                     pe::IMAGE_REL_AMD64_SECREL7 => (RelocationKind::SectionOffset, 7, 0), | 
| 78 |                     typ => (RelocationKind::Coff(typ), 0, 0), | 
| 79 |                 }, | 
| 80 |                 _ => (RelocationKind::Coff(relocation.typ.get(LE)), 0, 0), | 
| 81 |             }; | 
| 82 |             let target = RelocationTarget::Symbol(SymbolIndex( | 
| 83 |                 relocation.symbol_table_index.get(LE) as usize, | 
| 84 |             )); | 
| 85 |             ( | 
| 86 |                 u64::from(relocation.virtual_address.get(LE)), | 
| 87 |                 Relocation { | 
| 88 |                     kind, | 
| 89 |                     encoding: RelocationEncoding::Generic, | 
| 90 |                     size, | 
| 91 |                     target, | 
| 92 |                     addend, | 
| 93 |                     implicit_addend: true, | 
| 94 |                 }, | 
| 95 |             ) | 
| 96 |         }) | 
| 97 |     } | 
| 98 | } | 
| 99 |  | 
| 100 | impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> fmt::Debug | 
| 101 |     for CoffRelocationIterator<'data, 'file, R, Coff> | 
| 102 | { | 
| 103 |     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | 
| 104 |         f.debug_struct(name:"CoffRelocationIterator" ).finish() | 
| 105 |     } | 
| 106 | } | 
| 107 |  |