aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKarl Heuer1996-07-15 22:00:12 +0000
committerKarl Heuer1996-07-15 22:00:12 +0000
commit9da3f2d46ec6e9d337ff0bae5b4d382bfdf0ea51 (patch)
tree1170119c260bef7cd26e9624c3c44ad51caa5b4f /src
parente493299546bcc220e94e3d53501607f0e7d7823f (diff)
downloademacs-9da3f2d46ec6e9d337ff0bae5b4d382bfdf0ea51.tar.gz
emacs-9da3f2d46ec6e9d337ff0bae5b4d382bfdf0ea51.zip
Add 64-bit ELF and Alpha/ELF support.
Diffstat (limited to 'src')
-rw-r--r--src/unexelf.c126
1 files changed, 86 insertions, 40 deletions
diff --git a/src/unexelf.c b/src/unexelf.c
index 60e82cc6a95..1575b23b51d 100644
--- a/src/unexelf.c
+++ b/src/unexelf.c
@@ -423,6 +423,22 @@ Filesz Memsz Flags Align
423#include <elf.h> 423#include <elf.h>
424#include <sys/mman.h> 424#include <sys/mman.h>
425 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
426#ifndef emacs 442#ifndef emacs
427#define fatal(a, b, c) fprintf (stderr, a, b, c), exit (1) 443#define fatal(a, b, c) fprintf (stderr, a, b, c), exit (1)
428#else 444#else
@@ -462,13 +478,13 @@ extern void fatal (char *, ...);
462 */ 478 */
463 479
464#define OLD_SECTION_H(n) \ 480#define OLD_SECTION_H(n) \
465 (*(Elf32_Shdr *) ((byte *) old_section_h + old_file_h->e_shentsize * (n))) 481 (*(ElfW(Shdr) *) ((byte *) old_section_h + old_file_h->e_shentsize * (n)))
466#define NEW_SECTION_H(n) \ 482#define NEW_SECTION_H(n) \
467 (*(Elf32_Shdr *) ((byte *) new_section_h + new_file_h->e_shentsize * (n))) 483 (*(ElfW(Shdr) *) ((byte *) new_section_h + new_file_h->e_shentsize * (n)))
468#define OLD_PROGRAM_H(n) \ 484#define OLD_PROGRAM_H(n) \
469 (*(Elf32_Phdr *) ((byte *) old_program_h + old_file_h->e_phentsize * (n))) 485 (*(ElfW(Phdr) *) ((byte *) old_program_h + old_file_h->e_phentsize * (n)))
470#define NEW_PROGRAM_H(n) \ 486#define NEW_PROGRAM_H(n) \
471 (*(Elf32_Phdr *) ((byte *) new_program_h + new_file_h->e_phentsize * (n))) 487 (*(ElfW(Phdr) *) ((byte *) new_program_h + new_file_h->e_phentsize * (n)))
472 488
473#define PATCH_INDEX(n) \ 489#define PATCH_INDEX(n) \
474 do { \ 490 do { \
@@ -510,19 +526,19 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
510 /* Pointers to the file, program and section headers for the old and new 526 /* Pointers to the file, program and section headers for the old and new
511 * files. 527 * files.
512 */ 528 */
513 Elf32_Ehdr *old_file_h, *new_file_h; 529 ElfW(Ehdr) *old_file_h, *new_file_h;
514 Elf32_Phdr *old_program_h, *new_program_h; 530 ElfW(Phdr) *old_program_h, *new_program_h;
515 Elf32_Shdr *old_section_h, *new_section_h; 531 ElfW(Shdr) *old_section_h, *new_section_h;
516 532
517 /* Point to the section name table in the old file */ 533 /* Point to the section name table in the old file */
518 char *old_section_names; 534 char *old_section_names;
519 535
520 Elf32_Addr old_bss_addr, new_bss_addr; 536 ElfW(Addr) old_bss_addr, new_bss_addr;
521 Elf32_Word old_bss_size, new_data2_size; 537 ElfW(Addr) old_bss_size, new_data2_size;
522 Elf32_Off new_data2_offset; 538 ElfW(Off) new_data2_offset;
523 Elf32_Addr new_data2_addr; 539 ElfW(Addr) new_data2_addr;
524 540
525 int n, nn, old_bss_index, old_data_index, new_data2_index; 541 int n, nn, old_bss_index, old_data_index;
526 struct stat stat_buf; 542 struct stat stat_buf;
527 543
528 /* Open the old file & map it into the address space. */ 544 /* Open the old file & map it into the address space. */
@@ -541,15 +557,15 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
541 fatal ("Can't mmap (%s): errno %d\n", old_name, errno); 557 fatal ("Can't mmap (%s): errno %d\n", old_name, errno);
542 558
543#ifdef DEBUG 559#ifdef DEBUG
544 fprintf (stderr, "mmap (%s, %x) -> %x\n", old_name, stat_buf.st_size, 560 fprintf (stderr, "mmap (%s, %lx) -> %lx\n", old_name, stat_buf.st_size,
545 old_base); 561 (unsigned long) old_base);
546#endif 562#endif
547 563
548 /* Get pointers to headers & section names */ 564 /* Get pointers to headers & section names */
549 565
550 old_file_h = (Elf32_Ehdr *) old_base; 566 old_file_h = (ElfW(Ehdr) *) old_base;
551 old_program_h = (Elf32_Phdr *) ((byte *) old_base + old_file_h->e_phoff); 567 old_program_h = (ElfW(Phdr) *) ((byte *) old_base + old_file_h->e_phoff);
552 old_section_h = (Elf32_Shdr *) ((byte *) old_base + old_file_h->e_shoff); 568 old_section_h = (ElfW(Shdr) *) ((byte *) old_base + old_file_h->e_shoff);
553 old_section_names = (char *) old_base 569 old_section_names = (char *) old_base
554 + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset; 570 + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset;
555 571
@@ -574,7 +590,7 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
574 old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr; 590 old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr;
575 old_bss_size = OLD_SECTION_H (old_bss_index).sh_size; 591 old_bss_size = OLD_SECTION_H (old_bss_index).sh_size;
576#if defined(emacs) || !defined(DEBUG) 592#if defined(emacs) || !defined(DEBUG)
577 new_bss_addr = (Elf32_Addr) sbrk (0); 593 new_bss_addr = (ElfW(Addr)) sbrk (0);
578#else 594#else
579 new_bss_addr = old_bss_addr + old_bss_size + 0x1234; 595 new_bss_addr = old_bss_addr + old_bss_size + 0x1234;
580#endif 596#endif
@@ -584,15 +600,16 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
584 600
585#ifdef DEBUG 601#ifdef DEBUG
586 fprintf (stderr, "old_bss_index %d\n", old_bss_index); 602 fprintf (stderr, "old_bss_index %d\n", old_bss_index);
587 fprintf (stderr, "old_bss_addr %x\n", old_bss_addr); 603 fprintf (stderr, "old_bss_addr %lx\n", old_bss_addr);
588 fprintf (stderr, "old_bss_size %x\n", old_bss_size); 604 fprintf (stderr, "old_bss_size %lx\n", old_bss_size);
589 fprintf (stderr, "new_bss_addr %x\n", new_bss_addr); 605 fprintf (stderr, "new_bss_addr %lx\n", new_bss_addr);
590 fprintf (stderr, "new_data2_addr %x\n", new_data2_addr); 606 fprintf (stderr, "new_data2_addr %lx\n", new_data2_addr);
591 fprintf (stderr, "new_data2_size %x\n", new_data2_size); 607 fprintf (stderr, "new_data2_size %lx\n", new_data2_size);
592 fprintf (stderr, "new_data2_offset %x\n", new_data2_offset); 608 fprintf (stderr, "new_data2_offset %lx\n", new_data2_offset);
593#endif 609#endif
594 610
595 if ((unsigned) new_bss_addr < (unsigned) old_bss_addr + old_bss_size) 611 if ((unsigned long) new_bss_addr
612 < (unsigned long) old_bss_addr + old_bss_size)
596 fatal (".bss shrank when undumping???\n", 0, 0); 613 fatal (".bss shrank when undumping???\n", 0, 0);
597 614
598 /* Set the output file to the right size and mmap it. Set 615 /* Set the output file to the right size and mmap it. Set
@@ -620,9 +637,9 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
620 if (new_base == (caddr_t) -1) 637 if (new_base == (caddr_t) -1)
621 fatal ("Can't mmap (%s): errno %d\n", new_name, errno); 638 fatal ("Can't mmap (%s): errno %d\n", new_name, errno);
622 639
623 new_file_h = (Elf32_Ehdr *) new_base; 640 new_file_h = (ElfW(Ehdr) *) new_base;
624 new_program_h = (Elf32_Phdr *) ((byte *) new_base + old_file_h->e_phoff); 641 new_program_h = (ElfW(Phdr) *) ((byte *) new_base + old_file_h->e_phoff);
625 new_section_h = (Elf32_Shdr *) 642 new_section_h = (ElfW(Shdr) *)
626 ((byte *) new_base + old_file_h->e_shoff + new_data2_size); 643 ((byte *) new_base + old_file_h->e_shoff + new_data2_size);
627 644
628 /* Make our new file, program and section headers as copies of the 645 /* Make our new file, program and section headers as copies of the
@@ -644,9 +661,9 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
644 new_file_h->e_shnum += 1; 661 new_file_h->e_shnum += 1;
645 662
646#ifdef DEBUG 663#ifdef DEBUG
647 fprintf (stderr, "Old section offset %x\n", old_file_h->e_shoff); 664 fprintf (stderr, "Old section offset %lx\n", old_file_h->e_shoff);
648 fprintf (stderr, "Old section count %d\n", old_file_h->e_shnum); 665 fprintf (stderr, "Old section count %d\n", old_file_h->e_shnum);
649 fprintf (stderr, "New section offset %x\n", new_file_h->e_shoff); 666 fprintf (stderr, "New section offset %lx\n", new_file_h->e_shoff);
650 fprintf (stderr, "New section count %d\n", new_file_h->e_shnum); 667 fprintf (stderr, "New section count %d\n", new_file_h->e_shnum);
651#endif 668#endif
652 669
@@ -661,7 +678,7 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
661 for (n = new_file_h->e_phnum - 1; n >= 0; n--) 678 for (n = new_file_h->e_phnum - 1; n >= 0; n--)
662 { 679 {
663 /* Compute maximum of all requirements for alignment of section. */ 680 /* Compute maximum of all requirements for alignment of section. */
664 int alignment = (NEW_PROGRAM_H (n)).p_align; 681 unsigned int alignment = (NEW_PROGRAM_H (n)).p_align;
665 if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment) 682 if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment)
666 alignment = OLD_SECTION_H (old_bss_index).sh_addralign; 683 alignment = OLD_SECTION_H (old_bss_index).sh_addralign;
667 684
@@ -808,13 +825,34 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
808 memcpy (NEW_SECTION_H (nn).sh_offset + new_base, src, 825 memcpy (NEW_SECTION_H (nn).sh_offset + new_base, src,
809 NEW_SECTION_H (nn).sh_size); 826 NEW_SECTION_H (nn).sh_size);
810 827
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
811 /* If it is the symbol table, its st_shndx field needs to be patched. */ 849 /* If it is the symbol table, its st_shndx field needs to be patched. */
812 if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB 850 if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB
813 || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM) 851 || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM)
814 { 852 {
815 Elf32_Shdr *spt = &NEW_SECTION_H (nn); 853 ElfW(Shdr) *spt = &NEW_SECTION_H (nn);
816 unsigned int num = spt->sh_size / spt->sh_entsize; 854 unsigned int num = spt->sh_size / spt->sh_entsize;
817 Elf32_Sym * sym = (Elf32_Sym *) (NEW_SECTION_H (nn).sh_offset + 855 ElfW(Sym) * sym = (ElfW(Sym) *) (NEW_SECTION_H (nn).sh_offset +
818 new_base); 856 new_base);
819 for (; num--; sym++) 857 for (; num--; sym++)
820 { 858 {
@@ -832,7 +870,7 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
832 for (n = new_file_h->e_shnum - 1; n; n--) 870 for (n = new_file_h->e_shnum - 1; n; n--)
833 { 871 {
834 byte *symnames; 872 byte *symnames;
835 Elf32_Sym *symp, *symendp; 873 ElfW(Sym) *symp, *symendp;
836 874
837 if (NEW_SECTION_H (n).sh_type != SHT_DYNSYM 875 if (NEW_SECTION_H (n).sh_type != SHT_DYNSYM
838 && NEW_SECTION_H (n).sh_type != SHT_SYMTAB) 876 && NEW_SECTION_H (n).sh_type != SHT_SYMTAB)
@@ -840,8 +878,8 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
840 878
841 symnames = ((byte *) new_base 879 symnames = ((byte *) new_base
842 + NEW_SECTION_H (NEW_SECTION_H (n).sh_link).sh_offset); 880 + NEW_SECTION_H (NEW_SECTION_H (n).sh_link).sh_offset);
843 symp = (Elf32_Sym *) (NEW_SECTION_H (n).sh_offset + new_base); 881 symp = (ElfW(Sym) *) (NEW_SECTION_H (n).sh_offset + new_base);
844 symendp = (Elf32_Sym *) ((byte *)symp + NEW_SECTION_H (n).sh_size); 882 symendp = (ElfW(Sym) *) ((byte *)symp + NEW_SECTION_H (n).sh_size);
845 883
846 for (; symp < symendp; symp ++) 884 for (; symp < symendp; symp ++)
847 if (strcmp ((char *) (symnames + symp->st_name), "_end") == 0 885 if (strcmp ((char *) (symnames + symp->st_name), "_end") == 0
@@ -853,7 +891,7 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
853 that it can undo relocations performed by the runtime linker. */ 891 that it can undo relocations performed by the runtime linker. */
854 for (n = new_file_h->e_shnum - 1; n; n--) 892 for (n = new_file_h->e_shnum - 1; n; n--)
855 { 893 {
856 Elf32_Shdr section = NEW_SECTION_H (n); 894 ElfW(Shdr) section = NEW_SECTION_H (n);
857 switch (section.sh_type) { 895 switch (section.sh_type) {
858 default: 896 default:
859 break; 897 break;
@@ -867,14 +905,22 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
867 || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), 905 || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
868 ".data1")) 906 ".data1"))
869 { 907 {
870 Elf32_Addr offset = NEW_SECTION_H (nn).sh_addr - 908 ElfW(Addr) offset = NEW_SECTION_H (nn).sh_addr -
871 NEW_SECTION_H (nn).sh_offset; 909 NEW_SECTION_H (nn).sh_offset;
872 caddr_t reloc = old_base + section.sh_offset, end; 910 caddr_t reloc = old_base + section.sh_offset, end;
873 for (end = reloc + section.sh_size; reloc < end; 911 for (end = reloc + section.sh_size; reloc < end;
874 reloc += section.sh_entsize) 912 reloc += section.sh_entsize)
875 { 913 {
876 Elf32_Addr addr = ((Elf32_Rel *) reloc)->r_offset - offset; 914 ElfW(Addr) addr;
877 memcpy (new_base + addr, old_base + addr, 4); 915#ifdef __alpha__
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)));
878 } 924 }
879 } 925 }
880 break; 926 break;