comparison src/unexelf.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 501cfd01ee6d
children 11054d720c21
comparison
equal deleted inserted replaced
411:12e008d41344 412:697ef44129c6
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
411 411
412 #ifndef emacs 412 #ifndef emacs
413 #define fatal(a, b, c) fprintf (stderr, a, b, c), exit (1) 413 #define fatal(a, b, c) fprintf (stderr, a, b, c), exit (1)
414 #else 414 #else
415 #include <config.h> 415 #include <config.h>
416 extern void fatal (const char *, ...); 416 extern void fatal (CONST char *, ...);
417 #endif 417 #endif
418 418
419 #include <sys/types.h> 419 #include <sys/types.h>
420 #include <stdio.h> 420 #include <stdio.h>
421 #include <sys/stat.h> 421 #include <sys/stat.h>
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 (__NetBSD__) && !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 <sym.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 __NetBSD__
475 /*
476 * NetBSD does not have normal-looking user-land ELF support.
477 */
478 # ifdef __alpha__
479 # define ELFSIZE 64
480 # else
481 # define ELFSIZE 32
482 # endif
483 # include <sys/exec_elf.h>
484
485 # define PT_LOAD Elf_pt_load
486 # define SHT_SYMTAB Elf_sht_symtab
487 # define SHT_DYNSYM Elf_sht_dynsym
488 # define SHT_NULL Elf_sht_null
489 # define SHT_NOBITS Elf_sht_nobits
490 # define SHT_REL Elf_sht_rel
491 # define SHT_RELA Elf_sht_rela
492
493 # define SHN_UNDEF Elf_eshn_undefined
494 # define SHN_ABS Elf_eshn_absolute
495 # define SHN_COMMON Elf_eshn_common
496
497 # ifdef __alpha__
498 # include <sys/exec_ecoff.h>
499 # define HDRR struct ecoff_symhdr
500 # define pHDRR HDRR *
501 # endif
502 #endif /* __NetBSD__ */
503
504 #ifdef __OpenBSD__
505 # include <sys/exec_elf.h>
506 #endif
507
508 #if __GNU_LIBRARY__ - 0 >= 6
509 # include <link.h> /* get ElfW etc */ 431 # include <link.h> /* get ElfW etc */
510 #endif 432 #endif
511 433
512 #ifndef ElfW 434 #ifndef ElfW
513 # ifdef __STDC__ 435 # ifdef __STDC__
563 (n)++; } while (0) 485 (n)++; } while (0)
564 typedef unsigned char byte; 486 typedef unsigned char byte;
565 487
566 /* Round X up to a multiple of Y. */ 488 /* Round X up to a multiple of Y. */
567 489
568 static ElfW(Addr) 490 static int
569 round_up (ElfW(Addr) x, ElfW(Addr) y) 491 round_up (int x, int y)
570 { 492 {
571 int rem = x % y; 493 int rem = x % y;
572 if (rem == 0) 494 if (rem == 0)
573 return x; 495 return x;
574 return x - rem + y; 496 return x - rem + y;
607 ElfW(Addr) old_bss_addr, new_bss_addr; 529 ElfW(Addr) old_bss_addr, new_bss_addr;
608 ElfW(Word) old_bss_size, new_data2_size; 530 ElfW(Word) old_bss_size, new_data2_size;
609 ElfW(Off) new_data2_offset; 531 ElfW(Off) new_data2_offset;
610 ElfW(Addr) new_data2_addr; 532 ElfW(Addr) new_data2_addr;
611 533
612 int n, nn, old_bss_index, old_data_index, new_data2_index; 534 int n, nn, old_bss_index, old_data_index;
613 int old_sbss_index, old_mdebug_index;
614 struct stat stat_buf; 535 struct stat stat_buf;
615 536
616 /* Open the old file & map it into the address space. */ 537 /* Open the old file & map it into the address space. */
617 538
618 old_file = open (old_name, O_RDONLY); 539 old_file = open (old_name, O_RDONLY);
621 fatal ("Can't open %s for reading: errno %d\n", old_name, errno); 542 fatal ("Can't open %s for reading: errno %d\n", old_name, errno);
622 543
623 if (fstat (old_file, &stat_buf) == -1) 544 if (fstat (old_file, &stat_buf) == -1)
624 fatal ("Can't fstat (%s): errno %d\n", old_name, errno); 545 fatal ("Can't fstat (%s): errno %d\n", old_name, errno);
625 546
626 old_base = (caddr_t) mmap (0, stat_buf.st_size, PROT_READ, MAP_SHARED, old_file, 0); 547 old_base = mmap (0, stat_buf.st_size, PROT_READ, MAP_SHARED, old_file, 0);
627 548
628 if (old_base == (caddr_t) -1) 549 if (old_base == (caddr_t) -1)
629 fatal ("Can't mmap (%s): errno %d\n", old_name, errno); 550 fatal ("Can't mmap (%s): errno %d\n", old_name, errno);
630 551
631 #ifdef DEBUG 552 #ifdef DEBUG
657 break; 578 break;
658 } 579 }
659 if (old_bss_index == old_file_h->e_shnum) 580 if (old_bss_index == old_file_h->e_shnum)
660 fatal ("Can't find .bss in %s.\n", old_name, 0); 581 fatal ("Can't find .bss in %s.\n", old_name, 0);
661 582
662 for (old_sbss_index = 1; old_sbss_index < (int) old_file_h->e_shnum; 583 old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr;
663 old_sbss_index++) 584 old_bss_size = OLD_SECTION_H (old_bss_index).sh_size;
664 {
665 #ifdef DEBUG
666 fprintf (stderr, "Looking for .sbss - found %s\n",
667 old_section_names + OLD_SECTION_H (old_sbss_index).sh_name);
668 #endif
669 if (!strcmp (old_section_names + OLD_SECTION_H (old_sbss_index).sh_name,
670 ".sbss"))
671 break;
672 }
673 if (old_sbss_index == old_file_h->e_shnum)
674 {
675 old_sbss_index = -1;
676 old_bss_addr = OLD_SECTION_H(old_bss_index).sh_addr;
677 old_bss_size = OLD_SECTION_H(old_bss_index).sh_size;
678 new_data2_index = old_bss_index;
679 }
680 else
681 {
682 old_bss_addr = OLD_SECTION_H(old_sbss_index).sh_addr;
683 old_bss_size = OLD_SECTION_H(old_bss_index).sh_size
684 + OLD_SECTION_H(old_sbss_index).sh_size;
685 new_data2_index = old_sbss_index;
686 }
687
688 for (old_mdebug_index = 1; old_mdebug_index < (int) old_file_h->e_shnum;
689 old_mdebug_index++)
690 {
691 #ifdef DEBUG
692 fprintf (stderr, "Looking for .mdebug - found %s\n",
693 old_section_names + OLD_SECTION_H (old_mdebug_index).sh_name);
694 #endif
695 if (!strcmp (old_section_names + OLD_SECTION_H (old_mdebug_index).sh_name,
696 ".mdebug"))
697 break;
698 }
699 if (old_mdebug_index == old_file_h->e_shnum)
700 old_mdebug_index = 0;
701
702 for (old_data_index = 1; old_data_index < (int) old_file_h->e_shnum;
703 old_data_index++)
704 {
705 #ifdef DEBUG
706 fprintf (stderr, "Looking for .data - found %s\n",
707 old_section_names + OLD_SECTION_H (old_data_index).sh_name);
708 #endif
709 if (!strcmp (old_section_names + OLD_SECTION_H (old_data_index).sh_name,
710 ".data"))
711 break;
712 }
713 if (old_data_index == old_file_h->e_shnum)
714 old_data_index = 0;
715
716 #if defined (emacs) || !defined (DEBUG) 585 #if defined (emacs) || !defined (DEBUG)
717 new_bss_addr = (ElfW(Addr)) sbrk (0); 586 new_bss_addr = (ElfW(Addr)) sbrk (0);
718 #else 587 #else
719 new_bss_addr = old_bss_addr + old_bss_size + 0x1234; 588 new_bss_addr = old_bss_addr + old_bss_size + 0x1234;
720 #endif 589 #endif
721 new_data2_addr = old_bss_addr; 590 new_data2_addr = old_bss_addr;
722 new_data2_size = new_bss_addr - old_bss_addr; 591 new_data2_size = new_bss_addr - old_bss_addr;
723 new_data2_offset = OLD_SECTION_H (old_data_index).sh_offset + 592 new_data2_offset = OLD_SECTION_H (old_bss_index).sh_offset;
724 (new_data2_addr - OLD_SECTION_H (old_data_index).sh_addr);
725 593
726 #ifdef DEBUG 594 #ifdef DEBUG
727 fprintf (stderr, "old_bss_index %d\n", old_bss_index); 595 fprintf (stderr, "old_bss_index %d\n", old_bss_index);
728 fprintf (stderr, "old_bss_addr %x\n", old_bss_addr); 596 fprintf (stderr, "old_bss_addr %x\n", old_bss_addr);
729 fprintf (stderr, "old_bss_size %x\n", old_bss_size); 597 fprintf (stderr, "old_bss_size %x\n", old_bss_size);
748 new_file_size = stat_buf.st_size + old_file_h->e_shentsize + new_data2_size; 616 new_file_size = stat_buf.st_size + old_file_h->e_shentsize + new_data2_size;
749 617
750 if (ftruncate (new_file, new_file_size)) 618 if (ftruncate (new_file, new_file_size))
751 fatal ("Can't ftruncate (%s): errno %d\n", new_name, errno); 619 fatal ("Can't ftruncate (%s): errno %d\n", new_name, errno);
752 620
753 new_base = (caddr_t) mmap (0, new_file_size, PROT_READ | PROT_WRITE,
754 #ifdef UNEXEC_USE_MAP_PRIVATE 621 #ifdef UNEXEC_USE_MAP_PRIVATE
755 MAP_PRIVATE, 622 new_base = mmap (0, new_file_size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
623 new_file, 0);
756 #else 624 #else
757 MAP_SHARED, 625 new_base = mmap (0, new_file_size, PROT_READ | PROT_WRITE, MAP_SHARED,
758 #endif 626 new_file, 0);
759 new_file, 0); 627 #endif
760 628
761 if (new_base == (caddr_t) -1) 629 if (new_base == (caddr_t) -1)
762 fatal ("Can't mmap (%s): errno %d\n", new_name, errno); 630 fatal ("Can't mmap (%s): errno %d\n", new_name, errno);
763 631
764 new_file_h = (ElfW(Ehdr) *) new_base; 632 new_file_h = (ElfW(Ehdr) *) new_base;
804 /* Compute maximum of all requirements for alignment of section. */ 672 /* Compute maximum of all requirements for alignment of section. */
805 ElfW(Word) alignment = (NEW_PROGRAM_H (n)).p_align; 673 ElfW(Word) alignment = (NEW_PROGRAM_H (n)).p_align;
806 if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment) 674 if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment)
807 alignment = OLD_SECTION_H (old_bss_index).sh_addralign; 675 alignment = OLD_SECTION_H (old_bss_index).sh_addralign;
808 676
809 #ifdef __mips 677 #ifndef __mips /* ifndef added by jwz at suggestion of
810 /* According to r02kar@x4u2.desy.de (Karsten Kuenne) 678 r02kar@x4u2.desy.de (Karsten Kuenne) to avoid
811 and oliva@gnu.org (Alexandre Oliva), on IRIX 5.2, we 679 "Program segment above .bss" when dumping.
812 always get "Program segment above .bss" when dumping 680 */
813 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)
814 if (old_sbss_index != -1) 682 fatal ("Program segment above .bss in %s\n", old_name, 0);
815 #endif /* __mips */ 683 #endif /* __mips */
816 if (NEW_PROGRAM_H (n).p_vaddr + NEW_PROGRAM_H (n).p_filesz
817 > (old_sbss_index == -1
818 ? old_bss_addr
819 : round_up (old_bss_addr, alignment)))
820 fatal ("Program segment above .bss in %s\n", old_name, 0);
821 684
822 if (NEW_PROGRAM_H (n).p_type == PT_LOAD 685 if (NEW_PROGRAM_H (n).p_type == PT_LOAD
823 && (round_up ((NEW_PROGRAM_H (n)).p_vaddr 686 && (round_up ((int) ((NEW_PROGRAM_H (n)).p_vaddr
824 + (NEW_PROGRAM_H (n)).p_filesz, 687 + (NEW_PROGRAM_H (n)).p_filesz),
825 alignment) 688 alignment)
826 == round_up (old_bss_addr, alignment))) 689 == round_up ((int) old_bss_addr, alignment)))
827 break; 690 break;
828 } 691 }
829 if (n < 0) 692 if (n < 0)
830 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);
831 694
832 /* Make sure that the size includes any padding before the old .bss
833 section. */
834 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;
835 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;
836 697
837 #if 0 /* Maybe allow section after data2 - does this ever happen? */ 698 #if 0 /* Maybe allow section after data2 - does this ever happen? */
838 for (n = new_file_h->e_phnum - 1; n >= 0; n--) 699 for (n = new_file_h->e_phnum - 1; n >= 0; n--)
863 /* Walk through all section headers, insert the new data2 section right 724 /* Walk through all section headers, insert the new data2 section right
864 before the new bss section. */ 725 before the new bss section. */
865 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++)
866 { 727 {
867 caddr_t src; 728 caddr_t src;
868 /* 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. */
869 /* new_data2_index is the index of either old_sbss or old_bss, that was 730 if (n == old_bss_index)
870 chosen as a section for new_data2. */
871 if (n == new_data2_index)
872 { 731 {
873 /* Steal the data section header for this data2 section. */ 732 /* Steal the data section header for this data2 section. */
874 memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (old_data_index), 733 memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (old_data_index),
875 new_file_h->e_shentsize); 734 new_file_h->e_shentsize);
876 735
883 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;
884 743
885 /* Now copy over what we have in the memory now. */ 744 /* Now copy over what we have in the memory now. */
886 memcpy (NEW_SECTION_H (nn).sh_offset + new_base, 745 memcpy (NEW_SECTION_H (nn).sh_offset + new_base,
887 (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? */
888 new_data2_size); 748 new_data2_size);
889 nn++; 749 nn++;
890 } 750 }
891 751
892 memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (n), 752 memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (n),
893 old_file_h->e_shentsize); 753 old_file_h->e_shentsize);
894 754
895 if (n == old_bss_index 755 /* The new bss section's size is zero, and its file offset and virtual
896 /* The new bss and sbss section's size is zero, and its file offset 756 address should be off by NEW_DATA2_SIZE. */
897 and virtual address should be off by NEW_DATA2_SIZE. */ 757 if (n == old_bss_index)
898 || n == old_sbss_index
899 )
900 { 758 {
901 /* NN should be `old_s?bss_index + 1' at this point. */ 759 /* NN should be `old_bss_index + 1' at this point. */
902 NEW_SECTION_H (nn).sh_offset = 760 NEW_SECTION_H (nn).sh_offset += new_data2_size;
903 NEW_SECTION_H (new_data2_index).sh_offset + new_data2_size; 761 NEW_SECTION_H (nn).sh_addr += new_data2_size;
904 NEW_SECTION_H (nn).sh_addr =
905 NEW_SECTION_H (new_data2_index).sh_addr + new_data2_size;
906 /* 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
907 section address alignment followed the old bss section, so 763 section address alignment followed the old bss section, so
908 this section will be placed in exactly the same place. */ 764 this section will be placed in exactly the same place. */
909 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;
910 NEW_SECTION_H (nn).sh_size = 0; 766 NEW_SECTION_H (nn).sh_size = 0;
924 Erik Deumens, deumens@qtp.ufl.edu. */ 780 Erik Deumens, deumens@qtp.ufl.edu. */
925 if (NEW_SECTION_H (nn).sh_offset 781 if (NEW_SECTION_H (nn).sh_offset
926 >= OLD_SECTION_H (old_bss_index-1).sh_offset) 782 >= OLD_SECTION_H (old_bss_index-1).sh_offset)
927 NEW_SECTION_H (nn).sh_offset += new_data2_size; 783 NEW_SECTION_H (nn).sh_offset += new_data2_size;
928 #else 784 #else
929 if (round_up (NEW_SECTION_H (nn).sh_offset, 785 if (NEW_SECTION_H (nn).sh_offset >= new_data2_offset)
930 OLD_SECTION_H (old_bss_index).sh_addralign)
931 >= new_data2_offset)
932 NEW_SECTION_H (nn).sh_offset += new_data2_size; 786 NEW_SECTION_H (nn).sh_offset += new_data2_size;
933 #endif 787 #endif
934 /* Any section that was originally placed after the section 788 /* Any section that was originally placed after the section
935 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
936 header table entry. */ 790 header table entry. */
955 continue; 809 continue;
956 810
957 /* Write out the sections. .data and .data1 (and data2, called 811 /* Write out the sections. .data and .data1 (and data2, called
958 ".data" in the strings table) get copied from the current process 812 ".data" in the strings table) get copied from the current process
959 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
960 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")
961 || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name), 822 || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
962 ".sdata")
963 /* Taking these sections from the current process, breaks
964 Linux in a subtle way. Binaries only run on the
965 architecture (e.g. i586 vs i686) of the dumping machine */
966 #ifdef __sgi
967 || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
968 ".lit4")
969 || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
970 ".lit8")
971 || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
972 ".got")
973 #endif
974 || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
975 ".sdata1")
976 || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
977 ".data1")) 823 ".data1"))
824 #endif
978 src = (caddr_t) OLD_SECTION_H (n).sh_addr; 825 src = (caddr_t) OLD_SECTION_H (n).sh_addr;
979 else 826 else
980 src = old_base + OLD_SECTION_H (n).sh_offset; 827 src = old_base + OLD_SECTION_H (n).sh_offset;
981 828
982 memcpy (NEW_SECTION_H (nn).sh_offset + new_base, src, 829 memcpy (NEW_SECTION_H (nn).sh_offset + new_base, src,
983 NEW_SECTION_H (nn).sh_size); 830 NEW_SECTION_H (nn).sh_size);
984
985 #ifdef __alpha__
986 /* Update Alpha COFF symbol table: */
987 if (strcmp (old_section_names + OLD_SECTION_H (n).sh_name, ".mdebug")
988 == 0)
989 {
990 pHDRR symhdr = (pHDRR) (NEW_SECTION_H (nn).sh_offset + new_base);
991
992 symhdr->cbLineOffset += new_data2_size;
993 symhdr->cbDnOffset += new_data2_size;
994 symhdr->cbPdOffset += new_data2_size;
995 symhdr->cbSymOffset += new_data2_size;
996 symhdr->cbOptOffset += new_data2_size;
997 symhdr->cbAuxOffset += new_data2_size;
998 symhdr->cbSsOffset += new_data2_size;
999 symhdr->cbSsExtOffset += new_data2_size;
1000 symhdr->cbFdOffset += new_data2_size;
1001 symhdr->cbRfdOffset += new_data2_size;
1002 symhdr->cbExtOffset += new_data2_size;
1003 }
1004 #endif /* __alpha__ */
1005
1006 #if defined (__sony_news) && defined (_SYSTYPE_SYSV)
1007 if (NEW_SECTION_H (nn).sh_type == SHT_MIPS_DEBUG && old_mdebug_index)
1008 {
1009 int diff = NEW_SECTION_H(nn).sh_offset
1010 - OLD_SECTION_H(old_mdebug_index).sh_offset;
1011 HDRR *phdr = (HDRR *)(NEW_SECTION_H (nn).sh_offset + new_base);
1012
1013 if (diff)
1014 {
1015 phdr->cbLineOffset += diff;
1016 phdr->cbDnOffset += diff;
1017 phdr->cbPdOffset += diff;
1018 phdr->cbSymOffset += diff;
1019 phdr->cbOptOffset += diff;
1020 phdr->cbAuxOffset += diff;
1021 phdr->cbSsOffset += diff;
1022 phdr->cbSsExtOffset += diff;
1023 phdr->cbFdOffset += diff;
1024 phdr->cbRfdOffset += diff;
1025 phdr->cbExtOffset += diff;
1026 }
1027 }
1028 #endif /* __sony_news && _SYSTYPE_SYSV */
1029
1030 #ifdef __sgi
1031 /* Adjust the HDRR offsets in .mdebug and copy the
1032 line data if it's in its usual 'hole' in the object.
1033 Makes the new file debuggable with dbx.
1034 patches up two problems: the absolute file offsets
1035 in the HDRR record of .mdebug (see /usr/include/syms.h), and
1036 the ld bug that gets the line table in a hole in the
1037 elf file rather than in the .mdebug section proper.
1038 David Anderson. davea@sgi.com Jan 16,1994. */
1039 if (n == old_mdebug_index)
1040 {
1041 #define MDEBUGADJUST(__ct,__fileaddr) \
1042 if (n_phdrr->__ct > 0) \
1043 { \
1044 n_phdrr->__fileaddr += movement; \
1045 }
1046
1047 HDRR * o_phdrr = (HDRR *)((byte *)old_base + OLD_SECTION_H (n).sh_offset);
1048 HDRR * n_phdrr = (HDRR *)((byte *)new_base + NEW_SECTION_H (nn).sh_offset);
1049 unsigned movement = new_data2_size;
1050
1051 MDEBUGADJUST (idnMax, cbDnOffset);
1052 MDEBUGADJUST (ipdMax, cbPdOffset);
1053 MDEBUGADJUST (isymMax, cbSymOffset);
1054 MDEBUGADJUST (ioptMax, cbOptOffset);
1055 MDEBUGADJUST (iauxMax, cbAuxOffset);
1056 MDEBUGADJUST (issMax, cbSsOffset);
1057 MDEBUGADJUST (issExtMax, cbSsExtOffset);
1058 MDEBUGADJUST (ifdMax, cbFdOffset);
1059 MDEBUGADJUST (crfd, cbRfdOffset);
1060 MDEBUGADJUST (iextMax, cbExtOffset);
1061 /* The Line Section, being possible off in a hole of the object,
1062 requires special handling. */
1063 if (n_phdrr->cbLine > 0)
1064 {
1065 if (o_phdrr->cbLineOffset > (OLD_SECTION_H (n).sh_offset
1066 + OLD_SECTION_H (n).sh_size))
1067 {
1068 /* line data is in a hole in elf. do special copy and adjust
1069 for this ld mistake.
1070 */
1071 n_phdrr->cbLineOffset += movement;
1072
1073 memcpy (n_phdrr->cbLineOffset + new_base,
1074 o_phdrr->cbLineOffset + old_base, n_phdrr->cbLine);
1075 }
1076 else
1077 {
1078 /* somehow line data is in .mdebug as it is supposed to be. */
1079 MDEBUGADJUST (cbLine, cbLineOffset);
1080 }
1081 }
1082 }
1083 #endif /* __sgi */
1084 831
1085 /* 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. */
1086 if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB 833 if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB
1087 || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM) 834 || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM)
1088 { 835 {
1137 case SHT_RELA: 884 case SHT_RELA:
1138 /* This code handles two different size structs, but there should 885 /* This code handles two different size structs, but there should
1139 be no harm in that provided that r_offset is always the first 886 be no harm in that provided that r_offset is always the first
1140 member. */ 887 member. */
1141 nn = section.sh_info; 888 nn = section.sh_info;
889 #ifdef __powerpc__
890 /* The PowerPC has additional 'data' segments which need to be saved */
891 if (!strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data") ||
892 !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data1") ||
893 !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".sdata") ||
894 !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".sdata1"))
895 #else
1142 if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data") 896 if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data")
1143 || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), 897 || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
1144 ".sdata")
1145 #ifdef __sgi
1146 || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
1147 ".lit4")
1148 || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
1149 ".lit8")
1150 || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
1151 ".got")
1152 #endif
1153 || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
1154 ".sdata1")
1155 || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
1156 ".data1")) 898 ".data1"))
899 #endif
1157 { 900 {
1158 ElfW(Addr) offset = NEW_SECTION_H (nn).sh_addr - 901 ElfW(Addr) offset = NEW_SECTION_H (nn).sh_addr -
1159 NEW_SECTION_H (nn).sh_offset; 902 NEW_SECTION_H (nn).sh_offset;
1160 caddr_t reloc = old_base + section.sh_offset, end; 903 caddr_t reloc = old_base + section.sh_offset, end;
1161 for (end = reloc + section.sh_size; reloc < end; 904 for (end = reloc + section.sh_size; reloc < end;
1162 reloc += section.sh_entsize) 905 reloc += section.sh_entsize)
1163 { 906 {
1164 ElfW(Addr) addr = ((ElfW(Rel) *) reloc)->r_offset - offset; 907 ElfW(Addr) addr = ((ElfW(Rel) *) reloc)->r_offset - offset;
1165 #ifdef __alpha__
1166 /* The Alpha ELF binutils currently have a bug that
1167 sometimes results in relocs that contain all
1168 zeroes. Work around this for now... */
1169 if (((ElfW(Rel) *) reloc)->r_offset == 0)
1170 continue;
1171 #endif
1172 memcpy (new_base + addr, old_base + addr, sizeof(ElfW(Addr))); 908 memcpy (new_base + addr, old_base + addr, sizeof(ElfW(Addr)));
1173 } 909 }
1174 } 910 }
1175 break; 911 break;
1176 } 912 }