File elfutils-0.97-ftruncate-mmap-fix.diff of Package elfutils

---
 libelf/elf_update.c |   54 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

Index: b/libelf/elf_update.c
===================================================================
--- a/libelf/elf_update.c
+++ b/libelf/elf_update.c
@@ -53,6 +53,7 @@
 #endif
 
 #include <libelf.h>
+#include <stdio.h>
 #include <unistd.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
@@ -100,6 +101,33 @@ write_file (Elf *elf, off_t size, int ch
 #endif
     }
 
+  /*
+   * We may have truncated the file so lets update the mapping before
+   * actually writing to the file.
+   */
+  /*
+  else if (elf->map_address != NULL && elf->parent == NULL
+	   && (elf->maximum_size != ~((size_t) 0)
+	       && size != elf->maximum_size))
+    {
+      void *new_address;
+      int ret;
+      fprintf(stderr, "sync old: %p\n", elf->map_address);
+      ret = msync(elf->map_address, elf->maximum_size, MS_SYNC);
+      if (ret)
+	perror("msync failed");
+      new_address = mremap (elf->map_address, elf->maximum_size,
+			    size, MREMAP_MAYMOVE);
+      if (unlikely (new_address == MAP_FAILED)) {
+	__libelf_seterrno (ELF_E_WRITE_ERROR);
+	return -1;
+      }
+
+      fprintf(stderr, "old: %p, new: %p\n", elf->map_address, new_address);
+      elf->map_address = new_address;
+    }
+  */
+
   if (elf->map_address != NULL)
     {
       /* The file is mmaped.  */
@@ -141,6 +169,32 @@ write_file (Elf *elf, off_t size, int ch
       size = -1;
     }
 
+  if (elf->map_address != NULL && elf->parent == NULL
+      && (elf->maximum_size != ~((size_t) 0)
+	  && (size > 0 && (size_t)size != elf->maximum_size)))
+    {
+      /*
+       * We may have truncated the file so lets update the mapping before
+       * actually writing to the file.
+       */
+      void *new_address;
+      int ret;
+
+      fprintf(stderr, "sync old: %p\n", elf->map_address);
+      ret = msync(elf->map_address, elf->maximum_size, MS_SYNC);
+      if (ret)
+	perror("msync failed");
+      new_address = mremap (elf->map_address, elf->maximum_size,
+			    size, MREMAP_MAYMOVE);
+      if (unlikely (new_address == MAP_FAILED)) {
+	__libelf_seterrno (ELF_E_WRITE_ERROR);
+	return -1;
+      }
+
+      fprintf(stderr, "old: %p, new: %p\n", elf->map_address, new_address);
+      elf->map_address = new_address;
+    }
+
   if (size != -1 && elf->parent == NULL)
     elf->maximum_size = size;