diff --git a/src/common/loadable.rs b/src/common/loadable.rs index 7d24087..0cbaebc 100644 --- a/src/common/loadable.rs +++ b/src/common/loadable.rs @@ -85,18 +85,6 @@ impl Loadable { // } } - pub const fn section_names() -> &'static [&'static str] { - &[".text", ".rodata", ".data", ".bss"] - } - - pub const fn section_count() -> usize { - Self::section_names().len() - } - - pub const fn segment_count() -> usize { - 3 - } - pub fn segment_sections(&self) -> impl Iterator { let text = once(&self.text); let rodata = once(&self.rodata); diff --git a/src/formats/elf/output.rs b/src/formats/elf/output.rs index 08164d3..be8e9c7 100644 --- a/src/formats/elf/output.rs +++ b/src/formats/elf/output.rs @@ -1,10 +1,4 @@ -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::PathBuf}; use elf_utilities::{ header::Ehdr64, @@ -19,6 +13,8 @@ use crate::{ use super::ElfObject; +const SECTION_NAMES: [&str; 5] = [".text", ".rodata", ".data", ".bss", ".shstrtab"]; + pub struct ElfOutput { destination: PathBuf, writer: BufWriter, @@ -36,6 +32,29 @@ impl ElfOutput { Ok(result) } + + fn write_shstrtab( + &mut self, + shstrtab: (Vec, Vec), + mut offset: usize, + name_idx: usize, + ) -> Result { + const SHS: u16 = size_of::() as u16; + + // write .shstrtab header + let data_offset = (offset + usize::from(SHS)) as u64; + let strtab_header = make_section_header( + shstrtab.1[name_idx], + ShType::StrTab, + data_offset, + shstrtab.0.len() as u64, + ); + offset += self.writer.write(&strtab_header.to_le_bytes())?; + // write .shstrtab data + offset += self.writer.write(&shstrtab.0)?; + + Ok(offset) + } } impl Output for ElfOutput { @@ -44,10 +63,10 @@ impl Output for ElfOutput { const PHS: u16 = size_of::() as u16; const SHS: u16 = size_of::() as u16; - let strtab = make_strtab(); + let shstrtab = make_shstrtab(); let mut ehdr = make_elf_header(); - ehdr.e_shnum = Loadable::section_count() as u16 + 1; // +1 for .shstrtab - ehdr.e_phnum = Loadable::segment_count() as u16; + ehdr.e_shnum = SECTION_NAMES.len() as u16; + ehdr.e_phnum = 3u16; // .text, .rodata + .data, .bss ehdr.e_shstrndx = ehdr.e_shnum - 1; // .shstrab is always last ehdr.e_entry = loadable.start_offset()?; ehdr.e_phentsize = PHS; @@ -77,7 +96,7 @@ impl Output for ElfOutput { // write section header table (text + rodata + data + bss) for sections in loadable.segment_sections() { let sh = make_section_header( - strtab.1[name_idx], + shstrtab.1[name_idx], ShType::ProgBits, 0, sections.data_size(), @@ -87,19 +106,7 @@ impl Output for ElfOutput { } // .shstrtab as last section header written (+ the name data including) - { - // write .shstrtab header - let data_offset = (offset + usize::from(SHS)) as u64; - let strtab_header = make_section_header( - strtab.1[name_idx], - ShType::StrTab, - data_offset, - strtab.0.len() as u64, - ); - offset += self.writer.write(&strtab_header.to_le_bytes())?; - // write .shstrtab data - offset += self.writer.write(&strtab.0)?; - } + offset = self.write_shstrtab(shstrtab, offset, name_idx)?; // program data (segments) offset += pad_to_next_page(&mut self.writer, offset)?; @@ -188,11 +195,8 @@ fn make_program_header(offset: usize, size: u64, which: SegmentType) -> Phdr64 { } // strtab as bytes + indexes to individual strings -fn make_strtab() -> (Vec, Vec) { - let mut section_names = Vec::from(Loadable::section_names()); - section_names.push(".shstrtab"); - - let strtab_bytes = build_string_table(section_names, true); +fn make_shstrtab() -> (Vec, Vec) { + let strtab_bytes = build_string_table(Vec::from(SECTION_NAMES), true); let mut indexes = Vec::new(); let mut on_string = false;