//! # Relocation computations
//!
//! The following notation is used to describe relocation computations
//! specific to x86_64 ELF.
//!
//!  * A: The addend used to compute the value of the relocatable field.
//!  * B: The base address at which a shared object is loaded into memory
//!       during execution. Generally, a shared object file is built with a
//!       base virtual address of 0. However, the execution address of the
//!       shared object is different.
//!  * G: The offset into the global offset table at which the address of
//!       the relocation entry's symbol resides during execution.
//!  * GOT: The address of the global offset table.
//!  * L: The section offset or address of the procedure linkage table entry
//!       for a symbol.
//!  * P: The section offset or address of the storage unit being relocated,
//!       computed using r_offset.
//!  * S: The value of the symbol whose index resides in the relocation entry.
//!  * Z: The size of the symbol whose index resides in the relocation entry.
//!
//! Below are some common x86_64 relocation computations you might find useful:
//!
//! | Relocation                | Value | Size      | Formula           |
//! |:--------------------------|:------|:----------|:------------------|
//! | `R_X86_64_NONE`           | 0     | NONE      | NONE              |
//! | `R_X86_64_64`             | 1     | 64        | S + A             |
//! | `R_X86_64_PC32`           | 2     | 32        | S + A - P         |
//! | `R_X86_64_GOT32`          | 3     | 32        | G + A             |
//! | `R_X86_64_PLT32`          | 4     | 32        | L + A - P         |
//! | `R_X86_64_COPY`           | 5     | NONE      | NONE              |
//! | `R_X86_64_GLOB_DAT`       | 6     | 64        | S                 |
//! | `R_X86_64_JUMP_SLOT`      | 7     | 64        | S                 |
//! | `R_X86_64_RELATIVE`       | 8     | 64        | B + A             |
//! | `R_X86_64_GOTPCREL`       | 9     | 32        | G + GOT + A - P   |
//! | `R_X86_64_32`             | 10    | 32        | S + A             |
//! | `R_X86_64_32S`            | 11    | 32        | S + A             |
//! | `R_X86_64_16`             | 12    | 16        | S + A             |
//! | `R_X86_64_PC16`           | 13    | 16        | S + A - P         |
//! | `R_X86_64_8`              | 14    | 8         | S + A             |
//! | `R_X86_64_PC8`            | 15    | 8         | S + A - P         |
//! | `R_X86_64_DTPMOD64`       | 16    | 64        |                   |
//! | `R_X86_64_DTPOFF64`       | 17    | 64        |                   |
//! | `R_X86_64_TPOFF64`        | 18    | 64        |                   |
//! | `R_X86_64_TLSGD`          | 19    | 32        |                   |
//! | `R_X86_64_TLSLD`          | 20    | 32        |                   |
//! | `R_X86_64_DTPOFF32`       | 21    | 32        |                   |
//! | `R_X86_64_GOTTPOFF`       | 22    | 32        |                   |
//! | `R_X86_64_TPOFF32`        | 23    | 32        |                   |
//! | `R_X86_64_PC64`           | 24    | 64        | S + A - P         |
//! | `R_X86_64_GOTOFF64`       | 25    | 64        | S + A - GOT       |
//! | `R_X86_64_GOTPC32`        | 26    | 32        | GOT + A - P       |
//! | `R_X86_64_SIZE32`         | 32    | 32        | Z + A             |
//! | `R_X86_64_SIZE64`         | 33    | 64        | Z + A             |
//! | `R_X86_64_GOTPC32_TLSDESC`| 34    | 32        |                   |
//! | `R_X86_64_TLSDESC_CALL`   | 35    | NONE      |                   |
//! | `R_X86_64_TLSDESC`        | 36    | 64 × 2    |                   |
//! | `R_X86_64_IRELATIVE`      | 37    | 64        | indirect (B + A)  |
//!
//! TLS information is at http://people.redhat.com/aoliva/writeups/TLS/RFC-TLSDESC-x86.txt
//!
//! `R_X86_64_IRELATIVE` is similar to `R_X86_64_RELATIVE` except that
//! the value used in this relocation is the program address returned by the function,
//! which takes no arguments, at the address of the result of the corresponding
//! `R_X86_64_RELATIVE` relocation.
//!
//! Read more https://docs.oracle.com/cd/E23824_01/html/819-0690/chapter6-54839.html

include!("constants_relocation.rs");

macro_rules! elf_reloc {
    ($size:ident, $isize:ty) => {
        use core::fmt;
        #[cfg(feature = "alloc")]
        use scroll::{Pread, Pwrite, SizeWith};
        #[repr(C)]
        #[derive(Clone, Copy, PartialEq, Default)]
        #[cfg_attr(feature = "alloc", derive(Pread, Pwrite, SizeWith))]
        /// Relocation with an explicit addend
        pub struct Rela {
            /// Address
            pub r_offset: $size,
            /// Relocation type and symbol index
            pub r_info: $size,
            /// Addend
            pub r_addend: $isize,
        }
        #[repr(C)]
        #[derive(Clone, PartialEq, Default)]
        #[cfg_attr(feature = "alloc", derive(Pread, Pwrite, SizeWith))]
        /// Relocation without an addend
        pub struct Rel {
            /// address
            pub r_offset: $size,
            /// relocation type and symbol address
            pub r_info: $size,
        }
        use plain;
        unsafe impl plain::Plain for Rela {}
        unsafe impl plain::Plain for Rel {}

        impl fmt::Debug for Rela {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                let sym = r_sym(self.r_info);
                let typ = r_type(self.r_info);
                f.debug_struct("Rela")
                    .field("r_offset", &format_args!("{:x}", self.r_offset))
                    .field("r_info", &format_args!("{:x}", self.r_info))
                    .field("r_addend", &format_args!("{:x}", self.r_addend))
                    .field("r_typ", &typ)
                    .field("r_sym", &sym)
                    .finish()
            }
        }
        impl fmt::Debug for Rel {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                let sym = r_sym(self.r_info);
                let typ = r_type(self.r_info);
                f.debug_struct("Rel")
                    .field("r_offset", &format_args!("{:x}", self.r_offset))
                    .field("r_info", &format_args!("{:x}", self.r_info))
                    .field("r_typ", &typ)
                    .field("r_sym", &sym)
                    .finish()
            }
        }
    };
}

macro_rules! elf_rela_std_impl {
    ($size:ident, $isize:ty) => {
        if_alloc! {
            use crate::elf::reloc::Reloc;

            use core::slice;

            if_std! {
                use crate::error::Result;

                use std::fs::File;
                use std::io::{Read, Seek};
                use std::io::SeekFrom::Start;
            }

            impl From<Rela> for Reloc {
                fn from(rela: Rela) -> Self {
                    Reloc {
                        r_offset: u64::from(rela.r_offset),
                        r_addend: Some(i64::from(rela.r_addend)),
                        r_sym: r_sym(rela.r_info) as usize,
                        r_type: r_type(rela.r_info),
                    }
                }
            }

            impl From<Rel> for Reloc {
                fn from(rel: Rel) -> Self {
                    Reloc {
                        r_offset: u64::from(rel.r_offset),
                        r_addend: None,
                        r_sym: r_sym(rel.r_info) as usize,
                        r_type: r_type(rel.r_info),
                    }
                }
            }

            impl From<Reloc> for Rela {
                fn from(rela: Reloc) -> Self {
                    let r_info = r_info(rela.r_sym as $size, $size::from(rela.r_type));
                    Rela {
                        r_offset: rela.r_offset as $size,
                        r_info: r_info,
                        r_addend: rela.r_addend.unwrap_or(0) as $isize,
                    }
                }
            }

            impl From<Reloc> for Rel {
                fn from(rel: Reloc) -> Self {
                    let r_info = r_info(rel.r_sym as $size, $size::from(rel.r_type));
                    Rel {
                        r_offset: rel.r_offset as $size,
                        r_info: r_info,
                    }
                }
            }

            /// Gets the rela entries given a rela pointer and the _size_ of the rela section in the binary,
            /// in bytes.
            /// Assumes the pointer is valid and can safely return a slice of memory pointing to the relas because:
            /// 1. `ptr` points to memory received from the kernel (i.e., it loaded the executable), _or_
            /// 2. The binary has already been mmapped (i.e., it's a `SharedObject`), and hence it's safe to return a slice of that memory.
            /// 3. Or if you obtained the pointer in some other lawful manner
            pub unsafe fn from_raw_rela<'a>(ptr: *const Rela, size: usize) -> &'a [Rela] {
                slice::from_raw_parts(ptr, size / SIZEOF_RELA)
            }

            /// Gets the rel entries given a rel pointer and the _size_ of the rel section in the binary,
            /// in bytes.
            /// Assumes the pointer is valid and can safely return a slice of memory pointing to the rels because:
            /// 1. `ptr` points to memory received from the kernel (i.e., it loaded the executable), _or_
            /// 2. The binary has already been mmapped (i.e., it's a `SharedObject`), and hence it's safe to return a slice of that memory.
            /// 3. Or if you obtained the pointer in some other lawful manner
            pub unsafe fn from_raw_rel<'a>(ptr: *const Rel, size: usize) -> &'a [Rel] {
                slice::from_raw_parts(ptr, size / SIZEOF_REL)
            }

            #[cfg(feature = "std")]
            pub fn from_fd(fd: &mut File, offset: usize, size: usize) -> Result<Vec<Rela>> {
                let count = size / SIZEOF_RELA;
                let mut relocs = vec![Rela::default(); count];
                fd.seek(Start(offset as u64))?;
                unsafe {
                    fd.read_exact(plain::as_mut_bytes(&mut *relocs))?;
                }
                Ok(relocs)
            }
        } // end if_alloc
    };
}

pub mod reloc32 {

    pub use crate::elf::reloc::*;

    elf_reloc!(u32, i32);

    pub const SIZEOF_RELA: usize = 4 + 4 + 4;
    pub const SIZEOF_REL: usize = 4 + 4;

    #[inline(always)]
    pub fn r_sym(info: u32) -> u32 {
        info >> 8
    }

    #[inline(always)]
    pub fn r_type(info: u32) -> u32 {
        info & 0xff
    }

    #[inline(always)]
    pub fn r_info(sym: u32, typ: u32) -> u32 {
        (sym << 8) + (typ & 0xff)
    }

    elf_rela_std_impl!(u32, i32);
}

pub mod reloc64 {
    pub use crate::elf::reloc::*;

    elf_reloc!(u64, i64);

    pub const SIZEOF_RELA: usize = 8 + 8 + 8;
    pub const SIZEOF_REL: usize = 8 + 8;

    #[inline(always)]
    pub fn r_sym(info: u64) -> u32 {
        (info >> 32) as u32
    }

    #[inline(always)]
    pub fn r_type(info: u64) -> u32 {
        (info & 0xffff_ffff) as u32
    }

    #[inline(always)]
    pub fn r_info(sym: u64, typ: u64) -> u64 {
        (sym << 32) + typ
    }

    elf_rela_std_impl!(u64, i64);
}

//////////////////////////////
// Generic Reloc
/////////////////////////////
if_alloc! {
    use scroll::{ctx, Pread};
    use scroll::ctx::SizeWith;
    use core::fmt;
    use core::result;
    use crate::container::{Ctx, Container};
    use alloc::vec::Vec;

    #[derive(Clone, Copy, PartialEq, Default)]
    /// A unified ELF relocation structure
    pub struct Reloc {
        /// Address
        pub r_offset: u64,
        /// Addend
        pub r_addend: Option<i64>,
        /// The index into the corresponding symbol table - either dynamic or regular
        pub r_sym: usize,
        /// The relocation type
        pub r_type: u32,
    }

    impl Reloc {
        pub fn size(is_rela: bool, ctx: Ctx) -> usize {
            use scroll::ctx::SizeWith;
            Reloc::size_with(&(is_rela, ctx))
        }
    }

    type RelocCtx = (bool, Ctx);

    impl ctx::SizeWith<RelocCtx> for Reloc {
        fn size_with( &(is_rela, Ctx { container, .. }): &RelocCtx) -> usize {
            match container {
                Container::Little => {
                    if is_rela { reloc32::SIZEOF_RELA } else { reloc32::SIZEOF_REL }
                },
                Container::Big => {
                    if is_rela { reloc64::SIZEOF_RELA } else { reloc64::SIZEOF_REL }
                }
            }
        }
    }

    impl<'a> ctx::TryFromCtx<'a, RelocCtx> for Reloc {
        type Error = crate::error::Error;
        fn try_from_ctx(bytes: &'a [u8], (is_rela, Ctx { container, le }): RelocCtx) -> result::Result<(Self, usize), Self::Error> {
            use scroll::Pread;
            let reloc = match container {
                Container::Little => {
                    if is_rela {
                        (bytes.pread_with::<reloc32::Rela>(0, le)?.into(), reloc32::SIZEOF_RELA)
                    } else {
                        (bytes.pread_with::<reloc32::Rel>(0, le)?.into(), reloc32::SIZEOF_REL)
                    }
                },
                Container::Big => {
                    if is_rela {
                        (bytes.pread_with::<reloc64::Rela>(0, le)?.into(), reloc64::SIZEOF_RELA)
                    } else {
                        (bytes.pread_with::<reloc64::Rel>(0, le)?.into(), reloc64::SIZEOF_REL)
                    }
                }
            };
            Ok(reloc)
        }
    }

    impl ctx::TryIntoCtx<RelocCtx> for Reloc {
        type Error = crate::error::Error;
        /// Writes the relocation into `bytes`
        fn try_into_ctx(self, bytes: &mut [u8], (is_rela, Ctx {container, le}): RelocCtx) -> result::Result<usize, Self::Error> {
            use scroll::Pwrite;
            match container {
                Container::Little => {
                    if is_rela {
                        let rela: reloc32::Rela = self.into();
                        Ok(bytes.pwrite_with(rela, 0, le)?)
                    } else {
                        let rel: reloc32::Rel = self.into();
                        Ok(bytes.pwrite_with(rel, 0, le)?)
                    }
                },
                Container::Big => {
                    if is_rela {
                        let rela: reloc64::Rela = self.into();
                        Ok(bytes.pwrite_with(rela, 0, le)?)
                    } else {
                        let rel: reloc64::Rel = self.into();
                        Ok(bytes.pwrite_with(rel, 0, le)?)
                    }
                },
            }
        }
    }

    impl ctx::IntoCtx<(bool, Ctx)> for Reloc {
        /// Writes the relocation into `bytes`
        fn into_ctx(self, bytes: &mut [u8], ctx: RelocCtx) {
            use scroll::Pwrite;
            bytes.pwrite_with(self, 0, ctx).unwrap();
        }
    }

    impl fmt::Debug for Reloc {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            f.debug_struct("Reloc")
                .field("r_offset", &format_args!("{:x}", self.r_offset))
                .field("r_addend", &format_args!("{:x}", self.r_addend.unwrap_or(0)))
                .field("r_sym", &self.r_sym)
                .field("r_type", &self.r_type)
                .finish()
        }
    }

    #[derive(Default)]
    /// An ELF section containing relocations, allowing lazy iteration over symbols.
    pub struct RelocSection<'a> {
        bytes: &'a [u8],
        count: usize,
        ctx: RelocCtx,
        start: usize,
        end: usize,
    }

    impl<'a> fmt::Debug for RelocSection<'a> {
        fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
            let len = self.bytes.len();
            fmt.debug_struct("RelocSection")
                .field("bytes", &len)
                .field("range", &format!("{:#x}..{:#x}", self.start, self.end))
                .field("count", &self.count)
                .field("Relocations", &self.to_vec())
                .finish()
        }
    }

    impl<'a> RelocSection<'a> {
        #[cfg(feature = "endian_fd")]
        /// Parse a REL or RELA section of size `filesz` from `offset`.
        pub fn parse(bytes: &'a [u8], offset: usize, filesz: usize, is_rela: bool, ctx: Ctx) -> crate::error::Result<RelocSection<'a>> {
            // TODO: better error message when too large (see symtab implementation)
            let bytes = if filesz != 0 {
                bytes.pread_with::<&'a [u8]>(offset, filesz)?
            } else {
                &[]
            };

            Ok(RelocSection {
                bytes: bytes,
                count: filesz / Reloc::size(is_rela, ctx),
                ctx: (is_rela, ctx),
                start: offset,
                end: offset + filesz,
            })
        }

        /// Try to parse a single relocation from the binary, at `index`.
        #[inline]
        pub fn get(&self, index: usize) -> Option<Reloc> {
            if index >= self.count {
                None
            } else {
                Some(self.bytes.pread_with(index * Reloc::size_with(&self.ctx), self.ctx).unwrap())
            }
        }

        /// The number of relocations in the section.
        #[inline]
        pub fn len(&self) -> usize {
            self.count
        }

        /// Returns true if section has no relocations.
        #[inline]
        pub fn is_empty(&self) -> bool {
            self.count == 0
        }

        /// Iterate over all relocations.
        pub fn iter(&self) -> RelocIterator<'a> {
            self.into_iter()
        }

        /// Parse all relocations into a vector.
        pub fn to_vec(&self) -> Vec<Reloc> {
            self.iter().collect()
        }
    }

    impl<'a, 'b> IntoIterator for &'b RelocSection<'a> {
        type Item = <RelocIterator<'a> as Iterator>::Item;
        type IntoIter = RelocIterator<'a>;

        #[inline]
        fn into_iter(self) -> Self::IntoIter {
            RelocIterator {
                bytes: self.bytes,
                offset: 0,
                index: 0,
                count: self.count,
                ctx: self.ctx,
            }
        }
    }

    pub struct RelocIterator<'a> {
        bytes: &'a [u8],
        offset: usize,
        index: usize,
        count: usize,
        ctx: RelocCtx,
    }

    impl<'a> fmt::Debug for RelocIterator<'a> {
        fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
            fmt.debug_struct("RelocIterator")
                .field("bytes", &"<... redacted ...>")
                .field("offset", &self.offset)
                .field("index", &self.index)
                .field("count", &self.count)
                .field("ctx", &self.ctx)
                .finish()
        }
    }

    impl<'a> Iterator for RelocIterator<'a> {
        type Item = Reloc;

        #[inline]
        fn next(&mut self) -> Option<Self::Item> {
            if self.index >= self.count {
                None
            } else {
                self.index += 1;
                Some(self.bytes.gread_with(&mut self.offset, self.ctx).unwrap())
            }
        }
    }

    impl<'a> ExactSizeIterator for RelocIterator<'a> {
        #[inline]
        fn len(&self) -> usize {
            self.count - self.index
        }
    }
} // end if_alloc
