master
Ales Katona 4 years ago
parent 7a7bbb2ac0
commit 43c7f19dde
Signed by: almindor
GPG Key ID: 2F773149BF38B48F

@ -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<Item = &SegmentSections> { pub fn segment_sections(&self) -> impl Iterator<Item = &SegmentSections> {
let text = once(&self.text); let text = once(&self.text);
let rodata = once(&self.rodata); let rodata = once(&self.rodata);

@ -1,10 +1,4 @@
use std::{ use std::{fs::File, io::BufWriter, io::Write, mem::size_of, path::PathBuf};
fs::File,
io::BufWriter,
io::{Write},
mem::size_of,
path::{PathBuf},
};
use elf_utilities::{ use elf_utilities::{
header::Ehdr64, header::Ehdr64,
@ -19,6 +13,8 @@ use crate::{
use super::ElfObject; use super::ElfObject;
const SECTION_NAMES: [&str; 5] = [".text", ".rodata", ".data", ".bss", ".shstrtab"];
pub struct ElfOutput { pub struct ElfOutput {
destination: PathBuf, destination: PathBuf,
writer: BufWriter<File>, writer: BufWriter<File>,
@ -36,6 +32,29 @@ impl ElfOutput {
Ok(result) Ok(result)
} }
fn write_shstrtab(
&mut self,
shstrtab: (Vec<u8>, Vec<usize>),
mut offset: usize,
name_idx: usize,
) -> Result<usize, Error> {
const SHS: u16 = size_of::<Shdr64>() 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<ElfObject> for ElfOutput { impl Output<ElfObject> for ElfOutput {
@ -44,10 +63,10 @@ impl Output<ElfObject> for ElfOutput {
const PHS: u16 = size_of::<Phdr64>() as u16; const PHS: u16 = size_of::<Phdr64>() as u16;
const SHS: u16 = size_of::<Shdr64>() as u16; const SHS: u16 = size_of::<Shdr64>() as u16;
let strtab = make_strtab(); let shstrtab = make_shstrtab();
let mut ehdr = make_elf_header(); let mut ehdr = make_elf_header();
ehdr.e_shnum = Loadable::section_count() as u16 + 1; // +1 for .shstrtab ehdr.e_shnum = SECTION_NAMES.len() as u16;
ehdr.e_phnum = Loadable::segment_count() as u16; ehdr.e_phnum = 3u16; // .text, .rodata + .data, .bss
ehdr.e_shstrndx = ehdr.e_shnum - 1; // .shstrab is always last ehdr.e_shstrndx = ehdr.e_shnum - 1; // .shstrab is always last
ehdr.e_entry = loadable.start_offset()?; ehdr.e_entry = loadable.start_offset()?;
ehdr.e_phentsize = PHS; ehdr.e_phentsize = PHS;
@ -77,7 +96,7 @@ impl Output<ElfObject> for ElfOutput {
// write section header table (text + rodata + data + bss) // write section header table (text + rodata + data + bss)
for sections in loadable.segment_sections() { for sections in loadable.segment_sections() {
let sh = make_section_header( let sh = make_section_header(
strtab.1[name_idx], shstrtab.1[name_idx],
ShType::ProgBits, ShType::ProgBits,
0, 0,
sections.data_size(), sections.data_size(),
@ -87,19 +106,7 @@ impl Output<ElfObject> for ElfOutput {
} }
// .shstrtab as last section header written (+ the name data including) // .shstrtab as last section header written (+ the name data including)
{ offset = self.write_shstrtab(shstrtab, offset, name_idx)?;
// 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)?;
}
// program data (segments) // program data (segments)
offset += pad_to_next_page(&mut self.writer, offset)?; 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 // strtab as bytes + indexes to individual strings
fn make_strtab() -> (Vec<u8>, Vec<usize>) { fn make_shstrtab() -> (Vec<u8>, Vec<usize>) {
let mut section_names = Vec::from(Loadable::section_names()); let strtab_bytes = build_string_table(Vec::from(SECTION_NAMES), true);
section_names.push(".shstrtab");
let strtab_bytes = build_string_table(section_names, true);
let mut indexes = Vec::new(); let mut indexes = Vec::new();
let mut on_string = false; let mut on_string = false;

Loading…
Cancel
Save