Mercurial > hg > xemacs-beta
comparison src/unexelfsgi.c @ 163:0132846995bd r20-3b8
Import from CVS: tag r20-3b8
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:43:35 +0200 |
parents | 131b0175ea99 |
children | 5a88923fcbfe |
comparison
equal
deleted
inserted
replaced
162:4de2936b4e77 | 163:0132846995bd |
---|---|
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 | 482 /* Still more mods... Olivier Galibert 19971705 |
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 */ | |
483 | 488 |
484 #include <sys/types.h> | 489 #include <sys/types.h> |
485 #include <stdio.h> | 490 #include <stdio.h> |
486 #include <sys/stat.h> | 491 #include <sys/stat.h> |
487 #include <memory.h> | 492 #include <memory.h> |
491 #include <fcntl.h> | 496 #include <fcntl.h> |
492 #include <elf.h> | 497 #include <elf.h> |
493 #include <sym.h> /* for HDRR declaration */ | 498 #include <sym.h> /* for HDRR declaration */ |
494 #include <sys/mman.h> | 499 #include <sys/mman.h> |
495 | 500 |
501 /* in 64bits mode, use 64bits elf */ | |
502 #ifdef _ABI64 | |
503 typedef Elf64_Shdr l_Elf_Shdr; | |
504 typedef Elf64_Phdr l_Elf_Phdr; | |
505 typedef Elf64_Ehdr l_Elf_Ehdr; | |
506 typedef Elf64_Addr l_Elf_Addr; | |
507 typedef Elf64_Word l_Elf_Word; | |
508 typedef Elf64_Off l_Elf_Off; | |
509 typedef Elf64_Sym l_Elf_Sym; | |
510 #else | |
511 typedef Elf32_Shdr l_Elf_Shdr; | |
512 typedef Elf32_Phdr l_Elf_Phdr; | |
513 typedef Elf32_Ehdr l_Elf_Ehdr; | |
514 typedef Elf32_Addr l_Elf_Addr; | |
515 typedef Elf32_Word l_Elf_Word; | |
516 typedef Elf32_Off l_Elf_Off; | |
517 typedef Elf32_Sym l_Elf_Sym; | |
518 #endif | |
519 | |
520 | |
496 #ifndef emacs | 521 #ifndef emacs |
497 #define fatal(a, b, c) fprintf(stderr, a, b, c), exit(1) | 522 #define fatal(a, b, c) fprintf(stderr, a, b, c), exit(1) |
498 #else | 523 #else |
499 extern void fatal(char *, ...); | 524 extern void fatal(char *, ...); |
500 #endif | 525 #endif |
502 /* Get the address of a particular section or program header entry, | 527 /* Get the address of a particular section or program header entry, |
503 * accounting for the size of the entries. | 528 * accounting for the size of the entries. |
504 */ | 529 */ |
505 | 530 |
506 #define OLD_SECTION_H(n) \ | 531 #define OLD_SECTION_H(n) \ |
507 (*(Elf32_Shdr *) ((byte *) old_section_h + old_file_h->e_shentsize * (n))) | 532 (*(l_Elf_Shdr *) ((byte *) old_section_h + old_file_h->e_shentsize * (n))) |
508 #define NEW_SECTION_H(n) \ | 533 #define NEW_SECTION_H(n) \ |
509 (*(Elf32_Shdr *) ((byte *) new_section_h + new_file_h->e_shentsize * (n))) | 534 (*(l_Elf_Shdr *) ((byte *) new_section_h + new_file_h->e_shentsize * (n))) |
510 #define OLD_PROGRAM_H(n) \ | 535 #define OLD_PROGRAM_H(n) \ |
511 (*(Elf32_Phdr *) ((byte *) old_program_h + old_file_h->e_phentsize * (n))) | 536 (*(l_Elf_Phdr *) ((byte *) old_program_h + old_file_h->e_phentsize * (n))) |
512 #define NEW_PROGRAM_H(n) \ | 537 #define NEW_PROGRAM_H(n) \ |
513 (*(Elf32_Phdr *) ((byte *) new_program_h + new_file_h->e_phentsize * (n))) | 538 (*(l_Elf_Phdr *) ((byte *) new_program_h + new_file_h->e_phentsize * (n))) |
514 | 539 |
515 #define PATCH_INDEX(n) \ | 540 #define PATCH_INDEX(n) \ |
516 do { \ | 541 do { \ |
517 if ((n) >= old_bss_index) \ | 542 if ((n) >= old_bss_index) \ |
518 (n)++; } while (0) | 543 (n)++; } while (0) |
540 static int | 565 static int |
541 find_section (name, section_names, file_name, old_file_h, old_section_h, noerror) | 566 find_section (name, section_names, file_name, old_file_h, old_section_h, noerror) |
542 char *name; | 567 char *name; |
543 char *section_names; | 568 char *section_names; |
544 char *file_name; | 569 char *file_name; |
545 Elf32_Ehdr *old_file_h; | 570 l_Elf_Ehdr *old_file_h; |
546 Elf32_Shdr *old_section_h; | 571 l_Elf_Shdr *old_section_h; |
547 int noerror; | 572 int noerror; |
548 { | 573 { |
549 int idx; | 574 int idx; |
550 | 575 |
551 for (idx = 1; idx < old_file_h->e_shnum; idx++) | 576 for (idx = 1; idx < old_file_h->e_shnum; idx++) |
589 /* Pointers to the base of the image of the two files. */ | 614 /* Pointers to the base of the image of the two files. */ |
590 caddr_t old_base, new_base; | 615 caddr_t old_base, new_base; |
591 | 616 |
592 /* Pointers to the file, program and section headers for the old and new | 617 /* Pointers to the file, program and section headers for the old and new |
593 files. */ | 618 files. */ |
594 Elf32_Ehdr *old_file_h, *new_file_h; | 619 l_Elf_Ehdr *old_file_h, *new_file_h; |
595 Elf32_Phdr *old_program_h, *new_program_h; | 620 l_Elf_Phdr *old_program_h, *new_program_h; |
596 Elf32_Shdr *old_section_h, *new_section_h; | 621 l_Elf_Shdr *old_section_h, *new_section_h; |
597 | 622 |
598 /* Point to the section name table in the old file. */ | 623 /* Point to the section name table in the old file. */ |
599 char *old_section_names; | 624 char *old_section_names; |
600 | 625 |
601 Elf32_Addr old_bss_addr, new_bss_addr; | 626 l_Elf_Addr old_bss_addr, new_bss_addr; |
602 Elf32_Word old_bss_size, new_data2_size; | 627 l_Elf_Word old_bss_size, new_data2_size; |
603 Elf32_Off new_data2_offset; | 628 l_Elf_Off new_data2_offset; |
604 Elf32_Addr new_data2_addr; | 629 l_Elf_Addr new_data2_addr; |
605 Elf32_Addr new_offsets_shift; | 630 l_Elf_Addr new_offsets_shift; |
606 | 631 |
607 int n, nn, old_bss_index, old_data_index, new_data2_index; | 632 int n, nn, old_bss_index, old_data_index, new_data2_index; |
608 int old_mdebug_index; | 633 int old_mdebug_index; |
609 struct stat stat_buf; | 634 struct stat stat_buf; |
610 | 635 |
628 old_base); | 653 old_base); |
629 #endif | 654 #endif |
630 | 655 |
631 /* Get pointers to headers & section names. */ | 656 /* Get pointers to headers & section names. */ |
632 | 657 |
633 old_file_h = (Elf32_Ehdr *) old_base; | 658 old_file_h = (l_Elf_Ehdr *) old_base; |
634 old_program_h = (Elf32_Phdr *) ((byte *) old_base + old_file_h->e_phoff); | 659 old_program_h = (l_Elf_Phdr *) ((byte *) old_base + old_file_h->e_phoff); |
635 old_section_h = (Elf32_Shdr *) ((byte *) old_base + old_file_h->e_shoff); | 660 old_section_h = (l_Elf_Shdr *) ((byte *) old_base + old_file_h->e_shoff); |
636 old_section_names | 661 old_section_names |
637 = (char *) old_base + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset; | 662 = (char *) old_base + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset; |
638 | 663 |
639 /* Find the mdebug section, if any. */ | 664 /* Find the mdebug section, if any. */ |
640 | 665 |
654 | 679 |
655 old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr; | 680 old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr; |
656 old_bss_size = OLD_SECTION_H (old_bss_index).sh_size; | 681 old_bss_size = OLD_SECTION_H (old_bss_index).sh_size; |
657 #if defined(emacs) || !defined(DEBUG) | 682 #if defined(emacs) || !defined(DEBUG) |
658 bss_end = (unsigned int) sbrk (0); | 683 bss_end = (unsigned int) sbrk (0); |
659 new_bss_addr = (Elf32_Addr) bss_end; | 684 new_bss_addr = (l_Elf_Addr) bss_end; |
660 #else | 685 #else |
661 new_bss_addr = old_bss_addr + old_bss_size + 0x1234; | 686 new_bss_addr = old_bss_addr + old_bss_size + 0x1234; |
662 #endif | 687 #endif |
663 new_data2_addr = old_bss_addr; | 688 new_data2_addr = old_bss_addr; |
664 new_data2_size = new_bss_addr - old_bss_addr; | 689 new_data2_size = new_bss_addr - old_bss_addr; |
700 new_file, 0); | 725 new_file, 0); |
701 | 726 |
702 if (new_base == (caddr_t) -1) | 727 if (new_base == (caddr_t) -1) |
703 fatal ("Can't mmap (%s): errno %d\n", new_name, errno); | 728 fatal ("Can't mmap (%s): errno %d\n", new_name, errno); |
704 | 729 |
705 new_file_h = (Elf32_Ehdr *) new_base; | 730 new_file_h = (l_Elf_Ehdr *) new_base; |
706 new_program_h = (Elf32_Phdr *) ((byte *) new_base + old_file_h->e_phoff); | 731 new_program_h = (l_Elf_Phdr *) ((byte *) new_base + old_file_h->e_phoff); |
707 new_section_h | 732 new_section_h |
708 = (Elf32_Shdr *) ((byte *) new_base + old_file_h->e_shoff | 733 = (l_Elf_Shdr *) ((byte *) new_base + old_file_h->e_shoff |
709 + new_offsets_shift); | 734 + new_offsets_shift); |
710 | 735 |
711 /* Make our new file, program and section headers as copies of the | 736 /* Make our new file, program and section headers as copies of the |
712 originals. */ | 737 originals. */ |
713 | 738 |
855 so don't change it. */ | 880 so don't change it. */ |
856 if (NEW_SECTION_H (nn).sh_type != SHT_SYMTAB | 881 if (NEW_SECTION_H (nn).sh_type != SHT_SYMTAB |
857 && NEW_SECTION_H (nn).sh_type != SHT_DYNSYM) | 882 && NEW_SECTION_H (nn).sh_type != SHT_DYNSYM) |
858 PATCH_INDEX (NEW_SECTION_H (nn).sh_info); | 883 PATCH_INDEX (NEW_SECTION_H (nn).sh_info); |
859 | 884 |
885 /* Fix the type and alignment for the .sbss section */ | |
886 if (!strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".sbss")) | |
887 { | |
888 NEW_SECTION_H (nn).sh_type = SHT_PROGBITS; | |
889 NEW_SECTION_H (nn).sh_offset = round_up (NEW_SECTION_H (nn).sh_offset, | |
890 NEW_SECTION_H (nn).sh_addralign); | |
891 } | |
892 | |
860 /* Now, start to copy the content of sections. */ | 893 /* Now, start to copy the content of sections. */ |
861 if (NEW_SECTION_H (nn).sh_type == SHT_NULL | 894 if (NEW_SECTION_H (nn).sh_type == SHT_NULL |
862 || NEW_SECTION_H (nn).sh_type == SHT_NOBITS) | 895 || NEW_SECTION_H (nn).sh_type == SHT_NOBITS) |
863 continue; | 896 continue; |
864 | 897 |
865 /* Write out the sections. .data and .data1 (and data2, called | 898 /* Write out the sections. .data, .data1 nad .sbss (and data2, called |
866 ".data" in the strings table) get copied from the current process | 899 ".data" in the strings table) get copied from the current process |
867 instead of the old file. */ | 900 instead of the old file. */ |
868 if (!strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data") | 901 if (!strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data") |
869 || !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data1") | 902 || !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data1") |
870 || !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".got")) | 903 || !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".got") |
904 || !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".sbss")) | |
871 src = (caddr_t) OLD_SECTION_H (n).sh_addr; | 905 src = (caddr_t) OLD_SECTION_H (n).sh_addr; |
872 else | 906 else |
873 src = old_base + OLD_SECTION_H (n).sh_offset; | 907 src = old_base + OLD_SECTION_H (n).sh_offset; |
874 | 908 |
875 memcpy (NEW_SECTION_H (nn).sh_offset + new_base, src, | 909 memcpy (NEW_SECTION_H (nn).sh_offset + new_base, src, |
930 | 964 |
931 /* If it is the symbol table, its st_shndx field needs to be patched. */ | 965 /* If it is the symbol table, its st_shndx field needs to be patched. */ |
932 if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB | 966 if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB |
933 || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM) | 967 || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM) |
934 { | 968 { |
935 Elf32_Shdr *spt = &NEW_SECTION_H (nn); | 969 l_Elf_Shdr *spt = &NEW_SECTION_H (nn); |
936 unsigned int num = spt->sh_size / spt->sh_entsize; | 970 unsigned int num = spt->sh_size / spt->sh_entsize; |
937 Elf32_Sym * sym = (Elf32_Sym *) (NEW_SECTION_H (nn).sh_offset | 971 l_Elf_Sym * sym = (l_Elf_Sym *) (NEW_SECTION_H (nn).sh_offset |
938 + new_base); | 972 + new_base); |
939 for (; num--; sym++) | 973 for (; num--; sym++) |
940 { | 974 { |
941 if (sym->st_shndx == SHN_UNDEF | 975 if (sym->st_shndx == SHN_UNDEF |
942 || sym->st_shndx == SHN_ABS | 976 || sym->st_shndx == SHN_ABS |