@@ -826,11 +826,16 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsLibrary()
826826 replaceSection (getSectionName (shdrs.at (i)), rdi (shdrs.at (i).sh_size ));
827827 i++;
828828 }
829+ bool moveHeaderTableToTheEnd = rdi (hdr ()->e_shoff ) < pht_size;
829830
830831 /* Compute the total space needed for the replaced sections */
831832 off_t neededSpace = 0 ;
832833 for (auto & s : replacedSections)
833834 neededSpace += roundUp (s.second .size (), sectionAlignment);
835+
836+ off_t headerTableSpace = roundUp (rdi (hdr ()->e_shnum ) * rdi (hdr ()->e_shentsize ), sectionAlignment);
837+ if (moveHeaderTableToTheEnd)
838+ neededSpace += headerTableSpace;
834839 debug (" needed space is %d\n " , neededSpace);
835840
836841 Elf_Off startOffset = roundUp (fileContents->size (), getPageSize ());
@@ -860,24 +865,48 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsLibrary()
860865 startPage = startOffset;
861866 }
862867
863- /* Add a segment that maps the replaced sections into memory. */
864868 wri (hdr ()->e_phoff , sizeof (Elf_Ehdr));
865- phdrs.resize (rdi (hdr ()->e_phnum ) + 1 );
866- wri (hdr ()->e_phnum , rdi (hdr ()->e_phnum ) + 1 );
867- Elf_Phdr & phdr = phdrs.at (rdi (hdr ()->e_phnum ) - 1 );
868- wri (phdr.p_type , PT_LOAD);
869- wri (phdr.p_offset , startOffset);
870- wri (phdr.p_vaddr , wri (phdr.p_paddr , startPage));
871- wri (phdr.p_filesz , wri (phdr.p_memsz , neededSpace));
872- wri (phdr.p_flags , PF_R | PF_W);
873- wri (phdr.p_align , getPageSize ());
874869
870+ bool needNewSegment = true ;
871+ auto & lastSeg = phdrs.back ();
872+ /* Try to extend the last segment to include replaced sections */
873+ if (!phdrs.empty () &&
874+ rdi (lastSeg.p_type ) == PT_LOAD &&
875+ rdi (lastSeg.p_flags ) == (PF_R | PF_W) &&
876+ rdi (lastSeg.p_align ) == getPageSize ()) {
877+ auto segEnd = roundUp (rdi (lastSeg.p_offset ) + rdi (lastSeg.p_memsz ), getPageSize ());
878+ if (segEnd == startOffset) {
879+ auto newSz = startOffset + neededSpace - rdi (lastSeg.p_offset );
880+ wri (lastSeg.p_filesz , wri (lastSeg.p_memsz , newSz));
881+ needNewSegment = false ;
882+ }
883+ }
884+
885+ if (needNewSegment) {
886+ /* Add a segment that maps the replaced sections into memory. */
887+ phdrs.resize (rdi (hdr ()->e_phnum ) + 1 );
888+ wri (hdr ()->e_phnum , rdi (hdr ()->e_phnum ) + 1 );
889+ Elf_Phdr & phdr = phdrs.at (rdi (hdr ()->e_phnum ) - 1 );
890+ wri (phdr.p_type , PT_LOAD);
891+ wri (phdr.p_offset , startOffset);
892+ wri (phdr.p_vaddr , wri (phdr.p_paddr , startPage));
893+ wri (phdr.p_filesz , wri (phdr.p_memsz , neededSpace));
894+ wri (phdr.p_flags , PF_R | PF_W);
895+ wri (phdr.p_align , getPageSize ());
896+ }
875897
876898 normalizeNoteSegments ();
877899
878900
879901 /* Write out the replaced sections. */
880902 Elf_Off curOff = startOffset;
903+
904+ if (moveHeaderTableToTheEnd) {
905+ debug (" Moving the shtable to offset %d\n " , curOff);
906+ wri (hdr ()->e_shoff , curOff);
907+ curOff += headerTableSpace;
908+ }
909+
881910 writeReplacedSections (curOff, startPage, startOffset);
882911 assert (curOff == startOffset + neededSpace);
883912
0 commit comments