]> git.proxmox.com Git - rustc.git/blob - vendor/object-0.27.1/src/read/coff/relocation.rs
New upstream version 1.59.0+dfsg1
[rustc.git] / vendor / object-0.27.1 / src / read / coff / relocation.rs
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;
11
12 /// An iterator over the relocations in a `CoffSection`.
13 pub struct CoffRelocationIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
14 pub(super) file: &'file CoffFile<'data, R>,
15 pub(super) iter: slice::Iter<'data, pe::ImageRelocation>,
16 }
17
18 impl<'data, 'file, R: ReadRef<'data>> Iterator for CoffRelocationIterator<'data, 'file, R> {
19 type Item = (u64, Relocation);
20
21 fn next(&mut self) -> Option<Self::Item> {
22 self.iter.next().map(|relocation| {
23 let (kind, size, addend) = match self.file.header.machine.get(LE) {
24 pe::IMAGE_FILE_MACHINE_ARMNT => match relocation.typ.get(LE) {
25 pe::IMAGE_REL_ARM_ADDR32 => (RelocationKind::Absolute, 32, 0),
26 pe::IMAGE_REL_ARM_SECREL => (RelocationKind::SectionOffset, 32, 0),
27 typ => (RelocationKind::Coff(typ), 0, 0),
28 },
29 pe::IMAGE_FILE_MACHINE_ARM64 => match relocation.typ.get(LE) {
30 pe::IMAGE_REL_ARM64_ADDR32 => (RelocationKind::Absolute, 32, 0),
31 pe::IMAGE_REL_ARM64_SECREL => (RelocationKind::SectionOffset, 32, 0),
32 pe::IMAGE_REL_ARM64_ADDR64 => (RelocationKind::Absolute, 64, 0),
33 typ => (RelocationKind::Coff(typ), 0, 0),
34 },
35 pe::IMAGE_FILE_MACHINE_I386 => match relocation.typ.get(LE) {
36 pe::IMAGE_REL_I386_DIR16 => (RelocationKind::Absolute, 16, 0),
37 pe::IMAGE_REL_I386_REL16 => (RelocationKind::Relative, 16, 0),
38 pe::IMAGE_REL_I386_DIR32 => (RelocationKind::Absolute, 32, 0),
39 pe::IMAGE_REL_I386_DIR32NB => (RelocationKind::ImageOffset, 32, 0),
40 pe::IMAGE_REL_I386_SECTION => (RelocationKind::SectionIndex, 16, 0),
41 pe::IMAGE_REL_I386_SECREL => (RelocationKind::SectionOffset, 32, 0),
42 pe::IMAGE_REL_I386_SECREL7 => (RelocationKind::SectionOffset, 7, 0),
43 pe::IMAGE_REL_I386_REL32 => (RelocationKind::Relative, 32, -4),
44 typ => (RelocationKind::Coff(typ), 0, 0),
45 },
46 pe::IMAGE_FILE_MACHINE_AMD64 => match relocation.typ.get(LE) {
47 pe::IMAGE_REL_AMD64_ADDR64 => (RelocationKind::Absolute, 64, 0),
48 pe::IMAGE_REL_AMD64_ADDR32 => (RelocationKind::Absolute, 32, 0),
49 pe::IMAGE_REL_AMD64_ADDR32NB => (RelocationKind::ImageOffset, 32, 0),
50 pe::IMAGE_REL_AMD64_REL32 => (RelocationKind::Relative, 32, -4),
51 pe::IMAGE_REL_AMD64_REL32_1 => (RelocationKind::Relative, 32, -5),
52 pe::IMAGE_REL_AMD64_REL32_2 => (RelocationKind::Relative, 32, -6),
53 pe::IMAGE_REL_AMD64_REL32_3 => (RelocationKind::Relative, 32, -7),
54 pe::IMAGE_REL_AMD64_REL32_4 => (RelocationKind::Relative, 32, -8),
55 pe::IMAGE_REL_AMD64_REL32_5 => (RelocationKind::Relative, 32, -9),
56 pe::IMAGE_REL_AMD64_SECTION => (RelocationKind::SectionIndex, 16, 0),
57 pe::IMAGE_REL_AMD64_SECREL => (RelocationKind::SectionOffset, 32, 0),
58 pe::IMAGE_REL_AMD64_SECREL7 => (RelocationKind::SectionOffset, 7, 0),
59 typ => (RelocationKind::Coff(typ), 0, 0),
60 },
61 _ => (RelocationKind::Coff(relocation.typ.get(LE)), 0, 0),
62 };
63 let target = RelocationTarget::Symbol(SymbolIndex(
64 relocation.symbol_table_index.get(LE) as usize,
65 ));
66 (
67 u64::from(relocation.virtual_address.get(LE)),
68 Relocation {
69 kind,
70 encoding: RelocationEncoding::Generic,
71 size,
72 target,
73 addend,
74 implicit_addend: true,
75 },
76 )
77 })
78 }
79 }
80
81 impl<'data, 'file, R: ReadRef<'data>> fmt::Debug for CoffRelocationIterator<'data, 'file, R> {
82 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83 f.debug_struct("CoffRelocationIterator").finish()
84 }
85 }