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 }