comparison src/unexec.c @ 4759:aa5ed11f473b

Remove support for obsolete systems. See xemacs-patches message with ID <870180fe0911101613m6b8efa4bpf083fd9013950807@mail.gmail.com>.
author Jerry James <james@xemacs.org>
date Wed, 18 Nov 2009 08:49:14 -0700
parents facf3239ba30
children 304aebb79cd3
comparison
equal deleted inserted replaced
4758:75975fd0b7fc 4759:aa5ed11f473b
77 77
78 * COFF 78 * COFF
79 79
80 Define this if your system uses COFF for executables. 80 Define this if your system uses COFF for executables.
81 81
82 * COFF_ENCAPSULATE
83
84 Define this if you are using the GNU coff encapsulated a.out format.
85 This is closer to a.out than COFF. You should *not* define COFF if
86 you define COFF_ENCAPSULATE
87
88 Otherwise we assume you use Berkeley format.
89
90 * NO_REMAP 82 * NO_REMAP
91 83
92 Define this if you do not want to try to save Emacs's pure data areas 84 Define this if you do not want to try to save Emacs's pure data areas
93 as part of the text segment. 85 as part of the text segment.
94 86
101 Also, remapping can cause trouble with the built-in startup routine 93 Also, remapping can cause trouble with the built-in startup routine
102 /lib/crt0.o, which defines `environ' as an initialized variable. 94 /lib/crt0.o, which defines `environ' as an initialized variable.
103 Dumping `environ' as pure does not work! So, to use remapping, 95 Dumping `environ' as pure does not work! So, to use remapping,
104 you must write a startup routine for your machine in Emacs's crt0.c. 96 you must write a startup routine for your machine in Emacs's crt0.c.
105 If NO_REMAP is defined, Emacs uses the system's crt0.o. 97 If NO_REMAP is defined, Emacs uses the system's crt0.o.
106
107 * SECTION_ALIGNMENT
108
109 Some machines that use COFF executables require that each section
110 start on a certain boundary *in the COFF file*. Such machines should
111 define SECTION_ALIGNMENT to a mask of the low-order bits that must be
112 zero on such a boundary. This mask is used to control padding between
113 segments in the COFF file.
114
115 If SECTION_ALIGNMENT is not defined, the segments are written
116 consecutively with no attempt at alignment. This is right for
117 unmodified system V.
118 98
119 * SEGMENT_MASK 99 * SEGMENT_MASK
120 100
121 Some machines require that the beginnings and ends of segments 101 Some machines require that the beginnings and ends of segments
122 *in core* be on certain boundaries. For most machines, a page 102 *in core* be on certain boundaries. For most machines, a page
194 */ 174 */
195 #if defined(__lucid) && defined(__sparc) && !defined(sun) 175 #if defined(__lucid) && defined(__sparc) && !defined(sun)
196 # define sun 1 176 # define sun 1
197 #endif 177 #endif
198 178
199 #ifdef COFF_ENCAPSULATE
200 int need_coff_header = 1;
201 #include <coff-encap/a.out.encap.h> /* The location might be a poor assumption */
202 #else
203 #include <a.out.h> 179 #include <a.out.h>
204 #endif /* not COFF_ENCAPSULATE */
205 180
206 /* Define getpagesize if the system does not. 181 /* Define getpagesize if the system does not.
207 Note that this may depend on symbols defined in a.out.h. */ 182 Note that this may depend on symbols defined in a.out.h. */
208 #include "getpagesize.h" 183 #include "getpagesize.h"
209 184
212 #endif /* makedev */ 187 #endif /* makedev */
213 #include <stdio.h> 188 #include <stdio.h>
214 #include <sys/stat.h> 189 #include <sys/stat.h>
215 #include <errno.h> 190 #include <errno.h>
216 191
217 #include <sys/file.h> /* Must be after sys/types.h for USG and BSD4_1*/ 192 #include <sys/file.h> /* Must be after sys/types.h for USG */
218 193
219 #ifdef USG5 194 #ifdef USG5
220 #include <fcntl.h> 195 #include <fcntl.h>
221 #endif 196 #endif
222 197
265 extern void *sbrk (); 240 extern void *sbrk ();
266 #endif 241 #endif
267 242
268 #define SYMS_START ((long) N_SYMOFF (ohdr)) 243 #define SYMS_START ((long) N_SYMOFF (ohdr))
269 244
270 /* Some machines override the structure name for an a.out header. */
271 #ifndef EXEC_HDR_TYPE
272 #define EXEC_HDR_TYPE struct exec
273 #endif
274
275 #ifdef HPUX 245 #ifdef HPUX
276 #ifdef HP9000S200_ID
277 #define MY_ID HP9000S200_ID
278 #else
279 #include <model.h> 246 #include <model.h>
280 #define MY_ID MYSYS 247 #define MY_ID MYSYS
281 #endif /* no HP9000S200_ID */
282 static MAGIC OLDMAGIC = {MY_ID, SHARE_MAGIC}; 248 static MAGIC OLDMAGIC = {MY_ID, SHARE_MAGIC};
283 static MAGIC NEWMAGIC = {MY_ID, DEMAND_MAGIC}; 249 static MAGIC NEWMAGIC = {MY_ID, DEMAND_MAGIC};
284 #define N_TXTOFF(x) TEXT_OFFSET(x) 250 #define N_TXTOFF(x) TEXT_OFFSET(x)
285 #define N_SYMOFF(x) LESYM_OFFSET(x) 251 #define N_SYMOFF(x) LESYM_OFFSET(x)
286 static EXEC_HDR_TYPE hdr, ohdr; 252 static struct exec hdr, ohdr;
287 253
288 #else /* not HPUX */ 254 #else /* not HPUX */
289 255
290 #if defined (USG) && !defined (IBMAIX) && !defined (IRIS) && !defined (COFF_ENCAPSULATE) && !defined (LINUX) 256 #if defined (USG) && !defined (LINUX)
291 static struct bhdr hdr, ohdr; 257 static struct bhdr hdr, ohdr;
292 #define a_magic fmagic 258 #define a_magic fmagic
293 #define a_text tsize 259 #define a_text tsize
294 #define a_data dsize 260 #define a_data dsize
295 #define a_bss bsize 261 #define a_bss bsize
299 #define a_entry entry 265 #define a_entry entry
300 #define N_BADMAG(x) \ 266 #define N_BADMAG(x) \
301 (((x).fmagic)!=OMAGIC && ((x).fmagic)!=NMAGIC &&\ 267 (((x).fmagic)!=OMAGIC && ((x).fmagic)!=NMAGIC &&\
302 ((x).fmagic)!=FMAGIC && ((x).fmagic)!=IMAGIC) 268 ((x).fmagic)!=FMAGIC && ((x).fmagic)!=IMAGIC)
303 #define NEWMAGIC FMAGIC 269 #define NEWMAGIC FMAGIC
304 #else /* IRIS or IBMAIX or not USG */ 270 #else /* !USG or LINUX */
305 static EXEC_HDR_TYPE hdr, ohdr; 271 static struct exec hdr, ohdr;
306 #define NEWMAGIC ZMAGIC 272 #define NEWMAGIC ZMAGIC
307 #endif /* IRIS or IBMAIX not USG */ 273 #endif /* !USG or LINUX */
308 #endif /* not HPUX */ 274 #endif /* not HPUX */
309 275
310 static int unexec_text_start; 276 static int unexec_text_start;
311 static int unexec_data_start; 277 static int unexec_data_start;
312
313 #ifdef COFF_ENCAPSULATE
314 /* coffheader is defined in the GNU a.out.encap.h file. */
315 struct coffheader coffheader;
316 #endif
317 278
318 #endif /* not COFF */ 279 #endif /* not COFF */
319 280
320 static int pagemask; 281 static int pagemask;
321 282
390 351
391 if (make_hdr (new_, a_out, data_start, bss_start, entry_address, a_name, new_name) < 0 352 if (make_hdr (new_, a_out, data_start, bss_start, entry_address, a_name, new_name) < 0
392 || copy_text_and_data (new_, a_out) < 0 353 || copy_text_and_data (new_, a_out) < 0
393 || copy_sym (new_, a_out, a_name, new_name) < 0 354 || copy_sym (new_, a_out, a_name, new_name) < 0
394 #ifdef COFF 355 #ifdef COFF
395 #ifndef COFF_BSD_SYMBOLS
396 || adjust_lnnoptrs (new_, a_out, new_name) < 0 356 || adjust_lnnoptrs (new_, a_out, new_name) < 0
397 #endif
398 #endif 357 #endif
399 ) 358 )
400 { 359 {
401 close (new_); 360 close (new_);
402 /* unlink (new_name); / * Failed, unlink new a.out */ 361 /* unlink (new_name); / * Failed, unlink new a.out */
535 bias = bss_start - (f_ohdr.data_start + f_dhdr.s_size); 494 bias = bss_start - (f_ohdr.data_start + f_dhdr.s_size);
536 495
537 #endif 496 #endif
538 497
539 f_hdr.f_flags |= (F_RELFLG | F_EXEC); 498 f_hdr.f_flags |= (F_RELFLG | F_EXEC);
540 #ifdef TPIX
541 f_hdr.f_nscns = 3;
542 #endif
543 #ifdef EXEC_MAGIC 499 #ifdef EXEC_MAGIC
544 f_ohdr.magic = EXEC_MAGIC; 500 f_ohdr.magic = EXEC_MAGIC;
545 #endif 501 #endif
546 #ifndef NO_REMAP 502 #ifndef NO_REMAP
547 f_ohdr.text_start = (long) start_of_text (); 503 f_ohdr.text_start = (long) start_of_text ();
548 f_ohdr.tsize = data_start - f_ohdr.text_start; 504 f_ohdr.tsize = data_start - f_ohdr.text_start;
549 f_ohdr.data_start = data_start; 505 f_ohdr.data_start = data_start;
550 #endif /* NO_REMAP */ 506 #endif /* NO_REMAP */
551 f_ohdr.dsize = bss_start - f_ohdr.data_start; 507 f_ohdr.dsize = bss_start - f_ohdr.data_start;
552 f_ohdr.bsize = bss_end - bss_start; 508 f_ohdr.bsize = bss_end - bss_start;
553 #ifndef KEEP_OLD_TEXT_SCNPTR
554 /* On some machines, the old values are right. 509 /* On some machines, the old values are right.
555 ??? Maybe on all machines with NO_REMAP. */ 510 ??? Maybe on all machines with NO_REMAP. */
556 f_thdr.s_size = f_ohdr.tsize; 511 f_thdr.s_size = f_ohdr.tsize;
557 f_thdr.s_scnptr = sizeof (f_hdr) + sizeof (f_ohdr); 512 f_thdr.s_scnptr = sizeof (f_hdr) + sizeof (f_ohdr);
558 f_thdr.s_scnptr += (f_hdr.f_nscns) * (sizeof (f_thdr)); 513 f_thdr.s_scnptr += (f_hdr.f_nscns) * (sizeof (f_thdr));
559 #endif /* KEEP_OLD_TEXT_SCNPTR */
560 #ifdef ADJUST_TEXT_SCNHDR_SIZE
561 /* On some machines, `text size' includes all headers. */
562 f_thdr.s_size -= f_thdr.s_scnptr;
563 #endif /* ADJUST_TEST_SCNHDR_SIZE */
564 lnnoptr = f_thdr.s_lnnoptr; 514 lnnoptr = f_thdr.s_lnnoptr;
565 #ifdef SECTION_ALIGNMENT
566 /* Some systems require special alignment
567 of the sections in the file itself. */
568 f_thdr.s_scnptr
569 = (f_thdr.s_scnptr + SECTION_ALIGNMENT) & ~SECTION_ALIGNMENT;
570 #endif /* SECTION_ALIGNMENT */
571 #ifdef TPIX
572 f_thdr.s_scnptr = 0xd0;
573 #endif
574 text_scnptr = f_thdr.s_scnptr; 515 text_scnptr = f_thdr.s_scnptr;
575 #ifdef ADJUST_TEXTBASE
576 text_scnptr = sizeof (f_hdr) + sizeof (f_ohdr) + (f_hdr.f_nscns) * (sizeof (f_thdr));
577 #endif
578 #ifndef KEEP_OLD_PADDR
579 f_dhdr.s_paddr = f_ohdr.data_start; 516 f_dhdr.s_paddr = f_ohdr.data_start;
580 #endif /* KEEP_OLD_PADDR */
581 f_dhdr.s_vaddr = f_ohdr.data_start; 517 f_dhdr.s_vaddr = f_ohdr.data_start;
582 f_dhdr.s_size = f_ohdr.dsize; 518 f_dhdr.s_size = f_ohdr.dsize;
583 f_dhdr.s_scnptr = f_thdr.s_scnptr + f_thdr.s_size; 519 f_dhdr.s_scnptr = f_thdr.s_scnptr + f_thdr.s_size;
584 #ifdef SECTION_ALIGNMENT
585 /* Some systems require special alignment
586 of the sections in the file itself. */
587 f_dhdr.s_scnptr
588 = (f_dhdr.s_scnptr + SECTION_ALIGNMENT) & ~SECTION_ALIGNMENT;
589 #endif /* SECTION_ALIGNMENT */
590 #ifdef DATA_SECTION_ALIGNMENT
591 /* Some systems require special alignment
592 of the data section only. */
593 f_dhdr.s_scnptr
594 = (f_dhdr.s_scnptr + DATA_SECTION_ALIGNMENT) & ~DATA_SECTION_ALIGNMENT;
595 #endif /* DATA_SECTION_ALIGNMENT */
596 data_scnptr = f_dhdr.s_scnptr; 520 data_scnptr = f_dhdr.s_scnptr;
597 #ifndef KEEP_OLD_PADDR
598 f_bhdr.s_paddr = f_ohdr.data_start + f_ohdr.dsize; 521 f_bhdr.s_paddr = f_ohdr.data_start + f_ohdr.dsize;
599 #endif /* KEEP_OLD_PADDR */
600 f_bhdr.s_vaddr = f_ohdr.data_start + f_ohdr.dsize; 522 f_bhdr.s_vaddr = f_ohdr.data_start + f_ohdr.dsize;
601 f_bhdr.s_size = f_ohdr.bsize; 523 f_bhdr.s_size = f_ohdr.bsize;
602 f_bhdr.s_scnptr = 0L; 524 f_bhdr.s_scnptr = 0L;
603 #ifndef USG_SHARED_LIBRARIES 525 #ifndef USG_SHARED_LIBRARIES
604 bias = f_dhdr.s_scnptr + f_dhdr.s_size - block_copy_start; 526 bias = f_dhdr.s_scnptr + f_dhdr.s_size - block_copy_start;
699 #else /* if not COFF */ 621 #else /* if not COFF */
700 622
701 /* Get symbol table info from header of a.out file if given one. */ 623 /* Get symbol table info from header of a.out file if given one. */
702 if (a_out >= 0) 624 if (a_out >= 0)
703 { 625 {
704 #ifdef COFF_ENCAPSULATE
705 if (read (a_out, &coffheader, sizeof (coffheader)) != sizeof (coffheader))
706 {
707 PERROR(a_name);
708 }
709 if (coffheader.f_magic != COFF_MAGIC)
710 {
711 ERROR1("%s doesn't have legal coff magic number\n", a_name);
712 }
713 #endif
714 if (read (a_out, (char *) &ohdr, sizeof (hdr)) != sizeof (hdr)) 626 if (read (a_out, (char *) &ohdr, sizeof (hdr)) != sizeof (hdr))
715 { 627 {
716 PERROR (a_name); 628 PERROR (a_name);
717 } 629 }
718 630
722 } 634 }
723 hdr = ohdr; 635 hdr = ohdr;
724 } 636 }
725 else 637 else
726 { 638 {
727 #ifdef COFF_ENCAPSULATE
728 /* We probably could without too much trouble. The code is in gld
729 * but I don't have that much time or incentive.
730 */
731 ERROR0 ("can't build a COFF file from scratch yet");
732 #else
733 memset ((void *)&hdr, 0, sizeof (hdr)); 639 memset ((void *)&hdr, 0, sizeof (hdr));
734 #endif
735 } 640 }
736 641
737 unexec_text_start = (long) start_of_text (); 642 unexec_text_start = (long) start_of_text ();
738 unexec_data_start = data_start; 643 unexec_data_start = data_start;
739 644
757 #ifdef A_TEXT_OFFSET 662 #ifdef A_TEXT_OFFSET
758 hdr.a_text += A_TEXT_OFFSET (ohdr); 663 hdr.a_text += A_TEXT_OFFSET (ohdr);
759 #endif 664 #endif
760 665
761 #endif /* not NO_REMAP */ 666 #endif /* not NO_REMAP */
762
763 #ifdef COFF_ENCAPSULATE
764 /* We are encapsulating BSD format within COFF format. */
765 {
766 struct coffscn *tp, *dp, *bp;
767 tp = &coffheader.scns[0];
768 dp = &coffheader.scns[1];
769 bp = &coffheader.scns[2];
770 tp->s_size = hdr.a_text + sizeof(struct exec);
771 dp->s_paddr = data_start;
772 dp->s_vaddr = data_start;
773 dp->s_size = hdr.a_data;
774 bp->s_paddr = dp->s_vaddr + dp->s_size;
775 bp->s_vaddr = bp->s_paddr;
776 bp->s_size = hdr.a_bss;
777 coffheader.tsize = tp->s_size;
778 coffheader.dsize = dp->s_size;
779 coffheader.bsize = bp->s_size;
780 coffheader.text_start = tp->s_vaddr;
781 coffheader.data_start = dp->s_vaddr;
782 }
783 if (write (new_, &coffheader, sizeof (coffheader)) != sizeof (coffheader))
784 {
785 PERROR(new_name);
786 }
787 #endif /* COFF_ENCAPSULATE */
788 667
789 if (write (new_, (char *) &hdr, sizeof (hdr)) != sizeof (hdr)) 668 if (write (new_, (char *) &hdr, sizeof (hdr)) != sizeof (hdr))
790 { 669 {
791 PERROR (new_name); 670 PERROR (new_name);
792 } 671 }
883 762
884 #else /* COFF, but not USG_SHARED_LIBRARIES */ 763 #else /* COFF, but not USG_SHARED_LIBRARIES */
885 764
886 lseek (new_, (long) text_scnptr, 0); 765 lseek (new_, (long) text_scnptr, 0);
887 ptr = (char *) f_ohdr.text_start; 766 ptr = (char *) f_ohdr.text_start;
888 #ifdef HEADER_INCL_IN_TEXT
889 /* For Gould UTX/32, text starts after headers */
890 ptr = (char *) (ptr + text_scnptr);
891 #endif /* HEADER_INCL_IN_TEXT */
892 end = ptr + f_ohdr.tsize; 767 end = ptr + f_ohdr.tsize;
893 write_segment (new_, ptr, end); 768 write_segment (new_, ptr, end);
894 769
895 lseek (new_, (long) data_scnptr, 0); 770 lseek (new_, (long) data_scnptr, 0);
896 ptr = (char *) f_ohdr.data_start; 771 ptr = (char *) f_ohdr.data_start;
913 lseek (new_, (long) A_TEXT_SEEK (hdr), 0); 788 lseek (new_, (long) A_TEXT_SEEK (hdr), 0);
914 #else 789 #else
915 lseek (new_, (long) N_TXTOFF (hdr), 0); 790 lseek (new_, (long) N_TXTOFF (hdr), 0);
916 #endif /* no A_TEXT_SEEK */ 791 #endif /* no A_TEXT_SEEK */
917 792
918 #ifdef RISCiX
919
920 /* Acorn's RISC-iX has a wacky way of initializing the position of the heap.
921 * There is a little table in crt0.o that is filled at link time with
922 * the min and current brk positions, among other things. When start
923 * runs, it copies the table to where these parameters live during
924 * execution. This data is in text space, so it cannot be modified here
925 * before saving the executable, so the data is written manually. In
926 * addition, the table does not have a label, and the nearest accessible
927 * label (mcount) is not prefixed with a '_', thus making it inaccessible
928 * from within C programs. To overcome this, emacs's executable is passed
929 * through the command 'nm %s | fgrep mcount' into a pipe, and the
930 * resultant output is then used to find the address of 'mcount'. As far as
931 * is possible to determine, in RISC-iX releases prior to 1.2, the negative
932 * offset of the table from mcount is 0x2c, whereas from 1.2 onwards it is
933 * 0x30. bss_end has been rounded up to page boundary. This solution is
934 * based on suggestions made by Kevin Welton and Steve Hunt of Acorn, and
935 * avoids the need for a custom version of crt0.o for emacs which has its
936 * table in data space.
937 */
938
939 {
940 char command[1024];
941 char errbuf[1024];
942 char address_text[32];
943 int proforma[4];
944 FILE *pfile;
945 char *temp_ptr;
946 char c;
947 int mcount_address, mcount_offset, count;
948 extern char *_execname;
949
950
951 /* The use of _execname is incompatible with RISCiX 1.1 */
952 sprintf (command, "nm %s | fgrep mcount", _execname);
953
954 if ( (pfile = popen(command, "r")) == NULL)
955 {
956 sprintf (errbuf, "Could not open pipe");
957 PERROR (errbuf);
958 }
959
960 count=0;
961 while ( ((c=getc(pfile)) != EOF) && (c != ' ') && (count < 31))
962 address_text[count++]=c;
963 address_text[count]=0;
964
965 if ((count == 0) || pclose(pfile) != NULL)
966 {
967 sprintf (errbuf, "Failed to execute the command '%s'\n", command);
968 PERROR (errbuf);
969 }
970
971 sscanf(address_text, "%x", &mcount_address);
972 ptr = (char *) unexec_text_start;
973 mcount_offset = (char *)mcount_address - ptr;
974
975 #ifdef RISCiX_1_1
976 #define EDATA_OFFSET 0x2c
977 #else
978 #define EDATA_OFFSET 0x30
979 #endif
980
981 end = ptr + mcount_offset - EDATA_OFFSET;
982
983 write_segment (new_, ptr, end);
984
985 proforma[0] = bss_end; /* becomes _edata */
986 proforma[1] = bss_end; /* becomes _end */
987 proforma[2] = bss_end; /* becomes _minbrk */
988 proforma[3] = bss_end; /* becomes _curbrk */
989
990 write (new_, proforma, 16);
991
992 temp_ptr = ptr;
993 ptr = end + 16;
994 end = temp_ptr + hdr.a_text;
995
996 write_segment (new_, ptr, end);
997 }
998
999 #else /* !RISCiX */
1000 ptr = (char *) unexec_text_start; 793 ptr = (char *) unexec_text_start;
1001 end = ptr + hdr.a_text; 794 end = ptr + hdr.a_text;
1002 write_segment (new_, ptr, end); 795 write_segment (new_, ptr, end);
1003 #endif /* RISCiX */
1004 796
1005 ptr = (char *) unexec_data_start; 797 ptr = (char *) unexec_data_start;
1006 end = ptr + hdr.a_data; 798 end = ptr + hdr.a_data;
1007 /* This lseek is certainly incorrect when A_TEXT_OFFSET 799 /* This lseek is certainly incorrect when A_TEXT_OFFSET
1008 and I believe it is a no-op otherwise. 800 and I believe it is a no-op otherwise.
1133 if (chmod (name, sbuf.st_mode) == -1) 925 if (chmod (name, sbuf.st_mode) == -1)
1134 PERROR (name); 926 PERROR (name);
1135 } 927 }
1136 928
1137 #ifdef COFF 929 #ifdef COFF
1138 #ifndef COFF_BSD_SYMBOLS
1139
1140 /* 930 /*
1141 * If the COFF file contains a symbol table and a line number section, 931 * If the COFF file contains a symbol table and a line number section,
1142 * then any auxiliary entries that have values for x_lnnoptr must 932 * then any auxiliary entries that have values for x_lnnoptr must
1143 * be adjusted by the amount that the line number section has moved 933 * be adjusted by the amount that the line number section has moved
1144 * in the file (bias computed in make_hdr). The #@$%&* designers of 934 * in the file (bias computed in make_hdr). The #@$%&* designers of
1165 int UNUSED (readdesc); 955 int UNUSED (readdesc);
1166 char *new_name; 956 char *new_name;
1167 { 957 {
1168 int nsyms; 958 int nsyms;
1169 int new_; 959 int new_;
1170 #if defined (amdahl_uts) || defined (pfa) 960 #if defined defined (pfa)
1171 SYMENT symentry; 961 SYMENT symentry;
1172 AUXENT auxentry; 962 AUXENT auxentry;
1173 #else 963 #else
1174 struct syment symentry; 964 struct syment symentry;
1175 union auxent auxentry; 965 union auxent auxentry;
1202 } 992 }
1203 close (new_); 993 close (new_);
1204 return 0; 994 return 0;
1205 } 995 }
1206 996
1207 #endif /* COFF_BSD_SYMBOLS */
1208
1209 #endif /* COFF */ 997 #endif /* COFF */