use super::{ElfReader, IntoElfReader};
use crate::{Result, os::RawFile};
use alloc::{
string::{String, ToString},
vec::Vec,
};
#[derive(Debug)]
pub struct ElfBinary<'bytes> {
name: String,
bytes: &'bytes [u8],
}
impl<'bytes> ElfBinary<'bytes> {
pub fn new(name: &str, bytes: &'bytes [u8]) -> Self {
Self {
name: name.to_string(),
bytes,
}
}
}
impl<'bytes> ElfReader for ElfBinary<'bytes> {
fn file_name(&self) -> &str {
&self.name
}
fn read(&mut self, buf: &mut [u8], offset: usize) -> crate::Result<()> {
buf.copy_from_slice(&self.bytes[offset..offset + buf.len()]);
Ok(())
}
fn as_fd(&self) -> Option<isize> {
None
}
}
pub struct ElfFile {
inner: RawFile,
}
impl ElfFile {
pub unsafe fn from_owned_fd(path: &str, raw_fd: i32) -> Self {
ElfFile {
inner: RawFile::from_owned_fd(path, raw_fd),
}
}
pub fn from_path(path: impl AsRef<str>) -> Result<Self> {
let path = path.as_ref();
#[cfg(feature = "log")]
log::debug!("Opening ELF file: {}", path);
let inner = RawFile::from_path(path)?;
Ok(ElfFile { inner })
}
}
impl ElfReader for ElfFile {
fn file_name(&self) -> &str {
self.inner.file_name()
}
fn read(&mut self, buf: &mut [u8], offset: usize) -> Result<()> {
self.inner.read(buf, offset)
}
fn as_fd(&self) -> Option<isize> {
self.inner.as_fd()
}
}
impl<'a> ElfReader for &'a [u8] {
fn file_name(&self) -> &str {
"<memory>"
}
fn read(&mut self, buf: &mut [u8], offset: usize) -> Result<()> {
if offset + buf.len() > self.len() {
return Err(crate::Error::Io {
msg: "read offset out of bounds".into(),
});
}
buf.copy_from_slice(&self[offset..offset + buf.len()]);
Ok(())
}
fn as_fd(&self) -> Option<isize> {
None
}
}
impl<'a> IntoElfReader<'a> for &'a str {
type Reader = ElfFile;
fn into_reader(self) -> Result<Self::Reader> {
ElfFile::from_path(self)
}
}
impl<'a> IntoElfReader<'a> for String {
type Reader = ElfFile;
fn into_reader(self) -> Result<Self::Reader> {
ElfFile::from_path(&self)
}
}
impl<'a> IntoElfReader<'a> for &'a [u8] {
type Reader = ElfBinary<'a>;
fn into_reader(self) -> Result<Self::Reader> {
Ok(ElfBinary::new("<memory>", self))
}
}
impl<'a> IntoElfReader<'a> for &'a Vec<u8> {
type Reader = ElfBinary<'a>;
fn into_reader(self) -> Result<Self::Reader> {
Ok(ElfBinary::new("<memory>", self.as_slice()))
}
}
impl<'a> IntoElfReader<'a> for ElfFile {
type Reader = ElfFile;
fn into_reader(self) -> Result<Self::Reader> {
Ok(self)
}
}
impl<'a, 'b> IntoElfReader<'a> for ElfBinary<'b>
where
'b: 'a,
{
type Reader = ElfBinary<'b>;
fn into_reader(self) -> Result<Self::Reader> {
Ok(self)
}
}