Mercurial > hg > xemacs-beta
comparison src/unexelf.c @ 255:084402c475ba r20-5b26
Import from CVS: tag r20-5b26
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:21:18 +0200 |
parents | 677f6a0ee643 |
children | 65c19d2020f7 |
comparison
equal
deleted
inserted
replaced
254:e92abcaa252b | 255:084402c475ba |
---|---|
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 19.31. */ | 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 |
417 #include <errno.h> | 417 #include <errno.h> |
418 #include <unistd.h> | 418 #include <unistd.h> |
419 #include <fcntl.h> | 419 #include <fcntl.h> |
420 #include <elf.h> | 420 #include <elf.h> |
421 #include <sys/mman.h> | 421 #include <sys/mman.h> |
422 | |
423 #if __GNU_LIBRARY__ - 0 >= 6 | |
424 # include <link.h> /* get ElfW etc */ | |
425 #endif | |
426 | |
427 #ifndef ElfW | |
428 # ifdef __STDC__ | |
429 # define ElfW(type) Elf32_##type | |
430 # else | |
431 # define ElfW(type) Elf32_/**/type | |
432 # endif | |
433 #endif | |
422 | 434 |
423 #ifndef emacs | 435 #ifndef emacs |
424 #define fatal(a, b, c) fprintf (stderr, a, b, c), exit (1) | 436 #define fatal(a, b, c) fprintf (stderr, a, b, c), exit (1) |
425 #else | 437 #else |
426 #include <config.h> | 438 #include <config.h> |
457 deumens@qtp.ufl.edu | 469 deumens@qtp.ufl.edu |
458 Apr 23, 1996 | 470 Apr 23, 1996 |
459 */ | 471 */ |
460 | 472 |
461 #define OLD_SECTION_H(n) \ | 473 #define OLD_SECTION_H(n) \ |
462 (*(Elf32_Shdr *) ((byte *) old_section_h + old_file_h->e_shentsize * (n))) | 474 (*(ElfW(Shdr) *) ((byte *) old_section_h + old_file_h->e_shentsize * (n))) |
463 #define NEW_SECTION_H(n) \ | 475 #define NEW_SECTION_H(n) \ |
464 (*(Elf32_Shdr *) ((byte *) new_section_h + new_file_h->e_shentsize * (n))) | 476 (*(ElfW(Shdr) *) ((byte *) new_section_h + new_file_h->e_shentsize * (n))) |
465 #define OLD_PROGRAM_H(n) \ | 477 #define OLD_PROGRAM_H(n) \ |
466 (*(Elf32_Phdr *) ((byte *) old_program_h + old_file_h->e_phentsize * (n))) | 478 (*(ElfW(Phdr) *) ((byte *) old_program_h + old_file_h->e_phentsize * (n))) |
467 #define NEW_PROGRAM_H(n) \ | 479 #define NEW_PROGRAM_H(n) \ |
468 (*(Elf32_Phdr *) ((byte *) new_program_h + new_file_h->e_phentsize * (n))) | 480 (*(ElfW(Phdr) *) ((byte *) new_program_h + new_file_h->e_phentsize * (n))) |
469 | 481 |
470 #define PATCH_INDEX(n) \ | 482 #define PATCH_INDEX(n) \ |
471 do { \ | 483 do { \ |
472 if ((int) (n) >= old_bss_index) \ | 484 if ((int) (n) >= old_bss_index) \ |
473 (n)++; } while (0) | 485 (n)++; } while (0) |
505 caddr_t old_base, new_base; | 517 caddr_t old_base, new_base; |
506 | 518 |
507 /* Pointers to the file, program and section headers for the old and new | 519 /* Pointers to the file, program and section headers for the old and new |
508 * files. | 520 * files. |
509 */ | 521 */ |
510 Elf32_Ehdr *old_file_h, *new_file_h; | 522 ElfW(Ehdr) *old_file_h, *new_file_h; |
511 Elf32_Phdr *old_program_h, *new_program_h; | 523 ElfW(Phdr) *old_program_h, *new_program_h; |
512 Elf32_Shdr *old_section_h, *new_section_h; | 524 ElfW(Shdr) *old_section_h, *new_section_h; |
513 | 525 |
514 /* Point to the section name table in the old file */ | 526 /* Point to the section name table in the old file */ |
515 char *old_section_names; | 527 char *old_section_names; |
516 | 528 |
517 Elf32_Addr old_bss_addr, new_bss_addr; | 529 ElfW(Addr) old_bss_addr, new_bss_addr; |
518 Elf32_Word old_bss_size, new_data2_size; | 530 ElfW(Word) old_bss_size, new_data2_size; |
519 Elf32_Off new_data2_offset; | 531 ElfW(Off) new_data2_offset; |
520 Elf32_Addr new_data2_addr; | 532 ElfW(Addr) new_data2_addr; |
521 | 533 |
522 int n, nn, old_bss_index, old_data_index; | 534 int n, nn, old_bss_index, old_data_index; |
523 struct stat stat_buf; | 535 struct stat stat_buf; |
524 | 536 |
525 /* Open the old file & map it into the address space. */ | 537 /* Open the old file & map it into the address space. */ |
542 old_base); | 554 old_base); |
543 #endif | 555 #endif |
544 | 556 |
545 /* Get pointers to headers & section names */ | 557 /* Get pointers to headers & section names */ |
546 | 558 |
547 old_file_h = (Elf32_Ehdr *) old_base; | 559 old_file_h = (ElfW(Ehdr) *) old_base; |
548 old_program_h = (Elf32_Phdr *) ((byte *) old_base + old_file_h->e_phoff); | 560 old_program_h = (ElfW(Phdr) *) ((byte *) old_base + old_file_h->e_phoff); |
549 old_section_h = (Elf32_Shdr *) ((byte *) old_base + old_file_h->e_shoff); | 561 old_section_h = (ElfW(Shdr) *) ((byte *) old_base + old_file_h->e_shoff); |
550 old_section_names = (char *) old_base | 562 old_section_names = (char *) old_base |
551 + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset; | 563 + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset; |
552 | 564 |
553 /* Find the old .bss section. Figure out parameters of the new | 565 /* Find the old .bss section. Figure out parameters of the new |
554 * data2 and bss sections. | 566 * data2 and bss sections. |
568 if (old_bss_index == old_file_h->e_shnum) | 580 if (old_bss_index == old_file_h->e_shnum) |
569 fatal ("Can't find .bss in %s.\n", old_name, 0); | 581 fatal ("Can't find .bss in %s.\n", old_name, 0); |
570 | 582 |
571 old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr; | 583 old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr; |
572 old_bss_size = OLD_SECTION_H (old_bss_index).sh_size; | 584 old_bss_size = OLD_SECTION_H (old_bss_index).sh_size; |
573 #if defined(emacs) || !defined(DEBUG) | 585 #if defined (emacs) || !defined (DEBUG) |
574 new_bss_addr = (Elf32_Addr) sbrk (0); | 586 new_bss_addr = (ElfW(Addr)) sbrk (0); |
575 #else | 587 #else |
576 new_bss_addr = old_bss_addr + old_bss_size + 0x1234; | 588 new_bss_addr = old_bss_addr + old_bss_size + 0x1234; |
577 #endif | 589 #endif |
578 new_data2_addr = old_bss_addr; | 590 new_data2_addr = old_bss_addr; |
579 new_data2_size = new_bss_addr - old_bss_addr; | 591 new_data2_size = new_bss_addr - old_bss_addr; |
615 #endif | 627 #endif |
616 | 628 |
617 if (new_base == (caddr_t) -1) | 629 if (new_base == (caddr_t) -1) |
618 fatal ("Can't mmap (%s): errno %d\n", new_name, errno); | 630 fatal ("Can't mmap (%s): errno %d\n", new_name, errno); |
619 | 631 |
620 new_file_h = (Elf32_Ehdr *) new_base; | 632 new_file_h = (ElfW(Ehdr) *) new_base; |
621 new_program_h = (Elf32_Phdr *) ((byte *) new_base + old_file_h->e_phoff); | 633 new_program_h = (ElfW(Phdr) *) ((byte *) new_base + old_file_h->e_phoff); |
622 new_section_h = (Elf32_Shdr *) | 634 new_section_h = (ElfW(Shdr) *) |
623 ((byte *) new_base + old_file_h->e_shoff + new_data2_size); | 635 ((byte *) new_base + old_file_h->e_shoff + new_data2_size); |
624 | 636 |
625 /* Make our new file, program and section headers as copies of the | 637 /* Make our new file, program and section headers as copies of the |
626 * originals. | 638 * originals. |
627 */ | 639 */ |
819 | 831 |
820 /* 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. */ |
821 if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB | 833 if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB |
822 || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM) | 834 || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM) |
823 { | 835 { |
824 Elf32_Shdr *spt = &NEW_SECTION_H (nn); | 836 ElfW(Shdr) *spt = &NEW_SECTION_H (nn); |
825 unsigned int num = spt->sh_size / spt->sh_entsize; | 837 unsigned int num = spt->sh_size / spt->sh_entsize; |
826 Elf32_Sym * sym = (Elf32_Sym *) (NEW_SECTION_H (nn).sh_offset + | 838 ElfW(Sym) * sym = (ElfW(Sym) *) (NEW_SECTION_H (nn).sh_offset + |
827 new_base); | 839 new_base); |
828 for (; num--; sym++) | 840 for (; num--; sym++) |
829 { | 841 { |
830 if ((sym->st_shndx == SHN_UNDEF) | 842 if ((sym->st_shndx == SHN_UNDEF) |
831 || (sym->st_shndx == SHN_ABS) | 843 || (sym->st_shndx == SHN_ABS) |
839 | 851 |
840 /* Update the symbol values of _edata and _end. */ | 852 /* Update the symbol values of _edata and _end. */ |
841 for (n = new_file_h->e_shnum - 1; n; n--) | 853 for (n = new_file_h->e_shnum - 1; n; n--) |
842 { | 854 { |
843 byte *symnames; | 855 byte *symnames; |
844 Elf32_Sym *symp, *symendp; | 856 ElfW(Sym) *symp, *symendp; |
845 | 857 |
846 if (NEW_SECTION_H (n).sh_type != SHT_DYNSYM | 858 if (NEW_SECTION_H (n).sh_type != SHT_DYNSYM |
847 && NEW_SECTION_H (n).sh_type != SHT_SYMTAB) | 859 && NEW_SECTION_H (n).sh_type != SHT_SYMTAB) |
848 continue; | 860 continue; |
849 | 861 |
850 symnames = ((byte *) new_base | 862 symnames = ((byte *) new_base |
851 + NEW_SECTION_H (NEW_SECTION_H (n).sh_link).sh_offset); | 863 + NEW_SECTION_H (NEW_SECTION_H (n).sh_link).sh_offset); |
852 symp = (Elf32_Sym *) (NEW_SECTION_H (n).sh_offset + new_base); | 864 symp = (ElfW(Sym) *) (NEW_SECTION_H (n).sh_offset + new_base); |
853 symendp = (Elf32_Sym *) ((byte *)symp + NEW_SECTION_H (n).sh_size); | 865 symendp = (ElfW(Sym) *) ((byte *)symp + NEW_SECTION_H (n).sh_size); |
854 | 866 |
855 for (; symp < symendp; symp ++) | 867 for (; symp < symendp; symp ++) |
856 if (strcmp ((char *) (symnames + symp->st_name), "_end") == 0 | 868 if (strcmp ((char *) (symnames + symp->st_name), "_end") == 0 |
857 || strcmp ((char *) (symnames + symp->st_name), "_edata") == 0) | 869 || strcmp ((char *) (symnames + symp->st_name), "_edata") == 0) |
858 memcpy (&symp->st_value, &new_bss_addr, sizeof (new_bss_addr)); | 870 memcpy (&symp->st_value, &new_bss_addr, sizeof (new_bss_addr)); |
860 | 872 |
861 /* This loop seeks out relocation sections for the data section, so | 873 /* This loop seeks out relocation sections for the data section, so |
862 that it can undo relocations performed by the runtime linker. */ | 874 that it can undo relocations performed by the runtime linker. */ |
863 for (n = new_file_h->e_shnum - 1; n; n--) | 875 for (n = new_file_h->e_shnum - 1; n; n--) |
864 { | 876 { |
865 Elf32_Shdr section = NEW_SECTION_H (n); | 877 ElfW(Shdr) section = NEW_SECTION_H (n); |
866 switch (section.sh_type) { | 878 switch (section.sh_type) { |
867 default: | 879 default: |
868 break; | 880 break; |
869 case SHT_REL: | 881 case SHT_REL: |
870 case SHT_RELA: | 882 case SHT_RELA: |
882 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") |
883 || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), | 895 || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), |
884 ".data1")) | 896 ".data1")) |
885 #endif | 897 #endif |
886 { | 898 { |
887 Elf32_Addr offset = NEW_SECTION_H (nn).sh_addr - | 899 ElfW(Addr) offset = NEW_SECTION_H (nn).sh_addr - |
888 NEW_SECTION_H (nn).sh_offset; | 900 NEW_SECTION_H (nn).sh_offset; |
889 caddr_t reloc = old_base + section.sh_offset, end; | 901 caddr_t reloc = old_base + section.sh_offset, end; |
890 for (end = reloc + section.sh_size; reloc < end; | 902 for (end = reloc + section.sh_size; reloc < end; |
891 reloc += section.sh_entsize) | 903 reloc += section.sh_entsize) |
892 { | 904 { |
893 Elf32_Addr addr = ((Elf32_Rel *) reloc)->r_offset - offset; | 905 ElfW(Addr) addr = ((ElfW(Rel) *) reloc)->r_offset - offset; |
894 memcpy (new_base + addr, old_base + addr, 4); | 906 memcpy (new_base + addr, old_base + addr, sizeof(ElfW(Addr))); |
895 } | 907 } |
896 } | 908 } |
897 break; | 909 break; |
898 } | 910 } |
899 } | 911 } |