comparison src/unexelf.c @ 40750:593d80fe8029

(unexec): Minor changes; clean up comments.
author Richard M. Stallman <rms@gnu.org>
date Mon, 05 Nov 2001 22:17:42 +0000
parents 5374777dd618
children 300eaca41c49
comparison
equal deleted inserted replaced
40749:6554846ccb71 40750:593d80fe8029
402 [21] 1 0 0 0x8f949 0x68b7 .comment 402 [21] 1 0 0 0x8f949 0x68b7 .comment
403 0 0 0x1 0 403 0 0 0x1 0
404 404
405 */ 405 */
406 406
407 /* 407 /* We do not use mmap because that fails with NFS.
408 * Modified by rdh@yottayotta.com of Yotta Yotta Incorporated. 408 Instead we read the whole file, modify it, and write it out. */
409 * 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
424 #ifndef emacs 410 #ifndef emacs
425 #define fatal(a, b, c) fprintf (stderr, a, b, c), exit (1) 411 #define fatal(a, b, c) fprintf (stderr, a, b, c), exit (1)
426 #include <string.h> 412 #include <string.h>
427 #else 413 #else
428 #include <config.h> 414 #include <config.h>
658 char *new_name, *old_name; 644 char *new_name, *old_name;
659 unsigned data_start, bss_start, entry_address; 645 unsigned data_start, bss_start, entry_address;
660 { 646 {
661 int new_file, old_file, new_file_size; 647 int new_file, old_file, new_file_size;
662 648
663 /* Pointers to the base of the image of the two files. */ 649 /* Pointers to the base of the image of the two files. */
664 caddr_t old_base, new_base; 650 caddr_t old_base, new_base;
665 651
666 /* Pointers to the file, program and section headers for the old and new 652 /* Pointers to the file, program and section headers for the old and
667 * files. 653 new files. */
668 */
669 ElfW(Ehdr) *old_file_h, *new_file_h; 654 ElfW(Ehdr) *old_file_h, *new_file_h;
670 ElfW(Phdr) *old_program_h, *new_program_h; 655 ElfW(Phdr) *old_program_h, *new_program_h;
671 ElfW(Shdr) *old_section_h, *new_section_h; 656 ElfW(Shdr) *old_section_h, *new_section_h;
672 657
673 /* Point to the section name table in the old file */ 658 /* Point to the section name table in the old file. */
674 char *old_section_names; 659 char *old_section_names;
675 660
676 ElfW(Addr) old_bss_addr, new_bss_addr; 661 ElfW(Addr) old_bss_addr, new_bss_addr;
677 ElfW(Word) old_bss_size, new_data2_size; 662 ElfW(Word) old_bss_size, new_data2_size;
678 ElfW(Off) new_data2_offset; 663 ElfW(Off) new_data2_offset;
683 int old_data_index, new_data2_index; 668 int old_data_index, new_data2_index;
684 int old_mdebug_index; 669 int old_mdebug_index;
685 struct stat stat_buf; 670 struct stat stat_buf;
686 671
687 /* Open the old file, allocate a buffer of the right size, and read 672 /* Open the old file, allocate a buffer of the right size, and read
688 * in the file contents. */ 673 in the file contents. */
689 674
690 old_file = open (old_name, O_RDONLY); 675 old_file = open (old_name, O_RDONLY);
691 676
692 if (old_file < 0) 677 if (old_file < 0)
693 fatal ("Can't open %s for reading: errno %d\n", old_name, errno); 678 fatal ("Can't open %s for reading: errno %d\n", old_name, errno);
720 705
721 old_mdebug_index = find_section (".mdebug", old_section_names, 706 old_mdebug_index = find_section (".mdebug", old_section_names,
722 old_name, old_file_h, old_section_h, 1); 707 old_name, old_file_h, old_section_h, 1);
723 708
724 /* Find the old .bss section. Figure out parameters of the new 709 /* Find the old .bss section. Figure out parameters of the new
725 * data2 and bss sections. 710 data2 and bss sections. */
726 */
727 711
728 old_bss_index = find_section (".bss", old_section_names, 712 old_bss_index = find_section (".bss", old_section_names,
729 old_name, old_file_h, old_section_h, 0); 713 old_name, old_file_h, old_section_h, 0);
730 714
731 old_sbss_index = find_section (".sbss", old_section_names, 715 old_sbss_index = find_section (".sbss", old_section_names,
776 760
777 if ((unsigned) new_bss_addr < (unsigned) old_bss_addr + old_bss_size) 761 if ((unsigned) new_bss_addr < (unsigned) old_bss_addr + old_bss_size)
778 fatal (".bss shrank when undumping???\n", 0, 0); 762 fatal (".bss shrank when undumping???\n", 0, 0);
779 763
780 /* Set the output file to the right size. Allocate a buffer to hold 764 /* Set the output file to the right size. Allocate a buffer to hold
781 * the image of the new file. Set pointers to various interesting 765 the image of the new file. Set pointers to various interesting
782 * objects. stat_buf still has old_file data. 766 objects. stat_buf still has old_file data. */
783 */
784 767
785 new_file = open (new_name, O_RDWR | O_CREAT, 0666); 768 new_file = open (new_name, O_RDWR | O_CREAT, 0666);
786 if (new_file < 0) 769 if (new_file < 0)
787 fatal ("Can't creat (%s): errno %d\n", new_name, errno); 770 fatal ("Can't creat (%s): errno %d\n", new_name, errno);
788 771
805 new_program_h = (ElfW(Phdr) *) ((byte *) new_base + old_file_h->e_phoff); 788 new_program_h = (ElfW(Phdr) *) ((byte *) new_base + old_file_h->e_phoff);
806 new_section_h = (ElfW(Shdr) *) 789 new_section_h = (ElfW(Shdr) *)
807 ((byte *) new_base + old_file_h->e_shoff + new_data2_size); 790 ((byte *) new_base + old_file_h->e_shoff + new_data2_size);
808 791
809 /* Make our new file, program and section headers as copies of the 792 /* Make our new file, program and section headers as copies of the
810 * originals. 793 originals. */
811 */
812 794
813 memcpy (new_file_h, old_file_h, old_file_h->e_ehsize); 795 memcpy (new_file_h, old_file_h, old_file_h->e_ehsize);
814 memcpy (new_program_h, old_program_h, 796 memcpy (new_program_h, old_program_h,
815 old_file_h->e_phnum * old_file_h->e_phentsize); 797 old_file_h->e_phnum * old_file_h->e_phentsize);
816 798
817 /* Modify the e_shstrndx if necessary. */ 799 /* Modify the e_shstrndx if necessary. */
818 PATCH_INDEX (new_file_h->e_shstrndx); 800 PATCH_INDEX (new_file_h->e_shstrndx);
819 801
820 /* Fix up file header. We'll add one section. Section header is 802 /* Fix up file header. We'll add one section. Section header is
821 * further away now. 803 further away now. */
822 */
823 804
824 new_file_h->e_shoff += new_data2_size; 805 new_file_h->e_shoff += new_data2_size;
825 new_file_h->e_shnum += 1; 806 new_file_h->e_shnum += 1;
826 807
827 #ifdef DEBUG 808 #ifdef DEBUG
830 fprintf (stderr, "New section offset %x\n", new_file_h->e_shoff); 811 fprintf (stderr, "New section offset %x\n", new_file_h->e_shoff);
831 fprintf (stderr, "New section count %d\n", new_file_h->e_shnum); 812 fprintf (stderr, "New section count %d\n", new_file_h->e_shnum);
832 #endif 813 #endif
833 814
834 /* Fix up a new program header. Extend the writable data segment so 815 /* Fix up a new program header. Extend the writable data segment so
835 * that the bss area is covered too. Find that segment by looking 816 that the bss area is covered too. Find that segment by looking
836 * for a segment that ends just before the .bss area. Make sure 817 for a segment that ends just before the .bss area. Make sure
837 * that no segments are above the new .data2. Put a loop at the end 818 that no segments are above the new .data2. Put a loop at the end
838 * to adjust the offset and address of any segment that is above 819 to adjust the offset and address of any segment that is above
839 * data2, just in case we decide to allow this later. 820 data2, just in case we decide to allow this later. */
840 */
841 821
842 for (n = new_file_h->e_phnum - 1; n >= 0; n--) 822 for (n = new_file_h->e_phnum - 1; n >= 0; n--)
843 { 823 {
844 /* Compute maximum of all requirements for alignment of section. */ 824 /* Compute maximum of all requirements for alignment of section. */
845 ElfW(Word) alignment = (NEW_PROGRAM_H (n)).p_align; 825 ElfW(Word) alignment = (NEW_PROGRAM_H (n)).p_align;
885 NEW_PROGRAM_H (n).p_offset += new_data2_size; 865 NEW_PROGRAM_H (n).p_offset += new_data2_size;
886 } 866 }
887 #endif 867 #endif
888 868
889 /* Fix up section headers based on new .data2 section. Any section 869 /* Fix up section headers based on new .data2 section. Any section
890 * whose offset or virtual address is after the new .data2 section 870 whose offset or virtual address is after the new .data2 section
891 * gets its value adjusted. .bss size becomes zero and new address 871 gets its value adjusted. .bss size becomes zero and new address
892 * is set. data2 section header gets added by copying the existing 872 is set. data2 section header gets added by copying the existing
893 * .data header and modifying the offset, address and size. 873 .data header and modifying the offset, address and size. */
894 */
895 for (old_data_index = 1; old_data_index < (int) old_file_h->e_shnum; 874 for (old_data_index = 1; old_data_index < (int) old_file_h->e_shnum;
896 old_data_index++) 875 old_data_index++)
897 if (!strcmp (old_section_names + OLD_SECTION_H (old_data_index).sh_name, 876 if (!strcmp (old_section_names + OLD_SECTION_H (old_data_index).sh_name,
898 ".data")) 877 ".data"))
899 break; 878 break;
1215 } 1194 }
1216 break; 1195 break;
1217 } 1196 }
1218 } 1197 }
1219 1198
1220 /* Write out new_file, close it, and free the buffer containing its 1199 /* Write out new_file, and free the buffers. */
1221 * contents */
1222 1200
1223 if (write (new_file, new_base, new_file_size) != new_file_size) 1201 if (write (new_file, new_base, new_file_size) != new_file_size)
1224 fatal ("Didn't write %d bytes to %s: errno %d\n", 1202 fatal ("Didn't write %d bytes to %s: errno %d\n",
1225 new_file_size, new_base, errno); 1203 new_file_size, new_base, errno);
1226 1204
1205 free (old_base);
1206 free (new_base);
1207
1208 /* Close the files and make the new file executable. */
1209
1210 if (close (old_file))
1211 fatal ("Can't close (%s): errno %d\n", old_name, errno);
1212
1227 if (close (new_file)) 1213 if (close (new_file))
1228 fatal ("Can't close (%s): errno %d\n", new_name, errno); 1214 fatal ("Can't close (%s): errno %d\n", new_name, errno);
1229
1230 free (new_base);
1231
1232 /* Close old_file, and free the corresponding buffer */
1233
1234 if (close (old_file))
1235 fatal ("Can't close (%s): errno %d\n", old_name, errno);
1236
1237 free (old_base);
1238
1239 /* Make the new file executable */
1240 1215
1241 if (stat (new_name, &stat_buf) == -1) 1216 if (stat (new_name, &stat_buf) == -1)
1242 fatal ("Can't stat (%s): errno %d\n", new_name, errno); 1217 fatal ("Can't stat (%s): errno %d\n", new_name, errno);
1243 1218
1244 n = umask (777); 1219 n = umask (777);