diff options
author | Jim Blandy <jimb@redhat.com> | 1992-01-13 22:04:23 +0000 |
---|---|---|
committer | Jim Blandy <jimb@redhat.com> | 1992-01-13 22:04:23 +0000 |
commit | 31fe8ae4d9ac80da34cf2d714ec5f6626c25ee9a (patch) | |
tree | f8f2127ad6d231db883844bf36b1fed70f78f271 | |
parent | bd5cd35fd8b585ad3d87f8be98b45a415fea22c0 (diff) | |
download | emacs-31fe8ae4d9ac80da34cf2d714ec5f6626c25ee9a.tar.gz |
Initial revision
-rw-r--r-- | src/=x11term.h | 23 | ||||
-rw-r--r-- | src/cm.h | 169 | ||||
-rw-r--r-- | src/gnu.h | 114 | ||||
-rw-r--r-- | src/mem-limits.h | 102 | ||||
-rw-r--r-- | src/sinkmask.h | 91 | ||||
-rw-r--r-- | src/syntax.h | 92 | ||||
-rw-r--r-- | src/termchar.h | 45 | ||||
-rw-r--r-- | src/termopts.h | 40 | ||||
-rw-r--r-- | src/unexencap.c | 116 | ||||
-rw-r--r-- | src/unexmips.c | 305 | ||||
-rw-r--r-- | src/unexsunos4.c | 288 |
11 files changed, 1385 insertions, 0 deletions
diff --git a/src/=x11term.h b/src/=x11term.h new file mode 100644 index 00000000000..c6f24ba91eb --- /dev/null +++ b/src/=x11term.h @@ -0,0 +1,23 @@ +#include <X11/Xlib.h> +#include <X11/Xatom.h> +#include <X11/keysym.h> +#include <X11/cursorfont.h> +#include <X11/Xutil.h> +#include <X11/X10.h> + +#define XMOUSEBUFSIZE 64 + +#ifndef sigmask +#define sigmask(no) (1L << ((no) - 1)) +#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 */ +#define BLOCK_INPUT() +#define UNBLOCK_INPUT() +#endif /* SIGIO */ + +#define CLASS "emacs" /* class id for GNU Emacs, used in .Xdefaults, etc. */ diff --git a/src/cm.h b/src/cm.h new file mode 100644 index 00000000000..eef86b93be4 --- /dev/null +++ b/src/cm.h @@ -0,0 +1,169 @@ +/* Cursor motion calculation definitions for GNU Emacs + Copyright (C) 1985, 1989 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. */ + +/* Holds the minimum and maximum costs for the parametrized capabilities. */ +struct parmcap + { + int mincost, maxcost; + }; + +/* This structure holds everything needed to do cursor motion except the pad + character (PC) and the output speed of the terminal (ospeed), which + termcap wants in global variables. */ + +struct cm + { + /* Cursor position. -1 in *both* variables means the cursor + position is unknown, in order to force absolute cursor motion. */ + + int cm_curY; /* Current row */ + int cm_curX; /* Current column */ + + /* Capabilities from termcap */ + char *cm_up; /* up (up) */ + char *cm_down; /* down (do) */ + char *cm_left; /* left (le) */ + char *cm_right; /* right (nd) */ + char *cm_home; /* home (ho) */ + char *cm_cr; /* carriage return (cr) */ + char *cm_ll; /* last line (ll) */ + char *cm_tab; /* tab (ta) */ + char *cm_backtab; /* backtab (bt) */ + char *cm_abs; /* absolute (cm) */ + char *cm_habs; /* horizontal absolute (ch) */ + char *cm_vabs; /* vertical absolute (cv) */ +#if 0 + char *cm_ds; /* "don't send" string (ds) */ +#endif + char *cm_multiup; /* multiple up (UP) */ + char *cm_multidown; /* multiple down (DO) */ + char *cm_multileft; /* multiple left (LE) */ + char *cm_multiright; /* multiple right (RI) */ + int cm_cols; /* number of cols on screen (co) */ + int cm_rows; /* number of rows on screen (li) */ + int cm_tabwidth; /* tab width (it) */ + unsigned int cm_autowrap:1; /* autowrap flag (am) */ + unsigned int cm_magicwrap:1; /* VT-100: cursor stays in last col but + will cm_wrap if next char is + printing (xn) */ + unsigned int cm_usetabs:1; /* if set, use tabs */ + unsigned int cm_losewrap:1; /* if reach right margin, forget cursor + location */ + unsigned int cm_autolf:1; /* \r performs a \r\n (rn) */ + + /* Parametrized capabilities. This needs to be a struct since + the costs are accessed through pointers. */ + +#if 0 + struct parmcap cc_abs; /* absolute (cm) */ + struct parmcap cc_habs; /* horizontal absolute (ch) */ + struct parmcap cc_vabs; /* vertical absolute (cv) */ + struct parmcap cc_multiup; /* multiple up (UP) */ + struct parmcap cc_multidown; /* multiple down (DO) */ + struct parmcap cc_multileft; /* multiple left (LE) */ + struct parmcap cc_multiright; /* multiple right (RI) */ +#endif + + /* Costs for the non-parametrized capabilities */ + int cc_up; /* cost for up */ + int cc_down; /* etc. */ + int cc_left; + int cc_right; + int cc_home; + int cc_cr; + int cc_ll; + int cc_tab; + int cc_backtab; + /* These are temporary, until the code is installed to use the + struct parmcap fields above. */ + int cc_abs; + int cc_habs; + int cc_vabs; + }; + +extern struct cm Wcm; /* Terminal capabilities */ +extern char PC; /* Pad character */ +extern short ospeed; /* Output speed (from sg_ospeed) */ + +/* Shorthand */ +#ifndef NoCMShortHand +#define curY Wcm.cm_curY +#define curX Wcm.cm_curX +#define Up Wcm.cm_up +#define Down Wcm.cm_down +#define Left Wcm.cm_left +#define Right Wcm.cm_right +#define Tab Wcm.cm_tab +#define BackTab Wcm.cm_backtab +#define TabWidth Wcm.cm_tabwidth +#define CR Wcm.cm_cr +#define Home Wcm.cm_home +#define LastLine Wcm.cm_ll +#define AbsPosition Wcm.cm_abs +#define ColPosition Wcm.cm_habs +#define RowPosition Wcm.cm_vabs +#define MultiUp Wcm.cm_multiup +#define MultiDown Wcm.cm_multidown +#define MultiLeft Wcm.cm_multileft +#define MultiRight Wcm.cm_multiright +#define AutoWrap Wcm.cm_autowrap +#define MagicWrap Wcm.cm_magicwrap +#define UseTabs Wcm.cm_usetabs +#define ScreenRows Wcm.cm_rows +#define ScreenCols Wcm.cm_cols + +#define UpCost Wcm.cc_up +#define DownCost Wcm.cc_down +#define LeftCost Wcm.cc_left +#define RightCost Wcm.cc_right +#define HomeCost Wcm.cc_home +#define CRCost Wcm.cc_cr +#define LastLineCost Wcm.cc_ll +#define TabCost Wcm.cc_tab +#define BackTabCost Wcm.cc_backtab +#define AbsPositionCost Wcm.cc_abs +#define ColPositionCost Wcm.cc_habs +#define RowPositionCost Wcm.cc_vabs +#define MultiUpCost Wcm.cc_multiup +#define MultiDownCost Wcm.cc_multidown +#define MultiLeftCost Wcm.cc_multileft +#define MultiRightCost Wcm.cc_multiright +#endif + +#define cmat(row,col) (curY = (row), curX = (col)) +#define cmplus(n) \ + { \ + if ((curX += (n)) >= ScreenCols && !MagicWrap) \ + { \ + if (Wcm.cm_losewrap) losecursor (); \ + else if (AutoWrap) curX = 0, curY++; \ + else curX--; \ + } \ + } + +#define losecursor() (curX = -1, curY = -1) + +extern int cost; +extern int evalcost (); + +extern void cmputc (); +extern int cmcostinit (); +extern int cmgoto (); +extern int Wcm_clear (); +extern int Wcm_init (); diff --git a/src/gnu.h b/src/gnu.h new file mode 100644 index 00000000000..3985c406d2a --- /dev/null +++ b/src/gnu.h @@ -0,0 +1,114 @@ +#ifdef HAVE_X11 +#define gnu_width 50 +#define gnu_height 50 +static char gnu_bits[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xfe, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xf1, + 0xff, 0xff, 0xf3, 0xff, 0x8f, 0xff, 0xe1, 0xff, 0xff, 0xf9, 0x3f, 0x22, + 0xfe, 0xcb, 0xff, 0xff, 0xf8, 0xc3, 0xf8, 0xfc, 0xcb, 0xff, 0x7f, 0xfc, + 0xe0, 0xf9, 0xf9, 0xdb, 0xff, 0x7f, 0xfc, 0xf0, 0xfb, 0xf3, 0xd9, 0xff, + 0x3f, 0x7e, 0xf8, 0xff, 0xf7, 0xcc, 0xff, 0x9f, 0x3e, 0x1c, 0x7f, 0x44, + 0xce, 0xff, 0xcf, 0x1e, 0xcc, 0x01, 0x00, 0xe7, 0xff, 0xef, 0x0e, 0xce, + 0x38, 0x1c, 0xe0, 0xff, 0xef, 0x0e, 0x27, 0xfe, 0xfa, 0xc3, 0xff, 0xef, + 0x7c, 0x93, 0xff, 0xe5, 0xbf, 0xff, 0xef, 0x99, 0xc9, 0xab, 0x2a, 0x00, + 0xff, 0xcf, 0xc3, 0x24, 0x54, 0xc5, 0xd5, 0xff, 0x9f, 0x7f, 0x16, 0xab, + 0xca, 0xff, 0xff, 0x1f, 0x1f, 0x93, 0x46, 0x95, 0xff, 0xff, 0x7f, 0xc8, + 0x49, 0x99, 0x8a, 0xff, 0xff, 0xff, 0xf0, 0x49, 0x4b, 0x95, 0xff, 0xff, + 0xff, 0xf9, 0x4c, 0x88, 0x8a, 0xff, 0xff, 0xff, 0x1e, 0xe6, 0x58, 0x95, + 0xff, 0xff, 0x3f, 0x00, 0xe6, 0xb7, 0x0a, 0xff, 0xff, 0xbf, 0x8a, 0xea, + 0x50, 0x15, 0xff, 0xff, 0xff, 0x8f, 0xca, 0x99, 0x2a, 0xff, 0xff, 0xff, + 0xa7, 0x95, 0x7f, 0x15, 0xff, 0xff, 0xff, 0x23, 0x55, 0x7f, 0x2a, 0xfe, + 0xff, 0xff, 0x63, 0xd8, 0xfc, 0x14, 0xfe, 0xff, 0xff, 0x43, 0x9a, 0xfb, + 0x2b, 0xfe, 0xff, 0xff, 0xc3, 0xaa, 0x12, 0x94, 0xfc, 0xff, 0xff, 0xc1, + 0x32, 0xd5, 0xc1, 0xfd, 0xff, 0xff, 0x81, 0x46, 0xd5, 0x47, 0xfc, 0xff, + 0xff, 0x83, 0x6c, 0xc2, 0x6e, 0xfc, 0xff, 0xff, 0x83, 0x89, 0x88, 0x69, + 0xfe, 0xff, 0xff, 0x07, 0x92, 0x09, 0x3b, 0xfe, 0xff, 0xff, 0x07, 0x22, + 0x01, 0x3c, 0xfe, 0xff, 0xff, 0x0f, 0x4e, 0x02, 0x03, 0xfe, 0xff, 0xff, + 0x2f, 0xd0, 0x18, 0x3e, 0xff, 0xff, 0xff, 0x3f, 0xb0, 0x19, 0x9e, 0xff, + 0xff, 0xff, 0x7f, 0x00, 0x09, 0x80, 0xff, 0xff, 0xff, 0x7f, 0x01, 0xe3, + 0xc1, 0xff, 0xff, 0xff, 0xff, 0x05, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x5f, 0xfd, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff}; +#else /* X10 */ +#define sink_width 48 +#define sink_height 48 +#define sink_mask_width 48 +#define sink_mask_height 48 +short sink_bits[] = { + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0x9f80, 0xffff, 0xffff, + 0x9f9f, 0xffff, 0xffff, 0x8000, + 0xffff, 0x7fff, 0xbffe, 0xffff, + 0x7fff, 0xa003, 0xffff, 0x7fff, + 0xaffd, 0xffff, 0x3fff, 0xaff9, + 0xffff, 0xffff, 0xafff, 0xffff, + 0xffff, 0xaffc, 0xffff, 0x7fff, + 0xaff8, 0xffff, 0xffff, 0xaffc, + 0xffff, 0xffff, 0xafff, 0xffff, + 0xbfff, 0xaff7, 0xffff, 0x3fff, + 0xaff3, 0xffff, 0xffff, 0xaffc, + 0x003f, 0x0000, 0x2000, 0x007f, + 0x0000, 0xe000, 0xf8df, 0xffff, + 0x07ff, 0xf9cf, 0xff0f, 0xe7ff, + 0xf9cf, 0xfff7, 0xe7ff, 0xf9ff, + 0x63f7, 0xe7fb, 0xf9ff, 0x5a37, + 0xe7fb, 0xf9cf, 0x5af7, 0xe7fb, + 0xf9cf, 0x5af7, 0xe7f9, 0xf9ef, + 0xdb0f, 0xe7fa, 0xf9ff, 0xffff, + 0xe7ff, 0xf9df, 0xffff, 0xe7ff, + 0x19cf, 0xfffc, 0xe7ff, 0xd9cf, + 0xffff, 0xe7ff, 0xd9ff, 0xce47, + 0xe673, 0x19ff, 0xb5b6, 0xe7ad, + 0xd9cf, 0xb5b7, 0xe67d, 0xd9c7, + 0xb5b7, 0xe5ed, 0x19ef, 0x4db4, + 0xe673, 0xf1ff, 0xffff, 0xe3ff, + 0x03ff, 0x0380, 0xf000, 0x07ef, + 0x0100, 0xf800, 0xffc7, 0xf93f, + 0xffff, 0xffe7, 0xfd7f, 0xffe0, + 0xffff, 0x7d7f, 0xffdf, 0xffff, + 0xbd7f, 0xffb1, 0xffff, 0xbb7f, + 0xffae, 0xffef, 0xdaff, 0xffae, + 0xffc7, 0x66ff, 0xffaf, 0xffe7, + 0xbdff, 0xffaf, 0xffff, 0xc3ff, + 0xffaf, 0xffff, 0xffff, 0xffaf}; +short sink_mask_bits[] = { + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff}; +#endif /* X10 */ diff --git a/src/mem-limits.h b/src/mem-limits.h new file mode 100644 index 00000000000..39200f99501 --- /dev/null +++ b/src/mem-limits.h @@ -0,0 +1,102 @@ +/* Includes for memory limit warnings. + Copyright (C) 1990 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. */ + +#ifndef BSD4_2 +#ifndef USG +#include <sys/vlimit.h> +#endif /* not USG */ +#else /* if BSD4_2 */ +#include <sys/time.h> +#include <sys/resource.h> +#endif /* BSD4_2 */ + +#ifdef __STDC__ +typedef void *POINTER; +#else +typedef char *POINTER; +#endif + +typedef unsigned long SIZE; + +#ifdef NULL +#undef NULL +#endif +#define NULL ((POINTER) 0) + +#ifdef emacs +extern POINTER start_of_data (); + +#ifdef BSD +#ifndef DATA_SEG_BITS +#define start_of_data() &etext +#endif +#endif + +#else /* Not emacs */ +#define start_of_data() &etext +#endif /* Not emacs */ + + + +/* start of data space; can be changed by calling malloc_init */ +static POINTER data_space_start; + +/* Number of bytes of writable memory we can expect to be able to get */ +static unsigned int lim_data; + + + +#ifdef USG + +get_lim_data () +{ + extern long ulimit (); + +#ifdef ULIMIT_BREAK_VALUE + lim_data = ULIMIT_BREAK_VALUE; +#else + lim_data = ulimit (3, 0); +#endif + + lim_data -= (long) data_space_start; +} + +#else /* not USG */ +#ifndef BSD4_2 + +get_lim_data () +{ + lim_data = vlimit (LIM_DATA, -1); +} + +#else /* BSD4_2 */ + +get_lim_data () +{ + struct rlimit XXrlimit; + + getrlimit (RLIMIT_DATA, &XXrlimit); +#ifdef RLIM_INFINITY + lim_data = XXrlimit.rlim_cur & RLIM_INFINITY; /* soft limit */ +#else + lim_data = XXrlimit.rlim_cur; /* soft limit */ +#endif +} +#endif /* BSD4_2 */ +#endif /* not USG */ diff --git a/src/sinkmask.h b/src/sinkmask.h new file mode 100644 index 00000000000..1ad645df82f --- /dev/null +++ b/src/sinkmask.h @@ -0,0 +1,91 @@ +#define sink_mask_width 48 +#define sink_mask_height 48 +#ifdef HAVE_X11 +static char sink_mask_bits[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; +#else +short sink_mask_bits[] = { + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff}; +#endif /* HAVE_X11 */ diff --git a/src/syntax.h b/src/syntax.h new file mode 100644 index 00000000000..6bd9757c3a8 --- /dev/null +++ b/src/syntax.h @@ -0,0 +1,92 @@ +/* Declarations having to do with GNU Emacs syntax tables. + Copyright (C) 1985 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. */ + + +extern Lisp_Object Qsyntax_table_p; +extern Lisp_Object Fsyntax_table_p (), Fsyntax_table (), Fset_syntax_table (); + +/* The standard syntax table is stored where it will automatically + be used in all new buffers. */ +#define Vstandard_syntax_table buffer_defaults.syntax_table + +/* A syntax table is a Lisp vector of length 0400, whose elements are integers. + +The low 8 bits of the integer is a code, as follows: +*/ + +enum syntaxcode + { + Swhitespace, /* for a whitespace character */ + Spunct, /* for random punctuation characters */ + Sword, /* for a word constituent */ + Ssymbol, /* symbol constituent but not word constituent */ + Sopen, /* for a beginning delimiter */ + Sclose, /* for an ending delimiter */ + Squote, /* for a prefix character like Lisp ' */ + Sstring, /* for a string-grouping character like Lisp " */ + Smath, /* for delimiters like $ in Tex. */ + Sescape, /* for a character that begins a C-style escape */ + Scharquote, /* for a character that quotes the following character */ + Scomment, /* for a comment-starting character */ + Sendcomment, /* for a comment-ending character */ + Smax /* Upper bound on codes that are meaningful */ + }; + +#define SYNTAX(c) \ + ((enum syntaxcode) (XINT (XVECTOR (current_buffer->syntax_table)->contents[c]) & 0377)) + +/* The next 8 bits of the number is a character, + the matching delimiter in the case of Sopen or Sclose. */ + +#define SYNTAX_MATCH(c) \ + ((XINT (XVECTOR (current_buffer->syntax_table)->contents[c]) >> 8) & 0377) + +/* Then there are five single-bit flags that have the following meanings: + 1. This character is the first of a two-character comment-start sequence. + 2. This character is the second of a two-character comment-start sequence. + 3. This character is the first of a two-character comment-end sequence. + 4. This character is the second of a two-character comment-end sequence. + 5. This character is a prefix, for backward-prefix-chars. + Note that any two-character sequence whose first character has flag 1 + and whose second character has flag 2 will be interpreted as a comment start. */ + +#define SYNTAX_COMSTART_FIRST(c) \ + ((XINT (XVECTOR (current_buffer->syntax_table)->contents[c]) >> 16) & 1) + +#define SYNTAX_COMSTART_SECOND(c) \ + ((XINT (XVECTOR (current_buffer->syntax_table)->contents[c]) >> 17) & 1) + +#define SYNTAX_COMEND_FIRST(c) \ + ((XINT (XVECTOR (current_buffer->syntax_table)->contents[c]) >> 18) & 1) + +#define SYNTAX_COMEND_SECOND(c) \ + ((XINT (XVECTOR (current_buffer->syntax_table)->contents[c]) >> 19) & 1) + +#define SYNTAX_PREFIX(c) \ + ((XINT (XVECTOR (current_buffer->syntax_table)->contents[c]) >> 20) & 1) + +/* This array, indexed by a character, contains the syntax code which that + character signifies (as a char). For example, + (enum syntaxcode) syntax_spec_code['w'] is Sword. */ + +extern unsigned char syntax_spec_code[0400]; + +/* Indexed by syntax code, give the letter that describes it. */ + +extern char syntax_code_spec[13]; diff --git a/src/termchar.h b/src/termchar.h new file mode 100644 index 00000000000..d82ccb0bad9 --- /dev/null +++ b/src/termchar.h @@ -0,0 +1,45 @@ +/* Flags and parameters describing terminal's characteristics. + Copyright (C) 1985, 1986 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. */ + + +extern int baud_rate; /* Output speed in baud */ +extern int screen_width; /* Number of usable columns */ +extern int screen_height; /* Number of lines */ +extern int must_write_spaces; /* Nonzero means spaces in the text + must actually be output; can't just skip + over some columns to leave them blank. */ +extern int min_padding_speed; /* Speed below which no padding necessary */ +extern int fast_clear_end_of_line; /* Nonzero means terminal has + command for this */ + +extern int line_ins_del_ok; /* Terminal can insert and delete lines */ +extern int char_ins_del_ok; /* Terminal can insert and delete chars */ +extern int scroll_region_ok; /* Terminal supports setting the scroll + window */ +extern int memory_below_screen; /* Terminal remembers lines scrolled + off bottom */ +extern int fast_clear_end_of_line; /* Terminal has a `ce' string */ + +extern int dont_calculate_costs; /* Nonzero means don't bother computing + various cost tables; we won't use them. */ + +/* Nonzero means no need to redraw the entire screen on resuming + a suspended Emacs. This is useful on terminals with multiple pages, + where one page is used for Emacs and another for all else. */ +extern int no_redraw_on_reenter; diff --git a/src/termopts.h b/src/termopts.h new file mode 100644 index 00000000000..0b4c6234c4c --- /dev/null +++ b/src/termopts.h @@ -0,0 +1,40 @@ +/* Flags and paramaters describing user options for handling the terminal. + Copyright (C) 1985, 1986, 1990 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. */ + + +/* Nonzero means flash the screen instead of ringing the bell. */ +extern int visible_bell; + +/* Nonzero means invert white and black for the entire screen. */ +extern int inverse_video; + +/* Nonzero means use ^S/^Q as cretinous flow control. */ +extern int flow_control; + +/* Nonzero means use interrupt-driven input. */ +extern int interrupt_input; + +/* Nonzero while interrupts are temporarily deferred during redisplay. */ +extern int interrupts_deferred; + +/* Terminal has meta key */ +extern int meta_key; + +/* Nonzero means truncate lines in all windows less wide than the screen */ +extern int truncate_partial_width_windows; diff --git a/src/unexencap.c b/src/unexencap.c new file mode 100644 index 00000000000..4ffc41145a9 --- /dev/null +++ b/src/unexencap.c @@ -0,0 +1,116 @@ +/* Waiting for papers! */ + +/* + * Do an unexec() for coff encapsulation. Uses the approach I took + * for AKCL, so don't be surprised if it doesn't look too much like + * the other unexec() routines. Assumes NO_REMAP. Should be easy to + * adapt to the emacs style unexec() if that is desired, but this works + * just fine for me with GCC/GAS/GLD under System V. - Jordan + */ + +#include <sys/types.h> +#include <sys/fcntl.h> +#include <sys/file.h> +#include <stdio.h> +#include "/usr/gnu/lib/gcc/gcc-include/a.out.h" + +filecpy(to, from, n) +FILE *to, *from; +register int n; +{ + char buffer[BUFSIZ]; + + for (;;) + if (n > BUFSIZ) { + fread(buffer, BUFSIZ, 1, from); + fwrite(buffer, BUFSIZ, 1, to); + n -= BUFSIZ; + } else if (n > 0) { + fread(buffer, 1, n, from); + fwrite(buffer, 1, n, to); + break; + } else + break; +} +/* **************************************************************** + * 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; +{ + struct coffheader header1; + struct coffscn *tp, *dp, *bp; + struct exec header; + int stsize; + char *original_file = a_name; + char *save_file = new_name; + + char *data_begin, *data_end; + int original_data; + FILE *original, *save; + register int n; + register char *p; + extern char *sbrk(); + char stdin_buf[BUFSIZ], stdout_buf[BUFSIZ]; + + + fclose(stdin); + original = fopen(original_file, "r"); + if (stdin != original || original->_file != 0) { + fprintf(stderr, "unexec: Can't open the original file.\n"); + exit(1); + } + setbuf(original, stdin_buf); + fclose(stdout); + unlink(save_file); + n = open(save_file, O_CREAT|O_WRONLY, 0777); + if (n != 1 || (save = fdopen(n, "w")) != stdout) { + fprintf(stderr, "unexec: Can't open the save file.\n"); + exit(1); + } + setbuf(save, stdout_buf); + + fread(&header1, sizeof(header1), 1, original); + tp = &header1.scns[0]; + dp = &header1.scns[1]; + bp = &header1.scns[2]; + fread(&header, sizeof(header), 1, original); + data_begin=(char *)N_DATADDR(header); + data_end = sbrk(0); + original_data = header.a_data; + header.a_data = data_end - data_begin; + header.a_bss = 0; + dp->s_size = header.a_data; + bp->s_paddr = dp->s_vaddr + dp->s_size; + bp->s_vaddr = bp->s_paddr; + bp->s_size = 0; + header1.tsize = tp->s_size; + header1.dsize = dp->s_size; + header1.bsize = bp->s_size; + fwrite(&header1, sizeof(header1), 1, save); + fwrite(&header, sizeof(header), 1, save); + + filecpy(save, original, header.a_text); + + for (n = header.a_data, p = data_begin; ; n -= BUFSIZ, p += BUFSIZ) + if (n > BUFSIZ) + fwrite(p, BUFSIZ, 1, save); + else if (n > 0) { + fwrite(p, 1, n, save); + break; + } else + break; + + fseek(original, original_data, 1); + + filecpy(save, original, header.a_syms+header.a_trsize+header.a_drsize); + fread(&stsize, sizeof(stsize), 1, original); + fwrite(&stsize, sizeof(stsize), 1, save); + filecpy(save, original, stsize - sizeof(stsize)); + + fclose(original); + fclose(save); +} diff --git a/src/unexmips.c b/src/unexmips.c new file mode 100644 index 00000000000..8cfdd401b40 --- /dev/null +++ b/src/unexmips.c @@ -0,0 +1,305 @@ +/* Unexec for MIPS (including IRIS4D). + Note that the GNU project considers support for MIPS operation + a peripheral activity which should not be allowed to divert effort + from development of the GNU system. Changes in this code will be + installed when users send them in, but aside from that + we don't plan to think about it, or about whether other Emacs + maintenance might break it. + + 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 "config.h" +#include <sys/types.h> +#include <sys/file.h> +#include <sys/stat.h> +#include <stdio.h> +#include <varargs.h> +#include <filehdr.h> +#include <aouthdr.h> +#include <scnhdr.h> +#include <sym.h> + +#ifdef IRIS_4D +#include "getpagesize.h" +#endif + +static void fatal_unexec (); + +#define READ(_fd, _buffer, _size, _error_message, _error_arg) \ + errno = EEOF; \ + if (read (_fd, _buffer, _size) != _size) \ + fatal_unexec (_error_message, _error_arg); + +#define WRITE(_fd, _buffer, _size, _error_message, _error_arg) \ + if (write (_fd, _buffer, _size) != _size) \ + fatal_unexec (_error_message, _error_arg); + +#define SEEK(_fd, _position, _error_message, _error_arg) \ + errno = EEOF; \ + if (lseek (_fd, _position, L_SET) != _position) \ + fatal_unexec (_error_message, _error_arg); + +extern int errno; +extern int sys_nerr; +extern char *sys_errlist[]; +#define EEOF -1 + +static struct scnhdr *text_section; +static struct scnhdr *init_section; +static struct scnhdr *finit_section; +static struct scnhdr *rdata_section; +static struct scnhdr *data_section; +static struct scnhdr *lit8_section; +static struct scnhdr *lit4_section; +static struct scnhdr *sdata_section; +static struct scnhdr *sbss_section; +static struct scnhdr *bss_section; + +struct headers { + struct filehdr fhdr; + struct aouthdr aout; + struct scnhdr section[10]; +}; + +/* Define name of label for entry point for the dumped executable. */ + +#ifndef DEFAULT_ENTRY_ADDRESS +#define DEFAULT_ENTRY_ADDRESS __start +#endif + +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, old; + int pagesize, brk; + int newsyms, symrel; + int nread; + struct headers hdr; + int i; + int vaddr, scnptr; +#define BUFSIZE 8192 + char buffer[BUFSIZE]; + + old = open (a_name, O_RDONLY, 0); + if (old < 0) fatal_unexec ("opening %s", a_name); + + new = creat (new_name, 0666); + if (new < 0) fatal_unexec ("creating %s", new_name); + + hdr = *((struct headers *)TEXT_START); +#ifdef MIPS2 + if (hdr.fhdr.f_magic != MIPSELMAGIC + && hdr.fhdr.f_magic != MIPSEBMAGIC + && hdr.fhdr.f_magic != (MIPSELMAGIC | 1) + && hdr.fhdr.f_magic != (MIPSEBMAGIC | 1)) + { + fprintf(stderr, + "unexec: input file magic number is %x, not %x, %x, %x or %x.\n", + hdr.fhdr.f_magic, + MIPSELMAGIC, MIPSEBMAGIC, + MIPSELMAGIC | 1, MIPSEBMAGIC | 1); + exit(1); + } +#else /* not MIPS2 */ + if (hdr.fhdr.f_magic != MIPSELMAGIC + && hdr.fhdr.f_magic != MIPSEBMAGIC) + { + fprintf (stderr, "unexec: input file magic number is %x, not %x or %x.\n", + hdr.fhdr.f_magic, MIPSELMAGIC, MIPSEBMAGIC); + exit (1); + } +#endif /* not MIPS2 */ + if (hdr.fhdr.f_opthdr != sizeof (hdr.aout)) + { + fprintf (stderr, "unexec: input a.out header is %d bytes, not %d.\n", + hdr.fhdr.f_opthdr, sizeof (hdr.aout)); + exit (1); + } + if (hdr.aout.magic != ZMAGIC) + { + fprintf (stderr, "unexec: input file a.out magic number is %o, not %o.\n", + hdr.aout.magic, ZMAGIC); + exit (1); + } + +#define CHECK_SCNHDR(ptr, name, flags) \ + if (strcmp (hdr.section[i].s_name, name) == 0) \ + { \ + if (hdr.section[i].s_flags != flags) \ + fprintf (stderr, "unexec: %x flags (%x expected) in %s section.\n", \ + hdr.section[i].s_flags, flags, name); \ + ptr = hdr.section + i; \ + i += 1; \ + } \ + else \ + ptr = NULL; + + i = 0; + CHECK_SCNHDR (text_section, _TEXT, STYP_TEXT); + CHECK_SCNHDR (init_section, _INIT, STYP_INIT); + CHECK_SCNHDR (rdata_section, _RDATA, STYP_RDATA); + CHECK_SCNHDR (data_section, _DATA, STYP_DATA); +#ifdef _LIT8 + CHECK_SCNHDR (lit8_section, _LIT8, STYP_LIT8); + CHECK_SCNHDR (lit4_section, _LIT4, STYP_LIT4); +#endif /* _LIT8 */ + CHECK_SCNHDR (sdata_section, _SDATA, STYP_SDATA); + CHECK_SCNHDR (sbss_section, _SBSS, STYP_SBSS); + CHECK_SCNHDR (bss_section, _BSS, STYP_BSS); + if (i != hdr.fhdr.f_nscns) + fprintf (stderr, "unexec: %d sections found instead of %d.\n", + i, hdr.fhdr.f_nscns); + + pagesize = getpagesize (); + brk = (sbrk (0) + pagesize - 1) & (-pagesize); + hdr.aout.dsize = brk - DATA_START; + hdr.aout.bsize = 0; + if (entry_address == 0) + { + extern DEFAULT_ENTRY_ADDRESS (); + hdr.aout.entry = (unsigned)DEFAULT_ENTRY_ADDRESS; + } + else + hdr.aout.entry = entry_address; + + hdr.aout.bss_start = hdr.aout.data_start + hdr.aout.dsize; + rdata_section->s_size = data_start - DATA_START; + data_section->s_vaddr = data_start; + data_section->s_paddr = data_start; + data_section->s_size = brk - DATA_START; + data_section->s_scnptr = rdata_section->s_scnptr + rdata_section->s_size; + vaddr = data_section->s_vaddr + data_section->s_size; + scnptr = data_section->s_scnptr + data_section->s_size; + if (lit8_section != NULL) + { + lit8_section->s_vaddr = vaddr; + lit8_section->s_paddr = vaddr; + lit8_section->s_size = 0; + lit8_section->s_scnptr = scnptr; + } + if (lit4_section != NULL) + { + lit4_section->s_vaddr = vaddr; + lit4_section->s_paddr = vaddr; + lit4_section->s_size = 0; + lit4_section->s_scnptr = scnptr; + } + if (sdata_section != NULL) + { + sdata_section->s_vaddr = vaddr; + sdata_section->s_paddr = vaddr; + sdata_section->s_size = 0; + sdata_section->s_scnptr = scnptr; + } + if (sbss_section != NULL) + { + sbss_section->s_vaddr = vaddr; + sbss_section->s_paddr = vaddr; + sbss_section->s_size = 0; + sbss_section->s_scnptr = scnptr; + } + if (bss_section != NULL) + { + bss_section->s_vaddr = vaddr; + bss_section->s_paddr = vaddr; + bss_section->s_size = 0; + bss_section->s_scnptr = scnptr; + } + + WRITE (new, TEXT_START, hdr.aout.tsize, + "writing text section to %s", new_name); + WRITE (new, DATA_START, hdr.aout.dsize, + "writing text section to %s", new_name); + + SEEK (old, hdr.fhdr.f_symptr, "seeking to start of symbols in %s", a_name); + errno = EEOF; + nread = read (old, buffer, BUFSIZE); + if (nread < sizeof (HDRR)) fatal_unexec ("reading symbols from %s", a_name); +#define symhdr ((pHDRR)buffer) + newsyms = hdr.aout.tsize + hdr.aout.dsize; + symrel = newsyms - hdr.fhdr.f_symptr; + hdr.fhdr.f_symptr = newsyms; + symhdr->cbLineOffset += symrel; + symhdr->cbDnOffset += symrel; + symhdr->cbPdOffset += symrel; + symhdr->cbSymOffset += symrel; + symhdr->cbOptOffset += symrel; + symhdr->cbAuxOffset += symrel; + symhdr->cbSsOffset += symrel; + symhdr->cbSsExtOffset += symrel; + symhdr->cbFdOffset += symrel; + symhdr->cbRfdOffset += symrel; + symhdr->cbExtOffset += symrel; +#undef symhdr + do + { + if (write (new, buffer, nread) != nread) + fatal_unexec ("writing symbols to %s", new_name); + nread = read (old, buffer, BUFSIZE); + if (nread < 0) fatal_unexec ("reading symbols from %s", a_name); +#undef BUFSIZE + } while (nread != 0); + + SEEK (new, 0, "seeking to start of header in %s", new_name); + WRITE (new, &hdr, sizeof (hdr), + "writing header of %s", new_name); + + close (old); + close (new); + mark_x (new_name); +} + +/* + * mark_x + * + * After succesfully building the new a.out, mark it executable + */ + +static +mark_x (name) + char *name; +{ + struct stat sbuf; + int um = umask (777); + umask (um); + if (stat (name, &sbuf) < 0) + fatal_unexec ("getting protection on %s", name); + sbuf.st_mode |= 0111 & ~um; + if (chmod (name, sbuf.st_mode) < 0) + fatal_unexec ("setting protection on %s", name); +} + +static void +fatal_unexec (s, va_alist) + va_dcl +{ + va_list ap; + if (errno == EEOF) + fputs ("unexec: unexpected end of file, ", stderr); + else if (errno < sys_nerr) + fprintf (stderr, "unexec: %s, ", sys_errlist[errno]); + else + fprintf (stderr, "unexec: error code %d, ", errno); + va_start (ap); + _doprnt (s, ap, stderr); + fputs (".\n", stderr); + exit (1); +} diff --git a/src/unexsunos4.c b/src/unexsunos4.c new file mode 100644 index 00000000000..e95618ecc8a --- /dev/null +++ b/src/unexsunos4.c @@ -0,0 +1,288 @@ +/* + * Unexec for Berkeley a.out format + SUNOS shared libraries + * The unexeced executable contains the __DYNAMIC area from the + * original text file, and then the rest of data + bss + malloced area of + * the current process. (The __DYNAMIC area is at the top of the process + * data segment, we use "data_start" defined externally to mark the start + * of the "real" data segment.) + * + * For programs that want to remap some of the data segment read only + * a run_time_remap is provided. This attempts to remap largest area starting + * and ending on page boundaries between "data_start" and "bndry" + * For this it to figure out where the text file is located. A path search + * is attempted after trying argv[0] and if all fails we simply do not remap + * + * One feature of run_time_remap () is mandatory: reseting the break. + * + * Note that we can no longer map data into the text segment, as this causes + * the __DYNAMIC struct to become read only, breaking the runtime loader. + * Thus we no longer need to mess with a private crt0.c, the standard one + * will do just fine, since environ can live in the writable area between + * __DYNAMIC and data_start, just make sure that pre-crt0.o (the name + * is somewhat abused here) is loaded first! + * + * $Log: unexsunos4.c,v $ + * Revision 1.3 90/02/15 04:27:40 root + * Now it actually works. + * + * Revision 1.2 90/02/15 02:02:01 root + * Many comments, fixes, works not only with emacs. + * + * Revision 1.1 90/01/29 19:43:46 root + * Initial revision + * + */ +#ifdef emacs +#include "config.h" +#endif + +#include <sys/param.h> +#include <sys/mman.h> +#include <sys/file.h> +#include <sys/stat.h> +#include <string.h> +#include <stdio.h> +#include <a.out.h> + +/* + * for programs other than emacs + * define data_start + initialized here, and make sure + * this object is loaded first! + * emacs will define these elsewhere, and load the object containing + * data_start (pre-crt0.o or firstfile.o?) first! + * The custom crt0.o *must not* be loaded! + */ +#ifndef emacs + static int data_start = 0; + static int initialized = 0; +#else + extern int initialized; + extern unsigned data_start; + extern int pureptr; +#endif + +extern char *getenv (); +static unsigned Brk; +static struct exec nhdr; +static int rd_only_len; +static long cookie; + + +unexec (new_name, a_name, bndry, bss_start, entry) + char *new_name, *a_name; + unsigned bndry, bss_start, entry; +{ + char buf[PAGSIZ]; + int fd, new; + char *old; + struct exec ohdr; /* Allocate on the stack, not needed in the next life */ + struct stat stat; + +#ifdef emacs + fprintf (stderr, "Used %d bytes of Pure Storage\n", pureptr); +#endif + + if ((fd = open (a_name, O_RDONLY)) < 0) + { + fprintf (stderr, "%s: open: ", a_name); + perror (a_name); + exit (1); + } + if ((new = open (new_name, O_WRONLY | O_CREAT, 0666)) == -1) + { + fprintf (stderr, "%s: open: ", a_name); + perror (new_name); + exit (1); + } + + if ((fstat (fd, &stat) == -1)) + { + fprintf (stderr, "%s: ", a_name); + perror ("fstat"); + exit (1); + } + + old = (char *)mmap (0, stat.st_size, PROT_READ, MAP_SHARED, fd, 0); + if (old == (char *)-1) + { + fprintf (stderr, "%s: ", a_name); + perror ("mmap"); + exit (1); + } + close (fd); + + nhdr = ohdr = (*(struct exec *)old); + + + /* + * Remeber a magic cookie so we know we've got the right binary + * when remaping. + */ + cookie = time (0); + + Brk = sbrk (0); /* Save the break, it is reset to &_end (by ld.so?) */ + + /* + * Round up data start to a page boundary (Lose if not a 2 power!) + */ + data_start = ((((int)&data_start) - 1) & ~(N_PAGSIZ (nhdr) - 1)) + N_PAGSIZ (nhdr); + + /* + * Round down read only pages to a multiple of the page size + */ + if (bndry) + rd_only_len = ((int)bndry & ~(N_PAGSIZ (nhdr) - 1)) - data_start; + +#ifndef emacs + /* Have to do this some time before dumping the data */ + initialized = 1; +#endif + + /* + * Handle new data and bss sizes and optional new entry point. + * No one actually uses bss_start and entry, but tradition compels + * one to support them. + * Could complain if bss_start > Brk, but the caller is *supposed* to know + * what she is doing. + */ + nhdr.a_data = (bss_start ? bss_start : Brk) - N_DATADDR (nhdr); + nhdr.a_bss = bss_start ? Brk - bss_start : 0; + if (entry) + nhdr.a_entry = entry; + + /* + * Write out the text segment with new header + * Dynamic executables are ZMAGIC with N_TXTOFF==0 and the header + * part of the text segment, but no need to rely on this. + * So write the TEXT first, then go back replace the header. + * Doing it in the other order is less general! + */ + lseek (new, N_TXTOFF (nhdr), L_SET); + write (new, old + N_TXTOFF (ohdr), N_TXTOFF (ohdr) + ohdr.a_text); + lseek (new, 0L, L_SET); + write (new, &nhdr, sizeof (nhdr)); + + /* + * Write out the head of the old data segment from the file not + * from core, this has the unresolved __DYNAMIC relocation data + * we need to reload + */ + lseek (new, N_DATOFF (nhdr), L_SET); + write (new, old + N_DATOFF (ohdr), (int)&data_start - N_DATADDR (ohdr)); + + /* + * Copy the rest of the data from core + */ + write (new, &data_start, N_BSSADDR (nhdr) - (int)&data_start); + + /* + * Copy the symbol table and line numbers + */ + lseek (new, N_TRELOFF (nhdr), L_SET); + write (new, old + N_TRELOFF (ohdr), stat.st_size - N_TRELOFF (ohdr)); + + fchmod (new, 0755); +} + +void +run_time_remap (progname) + char *progname; +{ + char aout[MAXPATHLEN]; + register char *path, *p; + + /* Just in case */ + if (!initialized) + return; + + /* Restore the break */ + brk (Brk); + + /* If nothing to remap: we are done! */ + if (rd_only_len == 0) + return; + + /* + * Attempt to find the executable + * First try argv[0], will almost always succeed as shells tend to give + * the full path from the hash list rather than using execvp () + */ + if (is_it (progname)) + return; + + /* + * If argv[0] is a full path and does not exist, not much sense in + * searching further + */ + if (strchr (progname, '/')) + return; + + /* + * Try to search for argv[0] on the PATH + */ + path = getenv ("PATH"); + if (path == NULL) + return; + + while (*path) + { + /* copy through ':' or end */ + for (p = aout; *p = *path; ++p, ++path) + if (*p == ':') + { + ++path; /* move past ':' */ + break; + } + *p++ = '/'; + strcpy (p, progname); + /* + * aout is a candidate full path name + */ + if (is_it (aout)) + return; + } +} + +is_it (path) + char *path; +{ + int fd; + long paths_cookie; + struct exec hdr; + + /* + * Open an executable and check for a valid header! + * Can't bcmp() the header with what we had, it may have been stripped! + * so we may save looking at non executables with the same name, mostly + * directories. + */ + fd = open (path, O_RDONLY); + if (fd != -1) + { + if (read (fd, &hdr, sizeof (hdr)) == sizeof (hdr) + && !N_BADMAG (hdr) && N_DATOFF (hdr) == N_DATOFF (nhdr) + && N_TRELOFF (hdr) == N_TRELOFF (nhdr)) + { + /* compare cookies */ + lseek (fd, N_DATOFF (hdr) + (int)&cookie - N_DATADDR (hdr), L_SET); + read (fd, &paths_cookie, sizeof (paths_cookie)); + if (paths_cookie == cookie) + { /* Eureka */ + + /* + * Do the mapping + * The PROT_EXEC may not be needed, but it is safer this way. + * should the shared library decide to indirect through + * addresses in the data segment not part of __DYNAMIC + */ + mmap (data_start, rd_only_len, PROT_READ | PROT_EXEC, + MAP_SHARED | MAP_FIXED, fd, + N_DATOFF (hdr) + data_start - N_DATADDR (hdr)); + close (fd); + return 1; + } + } + close (fd); + } + return 0; +} |