This commit is contained in:
nora 2023-10-21 12:14:28 +02:00
parent b04e3b8a55
commit 898e84363a
2 changed files with 73 additions and 15 deletions

View file

@ -18,6 +18,7 @@ use std::{
collections::{hash_map::Entry, HashMap},
fs::{self, File},
io::{BufWriter, Write},
iter,
num::NonZeroU64,
path::PathBuf,
};
@ -90,7 +91,42 @@ pub fn run(opts: Opts) -> Result<()> {
let storage =
storage::allocate_storage(BASE_EXEC_ADDR, &cx.elves).context("while allocating storage")?;
dbg!(storage);
dbg!(&storage);
let mut writer = create_elf();
for section in &storage.sections {
let exec = if section.name == b"text".as_slice() {
ShFlags::SHF_EXECINSTR
} else {
ShFlags::empty()
};
let mut content = Vec::new();
for part in &section.parts {
let elf = cx.elves[part.file.0].elf;
let shdr = elf.section_header_by_name(&section.name)?;
let data = elf.section_content(shdr)?;
content.extend(iter::repeat(0).take(part.pad_from_prev.try_into().unwrap()));
content.extend(data);
}
let name = writer.add_sh_string(&section.name);
writer.add_section(Section {
name,
r#type: ShType(SHT_PROGBITS),
flags: ShFlags::SHF_ALLOC | exec,
fixed_entsize: None,
addr_align: NonZeroU64::new(
section
.parts
.first()
.map(|p| p.align)
.unwrap_or(DEFAULT_PAGE_ALIGN),
),
content,
})?;
}
cx.resolve()?;
@ -146,7 +182,7 @@ impl<'a> LinkCtxt<'a> {
}
}
fn write_output(opts: &Opts, text: &[u8], entry_offset_from_text: Addr) -> Result<()> {
fn create_elf() -> ElfWriter {
let ident = ElfIdent {
magic: *c::ELFMAG,
class: c::Class(c::ELFCLASS64),
@ -163,7 +199,11 @@ fn write_output(opts: &Opts, text: &[u8], entry_offset_from_text: Addr) -> Resul
machine: c::Machine(c::EM_X86_64),
};
let mut write = ElfWriter::new(header);
ElfWriter::new(header)
}
fn write_output(opts: &Opts, text: &[u8], entry_offset_from_text: Addr) -> Result<()> {
let mut write = create_elf();
let text_name = write.add_sh_string(b".text");
let text_section = write.add_section(Section {

View file

@ -9,23 +9,30 @@ use crate::{utils::AlignExt, ElfFile, FileId, DEFAULT_PAGE_ALIGN};
#[derive(Debug)]
pub struct Allocation {
file: FileId,
section: BString,
size: u64,
align: u64,
pub file: FileId,
pub section: BString,
pub size: u64,
pub align: u64,
}
#[derive(Debug)]
pub struct SegmentPart {
base: Addr,
file: FileId,
section: BString,
size: u64,
pub pad_from_prev: u64,
pub base: Addr,
pub align: u64,
pub file: FileId,
pub size: u64,
}
#[derive(Debug)]
pub struct StorageAllocation {
segment_parts: Vec<SegmentPart>,
pub sections: Vec<AllocatedSection>,
}
#[derive(Debug)]
pub struct AllocatedSection {
pub name: BString,
pub parts: Vec<SegmentPart>,
}
pub fn allocate_storage<'a>(base_addr: Addr, files: &[ElfFile<'a>]) -> Result<StorageAllocation> {
@ -54,23 +61,34 @@ pub fn allocate_storage<'a>(base_addr: Addr, files: &[ElfFile<'a>]) -> Result<St
debug!(?allocs, "Allocation pass one completed");
let mut current_addr = base_addr;
let mut segment_parts = Vec::new();
let mut section_parts = Vec::new();
for section in allocs {
let mut segment_parts = Vec::new();
current_addr = current_addr.align_up(DEFAULT_PAGE_ALIGN);
for alloc in section.1 {
let align = alloc.align;
let addr = current_addr.align_up(align);
let pad = addr.u64() - current_addr.u64();
current_addr = addr + alloc.size;
segment_parts.push(SegmentPart {
pad_from_prev: pad,
base: addr,
align: align,
file: alloc.file,
size: alloc.size,
section: section.0.to_owned(),
});
}
section_parts.push(AllocatedSection {
name: section.0.to_owned(),
parts: segment_parts,
})
}
Ok(StorageAllocation { segment_parts })
Ok(StorageAllocation {
sections: section_parts,
})
}