From f9706bd5587429c5f172ced0ea484693e02365c8 Mon Sep 17 00:00:00 2001 From: Ales Katona Date: Mon, 11 Jan 2021 16:04:20 -0800 Subject: [PATCH] add associated index type --- src/common/output.rs | 4 ++-- src/common/relocatable.rs | 8 +++++--- src/common/section.rs | 22 +++++++++++----------- src/formats/elf/object.rs | 8 +++++--- src/formats/elf/output.rs | 2 +- src/formats/elf/segment.rs | 12 ++++++------ 6 files changed, 30 insertions(+), 26 deletions(-) diff --git a/src/common/output.rs b/src/common/output.rs index 9beedb4..e81eb34 100644 --- a/src/common/output.rs +++ b/src/common/output.rs @@ -7,7 +7,7 @@ pub trait Output where R: Relocatable { - fn process_section(&mut self, section: Section) -> Result<(), Error>; + fn process_section(&mut self, section: Section) -> Result<(), Error>; fn finalize(self, objects: &Vec) -> Result; } @@ -18,7 +18,7 @@ impl Output for DummyOutput where R: Relocatable { - fn process_section(&mut self, section: Section) -> Result<(), Error> { + fn process_section(&mut self, section: Section) -> Result<(), Error> { eprintln!("Appending section: {}", section); Ok(()) } diff --git a/src/common/relocatable.rs b/src/common/relocatable.rs index 5b42a11..e520856 100644 --- a/src/common/relocatable.rs +++ b/src/common/relocatable.rs @@ -5,13 +5,15 @@ use crate::error::Error; use super::Section; -pub type BSI<'iter> = Box> + 'iter>; +pub type BSI<'iter, I> = Box, Error>> + 'iter>; /// Contains all the needed getters to construct a final /// mushed and relocated executable from an object file pub trait Relocatable: Display + TryFrom { + 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 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>; } diff --git a/src/common/section.rs b/src/common/section.rs index 6051130..9943e45 100644 --- a/src/common/section.rs +++ b/src/common/section.rs @@ -5,21 +5,21 @@ use std::{ }; #[derive(Clone)] -pub struct SectionInfo { +pub struct SectionInfo { pub file_size: u64, pub data_size: u64, - pub data_index: Option<(usize, usize)>, // object/section + pub data_index: Option, // some form of indexing to the source data (Relocatable's data) pub offset: u64, } #[derive(Clone)] -pub enum Section { - Text(SectionInfo), - Data(SectionInfo, bool), // readonly bool - Bss(SectionInfo), +pub enum Section { + Text(SectionInfo), + Data(SectionInfo, bool), // readonly bool + Bss(SectionInfo), } -impl Section { +impl Section { pub fn file_size(&self) -> Result { match self { 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)> for Section { type Error = Error; - fn try_from(value: (&str, SectionInfo)) -> Result { + fn try_from(value: (&str, SectionInfo)) -> Result { if value.0.starts_with(".text") { Ok(Section::Text(value.1)) } else if value.0.starts_with(".rodata") { @@ -55,7 +55,7 @@ impl<'data> TryFrom<(&str, SectionInfo)> for Section { } } -impl Display for SectionInfo { +impl Display for SectionInfo { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!( f, @@ -68,7 +68,7 @@ impl Display for SectionInfo { } } -impl Display for Section { +impl Display for Section { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { Section::Text(s) => writeln!(f, "TEXT {}", s), diff --git a/src/formats/elf/object.rs b/src/formats/elf/object.rs index 5689a7e..a3f1868 100644 --- a/src/formats/elf/object.rs +++ b/src/formats/elf/object.rs @@ -32,11 +32,13 @@ impl ElfObject { } impl Relocatable for ElfObject { + type Index = (usize, usize); // object index, section index + fn origin(&self) -> &Path { &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}; let iter = self @@ -83,9 +85,9 @@ impl Relocatable for ElfObject { 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; - let section = &self.elf.sections[section_index]; + let section = &self.elf.sections[index.1]; match §ion.contents { Contents64::Raw(v) => Ok(&v), diff --git a/src/formats/elf/output.rs b/src/formats/elf/output.rs index 54b8e1d..af8c6e8 100644 --- a/src/formats/elf/output.rs +++ b/src/formats/elf/output.rs @@ -160,7 +160,7 @@ impl ElfOutput { } impl Output 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) } diff --git a/src/formats/elf/segment.rs b/src/formats/elf/segment.rs index d3087d2..3d7769f 100644 --- a/src/formats/elf/segment.rs +++ b/src/formats/elf/segment.rs @@ -17,14 +17,14 @@ pub enum SegmentType { const SEGMENT_NAMES: [&str; 4] = [".text", ".rodata", ".data", ".bss"]; -pub struct OutputData([Vec; 4]); +pub struct OutputData([Vec>; 4]); impl<'data> OutputData { pub fn new() -> Self { 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 { Section::Text(si) => self.0[SI_TEXT].push(si), Section::Data(si, false) => self.0[SI_DATA].push(si), @@ -37,7 +37,7 @@ impl<'data> OutputData { pub fn sections_mut( &mut self, - ) -> impl Iterator)> { + ) -> impl Iterator>)> { self.0 .iter_mut() .enumerate() @@ -50,11 +50,11 @@ impl<'data> OutputData { let data1 = text_iter.filter_map(move |si| match si.data_index { 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 { 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); @@ -65,7 +65,7 @@ impl<'data> OutputData { pub fn data_bytes<'l>(&'l self, objects: &'l Vec) -> impl Iterator> { let iter = self.0[SI_DATA].iter().filter_map(move |si| match si.data_index { None => None, - Some(di) => Some(objects[di.0].section_data(di.1)), + Some(di) => Some(objects[di.0].section_data(di)), }); iter