fnf@well.UUCP (Fred Fish) (09/16/86)
Here are the diffs for building GNU emacs 17.64 on USG (or other systems using COFF), when there is a large hole in the address space between the end of text and the start of data. I have used these to bring GNU up on a 68020 running USG 5.3, where text starts at virtual address 0 and data starts at the next higher 1Mb boundry after the end of text. The result is a 413 (paged) executable with the text segment shared. Note that these diffs are relatively untested. I am still experiencing random 'Fatal error -- core dumped' problems, but these may be due to other problems (I'm a little suspicious of the interaction between malloc, sbrk, and ulimit at the moment). --------------------------------------------------------------------- *** unexec.orig Fri Sep 12 15:11:06 1986 --- unexec.c Fri Sep 12 16:17:24 1986 *************** *** 94,100 long lnnoptr; /* Pointer to line-number info within file */ #define SYMS_START block_copy_start ! static int text_scnptr; #else /* not COFF */ --- 94,101 ----- long lnnoptr; /* Pointer to line-number info within file */ #define SYMS_START block_copy_start ! static long text_scnptr; ! static long data_scnptr; #else /* not COFF */ *************** *** 319,324 f_ohdr.magic = EXEC_MAGIC; #endif f_ohdr.text_start = (long) start_of_text (); f_ohdr.tsize = data_start - f_ohdr.text_start; f_ohdr.data_start = data_start; f_ohdr.dsize = (long) sbrk (0) - f_ohdr.data_start; --- 320,326 ----- f_ohdr.magic = EXEC_MAGIC; #endif f_ohdr.text_start = (long) start_of_text (); + #ifndef NO_REMAP f_ohdr.tsize = data_start - f_ohdr.text_start; #endif f_ohdr.data_start = data_start; *************** *** 320,325 #endif f_ohdr.text_start = (long) start_of_text (); f_ohdr.tsize = data_start - f_ohdr.text_start; f_ohdr.data_start = data_start; f_ohdr.dsize = (long) sbrk (0) - f_ohdr.data_start; f_ohdr.bsize = 0; --- 322,328 ----- f_ohdr.text_start = (long) start_of_text (); #ifndef NO_REMAP f_ohdr.tsize = data_start - f_ohdr.text_start; + #endif f_ohdr.data_start = data_start; f_ohdr.dsize = (long) sbrk (0) - f_ohdr.data_start; f_ohdr.bsize = 0; *************** *** 337,342 f_dhdr.s_vaddr = f_ohdr.data_start; f_dhdr.s_size = f_ohdr.dsize; f_dhdr.s_scnptr = f_thdr.s_scnptr + f_thdr.s_size; #ifdef UMAX f_dhdr.s_scnptr &= ~pagemask; /* round down to page boundary */ #endif /* UMAX */ --- 340,346 ----- f_dhdr.s_vaddr = f_ohdr.data_start; f_dhdr.s_size = f_ohdr.dsize; f_dhdr.s_scnptr = f_thdr.s_scnptr + f_thdr.s_size; + data_scnptr = f_dhdr.s_scnptr; #ifdef UMAX f_dhdr.s_scnptr &= ~pagemask; /* round down to page boundary */ #endif /* UMAX */ *************** *** 516,521 extern int errno; #ifdef COFF lseek (new, (long) text_scnptr, 0); ptr = (char *) f_ohdr.text_start; end = ptr + f_ohdr.tsize + f_ohdr.dsize; --- 520,533 ----- extern int errno; #ifdef COFF + /* + * Write out the text and data segment separately to avoid problems + * on systems where there may be a large hole between text and data + * (I.E. NO_REMAP is defined). This should also work ok in the + * degenerate case where text and data is contiguous, so avoids + * having two pieces of code ifdef'd by NO_REMAP. + */ + lseek (new, (long) text_scnptr, 0); ptr = (char *) f_ohdr.text_start; end = ptr + f_ohdr.tsize; *************** *** 518,524 #ifdef COFF lseek (new, (long) text_scnptr, 0); ptr = (char *) f_ohdr.text_start; ! end = ptr + f_ohdr.tsize + f_ohdr.dsize; while (ptr < end) { nwrite = 128; --- 530,536 ----- lseek (new, (long) text_scnptr, 0); ptr = (char *) f_ohdr.text_start; ! end = ptr + f_ohdr.tsize; while (ptr < end) { nwrite = 128; *************** *** 527,533 if (nwrite != ret) { sprintf (buf, ! "unexec write failure: addr 0x%x, fileno %d, size 0x%x, wrote 0x%x, errno %d", ptr, new, nwrite, ret, errno); PERROR (buf); } --- 539,565 ----- if (nwrite != ret) { sprintf (buf, ! "unexec text section write failure: addr 0x%x, fileno %d, size 0x%x, wrote 0x%x, errno %d", ! ptr, new, nwrite, ret, errno); ! PERROR (buf); ! } ! ptr += nwrite; ! } ! ! /* Now write out the data segment */ ! ! lseek (new, (long) data_scnptr, 0); ! ptr = (char *) f_ohdr.data_start; ! end = ptr + f_ohdr.dsize; ! while (ptr < end) ! { ! nwrite = 128; ! if (nwrite > end - ptr) nwrite = end - ptr; ! ret = write (new, ptr, nwrite); ! if (nwrite != ret) ! { ! sprintf (buf, ! "unexec data section write failure: addr 0x%x, fileno %d, size 0x%x, wrote 0x%x, errno %d", ptr, new, nwrite, ret, errno); PERROR (buf); } -- =============================================================================== Fred Fish (602) 438-5976 well!fnf ===============================================================================