Mercurial > hg > xemacs-beta
comparison src/unexelf.c @ 359:8e84bee8ddd0 r21-1-9
Import from CVS: tag r21-1-9
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:57:55 +0200 |
parents | 4711e16a8e49 |
children | 1d62742628b6 |
comparison
equal
deleted
inserted
replaced
358:fed6e0f6a03a | 359:8e84bee8ddd0 |
---|---|
431 #if defined (__sony_news) && defined (_SYSTYPE_SYSV) | 431 #if defined (__sony_news) && defined (_SYSTYPE_SYSV) |
432 #include <sys/elf_mips.h> | 432 #include <sys/elf_mips.h> |
433 #include <sym.h> | 433 #include <sym.h> |
434 #endif /* __sony_news && _SYSTYPE_SYSV */ | 434 #endif /* __sony_news && _SYSTYPE_SYSV */ |
435 #ifdef __sgi | 435 #ifdef __sgi |
436 #include <sym.h> /* for HDRR declaration */ | 436 #include <syms.h> /* for HDRR declaration */ |
437 #endif /* __sgi */ | 437 #endif /* __sgi */ |
438 | 438 |
439 #if defined (__alpha__) && !defined (__NetBSD__) && !defined (__OpenBSD__) | 439 #if defined (__alpha__) && !defined (__NetBSD__) && !defined (__OpenBSD__) |
440 /* Declare COFF debugging symbol table. This used to be in | 440 /* Declare COFF debugging symbol table. This used to be in |
441 /usr/include/sym.h, but this file is no longer included in Red Hat | 441 /usr/include/sym.h, but this file is no longer included in Red Hat |
492 | 492 |
493 # define SHN_UNDEF Elf_eshn_undefined | 493 # define SHN_UNDEF Elf_eshn_undefined |
494 # define SHN_ABS Elf_eshn_absolute | 494 # define SHN_ABS Elf_eshn_absolute |
495 # define SHN_COMMON Elf_eshn_common | 495 # define SHN_COMMON Elf_eshn_common |
496 | 496 |
497 /* | |
498 * The magic of picking the right size types is handled by the ELFSIZE | |
499 * definition above. | |
500 */ | |
501 # ifdef __STDC__ | |
502 # define ElfW(type) Elf_##type | |
503 # else | |
504 # define ElfW(type) Elf_/**/type | |
505 # endif | |
506 | |
507 # ifdef __alpha__ | 497 # ifdef __alpha__ |
508 # include <sys/exec_ecoff.h> | 498 # include <sys/exec_ecoff.h> |
509 # define HDRR struct ecoff_symhdr | 499 # define HDRR struct ecoff_symhdr |
510 # define pHDRR HDRR * | 500 # define pHDRR HDRR * |
511 # endif | 501 # endif |
582 if (rem == 0) | 572 if (rem == 0) |
583 return x; | 573 return x; |
584 return x - rem + y; | 574 return x - rem + y; |
585 } | 575 } |
586 | 576 |
577 /* Return the index of the section named NAME. | |
578 SECTION_NAMES, FILE_NAME and FILE_H give information | |
579 about the file we are looking in. | |
580 | |
581 If we don't find the section NAME, that is a fatal error | |
582 if NOERROR is 0; we return -1 if NOERROR is nonzero. */ | |
583 | |
584 static int | |
585 find_section (name, section_names, file_name, old_file_h, old_section_h, noerror) | |
586 char *name; | |
587 char *section_names; | |
588 char *file_name; | |
589 ElfW(Ehdr) *old_file_h; | |
590 ElfW(Shdr) *old_section_h; | |
591 int noerror; | |
592 { | |
593 int idx; | |
594 | |
595 for (idx = 1; idx < old_file_h->e_shnum; idx++) | |
596 { | |
597 #ifdef DEBUG | |
598 fprintf (stderr, "Looking for %s - found %s\n", name, | |
599 section_names + OLD_SECTION_H (idx).sh_name); | |
600 #endif | |
601 if (!strcmp (section_names + OLD_SECTION_H (idx).sh_name, | |
602 name)) | |
603 break; | |
604 } | |
605 if (idx == old_file_h->e_shnum) | |
606 { | |
607 if (noerror) | |
608 return -1; | |
609 else | |
610 fatal ("Can't find %s in %s.\n", name, file_name, 0); | |
611 } | |
612 | |
613 return idx; | |
614 } | |
615 | |
587 /* **************************************************************** | 616 /* **************************************************************** |
588 * unexec | 617 * unexec |
589 * | 618 * |
590 * driving logic. | 619 * driving logic. |
591 * | 620 * |
617 ElfW(Addr) old_bss_addr, new_bss_addr; | 646 ElfW(Addr) old_bss_addr, new_bss_addr; |
618 ElfW(Word) old_bss_size, new_data2_size; | 647 ElfW(Word) old_bss_size, new_data2_size; |
619 ElfW(Off) new_data2_offset; | 648 ElfW(Off) new_data2_offset; |
620 ElfW(Addr) new_data2_addr; | 649 ElfW(Addr) new_data2_addr; |
621 | 650 |
622 int n, nn, old_bss_index, old_data_index, new_data2_index; | 651 int n, nn; |
623 int old_sbss_index, old_mdebug_index; | 652 int old_bss_index, old_sbss_index; |
653 int old_data_index, new_data2_index; | |
654 int old_mdebug_index; | |
624 struct stat stat_buf; | 655 struct stat stat_buf; |
625 | 656 |
626 /* Open the old file & map it into the address space. */ | 657 /* Open the old file & map it into the address space. */ |
627 | 658 |
628 old_file = open (old_name, O_RDONLY); | 659 old_file = open (old_name, O_RDONLY); |
649 old_program_h = (ElfW(Phdr) *) ((byte *) old_base + old_file_h->e_phoff); | 680 old_program_h = (ElfW(Phdr) *) ((byte *) old_base + old_file_h->e_phoff); |
650 old_section_h = (ElfW(Shdr) *) ((byte *) old_base + old_file_h->e_shoff); | 681 old_section_h = (ElfW(Shdr) *) ((byte *) old_base + old_file_h->e_shoff); |
651 old_section_names = (char *) old_base | 682 old_section_names = (char *) old_base |
652 + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset; | 683 + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset; |
653 | 684 |
685 /* Find the mdebug section, if any. */ | |
686 | |
687 old_mdebug_index = find_section (".mdebug", old_section_names, | |
688 old_name, old_file_h, old_section_h, 1); | |
689 | |
654 /* Find the old .bss section. Figure out parameters of the new | 690 /* Find the old .bss section. Figure out parameters of the new |
655 * data2 and bss sections. | 691 * data2 and bss sections. |
656 */ | 692 */ |
657 | 693 |
658 for (old_bss_index = 1; old_bss_index < (int) old_file_h->e_shnum; | 694 old_bss_index = find_section (".bss", old_section_names, |
659 old_bss_index++) | 695 old_name, old_file_h, old_section_h, 0); |
696 | |
697 old_sbss_index = find_section (".sbss", old_section_names, | |
698 old_name, old_file_h, old_section_h, 1); | |
699 | |
700 if (old_sbss_index == -1) | |
660 { | 701 { |
661 #ifdef DEBUG | 702 old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr; |
662 fprintf (stderr, "Looking for .bss - found %s\n", | 703 old_bss_size = OLD_SECTION_H (old_bss_index).sh_size; |
663 old_section_names + OLD_SECTION_H (old_bss_index).sh_name); | |
664 #endif | |
665 if (!strcmp (old_section_names + OLD_SECTION_H (old_bss_index).sh_name, | |
666 ELF_BSS_SECTION_NAME)) | |
667 break; | |
668 } | |
669 if (old_bss_index == old_file_h->e_shnum) | |
670 fatal ("Can't find .bss in %s.\n", old_name, 0); | |
671 | |
672 for (old_sbss_index = 1; old_sbss_index < (int) old_file_h->e_shnum; | |
673 old_sbss_index++) | |
674 { | |
675 #ifdef DEBUG | |
676 fprintf (stderr, "Looking for .sbss - found %s\n", | |
677 old_section_names + OLD_SECTION_H (old_sbss_index).sh_name); | |
678 #endif | |
679 if (!strcmp (old_section_names + OLD_SECTION_H (old_sbss_index).sh_name, | |
680 ".sbss")) | |
681 break; | |
682 } | |
683 if (old_sbss_index == old_file_h->e_shnum) | |
684 { | |
685 old_sbss_index = -1; | |
686 old_bss_addr = OLD_SECTION_H(old_bss_index).sh_addr; | |
687 old_bss_size = OLD_SECTION_H(old_bss_index).sh_size; | |
688 new_data2_offset = OLD_SECTION_H(old_bss_index).sh_offset; | |
689 new_data2_index = old_bss_index; | 704 new_data2_index = old_bss_index; |
690 } | 705 } |
691 else | 706 else |
692 { | 707 { |
693 old_bss_addr = OLD_SECTION_H(old_sbss_index).sh_addr; | 708 old_bss_addr = OLD_SECTION_H (old_sbss_index).sh_addr; |
694 old_bss_size = OLD_SECTION_H(old_bss_index).sh_size | 709 old_bss_size = OLD_SECTION_H (old_bss_index).sh_size |
695 + OLD_SECTION_H(old_sbss_index).sh_size; | 710 + OLD_SECTION_H (old_sbss_index).sh_size; |
696 new_data2_offset = OLD_SECTION_H(old_sbss_index).sh_offset; | |
697 new_data2_index = old_sbss_index; | 711 new_data2_index = old_sbss_index; |
698 } | 712 } |
699 | 713 |
700 for (old_mdebug_index = 1; old_mdebug_index < (int) old_file_h->e_shnum; | 714 /* Find the old .data section. Figure out parameters of |
701 old_mdebug_index++) | 715 the new data2 and bss sections. */ |
702 { | 716 |
703 #ifdef DEBUG | 717 old_data_index = find_section (".data", old_section_names, |
704 fprintf (stderr, "Looking for .mdebug - found %s\n", | 718 old_name, old_file_h, old_section_h, 0); |
705 old_section_names + OLD_SECTION_H (old_mdebug_index).sh_name); | |
706 #endif | |
707 if (!strcmp (old_section_names + OLD_SECTION_H (old_mdebug_index).sh_name, | |
708 ".mdebug")) | |
709 break; | |
710 } | |
711 if (old_mdebug_index == old_file_h->e_shnum) | |
712 old_mdebug_index = 0; | |
713 | 719 |
714 #if defined (emacs) || !defined (DEBUG) | 720 #if defined (emacs) || !defined (DEBUG) |
715 new_bss_addr = (ElfW(Addr)) sbrk (0); | 721 new_bss_addr = (ElfW(Addr)) sbrk (0); |
716 #else | 722 #else |
717 new_bss_addr = old_bss_addr + old_bss_size + 0x1234; | 723 new_bss_addr = old_bss_addr + old_bss_size + 0x1234; |
718 #endif | 724 #endif |
719 new_data2_addr = old_bss_addr; | 725 new_data2_addr = old_bss_addr; |
720 new_data2_size = new_bss_addr - old_bss_addr; | 726 new_data2_size = new_bss_addr - old_bss_addr; |
727 new_data2_offset = OLD_SECTION_H (old_data_index).sh_offset + | |
728 (new_data2_addr - OLD_SECTION_H (old_data_index).sh_addr); | |
721 | 729 |
722 #ifdef DEBUG | 730 #ifdef DEBUG |
723 fprintf (stderr, "old_bss_index %d\n", old_bss_index); | 731 fprintf (stderr, "old_bss_index %d\n", old_bss_index); |
724 fprintf (stderr, "old_bss_addr %x\n", old_bss_addr); | 732 fprintf (stderr, "old_bss_addr %x\n", old_bss_addr); |
725 fprintf (stderr, "old_bss_size %x\n", old_bss_size); | 733 fprintf (stderr, "old_bss_size %x\n", old_bss_size); |
800 /* Compute maximum of all requirements for alignment of section. */ | 808 /* Compute maximum of all requirements for alignment of section. */ |
801 ElfW(Word) alignment = (NEW_PROGRAM_H (n)).p_align; | 809 ElfW(Word) alignment = (NEW_PROGRAM_H (n)).p_align; |
802 if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment) | 810 if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment) |
803 alignment = OLD_SECTION_H (old_bss_index).sh_addralign; | 811 alignment = OLD_SECTION_H (old_bss_index).sh_addralign; |
804 | 812 |
805 #ifdef __mips | 813 #ifdef __sgi |
806 /* According to r02kar@x4u2.desy.de (Karsten Kuenne) | 814 /* According to r02kar@x4u2.desy.de (Karsten Kuenne) |
807 and oliva@gnu.org (Alexandre Oliva), on IRIX 5.2, we | 815 and oliva@gnu.org (Alexandre Oliva), on IRIX 5.2, we |
808 always get "Program segment above .bss" when dumping | 816 always get "Program segment above .bss" when dumping |
809 when the executable doesn't have an sbss section. */ | 817 when the executable doesn't have an sbss section. */ |
810 if (old_sbss_index != -1) | 818 if (old_sbss_index != -1) |
811 #endif /* __mips */ | 819 #endif /* __sgi */ |
812 if (NEW_PROGRAM_H (n).p_vaddr + NEW_PROGRAM_H (n).p_filesz | 820 if (NEW_PROGRAM_H (n).p_vaddr + NEW_PROGRAM_H (n).p_filesz |
813 > (old_sbss_index == -1 | 821 > (old_sbss_index == -1 |
814 ? old_bss_addr | 822 ? old_bss_addr |
815 : round_up (old_bss_addr, alignment))) | 823 : round_up (old_bss_addr, alignment))) |
816 fatal ("Program segment above .bss in %s\n", old_name, 0); | 824 fatal ("Program segment above .bss in %s\n", old_name, 0); |
954 ".data" in the strings table) get copied from the current process | 962 ".data" in the strings table) get copied from the current process |
955 instead of the old file. */ | 963 instead of the old file. */ |
956 if (!strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data") | 964 if (!strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data") |
957 || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name), | 965 || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name), |
958 ".sdata") | 966 ".sdata") |
959 /* Taking these sections from the current process, breaks | |
960 Linux in a subtle way. Binaries only run on the | |
961 architecture (e.g. i586 vs i686) of the dumping machine */ | |
962 #ifdef __sgi | |
963 || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name), | 967 || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name), |
964 ".lit4") | 968 ".lit4") |
965 || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name), | 969 || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name), |
966 ".lit8") | 970 ".lit8") |
967 || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name), | |
968 ".got") | |
969 #endif | |
970 || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name), | 971 || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name), |
971 ".sdata1") | 972 ".sdata1") |
972 || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name), | 973 || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name), |
973 ".data1")) | 974 ".data1")) |
974 src = (caddr_t) OLD_SECTION_H (n).sh_addr; | 975 src = (caddr_t) OLD_SECTION_H (n).sh_addr; |
998 symhdr->cbExtOffset += new_data2_size; | 999 symhdr->cbExtOffset += new_data2_size; |
999 } | 1000 } |
1000 #endif /* __alpha__ */ | 1001 #endif /* __alpha__ */ |
1001 | 1002 |
1002 #if defined (__sony_news) && defined (_SYSTYPE_SYSV) | 1003 #if defined (__sony_news) && defined (_SYSTYPE_SYSV) |
1003 if (NEW_SECTION_H (nn).sh_type == SHT_MIPS_DEBUG && old_mdebug_index) | 1004 if (NEW_SECTION_H (nn).sh_type == SHT_MIPS_DEBUG |
1005 && old_mdebug_index != -1) | |
1004 { | 1006 { |
1005 int diff = NEW_SECTION_H(nn).sh_offset | 1007 int diff = NEW_SECTION_H(nn).sh_offset |
1006 - OLD_SECTION_H(old_mdebug_index).sh_offset; | 1008 - OLD_SECTION_H(old_mdebug_index).sh_offset; |
1007 HDRR *phdr = (HDRR *)(NEW_SECTION_H (nn).sh_offset + new_base); | 1009 HDRR *phdr = (HDRR *)(NEW_SECTION_H (nn).sh_offset + new_base); |
1008 | 1010 |