elfutils/elfutils-0.97-ftruncate-mmap-fix.diff

84 lines
2.3 KiB
Diff

---
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;