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