|  |  |  | @ -25,7 +25,7 @@ use super::ElfObject; | 
		
	
		
			
				|  |  |  |  | pub struct ElfOutput { | 
		
	
		
			
				|  |  |  |  |     destination: PathBuf, | 
		
	
		
			
				|  |  |  |  |     file: ELF64, | 
		
	
		
			
				|  |  |  |  |     input_data: SegmentView, | 
		
	
		
			
				|  |  |  |  |     segment_view: SegmentView, | 
		
	
		
			
				|  |  |  |  |     writer: BufWriter<File>, | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -48,23 +48,7 @@ impl ElfOutput { | 
		
	
		
			
				|  |  |  |  |         let result = Self { | 
		
	
		
			
				|  |  |  |  |             destination, | 
		
	
		
			
				|  |  |  |  |             file: elf, | 
		
	
		
			
				|  |  |  |  |             input_data: SegmentView::default(), | 
		
	
		
			
				|  |  |  |  |             writer, | 
		
	
		
			
				|  |  |  |  |         }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         Ok(result) | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     pub fn from_object(object: &ElfObject, destination: PathBuf) -> Result<Self, Error> { | 
		
	
		
			
				|  |  |  |  |         let other = object.elf(); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         let str_path = expand_path(&destination)?; | 
		
	
		
			
				|  |  |  |  |         let writer = file_writer(str_path, 0o755)?; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         let result = Self { | 
		
	
		
			
				|  |  |  |  |             destination, | 
		
	
		
			
				|  |  |  |  |             file: elf_bin_from_object(other), | 
		
	
		
			
				|  |  |  |  |             input_data: SegmentView::default(), | 
		
	
		
			
				|  |  |  |  |             segment_view: SegmentView::default(), | 
		
	
		
			
				|  |  |  |  |             writer, | 
		
	
		
			
				|  |  |  |  |         }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -75,7 +59,7 @@ impl ElfOutput { | 
		
	
		
			
				|  |  |  |  |         let mut names = Vec::new(); | 
		
	
		
			
				|  |  |  |  |         let mut name_idx = 0usize; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         for (name, sections) in self.input_data.sections_mut() { | 
		
	
		
			
				|  |  |  |  |         for (name, sections) in self.segment_view.sections_mut() { | 
		
	
		
			
				|  |  |  |  |             let mut data_size = 0; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             for t in sections.iter() { | 
		
	
	
		
			
				
					|  |  |  | @ -147,13 +131,17 @@ impl ElfOutput { | 
		
	
		
			
				|  |  |  |  |         // contains .text + .rodata as one segment
 | 
		
	
		
			
				|  |  |  |  |         self.populate_segment( | 
		
	
		
			
				|  |  |  |  |             &mut offset, | 
		
	
		
			
				|  |  |  |  |             self.input_data.program_size(), | 
		
	
		
			
				|  |  |  |  |             self.segment_view.program_size(), | 
		
	
		
			
				|  |  |  |  |             SegmentType::Text, | 
		
	
		
			
				|  |  |  |  |         ); | 
		
	
		
			
				|  |  |  |  |         // contains .data as one segment
 | 
		
	
		
			
				|  |  |  |  |         self.populate_segment(&mut offset, self.input_data.data_size(), SegmentType::Data); | 
		
	
		
			
				|  |  |  |  |         self.populate_segment( | 
		
	
		
			
				|  |  |  |  |             &mut offset, | 
		
	
		
			
				|  |  |  |  |             self.segment_view.data_size(), | 
		
	
		
			
				|  |  |  |  |             SegmentType::Data, | 
		
	
		
			
				|  |  |  |  |         ); | 
		
	
		
			
				|  |  |  |  |         // contains .bss as one segment
 | 
		
	
		
			
				|  |  |  |  |         self.populate_segment(&mut offset, self.input_data.bss_size(), SegmentType::Bss); | 
		
	
		
			
				|  |  |  |  |         self.populate_segment(&mut offset, self.segment_view.bss_size(), SegmentType::Bss); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         Ok(offset) | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
	
		
			
				
					|  |  |  | @ -161,10 +149,10 @@ impl ElfOutput { | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | impl Output<ElfObject> for ElfOutput { | 
		
	
		
			
				|  |  |  |  |     fn process_section(&mut self, section: Section<(usize, usize)>) -> Result<(), Error> { | 
		
	
		
			
				|  |  |  |  |         self.input_data.append_section(section) | 
		
	
		
			
				|  |  |  |  |         self.segment_view.append_section(section) | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     fn finalize(mut self, objects: &Vec<ElfObject>) -> Result<PathBuf, Error> { | 
		
	
		
			
				|  |  |  |  |     fn finalize(mut self, objects: &[ElfObject]) -> Result<PathBuf, Error> { | 
		
	
		
			
				|  |  |  |  |         const EHS: u64 = size_of::<Ehdr64>() as u64; | 
		
	
		
			
				|  |  |  |  |         const PHS: u16 = size_of::<Phdr64>() as u16; | 
		
	
		
			
				|  |  |  |  |         const SHS: u16 = size_of::<Shdr64>() as u16; | 
		
	
	
		
			
				
					|  |  |  | @ -207,13 +195,13 @@ impl Output<ElfObject> for ElfOutput { | 
		
	
		
			
				|  |  |  |  |         offset += pad_to_next_page(&mut self.writer, offset)?; | 
		
	
		
			
				|  |  |  |  |         eprintln!("Prog start: {}", offset); | 
		
	
		
			
				|  |  |  |  |         // write section/segment data
 | 
		
	
		
			
				|  |  |  |  |         for bytes in self.input_data.program_bytes(objects) { | 
		
	
		
			
				|  |  |  |  |         for bytes in self.segment_view.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.input_data.data_bytes(objects) { | 
		
	
		
			
				|  |  |  |  |         for bytes in self.segment_view.data_bytes(objects) { | 
		
	
		
			
				|  |  |  |  |             offset += self.writer.write(bytes?)?; | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -236,20 +224,6 @@ fn file_writer(output_filename: &str, permission: u32) -> Result<BufWriter<File> | 
		
	
		
			
				|  |  |  |  |     Ok(BufWriter::new(file)) | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | // init new ELF64 from an object file meant as executable output
 | 
		
	
		
			
				|  |  |  |  | fn elf_bin_from_object(other: &ELF64) -> ELF64 { | 
		
	
		
			
				|  |  |  |  |     use elf_utilities::header::Type; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     let mut elf = ELF64::default(); | 
		
	
		
			
				|  |  |  |  |     elf.ehdr.set_elf_type(Type::Exec); | 
		
	
		
			
				|  |  |  |  |     elf.ehdr.e_ehsize = other.ehdr.e_ehsize; | 
		
	
		
			
				|  |  |  |  |     elf.ehdr.e_version = other.ehdr.e_version; | 
		
	
		
			
				|  |  |  |  |     elf.ehdr.e_ident = other.ehdr.e_ident; | 
		
	
		
			
				|  |  |  |  |     elf.ehdr.e_machine = other.ehdr.e_machine; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     elf | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | fn make_section_header(name_idx: usize, stype: ShType, size: u64) -> Shdr64 { | 
		
	
		
			
				|  |  |  |  |     let mut h = Shdr64::default(); | 
		
	
		
			
				|  |  |  |  |     h.set_type(stype); | 
		
	
	
		
			
				
					|  |  |  | 
 |