mirror of
https://github.com/Noratrieb/elven-forest.git
synced 2026-01-14 10:45:03 +01:00
link
This commit is contained in:
parent
b04e3b8a55
commit
898e84363a
2 changed files with 73 additions and 15 deletions
|
|
@ -18,6 +18,7 @@ use std::{
|
||||||
collections::{hash_map::Entry, HashMap},
|
collections::{hash_map::Entry, HashMap},
|
||||||
fs::{self, File},
|
fs::{self, File},
|
||||||
io::{BufWriter, Write},
|
io::{BufWriter, Write},
|
||||||
|
iter,
|
||||||
num::NonZeroU64,
|
num::NonZeroU64,
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
};
|
};
|
||||||
|
|
@ -90,7 +91,42 @@ pub fn run(opts: Opts) -> Result<()> {
|
||||||
let storage =
|
let storage =
|
||||||
storage::allocate_storage(BASE_EXEC_ADDR, &cx.elves).context("while allocating 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 §ion.parts {
|
||||||
|
let elf = cx.elves[part.file.0].elf;
|
||||||
|
let shdr = elf.section_header_by_name(§ion.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(§ion.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()?;
|
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 {
|
let ident = ElfIdent {
|
||||||
magic: *c::ELFMAG,
|
magic: *c::ELFMAG,
|
||||||
class: c::Class(c::ELFCLASS64),
|
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),
|
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_name = write.add_sh_string(b".text");
|
||||||
let text_section = write.add_section(Section {
|
let text_section = write.add_section(Section {
|
||||||
|
|
|
||||||
|
|
@ -9,23 +9,30 @@ use crate::{utils::AlignExt, ElfFile, FileId, DEFAULT_PAGE_ALIGN};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Allocation {
|
pub struct Allocation {
|
||||||
file: FileId,
|
pub file: FileId,
|
||||||
section: BString,
|
pub section: BString,
|
||||||
size: u64,
|
pub size: u64,
|
||||||
align: u64,
|
pub align: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SegmentPart {
|
pub struct SegmentPart {
|
||||||
base: Addr,
|
pub pad_from_prev: u64,
|
||||||
file: FileId,
|
pub base: Addr,
|
||||||
section: BString,
|
pub align: u64,
|
||||||
size: u64,
|
pub file: FileId,
|
||||||
|
pub size: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct StorageAllocation {
|
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> {
|
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");
|
debug!(?allocs, "Allocation pass one completed");
|
||||||
|
|
||||||
let mut current_addr = base_addr;
|
let mut current_addr = base_addr;
|
||||||
let mut segment_parts = Vec::new();
|
let mut section_parts = Vec::new();
|
||||||
for section in allocs {
|
for section in allocs {
|
||||||
|
let mut segment_parts = Vec::new();
|
||||||
|
|
||||||
current_addr = current_addr.align_up(DEFAULT_PAGE_ALIGN);
|
current_addr = current_addr.align_up(DEFAULT_PAGE_ALIGN);
|
||||||
for alloc in section.1 {
|
for alloc in section.1 {
|
||||||
let align = alloc.align;
|
let align = alloc.align;
|
||||||
let addr = current_addr.align_up(align);
|
let addr = current_addr.align_up(align);
|
||||||
|
let pad = addr.u64() - current_addr.u64();
|
||||||
|
|
||||||
current_addr = addr + alloc.size;
|
current_addr = addr + alloc.size;
|
||||||
|
|
||||||
segment_parts.push(SegmentPart {
|
segment_parts.push(SegmentPart {
|
||||||
|
pad_from_prev: pad,
|
||||||
base: addr,
|
base: addr,
|
||||||
|
align: align,
|
||||||
file: alloc.file,
|
file: alloc.file,
|
||||||
size: alloc.size,
|
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,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue