Article View: gnu.epoch.misc
Article #1890Patch to support epoch on the (st)ardent titan
From: Mike McNamara
Date: Fri, 21 Jun 1991 21:22
Date: Fri, 21 Jun 1991 21:22
1460 lines
49463 bytes
49463 bytes
The following patch adds support to epoch for the ardent
titan.
I have been using epoch on my titans since epoch first came
out; however, I've heavily hacked to code as people have made
suggestions and posted fixes and enhancements.
This patch should be applied to (epoch with patches 1 and 2
applied).
It is possible that I have forgotten something in sorting out
/this was a changed I needed to support the titan/ this was a neet
hack from Mike Newton/ so, if you run into some trouble, drop me a
line, I've probably already fixed it.
Enjoy.
diff -cbr epoch-3.2/etc/MACHINES titan-3.2/etc/MACHINES
*** epoch-3.2/etc/MACHINES Tue Oct 16 11:39:54 1990
--- titan-3.2/etc/MACHINES Wed Nov 28 08:43:31 1990
***************
*** 470,475 ****
--- 470,480 ----
18.52 should work.
+ Stardent (m-titan.h, s-usg5-3.h)
+
+ 18.55 works on the Stardent 500, 1500 & 3000 (aka Stiletto, 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 epoch-3.2/lisp/man.el titan-3.2/lisp/man.el
*** epoch-3.2/lisp/man.el Tue Oct 16 11:39:54 1990
--- titan-3.2/lisp/man.el Wed Nov 28 08:43:31 1990
***************
*** 145,153 ****
(defun insert-man-file (name)
;; Insert manual file (unpacked as necessary) into buffer
! (if (or (equal (substring name -2) ".Z")
(string-match "/cat[0-9][a-z]?\\.Z/" name))
! (call-process "zcat" name t nil)
! (if (equal (substring name -2) ".z")
! (call-process "pcat" nil t nil name)
! (insert-file-contents name))))
--- 192,206 ----
(defun insert-man-file (name)
;; Insert manual file (unpacked as necessary) into buffer
! (let (end)
! (cond ((or (equal (substring name -2) ".Z")
(string-match "/cat[0-9][a-z]?\\.Z/" name))
! (call-process "zcat" name t nil))
! ((equal (substring name -2) ".z")
! (call-process "pcat" nil t nil name))
! ((progn
! (setq end (+ (nth 1 (insert-file-contents name)) (point)))
! ;; Check magic number of file
! (looking-at "\037\235"))
! (delete-region (point) end)
! (call-process "zcat" name t nil)))))
diff -cbr epoch-3.2/src/buffer.c titan-3.2/src/buffer.c
*** epoch-3.2/src/buffer.c Thu Oct 18 17:21:22 1990
--- titan-3.2/src/buffer.c Tue Feb 19 10:24:56 1991
***************
*** 851,857 ****
if (c == p)
return;
! if (w)
swb = NULL (selected_window) ? 0 : XBUFFER (w->buffer);
if (p && NULL (p->name))
--- 851,857 ----
if (c == p)
return;
! if (selected_window)
swb = NULL (selected_window) ? 0 : XBUFFER (w->buffer);
if (p && NULL (p->name))
diff -cbr epoch-3.2/src/config.h titan-3.2/src/config.h
*** epoch-3.2/src/config.h Tue Oct 16 11:56:47 1990
--- titan-3.2/src/config.h Wed Jan 16 09:39:28 1991
***************
*** 19,29 ****
and this notice must be preserved on all copies. */
/* 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-sunos4.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
--- 19,30 ----
and this notice must be preserved on all copies. */
+
/* 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
***************
*** 30,36 ****
the names of the m- files to use for them.
See m-template.h for info on what m- files should define.
*/
! #include "m-sparc.h"
/* Load in the conversion definitions if this system
needs them and the source file being compiled has not
--- 31,37 ----
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
***************
*** 102,108 ****
#ifdef HAVE_X_WINDOWS
#define PURESIZE 200000
#else
! #define PURESIZE 118000
#endif
#endif
--- 103,109 ----
#ifdef HAVE_X_WINDOWS
#define PURESIZE 200000
#else
! #define PURESIZE 200000
#endif
#endif
diff -cbr epoch-3.2/src/dispepoch.c titan-3.2/src/dispepoch.c
*** epoch-3.2/src/dispepoch.c Wed Oct 24 07:33:22 1990
--- titan-3.2/src/dispepoch.c Fri Jan 18 14:38:37 1991
***************
*** 1428,1434 ****
if (XINT (n) > 0)
{
#ifdef subprocesses
! #ifdef SIGIO
gobble_input ();
#endif /* SIGIO */
wait_reading_process_input (XINT (n), 1, 1);
--- 1428,1434 ----
if (XINT (n) > 0)
{
#ifdef subprocesses
! #if defined(SIGIO) && defined (FIONREAD)
gobble_input ();
#endif /* SIGIO */
wait_reading_process_input (XINT (n), 1, 1);
diff -cbr epoch-3.2/src/keyboard.c titan-3.2/src/keyboard.c
*** epoch-3.2/src/keyboard.c Thu Oct 18 17:20:27 1990
--- titan-3.2/src/keyboard.c Wed May 22 11:02:16 1991
***************
*** 792,798 ****
get_char (commandflag)
int commandflag;
{
! #ifdef __STDC__
#define VOLATILE volatile
#else
#define VOLATILE
--- 792,798 ----
get_char (commandflag)
int commandflag;
{
! #if defined(__STDC__) || defined(titan)
#define VOLATILE volatile
#else
#define VOLATILE
diff -cbr epoch-3.2/src/process.c titan-3.2/src/process.c
*** epoch-3.2/src/process.c Tue May 28 16:32:15 1991
--- titan-3.2/src/process.c Thu May 30 18:12:08 1991
***************
*** 63,69 ****
#else /* not IRIS, not UNIPLUS */
#ifdef HAVE_TIMEVAL
! #if defined(USG) && !defined(IBMRTAIX) && !defined(OS_386ix)
#include <time.h>
#else /* IBMRTAIX, 386/ix, or not USG */
#include <sys/time.h>
--- 63,69 ----
#else /* not IRIS, not UNIPLUS */
#ifdef HAVE_TIMEVAL
! #if defined(USG) && !defined(IBMRTAIX) && !defined(OS_386ix) && !defined(titan)
#include <time.h>
#else /* IBMRTAIX, 386/ix, or not USG */
#include <sys/time.h>
***************
*** 82,87 ****
--- 82,90 ----
#ifdef SYSV_PTYS
#include <sys/tty.h>
+ #ifdef titan
+ #include <sys/ttyhw.h>
+ #endif /* titan */
#ifdef OS_386ix
#include <sys/ptem.h> /* Necessary for struct winsize */
#endif
***************
*** 1440,1445 ****
--- 1443,1451 ----
#endif /* not HAVE_TIMEVAL */
int Atemp;
int wait_channel = 0;
+ #ifdef titan
+ volatile
+ #endif
struct Lisp_Process *wait_proc = 0;
extern kbd_count;
extern int eqlength; /* length of internal X event Q */
***************
*** 1611,1616 ****
--- 1617,1640 ----
else if (xerrno == EFAULT)
Available = 0;
#endif
+ #ifdef titan
+ /* if we get ENOSTR, then the stream emulation of select
+ is telling us that one of the file descriptors is no
+ longer active. It returns the negative of the file
+ descriptor, plus 1
+ */
+ else if (xerrno == ENOSTR ) {
+ Available = 1<<(-nfds-1);
+ nfds = 1;
+ }
+ /* If other end has died, we get an ENXIO. However, there may
+ still be data to read. Available IS correct in this case,
+ hence we just ignore ENXIO, and proceed. Note that SIGCHLD
+ will come along soon and and clear this file descriptor.
+ */
+ else if (xerrno == ENXIO )
+ ;
+ #endif /* titan */
else if (xerrno == EBADF)
abort ();
else
***************
*** 1649,1657 ****
/* Check for data from a process or a command channel */
! for (channel = 3; Available && channel < MAXDESC; channel++)
{
m = ChannelMask (channel);
if (m & Available)
{
Available &= ~m;
--- 1673,1710 ----
/* Check for data from a process or a command channel */
! for (channel = 3; (Available || Exception) && channel < MAXDESC; channel++)
{
m = ChannelMask (channel);
+ #ifdef titan
+ /* When an exceptional event occurs, (i.e., an out of band
+ message is delivered) discard any data associated with it.
+
+ Without this (ahem, "hack"), every subprocess initiation on the
+ titan was prefixed with a ^P (0x10) which was merely annoying when
+ starting a shell subprocess, but would break server.el:
+ "^PClient 401: /etc/passwd"...
+
+ Question to the gnu-world: what does everyone else do with
+ Exception events? I notice that above in the select call,
+ HP & IBM explicitly do not select for exceptions; others select for
+ them, but pay no attention to the value in &Exception.
+
+ You should note that select'ing for both readable (Available) and
+ exceptions (Exception), but only doing channel reads based on bits
+ set in Available can eat gobs of cpu time if an exception event
+ happens on one of your channels....
+
+ */
+ if ( m & Exception)
+ {
+ int ndiscarded;
+ char chars[512];
+ Exception &= ~m;
+ proc = chan_process[channel];
+ ndiscarded = read (channel, chars, sizeof chars);
+ }
+ #endif /* titan */
if (m & Available)
{
Available &= ~m;
***************
*** 1949,1954 ****
--- 2002,2008 ----
Lisp_Object current_group;
int nomsg;
{
+ extern int errno;
Lisp_Object proc;
register struct Lisp_Process *p = 0;
int gid;
***************
*** 1992,1997 ****
--- 2046,2052 ----
flush_pending_output (XFASTINT (p->infd));
break;
}
+
/* gid may be a pid, or minus a pgrp's number */
#ifdef BSD
/* On bsd, [man says] kill does not accept a negative number to kill a pgrp.
***************
*** 2002,2008 ****
#ifdef HPUX /* previous ioctl failed, gid is not valid */
ioctl( XFASTINT (p->infd), TIOCSIGSEND, signo);
#else
! kill (gid, signo);
#endif /* HPUX */
#endif /* Not BSD. */
--- 2057,2064 ----
#ifdef HPUX /* previous ioctl failed, gid is not valid */
ioctl( XFASTINT (p->infd), TIOCSIGSEND, signo);
#else
! if( kill (gid, signo) != 0)
! error("kill: error %d", errno);
#endif /* HPUX */
#endif /* Not BSD. */
diff -cbr epoch-3.2/src/sysdep.c titan-3.2/src/sysdep.c
*** epoch-3.2/src/sysdep.c Thu Oct 18 17:20:52 1990
--- titan-3.2/src/sysdep.c Wed Jan 16 09:47:51 1991
***************
*** 1498,1503 ****
--- 1498,1504 ----
end_of_text ()
{
#ifdef TEXT_END
+ extern TEXT_END;
return ((char *) TEXT_END);
#else
extern int etext;
***************
*** 1514,1519 ****
--- 1515,1521 ----
end_of_data ()
{
#ifdef DATA_END
+ extern DATA_END;
return ((char *) DATA_END);
#else
extern int edata;
diff -cbr epoch-3.2/src/x11term.c titan-3.2/src/x11term.c
*** epoch-3.2/src/x11term.c Tue Jun 4 09:06:08 1991
--- titan-3.2/src/x11term.c Thu Mar 14 11:13:48 1991
***************
*** 38,44 ****
#include "x11term.h"
! #if defined(USG) && ! defined(IBMRTAIX) && !defined(OS_386ix)
#include <time.h>
#else
#include <sys/time.h>
--- 38,44 ----
#include "x11term.h"
! #if defined(USG) && ! defined(IBMRTAIX) && !defined(OS_386ix) && !defined(titan)
#include <time.h>
#else
#include <sys/time.h>
diff -cbr epoch-3.2/src/x11term.h titan-3.2/src/x11term.h
*** epoch-3.2/src/x11term.h Wed Oct 24 07:47:58 1990
--- titan-3.2/src/x11term.h Wed Jan 16 11:02:05 1991
***************
*** 25,32 ****
--- 25,37 ----
}
#define UNBLOCK_INPUT() sigprocmask (SIG_SETMASK, &BLOCK_INPUT_mask, (sigset_t *)0)
#else /* not POSIX_SIGNAL */
+ #if defined (SIGIO) && defined (FIONREAD) && !defined (BROKEN_FIONREAD)
#define BLOCK_INPUT() BLOCK_INPUT_mask = sigblock (sigmask (SIGIO))
#define UNBLOCK_INPUT() sigsetmask (BLOCK_INPUT_mask)
+ #else /* not SIGIO && FIONREAD */
+ #define BLOCK_INPUT()
+ #define UNBLOCK_INPUT()
+ #endif /* SIGIO && FINOREAD */
#endif /* not POSIX_SIGNAL */
#else /* not SIGIO */
*** epoch-3.2/src/x11fns.c Tue Jun 4 09:06:08 1991
--- titan-3.2/src/x11fns.c Mon Jun 17 11:24:01 1991
***************
*** 33,39 ****
#include "x11term.h"
#include "dispextern.h"
#include "termchar.h"
! #if defined(USG) && ! defined(OS_386ix) && ! defined(IRIS_4D) && ! defined(USGV4) && ! defined(IBMAIX)
#include <time.h>
#else
#include <sys/time.h>
--- 33,39 ----
#include "x11term.h"
#include "dispextern.h"
#include "termchar.h"
! #if defined(USG) && ! defined(OS_386ix) && ! defined(IRIS_4D) && ! defined(USGV4) && ! defined(IBMAIX) && ! defined(titan)
#include <time.h>
#else
#include <sys/time.h>
*** /dev/null Sat Jun 15 22:59:45 1991
--- epoch-3.2/src/m-titan.h Fri May 17 09:42:29 1991
***************
*** 0 ****
--- 1,237 ----
+ /* m- file for Ardent Titans.
+ Copyright (C) 1987 Free Software Foundation, Inc.
+
+ #ifndef __P3__
+ #define __P2__ 1
+ #endif
+
+ 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. */
+
+ /* 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 */
+
+ /* allow emacs as large as 64 megabytes *
+
+ #define VALBITS 26
+ #define GCTYPEBITS 5
+
+ /* 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
+
+ /*
+ * 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, Titan supports ^Z */
+ #ifdef NOMULTIPLEJOBS
+ #undef NOMULTIPLEJOBS
+ #endif /* */
+
+ /* Titan can support interrupt driven i/o; use it if you'd like to. */
+ /*
+ #ifdef INTERRUPT_INPUT
+ #undef INTERRUPT_INPUT
+ #endif /* */
+
+ /* Titan supports timeval; x11term.c seems to need timeval, hence
+ I suggest you use it. */
+ #ifndef HAVE_TIMEVAL
+ #define HAVE_TIMEVAL
+ #endif /* */
+
+ /* Titan supports ptys */
+ #ifndef HAVE_PTYS
+ #define HAVE_PTYS
+ #define SYSV_PTYS
+ #endif /* */
+
+ /* Titan does not support select on pipes, so force socket usage */
+ #ifndef SKTPAIR
+ #define SKTPAIR
+ #endif /* */
+
+ #ifndef HAVE_SOCKETS
+ #define HAVE_SOCKETS
+ #endif /* HAVE_SOCKETS */
+
+ /* Titan 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 /* */
+
+ /* 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
+
+ #define HAVE_SELECT
+
+ /* The titan only defines utimes in the BSD environment */
+ #define MISSING_UTIMES
+
+ /* setenv is a useful thing to have */
+ #define MAINTAIN_ENVIRONMENT
+
+ /* (loadst.c) Titan 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__
+ #define DATA_START 0x10000000
+ #else
+ #define DATA_START 0x10003000
+ #endif
+ #define DATA_SEG_BITS 0x10000000
+
+ /* -NW: titan cc performs lint; emacs is not lint free; -NW kills warnings */
+ #define C_DEBUG_SWITCH -g -NW
+
+ /* 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 XPNTR(a) (XUINT(a) == 0 ? 0 : (XUINT (a) | DATA_SEG_BITS))*/
+
+ #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 400000
+
+ #define DONT_DELETE_MAILFILE
+
+ /*#define BSTRING */
+ #define BROKEN_FIONREAD
+
+ #define USE_STREAMS
+ #define HAVE_UNIX_DOMAIN
*** /dev/null Mon Jun 17 11:34:33 1991
--- epoch-3.2/src/unextitan.c Thu Dec 13 13:28:29 1990
***************
*** 0 ****
--- 1,780 ----
+ /* 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's port of unexec
+ * to the titan.
+ /* Aug 88 Tim Moore, Ardent Computer: Made many changes for the Ardent Titan.
+ * The Titan uses COFF format, but copies section headers into the text
+ * segment; also, some changes are necessary to avoid reading and writing to
+ * the floating point hardware.
+ */
+
+ /* 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 */
--
+-----------+-----------------------------------------------------------------+
|mac@kpc.com| Increasing Software complexity lets us sell Mainframes as |
| | personal computers. Carry on, X windows/Postscript/emacs/CASE!! |
+-----------+-----------------------------------------------------------------+
Technical Details
Message-ID:
<MAC.91Jun21142229@gold.kpc.com>Path:
arc1-ca.pugleaf.net!gmdzi!unido!mcsun!uunet!zaphod.mps.ohio-state.edu!mips!kpc.com!ardent!macShow Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: fc7ee,9ede9f4fba8ce46c,start X-Google-Attributes: gidfc7ee,public X-Google-ArrivalTime: 1991-06-22 06:21:55 PST Path: arc1-ca.pugleaf.net!gmdzi!unido!mcsun!uunet!zaphod.mps.ohio-state.edu!mips!kpc.com!ardent!mac From: mac@gold.kpc.com (Mike McNamara) Newsgroups: gnu.epoch.misc Subject: Patch to support epoch on the (st)ardent titan Message-ID: <MAC.91Jun21142229@gold.kpc.com> Date: 21 Jun 91 21:22:29 GMT Sender: uucp@kpc.com (UNIX-to-UNIX Copy) Reply-To: mac@ardent.com (Michael McNamara) Distribution: gnu Organization: Kubota Pacific Computer Incoporated, Santa Clara, CA Lines: 1460 Nntp-Posting-Host: gold