use internal writer

master
Ales Katona 4 years ago
parent a2733f70dc
commit 77b97859df
Signed by: almindor
GPG Key ID: 2F773149BF38B48F

@ -24,12 +24,13 @@ use super::ElfObject;
pub struct ElfOutput<'data> { pub struct ElfOutput<'data> {
destination: PathBuf, destination: PathBuf,
file: ELF64, file: ELF64,
input_data: InputData<'data>, input_data: InputData<'data>,
writer: BufWriter<File>,
} }
impl<'data> ElfOutput<'data> { impl<'data> ElfOutput<'data> {
pub fn new(destination: PathBuf) -> Self { pub fn new(destination: PathBuf) -> Result<Self, Error> {
use elf_utilities::header::{Class, Data, Machine, Type, Version, OSABI}; use elf_utilities::header::{Class, Data, Machine, Type, Version, OSABI};
let mut elf = ELF64::default(); let mut elf = ELF64::default();
@ -41,21 +42,33 @@ impl<'data> ElfOutput<'data> {
elf.ehdr.set_osabi(OSABI::Linux); elf.ehdr.set_osabi(OSABI::Linux);
elf.ehdr.set_data(Data::LSB2); elf.ehdr.set_data(Data::LSB2);
Self { let str_path = expand_path(&destination)?;
let writer = file_writer(str_path, 0o755)?;
let result = Self {
destination, destination,
file: elf, file: elf,
input_data: InputData::new(), input_data: InputData::new(),
} writer,
};
Ok(result)
} }
pub fn from_object(object: &ElfObject, destination: PathBuf) -> Self { pub fn from_object(object: &ElfObject, destination: PathBuf) -> Result<Self, Error> {
let other = object.elf(); let other = object.elf();
Self { let str_path = expand_path(&destination)?;
let writer = file_writer(str_path, 0o755)?;
let result = Self {
destination, destination,
file: elf_bin_from_object(other), file: elf_bin_from_object(other),
input_data: InputData::new(), input_data: InputData::new(),
} writer,
};
Ok(result)
} }
fn populate_sections(&mut self) -> Result<(), Error> { fn populate_sections(&mut self) -> Result<(), Error> {
@ -172,18 +185,15 @@ impl<'data> Output<'data> for ElfOutput<'data> {
self.file.ehdr.e_phoff = EHS; self.file.ehdr.e_phoff = EHS;
self.file.ehdr.e_shoff = self.file.ehdr.e_phoff + (usize::from(self.file.ehdr.e_phentsize) * self.file.segments.len()) as u64; self.file.ehdr.e_shoff = self.file.ehdr.e_phoff + (usize::from(self.file.ehdr.e_phentsize) * self.file.segments.len()) as u64;
let str_path = expand_path(&self.destination)?;
let mut writer = file_writer(str_path, 0o755)?;
let mut offset = 0; let mut offset = 0;
// write ELF header // write ELF header
offset += writer.write(&self.file.ehdr.to_le_bytes())?; offset += self.writer.write(&self.file.ehdr.to_le_bytes())?;
// write program header table // write program header table
for seg in self.file.segments.iter_mut() { for seg in self.file.segments.iter_mut() {
seg.header.p_offset = offset as u64; seg.header.p_offset = offset as u64;
offset += writer.write(&seg.header.to_le_bytes())?; offset += self.writer.write(&seg.header.to_le_bytes())?;
} }
eprintln!("SH start: {}", offset); eprintln!("SH start: {}", offset);
@ -192,27 +202,27 @@ impl<'data> Output<'data> for ElfOutput<'data> {
if sec.header.get_type() == ShType::StrTab { if sec.header.get_type() == ShType::StrTab {
sec.header.sh_offset = offset as u64 + u64::from(SHS); sec.header.sh_offset = offset as u64 + u64::from(SHS);
} }
offset += writer.write(&sec.header.to_le_bytes())?; offset += self.writer.write(&sec.header.to_le_bytes())?;
if sec.header.get_type() == ShType::StrTab { if sec.header.get_type() == ShType::StrTab {
offset += writer.write(&sec.to_le_bytes())?; offset += self.writer.write(&sec.to_le_bytes())?;
} }
} }
// program data (segments) // program data (segments)
offset += pad_to_next_page(&mut writer, offset)?; offset += pad_to_next_page(&mut self.writer, offset)?;
eprintln!("Prog start: {}", offset); eprintln!("Prog start: {}", offset);
// write section/segment data // write section/segment data
for bytes in self.input_data.program_bytes() { for bytes in self.input_data.program_bytes() {
offset += writer.write(bytes)?; offset += self.writer.write(bytes)?;
} }
offset += pad_to_next_page(&mut writer, offset)?; offset += pad_to_next_page(&mut self.writer, offset)?;
eprintln!("Data start: {}", offset); eprintln!("Data start: {}", offset);
for bytes in self.input_data.data_bytes() { for bytes in self.input_data.data_bytes() {
offset += writer.write(bytes)?; offset += self.writer.write(bytes)?;
} }
writer.flush()?; self.writer.flush()?;
Ok(self.destination) Ok(self.destination)
} }

@ -28,7 +28,7 @@ fn main() {
if maybe_out.is_none() { if maybe_out.is_none() {
let dest = storage.destination().expect("Path resolution"); let dest = storage.destination().expect("Path resolution");
maybe_out = Some(ElfOutput::from_object(&relocatable, dest)); maybe_out = Some(ElfOutput::from_object(&relocatable, dest).expect("Output file creation"));
} }
linker.add_relocatable(Box::new(relocatable)); linker.add_relocatable(Box::new(relocatable));
} }

Loading…
Cancel
Save