use elf-utilities for ELF64
parent
21096384d8
commit
951358daac
@ -1,13 +1,13 @@
|
|||||||
mod lazy;
|
mod lazy;
|
||||||
|
mod output;
|
||||||
mod relocatable;
|
mod relocatable;
|
||||||
mod section;
|
mod section;
|
||||||
mod storage;
|
mod storage;
|
||||||
mod symbol;
|
mod symbol;
|
||||||
mod output;
|
|
||||||
|
|
||||||
pub use lazy::*;
|
pub use lazy::*;
|
||||||
|
pub use output::*;
|
||||||
pub use relocatable::*;
|
pub use relocatable::*;
|
||||||
pub use section::*;
|
pub use section::*;
|
||||||
pub use storage::*;
|
pub use storage::*;
|
||||||
pub use symbol::*;
|
pub use symbol::*;
|
||||||
pub use output::*;
|
|
@ -1,110 +0,0 @@
|
|||||||
use std::iter::Cloned;
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
common::{Section, SectionInfo, SectionIterResult},
|
|
||||||
error::Error,
|
|
||||||
};
|
|
||||||
use xmas_elf::{
|
|
||||||
sections::{SectionData, SectionHeader, SectionIter as ElfIter, ShType},
|
|
||||||
ElfFile,
|
|
||||||
};
|
|
||||||
|
|
||||||
impl<'data> Section<'data> {
|
|
||||||
pub fn iterate(
|
|
||||||
elf: &'data ElfFile<'data>,
|
|
||||||
iter: &mut ElfIter<'data, 'data>,
|
|
||||||
) -> SectionIterResult<'data> {
|
|
||||||
if let Some(h) = iter.next() {
|
|
||||||
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(&elf).unwrap_or("null");
|
|
||||||
match section_data_to_iterator(elf, h) {
|
|
||||||
Ok(i) => Section::from_name(s_name, &h, Some(Box::new(i))),
|
|
||||||
Err(err) => SectionIterResult::Err(err),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// bss
|
|
||||||
ShType::NoBits => {
|
|
||||||
let si = SectionInfo {
|
|
||||||
size: h.size(),
|
|
||||||
data: None,
|
|
||||||
offset: h.offset(),
|
|
||||||
};
|
|
||||||
let s = Section::Bss(si);
|
|
||||||
SectionIterResult::Ok(s)
|
|
||||||
}
|
|
||||||
_ => SectionIterResult::Skip,
|
|
||||||
},
|
|
||||||
Err(err) => SectionIterResult::Err(err),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
SectionIterResult::None
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_name(
|
|
||||||
name: &str,
|
|
||||||
header: &SectionHeader,
|
|
||||||
data: Option<Box<dyn Iterator<Item = u8> + 'data>>,
|
|
||||||
) -> SectionIterResult<'data> {
|
|
||||||
if name.starts_with(".text") {
|
|
||||||
if header.size() == 0 {
|
|
||||||
return SectionIterResult::Skip; // empty texts
|
|
||||||
}
|
|
||||||
let iter = match data {
|
|
||||||
Some(i) => i,
|
|
||||||
None => return SectionIterResult::Err(Error::MissingSectionData(".text")),
|
|
||||||
};
|
|
||||||
let si = SectionInfo {
|
|
||||||
size: header.size(),
|
|
||||||
data: Some(iter),
|
|
||||||
offset: header.offset(),
|
|
||||||
};
|
|
||||||
return SectionIterResult::Ok(Section::Text(si));
|
|
||||||
} else if name.starts_with(".rodata") || name.starts_with(".data") {
|
|
||||||
if header.size() == 0 {
|
|
||||||
return SectionIterResult::Skip; // empty data
|
|
||||||
}
|
|
||||||
let iter = match data {
|
|
||||||
Some(i) => i,
|
|
||||||
None => return SectionIterResult::Err(Error::MissingSectionData(".data")),
|
|
||||||
};
|
|
||||||
let si = SectionInfo {
|
|
||||||
size: header.size(),
|
|
||||||
data: Some(iter),
|
|
||||||
offset: header.offset(),
|
|
||||||
};
|
|
||||||
return SectionIterResult::Ok(Section::Data(si));
|
|
||||||
} else if name.starts_with(".bss") {
|
|
||||||
let si = SectionInfo {
|
|
||||||
size: header.size(),
|
|
||||||
data: None,
|
|
||||||
offset: header.offset(),
|
|
||||||
};
|
|
||||||
return SectionIterResult::Ok(Section::Bss(si));
|
|
||||||
}
|
|
||||||
|
|
||||||
SectionIterResult::Skip
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn section_data_to_iterator<'file>(
|
|
||||||
elf: &'file ElfFile,
|
|
||||||
header: SectionHeader<'file>,
|
|
||||||
) -> Result<Cloned<std::slice::Iter<'file, u8>>, Error> {
|
|
||||||
let data = header
|
|
||||||
.get_data(&elf)
|
|
||||||
.map_err(|e| Error::MissingSectionData(e))?;
|
|
||||||
|
|
||||||
match data {
|
|
||||||
SectionData::Empty => Ok(([]).iter().cloned()),
|
|
||||||
SectionData::Undefined(bytes) => {
|
|
||||||
let iter = bytes.iter().cloned();
|
|
||||||
Ok(iter)
|
|
||||||
}
|
|
||||||
_ => Err(Error::InvalidSectionData), // TODO: more context needed
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
use crate::{
|
|
||||||
common::{Section, SectionIterResult},
|
|
||||||
error::Error,
|
|
||||||
};
|
|
||||||
use xmas_elf::sections::SectionIter as ElfIter;
|
|
||||||
use xmas_elf::ElfFile;
|
|
||||||
|
|
||||||
pub struct SectionIter<'data> {
|
|
||||||
pub elf: &'data ElfFile<'data>,
|
|
||||||
pub iter: ElfIter<'data, 'data>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'data> Iterator for SectionIter<'data> {
|
|
||||||
type Item = Result<Section<'data>, Error>;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
match Section::iterate(&self.elf, &mut self.iter) {
|
|
||||||
SectionIterResult::Err(err) => Some(Err(err)),
|
|
||||||
SectionIterResult::None => None,
|
|
||||||
SectionIterResult::Skip => self.next(),
|
|
||||||
SectionIterResult::Ok(r) => Some(Ok(r)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue