mac@gold.kpc.com (Mike McNamara) (05/18/91)
This diff adds support to gnu emacs-18.57 for the Stardent Titan machines. In the past, I have posted a similar diff to this newsgroup (or predecesor newsgroups) for gnu emacs versions 18.53, 18.54, and 18.55. I had hoped that the Free Software Foundation would add this machine to those listed in /etc/MACHINES, with all that implies. This has not yet happened. Please tell me what I need to do to get the FSF to support the Stardent machines in future releases of gnu-emacs. In the meantime, I will continue to send new patches as new versions of gnu-emacs become available. diff -cbr dist-18.57/etc/MACHINES emacs-18.57/etc/MACHINES *** dist-18.57/etc/MACHINES Tue Jan 15 20:08:29 1991 --- emacs-18.57/etc/MACHINES Mon Mar 4 09:54:51 1991 *************** *** 584,589 **** --- 584,594 ---- Works, as of 18.56. Note that this is a MIPS architecture machine. + Stardent (m-titan.h, s-usg5-3.h) + + 18.55, 6 & 7 work on the Stardent 1500 & 3000 (aka Titan P2 + and Titan P3). + Stride (m-stride.h; s-usg5-2.h) Works (most recent news for 18.30) on their release 2.0. diff -cbr dist-18.57/src/dispnew.c emacs-18.57/src/dispnew.c *** dist-18.57/src/dispnew.c Tue Jan 8 09:25:14 1991 --- emacs-18.57/src/dispnew.c Mon Mar 4 09:54:52 1991 *************** *** 1413,1421 **** --- 1413,1425 ---- if (XINT (n) > 0) { #ifdef subprocesses + /* We are unable to use interrupts if FIONREAD is not available, + so don't call gobble_input (or home?) without it */ + #ifdef FIONREAD #ifdef SIGIO gobble_input (); #endif /* SIGIO */ + #endif /* FIONREAD */ wait_reading_process_input (XINT (n), 1, 1); #else /* no subprocesses */ immediate_quit = 1; diff -cbr dist-18.57/src/process.c emacs-18.57/src/process.c *** dist-18.57/src/process.c Tue Jan 15 17:28:34 1991 --- emacs-18.57/src/process.c Mon May 13 16:55:47 1991 *************** *** 90,95 **** --- 90,99 ---- #ifdef SYSV_PTYS #include <sys/tty.h> + #ifdef titan + #include <sys/ttyhw.h> + #include <sys/stream.h> + #endif /* titan's pty needs ttyhw & stream */ #include <sys/pty.h> #endif *************** *** 1461,1466 **** --- 1465,1473 ---- #endif /* not HAVE_TIMEVAL */ SELECT_TYPE Atemp; int wait_channel = 0; + #ifdef titan + volatile + #endif struct Lisp_Process *wait_proc = 0; extern kbd_count; diff -cbr dist-18.57/src/sysdep.c emacs-18.57/src/sysdep.c *** dist-18.57/src/sysdep.c Tue Jan 15 18:43:45 1991 --- emacs-18.57/src/sysdep.c Mon May 13 16:46:10 1991 *************** *** 220,225 **** --- 220,229 ---- #endif /* AIX */ #ifdef SYSV_PTYS + #ifdef titan + #include <sys/ttyhw.h> + #include <sys/stream.h> + #endif /* titan's pty needs ttyhw & stream */ #include <sys/tty.h> #include <sys/pty.h> #endif *************** *** 1529,1534 **** --- 1533,1539 ---- end_of_text () { #ifdef TEXT_END + extern TEXT_END; return ((char *) TEXT_END); #else extern int etext; *************** *** 1545,1550 **** --- 1550,1556 ---- end_of_data () { #ifdef DATA_END + extern int DATA_END; return ((char *) DATA_END); #else extern int edata; diff -cbr dist-18.57/src/x11term.c emacs-18.57/src/x11term.c *** dist-18.57/src/x11term.c Thu Jan 24 09:36:39 1991 --- emacs-18.57/src/x11term.c Tue May 14 11:05:01 1991 *************** *** 81,87 **** #include <sys/sysmacros.h> /* for "minor" */ #include <sys/time.h> #else ! #ifdef UNIPLUS #include <sys/time.h> #else /* not IRIS, not UNIPLUS */ --- 81,87 ---- #include <sys/sysmacros.h> /* for "minor" */ #include <sys/time.h> #else ! #if defined (UNIPLUS) || defined(USG_SYS_TIME) #include <sys/time.h> #else /* not IRIS, not UNIPLUS */ diff -cbr dist-18.57/src/x11term.h emacs-18.57/src/x11term.h *** dist-18.57/src/x11term.h Wed Nov 28 15:07:33 1990 --- emacs-18.57/src/x11term.h Mon May 13 17:00:28 1991 *************** *** 12,18 **** #endif #define BLOCK_INPUT_DECLARE() int BLOCK_INPUT_mask ! #ifdef SIGIO #define BLOCK_INPUT() BLOCK_INPUT_mask = sigblock (sigmask (SIGIO)) #define UNBLOCK_INPUT() sigsetmask (BLOCK_INPUT_mask) #else /* not SIGIO */ --- 12,18 ---- #endif #define BLOCK_INPUT_DECLARE() int BLOCK_INPUT_mask ! #if defined(SIGIO) && defined(FINOREAD) #define BLOCK_INPUT() BLOCK_INPUT_mask = sigblock (sigmask (SIGIO)) #define UNBLOCK_INPUT() sigsetmask (BLOCK_INPUT_mask) #else /* not SIGIO */ *** /dev/null Tue May 14 14:07:37 1991 --- emacs-18.57/src/m-titan.h Tue May 14 10:29:50 1991 *************** *** 0 **** --- 1,224 ---- + /* m- file for Stardent 1500 & Stardent 3000s. + Copyright (C) 1987 Free Software Foundation, Inc. + + This file is part of GNU Emacs. + + GNU Emacs is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY. No author or distributor + accepts responsibility to anyone for the consequences of using it + or for whether it serves any particular purpose or works at all, + unless he says so in writing. Refer to the GNU Emacs General Public + License for full details. + + Everyone is granted permission to copy, modify and redistribute + GNU Emacs, but only under the conditions described in the + GNU Emacs General Public License. A copy of this license is + supposed to have been given to you along with GNU Emacs so you + can know your rights and responsibilities. It should be in a + file named COPYING. Among other things, the copyright notice + and this notice must be preserved on all copies. */ + + #ifndef __P3__ + #ifndef __P2__ + #define __P2__ + #endif + #endif + + + /* The following three symbols give information on + the size of various data types. */ + + #define SHORTBITS 16 /* Number of bits in a short */ + + #define INTBITS 32 /* Number of bits in an int */ + + #define LONGBITS 32 /* Number of bits in a long */ + + /* Define BIG_ENDIAN iff lowest-numbered byte in a word + is the most significant byte. */ + + #define BIG_ENDIAN + + /* Define NO_ARG_ARRAY if you cannot take the address of the first of a + * group of arguments and treat it as an array of the arguments. */ + + #define NO_ARG_ARRAY + + /* Define WORD_MACHINE if addresses and such have + * to be corrected before they can be used as byte counts. */ + + #undef WORD_MACHINE + + /* Define how to take a char and sign-extend into an int. + On machines where char is signed, this is a no-op. */ + + #define SIGN_EXTEND_CHAR(c) (c) + + /* Now define a symbol for the cpu type, if your compiler + does not define it automatically: + Ones defined so far include vax, m68000, ns16000, pyramid, + orion, tahoe, APOLLO and many others */ + + #ifndef titan /* C compiler defines this */ + # define titan + #endif + + /* Use type int rather than a union, to represent Lisp_Object */ + /* This is desirable for most machines. */ + + #define NO_UNION_TYPE + + /* Define EXPLICIT_SIGN_EXTEND if XINT must explicitly sign-extend + the 24-bit bit field into an int. In other words, if bit fields + are always unsigned. + + If you use NO_UNION_TYPE, this flag does not matter. */ + + #define EXPLICIT_SIGN_EXTEND + + /* Data type of load average, as read out of kmem. */ + + #define LOAD_AVE_TYPE long + + /* Convert that into an integer that is 100 for a load average of 1.0 */ + + #define LOAD_AVE_CVT(x) (int) (((double) (x)) * 100. / 65536.) + + /* Define CANNOT_DUMP on machines where unexec does not work. + Then the function dump-emacs will not be defined + and temacs will do (load "loadup") automatically unless told otherwise. */ + + /* #define CANNOT_DUMP */ + + /* Define VIRT_ADDR_VARIES if the virtual addresses of + pure and impure space as loaded can vary, and even their + relative order cannot be relied on. + + Otherwise Emacs assumes that text space precedes data space, + numerically. */ + + /* #define VIRT_ADDR_VARIES */ + + /* Define C_ALLOCA if this machine does not support a true alloca + and the one written in C should be used instead. + Define HAVE_ALLOCA to say that the system provides a properly + working alloca function and it should be used. + Define neither one if an assembler-language alloca + in the file alloca.s should be used. */ + + #define C_ALLOCA + /* #define HAVE_ALLOCA */ + + /* Define NO_REMAP if memory segmentation makes it not work well + to change the boundary between the text section and data section + when Emacs is dumped. If you define this, the preloaded Lisp + code will not be sharable; but that's better than failing completely. */ + + #define NO_REMAP + + /* Allow emacs to grow up to 64 Mbytes */ + #define VALBITS 26 + #define GCTYPEBITS 5 + /* + * Define HAVE_TERMIO if the system provides sysV-style ioctls + * for terminal control. + */ + + /* Ardent supports both termcap and terminfo; hence either define HAVE_TERMIO, + (gets you terminfo) or undefine it, (gets you termcap) as you wish. Note: + Ardent also supplies captoinfo, which translates from termcap to terminfo, + which lets you be even more terminal library independant. */ + + #define HAVE_TERMIO /* */ + + /* Give alloca some direction */ + #define STACK_DIRECTION -1 + + /* undo various usg5-3 defines */ + + /* Unlike most SYSV's, Stardent supports ^Z */ + #ifdef NOMULTIPLEJOBS + #undef NOMULTIPLEJOBS + #endif /* */ + + /* Stardent does not adequately support interrupt I/O */ + #ifdef INTERRUPT_INPUT + #undef INTERRUPT_INPUT + #endif /* */ + #undef SIGIO + /* Stardent supports timeval; x11term.c seems to need timeval, hence + I suggest you use it. */ + #ifndef HAVE_TIMEVAL + #define HAVE_TIMEVAL + #define USG_SYS_TIME + #endif /* */ + + /* Stardent supports ptys */ + #ifndef HAVE_PTYS + #define HAVE_PTYS + #define SYSV_PTYS + #endif /* */ + + /* Stardent does NOT put networking library in libnsl_s.a; it's in libc */ + #ifdef LIBX10_SYSTEM + #undef LIBX10_SYSTEM + #endif /* */ + #ifdef LIBX11_SYSTEM + #undef LIBX11_SYSTEM + #endif /* */ + + #define HAVE_X_WINDOWS + #define X11 + /* ardent specific defines */ + + #define START_FILES /lib/crt0.o + #define C_OPTIMIZE_SWITCH -O1 + #define C_SWITCH_MACHINE -I/usr/X11/include + #define LD_SWITCH_MACHINE + + /* ardent supplies a working select even in sysv mode */ + #define HAVE_SELECT + + /* The Stardent only defines utimes in the BSD environment */ + #define MISSING_UTIMES + + /* setenv is a useful thing to have */ + #define MAINTAIN_ENVIRONMENT + + /* (loadst.c) Stardent does not have this */ + #undef DKSTAT_HEADER_FILE + + /* RMS asked that I create an unextitan, as unexec.c has too many ifdefs already */ + #define UNEXEC unextitan.o + #define TEXT_END _etext + #define DATA_END _edata + #define DATA_SECTION_ALIGNMENT pagemask + #define TEXT_START 0x400000 + #ifdef __P3__ /* The Titan P3 (aka Stardent 3000) data section starts here */ + #define DATA_START 0x10000000 + #else /* The Titan P2 (aka Stardent 1500) data section starts here */ + #define DATA_START 0x10003000 + #endif + #define DATA_SEG_BITS 0x10000000 + + /* -NW: Stardent cc performs lint; emacs is not lint free; -NW kills warnings */ + #define C_DEBUG_SWITCH -g + + + /* The standard definitions of these macros would work ok, + but these are faster because the constants are short. */ + + #define XUINT(a) (((unsigned)(a) << INTBITS-VALBITS) >> INTBITS-VALBITS) + + #define XSET(var, type, ptr) \ + ((var) = ((int)(type) << VALBITS) + (((unsigned) (ptr) << INTBITS-VALBITS) >> INTBITS-VALBITS)) + + #define XSETINT(a, b) XSET(a, XTYPE(a), b) + #define XSETUINT(a, b) XSET(a, XTYPE(a), b) + #define XSETPNTR(a, b) XSET(a, XTYPE(a), b) + + #define XMARKBIT(a) ((a) < 0) + /*(a < 0) returns 1, not MARKBIT, so XSETMARKBIT has to be redefined.*/ + #define XSETMARKBIT(a,b) ((a) = ((b) ? (a)|MARKBIT : (a) & ~MARKBIT)) + #define XUNMARK(a) ((a) = (((a) << INTBITS-GCTYPEBITS-VALBITS) >> INTBITS-GCTYPEBITS-VALBITS)) + #define PURESIZE 200000 *** /dev/null Tue May 14 14:10:50 1991 --- emacs-18.57/src/unextitan.c Mon Mar 4 10:07:38 1991 *************** *** 0 **** --- 1,777 ---- + /* Copyright (C) 1985, 1986, 1987, 1988 Free Software Foundation, Inc. + + NO WARRANTY + + BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY + NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT + WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, + RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS" + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY + AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE + DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR + CORRECTION. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M. + STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY + WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE + LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR + OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE + USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR + DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR + A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS + PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH + DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. + + GENERAL PUBLIC LICENSE TO COPY + + 1. You may copy and distribute verbatim copies of this source file + as you receive it, in any medium, provided that you conspicuously and + appropriately publish on each copy a valid copyright notice "Copyright + (C) 1987 Free Software Foundation, Inc."; and include following the + copyright notice a verbatim copy of the above disclaimer of warranty + and of this License. You may charge a distribution fee for the + physical act of transferring a copy. + + 2. You may modify your copy or copies of this source file or + any portion of it, and copy and distribute such modifications under + the terms of Paragraph 1 above, provided that you also do the following: + + a) cause the modified files to carry prominent notices stating + that you changed the files and the date of any change; and + + b) cause the whole of any work that you distribute or publish, + that in whole or in part contains or is a derivative of this + program or any part thereof, to be licensed at no charge to all + third parties on terms identical to those contained in this + License Agreement (except that you may choose to grant more extensive + warranty protection to some or all third parties, at your option). + + c) You may charge a distribution fee for the physical act of + transferring a copy, and you may at your option offer warranty + protection in exchange for a fee. + + Mere aggregation of another unrelated program with this program (or its + derivative) on a volume of a storage or distribution medium does not bring + the other program under the scope of these terms. + + 3. You may copy and distribute this program (or a portion or derivative + of it, under Paragraph 2) in object code or executable form under the terms + of Paragraphs 1 and 2 above provided that you also do one of the following: + + a) accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of + Paragraphs 1 and 2 above; or, + + b) accompany it with a written offer, valid for at least three + years, to give any third party free (except for a nominal + shipping charge) a complete machine-readable copy of the + corresponding source code, to be distributed under the terms of + Paragraphs 1 and 2 above; or, + + c) accompany it with the information you received as to where the + corresponding source code may be obtained. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form alone.) + + For an executable file, complete source code means all the source code for + all modules it contains; but, as a special exception, it need not include + source code for modules which are standard libraries that accompany the + operating system on which the executable file runs. + + 4. You may not copy, sublicense, distribute or transfer this program + except as expressly provided under this License Agreement. Any attempt + otherwise to copy, sublicense, distribute or transfer this program is void and + your rights to use the program under this License agreement shall be + automatically terminated. However, parties who have received computer + software programs from you with this License Agreement will not have + their licenses terminated so long as such parties remain in full compliance. + + 5. If you wish to incorporate parts of this program into other free + programs whose distribution conditions are different, write to the Free + Software Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not yet + worked out a simple rule that can be stated here, but we will often permit + this. We will be guided by the two goals of preserving the free status of + all derivatives of our free software and of promoting the sharing and reuse of + software. + + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! */ + + + /* + * unexec.c - Convert a running program into an a.out file. + * + * Author: Spencer W. Thomas + * Computer Science Dept. + * University of Utah + * Date: Tue Mar 2 1982 + * Modified heavily since then. + * + * Synopsis: + * unexec (new_name, a_name, data_start, bss_start, entry_address) + * char *new_name, *a_name; + * unsigned data_start, bss_start, entry_address; + * + * Takes a snapshot of the program and makes an a.out format file in the + * file named by the string argument new_name. + * If a_name is non-NULL, the symbol table will be taken from the given file. + * On some machines, an existing a_name file is required. + * + * The boundaries within the a.out file may be adjusted with the data_start + * and bss_start arguments. Either or both may be given as 0 for defaults. + * + * Data_start gives the boundary between the text segment and the data + * segment of the program. The text segment can contain shared, read-only + * program code and literal data, while the data segment is always unshared + * and unprotected. Data_start gives the lowest unprotected address. + * The value you specify may be rounded down to a suitable boundary + * as required by the machine you are using. + * + * Specifying zero for data_start means the boundary between text and data + * should not be the same as when the program was loaded. + * If NO_REMAP is defined, the argument data_start is ignored and the + * segment boundaries are never changed. + * + * Bss_start indicates how much of the data segment is to be saved in the + * a.out file and restored when the program is executed. It gives the lowest + * unsaved address, and is rounded up to a page boundary. The default when 0 + * is given assumes that the entire data segment is to be stored, including + * the previous data and bss as well as any additional storage allocated with + * break (2). + * + * The new file is set up to start at entry_address. + * + * If you make improvements I'd like to get them too. + * harpo!utah-cs!thomas, thomas@Utah-20 + * + */ + /* March 89 Michael McNamara (mac@ardent): finished Tim Moore's port of unexec + * to the titan. + */ + + /* There are several compilation parameters affecting unexec: + + * COFF + + Define this if your system uses COFF for executables. + Otherwise we assume you use Berkeley format. + + * NO_REMAP + + Define this if you do not want to try to save Emacs's pure data areas + as part of the text segment. + + Saving them as text is good because it allows users to share more. + + However, on machines that locate the text area far from the data area, + the boundary cannot feasibly be moved. Such machines require + NO_REMAP. + + Also, remapping can cause trouble with the built-in startup routine + /lib/crt0.o, which defines `environ' as an initialized variable. + Dumping `environ' as pure does not work! So, to use remapping, + you must write a startup routine for your machine in Emacs's crt0.c. + If NO_REMAP is defined, Emacs uses the system's crt0.o. + + * SECTION_ALIGNMENT + + Some machines that use COFF executables require that each section + start on a certain boundary *in the COFF file*. Such machines should + define SECTION_ALIGNMENT to a mask of the low-order bits that must be + zero on such a boundary. This mask is used to control padding between + segments in the COFF file. + + If SECTION_ALIGNMENT is not defined, the segments are written + consecutively with no attempt at alignment. This is right for + unmodified system V. + + * SEGMENT_MASK + + Some machines require that the beginnings and ends of segments + *in core* be on certain boundaries. For most machines, a page + boundary is sufficient. That is the default. When a larger + boundary is needed, define SEGMENT_MASK to a mask of + the bits that must be zero on such a boundary. + + * A_TEXT_OFFSET(HDR) + + Some machines count the a.out header as part of the size of the text + segment (a_text); they may actually load the header into core as the + first data in the text segment. Some have additional padding between + the header and the real text of the program that is counted in a_text. + + For these machines, define A_TEXT_OFFSET(HDR) to examine the header + structure HDR and return the number of bytes to add to `a_text' + before writing it (above and beyond the number of bytes of actual + program text). HDR's standard fields are already correct, except that + this adjustment to the `a_text' field has not yet been made; + thus, the amount of offset can depend on the data in the file. + + * A_TEXT_SEEK(HDR) + + If defined, this macro specifies the number of bytes to seek into the + a.out file before starting to write the text segment.a + + * EXEC_MAGIC + + For machines using COFF, this macro, if defined, is a value stored + into the magic number field of the output file. + + * ADJUST_EXEC_HEADER + + This macro can be used to generate statements to adjust or + initialize nonstandard fields in the file header + + * ADDR_CORRECT(ADDR) + + Macro to correct an int which is the bit pattern of a pointer to a byte + into an int which is the number of a byte. + + This macro has a default definition which is usually right. + This default definition is a no-op on most machines (where a + pointer looks like an int) but not on all machines. + + */ + + #ifndef emacs + #define PERROR(arg) perror (arg); return -1 + #else + #include "config.h" + #define PERROR(file) report_error (file, new) + #endif + + #ifndef CANNOT_DUMP /* all rest of file! */ + + #ifndef CANNOT_UNEXEC /* most of rest of file */ + + #include <a.out.h> + /* Define getpagesize () if the system does not. + Note that this may depend on symbols defined in a.out.h + */ + #include "getpagesize.h" + + #ifndef makedev /* Try to detect types.h already loaded */ + #include <sys/types.h> + #endif + #include <stdio.h> + #include <sys/stat.h> + #include <errno.h> + + extern char *start_of_text (); /* Start of text */ + extern char *start_of_data (); /* Start of initialized data */ + + static long block_copy_start; /* Old executable start point */ + static struct filehdr f_hdr; /* File header */ + static struct aouthdr f_ohdr; /* Optional file header (a.out) */ + static struct scnhdr f_thdr; /* Text section header */ + static struct scnhdr f_dhdr; /* Data section header */ + static struct scnhdr f_shdr; /* Symtab section header */ + static struct scnhdr f_bhdr; /* Bss section header */ + static struct scnhdr f_ihdr; /* Ident section header */ + static struct scnhdr scntemp; /* Temporary section header */ + static long old_ident_scnptr; + long bias; /* Bias to add for growth */ + long lnnoptr; /* Pointer to line-number info within file */ + #define SYMS_START block_copy_start + + static long text_scnptr; + static long data_scnptr; + static long symtab_scnptr; + static long ident_scnptr; + static long symptr_scnptr; + + static int pagemask; + + /* Correct an int which is the bit pattern of a pointer to a byte + into an int which is the number of a byte. + This is a no-op on ordinary machines, but not on all. */ + + #ifndef ADDR_CORRECT /* Let m-*.h files override this definition */ + #define ADDR_CORRECT(x) ((char *)(x) - (char*)0) + #endif + + #ifdef emacs + + static + report_error (file, fd) + char *file; + int fd; + { + if (fd) + close (fd); + error ("Failure operating on %s", file); + } + #endif /* emacs */ + + #define ERROR0(msg) report_error_1 (new, msg, 0, 0); return -1 + #define ERROR1(msg,x) report_error_1 (new, msg, x, 0); return -1 + #define ERROR2(msg,x,y) report_error_1 (new, msg, x, y); return -1 + + static + report_error_1 (fd, msg, a1, a2) + int fd; + char *msg; + unsigned int a1, a2; + { + close (fd); + #ifdef emacs + error (msg, a1, a2); + #else + fprintf (stderr, msg, a1, a2); + fprintf (stderr, "\n"); + #endif + } + + /* **************************************************************** + * unexec + * + * driving logic. + */ + unexec (new_name, a_name, data_start, bss_start, entry_address) + char *new_name, *a_name; + unsigned data_start, bss_start, entry_address; + { + int new = -1; + int a_out = -1; + + if (a_name && (a_out = open (a_name, 0)) < 0) + { + PERROR (a_name); + } + if ((new = creat (new_name, 0666)) < 0) + { + PERROR (new_name); + } + + if (make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name) < 0 + || copy_text_and_data (new) < 0 + || copy_sym (new, a_out, a_name, new_name) < 0) + { + close (new); + /* unlink (new_name); /* Failed, unlink new a.out */ + return -1; + } + + close (new); + if (a_out >= 0) + close (a_out); + mark_x (new_name); + return 0; + } + + /* **************************************************************** + * make_hdr + * + * Make the header in the new a.out from the header in core. + * Modify the text and data sizes. + */ + static int + make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name) + int new, a_out; + unsigned data_start, bss_start, entry_address; + char *a_name; + char *new_name; + { + register int scns; + unsigned int bss_end; + unsigned int start_next_section; + + pagemask = getpagesize () - 1; + + /* Adjust text/data boundary. */ + #ifdef NO_REMAP + data_start = (int) start_of_data (); + #else /* not NO_REMAP */ + if (!data_start) + data_start = (int) start_of_data (); + #endif /* not NO_REMAP */ + data_start = ADDR_CORRECT (data_start); + + #ifdef SEGMENT_MASK + data_start = data_start & ~SEGMENT_MASK; /* (Down) to segment boundary. */ + #else + data_start = data_start & ~pagemask; /* (Down) to page boundary. */ + #endif + + bss_end = ADDR_CORRECT (sbrk (0)) + pagemask; + bss_end &= ~ pagemask; + + /* Adjust data/bss boundary. */ + if (bss_start != 0) + { + bss_start = (ADDR_CORRECT (bss_start) + pagemask); + /* (Up) to page bdry. */ + bss_start &= ~ pagemask; + if (bss_start > bss_end) + { + ERROR1 ("unexec: Specified bss_start (%u) is past end of program", + bss_start); + } + } + else + bss_start = bss_end; + + if (data_start > bss_start) /* Can't have negative data size. */ + { + ERROR2 ("unexec: data_start (%u) can't be greater than bss_start (%u)", + data_start, bss_start); + } + + /* Salvage as much info from the existing file as possible */ + if (a_out >= 0) + { + if (read (a_out, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr)) + { + PERROR (a_name); + } + block_copy_start += sizeof (f_hdr); + if (f_hdr.f_opthdr > 0) + { + if (read (a_out, &f_ohdr, sizeof (f_ohdr)) != sizeof (f_ohdr)) + { + PERROR (a_name); + } + block_copy_start += sizeof (f_ohdr); + } + /* Loop through section headers, copying them in */ + for (scns = f_hdr.f_nscns; scns > 0; scns--) { + if (read (a_out, &scntemp, sizeof (scntemp)) != sizeof (scntemp)) + { + PERROR (a_name); + } + if (scntemp.s_scnptr > 0L) + { + if (block_copy_start < scntemp.s_scnptr + scntemp.s_size) + block_copy_start = scntemp.s_scnptr + scntemp.s_size; + } + if (strcmp (scntemp.s_name, ".text") == 0) + { + f_thdr = scntemp; + } + else if (strcmp (scntemp.s_name, ".ident") == 0) + { + f_ihdr = scntemp; + } + else if (strcmp (scntemp.s_name, ".data") == 0) + { + f_dhdr = scntemp; + } + else if (strcmp (scntemp.s_name, ".bss") == 0) + { + f_bhdr = scntemp; + } + else if (strcmp (scntemp.s_name, ".symtab") == 0) + { + f_shdr = scntemp; + } + } + } + else + { + ERROR0 ("can't build a COFF file from scratch yet"); + } + + /* Now we alter the contents of all the f_*hdr variables + to correspond to what we want to dump. */ + + f_hdr.f_flags |= ( + #ifndef titan + F_RELFLG | + #endif + F_EXEC); + #ifdef EXEC_MAGIC + f_ohdr.magic = EXEC_MAGIC; + #endif + #ifndef NO_REMAP + f_ohdr.text_start = (long) start_of_text (); + f_ohdr.tsize = data_start - f_ohdr.text_start; + f_ohdr.data_start = data_start; + #endif /* NO_REMAP */ + f_ohdr.dsize = bss_start - f_ohdr.data_start; + f_ohdr.bsize = bss_end - bss_start; + #ifdef SECTION_ALIGNMENT + /* Some systems require special alignment + of the sections in the file itself. */ + f_thdr.s_scnptr + = (f_thdr.s_scnptr + SECTION_ALIGNMENT) & ~SECTION_ALIGNMENT; + #endif /* SECTION_ALIGNMENT */ + text_scnptr = f_thdr.s_scnptr; + f_dhdr.s_paddr = f_ohdr.data_start; + 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 SECTION_ALIGNMENT + /* Some systems require special alignment + of the sections in the file itself. */ + f_dhdr.s_scnptr + = (f_dhdr.s_scnptr + SECTION_ALIGNMENT) & ~SECTION_ALIGNMENT; + #endif /* SECTION_ALIGNMENT */ + #ifdef DATA_SECTION_ALIGNMENT + /* Some systems require special alignment + of the data section only. */ + f_dhdr.s_scnptr + = (f_dhdr.s_scnptr + DATA_SECTION_ALIGNMENT) & ~DATA_SECTION_ALIGNMENT; + #endif /* DATA_SECTION_ALIGNMENT */ + data_scnptr = f_dhdr.s_scnptr; + f_bhdr.s_paddr = f_ohdr.data_start + f_ohdr.dsize; + f_bhdr.s_vaddr = f_ohdr.data_start + f_ohdr.dsize; + f_bhdr.s_size = f_ohdr.bsize; + f_bhdr.s_scnptr = 0L; + ident_scnptr = f_ihdr.s_scnptr; + if (f_ihdr.s_scnptr > 0L) + { + f_ihdr.s_scnptr = f_dhdr.s_scnptr + f_dhdr.s_size; + #ifdef DATA_SECTION_ALIGNMENT + f_ihdr.s_scnptr = (f_ihdr.s_scnptr + DATA_SECTION_ALIGNMENT) + & ~DATA_SECTION_ALIGNMENT; + #endif + start_next_section = f_ihdr.s_scnptr + f_ihdr.s_size; + } + symtab_scnptr = f_shdr.s_scnptr; + if (f_shdr.s_scnptr > 0L) /* symbol section */ + { + f_shdr.s_scnptr = start_next_section; + start_next_section = f_shdr.s_scnptr + f_shdr.s_size; + } + symptr_scnptr = f_hdr.f_symptr; + if (f_hdr.f_symptr > 0L) + { + f_hdr.f_symptr = start_next_section; + } + + #ifdef ADJUST_EXEC_HEADER + ADJUST_EXEC_HEADER + #endif /* ADJUST_EXEC_HEADER */ + + if (write (new, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr)) + { + PERROR (new_name); + } + + if (write (new, &f_ohdr, sizeof (f_ohdr)) != sizeof (f_ohdr)) + { + PERROR (new_name); + } + + if (write (new, &f_thdr, sizeof (f_thdr)) != sizeof (f_thdr)) + { + PERROR (new_name); + } + + if (write (new, &f_dhdr, sizeof (f_dhdr)) != sizeof (f_dhdr)) + { + PERROR (new_name); + } + + if (write (new, &f_ihdr, sizeof (f_ihdr)) != sizeof (f_ihdr)) + { + PERROR (new_name); + } + + if (write (new, &f_shdr, sizeof (f_shdr)) != sizeof (f_shdr)) + { + PERROR (new_name); + } + + return (0); + } + + /* **************************************************************** + * copy_text_and_data + * + * Copy the text and data segments from memory to the new a.out + */ + static int + copy_text_and_data (new) + int new; + { + register char *end; + register char *ptr; + + lseek (new, (long) text_scnptr, 0); + /* The titan stores its headers in the text segment. Also, we have to + avoid reading the floating point stuff, which is located at the + beginning of the data segment. */ + + ptr = (char *) f_thdr.s_vaddr; + end = ptr + f_thdr.s_size; + write_segment (new, ptr, end); + printf("copied text segment from [%x-%x] to xemacs\n", (int)ptr, (int)end); + lseek (new, (long) (data_scnptr + (DATA_START - f_ohdr.data_start)), 0); + printf("seeked to %x\n", (int)(data_scnptr + (DATA_START - + f_ohdr.data_start))); + ptr = (char *)DATA_START; + end = ptr + f_ohdr.dsize; + write_segment (new, ptr, end); + printf("copied data segment from [%x-%x] to xemacs\n", (int)ptr, (int)end); + return 0; + } + + write_segment (new, ptr, end) + int new; + register char *ptr, *end; + { + register int i, nwrite, ret; + char buf[80]; + extern int errno; + char zeros[128]; + + bzero (zeros, sizeof zeros); + + for (i = 0; ptr < end;) + { + /* distance to next multiple of 128. */ + nwrite = (((int) ptr + 128) & -128) - (int) ptr; + /* But not beyond specified end. */ + if (nwrite > end - ptr) nwrite = end - ptr; + ret = write (new, ptr, nwrite); + /* If write gets a page fault, it means we reached + a gap between the old text segment and the old data segment. + This gap has probably been remapped into part of the text segment. + So write zeros for it. */ + if (ret == -1 && errno == EFAULT) + write (new, zeros, nwrite); + else 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); + } + i += nwrite; + ptr += nwrite; + } + } + + /* **************************************************************** + * copy_sym + * + * Copy the relocation information and symbol table from the a.out to the new + */ + static int + copy_sym (new, a_out, a_name, new_name) + int new, a_out; + char *a_name, *new_name; + { + #define SIZE 8192 + char page[SIZE]; + int n,newsyms,symrel; + char * ptr; + char * end; + + if (a_out < 0) + return 0; + + if (SYMS_START == 0L) + return 0; + + + /* Copy .ident section */ + if(ident_scnptr > 0) + { + lseek(a_out, ident_scnptr, 0); + printf( "seeking to 0x%x (start of .ident) in %s\n", + ident_scnptr,a_name); + lseek (new, (long) f_ihdr.s_scnptr, 0); + printf( "seeking to 0x%x (start of .ident) in %s\n", + f_ihdr.s_scnptr,new_name); + if ( (n = read(a_out, page, SIZE)) < 0) + PERROR("reading .ident section"); + do + { + ptr = (char *) page; + end = ptr + n; + write_segment (new, ptr, end); + if( (n = read(a_out, page, SIZE)) < 0) + PERROR("reading .ident section"); + } while (n != 0); + } + + /* Copy symtab section */ + if(symtab_scnptr > 0) + { + lseek(a_out, symtab_scnptr, 0); + printf( "seeking to 0x%x (start of .symtab) in %s\n", + symtab_scnptr,a_name); + lseek (new, (long) f_shdr.s_scnptr, 0); + printf( "seeking to 0x%x (start of .symtab) in %s\n", + f_shdr.s_scnptr,new_name); + if ( (n = read(a_out, page, SIZE)) < 0) + PERROR("reading .symtab section"); + do + { + ptr = (char *) page; + end = ptr + n; + write_segment (new, ptr, end); + if( (n = read(a_out, page, SIZE)) < 0) + PERROR("reading .ident section"); + } while (n != 0); + } + + /* Copy & adjust symptr section */ + if(symptr_scnptr>0) + { + lseek(a_out, symptr_scnptr, 0); + printf( "seeking to 0x%x (start of .symptr) in %s\n", + symptr_scnptr,a_name); + lseek (new, (long) f_hdr.f_symptr, 0); + printf( "seeking to 0x%x (start of .symptr) in %s\n", + f_hdr.f_symptr,new_name); + n = read(a_out, page, SIZE); + if (n < sizeof(SYMBOLS)) { + PERROR("reading symbols from temacs"); + } + #define symhdr ((SYMBOLS *)page) + symrel = f_hdr.f_symptr - symptr_scnptr; + symhdr->strings_off += symrel; + if(symhdr->comini_off) /* If there is common initialized data...*/ + symhdr->comini_off += symrel; + symhdr->address_off += symrel; + symhdr->symbols_off += symrel; + #undef symhdr + do + { + ptr = (char *) page; + end = ptr + n; + write_segment (new, ptr, end); + n = read(a_out, page, SIZE); + if (n < 0) { + PERROR("reading more symbols from temacs"); + } + #undef SIZE + } while (n != 0); + } + + return 0; + } + + /* **************************************************************** + * mark_x + * + * After succesfully building the new a.out, mark it executable + */ + static + mark_x (name) + char *name; + { + struct stat sbuf; + int um; + int new = 0; /* for PERROR */ + + um = umask (777); + umask (um); + if (stat (name, &sbuf) == -1) + { + PERROR (name); + } + sbuf.st_mode |= 0111 & ~um; + if (chmod (name, sbuf.st_mode) == -1) + PERROR (name); + } + #endif /* not CANNOT_UNEXEC */ + + #endif /* not CANNOT_DUMP */ *** /dev/null Tue May 14 14:10:50 1991 --- emacs-18.57/src/config.h Tue May 14 14:37:01 1991 *************** *** 0 **** --- 1,108 ---- + /* GNU Emacs site configuration template file. + Copyright (C) 1988 Free Software Foundation, Inc. + + This file is part of GNU Emacs. + + GNU Emacs is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + GNU Emacs is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Emacs; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + + + /* Include here a s- file that describes the system type you are using. + See the file ../etc/MACHINES for a list of systems and + the names of the s- files to use for them. + See s-template.h for documentation on writing s- files. */ + #include "s-usg5-3.h" + + /* Include here a m- file that describes the machine and system you use. + See the file ../etc/MACHINES for a list of machines and + the names of the m- files to use for them. + See m-template.h for info on what m- files should define. + */ + #include "m-titan.h" + + /* Load in the conversion definitions if this system + needs them and the source file being compiled has not + said to inhibit this. There should be no need for you + to alter these lines. */ + + #ifdef SHORTNAMES + #ifndef NO_SHORTNAMES + #include "../shortnames/remap.h" + #endif /* not NO_SHORTNAMES */ + #endif /* SHORTNAMES */ + + /* Define HAVE_X_WINDOWS if you want to use the X window system. */ + + #define HAVE_X_WINDOWS + + /* Define X11 if you want to use version 11 of X windows. + Otherwise, Emacs expects to use version 10. */ + + #define X11 + + /* Define HAVE_X_MENU if you want to use the X window menu system. + This appears to work on some machines that support X + and not on others. */ + + /* #define HAVE_X_MENU */ + + /* Define `subprocesses' should be defined if you want to + have code for asynchronous subprocesses + (as used in M-x compile and M-x shell). + These do not work for some USG systems yet; + for the ones where they work, the s-*.h file defines this flag. */ + + #ifndef VMS + #ifndef USG + #define subprocesses + #endif + #endif + + /* Define USER_FULL_NAME to return a string + that is the user's full name. + It can assume that the variable `pw' + points to the password file entry for this user. + + At some sites, the pw_gecos field contains + the user's full name. If neither this nor any other + field contains the right thing, use pw_name, + giving the user's login name, since that is better than nothing. */ + + #define USER_FULL_NAME pw->pw_gecos + + /* Define AMPERSAND_FULL_NAME if you use the convention + that & in the full name stands for the login id. */ + + /* #define AMPERSAND_FULL_NAME */ + + /* # bytes of pure Lisp code to leave space for. + Note that s-vms.h and m-sun2.h may override this default. */ + + #ifndef PURESIZE + #ifdef HAVE_X_WINDOWS + #define PURESIZE 122000 + #else + #define PURESIZE 119000 + #endif + #endif + + /* Define HIGHPRI as a negative number + if you want Emacs to run at a higher than normal priority. + For this to take effect, you must install Emacs with setuid root. + Emacs will change back to the users's own uid after setting + its priority. */ + + /* #define HIGHPRI */ + -- +-----------+-----------------------------------------------------------------+ |mac@kpc.com| Increasing Software complexity lets us sell Mainframes as | | | personal computers. Carry on, X windows/Postscript/emacs/CASE!! | +-----------+-----------------------------------------------------------------+