comparison src/unexelf.c @ 371:cc15677e0335 r21-2b1

Import from CVS: tag r21-2b1
author cvs
date Mon, 13 Aug 2007 11:03:08 +0200
parents 1d62742628b6
children 6240c7796c7a
comparison
equal deleted inserted replaced
370:bd866891f083 371:cc15677e0335
16 You should have received a copy of the GNU General Public License 16 You should have received a copy of the GNU General Public License
17 along with XEmacs; see the file COPYING. If not, write to 17 along with XEmacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */ 19 Boston, MA 02111-1307, USA. */
20 20
21 /* Synched up with: FSF 20.4. */ 21 /* Synched up with: FSF 20.2. */
22 22
23 /* 23 /*
24 * unexec.c - Convert a running program into an a.out file. 24 * unexec.c - Convert a running program into an a.out file.
25 * 25 *
26 * Author: Spencer W. Thomas 26 * Author: Spencer W. Thomas
422 #include <memory.h> 422 #include <memory.h>
423 #include <string.h> 423 #include <string.h>
424 #include <errno.h> 424 #include <errno.h>
425 #include <unistd.h> 425 #include <unistd.h>
426 #include <fcntl.h> 426 #include <fcntl.h>
427 #if !defined (__OpenBSD__)
428 #include <elf.h> 427 #include <elf.h>
429 #endif
430 #include <sys/mman.h> 428 #include <sys/mman.h>
431 #if defined (__sony_news) && defined (_SYSTYPE_SYSV) 429
432 #include <sys/elf_mips.h> 430 #if __GLIBC__ - 0 >= 2
433 #include <sym.h>
434 #endif /* __sony_news && _SYSTYPE_SYSV */
435 #ifdef __sgi
436 #include <syms.h> /* for HDRR declaration */
437 #endif /* __sgi */
438
439 #if defined (__alpha__) && !defined (__NetBSD__) && !defined (__OpenBSD__)
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
442 5.0 and presumably in any other glibc 2.x based distribution. */
443 typedef struct {
444 short magic;
445 short vstamp;
446 int ilineMax;
447 int idnMax;
448 int ipdMax;
449 int isymMax;
450 int ioptMax;
451 int iauxMax;
452 int issMax;
453 int issExtMax;
454 int ifdMax;
455 int crfd;
456 int iextMax;
457 long cbLine;
458 long cbLineOffset;
459 long cbDnOffset;
460 long cbPdOffset;
461 long cbSymOffset;
462 long cbOptOffset;
463 long cbAuxOffset;
464 long cbSsOffset;
465 long cbSsExtOffset;
466 long cbFdOffset;
467 long cbRfdOffset;
468 long cbExtOffset;
469 } HDRR, *pHDRR;
470 #define cbHDRR sizeof(HDRR)
471 #define hdrNil ((pHDRR)0)
472 #endif
473
474 #ifdef __OpenBSD__
475 # include <sys/exec_elf.h>
476 #endif
477
478 #if __GNU_LIBRARY__ - 0 >= 6
479 # include <link.h> /* get ElfW etc */ 431 # include <link.h> /* get ElfW etc */
480 #endif 432 #endif
481 433
482 #ifndef ElfW 434 #ifndef ElfW
483 # ifdef __STDC__ 435 # ifdef __STDC__
533 (n)++; } while (0) 485 (n)++; } while (0)
534 typedef unsigned char byte; 486 typedef unsigned char byte;
535 487
536 /* Round X up to a multiple of Y. */ 488 /* Round X up to a multiple of Y. */
537 489
538 static ElfW(Addr) 490 static int
539 round_up (ElfW(Addr) x, ElfW(Addr) y) 491 round_up (int x, int y)
540 { 492 {
541 int rem = x % y; 493 int rem = x % y;
542 if (rem == 0) 494 if (rem == 0)
543 return x; 495 return x;
544 return x - rem + y; 496 return x - rem + y;
545 }
546
547 /* Return the index of the section named NAME.
548 SECTION_NAMES, FILE_NAME and FILE_H give information
549 about the file we are looking in.
550
551 If we don't find the section NAME, that is a fatal error
552 if NOERROR is 0; we return -1 if NOERROR is nonzero. */
553
554 static int
555 find_section (name, section_names, file_name, old_file_h, old_section_h, noerror)
556 char *name;
557 char *section_names;
558 char *file_name;
559 ElfW(Ehdr) *old_file_h;
560 ElfW(Shdr) *old_section_h;
561 int noerror;
562 {
563 int idx;
564
565 for (idx = 1; idx < old_file_h->e_shnum; idx++)
566 {
567 #ifdef DEBUG
568 fprintf (stderr, "Looking for %s - found %s\n", name,
569 section_names + OLD_SECTION_H (idx).sh_name);
570 #endif
571 if (!strcmp (section_names + OLD_SECTION_H (idx).sh_name,
572 name))
573 break;
574 }
575 if (idx == old_file_h->e_shnum)
576 {
577 if (noerror)
578 return -1;
579 else
580 fatal ("Can't find %s in %s.\n", name, file_name, 0);
581 }
582
583 return idx;
584 } 497 }
585 498
586 /* **************************************************************** 499 /* ****************************************************************
587 * unexec 500 * unexec
588 * 501 *
616 ElfW(Addr) old_bss_addr, new_bss_addr; 529 ElfW(Addr) old_bss_addr, new_bss_addr;
617 ElfW(Word) old_bss_size, new_data2_size; 530 ElfW(Word) old_bss_size, new_data2_size;
618 ElfW(Off) new_data2_offset; 531 ElfW(Off) new_data2_offset;
619 ElfW(Addr) new_data2_addr; 532 ElfW(Addr) new_data2_addr;
620 533
621 int n, nn; 534 int n, nn, old_bss_index, old_data_index;
622 int old_bss_index, old_sbss_index;
623 int old_data_index, new_data2_index;
624 int old_mdebug_index;
625 struct stat stat_buf; 535 struct stat stat_buf;
626 536
627 /* Open the old file & map it into the address space. */ 537 /* Open the old file & map it into the address space. */
628 538
629 old_file = open (old_name, O_RDONLY); 539 old_file = open (old_name, O_RDONLY);
650 old_program_h = (ElfW(Phdr) *) ((byte *) old_base + old_file_h->e_phoff); 560 old_program_h = (ElfW(Phdr) *) ((byte *) old_base + old_file_h->e_phoff);
651 old_section_h = (ElfW(Shdr) *) ((byte *) old_base + old_file_h->e_shoff); 561 old_section_h = (ElfW(Shdr) *) ((byte *) old_base + old_file_h->e_shoff);
652 old_section_names = (char *) old_base 562 old_section_names = (char *) old_base
653 + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset; 563 + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset;
654 564
655 /* Find the mdebug section, if any. */
656
657 old_mdebug_index = find_section (".mdebug", old_section_names,
658 old_name, old_file_h, old_section_h, 1);
659
660 /* Find the old .bss section. Figure out parameters of the new 565 /* Find the old .bss section. Figure out parameters of the new
661 * data2 and bss sections. 566 * data2 and bss sections.
662 */ 567 */
663 568
664 old_bss_index = find_section (".bss", old_section_names, 569 for (old_bss_index = 1; old_bss_index < (int) old_file_h->e_shnum;
665 old_name, old_file_h, old_section_h, 0); 570 old_bss_index++)
666
667 old_sbss_index = find_section (".sbss", old_section_names,
668 old_name, old_file_h, old_section_h, 1);
669
670 if (old_sbss_index == -1)
671 { 571 {
672 old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr; 572 #ifdef DEBUG
673 old_bss_size = OLD_SECTION_H (old_bss_index).sh_size; 573 fprintf (stderr, "Looking for .bss - found %s\n",
674 new_data2_index = old_bss_index; 574 old_section_names + OLD_SECTION_H (old_bss_index).sh_name);
575 #endif
576 if (!strcmp (old_section_names + OLD_SECTION_H (old_bss_index).sh_name,
577 ELF_BSS_SECTION_NAME))
578 break;
675 } 579 }
676 else 580 if (old_bss_index == old_file_h->e_shnum)
677 { 581 fatal ("Can't find .bss in %s.\n", old_name, 0);
678 old_bss_addr = OLD_SECTION_H (old_sbss_index).sh_addr; 582
679 old_bss_size = OLD_SECTION_H (old_bss_index).sh_size 583 old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr;
680 + OLD_SECTION_H (old_sbss_index).sh_size; 584 old_bss_size = OLD_SECTION_H (old_bss_index).sh_size;
681 new_data2_index = old_sbss_index;
682 }
683
684 /* Find the old .data section. Figure out parameters of
685 the new data2 and bss sections. */
686
687 old_data_index = find_section (".data", old_section_names,
688 old_name, old_file_h, old_section_h, 0);
689
690 #if defined (emacs) || !defined (DEBUG) 585 #if defined (emacs) || !defined (DEBUG)
691 new_bss_addr = (ElfW(Addr)) sbrk (0); 586 new_bss_addr = (ElfW(Addr)) sbrk (0);
692 #else 587 #else
693 new_bss_addr = old_bss_addr + old_bss_size + 0x1234; 588 new_bss_addr = old_bss_addr + old_bss_size + 0x1234;
694 #endif 589 #endif
695 new_data2_addr = old_bss_addr; 590 new_data2_addr = old_bss_addr;
696 new_data2_size = new_bss_addr - old_bss_addr; 591 new_data2_size = new_bss_addr - old_bss_addr;
697 new_data2_offset = OLD_SECTION_H (old_data_index).sh_offset + 592 new_data2_offset = OLD_SECTION_H (old_bss_index).sh_offset;
698 (new_data2_addr - OLD_SECTION_H (old_data_index).sh_addr);
699 593
700 #ifdef DEBUG 594 #ifdef DEBUG
701 fprintf (stderr, "old_bss_index %d\n", old_bss_index); 595 fprintf (stderr, "old_bss_index %d\n", old_bss_index);
702 fprintf (stderr, "old_bss_addr %x\n", old_bss_addr); 596 fprintf (stderr, "old_bss_addr %x\n", old_bss_addr);
703 fprintf (stderr, "old_bss_size %x\n", old_bss_size); 597 fprintf (stderr, "old_bss_size %x\n", old_bss_size);
778 /* Compute maximum of all requirements for alignment of section. */ 672 /* Compute maximum of all requirements for alignment of section. */
779 ElfW(Word) alignment = (NEW_PROGRAM_H (n)).p_align; 673 ElfW(Word) alignment = (NEW_PROGRAM_H (n)).p_align;
780 if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment) 674 if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment)
781 alignment = OLD_SECTION_H (old_bss_index).sh_addralign; 675 alignment = OLD_SECTION_H (old_bss_index).sh_addralign;
782 676
783 #ifdef __sgi 677 #ifndef __mips /* ifndef added by jwz at suggestion of
784 /* According to r02kar@x4u2.desy.de (Karsten Kuenne) 678 r02kar@x4u2.desy.de (Karsten Kuenne) to avoid
785 and oliva@gnu.org (Alexandre Oliva), on IRIX 5.2, we 679 "Program segment above .bss" when dumping.
786 always get "Program segment above .bss" when dumping 680 */
787 when the executable doesn't have an sbss section. */ 681 if (NEW_PROGRAM_H (n).p_vaddr + NEW_PROGRAM_H (n).p_filesz > old_bss_addr)
788 if (old_sbss_index != -1) 682 fatal ("Program segment above .bss in %s\n", old_name, 0);
789 #endif /* __sgi */ 683 #endif /* __mips */
790 if (NEW_PROGRAM_H (n).p_vaddr + NEW_PROGRAM_H (n).p_filesz
791 > (old_sbss_index == -1
792 ? old_bss_addr
793 : round_up (old_bss_addr, alignment)))
794 fatal ("Program segment above .bss in %s\n", old_name, 0);
795 684
796 if (NEW_PROGRAM_H (n).p_type == PT_LOAD 685 if (NEW_PROGRAM_H (n).p_type == PT_LOAD
797 && (round_up ((NEW_PROGRAM_H (n)).p_vaddr 686 && (round_up ((int) ((NEW_PROGRAM_H (n)).p_vaddr
798 + (NEW_PROGRAM_H (n)).p_filesz, 687 + (NEW_PROGRAM_H (n)).p_filesz),
799 alignment) 688 alignment)
800 == round_up (old_bss_addr, alignment))) 689 == round_up ((int) old_bss_addr, alignment)))
801 break; 690 break;
802 } 691 }
803 if (n < 0) 692 if (n < 0)
804 fatal ("Couldn't find segment next to .bss in %s\n", old_name, 0); 693 fatal ("Couldn't find segment next to .bss in %s\n", old_name, 0);
805 694
806 /* Make sure that the size includes any padding before the old .bss
807 section. */
808 NEW_PROGRAM_H (n).p_filesz = new_bss_addr - NEW_PROGRAM_H (n).p_vaddr; 695 NEW_PROGRAM_H (n).p_filesz = new_bss_addr - NEW_PROGRAM_H (n).p_vaddr;
809 NEW_PROGRAM_H (n).p_memsz = NEW_PROGRAM_H (n).p_filesz; 696 NEW_PROGRAM_H (n).p_memsz = NEW_PROGRAM_H (n).p_filesz;
810 697
811 #if 0 /* Maybe allow section after data2 - does this ever happen? */ 698 #if 0 /* Maybe allow section after data2 - does this ever happen? */
812 for (n = new_file_h->e_phnum - 1; n >= 0; n--) 699 for (n = new_file_h->e_phnum - 1; n >= 0; n--)
837 /* Walk through all section headers, insert the new data2 section right 724 /* Walk through all section headers, insert the new data2 section right
838 before the new bss section. */ 725 before the new bss section. */
839 for (n = 1, nn = 1; n < (int) old_file_h->e_shnum; n++, nn++) 726 for (n = 1, nn = 1; n < (int) old_file_h->e_shnum; n++, nn++)
840 { 727 {
841 caddr_t src; 728 caddr_t src;
842 /* If it is (s)bss section, insert the new data2 section before it. */ 729 /* If it is bss section, insert the new data2 section before it. */
843 /* new_data2_index is the index of either old_sbss or old_bss, that was 730 if (n == old_bss_index)
844 chosen as a section for new_data2. */
845 if (n == new_data2_index)
846 { 731 {
847 /* Steal the data section header for this data2 section. */ 732 /* Steal the data section header for this data2 section. */
848 memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (old_data_index), 733 memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (old_data_index),
849 new_file_h->e_shentsize); 734 new_file_h->e_shentsize);
850 735
857 NEW_SECTION_H (nn).sh_addralign = OLD_SECTION_H (n).sh_addralign; 742 NEW_SECTION_H (nn).sh_addralign = OLD_SECTION_H (n).sh_addralign;
858 743
859 /* Now copy over what we have in the memory now. */ 744 /* Now copy over what we have in the memory now. */
860 memcpy (NEW_SECTION_H (nn).sh_offset + new_base, 745 memcpy (NEW_SECTION_H (nn).sh_offset + new_base,
861 (caddr_t) OLD_SECTION_H (n).sh_addr, 746 (caddr_t) OLD_SECTION_H (n).sh_addr,
747 /* #### mrb: should be old_bss_size instead? */
862 new_data2_size); 748 new_data2_size);
863 nn++; 749 nn++;
864 } 750 }
865 751
866 memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (n), 752 memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (n),
867 old_file_h->e_shentsize); 753 old_file_h->e_shentsize);
868 754
869 if (n == old_bss_index 755 /* The new bss section's size is zero, and its file offset and virtual
870 /* The new bss and sbss section's size is zero, and its file offset 756 address should be off by NEW_DATA2_SIZE. */
871 and virtual address should be off by NEW_DATA2_SIZE. */ 757 if (n == old_bss_index)
872 || n == old_sbss_index
873 )
874 { 758 {
875 /* NN should be `old_s?bss_index + 1' at this point. */ 759 /* NN should be `old_bss_index + 1' at this point. */
876 NEW_SECTION_H (nn).sh_offset = 760 NEW_SECTION_H (nn).sh_offset += new_data2_size;
877 NEW_SECTION_H (new_data2_index).sh_offset + new_data2_size; 761 NEW_SECTION_H (nn).sh_addr += new_data2_size;
878 NEW_SECTION_H (nn).sh_addr =
879 NEW_SECTION_H (new_data2_index).sh_addr + new_data2_size;
880 /* Let the new bss section address alignment be the same as the 762 /* Let the new bss section address alignment be the same as the
881 section address alignment followed the old bss section, so 763 section address alignment followed the old bss section, so
882 this section will be placed in exactly the same place. */ 764 this section will be placed in exactly the same place. */
883 NEW_SECTION_H (nn).sh_addralign = OLD_SECTION_H (nn).sh_addralign; 765 NEW_SECTION_H (nn).sh_addralign = OLD_SECTION_H (nn).sh_addralign;
884 NEW_SECTION_H (nn).sh_size = 0; 766 NEW_SECTION_H (nn).sh_size = 0;
898 Erik Deumens, deumens@qtp.ufl.edu. */ 780 Erik Deumens, deumens@qtp.ufl.edu. */
899 if (NEW_SECTION_H (nn).sh_offset 781 if (NEW_SECTION_H (nn).sh_offset
900 >= OLD_SECTION_H (old_bss_index-1).sh_offset) 782 >= OLD_SECTION_H (old_bss_index-1).sh_offset)
901 NEW_SECTION_H (nn).sh_offset += new_data2_size; 783 NEW_SECTION_H (nn).sh_offset += new_data2_size;
902 #else 784 #else
903 if (round_up (NEW_SECTION_H (nn).sh_offset, 785 if (NEW_SECTION_H (nn).sh_offset >= new_data2_offset)
904 OLD_SECTION_H (old_bss_index).sh_addralign)
905 >= new_data2_offset)
906 NEW_SECTION_H (nn).sh_offset += new_data2_size; 786 NEW_SECTION_H (nn).sh_offset += new_data2_size;
907 #endif 787 #endif
908 /* Any section that was originally placed after the section 788 /* Any section that was originally placed after the section
909 header table should now be off by the size of one section 789 header table should now be off by the size of one section
910 header table entry. */ 790 header table entry. */
929 continue; 809 continue;
930 810
931 /* Write out the sections. .data and .data1 (and data2, called 811 /* Write out the sections. .data and .data1 (and data2, called
932 ".data" in the strings table) get copied from the current process 812 ".data" in the strings table) get copied from the current process
933 instead of the old file. */ 813 instead of the old file. */
814 #ifdef __powerpc__
815 /* The PowerPC has additional 'data' segments which need to be saved */
816 if (!strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data") ||
817 !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data1") ||
818 !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".sdata") ||
819 !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".sdata1"))
820 #else
934 if (!strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data") 821 if (!strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data")
935 || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name), 822 || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
936 ".sdata")
937 || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
938 ".lit4")
939 || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
940 ".lit8")
941 || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
942 ".sdata1")
943 || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
944 ".data1")) 823 ".data1"))
824 #endif
945 src = (caddr_t) OLD_SECTION_H (n).sh_addr; 825 src = (caddr_t) OLD_SECTION_H (n).sh_addr;
946 else 826 else
947 src = old_base + OLD_SECTION_H (n).sh_offset; 827 src = old_base + OLD_SECTION_H (n).sh_offset;
948 828
949 memcpy (NEW_SECTION_H (nn).sh_offset + new_base, src, 829 memcpy (NEW_SECTION_H (nn).sh_offset + new_base, src,
950 NEW_SECTION_H (nn).sh_size); 830 NEW_SECTION_H (nn).sh_size);
951
952 #ifdef __alpha__
953 /* Update Alpha COFF symbol table: */
954 if (strcmp (old_section_names + OLD_SECTION_H (n).sh_name, ".mdebug")
955 == 0)
956 {
957 pHDRR symhdr = (pHDRR) (NEW_SECTION_H (nn).sh_offset + new_base);
958
959 symhdr->cbLineOffset += new_data2_size;
960 symhdr->cbDnOffset += new_data2_size;
961 symhdr->cbPdOffset += new_data2_size;
962 symhdr->cbSymOffset += new_data2_size;
963 symhdr->cbOptOffset += new_data2_size;
964 symhdr->cbAuxOffset += new_data2_size;
965 symhdr->cbSsOffset += new_data2_size;
966 symhdr->cbSsExtOffset += new_data2_size;
967 symhdr->cbFdOffset += new_data2_size;
968 symhdr->cbRfdOffset += new_data2_size;
969 symhdr->cbExtOffset += new_data2_size;
970 }
971 #endif /* __alpha__ */
972
973 #if defined (__sony_news) && defined (_SYSTYPE_SYSV)
974 if (NEW_SECTION_H (nn).sh_type == SHT_MIPS_DEBUG
975 && old_mdebug_index != -1)
976 {
977 int diff = NEW_SECTION_H(nn).sh_offset
978 - OLD_SECTION_H(old_mdebug_index).sh_offset;
979 HDRR *phdr = (HDRR *)(NEW_SECTION_H (nn).sh_offset + new_base);
980
981 if (diff)
982 {
983 phdr->cbLineOffset += diff;
984 phdr->cbDnOffset += diff;
985 phdr->cbPdOffset += diff;
986 phdr->cbSymOffset += diff;
987 phdr->cbOptOffset += diff;
988 phdr->cbAuxOffset += diff;
989 phdr->cbSsOffset += diff;
990 phdr->cbSsExtOffset += diff;
991 phdr->cbFdOffset += diff;
992 phdr->cbRfdOffset += diff;
993 phdr->cbExtOffset += diff;
994 }
995 }
996 #endif /* __sony_news && _SYSTYPE_SYSV */
997
998 #ifdef __sgi
999 /* Adjust the HDRR offsets in .mdebug and copy the
1000 line data if it's in its usual 'hole' in the object.
1001 Makes the new file debuggable with dbx.
1002 patches up two problems: the absolute file offsets
1003 in the HDRR record of .mdebug (see /usr/include/syms.h), and
1004 the ld bug that gets the line table in a hole in the
1005 elf file rather than in the .mdebug section proper.
1006 David Anderson. davea@sgi.com Jan 16,1994. */
1007 if (n == old_mdebug_index)
1008 {
1009 #define MDEBUGADJUST(__ct,__fileaddr) \
1010 if (n_phdrr->__ct > 0) \
1011 { \
1012 n_phdrr->__fileaddr += movement; \
1013 }
1014
1015 HDRR * o_phdrr = (HDRR *)((byte *)old_base + OLD_SECTION_H (n).sh_offset);
1016 HDRR * n_phdrr = (HDRR *)((byte *)new_base + NEW_SECTION_H (nn).sh_offset);
1017 unsigned movement = new_data2_size;
1018
1019 MDEBUGADJUST (idnMax, cbDnOffset);
1020 MDEBUGADJUST (ipdMax, cbPdOffset);
1021 MDEBUGADJUST (isymMax, cbSymOffset);
1022 MDEBUGADJUST (ioptMax, cbOptOffset);
1023 MDEBUGADJUST (iauxMax, cbAuxOffset);
1024 MDEBUGADJUST (issMax, cbSsOffset);
1025 MDEBUGADJUST (issExtMax, cbSsExtOffset);
1026 MDEBUGADJUST (ifdMax, cbFdOffset);
1027 MDEBUGADJUST (crfd, cbRfdOffset);
1028 MDEBUGADJUST (iextMax, cbExtOffset);
1029 /* The Line Section, being possible off in a hole of the object,
1030 requires special handling. */
1031 if (n_phdrr->cbLine > 0)
1032 {
1033 if (o_phdrr->cbLineOffset > (OLD_SECTION_H (n).sh_offset
1034 + OLD_SECTION_H (n).sh_size))
1035 {
1036 /* line data is in a hole in elf. do special copy and adjust
1037 for this ld mistake.
1038 */
1039 n_phdrr->cbLineOffset += movement;
1040
1041 memcpy (n_phdrr->cbLineOffset + new_base,
1042 o_phdrr->cbLineOffset + old_base, n_phdrr->cbLine);
1043 }
1044 else
1045 {
1046 /* somehow line data is in .mdebug as it is supposed to be. */
1047 MDEBUGADJUST (cbLine, cbLineOffset);
1048 }
1049 }
1050 }
1051 #endif /* __sgi */
1052 831
1053 /* If it is the symbol table, its st_shndx field needs to be patched. */ 832 /* If it is the symbol table, its st_shndx field needs to be patched. */
1054 if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB 833 if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB
1055 || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM) 834 || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM)
1056 { 835 {
1085 symp = (ElfW(Sym) *) (NEW_SECTION_H (n).sh_offset + new_base); 864 symp = (ElfW(Sym) *) (NEW_SECTION_H (n).sh_offset + new_base);
1086 symendp = (ElfW(Sym) *) ((byte *)symp + NEW_SECTION_H (n).sh_size); 865 symendp = (ElfW(Sym) *) ((byte *)symp + NEW_SECTION_H (n).sh_size);
1087 866
1088 for (; symp < symendp; symp ++) 867 for (; symp < symendp; symp ++)
1089 if (strcmp ((char *) (symnames + symp->st_name), "_end") == 0 868 if (strcmp ((char *) (symnames + symp->st_name), "_end") == 0
1090 || strcmp ((char *) (symnames + symp->st_name), "end") == 0 869 || strcmp ((char *) (symnames + symp->st_name), "_edata") == 0)
1091 || strcmp ((char *) (symnames + symp->st_name), "_edata") == 0
1092 || strcmp ((char *) (symnames + symp->st_name), "edata") == 0)
1093 memcpy (&symp->st_value, &new_bss_addr, sizeof (new_bss_addr)); 870 memcpy (&symp->st_value, &new_bss_addr, sizeof (new_bss_addr));
1094 } 871 }
1095 872
1096 /* This loop seeks out relocation sections for the data section, so 873 /* This loop seeks out relocation sections for the data section, so
1097 that it can undo relocations performed by the runtime linker. */ 874 that it can undo relocations performed by the runtime linker. */
1105 case SHT_RELA: 882 case SHT_RELA:
1106 /* This code handles two different size structs, but there should 883 /* This code handles two different size structs, but there should
1107 be no harm in that provided that r_offset is always the first 884 be no harm in that provided that r_offset is always the first
1108 member. */ 885 member. */
1109 nn = section.sh_info; 886 nn = section.sh_info;
887 #ifdef __powerpc__
888 /* The PowerPC has additional 'data' segments which need to be saved */
889 if (!strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data") ||
890 !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data1") ||
891 !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".sdata") ||
892 !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".sdata1"))
893 #else
1110 if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data") 894 if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data")
1111 || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), 895 || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
1112 ".sdata")
1113 #ifdef __sgi
1114 || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
1115 ".lit4")
1116 || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
1117 ".lit8")
1118 || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
1119 ".got")
1120 #endif
1121 || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
1122 ".sdata1")
1123 || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
1124 ".data1")) 896 ".data1"))
897 #endif
1125 { 898 {
1126 ElfW(Addr) offset = NEW_SECTION_H (nn).sh_addr - 899 ElfW(Addr) offset = NEW_SECTION_H (nn).sh_addr -
1127 NEW_SECTION_H (nn).sh_offset; 900 NEW_SECTION_H (nn).sh_offset;
1128 caddr_t reloc = old_base + section.sh_offset, end; 901 caddr_t reloc = old_base + section.sh_offset, end;
1129 for (end = reloc + section.sh_size; reloc < end; 902 for (end = reloc + section.sh_size; reloc < end;
1130 reloc += section.sh_entsize) 903 reloc += section.sh_entsize)
1131 { 904 {
1132 ElfW(Addr) addr = ((ElfW(Rel) *) reloc)->r_offset - offset; 905 ElfW(Addr) addr = ((ElfW(Rel) *) reloc)->r_offset - offset;
1133 #ifdef __alpha__
1134 /* The Alpha ELF binutils currently have a bug that
1135 sometimes results in relocs that contain all
1136 zeroes. Work around this for now... */
1137 if (((ElfW(Rel) *) reloc)->r_offset == 0)
1138 continue;
1139 #endif
1140 memcpy (new_base + addr, old_base + addr, sizeof(ElfW(Addr))); 906 memcpy (new_base + addr, old_base + addr, sizeof(ElfW(Addr)));
1141 } 907 }
1142 } 908 }
1143 break; 909 break;
1144 } 910 }