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