add xmas-elf support together with elf-utils
parent
951358daac
commit
0e1c83bbed
@ -1,3 +1,5 @@
|
||||
mod elf;
|
||||
mod xelf;
|
||||
|
||||
pub use elf::*;
|
||||
pub use xelf::*;
|
||||
|
@ -0,0 +1,26 @@
|
||||
use crate::common::{Lazy, Symbol};
|
||||
use crate::error::Error;
|
||||
use crate::linker::Linker;
|
||||
use xmas_elf::ElfFile;
|
||||
|
||||
mod object;
|
||||
|
||||
pub use object::XElfObject;
|
||||
|
||||
impl Linker<'_> {
|
||||
// shortcut to avoid turbofish
|
||||
pub fn xelf() -> Self {
|
||||
Self::new(Vec::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'data> Lazy<&'data str, ElfFile<'data>> for Symbol<'data> {
|
||||
fn value(&self, src: &ElfFile<'data>) -> Result<&'data str, Error> {
|
||||
src.get_string(self.index)
|
||||
.map_err(|e| Error::MissingSectionData(e))
|
||||
}
|
||||
|
||||
fn resolved(&self) -> bool {
|
||||
self.str_ref.is_some()
|
||||
}
|
||||
}
|
@ -0,0 +1,113 @@
|
||||
use std::{
|
||||
convert::TryFrom,
|
||||
fmt::Display,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use crate::common::{Relocatable, Section, SectionInfo, Storage};
|
||||
use crate::{common::BSI, error::Error};
|
||||
use xmas_elf::{ElfFile, sections::{SectionData, SectionHeader}};
|
||||
use xmas_elf::{header::Type as ElfType, sections::ShType};
|
||||
|
||||
pub struct XElfObject<'data> {
|
||||
origin: PathBuf,
|
||||
elf: ElfFile<'data>,
|
||||
}
|
||||
|
||||
impl<'data> XElfObject<'data> {
|
||||
pub fn new(storage: &'data mut Storage) -> Result<Self, Error> {
|
||||
let origin = storage.origin()?;
|
||||
let elf = ElfFile::new(storage.bytes()?).map_err(|_| Error::InvalidObjectType(0))?;
|
||||
|
||||
is_relocatable(&elf)?;
|
||||
let result = XElfObject { origin, elf };
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn data(&self, h: &SectionHeader<'data>) -> Result<std::slice::Iter<'data, u8>, Error> {
|
||||
match h.get_data(&self.elf) {
|
||||
Ok(SectionData::Undefined(ba)) => Ok(ba.iter()),
|
||||
Ok(_) => Err(Error::InvalidSectionData),
|
||||
Err(_) => Err(Error::InvalidSectionData),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Relocatable for XElfObject<'_> {
|
||||
fn origin(&self) -> &Path {
|
||||
&self.origin
|
||||
}
|
||||
|
||||
fn sections(&self) -> BSI<'_> {
|
||||
let iter = self.elf.section_iter().filter_map(move |h| {
|
||||
let h_result = h.get_type().map_err(|e| Error::MissingSectionHeader(e));
|
||||
return match h_result {
|
||||
Ok(h_type) => match h_type {
|
||||
// text, [ro]data
|
||||
ShType::ProgBits => {
|
||||
let s_name = h.get_name(&self.elf).unwrap_or("null");
|
||||
if h.size() > 0 {
|
||||
match self.data(&h) {
|
||||
Ok(data_iter) => {
|
||||
let si = SectionInfo {
|
||||
size: h.size(),
|
||||
data: Some(Box::new(data_iter.copied())),
|
||||
offset: h.offset(),
|
||||
};
|
||||
|
||||
match Section::try_from((s_name, si)) {
|
||||
Ok(s) => Some(Ok(s)),
|
||||
Err(Error::InvalidSectionName) => None, // skip
|
||||
Err(err) => Some(Err(err)),
|
||||
}
|
||||
}
|
||||
Err(err) => Some(Err(err)),
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
// bss
|
||||
ShType::NoBits => Some(Ok(Section::Bss(SectionInfo {
|
||||
size: h.size(),
|
||||
data: None,
|
||||
offset: h.offset(),
|
||||
}))),
|
||||
_ => None,
|
||||
},
|
||||
Err(err) => Some(Err(err)),
|
||||
};
|
||||
});
|
||||
|
||||
Box::new(iter)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for XElfObject<'_> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"==={:?}===\n>Symbols:\n{}\n>Sections:\n",
|
||||
self.origin().file_name().unwrap(),
|
||||
"TODO"
|
||||
)?;
|
||||
|
||||
for section in self.sections() {
|
||||
let u = section.unwrap();
|
||||
write!(f, "{}", u)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn is_relocatable(elf: &ElfFile) -> Result<(), Error> {
|
||||
let raw_type = elf.header.pt2.type_();
|
||||
let elf_type: ElfType = raw_type.as_type();
|
||||
if elf_type != ElfType::Relocatable {
|
||||
return Err(Error::InvalidObjectType(raw_type.0.into()));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in New Issue