From: Ulrich Drepper Date: Sun, 28 May 2006 07:47:25 +0000 (+0000) Subject: Fix rewriting of existing files. X-Git-Tag: elfutils-0.121~21 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f97208e04f4099ba9fde520ba2aaa1818f053e19;p=thirdparty%2Felfutils.git Fix rewriting of existing files. --- diff --git a/libelf/ChangeLog b/libelf/ChangeLog index 46083253c..d42bf18bf 100644 --- a/libelf/ChangeLog +++ b/libelf/ChangeLog @@ -1,3 +1,9 @@ +2006-05-28 Ulrich Drepper + + * elf32_updatefile.c (updatemmap): Preserve section content if + copying would overwrite them. + Fix msync paramters. + 2006-04-04 Roland McGrath * elf32_updatefile.c (updatemmap): Handle other-endian case. diff --git a/libelf/elf32_updatefile.c b/libelf/elf32_updatefile.c index 7561a685d..6eab3cf03 100644 --- a/libelf/elf32_updatefile.c +++ b/libelf/elf32_updatefile.c @@ -239,6 +239,32 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum) = memcpy (p, scn->shdr.ELFW(e,LIBELFBITS), sizeof (ElfW2(LIBELFBITS,Shdr))); } + + /* If the file is mmaped and the original position of the + section in the file is lower than the new position we + need to save the section content since otherwise it is + overwritten before it can be copied. If there are + multiple data segments in the list only the first can be + from the file. */ + if (((char *) elf->map_address + elf->start_offset + <= (char *) scn->data_list.data.d.d_buf) + && ((char *) scn->data_list.data.d.d_buf + < ((char *) elf->map_address + elf->start_offset + + elf->maximum_size)) + && (((char *) elf->map_address + elf->start_offset + + scn->shdr.ELFW(e,LIBELFBITS)->sh_offset) + > (char *) scn->data_list.data.d.d_buf)) + { + void *p = malloc (scn->data_list.data.d.d_size); + if (p == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + return -1; + } + scn->data_list.data.d.d_buf = scn->data_base + = memcpy (p, scn->data_list.data.d.d_buf, + scn->data_list.data.d.d_size); + } } /* Iterate over all the section in the order in which they @@ -364,10 +390,10 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum) /* Make sure the content hits the disk. */ char *msync_start = ((char *) elf->map_address - + elf->start_offset / sysconf (_SC_PAGESIZE)); + + (elf->start_offset & ~(sysconf (_SC_PAGESIZE) - 1))); char *msync_end = ((char *) elf->map_address + elf->start_offset + ehdr->e_shoff - * ehdr->e_shentsize * shnum); + + ehdr->e_shentsize * shnum); (void) msync (msync_start, msync_end - msync_start, MS_SYNC); return 0;