first file output
							parent
							
								
									0e1c83bbed
								
							
						
					
					
						commit
						54adb8559d
					
				| @ -1,24 +1,32 @@ | ||||
| use std::path::PathBuf; | ||||
| 
 | ||||
| use super::Section; | ||||
| use crate::error::Error; | ||||
| 
 | ||||
| pub trait Output { | ||||
| pub trait Output<'data> { | ||||
|     fn allocate(&mut self, size: u64) -> Result<u64, Error>; | ||||
| 
 | ||||
|     fn append_section(&mut self, section: &Section) -> Result<(), Error>; | ||||
|     fn append_section(&mut self, section: Section<'data>) -> Result<(), Error>; | ||||
| 
 | ||||
|     // fn prepare_symbol<V, S>(&mut self, symbol: impl Lazy<V, S>) -> Result<&mut Self, Error>;
 | ||||
| 
 | ||||
|     fn finalize(self) -> Result<PathBuf, Error>; | ||||
| } | ||||
| 
 | ||||
| pub struct DummyOutput; | ||||
| 
 | ||||
| impl Output for DummyOutput { | ||||
| impl<'data> Output<'data> for DummyOutput { | ||||
|     fn allocate(&mut self, size: u64) -> Result<u64, Error> { | ||||
|         eprintln!("Allocating: {}", size); | ||||
|         Ok(size) | ||||
|     } | ||||
| 
 | ||||
|     fn append_section(&mut self, section: &Section) -> Result<(), Error> { | ||||
|     fn append_section(&mut self, section: Section<'data>) -> Result<(), Error> { | ||||
|         eprintln!("Appending section: {}", section); | ||||
|         Ok(()) | ||||
|     } | ||||
| 
 | ||||
|     fn finalize(self) -> Result<PathBuf, Error> { | ||||
|         todo!(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,5 +1,9 @@ | ||||
| #[cfg(feature = "elf")] | ||||
| mod elf; | ||||
| #[cfg(feature = "xelf")] | ||||
| mod xelf; | ||||
| 
 | ||||
| #[cfg(feature = "elf")] | ||||
| pub use elf::*; | ||||
| #[cfg(feature = "xelf")] | ||||
| pub use xelf::*; | ||||
|  | ||||
| @ -0,0 +1,128 @@ | ||||
| use std::path::PathBuf; | ||||
| 
 | ||||
| use elf_utilities::{ | ||||
|     file::{ELF64Dumper, ELF64}, | ||||
|     section::Section64, | ||||
|     segment::{Segment64, Type}, | ||||
| }; | ||||
| 
 | ||||
| use crate::{ | ||||
|     common::{Output, Section, SectionInfo}, | ||||
|     error::Error, | ||||
| }; | ||||
| 
 | ||||
| use super::ElfObject; | ||||
| 
 | ||||
| pub struct ElfOutput<'data> { | ||||
|     destination: PathBuf, | ||||
|     dump: ELF64Dumper, | ||||
|     text: Vec<SectionInfo<'data>>, | ||||
|     data: Vec<SectionInfo<'data>>, | ||||
|     bss: Vec<SectionInfo<'data>>, | ||||
| } | ||||
| 
 | ||||
| impl ElfOutput<'_> { | ||||
|     pub fn new(destination: PathBuf) -> Self { | ||||
|         use elf_utilities::header::{Class, Data, Machine, Type, Version, OSABI}; | ||||
| 
 | ||||
|         let mut elf = ELF64::default(); | ||||
|         elf.ehdr.set_elf_type(Type::Exec); | ||||
|         elf.ehdr.set_class(Class::Bit64); | ||||
|         elf.ehdr.set_machine(Machine::Intel386); | ||||
|         elf.ehdr.set_object_version(Version::Current); | ||||
|         elf.ehdr.set_file_version(Version::Current); | ||||
|         elf.ehdr.set_osabi(OSABI::Linux); | ||||
|         elf.ehdr.set_data(Data::LSB2); | ||||
| 
 | ||||
|         Self { | ||||
|             destination, | ||||
|             dump: ELF64Dumper::new(elf), | ||||
|             text: Vec::new(), | ||||
|             data: Vec::new(), | ||||
|             bss: Vec::new(), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn from_object(object: &ElfObject, destination: PathBuf) -> Self { | ||||
|         use elf_utilities::header::Type; | ||||
| 
 | ||||
|         let other = object.elf(); | ||||
| 
 | ||||
|         let mut elf = ELF64::default(); | ||||
|         elf.ehdr = other.ehdr.clone(); | ||||
|         elf.ehdr.set_elf_type(Type::Exec); | ||||
| 
 | ||||
|         Self { | ||||
|             destination, | ||||
|             dump: ELF64Dumper::new(elf), | ||||
|             text: Vec::new(), | ||||
|             data: Vec::new(), | ||||
|             bss: Vec::new(), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn populate_section_data(&mut self) -> Result<u64, Error> { | ||||
|         use elf_utilities::section::{Contents64, Shdr64, Type}; | ||||
| 
 | ||||
|         let mut data = Vec::new(); | ||||
| 
 | ||||
|         for t in self.text.iter_mut() { | ||||
|             if let Some(iter) = &mut t.data { | ||||
|                 data.extend(iter.as_mut()); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         let mut header = Shdr64::default(); | ||||
|         header.set_type(Type::ProgBits); | ||||
|         header.sh_entsize = data.len() as u64; | ||||
| 
 | ||||
|         let sec64 = Section64 { | ||||
|             name: ".text".into(), | ||||
|             header, | ||||
|             contents: Contents64::Raw(data), | ||||
|         }; | ||||
| 
 | ||||
|         self.dump.file.add_section(sec64); | ||||
| 
 | ||||
|         Ok(0) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'data> Output<'data> for ElfOutput<'data> { | ||||
|     fn allocate(&mut self, size: u64) -> Result<u64, Error> { | ||||
|         Ok(size) | ||||
|     } | ||||
| 
 | ||||
|     fn append_section(&mut self, section: Section<'data>) -> Result<(), Error> { | ||||
|         match section { | ||||
|             Section::Text(si) => self.text.push(si), | ||||
|             Section::Data(si) => self.data.push(si), | ||||
|             Section::Bss(si) => self.bss.push(si), | ||||
|         } | ||||
| 
 | ||||
|         Ok(()) | ||||
|     } | ||||
| 
 | ||||
|     fn finalize(mut self) -> Result<PathBuf, Error> { | ||||
|         use std::io::Error as IOError; | ||||
|         use std::io::ErrorKind; | ||||
| 
 | ||||
|         self.populate_section_data()?; | ||||
|         let mut segment = Segment64::default(); | ||||
|         segment.header.set_type(Type::Load); | ||||
|         self.dump.file.segments.push(segment); | ||||
|         self.dump.file.finalize(); | ||||
| 
 | ||||
|         let str_path = self.destination.to_str().ok_or_else(|| { | ||||
|             let ioe = IOError::new(ErrorKind::Other, "Path expansion fail"); | ||||
|             let boxed = Box::new(ioe); | ||||
|             Error::IOError(boxed) | ||||
|         })?; | ||||
| 
 | ||||
|         self.dump | ||||
|             .generate_elf_file(str_path, 0o755) | ||||
|             .map_err(|e| Error::IOError(e))?; | ||||
| 
 | ||||
|         Ok(self.destination) | ||||
|     } | ||||
| } | ||||
					Loading…
					
					
				
		Reference in New Issue