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