From 3b3f834a2fee6d474adbecbe696b9d611d29aeac Mon Sep 17 00:00:00 2001 From: Ales Katona Date: Fri, 15 Jan 2021 16:30:47 -0800 Subject: [PATCH] unify DataIndex to specific type --- src/common/output.rs | 2 +- src/common/relocatable.rs | 27 +++++++++++++++++++++------ src/common/section.rs | 22 ++++++++++++---------- src/formats/elf/loadable.rs | 12 ++++++------ src/formats/elf/object.rs | 16 +++++++--------- src/formats/elf/output.rs | 2 +- src/linker.rs | 7 ++----- 7 files changed, 50 insertions(+), 38 deletions(-) diff --git a/src/common/output.rs b/src/common/output.rs index 00f52e7..4d97f8b 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: &[R]) -> Result; } diff --git a/src/common/relocatable.rs b/src/common/relocatable.rs index 0d8e7e3..3f23b38 100644 --- a/src/common/relocatable.rs +++ b/src/common/relocatable.rs @@ -5,18 +5,33 @@ use crate::error::Error; use super::Section; -pub type BSI<'iter, I> = Box, Error>> + 'iter>; +#[derive(Clone, Copy)] +// index into section of given object stored in the linker +pub struct DataIndex { + pub object_index: usize, + pub section_index: usize, +} + +impl DataIndex { + pub fn new(object_index: usize, section_index: usize) -> Self { + DataIndex { object_index, section_index } + } + + pub fn for_object(object_index: usize) -> Self { + DataIndex { object_index, section_index: 0 } + } +} + +pub type BSI<'iter> = Box> + 'iter>; /// Contains all the needed getters to construct a final /// mushed and relocated executable from an object file pub trait Relocatable: Display + Sized { // + TryFrom { - type Index; // index into the data, e.g. usize - - fn new(origin: PathBuf, object_index: usize) -> Result; + fn new(origin: PathBuf, index: DataIndex) -> Result; fn origin(&self) -> &Path; // not same as section's path since this one's supposed to be cannonical - fn sections(&self) -> BSI; + fn sections(&self) -> BSI; - fn section_data(&self, section_index: Self::Index) -> Result<&[u8], Error>; + fn section_data(&self, section_index: DataIndex) -> Result<&[u8], Error>; } diff --git a/src/common/section.rs b/src/common/section.rs index c47a5ad..cae7713 100644 --- a/src/common/section.rs +++ b/src/common/section.rs @@ -4,25 +4,27 @@ use std::{ fmt::{Display, Formatter}, }; +use super::DataIndex; + #[derive(Clone)] -pub struct SectionInfo { +pub struct SectionInfo { pub file_size: u64, pub data_size: u64, - pub data_index: Option, // some form of indexing to the source data (Relocatable's data) + 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<'data, I> TryFrom<(&str, SectionInfo)> for Section { +impl<'data> 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") { @@ -37,7 +39,7 @@ impl<'data, I> TryFrom<(&str, SectionInfo)> for Section { } } -impl Display for SectionInfo { +impl Display for SectionInfo { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!( f, @@ -50,7 +52,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/loadable.rs b/src/formats/elf/loadable.rs index a95bd7b..a0bda9c 100644 --- a/src/formats/elf/loadable.rs +++ b/src/formats/elf/loadable.rs @@ -12,7 +12,7 @@ pub enum SegmentType { Bss, } -type SegmentSections = Vec>; +type SegmentSections = Vec; #[derive(Default)] pub struct Loadable { @@ -22,8 +22,8 @@ pub struct Loadable { bss: SegmentSections, } -impl<'data> Loadable { - pub fn process_section(&mut self, section: Section<(usize, usize)>) -> Result<(), Error> { +impl Loadable { + pub fn process_section(&mut self, section: Section) -> Result<(), Error> { match section { Section::Text(si) => self.text.push(si), Section::Data(si, true) => self.rodata.push(si), @@ -52,11 +52,11 @@ impl<'data> Loadable { let data1 = text_iter.filter_map(move |si| match si.data_index { None => None, - Some(di) => Some(objects[di.0].section_data(di)), + Some(di) => Some(objects[di.object_index].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)), + Some(di) => Some(objects[di.object_index].section_data(di)), }); data1.chain(data2) @@ -68,7 +68,7 @@ impl<'data> Loadable { ) -> impl Iterator> { let iter = self.data.iter().filter_map(move |si| match si.data_index { None => None, - Some(di) => Some(objects[di.0].section_data(di)), + Some(di) => Some(objects[di.object_index].section_data(di)), }); iter diff --git a/src/formats/elf/object.rs b/src/formats/elf/object.rs index 759dbaf..63de474 100644 --- a/src/formats/elf/object.rs +++ b/src/formats/elf/object.rs @@ -4,7 +4,7 @@ use std::{ path::{Path, PathBuf}, }; -use crate::common::{Relocatable, Section, SectionInfo}; +use crate::common::{DataIndex, Relocatable, Section, SectionInfo}; use crate::{common::BSI, error::Error}; use elf_utilities::{file::ELF64, parser::read_elf64}; @@ -41,17 +41,15 @@ impl ElfObject { } impl Relocatable for ElfObject { - type Index = (usize, usize); // object index, section index - - fn new(origin: PathBuf, object_index: usize) -> Result { - ElfObject::new(origin, object_index) + fn new(origin: PathBuf, di: DataIndex) -> Result { + ElfObject::new(origin, di.object_index) } fn origin(&self) -> &Path { &self.origin } - fn sections(&self) -> BSI<(usize, usize)> { + fn sections(&self) -> BSI { use elf_utilities::section::{Contents64, Type}; let iter = self @@ -69,7 +67,7 @@ impl Relocatable for ElfObject { let si = SectionInfo { file_size: s.header.sh_size, data_size: s.header.sh_size, - data_index: Some((self.object_index, i)), + data_index: Some(DataIndex::new(self.object_index, i)), offset: s.header.sh_offset, }; let s_name: &str = &s.name; @@ -98,9 +96,9 @@ impl Relocatable for ElfObject { Box::new(iter) } - fn section_data(&self, index: (usize, usize)) -> Result<&[u8], Error> { + fn section_data(&self, index: DataIndex) -> Result<&[u8], Error> { use elf_utilities::section::Contents64; - let section = &self.elf.sections[index.1]; + let section = &self.elf.sections[index.section_index]; match §ion.contents { Contents64::Raw(v) => Ok(&v), diff --git a/src/formats/elf/output.rs b/src/formats/elf/output.rs index 6557799..4b84767 100644 --- a/src/formats/elf/output.rs +++ b/src/formats/elf/output.rs @@ -148,7 +148,7 @@ impl ElfOutput { } impl Output for ElfOutput { - fn process_section(&mut self, section: Section<(usize, usize)>) -> Result<(), Error> { + fn process_section(&mut self, section: Section) -> Result<(), Error> { self.loadable.process_section(section) } diff --git a/src/linker.rs b/src/linker.rs index e367742..0c708bb 100644 --- a/src/linker.rs +++ b/src/linker.rs @@ -4,10 +4,7 @@ use std::{ path::{Path, PathBuf}, }; -use crate::{ - common::{Output, Relocatable}, - error::Error, -}; +use crate::{common::{DataIndex, Output, Relocatable}, error::Error}; pub struct Linker where @@ -32,7 +29,7 @@ where pub fn add_relocatable(&mut self, origin: PathBuf) -> Result<(), Error> { self.relocatables - .push(R::new(origin, self.relocatables.len())?); + .push(R::new(origin, DataIndex::for_object(self.relocatables.len()))?); Ok(()) }