#[cfg(feature = "std")]
pub trait ElfRela {
fn r_offset(&self) -> u64;
fn r_info(&self) -> u64;
fn r_addend(&self) -> i64;
}
macro_rules! elf_rela {
($size:ident, $typ:ty) => {
#[repr(C)]
#[derive(Clone, Copy, PartialEq, Default)]
pub struct Rela {
pub r_offset: $size,
pub r_info: $size,
pub r_addend: $typ,
}
};
($size:ident) => {
};
}
macro_rules! signed_from_unsigned {
(u32) => {i32};
(u64) => {i64}
}
pub const R_X86_64_NONE: u64 = 0;
pub const R_X86_64_64: u64 = 1;
pub const R_X86_64_PC32: u64 = 2;
pub const R_X86_64_GOT32: u64 = 3;
pub const R_X86_64_PLT32: u64 = 4;
pub const R_X86_64_COPY: u64 = 5;
pub const R_X86_64_GLOB_DAT: u64 = 6;
pub const R_X86_64_JUMP_SLOT: u64 = 7;
pub const R_X86_64_RELATIVE: u64 = 8;
pub const R_X86_64_GOTPCREL: u64 = 9;
pub const R_X86_64_32: u64 = 10;
pub const R_X86_64_32S: u64 = 11;
pub const R_X86_64_16: u64 = 12;
pub const R_X86_64_PC16: u64 = 13;
pub const R_X86_64_8: u64 = 14;
pub const R_X86_64_PC8: u64 = 15;
pub const R_X86_64_DTPMOD64: u64 = 16;
pub const R_X86_64_DTPOFF64: u64 = 17;
pub const R_X86_64_TPOFF64: u64 = 18;
pub const R_X86_64_TLSGD: u64 = 19;
pub const R_X86_64_TLSLD: u64 = 20;
pub const R_X86_64_DTPOFF32: u64 = 21;
pub const R_X86_64_GOTTPOFF: u64 = 22;
pub const R_X86_64_TPOFF32: u64 = 23;
pub const R_X86_64_PC64: u64 = 24;
pub const R_X86_64_GOTOFF64: u64 = 25;
pub const R_X86_64_GOTPC32: u64 = 26;
pub const R_X86_64_GOT64: u64 = 27;
pub const R_X86_64_GOTPCREL64: u64 = 28;
pub const R_X86_64_GOTPC64: u64 = 29;
pub const R_X86_64_GOTPLT64: u64 = 30;
pub const R_X86_64_PLTOFF64: u64 = 31;
pub const R_X86_64_SIZE32: u64 = 32;
pub const R_X86_64_SIZE64: u64 = 33;
pub const R_X86_64_GOTPC32_TLSDESC: u64 = 34;
pub const R_X86_64_TLSDESC_CALL: u64 = 35;
pub const R_X86_64_TLSDESC: u64 = 36;
pub const R_X86_64_IRELATIVE: u64 = 37;
pub const R_X86_64_RELATIVE64: u64 = 38;
pub const R_X86_64_NUM: u64 = 39;
#[inline]
pub fn type_to_str(typ: u64) -> &'static str {
match typ {
R_X86_64_NONE => "NONE",
R_X86_64_64 => "64",
R_X86_64_PC32 => "PC32",
R_X86_64_GOT32 => "GOT32",
R_X86_64_PLT32 => "PLT32",
R_X86_64_COPY => "COPY",
R_X86_64_GLOB_DAT => "GLOB_DAT",
R_X86_64_JUMP_SLOT => "JUMP_SLOT",
R_X86_64_RELATIVE => "RELATIVE",
R_X86_64_GOTPCREL => "GOTPCREL",
R_X86_64_32 => "32",
R_X86_64_32S => "32S",
R_X86_64_16 => "16",
R_X86_64_PC16 => "PC16",
R_X86_64_8 => "8",
R_X86_64_PC8 => "PC8",
R_X86_64_DTPMOD64 => "DTPMOD64",
R_X86_64_DTPOFF64 => "DTPOFF64",
R_X86_64_TPOFF64 => "TPOFF64",
R_X86_64_TLSGD => "TLSGD",
R_X86_64_TLSLD => "TLSLD",
R_X86_64_DTPOFF32 => "DTPOFF32",
R_X86_64_GOTTPOFF => "GOTTPOFF",
R_X86_64_TPOFF32 => "TPOFF32",
R_X86_64_PC64 => "PC64",
R_X86_64_GOTOFF64 => "GOTOFF64",
R_X86_64_GOTPC32 => "GOTPC32",
R_X86_64_GOT64 => "GOT64",
R_X86_64_GOTPCREL64 => "GOTPCREL64",
R_X86_64_GOTPC64 => "GOTPC64",
R_X86_64_GOTPLT64 => "GOTPLT64",
R_X86_64_PLTOFF64 => "PLTOFF64",
R_X86_64_SIZE32 => "SIZE32",
R_X86_64_SIZE64 => "SIZE64",
R_X86_64_GOTPC32_TLSDESC => "GOTPC32_TLSDESC",
R_X86_64_TLSDESC_CALL => "TLSDESC_CALL",
R_X86_64_TLSDESC => "TLSDESC",
R_X86_64_IRELATIVE => "IRELATIVE",
R_X86_64_RELATIVE64 => "RELATIVE64",
_ => "UNKNOWN_RELA_TYPE",
}
}
macro_rules! elf_rela_impure_impl { ($from_endian:item) => {
#[cfg(feature = "std")]
pub use self::impure::*;
#[cfg(feature = "std")]
mod impure {
use super::*;
use core::fmt;
use core::slice;
use std::fs::File;
use std::io::{self, Read, Seek};
use std::io::SeekFrom::Start;
impl ElfRela for Rela {
fn r_offset(&self) -> u64 {
self.r_offset as u64
}
fn r_info(&self) -> u64 {
self.r_offset as u64
}
fn r_addend(&self) -> i64 {
self.r_offset as i64
}
}
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);
write!(f,
"r_offset: {:x} {} @ {} r_addend: {:x}",
self.r_offset,
type_to_str(typ as u64),
sym,
self.r_addend)
}
}
pub unsafe fn from_raw<'a>(ptr: *const Rela, size: usize) -> &'a [Rela] {
slice::from_raw_parts(ptr, size / SIZEOF_RELA)
}
pub fn from_fd(fd: &mut File, offset: usize, size: usize) -> io::Result<Vec<Rela>> {
let count = size / SIZEOF_RELA;
let mut bytes = vec![0u8; size];
try!(fd.seek(Start(offset as u64)));
try!(fd.read(&mut bytes));
let bytes = unsafe { slice::from_raw_parts(bytes.as_ptr() as *mut Rela, count) };
let mut res = Vec::with_capacity(count);
res.extend_from_slice(bytes);
Ok(res)
}
#[cfg(feature = "endian_fd")]
$from_endian
}
};}