aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndreas Schwab2009-02-02 16:06:58 +0000
committerAndreas Schwab2009-02-02 16:06:58 +0000
commit826ba17e917e1f94267d0dc135c5b157b062dcd9 (patch)
treeae6b18b9e1c93c6b4595dd75e95e48353c4248cc /src
parent1b7c198ad16aac7eae623980acce27eec671df46 (diff)
downloademacs-826ba17e917e1f94267d0dc135c5b157b062dcd9.tar.gz
emacs-826ba17e917e1f94267d0dc135c5b157b062dcd9.zip
(unexec): Handle unaligned bss offset.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog4
-rw-r--r--src/unexelf.c43
2 files changed, 30 insertions, 17 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 36fe949e633..6ccef6df766 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,7 @@
12009-02-02 Andreas Schwab <schwab@suse.de>
2
3 * unexelf.c (unexec): Handle unaligned bss offset.
4
12009-02-01 Adrian Robert <Adrian.B.Robert@gmail.com> 52009-02-01 Adrian Robert <Adrian.B.Robert@gmail.com>
2 6
3 * nsterm.m (ns_read_socket): Copy 2009-01-29 and 2009-01-30 7 * nsterm.m (ns_read_socket): Copy 2009-01-29 and 2009-01-30
diff --git a/src/unexelf.c b/src/unexelf.c
index 6213aaf88fd..4e1e39a3f70 100644
--- a/src/unexelf.c
+++ b/src/unexelf.c
@@ -27,8 +27,8 @@ what you give them. Help stamp out software-hoarding! */
27 * unexec.c - Convert a running program into an a.out file. 27 * unexec.c - Convert a running program into an a.out file.
28 * 28 *
29 * Author: Spencer W. Thomas 29 * Author: Spencer W. Thomas
30 * Computer Science Dept. 30 * Computer Science Dept.
31 * University of Utah 31 * University of Utah
32 * Date: Tue Mar 2 1982 32 * Date: Tue Mar 2 1982
33 * Modified heavily since then. 33 * Modified heavily since then.
34 * 34 *
@@ -680,6 +680,8 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
680 ElfW(Word) old_bss_size, new_data2_size; 680 ElfW(Word) old_bss_size, new_data2_size;
681 ElfW(Off) new_data2_offset; 681 ElfW(Off) new_data2_offset;
682 ElfW(Addr) new_data2_addr; 682 ElfW(Addr) new_data2_addr;
683 ElfW(Off) old_bss_offset;
684 ElfW(Word) new_data2_incr;
683 685
684 int n, nn; 686 int n, nn;
685 int old_bss_index, old_sbss_index, old_plt_index; 687 int old_bss_index, old_sbss_index, old_plt_index;
@@ -754,6 +756,7 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
754 { 756 {
755 old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr; 757 old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr;
756 old_bss_size = OLD_SECTION_H (old_bss_index).sh_size; 758 old_bss_size = OLD_SECTION_H (old_bss_index).sh_size;
759 old_bss_offset = OLD_SECTION_H (old_bss_index).sh_offset;
757 new_data2_index = old_bss_index; 760 new_data2_index = old_bss_index;
758 } 761 }
759 else if (old_plt_index != -1 762 else if (old_plt_index != -1
@@ -766,6 +769,7 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
766 + OLD_SECTION_H (old_plt_index).sh_size; 769 + OLD_SECTION_H (old_plt_index).sh_size;
767 if (old_sbss_index != -1) 770 if (old_sbss_index != -1)
768 old_bss_size += OLD_SECTION_H (old_sbss_index).sh_size; 771 old_bss_size += OLD_SECTION_H (old_sbss_index).sh_size;
772 old_bss_offset = OLD_SECTION_H (old_plt_index).sh_offset;
769 new_data2_index = old_plt_index; 773 new_data2_index = old_plt_index;
770 } 774 }
771 else 775 else
@@ -773,6 +777,7 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
773 old_bss_addr = OLD_SECTION_H (old_sbss_index).sh_addr; 777 old_bss_addr = OLD_SECTION_H (old_sbss_index).sh_addr;
774 old_bss_size = OLD_SECTION_H (old_bss_index).sh_size 778 old_bss_size = OLD_SECTION_H (old_bss_index).sh_size
775 + OLD_SECTION_H (old_sbss_index).sh_size; 779 + OLD_SECTION_H (old_sbss_index).sh_size;
780 old_bss_offset = OLD_SECTION_H (old_sbss_index).sh_offset;
776 new_data2_index = old_sbss_index; 781 new_data2_index = old_sbss_index;
777 } 782 }
778 783
@@ -789,17 +794,24 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
789#endif 794#endif
790 new_data2_addr = old_bss_addr; 795 new_data2_addr = old_bss_addr;
791 new_data2_size = new_bss_addr - old_bss_addr; 796 new_data2_size = new_bss_addr - old_bss_addr;
792 new_data2_offset = OLD_SECTION_H (old_data_index).sh_offset + 797 new_data2_offset = OLD_SECTION_H (old_data_index).sh_offset
793 (new_data2_addr - OLD_SECTION_H (old_data_index).sh_addr); 798 + (new_data2_addr - OLD_SECTION_H (old_data_index).sh_addr);
799 /* This is the amount by which the sections following the bss sections
800 must be shifted in the image. It can differ from new_data2_size if
801 the end of the old .data section (and thus the offset of the .bss
802 section) was unaligned. */
803 new_data2_incr = new_data2_size + (new_data2_offset - old_bss_offset);
794 804
795#ifdef DEBUG 805#ifdef DEBUG
796 fprintf (stderr, "old_bss_index %d\n", old_bss_index); 806 fprintf (stderr, "old_bss_index %d\n", old_bss_index);
797 fprintf (stderr, "old_bss_addr %x\n", old_bss_addr); 807 fprintf (stderr, "old_bss_addr %x\n", old_bss_addr);
798 fprintf (stderr, "old_bss_size %x\n", old_bss_size); 808 fprintf (stderr, "old_bss_size %x\n", old_bss_size);
809 fprintf (stderr, "old_bss_offset %x\n", old_bss_offset);
799 fprintf (stderr, "new_bss_addr %x\n", new_bss_addr); 810 fprintf (stderr, "new_bss_addr %x\n", new_bss_addr);
800 fprintf (stderr, "new_data2_addr %x\n", new_data2_addr); 811 fprintf (stderr, "new_data2_addr %x\n", new_data2_addr);
801 fprintf (stderr, "new_data2_size %x\n", new_data2_size); 812 fprintf (stderr, "new_data2_size %x\n", new_data2_size);
802 fprintf (stderr, "new_data2_offset %x\n", new_data2_offset); 813 fprintf (stderr, "new_data2_offset %x\n", new_data2_offset);
814 fprintf (stderr, "new_data2_incr %x\n", new_data2_incr);
803#endif 815#endif
804 816
805 if ((unsigned) new_bss_addr < (unsigned) old_bss_addr + old_bss_size) 817 if ((unsigned) new_bss_addr < (unsigned) old_bss_addr + old_bss_size)
@@ -813,7 +825,7 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
813 if (new_file < 0) 825 if (new_file < 0)
814 fatal ("Can't creat (%s): errno %d\n", new_name, errno); 826 fatal ("Can't creat (%s): errno %d\n", new_name, errno);
815 827
816 new_file_size = stat_buf.st_size + old_file_h->e_shentsize + new_data2_size; 828 new_file_size = stat_buf.st_size + old_file_h->e_shentsize + new_data2_incr;
817 829
818 if (ftruncate (new_file, new_file_size)) 830 if (ftruncate (new_file, new_file_size))
819 fatal ("Can't ftruncate (%s): errno %d\n", new_name, errno); 831 fatal ("Can't ftruncate (%s): errno %d\n", new_name, errno);
@@ -826,7 +838,7 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
826 new_file_h = (ElfW(Ehdr) *) new_base; 838 new_file_h = (ElfW(Ehdr) *) new_base;
827 new_program_h = (ElfW(Phdr) *) ((byte *) new_base + old_file_h->e_phoff); 839 new_program_h = (ElfW(Phdr) *) ((byte *) new_base + old_file_h->e_phoff);
828 new_section_h = (ElfW(Shdr) *) 840 new_section_h = (ElfW(Shdr) *)
829 ((byte *) new_base + old_file_h->e_shoff + new_data2_size); 841 ((byte *) new_base + old_file_h->e_shoff + new_data2_incr);
830 842
831 /* Make our new file, program and section headers as copies of the 843 /* Make our new file, program and section headers as copies of the
832 originals. */ 844 originals. */
@@ -841,7 +853,7 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
841 /* Fix up file header. We'll add one section. Section header is 853 /* Fix up file header. We'll add one section. Section header is
842 further away now. */ 854 further away now. */
843 855
844 new_file_h->e_shoff += new_data2_size; 856 new_file_h->e_shoff += new_data2_incr;
845 new_file_h->e_shnum += 1; 857 new_file_h->e_shnum += 1;
846 858
847#ifdef DEBUG 859#ifdef DEBUG
@@ -901,7 +913,7 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
901 NEW_PROGRAM_H (n).p_vaddr += new_data2_size - old_bss_size; 913 NEW_PROGRAM_H (n).p_vaddr += new_data2_size - old_bss_size;
902 914
903 if (NEW_PROGRAM_H (n).p_offset >= new_data2_offset) 915 if (NEW_PROGRAM_H (n).p_offset >= new_data2_offset)
904 NEW_PROGRAM_H (n).p_offset += new_data2_size; 916 NEW_PROGRAM_H (n).p_offset += new_data2_incr;
905 } 917 }
906#endif 918#endif
907 919
@@ -957,10 +969,8 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
957 ) 969 )
958 { 970 {
959 /* NN should be `old_s?bss_index + 1' at this point. */ 971 /* NN should be `old_s?bss_index + 1' at this point. */
960 NEW_SECTION_H (nn).sh_offset = 972 NEW_SECTION_H (nn).sh_offset = new_data2_offset + new_data2_size;
961 NEW_SECTION_H (new_data2_index).sh_offset + new_data2_size; 973 NEW_SECTION_H (nn).sh_addr = new_data2_addr + new_data2_size;
962 NEW_SECTION_H (nn).sh_addr =
963 NEW_SECTION_H (new_data2_index).sh_addr + new_data2_size;
964 /* Let the new bss section address alignment be the same as the 974 /* Let the new bss section address alignment be the same as the
965 section address alignment followed the old bss section, so 975 section address alignment followed the old bss section, so
966 this section will be placed in exactly the same place. */ 976 this section will be placed in exactly the same place. */
@@ -970,16 +980,15 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
970 else 980 else
971 { 981 {
972 /* Any section that was originally placed after the .bss 982 /* Any section that was originally placed after the .bss
973 section should now be off by NEW_DATA2_SIZE. If a 983 section should now be off by NEW_DATA2_INCR. If a
974 section overlaps the .bss section, consider it to be 984 section overlaps the .bss section, consider it to be
975 placed after the .bss section. Overlap can occur if the 985 placed after the .bss section. Overlap can occur if the
976 section just before .bss has less-strict alignment; this 986 section just before .bss has less-strict alignment; this
977 was observed between .symtab and .bss on Solaris 2.5.1 987 was observed between .symtab and .bss on Solaris 2.5.1
978 (sparc) with GCC snapshot 960602. */ 988 (sparc) with GCC snapshot 960602. */
979 989
980 if (NEW_SECTION_H (nn).sh_offset + NEW_SECTION_H (nn).sh_size 990 if (NEW_SECTION_H (nn).sh_offset >= old_bss_offset)
981 > new_data2_offset) 991 NEW_SECTION_H (nn).sh_offset += new_data2_incr;
982 NEW_SECTION_H (nn).sh_offset += new_data2_size;
983 992
984 /* Any section that was originally placed after the section 993 /* Any section that was originally placed after the section
985 header table should now be off by the size of one section 994 header table should now be off by the size of one section
@@ -1084,7 +1093,7 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
1084#if defined (_SYSTYPE_SYSV) 1093#if defined (_SYSTYPE_SYSV)
1085 if (NEW_SECTION_H (nn).sh_type == SHT_MIPS_DEBUG 1094 if (NEW_SECTION_H (nn).sh_type == SHT_MIPS_DEBUG
1086 && old_mdebug_index != -1) 1095 && old_mdebug_index != -1)
1087 { 1096 {
1088 int diff = NEW_SECTION_H(nn).sh_offset 1097 int diff = NEW_SECTION_H(nn).sh_offset
1089 - OLD_SECTION_H(old_mdebug_index).sh_offset; 1098 - OLD_SECTION_H(old_mdebug_index).sh_offset;
1090 HDRR *phdr = (HDRR *)(NEW_SECTION_H (nn).sh_offset + new_base); 1099 HDRR *phdr = (HDRR *)(NEW_SECTION_H (nn).sh_offset + new_base);