aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2001-11-05 11:48:48 +0000
committerEli Zaretskii2001-11-05 11:48:48 +0000
commit6fb8339ca8ebb4deda62b34d82a8ff33fd43f1db (patch)
tree84ff9b25d549b365288d1a6455b60ceb999c993f
parent7dd73b78d0e82746ed1ef4f7cab833c0d0d2ac76 (diff)
downloademacs-6fb8339ca8ebb4deda62b34d82a8ff33fd43f1db.tar.gz
emacs-6fb8339ca8ebb4deda62b34d82a8ff33fd43f1db.zip
(unexec): mmap() has problems on nfs-mounted file
systems. Don't use it anymore.
-rw-r--r--src/ChangeLog5
-rw-r--r--src/unexelf.c76
2 files changed, 55 insertions, 26 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 8f4f49d4d33..fa65344ada4 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
12001-11-05 Dale Hagglund <rdh@yottayotta.com>
2
3 * unexelf.c (unexec): Don't use `mmap'. Instead, read and write
4 the program image directly.
5
12001-11-05 Pavel Jan,Bm(Bk <Pavel@Janik.cz> 62001-11-05 Pavel Jan,Bm(Bk <Pavel@Janik.cz>
2 7
3 * buffer.h (Fbuffer_local_value): Add prototype. 8 * buffer.h (Fbuffer_local_value): Add prototype.
diff --git a/src/unexelf.c b/src/unexelf.c
index 4f832aeb3a0..5519625c783 100644
--- a/src/unexelf.c
+++ b/src/unexelf.c
@@ -404,6 +404,23 @@ Filesz Memsz Flags Align
404 404
405 */ 405 */
406 406
407/*
408 * Modified by rdh@yottayotta.com of Yotta Yotta Incorporated.
409 *
410 * The code originally used mmap() to create a memory image of the new
411 * and old object files. This had a few handy features: (1) you get
412 * to use a cool system call like mmap, (2) no need to explicitly
413 * write out the new file before the close, and (3) no swap space
414 * requirements. Unfortunately, mmap() often fails to work with
415 * nfs-mounted file systems.
416 *
417 * So, instead of relying on the vm subsystem to do the file i/o for
418 * us, it's now done explicitly. A buffer of the right size for the
419 * file is dynamically allocated, and either the old_name is read into
420 * it, or it is initialized with the correct new executable contents,
421 * and then written to new_name.
422 */
423
407#ifndef emacs 424#ifndef emacs
408#define fatal(a, b, c) fprintf (stderr, a, b, c), exit (1) 425#define fatal(a, b, c) fprintf (stderr, a, b, c), exit (1)
409#include <string.h> 426#include <string.h>
@@ -667,7 +684,8 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
667 int old_mdebug_index; 684 int old_mdebug_index;
668 struct stat stat_buf; 685 struct stat stat_buf;
669 686
670 /* Open the old file & map it into the address space. */ 687 /* Open the old file, allocate a buffer of the right size, and read
688 * in the file contents. */
671 689
672 old_file = open (old_name, O_RDONLY); 690 old_file = open (old_name, O_RDONLY);
673 691
@@ -677,17 +695,19 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
677 if (fstat (old_file, &stat_buf) == -1) 695 if (fstat (old_file, &stat_buf) == -1)
678 fatal ("Can't fstat (%s): errno %d\n", old_name, errno); 696 fatal ("Can't fstat (%s): errno %d\n", old_name, errno);
679 697
680 old_base = mmap ((caddr_t) 0, stat_buf.st_size, PROT_READ, MAP_SHARED, 698 old_base = malloc (stat_buf.st_size);
681 old_file, 0);
682 699
683 if (old_base == (caddr_t) -1) 700 if (old_base == 0)
684 fatal ("Can't mmap (%s): errno %d\n", old_name, errno); 701 fatal ("Can't allocate buffer for %s\n", old_name);
685 702
686#ifdef DEBUG 703#ifdef DEBUG
687 fprintf (stderr, "mmap (%s, %x) -> %x\n", old_name, stat_buf.st_size, 704 fprintf (stderr, "%s: malloc(%d) -> %x\n", old_name, stat_buf.st_size,
688 old_base); 705 old_base);
689#endif 706#endif
690 707
708 if (read (old_file, old_base, stat_buf.st_size) != stat_buf.st_size)
709 fatal ("Didn't read all of %s: errno %d\n", old_name, errno);
710
691 /* Get pointers to headers & section names */ 711 /* Get pointers to headers & section names */
692 712
693 old_file_h = (ElfW(Ehdr) *) old_base; 713 old_file_h = (ElfW(Ehdr) *) old_base;
@@ -757,9 +777,9 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
757 if ((unsigned) new_bss_addr < (unsigned) old_bss_addr + old_bss_size) 777 if ((unsigned) new_bss_addr < (unsigned) old_bss_addr + old_bss_size)
758 fatal (".bss shrank when undumping???\n", 0, 0); 778 fatal (".bss shrank when undumping???\n", 0, 0);
759 779
760 /* Set the output file to the right size and mmap it. Set 780 /* Set the output file to the right size. Allocate a buffer to hold
761 * pointers to various interesting objects. stat_buf still has 781 * the image of the new file. Set pointers to various interesting
762 * old_file data. 782 * objects. stat_buf still has old_file data.
763 */ 783 */
764 784
765 new_file = open (new_name, O_RDWR | O_CREAT, 0666); 785 new_file = open (new_name, O_RDWR | O_CREAT, 0666);
@@ -771,16 +791,15 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
771 if (ftruncate (new_file, new_file_size)) 791 if (ftruncate (new_file, new_file_size))
772 fatal ("Can't ftruncate (%s): errno %d\n", new_name, errno); 792 fatal ("Can't ftruncate (%s): errno %d\n", new_name, errno);
773 793
774#ifdef UNEXEC_USE_MAP_PRIVATE 794 new_base = malloc (new_file_size);
775 new_base = mmap ((caddr_t) 0, new_file_size, PROT_READ | PROT_WRITE,
776 MAP_PRIVATE, new_file, 0);
777#else
778 new_base = mmap ((caddr_t) 0, new_file_size, PROT_READ | PROT_WRITE,
779 MAP_SHARED, new_file, 0);
780#endif
781 795
782 if (new_base == (caddr_t) -1) 796 if (new_base == 0)
783 fatal ("Can't mmap (%s): errno %d\n", new_name, errno); 797 fatal ("Can't allocate buffer for %s\n", old_name);
798
799#ifdef DEBUG
800 fprintf (stderr, "%s: malloc(%d) -> %x\n", new_name, new_file_size
801 new_base);
802#endif
784 803
785 new_file_h = (ElfW(Ehdr) *) new_base; 804 new_file_h = (ElfW(Ehdr) *) new_base;
786 new_program_h = (ElfW(Phdr) *) ((byte *) new_base + old_file_h->e_phoff); 805 new_program_h = (ElfW(Phdr) *) ((byte *) new_base + old_file_h->e_phoff);
@@ -1198,21 +1217,26 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
1198 } 1217 }
1199 } 1218 }
1200 1219
1201#ifdef UNEXEC_USE_MAP_PRIVATE 1220 /* Write out new_file, close it, and free the buffer containing its
1202 if (lseek (new_file, 0, SEEK_SET) == -1) 1221 * contents */
1203 fatal ("Can't rewind (%s): errno %d\n", new_name, errno);
1204 1222
1205 if (write (new_file, new_base, new_file_size) != new_file_size) 1223 if (write (new_file, new_base, new_file_size) != new_file_size)
1206 fatal ("Can't write (%s): errno %d\n", new_name, errno); 1224 fatal ("Didn't write %d bytes to %s: errno %d\n",
1207#endif 1225 new_file_size, new_base, errno);
1226
1227 if (close (new_file))
1228 fatal ("Can't close (%s): errno %d\n", new_name, errno);
1208 1229
1209 /* Close the files and make the new file executable. */ 1230 free (new_base);
1231
1232 /* Close old_file, and free the corresponding buffer */
1210 1233
1211 if (close (old_file)) 1234 if (close (old_file))
1212 fatal ("Can't close (%s): errno %d\n", old_name, errno); 1235 fatal ("Can't close (%s): errno %d\n", old_name, errno);
1213 1236
1214 if (close (new_file)) 1237 free (old_base);
1215 fatal ("Can't close (%s): errno %d\n", new_name, errno); 1238
1239 /* Make the new file executable */
1216 1240
1217 if (stat (new_name, &stat_buf) == -1) 1241 if (stat (new_name, &stat_buf) == -1)
1218 fatal ("Can't stat (%s): errno %d\n", new_name, errno); 1242 fatal ("Can't stat (%s): errno %d\n", new_name, errno);