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