Skip to content

Commit 3535498

Browse files
tool: emit empty strtab when serialising ELF
Signed-off-by: Bill Nguyen <bill.nguyen@student.unsw.edu.au>
1 parent 23f1f6d commit 3535498

File tree

1 file changed

+42
-3
lines changed

1 file changed

+42
-3
lines changed

tool/microkit/src/elf.rs

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ const PF_R: u32 = 0x4;
108108

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

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

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

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

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

507509
let mut elf_file = match File::create(out) {
@@ -539,7 +541,7 @@ impl ElfFile {
539541
phnum: phnum as u16,
540542
shentsize: shentsize as u16,
541543
shnum: shnum as u16,
542-
shstrndx: 0,
544+
shstrndx: (shnum - 1) as u16,
543545
};
544546
elf_file
545547
.write_all(unsafe {
@@ -617,6 +619,33 @@ impl ElfFile {
617619
)
618620
});
619621
}
622+
let strtab_seg = ElfSectionHeader64 {
623+
name: 0,
624+
type_: SHT_STRTAB,
625+
flags: 0,
626+
addr: 0,
627+
offset: data_off_watermark, // points to a null byte that we will write later after all the data
628+
size: 1,
629+
link: 0,
630+
info: 0,
631+
addralign: 0,
632+
entsize: 0,
633+
};
634+
635+
// Uncomment this if more data needs to be written.
636+
// data_off_watermark += 1;
637+
// Have to comment out to keep clippy happy, else:
638+
// "warning: value assigned to `data_off_watermark` is never read", or if we try to allow with `#[allow(unused_assignments)]`:
639+
// "error[E0658]: attributes on expressions are experimental"
640+
641+
elf_file
642+
.write_all(unsafe { struct_to_bytes(&strtab_seg) })
643+
.unwrap_or_else(|_| {
644+
panic!(
645+
"Failed to write ELF string table section header for '{}'",
646+
out.display()
647+
)
648+
});
620649

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

666+
// Then the null byte for string table
667+
elf_file
668+
.write_all(vec![0u8; 1].as_slice())
669+
.unwrap_or_else(|_| {
670+
panic!(
671+
"Failed to write ELF string table byte for '{}'",
672+
out.display()
673+
)
674+
});
675+
637676
elf_file.flush().unwrap();
638677

639678
Ok(metadata(out).unwrap().len())

0 commit comments

Comments
 (0)