summaryrefslogtreecommitdiffstats
path: root/third_party/rust/goblin/src/pe/relocation.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/rust/goblin/src/pe/relocation.rs
parentInitial commit. (diff)
downloadfirefox-esr-upstream.tar.xz
firefox-esr-upstream.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/goblin/src/pe/relocation.rs')
-rw-r--r--third_party/rust/goblin/src/pe/relocation.rs133
1 files changed, 133 insertions, 0 deletions
diff --git a/third_party/rust/goblin/src/pe/relocation.rs b/third_party/rust/goblin/src/pe/relocation.rs
new file mode 100644
index 0000000000..ab8398ce73
--- /dev/null
+++ b/third_party/rust/goblin/src/pe/relocation.rs
@@ -0,0 +1,133 @@
+use crate::error;
+use scroll::{IOread, IOwrite, Pread, Pwrite, SizeWith};
+
+/// Size of a single COFF relocation.
+pub const COFF_RELOCATION_SIZE: usize = 10;
+
+// x86 relocations.
+
+/// The relocation is ignored.
+pub const IMAGE_REL_I386_ABSOLUTE: u16 = 0x0000;
+/// Not supported.
+pub const IMAGE_REL_I386_DIR16: u16 = 0x0001;
+/// Not supported.
+pub const IMAGE_REL_I386_REL16: u16 = 0x0002;
+/// The target's 32-bit VA.
+pub const IMAGE_REL_I386_DIR32: u16 = 0x0006;
+/// The target's 32-bit RVA.
+pub const IMAGE_REL_I386_DIR32NB: u16 = 0x0007;
+/// Not supported.
+pub const IMAGE_REL_I386_SEG12: u16 = 0x0009;
+/// The 16-bit section index of the section that contains the target.
+///
+/// This is used to support debugging information.
+pub const IMAGE_REL_I386_SECTION: u16 = 0x000A;
+/// The 32-bit offset of the target from the beginning of its section.
+///
+/// This is used to support debugging information and static thread local storage.
+pub const IMAGE_REL_I386_SECREL: u16 = 0x000B;
+/// The CLR token.
+pub const IMAGE_REL_I386_TOKEN: u16 = 0x000C;
+/// A 7-bit offset from the base of the section that contains the target.
+pub const IMAGE_REL_I386_SECREL7: u16 = 0x000D;
+/// The 32-bit relative displacement to the target.
+///
+/// This supports the x86 relative branch and call instructions.
+pub const IMAGE_REL_I386_REL32: u16 = 0x0014;
+
+// x86-64 relocations.
+
+/// The relocation is ignored.
+pub const IMAGE_REL_AMD64_ABSOLUTE: u16 = 0x0000;
+/// The 64-bit VA of the relocation target.
+pub const IMAGE_REL_AMD64_ADDR64: u16 = 0x0001;
+/// The 32-bit VA of the relocation target.
+pub const IMAGE_REL_AMD64_ADDR32: u16 = 0x0002;
+/// The 32-bit address without an image base (RVA).
+pub const IMAGE_REL_AMD64_ADDR32NB: u16 = 0x0003;
+/// The 32-bit relative address from the byte following the relocation.
+pub const IMAGE_REL_AMD64_REL32: u16 = 0x0004;
+/// The 32-bit address relative to byte distance 1 from the relocation.
+pub const IMAGE_REL_AMD64_REL32_1: u16 = 0x0005;
+/// The 32-bit address relative to byte distance 2 from the relocation.
+pub const IMAGE_REL_AMD64_REL32_2: u16 = 0x0006;
+/// The 32-bit address relative to byte distance 3 from the relocation.
+pub const IMAGE_REL_AMD64_REL32_3: u16 = 0x0007;
+/// The 32-bit address relative to byte distance 4 from the relocation.
+pub const IMAGE_REL_AMD64_REL32_4: u16 = 0x0008;
+/// The 32-bit address relative to byte distance 5 from the relocation.
+pub const IMAGE_REL_AMD64_REL32_5: u16 = 0x0009;
+/// The 16-bit section index of the section that contains the target.
+///
+/// This is used to support debugging information.
+pub const IMAGE_REL_AMD64_SECTION: u16 = 0x000A;
+/// The 32-bit offset of the target from the beginning of its section.
+///
+/// This is used to support debugging information and static thread local storage.
+pub const IMAGE_REL_AMD64_SECREL: u16 = 0x000B;
+/// A 7-bit unsigned offset from the base of the section that contains the target.
+pub const IMAGE_REL_AMD64_SECREL7: u16 = 0x000C;
+/// CLR tokens.
+pub const IMAGE_REL_AMD64_TOKEN: u16 = 0x000D;
+/// A 32-bit signed span-dependent value emitted into the object.
+pub const IMAGE_REL_AMD64_SREL32: u16 = 0x000E;
+/// A pair that must immediately follow every span-dependent value.
+pub const IMAGE_REL_AMD64_PAIR: u16 = 0x000F;
+/// A 32-bit signed span-dependent value that is applied at link time.
+pub const IMAGE_REL_AMD64_SSPAN32: u16 = 0x0010;
+
+/// A COFF relocation.
+#[repr(C)]
+#[derive(Debug, Copy, Clone, PartialEq, Default, Pread, Pwrite, IOread, IOwrite, SizeWith)]
+pub struct Relocation {
+ /// The address of the item to which relocation is applied.
+ ///
+ /// This is the offset from the beginning of the section, plus the
+ /// value of the section's `virtual_address` field.
+ pub virtual_address: u32,
+ /// A zero-based index into the symbol table.
+ ///
+ /// This symbol gives the address that is to be used for the relocation. If the specified
+ /// symbol has section storage class, then the symbol's address is the address with the
+ /// first section of the same name.
+ pub symbol_table_index: u32,
+ /// A value that indicates the kind of relocation that should be performed.
+ ///
+ /// Valid relocation types depend on machine type.
+ pub typ: u16,
+}
+
+/// An iterator for COFF relocations.
+#[derive(Default)]
+pub struct Relocations<'a> {
+ offset: usize,
+ relocations: &'a [u8],
+}
+
+impl<'a> Relocations<'a> {
+ /// Parse a COFF relocation table at the given offset.
+ ///
+ /// The offset and number of relocations should be from the COFF section header.
+ pub fn parse(bytes: &'a [u8], offset: usize, number: usize) -> error::Result<Relocations<'a>> {
+ let relocations = bytes.pread_with(offset, number * COFF_RELOCATION_SIZE)?;
+ Ok(Relocations {
+ offset: 0,
+ relocations,
+ })
+ }
+}
+
+impl<'a> Iterator for Relocations<'a> {
+ type Item = Relocation;
+ fn next(&mut self) -> Option<Self::Item> {
+ if self.offset >= self.relocations.len() {
+ None
+ } else {
+ Some(
+ self.relocations
+ .gread_with(&mut self.offset, scroll::LE)
+ .unwrap(),
+ )
+ }
+ }
+}