add associated index type

master
Ales Katona 4 years ago
parent 818e0a53f3
commit f9706bd558
Signed by: almindor
GPG Key ID: 2F773149BF38B48F

@ -7,7 +7,7 @@ pub trait Output<R>
where where
R: Relocatable R: Relocatable
{ {
fn process_section(&mut self, section: Section) -> Result<(), Error>; fn process_section(&mut self, section: Section<R::Index>) -> Result<(), Error>;
fn finalize(self, objects: &Vec<R>) -> Result<PathBuf, Error>; fn finalize(self, objects: &Vec<R>) -> Result<PathBuf, Error>;
} }
@ -18,7 +18,7 @@ impl<R> Output<R> for DummyOutput
where where
R: Relocatable R: Relocatable
{ {
fn process_section(&mut self, section: Section) -> Result<(), Error> { fn process_section(&mut self, section: Section<R::Index>) -> Result<(), Error> {
eprintln!("Appending section: {}", section); eprintln!("Appending section: {}", section);
Ok(()) Ok(())
} }

@ -5,13 +5,15 @@ use crate::error::Error;
use super::Section; use super::Section;
pub type BSI<'iter> = Box<dyn Iterator<Item = Result<Section, Error>> + 'iter>; pub type BSI<'iter, I> = Box<dyn Iterator<Item = Result<Section<I>, Error>> + 'iter>;
/// Contains all the needed getters to construct a final /// Contains all the needed getters to construct a final
/// mushed and relocated executable from an object file /// mushed and relocated executable from an object file
pub trait Relocatable: Display + TryFrom<PathBuf, Error = Error> { pub trait Relocatable: Display + TryFrom<PathBuf, Error = Error> {
type Index; // index into the data, e.g. usize
fn origin(&self) -> &Path; // not same as section's path since this one's supposed to be cannonical fn origin(&self) -> &Path; // not same as section's path since this one's supposed to be cannonical
fn sections<'iter>(self: &'iter Self) -> BSI<'iter>; fn sections<'iter>(self: &'iter Self) -> BSI<'iter, Self::Index>;
fn section_data(&self, section_index: usize) -> Result<&[u8], Error>; fn section_data(&self, section_index: Self::Index) -> Result<&[u8], Error>;
} }

@ -5,21 +5,21 @@ use std::{
}; };
#[derive(Clone)] #[derive(Clone)]
pub struct SectionInfo { pub struct SectionInfo<I> {
pub file_size: u64, pub file_size: u64,
pub data_size: u64, pub data_size: u64,
pub data_index: Option<(usize, usize)>, // object/section pub data_index: Option<I>, // some form of indexing to the source data (Relocatable's data)
pub offset: u64, pub offset: u64,
} }
#[derive(Clone)] #[derive(Clone)]
pub enum Section { pub enum Section<I> {
Text(SectionInfo), Text(SectionInfo<I>),
Data(SectionInfo, bool), // readonly bool Data(SectionInfo<I>, bool), // readonly bool
Bss(SectionInfo), Bss(SectionInfo<I>),
} }
impl Section { impl<I> Section<I> {
pub fn file_size(&self) -> Result<u64, Error> { pub fn file_size(&self) -> Result<u64, Error> {
match self { match self {
Section::Text(s) => Ok(s.file_size), Section::Text(s) => Ok(s.file_size),
@ -37,10 +37,10 @@ impl Section {
} }
} }
impl<'data> TryFrom<(&str, SectionInfo)> for Section { impl<'data, I> TryFrom<(&str, SectionInfo<I>)> for Section<I> {
type Error = Error; type Error = Error;
fn try_from(value: (&str, SectionInfo)) -> Result<Self, Self::Error> { fn try_from(value: (&str, SectionInfo<I>)) -> Result<Self, Self::Error> {
if value.0.starts_with(".text") { if value.0.starts_with(".text") {
Ok(Section::Text(value.1)) Ok(Section::Text(value.1))
} else if value.0.starts_with(".rodata") { } else if value.0.starts_with(".rodata") {
@ -55,7 +55,7 @@ impl<'data> TryFrom<(&str, SectionInfo)> for Section {
} }
} }
impl Display for SectionInfo { impl<I> Display for SectionInfo<I> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!( write!(
f, f,
@ -68,7 +68,7 @@ impl Display for SectionInfo {
} }
} }
impl Display for Section { impl<I> Display for Section<I> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self { match self {
Section::Text(s) => writeln!(f, "TEXT {}", s), Section::Text(s) => writeln!(f, "TEXT {}", s),

@ -32,11 +32,13 @@ impl ElfObject {
} }
impl Relocatable for ElfObject { impl Relocatable for ElfObject {
type Index = (usize, usize); // object index, section index
fn origin(&self) -> &Path { fn origin(&self) -> &Path {
&self.origin &self.origin
} }
fn sections<'sections>(self: &'sections Self) -> BSI<'sections> { fn sections<'iter>(self: &'iter Self) -> BSI<'iter, (usize, usize)> {
use elf_utilities::section::{Contents64, Type}; use elf_utilities::section::{Contents64, Type};
let iter = self let iter = self
@ -83,9 +85,9 @@ impl Relocatable for ElfObject {
Box::new(iter) Box::new(iter)
} }
fn section_data(&self, section_index: usize) -> Result<&[u8], Error> { fn section_data(&self, index: (usize, usize)) -> Result<&[u8], Error> {
use elf_utilities::section::Contents64; use elf_utilities::section::Contents64;
let section = &self.elf.sections[section_index]; let section = &self.elf.sections[index.1];
match &section.contents { match &section.contents {
Contents64::Raw(v) => Ok(&v), Contents64::Raw(v) => Ok(&v),

@ -160,7 +160,7 @@ impl ElfOutput {
} }
impl Output<ElfObject> for ElfOutput { impl Output<ElfObject> for ElfOutput {
fn process_section(&mut self, section: Section) -> Result<(), Error> { fn process_section(&mut self, section: Section<(usize, usize)>) -> Result<(), Error> {
self.input_data.append_section(section) self.input_data.append_section(section)
} }

@ -17,14 +17,14 @@ pub enum SegmentType {
const SEGMENT_NAMES: [&str; 4] = [".text", ".rodata", ".data", ".bss"]; const SEGMENT_NAMES: [&str; 4] = [".text", ".rodata", ".data", ".bss"];
pub struct OutputData([Vec<SectionInfo>; 4]); pub struct OutputData([Vec<SectionInfo<(usize, usize)>>; 4]);
impl<'data> OutputData { impl<'data> OutputData {
pub fn new() -> Self { pub fn new() -> Self {
Self([Vec::new(), Vec::new(), Vec::new(), Vec::new()]) Self([Vec::new(), Vec::new(), Vec::new(), Vec::new()])
} }
pub fn append_section(&mut self, section: Section) -> Result<(), Error> { pub fn append_section(&mut self, section: Section<(usize, usize)>) -> Result<(), Error> {
match section { match section {
Section::Text(si) => self.0[SI_TEXT].push(si), Section::Text(si) => self.0[SI_TEXT].push(si),
Section::Data(si, false) => self.0[SI_DATA].push(si), Section::Data(si, false) => self.0[SI_DATA].push(si),
@ -37,7 +37,7 @@ impl<'data> OutputData {
pub fn sections_mut( pub fn sections_mut(
&mut self, &mut self,
) -> impl Iterator<Item = (&'static str, &mut Vec<SectionInfo>)> { ) -> impl Iterator<Item = (&'static str, &mut Vec<SectionInfo<(usize, usize)>>)> {
self.0 self.0
.iter_mut() .iter_mut()
.enumerate() .enumerate()
@ -50,11 +50,11 @@ impl<'data> OutputData {
let data1 = text_iter.filter_map(move |si| match si.data_index { let data1 = text_iter.filter_map(move |si| match si.data_index {
None => None, None => None,
Some(di) => Some(objects[di.0].section_data(di.1)), Some(di) => Some(objects[di.0].section_data(di)),
}); });
let data2 = rodata_iter.filter_map(move |si| match si.data_index { let data2 = rodata_iter.filter_map(move |si| match si.data_index {
None => None, None => None,
Some(di) => Some(objects[di.0].section_data(di.1)), Some(di) => Some(objects[di.0].section_data(di)),
}); });
let iter = data1.chain(data2); let iter = data1.chain(data2);
@ -65,7 +65,7 @@ impl<'data> OutputData {
pub fn data_bytes<'l>(&'l self, objects: &'l Vec<ElfObject>) -> impl Iterator<Item = Result<&'l [u8], Error>> { pub fn data_bytes<'l>(&'l self, objects: &'l Vec<ElfObject>) -> impl Iterator<Item = Result<&'l [u8], Error>> {
let iter = self.0[SI_DATA].iter().filter_map(move |si| match si.data_index { let iter = self.0[SI_DATA].iter().filter_map(move |si| match si.data_index {
None => None, None => None,
Some(di) => Some(objects[di.0].section_data(di.1)), Some(di) => Some(objects[di.0].section_data(di)),
}); });
iter iter

Loading…
Cancel
Save