Mercurial > emacs
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); |