--- prelink/src/exec.c (revision 208) +++ prelink/src/exec.c (working copy) @@ -1,4 +1,4 @@ -/* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Red Hat, Inc. +/* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2016 Red Hat, Inc. Written by Jakub Jelinek , 2001. This program is free software; you can redistribute it and/or modify @@ -555,17 +555,31 @@ error_out: if (adj > dso->phdr[i].p_filesz) { adj -= dso->phdr[i].p_filesz; - for (j = slast; - j < dso->ehdr.e_shnum - && (dso->shdr[j].sh_flags - & (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR)); - ++j) - if (dso->shdr[j].sh_addr >= dso->phdr[i].p_vaddr - + dso->phdr[i].p_memsz) - adj = (adj + dso->shdr[j].sh_addralign - 1) - & ~(dso->shdr[j].sh_addralign - 1); - dso->phdr[i].p_filesz += adj; + + for (j = 1; j < dso->ehdr.e_shnum; ++j) + if (dso->shdr[j].sh_addr < dso->phdr[i].p_vaddr + || dso->shdr[j].sh_addr + dso->shdr[j].sh_size + > dso->phdr[i].p_vaddr + dso->phdr[i].p_memsz) + { + if (dso->shdr[j].sh_offset + >= dso->phdr[i].p_offset + dso->phdr[i].p_filesz - adj + && dso->shdr[j].sh_offset + < dso->phdr[i].p_offset + dso->phdr[i].p_filesz) + break; + } + if (j == dso->ehdr.e_shnum) + adj = 0; + else + for (j = slast; + j < dso->ehdr.e_shnum + && (dso->shdr[j].sh_flags + & (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR)); + ++j) + if (dso->shdr[j].sh_addr >= dso->phdr[i].p_vaddr + + dso->phdr[i].p_memsz) + adj = (adj + dso->shdr[j].sh_addralign - 1) + & ~(dso->shdr[j].sh_addralign - 1); } else adj = 0; @@ -619,6 +633,26 @@ error_out: && (dso->shdr[j].sh_flags & (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR))) { + switch (dso->shdr[j].sh_type) + { + case SHT_HASH: + case SHT_GNU_HASH: + case SHT_DYNSYM: + case SHT_REL: + case SHT_RELA: + case SHT_STRTAB: + case SHT_NOTE: + case SHT_GNU_verdef: + case SHT_GNU_verneed: + case SHT_GNU_versym: + case SHT_GNU_LIBLIST: + break; + default: + error (0, 0, "%s: NOBITS section conversion would require moving non-movable section", + dso->filename); + goto error_out; + } + dso->shdr[j].sh_offset += adj; dso->shdr[j++].sh_addr += adj; }