diff --git a/src/common/loadable.rs b/src/common/loadable.rs index 802a358..310353c 100644 --- a/src/common/loadable.rs +++ b/src/common/loadable.rs @@ -32,11 +32,11 @@ impl Loadable { Ok(()) } - pub fn sections_mut(&mut self) -> impl Iterator { - let text = once(&mut self.text).map(|s| (".text", s)); - let rodata = once(&mut self.rodata).map(|s| (".rodata", s)); - let data = once(&mut self.data).map(|s| (".data", s)); - let bss = once(&mut self.bss).map(|s| (".bss", s)); + pub fn sections(&self) -> impl Iterator { + let text = once(&self.text).map(|s| (".text", s)); + let rodata = once(&self.rodata).map(|s| (".rodata", s)); + let data = once(&self.data).map(|s| (".data", s)); + let bss = once(&self.bss).map(|s| (".bss", s)); text.chain(rodata).chain(data).chain(bss) } diff --git a/src/common/output.rs b/src/common/output.rs index 4d97f8b..af97107 100644 --- a/src/common/output.rs +++ b/src/common/output.rs @@ -1,13 +1,11 @@ use std::path::PathBuf; -use super::{Relocatable, Section}; +use super::{Loadable, Relocatable}; use crate::error::Error; pub trait Output where R: Relocatable, { - fn process_section(&mut self, section: Section) -> Result<(), Error>; - - fn finalize(self, objects: &[R]) -> Result; + fn finalize(self, objects: &[R], loadable: &Loadable) -> Result; } diff --git a/src/common/relocatable.rs b/src/common/relocatable.rs index 3f23b38..9c26d19 100644 --- a/src/common/relocatable.rs +++ b/src/common/relocatable.rs @@ -14,11 +14,17 @@ pub struct DataIndex { impl DataIndex { pub fn new(object_index: usize, section_index: usize) -> Self { - DataIndex { object_index, section_index } + DataIndex { + object_index, + section_index, + } } pub fn for_object(object_index: usize) -> Self { - DataIndex { object_index, section_index: 0 } + DataIndex { + object_index, + section_index: 0, + } } } diff --git a/src/formats/elf/object.rs b/src/formats/elf/object.rs index 63de474..32d06d8 100644 --- a/src/formats/elf/object.rs +++ b/src/formats/elf/object.rs @@ -34,10 +34,6 @@ impl ElfObject { Ok(result) } - - pub fn elf(&self) -> &ELF64 { - &self.elf - } } impl Relocatable for ElfObject { @@ -63,7 +59,9 @@ impl Relocatable for ElfObject { if match &s.contents { Contents64::Raw(v) => Some(v), _ => None, - }.is_some() { + } + .is_some() + { let si = SectionInfo { file_size: s.header.sh_size, data_size: s.header.sh_size, diff --git a/src/formats/elf/output.rs b/src/formats/elf/output.rs index e5d2504..47d3ecc 100644 --- a/src/formats/elf/output.rs +++ b/src/formats/elf/output.rs @@ -14,14 +14,16 @@ use elf_utilities::{ segment::{Phdr64, Segment64, Type as SeType, PF_R, PF_W, PF_X}, }; -use crate::{common::{Loadable, Output, Section, SegmentType}, error::Error}; +use crate::{ + common::{Loadable, Output, SegmentType}, + error::Error, +}; use super::ElfObject; pub struct ElfOutput { destination: PathBuf, file: ELF64, - loadable: Loadable, writer: BufWriter, } @@ -44,18 +46,17 @@ impl ElfOutput { let result = Self { destination, file: elf, - loadable: Loadable::default(), writer, }; Ok(result) } - fn populate_sections(&mut self) -> Result<(), Error> { + fn populate_sections(&mut self, loadable: &Loadable) -> Result<(), Error> { let mut names = Vec::new(); let mut name_idx = 0usize; - for (name, sections) in self.loadable.sections_mut() { + for (name, sections) in loadable.sections() { let mut data_size = 0; for t in sections.iter() { @@ -121,40 +122,28 @@ impl ElfOutput { *offset += page_size; } - fn populate_segments(&mut self) -> Result { + fn populate_segments(&mut self, loadable: &Loadable) -> Result { let mut offset = 0u64; // program header/segments // contains .text + .rodata as one segment - self.populate_segment( - &mut offset, - self.loadable.program_size(), - SegmentType::Text, - ); + self.populate_segment(&mut offset, loadable.program_size(), SegmentType::Text); // contains .data as one segment - self.populate_segment( - &mut offset, - self.loadable.data_size(), - SegmentType::Data, - ); + self.populate_segment(&mut offset, loadable.data_size(), SegmentType::Data); // contains .bss as one segment - self.populate_segment(&mut offset, self.loadable.bss_size(), SegmentType::Bss); + self.populate_segment(&mut offset, loadable.bss_size(), SegmentType::Bss); Ok(offset) } } impl Output for ElfOutput { - fn process_section(&mut self, section: Section) -> Result<(), Error> { - self.loadable.process_section(section) - } - - fn finalize(mut self, objects: &[ElfObject]) -> Result { + fn finalize(mut self, objects: &[ElfObject], loadable: &Loadable) -> Result { const EHS: u64 = size_of::() as u64; const PHS: u16 = size_of::() as u16; const SHS: u16 = size_of::() as u16; - self.populate_sections()?; - let page_size = self.populate_segments()?; + self.populate_sections(loadable)?; + let page_size = self.populate_segments(loadable)?; self.file.ehdr.e_shnum = self.file.sections.len() as u16; self.file.ehdr.e_entry = 4096; // TODO @@ -191,13 +180,13 @@ impl Output for ElfOutput { offset += pad_to_next_page(&mut self.writer, offset)?; eprintln!("Prog start: {}", offset); // write section/segment data - for bytes in self.loadable.program_bytes(objects) { + for bytes in loadable.program_bytes(objects) { offset += self.writer.write(bytes?)?; } offset += pad_to_next_page(&mut self.writer, offset)?; eprintln!("Data start: {}", offset); - for bytes in self.loadable.data_bytes(objects) { + for bytes in loadable.data_bytes(objects) { offset += self.writer.write(bytes?)?; } diff --git a/src/linker.rs b/src/linker.rs index 0c708bb..e88f4a9 100644 --- a/src/linker.rs +++ b/src/linker.rs @@ -4,7 +4,10 @@ use std::{ path::{Path, PathBuf}, }; -use crate::{common::{DataIndex, Output, Relocatable}, error::Error}; +use crate::{ + common::{DataIndex, Loadable, Output, Relocatable}, + error::Error, +}; pub struct Linker where @@ -12,6 +15,7 @@ where O: Output, { relocatables: Vec, + loadable: Loadable, output: O, } @@ -23,13 +27,16 @@ where pub fn new(output: O) -> Self { Self { relocatables: Vec::new(), + loadable: Loadable::default(), output, } } pub fn add_relocatable(&mut self, origin: PathBuf) -> Result<(), Error> { - self.relocatables - .push(R::new(origin, DataIndex::for_object(self.relocatables.len()))?); + self.relocatables.push(R::new( + origin, + DataIndex::for_object(self.relocatables.len()), + )?); Ok(()) } @@ -37,11 +44,11 @@ where pub fn link(mut self) -> Result { for r in self.relocatables.iter() { for s in r.sections() { - self.output.process_section(s?)?; + self.loadable.process_section(s?)?; } } - self.output.finalize(&self.relocatables) + self.output.finalize(&self.relocatables, &self.loadable) } pub fn object_path(origin: &Path) -> Result {