@@ -255,24 +255,27 @@ void elf_file::read_sh(void) {
255255// This is necessary to ensure the whole segment contains data defined in sections, otherwise you end up
256256// signing/hashing/encrypting data that may not be written, as many tools write in sections not segments
257257void elf_file::remove_sh_holes (void ) {
258+ bool found_hole = false ;
258259 for (int i=0 ; i+1 < sh_entries.size (); i++) {
259260 auto sh0 = &(sh_entries[i]);
260261 elf32_sh_entry sh1 = sh_entries[i+1 ];
261262 if (
262263 (sh0->type == SHT_PROGBITS && sh1.type == SHT_PROGBITS)
263264 && (sh0->size && sh1.size )
264265 && (sh0->addr + sh0->size < sh1.addr )
265- && (segment_from_virtual_address ( sh0-> addr ) == segment_from_virtual_address (sh1. addr ))
266- && segment_from_virtual_address ( sh0-> addr ) != NULL
266+ && (segment_from_section (* sh0) == segment_from_section (sh1))
267+ && segment_from_section (* sh0) != NULL
267268 ) {
268269 uint32_t gap = sh1.addr - sh0->addr - sh0->size ;
269270 if (gap > sh1.addralign ) {
270- fail (ERROR_INCOMPATIBLE, " Cannot plug gap greater than alignment - gap %d, alignment %d" , gap, sh1.addralign );
271+ fail (ERROR_INCOMPATIBLE, " Section %d: Cannot plug gap greater than alignment - gap %d, alignment %d" , i , gap, sh1.addralign );
271272 }
272273 if (verbose) printf (" Section %d: Moving end from 0x%08x to 0x%08x to plug gap\n " , i, sh0->addr + sh0->size , sh1.addr );
273274 sh0->size = sh1.addr - sh0->addr ;
275+ found_hole = true ;
274276 }
275277 }
278+ if (found_hole) read_sh_data ();
276279}
277280
278281// Read the section data from the internal byte array into discrete sections.
@@ -290,7 +293,7 @@ void elf_file::read_sh_data(void) {
290293}
291294
292295const std::string elf_file::section_name (uint32_t sh_name) const {
293- if (!eh.sh_str_index || eh.sh_str_index > eh.sh_num )
296+ if (!eh.sh_str_index || eh.sh_str_index > eh.sh_num || eh. sh_str_index >= sh_data. size () )
294297 return " " ;
295298
296299 if (sh_name > sh_data[eh.sh_str_index ].size ())
@@ -394,9 +397,6 @@ int elf_file::read_file(std::shared_ptr<std::iostream> file) {
394397 if (!rc) {
395398 read_ph ();
396399 read_sh ();
397-
398- // Remove any holes in the ELF file, as these cause issues when signing/hashing/encrypting
399- remove_sh_holes ();
400400 }
401401 read_sh_data ();
402402 }
@@ -475,6 +475,16 @@ const elf32_ph_entry* elf_file::segment_from_virtual_address(uint32_t vaddr) {
475475 return NULL ;
476476}
477477
478+ const elf32_ph_entry* elf_file::segment_from_section (const elf32_sh_entry &sh) {
479+ for (int i = 0 ; i < eh.ph_num ; i++) {
480+ if (sh.offset >= ph_entries[i].offset && sh.offset < ph_entries[i].offset + ph_entries[i].filez ) {
481+ if (verbose) printf (" segment %d contains section %s\n " , i, section_name (sh.name ).c_str ());
482+ return &ph_entries[i];
483+ }
484+ }
485+ return nullptr ;
486+ }
487+
478488// Appends a new segment and section - filled with zeros
479489// Use content to replace the content
480490const elf32_ph_entry& elf_file::append_segment (uint32_t vaddr, uint32_t paddr, uint32_t size, const std::string &name) {
0 commit comments