Mercurial > hg > xemacs-beta
comparison src/unexelfsgi.c @ 412:697ef44129c6 r21-2-14
Import from CVS: tag r21-2-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:20:41 +0200 |
parents | 74fd4e045ea6 |
children |
comparison
equal
deleted
inserted
replaced
411:12e008d41344 | 412:697ef44129c6 |
---|---|
613 /* Pointers to the file, program and section headers for the old and new | 613 /* Pointers to the file, program and section headers for the old and new |
614 files. */ | 614 files. */ |
615 l_Elf_Ehdr *old_file_h, *new_file_h; | 615 l_Elf_Ehdr *old_file_h, *new_file_h; |
616 l_Elf_Phdr *old_program_h, *new_program_h; | 616 l_Elf_Phdr *old_program_h, *new_program_h; |
617 l_Elf_Shdr *old_section_h, *new_section_h; | 617 l_Elf_Shdr *old_section_h, *new_section_h; |
618 l_Elf_Shdr *oldbss; | |
619 | 618 |
620 /* Point to the section name table in the old file. */ | 619 /* Point to the section name table in the old file. */ |
621 char *old_section_names; | 620 char *old_section_names; |
622 | 621 |
623 l_Elf_Addr old_bss_addr, new_bss_addr; | 622 l_Elf_Addr old_bss_addr, new_bss_addr; |
696 new_data2_size = new_bss_addr - old_bss_addr; | 695 new_data2_size = new_bss_addr - old_bss_addr; |
697 new_data2_offset = OLD_SECTION_H (old_data_index).sh_offset + | 696 new_data2_offset = OLD_SECTION_H (old_data_index).sh_offset + |
698 (new_data2_addr - OLD_SECTION_H (old_data_index).sh_addr); | 697 (new_data2_addr - OLD_SECTION_H (old_data_index).sh_addr); |
699 new_base_offset = OLD_SECTION_H (old_data_index).sh_offset + | 698 new_base_offset = OLD_SECTION_H (old_data_index).sh_offset + |
700 (old_base_addr - OLD_SECTION_H (old_data_index).sh_addr); | 699 (old_base_addr - OLD_SECTION_H (old_data_index).sh_addr); |
701 new_offsets_shift = new_bss_addr - (old_base_addr & ~0xfff) + | 700 new_offsets_shift = new_bss_addr - |
702 ((old_base_addr & 0xfff) ? 0x1000 : 0); | 701 ((old_base_addr & ~0xfff) + ((old_base_addr & 0xfff) ? 0x1000 : 0)); |
703 | 702 |
704 #ifdef DEBUG | 703 #ifdef DEBUG |
705 fprintf (stderr, "old_bss_index %d\n", old_bss_index); | 704 fprintf (stderr, "old_bss_index %d\n", old_bss_index); |
706 fprintf (stderr, "old_bss_addr %x\n", old_bss_addr); | 705 fprintf (stderr, "old_bss_addr %x\n", old_bss_addr); |
707 fprintf (stderr, "old_bss_size %x\n", old_bss_size); | 706 fprintf (stderr, "old_bss_size %x\n", old_bss_size); |
767 fprintf (stderr, "New section count %d\n", new_file_h->e_shnum); | 766 fprintf (stderr, "New section count %d\n", new_file_h->e_shnum); |
768 #endif | 767 #endif |
769 | 768 |
770 /* Fix up a new program header. Extend the writable data segment so | 769 /* Fix up a new program header. Extend the writable data segment so |
771 that the bss area is covered too. Find that segment by looking | 770 that the bss area is covered too. Find that segment by looking |
772 for one that starts before and ends after the .bss and it PT_LOADable. | 771 for a segment that ends just before the .bss area. Make sure |
773 Put a loop at the end to adjust the offset and address of any segment | 772 that no segments are above the new .data2. Put a loop at the end |
774 that is above data2, just in case we decide to allow this later. */ | 773 to adjust the offset and address of any segment that is above |
775 | 774 data2, just in case we decide to allow this later. */ |
776 oldbss = &OLD_SECTION_H(old_bss_index); | 775 |
777 for (n = new_file_h->e_phnum - 1; n >= 0; n--) | 776 for (n = new_file_h->e_phnum - 1; n >= 0; n--) |
778 { | 777 { |
779 /* Compute maximum of all requirements for alignment of section. */ | 778 /* Compute maximum of all requirements for alignment of section. */ |
780 l_Elf_Phdr * ph = (l_Elf_Phdr *)((byte *) new_program_h + | 779 int alignment = (NEW_PROGRAM_H (n)).p_align; |
781 new_file_h->e_phentsize*(n)); | 780 if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment) |
782 #ifdef DEBUG | 781 alignment = OLD_SECTION_H (old_bss_index).sh_addralign; |
783 printf ("%d @ %0x + %0x against %0x + %0x", | 782 |
784 n, ph->p_vaddr, ph->p_memsz, | 783 /* Supposedly this condition is okay for the SGI. */ |
785 oldbss->sh_addr, oldbss->sh_size); | 784 #if 0 |
785 if (NEW_PROGRAM_H (n).p_vaddr + NEW_PROGRAM_H (n).p_filesz > old_base_addr) | |
786 fatal ("Program segment above .bss in %s\n", old_name); | |
786 #endif | 787 #endif |
787 if ((ph->p_type == PT_LOAD) && | 788 |
788 (ph->p_vaddr <= oldbss->sh_addr) && | 789 if (NEW_PROGRAM_H (n).p_type == PT_LOAD |
789 ((ph->p_vaddr + ph->p_memsz)>=(oldbss->sh_addr + oldbss->sh_size))) { | 790 && (round_up ((NEW_PROGRAM_H (n)).p_vaddr |
790 ph->p_filesz += new_offsets_shift; | 791 + (NEW_PROGRAM_H (n)).p_filesz, |
791 ph->p_memsz = ph->p_filesz; | 792 alignment) |
792 #ifdef DEBUG | 793 == round_up (old_base_addr, alignment))) |
793 puts (" That's the one!"); | 794 break; |
794 fflush (stdout); | |
795 #endif | |
796 break; | |
797 } | |
798 #ifdef DEBUG | |
799 putchar ('\n'); | |
800 fflush (stdout); | |
801 #endif | |
802 } | 795 } |
803 if (n < 0) | 796 if (n < 0) |
804 fatal ("Couldn't find segment next to %s in %s\n", | 797 fatal ("Couldn't find segment next to %s in %s\n", |
805 old_sbss_index == -1 ? ".sbss" : ".bss", old_name); | 798 old_sbss_index == -1 ? ".sbss" : ".bss", old_name); |
806 | 799 |
800 NEW_PROGRAM_H (n).p_filesz += new_offsets_shift; | |
801 NEW_PROGRAM_H (n).p_memsz = NEW_PROGRAM_H (n).p_filesz; | |
807 | 802 |
808 #if 1 /* Maybe allow section after data2 - does this ever happen? */ | 803 #if 1 /* Maybe allow section after data2 - does this ever happen? */ |
809 for (n = new_file_h->e_phnum - 1; n >= 0; n--) | 804 for (n = new_file_h->e_phnum - 1; n >= 0; n--) |
810 { | 805 { |
811 if (NEW_PROGRAM_H (n).p_vaddr | 806 if (NEW_PROGRAM_H (n).p_vaddr |