|
|
|
@ -14,7 +14,7 @@ use elf_utilities::{
|
|
|
|
|
|
|
|
|
|
use crate::{
|
|
|
|
|
common::{
|
|
|
|
|
expand_path, pad_to_next_page, Loadable, Output, Relocatable, SegmentType, SymbolValue,
|
|
|
|
|
expand_path, next_page, page_padding, Loadable, Output, Relocatable, SegmentType, SymbolValue,
|
|
|
|
|
},
|
|
|
|
|
error::Error,
|
|
|
|
|
};
|
|
|
|
@ -50,7 +50,7 @@ impl ElfOutput {
|
|
|
|
|
const SHS: u16 = size_of::<Shdr64>() as u16;
|
|
|
|
|
|
|
|
|
|
// write .shstrtab header
|
|
|
|
|
let data_offset = (offset + usize::from(SHS)) as u64;
|
|
|
|
|
let data_offset = offset + usize::from(SHS);
|
|
|
|
|
let strtab_header = make_section_header(
|
|
|
|
|
shstrtab.1[name_idx],
|
|
|
|
|
ShType::StrTab,
|
|
|
|
@ -77,7 +77,7 @@ impl Output<ElfObject> for ElfOutput {
|
|
|
|
|
|
|
|
|
|
let shstrtab = make_shstrtab();
|
|
|
|
|
let mut ehdr = make_elf_header();
|
|
|
|
|
ehdr.e_shnum = SECTION_NAMES.len() as u16;
|
|
|
|
|
ehdr.e_shnum = (SECTION_NAMES.len() + 1) 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()? as u64;
|
|
|
|
@ -104,17 +104,23 @@ impl Output<ElfObject> for ElfOutput {
|
|
|
|
|
offset += self.writer.write(&ph.to_le_bytes())?;
|
|
|
|
|
|
|
|
|
|
eprintln!("SH start: {}", offset);
|
|
|
|
|
let mut name_idx = 0;
|
|
|
|
|
let mut name_idx = 0; // TODO: fix to make this empty!
|
|
|
|
|
let mut sec_offset = next_page(offset + (SHS as usize) * Loadable::sections_count());
|
|
|
|
|
eprintln!("Sec_offset: {}", sec_offset);
|
|
|
|
|
// write 0-section
|
|
|
|
|
let empty_sh = make_section_header(0, ShType::Null, 0, 0);
|
|
|
|
|
offset += self.writer.write(&empty_sh.to_le_bytes())?;
|
|
|
|
|
// write section header table (text + rodata + data + bss)
|
|
|
|
|
for sections in loadable.segment_sections() {
|
|
|
|
|
let sh = make_section_header(
|
|
|
|
|
shstrtab.1[name_idx],
|
|
|
|
|
ShType::ProgBits,
|
|
|
|
|
0,
|
|
|
|
|
sec_offset,
|
|
|
|
|
sections.data_size(),
|
|
|
|
|
);
|
|
|
|
|
name_idx += 1;
|
|
|
|
|
offset += self.writer.write(&sh.to_le_bytes())?;
|
|
|
|
|
sec_offset += sections.data_size() as usize;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// .shstrtab as last section header written (+ the name data including)
|
|
|
|
@ -130,6 +136,7 @@ impl Output<ElfObject> for ElfOutput {
|
|
|
|
|
.get(si.object_index)
|
|
|
|
|
.ok_or(Error::InvalidObjectIndex)?;
|
|
|
|
|
let bytes = object.bytes(si.offset, si.file_size)?;
|
|
|
|
|
// eprintln!("Writing program section from {} offset {} size {}\n\t{:x?}", si.object_index, si.offset, bytes.len(), bytes);
|
|
|
|
|
offset += self.writer.write(bytes)?;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -210,7 +217,7 @@ fn make_elf_header() -> Ehdr64 {
|
|
|
|
|
ehdr
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn make_section_header(name_idx: usize, stype: ShType, offset: u64, size: u64) -> Shdr64 {
|
|
|
|
|
fn make_section_header(name_idx: usize, stype: ShType, offset: usize, size: u64) -> Shdr64 {
|
|
|
|
|
let mut h = Shdr64::default();
|
|
|
|
|
h.set_type(stype);
|
|
|
|
|
|
|
|
|
@ -222,7 +229,7 @@ fn make_section_header(name_idx: usize, stype: ShType, offset: u64, size: u64) -
|
|
|
|
|
h.sh_link = 0;
|
|
|
|
|
h.sh_size = size;
|
|
|
|
|
// filled at finalize()
|
|
|
|
|
h.sh_offset = offset;
|
|
|
|
|
h.sh_offset = offset as u64;
|
|
|
|
|
|
|
|
|
|
h
|
|
|
|
|
}
|
|
|
|
@ -270,3 +277,14 @@ fn make_shstrtab() -> (Vec<u8>, Vec<usize>) {
|
|
|
|
|
|
|
|
|
|
(strtab_bytes, indexes)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn pad_to_next_page(writer: &mut BufWriter<File>, offset: usize) -> Result<usize, Error> {
|
|
|
|
|
use std::convert::TryInto;
|
|
|
|
|
|
|
|
|
|
let padding = page_padding(offset);
|
|
|
|
|
|
|
|
|
|
eprintln!("Padding from: {} with: {}", offset, padding);
|
|
|
|
|
writer.seek(SeekFrom::Current(padding.try_into()?))?;
|
|
|
|
|
|
|
|
|
|
Ok(padding)
|
|
|
|
|
}
|