comparison src/unexelf.c @ 15719:fdac027af4e1

Undo previous change.
author Karl Heuer <kwzh@gnu.org>
date Tue, 16 Jul 1996 22:39:31 +0000
parents 8978d34759dc
children 2c15b1cd3b84
comparison
equal deleted inserted replaced
15718:8db4678b2fd8 15719:fdac027af4e1
420 #include <errno.h> 420 #include <errno.h>
421 #include <unistd.h> 421 #include <unistd.h>
422 #include <fcntl.h> 422 #include <fcntl.h>
423 #include <elf.h> 423 #include <elf.h>
424 #include <sys/mman.h> 424 #include <sys/mman.h>
425
426 #ifdef __alpha__
427 # include <sym.h> /* get COFF debugging symbol table declaration */
428 #endif
429
430 #ifdef __GNU_LIBRARY__
431 # include <link.h> /* get definition of ElfW */
432 #endif
433
434 #ifndef ElfW
435 # ifdef __STDC__
436 # define ElfW(type) Elf32_##type
437 # else
438 # define ElfW(type) Elf32_/**/type
439 # endif
440 #endif
441 425
442 #ifndef emacs 426 #ifndef emacs
443 #define fatal(a, b, c) fprintf (stderr, a, b, c), exit (1) 427 #define fatal(a, b, c) fprintf (stderr, a, b, c), exit (1)
444 #else 428 #else
445 #include <config.h> 429 #include <config.h>
476 deumens@qtp.ufl.edu 460 deumens@qtp.ufl.edu
477 Apr 23, 1996 461 Apr 23, 1996
478 */ 462 */
479 463
480 #define OLD_SECTION_H(n) \ 464 #define OLD_SECTION_H(n) \
481 (*(ElfW(Shdr) *) ((byte *) old_section_h + old_file_h->e_shentsize * (n))) 465 (*(Elf32_Shdr *) ((byte *) old_section_h + old_file_h->e_shentsize * (n)))
482 #define NEW_SECTION_H(n) \ 466 #define NEW_SECTION_H(n) \
483 (*(ElfW(Shdr) *) ((byte *) new_section_h + new_file_h->e_shentsize * (n))) 467 (*(Elf32_Shdr *) ((byte *) new_section_h + new_file_h->e_shentsize * (n)))
484 #define OLD_PROGRAM_H(n) \ 468 #define OLD_PROGRAM_H(n) \
485 (*(ElfW(Phdr) *) ((byte *) old_program_h + old_file_h->e_phentsize * (n))) 469 (*(Elf32_Phdr *) ((byte *) old_program_h + old_file_h->e_phentsize * (n)))
486 #define NEW_PROGRAM_H(n) \ 470 #define NEW_PROGRAM_H(n) \
487 (*(ElfW(Phdr) *) ((byte *) new_program_h + new_file_h->e_phentsize * (n))) 471 (*(Elf32_Phdr *) ((byte *) new_program_h + new_file_h->e_phentsize * (n)))
488 472
489 #define PATCH_INDEX(n) \ 473 #define PATCH_INDEX(n) \
490 do { \ 474 do { \
491 if ((int) (n) >= old_bss_index) \ 475 if ((int) (n) >= old_bss_index) \
492 (n)++; } while (0) 476 (n)++; } while (0)
524 caddr_t old_base, new_base; 508 caddr_t old_base, new_base;
525 509
526 /* Pointers to the file, program and section headers for the old and new 510 /* Pointers to the file, program and section headers for the old and new
527 * files. 511 * files.
528 */ 512 */
529 ElfW(Ehdr) *old_file_h, *new_file_h; 513 Elf32_Ehdr *old_file_h, *new_file_h;
530 ElfW(Phdr) *old_program_h, *new_program_h; 514 Elf32_Phdr *old_program_h, *new_program_h;
531 ElfW(Shdr) *old_section_h, *new_section_h; 515 Elf32_Shdr *old_section_h, *new_section_h;
532 516
533 /* Point to the section name table in the old file */ 517 /* Point to the section name table in the old file */
534 char *old_section_names; 518 char *old_section_names;
535 519
536 ElfW(Addr) old_bss_addr, new_bss_addr; 520 Elf32_Addr old_bss_addr, new_bss_addr;
537 ElfW(Addr) old_bss_size, new_data2_size; 521 Elf32_Word old_bss_size, new_data2_size;
538 ElfW(Off) new_data2_offset; 522 Elf32_Off new_data2_offset;
539 ElfW(Addr) new_data2_addr; 523 Elf32_Addr new_data2_addr;
540 524
541 int n, nn, old_bss_index, old_data_index; 525 int n, nn, old_bss_index, old_data_index, new_data2_index;
542 struct stat stat_buf; 526 struct stat stat_buf;
543 527
544 /* Open the old file & map it into the address space. */ 528 /* Open the old file & map it into the address space. */
545 529
546 old_file = open (old_name, O_RDONLY); 530 old_file = open (old_name, O_RDONLY);
555 539
556 if (old_base == (caddr_t) -1) 540 if (old_base == (caddr_t) -1)
557 fatal ("Can't mmap (%s): errno %d\n", old_name, errno); 541 fatal ("Can't mmap (%s): errno %d\n", old_name, errno);
558 542
559 #ifdef DEBUG 543 #ifdef DEBUG
560 fprintf (stderr, "mmap (%s, %lx) -> %lx\n", old_name, stat_buf.st_size, 544 fprintf (stderr, "mmap (%s, %x) -> %x\n", old_name, stat_buf.st_size,
561 (unsigned long) old_base); 545 old_base);
562 #endif 546 #endif
563 547
564 /* Get pointers to headers & section names */ 548 /* Get pointers to headers & section names */
565 549
566 old_file_h = (ElfW(Ehdr) *) old_base; 550 old_file_h = (Elf32_Ehdr *) old_base;
567 old_program_h = (ElfW(Phdr) *) ((byte *) old_base + old_file_h->e_phoff); 551 old_program_h = (Elf32_Phdr *) ((byte *) old_base + old_file_h->e_phoff);
568 old_section_h = (ElfW(Shdr) *) ((byte *) old_base + old_file_h->e_shoff); 552 old_section_h = (Elf32_Shdr *) ((byte *) old_base + old_file_h->e_shoff);
569 old_section_names = (char *) old_base 553 old_section_names = (char *) old_base
570 + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset; 554 + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset;
571 555
572 /* Find the old .bss section. Figure out parameters of the new 556 /* Find the old .bss section. Figure out parameters of the new
573 * data2 and bss sections. 557 * data2 and bss sections.
588 fatal ("Can't find .bss in %s.\n", old_name, 0); 572 fatal ("Can't find .bss in %s.\n", old_name, 0);
589 573
590 old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr; 574 old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr;
591 old_bss_size = OLD_SECTION_H (old_bss_index).sh_size; 575 old_bss_size = OLD_SECTION_H (old_bss_index).sh_size;
592 #if defined(emacs) || !defined(DEBUG) 576 #if defined(emacs) || !defined(DEBUG)
593 new_bss_addr = (ElfW(Addr)) sbrk (0); 577 new_bss_addr = (Elf32_Addr) sbrk (0);
594 #else 578 #else
595 new_bss_addr = old_bss_addr + old_bss_size + 0x1234; 579 new_bss_addr = old_bss_addr + old_bss_size + 0x1234;
596 #endif 580 #endif
597 new_data2_addr = old_bss_addr; 581 new_data2_addr = old_bss_addr;
598 new_data2_size = new_bss_addr - old_bss_addr; 582 new_data2_size = new_bss_addr - old_bss_addr;
599 new_data2_offset = OLD_SECTION_H (old_bss_index).sh_offset; 583 new_data2_offset = OLD_SECTION_H (old_bss_index).sh_offset;
600 584
601 #ifdef DEBUG 585 #ifdef DEBUG
602 fprintf (stderr, "old_bss_index %d\n", old_bss_index); 586 fprintf (stderr, "old_bss_index %d\n", old_bss_index);
603 fprintf (stderr, "old_bss_addr %lx\n", old_bss_addr); 587 fprintf (stderr, "old_bss_addr %x\n", old_bss_addr);
604 fprintf (stderr, "old_bss_size %lx\n", old_bss_size); 588 fprintf (stderr, "old_bss_size %x\n", old_bss_size);
605 fprintf (stderr, "new_bss_addr %lx\n", new_bss_addr); 589 fprintf (stderr, "new_bss_addr %x\n", new_bss_addr);
606 fprintf (stderr, "new_data2_addr %lx\n", new_data2_addr); 590 fprintf (stderr, "new_data2_addr %x\n", new_data2_addr);
607 fprintf (stderr, "new_data2_size %lx\n", new_data2_size); 591 fprintf (stderr, "new_data2_size %x\n", new_data2_size);
608 fprintf (stderr, "new_data2_offset %lx\n", new_data2_offset); 592 fprintf (stderr, "new_data2_offset %x\n", new_data2_offset);
609 #endif 593 #endif
610 594
611 if ((unsigned long) new_bss_addr 595 if ((unsigned) new_bss_addr < (unsigned) old_bss_addr + old_bss_size)
612 < (unsigned long) old_bss_addr + old_bss_size)
613 fatal (".bss shrank when undumping???\n", 0, 0); 596 fatal (".bss shrank when undumping???\n", 0, 0);
614 597
615 /* Set the output file to the right size and mmap it. Set 598 /* Set the output file to the right size and mmap it. Set
616 * pointers to various interesting objects. stat_buf still has 599 * pointers to various interesting objects. stat_buf still has
617 * old_file data. 600 * old_file data.
635 #endif 618 #endif
636 619
637 if (new_base == (caddr_t) -1) 620 if (new_base == (caddr_t) -1)
638 fatal ("Can't mmap (%s): errno %d\n", new_name, errno); 621 fatal ("Can't mmap (%s): errno %d\n", new_name, errno);
639 622
640 new_file_h = (ElfW(Ehdr) *) new_base; 623 new_file_h = (Elf32_Ehdr *) new_base;
641 new_program_h = (ElfW(Phdr) *) ((byte *) new_base + old_file_h->e_phoff); 624 new_program_h = (Elf32_Phdr *) ((byte *) new_base + old_file_h->e_phoff);
642 new_section_h = (ElfW(Shdr) *) 625 new_section_h = (Elf32_Shdr *)
643 ((byte *) new_base + old_file_h->e_shoff + new_data2_size); 626 ((byte *) new_base + old_file_h->e_shoff + new_data2_size);
644 627
645 /* Make our new file, program and section headers as copies of the 628 /* Make our new file, program and section headers as copies of the
646 * originals. 629 * originals.
647 */ 630 */
659 642
660 new_file_h->e_shoff += new_data2_size; 643 new_file_h->e_shoff += new_data2_size;
661 new_file_h->e_shnum += 1; 644 new_file_h->e_shnum += 1;
662 645
663 #ifdef DEBUG 646 #ifdef DEBUG
664 fprintf (stderr, "Old section offset %lx\n", old_file_h->e_shoff); 647 fprintf (stderr, "Old section offset %x\n", old_file_h->e_shoff);
665 fprintf (stderr, "Old section count %d\n", old_file_h->e_shnum); 648 fprintf (stderr, "Old section count %d\n", old_file_h->e_shnum);
666 fprintf (stderr, "New section offset %lx\n", new_file_h->e_shoff); 649 fprintf (stderr, "New section offset %x\n", new_file_h->e_shoff);
667 fprintf (stderr, "New section count %d\n", new_file_h->e_shnum); 650 fprintf (stderr, "New section count %d\n", new_file_h->e_shnum);
668 #endif 651 #endif
669 652
670 /* Fix up a new program header. Extend the writable data segment so 653 /* Fix up a new program header. Extend the writable data segment so
671 * that the bss area is covered too. Find that segment by looking 654 * that the bss area is covered too. Find that segment by looking
676 */ 659 */
677 660
678 for (n = new_file_h->e_phnum - 1; n >= 0; n--) 661 for (n = new_file_h->e_phnum - 1; n >= 0; n--)
679 { 662 {
680 /* Compute maximum of all requirements for alignment of section. */ 663 /* Compute maximum of all requirements for alignment of section. */
681 unsigned int alignment = (NEW_PROGRAM_H (n)).p_align; 664 int alignment = (NEW_PROGRAM_H (n)).p_align;
682 if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment) 665 if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment)
683 alignment = OLD_SECTION_H (old_bss_index).sh_addralign; 666 alignment = OLD_SECTION_H (old_bss_index).sh_addralign;
684 667
685 if (NEW_PROGRAM_H (n).p_vaddr + NEW_PROGRAM_H (n).p_filesz > old_bss_addr) 668 if (NEW_PROGRAM_H (n).p_vaddr + NEW_PROGRAM_H (n).p_filesz > old_bss_addr)
686 fatal ("Program segment above .bss in %s\n", old_name, 0); 669 fatal ("Program segment above .bss in %s\n", old_name, 0);
823 src = old_base + OLD_SECTION_H (n).sh_offset; 806 src = old_base + OLD_SECTION_H (n).sh_offset;
824 807
825 memcpy (NEW_SECTION_H (nn).sh_offset + new_base, src, 808 memcpy (NEW_SECTION_H (nn).sh_offset + new_base, src,
826 NEW_SECTION_H (nn).sh_size); 809 NEW_SECTION_H (nn).sh_size);
827 810
828 #ifdef __alpha__
829 /* Update Alpha COFF symbol table: */
830 if (strcmp (old_section_names + OLD_SECTION_H (n).sh_name, ".mdebug")
831 == 0)
832 {
833 pHDRR symhdr = (pHDRR) (NEW_SECTION_H (nn).sh_offset + new_base);
834
835 symhdr->cbLineOffset += new_data2_size;
836 symhdr->cbDnOffset += new_data2_size;
837 symhdr->cbPdOffset += new_data2_size;
838 symhdr->cbSymOffset += new_data2_size;
839 symhdr->cbOptOffset += new_data2_size;
840 symhdr->cbAuxOffset += new_data2_size;
841 symhdr->cbSsOffset += new_data2_size;
842 symhdr->cbSsExtOffset += new_data2_size;
843 symhdr->cbFdOffset += new_data2_size;
844 symhdr->cbRfdOffset += new_data2_size;
845 symhdr->cbExtOffset += new_data2_size;
846 }
847 #endif /* __alpha__ */
848
849 /* If it is the symbol table, its st_shndx field needs to be patched. */ 811 /* If it is the symbol table, its st_shndx field needs to be patched. */
850 if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB 812 if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB
851 || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM) 813 || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM)
852 { 814 {
853 ElfW(Shdr) *spt = &NEW_SECTION_H (nn); 815 Elf32_Shdr *spt = &NEW_SECTION_H (nn);
854 unsigned int num = spt->sh_size / spt->sh_entsize; 816 unsigned int num = spt->sh_size / spt->sh_entsize;
855 ElfW(Sym) * sym = (ElfW(Sym) *) (NEW_SECTION_H (nn).sh_offset + 817 Elf32_Sym * sym = (Elf32_Sym *) (NEW_SECTION_H (nn).sh_offset +
856 new_base); 818 new_base);
857 for (; num--; sym++) 819 for (; num--; sym++)
858 { 820 {
859 if ((sym->st_shndx == SHN_UNDEF) 821 if ((sym->st_shndx == SHN_UNDEF)
860 || (sym->st_shndx == SHN_ABS) 822 || (sym->st_shndx == SHN_ABS)
868 830
869 /* Update the symbol values of _edata and _end. */ 831 /* Update the symbol values of _edata and _end. */
870 for (n = new_file_h->e_shnum - 1; n; n--) 832 for (n = new_file_h->e_shnum - 1; n; n--)
871 { 833 {
872 byte *symnames; 834 byte *symnames;
873 ElfW(Sym) *symp, *symendp; 835 Elf32_Sym *symp, *symendp;
874 836
875 if (NEW_SECTION_H (n).sh_type != SHT_DYNSYM 837 if (NEW_SECTION_H (n).sh_type != SHT_DYNSYM
876 && NEW_SECTION_H (n).sh_type != SHT_SYMTAB) 838 && NEW_SECTION_H (n).sh_type != SHT_SYMTAB)
877 continue; 839 continue;
878 840
879 symnames = ((byte *) new_base 841 symnames = ((byte *) new_base
880 + NEW_SECTION_H (NEW_SECTION_H (n).sh_link).sh_offset); 842 + NEW_SECTION_H (NEW_SECTION_H (n).sh_link).sh_offset);
881 symp = (ElfW(Sym) *) (NEW_SECTION_H (n).sh_offset + new_base); 843 symp = (Elf32_Sym *) (NEW_SECTION_H (n).sh_offset + new_base);
882 symendp = (ElfW(Sym) *) ((byte *)symp + NEW_SECTION_H (n).sh_size); 844 symendp = (Elf32_Sym *) ((byte *)symp + NEW_SECTION_H (n).sh_size);
883 845
884 for (; symp < symendp; symp ++) 846 for (; symp < symendp; symp ++)
885 if (strcmp ((char *) (symnames + symp->st_name), "_end") == 0 847 if (strcmp ((char *) (symnames + symp->st_name), "_end") == 0
886 || strcmp ((char *) (symnames + symp->st_name), "_edata") == 0) 848 || strcmp ((char *) (symnames + symp->st_name), "_edata") == 0)
887 memcpy (&symp->st_value, &new_bss_addr, sizeof (new_bss_addr)); 849 memcpy (&symp->st_value, &new_bss_addr, sizeof (new_bss_addr));
889 851
890 /* This loop seeks out relocation sections for the data section, so 852 /* This loop seeks out relocation sections for the data section, so
891 that it can undo relocations performed by the runtime linker. */ 853 that it can undo relocations performed by the runtime linker. */
892 for (n = new_file_h->e_shnum - 1; n; n--) 854 for (n = new_file_h->e_shnum - 1; n; n--)
893 { 855 {
894 ElfW(Shdr) section = NEW_SECTION_H (n); 856 Elf32_Shdr section = NEW_SECTION_H (n);
895 switch (section.sh_type) { 857 switch (section.sh_type) {
896 default: 858 default:
897 break; 859 break;
898 case SHT_REL: 860 case SHT_REL:
899 case SHT_RELA: 861 case SHT_RELA:
903 nn = section.sh_info; 865 nn = section.sh_info;
904 if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data") 866 if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data")
905 || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), 867 || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
906 ".data1")) 868 ".data1"))
907 { 869 {
908 ElfW(Addr) offset = NEW_SECTION_H (nn).sh_addr - 870 Elf32_Addr offset = NEW_SECTION_H (nn).sh_addr -
909 NEW_SECTION_H (nn).sh_offset; 871 NEW_SECTION_H (nn).sh_offset;
910 caddr_t reloc = old_base + section.sh_offset, end; 872 caddr_t reloc = old_base + section.sh_offset, end;
911 for (end = reloc + section.sh_size; reloc < end; 873 for (end = reloc + section.sh_size; reloc < end;
912 reloc += section.sh_entsize) 874 reloc += section.sh_entsize)
913 { 875 {
914 ElfW(Addr) addr; 876 Elf32_Addr addr = ((Elf32_Rel *) reloc)->r_offset - offset;
915 #ifdef __alpha__ 877 memcpy (new_base + addr, old_base + addr, 4);
916 /* The Alpha ELF binutils currently have a bug that
917 sometimes results in relocs that contain all
918 zeroes. Work around this for now... */
919 if (((ElfW(Rel) *) reloc)->r_offset == 0)
920 continue;
921 #endif
922 addr = ((ElfW(Rel) *) reloc)->r_offset - offset;
923 memcpy (new_base + addr, old_base + addr, sizeof(ElfW(Addr)));
924 } 878 }
925 } 879 }
926 break; 880 break;
927 } 881 }
928 } 882 }