diff --git a/src/formats/elf/output.rs b/src/formats/elf/output.rs index 347053c..a9de61d 100644 --- a/src/formats/elf/output.rs +++ b/src/formats/elf/output.rs @@ -1,10 +1,10 @@ -use std::{fs::File, io::BufWriter, io::Write, mem::size_of, path::PathBuf}; +use std::{fs::File, io::BufWriter, io::Write, mem::size_of, path::{Path, PathBuf}}; use elf_utilities::{ file::ELF64, header::Ehdr64, - section::{build_string_table, Contents64, Section64, Shdr64}, - segment::{Phdr64, PF_R, PF_W, PF_X}, + section::{build_string_table, Contents64, Section64, Shdr64, Type as ShType}, + segment::{Phdr64, Segment64, Type as SeType, PF_R, PF_W, PF_X}, }; use crate::{ @@ -53,7 +53,7 @@ impl<'data> ElfOutput<'data> { fn populate_sections(&mut self) -> Result { let mut names = Vec::new(); - let mut names_len = 0usize; + let mut name_idx = 0usize; let mut result = 0u64; for (name, sections) in self.segment_data.iter_mut() { @@ -70,24 +70,23 @@ impl<'data> ElfOutput<'data> { } result += data.len() as u64; - names_len += name.len(); names.push(name); let section = Section64 { name: name.into(), - header: make_section_header(&name, names_len, data.len()), + header: make_section_header(name_idx, ShType::ProgBits, data.len()), contents: Contents64::Raw(data), }; + name_idx += name.len() + 1; self.file.add_section(section); } let name = ".shstrtab"; - names_len += name.len(); names.push(name); let string_table = build_string_table(names, true); result += string_table.len() as u64; let section = Section64 { name: name.into(), - header: make_section_header(&name, names_len, string_table.len()), + header: make_section_header(name_idx, ShType::StrTab, string_table.len()), contents: Contents64::Raw(string_table), }; self.file.add_section(section); @@ -96,8 +95,6 @@ impl<'data> ElfOutput<'data> { } fn populate_segment(&mut self, offset: &mut u64, size: u64, which: SegmentType) -> u64 { - use elf_utilities::segment::{Segment64, Type}; - if size == 0 { return 0; } @@ -105,7 +102,7 @@ impl<'data> ElfOutput<'data> { let mut segment = Segment64 { header: Phdr64::default(), }; - segment.header.set_type(Type::Load); + segment.header.set_type(SeType::Load); segment.header.p_filesz = size; segment.header.p_memsz = size; segment.header.p_offset = *offset; @@ -162,9 +159,6 @@ impl<'data> Output<'data> for ElfOutput<'data> { } fn finalize(mut self) -> Result { - use std::io::Error as IOError; - use std::io::ErrorKind; - const EHS: u64 = size_of::() as u64; const PHS: u64 = size_of::() as u64; const SHS: u16 = size_of::() as u16; @@ -181,11 +175,7 @@ impl<'data> Output<'data> for ElfOutput<'data> { self.file.ehdr.e_shnum = self.file.sections.len() as u16; self.file.ehdr.e_entry = 0x100; // TODO - 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) - })?; + let str_path = expand_path(&self.destination)?; let mut writer = file_writer(str_path, 0o755)?; let mut offset = 0; @@ -206,7 +196,6 @@ impl<'data> Output<'data> for ElfOutput<'data> { // write section header table for sec in self.file.sections.iter() { - eprintln!("NAme index: {}", sec.header.sh_name); offset += writer.write(&sec.header.to_le_bytes())?; } writer.flush()?; @@ -242,25 +231,30 @@ fn elf_bin_from_object(other: &ELF64) -> ELF64 { elf } -fn make_section_header(name: &str, names_len: usize, size: usize) -> Shdr64 { - use elf_utilities::section::Type; - +fn make_section_header(name_idx: usize, stype: ShType, size: usize) -> Shdr64 { let mut h = Shdr64::default(); - match name { - ".shstrtab" => h.set_type(Type::StrTab), - ".bss" => h.set_type(Type::NoBits), - _ => h.set_type(Type::ProgBits), - } + h.set_type(stype); // section index used for name and section indexing (currently same) - let idx = 1 + (names_len as u32); // add 0 at start - // name index + let idx = 1 + (name_idx as u32); // add 0 at start + // name index h.sh_name = idx; // link index - h.sh_link = 0; //idx; + h.sh_link = 0; h.sh_size = size as u64; - // TODO + // filled at finalize() // h.sh_offset = offset; h } + +fn expand_path(path: &Path) -> Result<&str, Error> { + use std::io::Error as IOError; + use std::io::ErrorKind; + + path.to_str().ok_or_else(|| { + let ioe = IOError::new(ErrorKind::Other, "Path expansion fail"); + let boxed = Box::new(ioe); + Error::IOError(boxed) + }) +} \ No newline at end of file