diff options
| -rw-r--r-- | src/ChangeLog | 5 | ||||
| -rw-r--r-- | src/unexelf.c | 76 |
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 @@ | |||
| 1 | 2001-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 | |||
| 1 | 2001-11-05 Pavel Jan,Bm(Bk <Pavel@Janik.cz> | 6 | 2001-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); |