use internal writer

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

@ -26,10 +26,11 @@ pub struct ElfOutput<'data> {
destination: PathBuf,
file: ELF64,
input_data: InputData<'data>,
writer: BufWriter<File>,
}
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};
let mut elf = ELF64::default();
@ -41,21 +42,33 @@ impl<'data> ElfOutput<'data> {
elf.ehdr.set_osabi(OSABI::Linux);
elf.ehdr.set_data(Data::LSB2);
Self {
let str_path = expand_path(&destination)?;
let writer = file_writer(str_path, 0o755)?;
let result = Self {
destination,
file: elf,
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();
Self {
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: InputData::new(),
}
writer,
};
Ok(result)
}
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_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;
// 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
for seg in self.file.segments.iter_mut() {
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);
@ -192,27 +202,27 @@ impl<'data> Output<'data> for ElfOutput<'data> {
if sec.header.get_type() == ShType::StrTab {
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 {
offset += writer.write(&sec.to_le_bytes())?;
offset += self.writer.write(&sec.to_le_bytes())?;
}
}
// program data (segments)
offset += pad_to_next_page(&mut writer, offset)?;
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() {
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);
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)
}

@ -28,7 +28,7 @@ fn main() {
if maybe_out.is_none() {
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));
}

Loading…
Cancel
Save