@@ -108,6 +108,7 @@ const PF_R: u32 = 0x4;
108108
109109/// ELF section-header type (`sh_type`)
110110const SHT_PROGBITS : u32 = 0x1 ;
111+ const SHT_STRTAB : u32 = 0x3 ;
111112
112113/// ELF section-header flags (`sh_flags`)
113114const 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