Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 42 additions & 3 deletions tool/microkit/src/elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ const PF_R: u32 = 0x4;

/// ELF section-header type (`sh_type`)
const SHT_PROGBITS: u32 = 0x1;
const SHT_STRTAB: u32 = 0x3;

/// ELF section-header flags (`sh_flags`)
const SHF_WRITE: u64 = 0x1;
Expand Down Expand Up @@ -494,14 +495,15 @@ impl ElfFile {
self.segments.iter().filter(|s| s.loadable).collect()
}

/// Re-create a minimal ELF file with all the segments.
/// Re-create a minimal ELF file with all the program and section headers.
pub fn reserialise(&self, out: &std::path::Path) -> Result<u64, String> {
let ehsize = size_of::<ElfHeader64>();

let phnum = self.loadable_segments().len();
let phentsize = size_of::<ElfProgramHeader64>();

let shnum = self.loadable_segments().len() + 1; // First entry is reserved
// First entry is reserved, last entry is dummy strtab
let shnum = self.loadable_segments().len() + 2;
let shentsize = size_of::<ElfSectionHeader64>();

let mut elf_file = match File::create(out) {
Expand Down Expand Up @@ -539,7 +541,7 @@ impl ElfFile {
phnum: phnum as u16,
shentsize: shentsize as u16,
shnum: shnum as u16,
shstrndx: 0,
shstrndx: (shnum - 1) as u16,
};
elf_file
.write_all(unsafe {
Expand Down Expand Up @@ -617,6 +619,33 @@ impl ElfFile {
)
});
}
let strtab_seg = ElfSectionHeader64 {
name: 0,
type_: SHT_STRTAB,
flags: 0,
addr: 0,
offset: data_off_watermark, // points to a null byte that we will write later after all the data
size: 1,
link: 0,
info: 0,
addralign: 0,
entsize: 0,
};

// Uncomment this if more data needs to be written.
// data_off_watermark += 1;
// Have to comment out to keep clippy happy, else:
// "warning: value assigned to `data_off_watermark` is never read", or if we try to allow with `#[allow(unused_assignments)]`:
// "error[E0658]: attributes on expressions are experimental"

elf_file
.write_all(unsafe { struct_to_bytes(&strtab_seg) })
.unwrap_or_else(|_| {
panic!(
"Failed to write ELF string table section header for '{}'",
out.display()
)
});

// Finally the data for each segment will follow
for (i, seg) in self
Expand All @@ -634,6 +663,16 @@ impl ElfFile {
});
}

// Then the null byte for string table
elf_file
.write_all(vec![0u8; 1].as_slice())
.unwrap_or_else(|_| {
panic!(
"Failed to write ELF string table byte for '{}'",
out.display()
)
});

elf_file.flush().unwrap();

Ok(metadata(out).unwrap().len())
Expand Down