comparison src/unexelfsgi.c @ 70:131b0175ea99 r20-0b30

Import from CVS: tag r20-0b30
author cvs
date Mon, 13 Aug 2007 09:02:59 +0200
parents 8b0bdfdf0cf0
children 0132846995bd
comparison
equal deleted inserted replaced
69:804d1389bcd6 70:131b0175ea99
477 So, the shift for all sections beyond the playing field is: 477 So, the shift for all sections beyond the playing field is:
478 478
479 new_bss_addr - roundup(old_bss_addr,0x1000) 479 new_bss_addr - roundup(old_bss_addr,0x1000)
480 480
481 */ 481 */
482 /* Still more mods... Olivier Galibert 19971705 482
483 - support for .sbss section (automagically changed to data without
484 name change)
485 - support for 64bits ABI (will need a bunch of fixes in the rest
486 of the code before it works
487 */
488 483
489 #include <sys/types.h> 484 #include <sys/types.h>
490 #include <stdio.h> 485 #include <stdio.h>
491 #include <sys/stat.h> 486 #include <sys/stat.h>
492 #include <memory.h> 487 #include <memory.h>
495 #include <unistd.h> 490 #include <unistd.h>
496 #include <fcntl.h> 491 #include <fcntl.h>
497 #include <elf.h> 492 #include <elf.h>
498 #include <sym.h> /* for HDRR declaration */ 493 #include <sym.h> /* for HDRR declaration */
499 #include <sys/mman.h> 494 #include <sys/mman.h>
500 #include <config.h>
501 #include "sysdep.h"
502
503 /* in 64bits mode, use 64bits elf */
504 #ifdef _ABI64
505 typedef Elf64_Shdr l_Elf_Shdr;
506 typedef Elf64_Phdr l_Elf_Phdr;
507 typedef Elf64_Ehdr l_Elf_Ehdr;
508 typedef Elf64_Addr l_Elf_Addr;
509 typedef Elf64_Word l_Elf_Word;
510 typedef Elf64_Off l_Elf_Off;
511 typedef Elf64_Sym l_Elf_Sym;
512 #else
513 typedef Elf32_Shdr l_Elf_Shdr;
514 typedef Elf32_Phdr l_Elf_Phdr;
515 typedef Elf32_Ehdr l_Elf_Ehdr;
516 typedef Elf32_Addr l_Elf_Addr;
517 typedef Elf32_Word l_Elf_Word;
518 typedef Elf32_Off l_Elf_Off;
519 typedef Elf32_Sym l_Elf_Sym;
520 #endif
521
522 495
523 #ifndef emacs 496 #ifndef emacs
524 #define fatal(a, b, c) fprintf(stderr, a, b, c), exit(1) 497 #define fatal(a, b, c) fprintf(stderr, a, b, c), exit(1)
525 #else 498 #else
526 extern void fatal(char *, ...); 499 extern void fatal(char *, ...);
529 /* Get the address of a particular section or program header entry, 502 /* Get the address of a particular section or program header entry,
530 * accounting for the size of the entries. 503 * accounting for the size of the entries.
531 */ 504 */
532 505
533 #define OLD_SECTION_H(n) \ 506 #define OLD_SECTION_H(n) \
534 (*(l_Elf_Shdr *) ((byte *) old_section_h + old_file_h->e_shentsize * (n))) 507 (*(Elf32_Shdr *) ((byte *) old_section_h + old_file_h->e_shentsize * (n)))
535 #define NEW_SECTION_H(n) \ 508 #define NEW_SECTION_H(n) \
536 (*(l_Elf_Shdr *) ((byte *) new_section_h + new_file_h->e_shentsize * (n))) 509 (*(Elf32_Shdr *) ((byte *) new_section_h + new_file_h->e_shentsize * (n)))
537 #define OLD_PROGRAM_H(n) \ 510 #define OLD_PROGRAM_H(n) \
538 (*(l_Elf_Phdr *) ((byte *) old_program_h + old_file_h->e_phentsize * (n))) 511 (*(Elf32_Phdr *) ((byte *) old_program_h + old_file_h->e_phentsize * (n)))
539 #define NEW_PROGRAM_H(n) \ 512 #define NEW_PROGRAM_H(n) \
540 (*(l_Elf_Phdr *) ((byte *) new_program_h + new_file_h->e_phentsize * (n))) 513 (*(Elf32_Phdr *) ((byte *) new_program_h + new_file_h->e_phentsize * (n)))
541 514
542 #define PATCH_INDEX(n) \ 515 #define PATCH_INDEX(n) \
543 do { \ 516 do { \
544 if ((n) >= old_bss_index) \ 517 if ((n) >= old_bss_index) \
545 (n)++; } while (0) 518 (n)++; } while (0)
546 typedef unsigned char byte; 519 typedef unsigned char byte;
547
548 /* IRIX 5 defines this only in inttypes.h, and you can't include both
549 * inttypes.h and sys/types.h. This is fixed by IRIX 6.2. */
550 #ifndef HAVE_UINTPTR_T
551 typedef unsigned long int uintptr_t;
552 #endif
553 520
554 /* Round X up to a multiple of Y. */ 521 /* Round X up to a multiple of Y. */
555 522
556 int 523 int
557 round_up (x, y) 524 round_up (x, y)
573 static int 540 static int
574 find_section (name, section_names, file_name, old_file_h, old_section_h, noerror) 541 find_section (name, section_names, file_name, old_file_h, old_section_h, noerror)
575 char *name; 542 char *name;
576 char *section_names; 543 char *section_names;
577 char *file_name; 544 char *file_name;
578 l_Elf_Ehdr *old_file_h; 545 Elf32_Ehdr *old_file_h;
579 l_Elf_Shdr *old_section_h; 546 Elf32_Shdr *old_section_h;
580 int noerror; 547 int noerror;
581 { 548 {
582 int idx; 549 int idx;
583 550
584 for (idx = 1; idx < old_file_h->e_shnum; idx++) 551 for (idx = 1; idx < old_file_h->e_shnum; idx++)
612 * 579 *
613 */ 580 */
614 void 581 void
615 unexec (new_name, old_name, data_start, bss_start, entry_address) 582 unexec (new_name, old_name, data_start, bss_start, entry_address)
616 char *new_name, *old_name; 583 char *new_name, *old_name;
617 uintptr_t data_start, bss_start, entry_address; 584 unsigned data_start, bss_start, entry_address;
618 { 585 {
619 extern uintptr_t bss_end; 586 extern unsigned int bss_end;
620 int new_file, old_file, new_file_size; 587 int new_file, old_file, new_file_size;
621 588
622 /* Pointers to the base of the image of the two files. */ 589 /* Pointers to the base of the image of the two files. */
623 caddr_t old_base, new_base; 590 caddr_t old_base, new_base;
624 591
625 /* Pointers to the file, program and section headers for the old and new 592 /* Pointers to the file, program and section headers for the old and new
626 files. */ 593 files. */
627 l_Elf_Ehdr *old_file_h, *new_file_h; 594 Elf32_Ehdr *old_file_h, *new_file_h;
628 l_Elf_Phdr *old_program_h, *new_program_h; 595 Elf32_Phdr *old_program_h, *new_program_h;
629 l_Elf_Shdr *old_section_h, *new_section_h; 596 Elf32_Shdr *old_section_h, *new_section_h;
630 597
631 /* Point to the section name table in the old file. */ 598 /* Point to the section name table in the old file. */
632 char *old_section_names; 599 char *old_section_names;
633 600
634 l_Elf_Addr old_bss_addr, new_bss_addr; 601 Elf32_Addr old_bss_addr, new_bss_addr;
635 l_Elf_Addr old_base_addr; 602 Elf32_Word old_bss_size, new_data2_size;
636 l_Elf_Word old_bss_size, new_data2_size; 603 Elf32_Off new_data2_offset;
637 l_Elf_Off new_data2_offset, new_base_offset; 604 Elf32_Addr new_data2_addr;
638 l_Elf_Addr new_data2_addr; 605 Elf32_Addr new_offsets_shift;
639 l_Elf_Addr new_offsets_shift;
640 606
641 int n, nn, old_bss_index, old_data_index, new_data2_index; 607 int n, nn, old_bss_index, old_data_index, new_data2_index;
642 int old_mdebug_index, old_sbss_index; 608 int old_mdebug_index;
643 struct stat stat_buf; 609 struct stat stat_buf;
644 610
645 /* Open the old file & map it into the address space. */ 611 /* Open the old file & map it into the address space. */
646 612
647 old_file = open (old_name, O_RDONLY); 613 old_file = open (old_name, O_RDONLY);
662 old_base); 628 old_base);
663 #endif 629 #endif
664 630
665 /* Get pointers to headers & section names. */ 631 /* Get pointers to headers & section names. */
666 632
667 old_file_h = (l_Elf_Ehdr *) old_base; 633 old_file_h = (Elf32_Ehdr *) old_base;
668 old_program_h = (l_Elf_Phdr *) ((byte *) old_base + old_file_h->e_phoff); 634 old_program_h = (Elf32_Phdr *) ((byte *) old_base + old_file_h->e_phoff);
669 old_section_h = (l_Elf_Shdr *) ((byte *) old_base + old_file_h->e_shoff); 635 old_section_h = (Elf32_Shdr *) ((byte *) old_base + old_file_h->e_shoff);
670 old_section_names 636 old_section_names
671 = (char *) old_base + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset; 637 = (char *) old_base + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset;
672 638
673 /* Find the mdebug section, if any. */ 639 /* Find the mdebug section, if any. */
674 640
675 old_mdebug_index = find_section (".mdebug", old_section_names, 641 old_mdebug_index = find_section (".mdebug", old_section_names,
676 old_name, old_file_h, old_section_h, 1); 642 old_name, old_file_h, old_section_h, 1);
677 643
678 /* Find the .sbss section, if any. */
679
680 old_sbss_index = find_section (".sbss", old_section_names,
681 old_name, old_file_h, old_section_h, 1);
682
683 /* Find the old .bss section. */ 644 /* Find the old .bss section. */
684 645
685 old_bss_index = find_section (".bss", old_section_names, 646 old_bss_index = find_section (".bss", old_section_names,
686 old_name, old_file_h, old_section_h, 0); 647 old_name, old_file_h, old_section_h, 0);
687 648
691 old_data_index = find_section (".data", old_section_names, 652 old_data_index = find_section (".data", old_section_names,
692 old_name, old_file_h, old_section_h, 0); 653 old_name, old_file_h, old_section_h, 0);
693 654
694 old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr; 655 old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr;
695 old_bss_size = OLD_SECTION_H (old_bss_index).sh_size; 656 old_bss_size = OLD_SECTION_H (old_bss_index).sh_size;
696 old_base_addr = old_sbss_index == -1 ? old_bss_addr : OLD_SECTION_H (old_sbss_index).sh_addr;
697 #if defined(emacs) || !defined(DEBUG) 657 #if defined(emacs) || !defined(DEBUG)
698 bss_end = (uintptr_t) sbrk (0); 658 bss_end = (unsigned int) sbrk (0);
699 new_bss_addr = (l_Elf_Addr) bss_end; 659 new_bss_addr = (Elf32_Addr) bss_end;
700 #else 660 #else
701 new_bss_addr = old_bss_addr + old_bss_size + 0x1234; 661 new_bss_addr = old_bss_addr + old_bss_size + 0x1234;
702 #endif 662 #endif
703 new_data2_addr = old_bss_addr; 663 new_data2_addr = old_bss_addr;
704 new_data2_size = new_bss_addr - old_bss_addr; 664 new_data2_size = new_bss_addr - old_bss_addr;
705 new_data2_offset = OLD_SECTION_H (old_data_index).sh_offset + 665 new_data2_offset = OLD_SECTION_H (old_data_index).sh_offset +
706 (new_data2_addr - OLD_SECTION_H (old_data_index).sh_addr); 666 (new_data2_addr - OLD_SECTION_H (old_data_index).sh_addr);
707 new_base_offset = OLD_SECTION_H (old_data_index).sh_offset +
708 (old_base_addr - OLD_SECTION_H (old_data_index).sh_addr);
709 new_offsets_shift = new_bss_addr - 667 new_offsets_shift = new_bss_addr -
710 ((old_base_addr & ~0xfff) + ((old_base_addr & 0xfff) ? 0x1000 : 0)); 668 ((old_bss_addr & ~0xfff) + ((old_bss_addr & 0xfff) ? 0x1000 : 0));
711 669
712 #ifdef DEBUG 670 #ifdef DEBUG
713 fprintf (stderr, "old_bss_index %d\n", old_bss_index); 671 fprintf (stderr, "old_bss_index %d\n", old_bss_index);
714 fprintf (stderr, "old_bss_addr %x\n", old_bss_addr); 672 fprintf (stderr, "old_bss_addr %x\n", old_bss_addr);
715 fprintf (stderr, "old_bss_size %x\n", old_bss_size); 673 fprintf (stderr, "old_bss_size %x\n", old_bss_size);
716 fprintf (stderr, "old_base_addr %x\n", old_base_addr);
717 fprintf (stderr, "new_bss_addr %x\n", new_bss_addr); 674 fprintf (stderr, "new_bss_addr %x\n", new_bss_addr);
718 fprintf (stderr, "new_data2_addr %x\n", new_data2_addr); 675 fprintf (stderr, "new_data2_addr %x\n", new_data2_addr);
719 fprintf (stderr, "new_data2_size %x\n", new_data2_size); 676 fprintf (stderr, "new_data2_size %x\n", new_data2_size);
720 fprintf (stderr, "new_data2_offset %x\n", new_data2_offset); 677 fprintf (stderr, "new_data2_offset %x\n", new_data2_offset);
721 fprintf (stderr, "new_offsets_shift %x\n", new_offsets_shift); 678 fprintf (stderr, "new_offsets_shift %x\n", new_offsets_shift);
743 new_file, 0); 700 new_file, 0);
744 701
745 if (new_base == (caddr_t) -1) 702 if (new_base == (caddr_t) -1)
746 fatal ("Can't mmap (%s): errno %d\n", new_name, errno); 703 fatal ("Can't mmap (%s): errno %d\n", new_name, errno);
747 704
748 new_file_h = (l_Elf_Ehdr *) new_base; 705 new_file_h = (Elf32_Ehdr *) new_base;
749 new_program_h = (l_Elf_Phdr *) ((byte *) new_base + old_file_h->e_phoff); 706 new_program_h = (Elf32_Phdr *) ((byte *) new_base + old_file_h->e_phoff);
750 new_section_h 707 new_section_h
751 = (l_Elf_Shdr *) ((byte *) new_base + old_file_h->e_shoff 708 = (Elf32_Shdr *) ((byte *) new_base + old_file_h->e_shoff
752 + new_offsets_shift); 709 + new_offsets_shift);
753 710
754 /* Make our new file, program and section headers as copies of the 711 /* Make our new file, program and section headers as copies of the
755 originals. */ 712 originals. */
756 713
788 if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment) 745 if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment)
789 alignment = OLD_SECTION_H (old_bss_index).sh_addralign; 746 alignment = OLD_SECTION_H (old_bss_index).sh_addralign;
790 747
791 /* Supposedly this condition is okay for the SGI. */ 748 /* Supposedly this condition is okay for the SGI. */
792 #if 0 749 #if 0
793 if (NEW_PROGRAM_H (n).p_vaddr + NEW_PROGRAM_H (n).p_filesz > old_base_addr) 750 if (NEW_PROGRAM_H (n).p_vaddr + NEW_PROGRAM_H (n).p_filesz > old_bss_addr)
794 fatal ("Program segment above .bss in %s\n", old_name, 0); 751 fatal ("Program segment above .bss in %s\n", old_name, 0);
795 #endif 752 #endif
796 753
797 if (NEW_PROGRAM_H (n).p_type == PT_LOAD 754 if (NEW_PROGRAM_H (n).p_type == PT_LOAD
798 && (round_up ((NEW_PROGRAM_H (n)).p_vaddr 755 && (round_up ((NEW_PROGRAM_H (n)).p_vaddr
799 + (NEW_PROGRAM_H (n)).p_filesz, 756 + (NEW_PROGRAM_H (n)).p_filesz,
800 alignment) 757 alignment)
801 == round_up (old_base_addr, alignment))) 758 == round_up (old_bss_addr, alignment)))
802 break; 759 break;
803 } 760 }
804 if (n < 0) 761 if (n < 0)
805 fatal ("Couldn't find segment next to %s in %s\n", 762 fatal ("Couldn't find segment next to .bss in %s\n", old_name, 0);
806 old_sbss_index == -1 ? ".sbss" : ".bss", old_name, 0);
807 763
808 NEW_PROGRAM_H (n).p_filesz += new_offsets_shift; 764 NEW_PROGRAM_H (n).p_filesz += new_offsets_shift;
809 NEW_PROGRAM_H (n).p_memsz = NEW_PROGRAM_H (n).p_filesz; 765 NEW_PROGRAM_H (n).p_memsz = NEW_PROGRAM_H (n).p_filesz;
810 766
811 #if 1 /* Maybe allow section after data2 - does this ever happen? */ 767 #if 1 /* Maybe allow section after data2 - does this ever happen? */
885 old_file_h->e_shentsize); 841 old_file_h->e_shentsize);
886 842
887 /* Any section that was original placed AFTER the bss 843 /* Any section that was original placed AFTER the bss
888 section must now be adjusted by NEW_OFFSETS_SHIFT. */ 844 section must now be adjusted by NEW_OFFSETS_SHIFT. */
889 845
890 if (NEW_SECTION_H (nn).sh_offset >= new_base_offset) 846 if (NEW_SECTION_H (nn).sh_offset >= new_data2_offset)
891 NEW_SECTION_H (nn).sh_offset += new_offsets_shift; 847 NEW_SECTION_H (nn).sh_offset += new_offsets_shift;
892 848
893 /* If any section hdr refers to the section after the new .data 849 /* If any section hdr refers to the section after the new .data
894 section, make it refer to next one because we have inserted 850 section, make it refer to next one because we have inserted
895 a new section in between. */ 851 a new section in between. */
899 so don't change it. */ 855 so don't change it. */
900 if (NEW_SECTION_H (nn).sh_type != SHT_SYMTAB 856 if (NEW_SECTION_H (nn).sh_type != SHT_SYMTAB
901 && NEW_SECTION_H (nn).sh_type != SHT_DYNSYM) 857 && NEW_SECTION_H (nn).sh_type != SHT_DYNSYM)
902 PATCH_INDEX (NEW_SECTION_H (nn).sh_info); 858 PATCH_INDEX (NEW_SECTION_H (nn).sh_info);
903 859
904 /* Fix the type and alignment for the .sbss section */
905 if (!strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".sbss"))
906 {
907 NEW_SECTION_H (nn).sh_type = SHT_PROGBITS;
908 NEW_SECTION_H (nn).sh_offset = round_up (NEW_SECTION_H (nn).sh_offset,
909 NEW_SECTION_H (nn).sh_addralign);
910 }
911
912 /* Now, start to copy the content of sections. */ 860 /* Now, start to copy the content of sections. */
913 if (NEW_SECTION_H (nn).sh_type == SHT_NULL 861 if (NEW_SECTION_H (nn).sh_type == SHT_NULL
914 || NEW_SECTION_H (nn).sh_type == SHT_NOBITS) 862 || NEW_SECTION_H (nn).sh_type == SHT_NOBITS)
915 continue; 863 continue;
916 864
917 /* Write out the sections. .data, .data1 and .sbss (and data2, called 865 /* Write out the sections. .data and .data1 (and data2, called
918 ".data" in the strings table) get copied from the current process 866 ".data" in the strings table) get copied from the current process
919 instead of the old file. */ 867 instead of the old file. */
920 if (!strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data") 868 if (!strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data")
921 || !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data1") 869 || !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data1")
922 || !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".got") 870 || !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".got"))
923 || !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".sbss"))
924 src = (caddr_t) OLD_SECTION_H (n).sh_addr; 871 src = (caddr_t) OLD_SECTION_H (n).sh_addr;
925 else 872 else
926 src = old_base + OLD_SECTION_H (n).sh_offset; 873 src = old_base + OLD_SECTION_H (n).sh_offset;
927 874
928 memcpy (NEW_SECTION_H (nn).sh_offset + new_base, src, 875 memcpy (NEW_SECTION_H (nn).sh_offset + new_base, src,
983 930
984 /* If it is the symbol table, its st_shndx field needs to be patched. */ 931 /* If it is the symbol table, its st_shndx field needs to be patched. */
985 if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB 932 if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB
986 || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM) 933 || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM)
987 { 934 {
988 l_Elf_Shdr *spt = &NEW_SECTION_H (nn); 935 Elf32_Shdr *spt = &NEW_SECTION_H (nn);
989 unsigned int num = spt->sh_size / spt->sh_entsize; 936 unsigned int num = spt->sh_size / spt->sh_entsize;
990 l_Elf_Sym * sym = (l_Elf_Sym *) (NEW_SECTION_H (nn).sh_offset 937 Elf32_Sym * sym = (Elf32_Sym *) (NEW_SECTION_H (nn).sh_offset
991 + new_base); 938 + new_base);
992 for (; num--; sym++) 939 for (; num--; sym++)
993 { 940 {
994 if (sym->st_shndx == SHN_UNDEF 941 if (sym->st_shndx == SHN_UNDEF
995 || sym->st_shndx == SHN_ABS 942 || sym->st_shndx == SHN_ABS