aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKen Raeburn2001-07-06 08:41:36 +0000
committerKen Raeburn2001-07-06 08:41:36 +0000
commitad782551325b7c694ee234b5ff4c5688d90e561c (patch)
treef4355f141142b6018183518fa1761b53e295ede2 /src
parentf25cfe53951f57e1b2c3972877297df3d86bb980 (diff)
downloademacs-ad782551325b7c694ee234b5ff4c5688d90e561c.tar.gz
emacs-ad782551325b7c694ee234b5ff4c5688d90e561c.zip
properly mark Attic files as deleted
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.in1226
-rw-r--r--src/XTests.c179
-rw-r--r--src/XTests.h7
-rw-r--r--src/convexos.h10
-rw-r--r--src/environ.c316
-rw-r--r--src/m/dos386.h115
-rw-r--r--src/mach2.h48
-rw-r--r--src/old-ralloc.c1069
-rw-r--r--src/sol2-2.h18
-rw-r--r--src/unexelf1.c952
-rw-r--r--src/unexsgi.c900
-rw-r--r--src/x11term.h24
-rw-r--r--src/xscrollbar.h123
-rw-r--r--src/xselect.c.old950
14 files changed, 0 insertions, 5937 deletions
diff --git a/src/Makefile.in b/src/Makefile.in
deleted file mode 100644
index 03faaae332b..00000000000
--- a/src/Makefile.in
+++ /dev/null
@@ -1,1226 +0,0 @@
1# Makefile for GNU Emacs.
2# Copyright (C) 1985, 87, 88, 93, 94, 95, 99, 2000, 2001
3# Free Software Foundation, Inc.
4
5# This file is part of GNU Emacs.
6
7# GNU Emacs is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2, or (at your option)
10# any later version.
11
12# GNU Emacs is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16
17# You should have received a copy of the GNU General Public License
18# along with GNU Emacs; see the file COPYING. If not, write to
19# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20# Boston, MA 02111-1307, USA.
21
22
23# Note that this file is edited by msdos/sed1v2.inp for MSDOS. That
24# script may need modifying in sync with changes made here. Try to
25# avoid shell-ism because the DOS build has to use the DOS shell.
26
27# Don't try to replace the ccp processing using autoconf facilities,
28# says rms.
29
30# Here are the things that we expect ../configure to edit.
31# We use $(srcdir) explicitly in dependencies so as not to depend on VPATH.
32srcdir=@srcdir@
33VPATH=@srcdir@
34CC=@CC@
35CPP=@CPP@
36CFLAGS=@CFLAGS@
37CPPFLAGS=@CPPFLAGS@
38LDFLAGS=@LDFLAGS@
39LN_S=@LN_S@
40# Substitute an assignment for the MAKE variable, because
41# BSD doesn't have it as a default.
42@SET_MAKE@
43# Don't use LIBS. configure puts stuff in it that either shouldn't be
44# linked with Emacs or is duplicated by the cpp stuff below.
45# LIBS = @LIBS@
46LIBOBJS = @LIBOBJS@
47
48# On Xenix and the IBM RS6000, double-dot gets screwed up.
49dot = .
50dotdot = ${dot}${dot}
51lispsource = ${srcdir}/$(dot)$(dot)/lisp/
52libsrc = $(dot)$(dot)/lib-src/
53etc = $(dot)$(dot)/etc/
54oldXMenudir = $(dot)$(dot)/oldXMenu/
55lwlibdir = $(dot)$(dot)/lwlib/
56
57# Configuration files for .o files to depend on.
58M_FILE = ${srcdir}/@machfile@
59S_FILE = ${srcdir}/@opsysfile@
60config_h = config.h $(M_FILE) $(S_FILE)
61
62# ========================== start of cpp stuff =======================
63/* From here on, comments must be done in C syntax. */
64
65C_SWITCH_SYSTEM=
66
67/* just to be sure the sh is used */
68SHELL=/bin/sh
69
70#define THIS_IS_MAKEFILE
71#define NO_SHORTNAMES
72#define NOT_C_CODE
73#include "config.h"
74
75/* We won't really call alloca;
76 don't let the file name alloca.c get messed up. */
77#ifdef alloca
78#undef alloca
79#endif
80
81/* Don't let the file name mktime.c get messed up. */
82#ifdef mktime
83#undef mktime
84#endif
85
86/* Use HAVE_X11 as an alias for X11 in this file
87 to avoid problems with X11 as a subdirectory name
88 in -I and other such options which pass through this file. */
89
90#ifdef X11
91#define HAVE_X11
92#undef X11
93#endif
94
95/* On some machines #define register is done in config;
96 don't let it interfere with this file. */
97#undef register
98
99/* On some systems we may not be able to use the system make command. */
100#ifdef MAKE_COMMAND
101MAKE = MAKE_COMMAND
102#endif
103
104#ifdef C_COMPILER
105CC = C_COMPILER
106#endif
107
108/* GNU libc requires ORDINARY_LINK so that its own crt0 is used.
109 Linux is an exception because it uses a funny variant of GNU libc. */
110#ifdef __GNU_LIBRARY__
111#ifndef LINUX
112#define ORDINARY_LINK
113#endif
114#endif
115
116/* Some machines don't find the standard C libraries in the usual place. */
117#ifndef ORDINARY_LINK
118#ifndef LIB_STANDARD
119#define LIB_STANDARD -lc
120#endif
121#else
122#ifndef LIB_STANDARD
123#define LIB_STANDARD
124#endif
125#endif
126
127/* Unless inhibited or changed, use -lg to link for debugging. */
128#ifndef LIBS_DEBUG
129#define LIBS_DEBUG -lg
130#endif
131
132/* Some s/SYSTEM.h files define this to request special libraries. */
133#ifndef LIBS_SYSTEM
134#define LIBS_SYSTEM
135#endif
136
137/* Some m/MACHINE.h files define this to request special libraries. */
138#ifndef LIBS_MACHINE
139#define LIBS_MACHINE
140#endif
141
142#ifndef LIB_MATH
143# define LIB_MATH -lm
144#endif /* LIB_MATH */
145
146/* Some s/SYSTEM.h files define this to request special switches in ld. */
147#ifndef LD_SWITCH_SYSTEM
148#if !defined (__GNUC__) && (defined(COFF_ENCAPSULATE) || (defined (BSD_SYSTEM) && !defined (COFF)))
149#define LD_SWITCH_SYSTEM -X
150#else /* ! defined(COFF_ENCAPSULATE) || (defined (BSD_SYSTEM) && !defined (COFF)) */
151#define LD_SWITCH_SYSTEM
152#endif /* ! defined(COFF_ENCAPSULATE) || (defined (BSD_SYSTEM) && !defined (COFF)) */
153#endif /* LD_SWITCH_SYSTEM */
154
155/* This holds special options for linking temacs
156 that should be used for linking anything else. */
157#ifndef LD_SWITCH_SYSTEM_TEMACS
158#define LD_SWITCH_SYSTEM_TEMACS
159#endif
160
161/* Some m/MACHINE.h files define this to request special switches in ld. */
162#ifndef LD_SWITCH_MACHINE
163#define LD_SWITCH_MACHINE
164#endif
165
166/* This holds special options for linking temacs
167 that should be used for linking anything else. */
168#ifndef LD_SWITCH_MACHINE_TEMACS
169#define LD_SWITCH_MACHINE_TEMACS
170#endif
171
172/* Some m/MACHINE.h files define this to request special switches in cc. */
173#ifndef C_SWITCH_MACHINE
174#define C_SWITCH_MACHINE
175#endif
176
177/* Some s/SYSTEM.h files define this to request special switches in cc. */
178#ifndef C_SWITCH_SYSTEM
179#define C_SWITCH_SYSTEM
180#endif
181
182/* These macros are for switches specifically related to X Windows. */
183#ifndef C_SWITCH_X_MACHINE
184#define C_SWITCH_X_MACHINE
185#endif
186
187#ifndef C_SWITCH_X_SYSTEM
188#define C_SWITCH_X_SYSTEM
189#endif
190
191#ifndef C_SWITCH_X_SITE
192#define C_SWITCH_X_SITE
193#endif
194
195#ifndef LD_SWITCH_X_SITE
196#define LD_SWITCH_X_SITE
197#endif
198
199#ifndef LD_SWITCH_X_DEFAULT
200#define LD_SWITCH_X_DEFAULT
201#endif
202
203/* These can be passed in from config.h to define special load and
204 compile switches needed by individual sites */
205#ifndef LD_SWITCH_SITE
206#define LD_SWITCH_SITE
207#endif
208
209#ifndef C_SWITCH_SITE
210#define C_SWITCH_SITE
211#endif
212
213#ifndef ORDINARY_LINK
214
215#ifndef CRT0_COMPILE
216#define CRT0_COMPILE $(CC) -c $(ALL_CFLAGS) C_SWITCH_ASM
217#endif
218
219#ifndef START_FILES
220#ifdef NO_REMAP
221#ifdef COFF_ENCAPSULATE
222#define START_FILES pre-crt0.o /usr/local/lib/gcc-crt0.o
223#else /* ! defined (COFF_ENCAPSULATE) */
224#define START_FILES pre-crt0.o /lib/crt0.o
225#endif /* ! defined (COFF_ENCAPSULATE) */
226#else /* ! defined (NO_REMAP) */
227#define START_FILES ecrt0.o
228#endif /* ! defined (NO_REMAP) */
229#endif /* START_FILES */
230STARTFILES = START_FILES
231
232#else /* ORDINARY_LINK */
233
234/* config.h might want to force START_FILES anyway */
235#ifdef START_FILES
236STARTFILES = START_FILES
237#endif /* START_FILES */
238
239#endif /* not ORDINARY_LINK */
240
241
242/* cc switches needed to make `asm' keyword work.
243 Nothing special needed on most machines. */
244#ifndef C_SWITCH_ASM
245#define C_SWITCH_ASM
246#endif
247
248#ifdef USE_X_TOOLKIT
249#define USE_@X_TOOLKIT_TYPE@
250TOOLKIT_DEFINES = -DUSE_@X_TOOLKIT_TYPE@
251#else
252TOOLKIT_DEFINES =
253#endif
254
255/* DO NOT use -R. There is a special hack described in lastfile.c
256 which is used instead. Some initialized data areas are modified
257 at initial startup, then labeled as part of the text area when
258 Emacs is dumped for the first time, and never changed again. */
259
260/* -Demacs is needed to make some files produce the correct version
261 for use in Emacs.
262
263 -DHAVE_CONFIG_H is needed for some other files to take advantage of
264 the information in `config.h'. */
265
266/* C_SWITCH_X_SITE must come before C_SWITCH_X_MACHINE and C_SWITCH_X_SYSTEM
267 since it may have -I options that should override those two. */
268ALL_CFLAGS=-Demacs -DHAVE_CONFIG_H $(TOOLKIT_DEFINES) $(MYCPPFLAG) -I. -I${srcdir} C_SWITCH_MACHINE C_SWITCH_SYSTEM C_SWITCH_SITE C_SWITCH_X_SITE C_SWITCH_X_MACHINE C_SWITCH_X_SYSTEM ${CFLAGS}
269.c.o:
270 $(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $<
271
272#ifndef LIBX10_MACHINE
273#define LIBX10_MACHINE
274#endif
275
276#ifndef LIBX11_MACHINE
277#define LIBX11_MACHINE
278#endif
279
280#ifndef LIBX10_SYSTEM
281#define LIBX10_SYSTEM
282#endif
283
284#ifndef LIBX11_SYSTEM
285#define LIBX11_SYSTEM
286#endif
287
288#ifndef LIB_X11_LIB
289#define LIB_X11_LIB -lX11
290#endif
291
292#ifdef HAVE_X_WINDOWS
293#ifdef HAVE_MENUS
294
295/* Include xmenu.o in the list of X object files. */
296XOBJ= xterm.o xfns.o xselect.o xrdb.o fontset.o
297
298/* The X Menu stuff is present in the X10 distribution, but missing
299 from X11. If we have X10, just use the installed library;
300 otherwise, use our own copy. */
301#ifdef HAVE_X11
302#ifdef USE_X_TOOLKIT
303OLDXMENU=${lwlibdir}liblw.a
304LIBXMENU= $(OLDXMENU)
305#else /* not USE_X_TOOLKIT */
306OLDXMENU= ${oldXMenudir}libXMenu11.a
307LIBXMENU= $(OLDXMENU)
308#endif /* not USE_X_TOOLKIT */
309#else /* not HAVE_X11 */
310LIBXMENU= -lXMenu
311#endif /* not HAVE_X11 */
312
313#else /* not HAVE_MENUS */
314
315/* Otherwise, omit xmenu.o from the list of X object files, and
316 don't worry about the menu library at all. */
317XOBJ= xterm.o xfns.o xselect.o xrdb.o fontset.o
318LIBXMENU=
319#endif /* not HAVE_MENUS */
320
321#ifdef USE_X_TOOLKIT
322#define @X_TOOLKIT_TYPE@
323#if defined (LUCID) || defined (ATHENA)
324#if HAVE_XAW3D
325LIBW= -lXaw3d
326#else
327LIBW= -lXaw
328#endif
329#endif
330#ifdef MOTIF
331#if defined (HAVE_MOTIF_2_1) && defined (HAVE_LIBXP)
332#define LIB_MOTIF_EXTRA -lXp
333#else
334#define LIB_MOTIF_EXTRA
335#endif
336#ifdef LIB_MOTIF
337LIBW= LIB_MOTIF LIB_MOTIF_EXTRA
338#else
339LIBW= -lXm LIB_MOTIF_EXTRA
340#endif
341#endif
342#ifdef OPEN_LOOK
343LIBW= -lXol
344#endif
345
346#ifdef HAVE_X11XTR6
347#ifdef NEED_LIBW
348LIBXTR6 = -lSM -lICE -lw
349#else
350LIBXTR6 = -lSM -lICE
351#endif
352#endif
353
354#ifndef LIBXMU
355#define LIBXMU -lXmu
356#endif
357
358#ifdef LIBXT_STATIC
359/* We assume the config files have defined STATIC_OPTION
360 since that might depend on the operating system.
361 (Don't forget you need different definitions with and without __GNUC__.) */
362LIBXT= STATIC_OPTION $(LIBW) LIBXMU -lXt $(LIBXTR6) -lXext DYNAMIC_OPTION
363#else /* not LIBXT_STATIC */
364LIBXT= $(LIBW) LIBXMU -lXt $(LIBXTR6) -lXext
365#endif /* not LIBXT_STATIC */
366
367#else /* not USE_X_TOOLKIT */
368LIBXT=
369#endif /* not USE_X_TOOLKIT */
370
371#if HAVE_XPM
372#ifndef LIBXPM
373#define LIBXPM -lXpm
374#endif /* not defined LIBXPM */
375#else /* not HAVE_XPM */
376#define LIBXPM
377#endif /* not HAVE_XPM */
378
379#if HAVE_JPEG
380#ifndef LIBJPEG
381#define LIBJPEG -ljpeg
382#endif /* not defined LIBJPEG */
383#else /* not HAVE_JPEG */
384#define LIBJPEG
385#endif /* not HAVE_JPEG */
386
387#if HAVE_PNG
388#ifndef LIBPNG
389#define LIBPNG -lpng -lz -lm
390#endif /* not defined LIBPNG */
391#else /* not HAVE_PNG */
392#define LIBPNG
393#endif /* not HAVE_PNG */
394
395#if HAVE_TIFF
396#ifndef LIBTIFF
397#define LIBTIFF -ltiff
398#endif /* not defined LIBTIFF */
399#else /* not HAVE_TIFF */
400#define LIBTIFF
401#endif /* not HAVE_TIFF */
402
403#if HAVE_GIF
404#ifndef LIBGIF
405#define LIBGIF -lungif
406#endif /* not defined LIBGIF */
407#else /* not HAVE_GIF */
408#define LIBGIF
409#endif /* not HAVE_GIF */
410
411#ifdef HAVE_X11
412/* LD_SWITCH_X_DEFAULT comes after everything else that specifies
413 options for where to find X libraries, but before those libraries. */
414X11_LDFLAGS = LD_SWITCH_X_SITE LD_SWITCH_X_DEFAULT
415LIBX= $(LIBXMENU) $(X11_LDFLAGS) $(LIBXT) LIBTIFF LIBJPEG LIBPNG LIBGIF LIBXPM LIB_X11_LIB LIBX11_MACHINE LIBX11_SYSTEM
416#else /* not HAVE_X11 */
417LIBX= $(LIBXMENU) LD_SWITCH_X_SITE -lX10 LIBX10_MACHINE LIBX10_SYSTEM
418#endif /* not HAVE_X11 */
419#endif /* not HAVE_X_WINDOWS */
420
421LIBSOUND= @LIBSOUND@
422
423#ifndef ORDINARY_LINK
424/* Fix linking if compiled with GCC. */
425#ifdef __GNUC__
426
427#if __GNUC__ > 1
428
429#ifdef LINKER
430#define LINKER_WAS_SPECIFIED
431#endif
432
433/* Versions of GCC >= 2.0 put their library, libgcc.a, in obscure
434 places that are difficult to figure out at make time. Fortunately,
435 these same versions allow you to pass arbitrary flags on to the
436 linker, so there's no reason not to use it as a linker.
437
438 Well, it's not quite perfect. The `-nostdlib' keeps GCC from
439 searching for libraries in its internal directories, so we have to
440 ask GCC explicitly where to find libgcc.a. */
441
442#ifndef LINKER
443#define LINKER $(CC) -nostdlib
444#endif
445
446#ifndef LIB_GCC
447/* Ask GCC where to find libgcc.a. */
448#define LIB_GCC `$(CC) -print-libgcc-file-name`
449#endif /* not LIB_GCC */
450
451GNULIB_VAR = LIB_GCC
452
453#ifndef LINKER_WAS_SPECIFIED
454/* GCC passes any argument prefixed with -Xlinker directly to the
455 linker. See prefix-args.c for an explanation of why we don't do
456 this with the shell's `for' construct.
457 Note that some people don't have '.' in their paths, so we must
458 use ./prefix-args. */
459#define YMF_PASS_LDFLAGS(flags) `./prefix-args -Xlinker flags`
460#else
461#define YMF_PASS_LDFLAGS(flags) flags
462#endif
463
464#else /* __GNUC__ < 2 */
465
466#ifndef LIB_GCC
467#define LIB_GCC /usr/local/lib/gcc-gnulib
468#endif /* not LIB_GCC */
469GNULIB_VAR = `if [ -f LIB_GCC ] ; then echo LIB_GCC; else echo; fi`
470#endif /* __GNUC__ < 2 */
471#else /* not __GNUC__ */
472GNULIB_VAR =
473
474#endif /* not __GNUC__ */
475#endif /* not ORDINARY_LINK */
476
477/* Specify address for ld to start loading at,
478 if requested by configuration. */
479#ifdef LD_TEXT_START_ADDR
480STARTFLAGS = -T LD_TEXT_START_ADDR -e __start
481#endif
482
483#ifdef ORDINARY_LINK
484LD = $(CC)
485#else
486#ifdef COFF_ENCAPSULATE
487LD=$(CC) -nostdlib
488#else /* not ORDINARY_LINK */
489#ifdef LINKER
490LD=LINKER
491#else /* not LINKER */
492LD=ld
493#endif /* not LINKER */
494#endif /* not COFF_ENCAPSULATE */
495#endif /* not ORDINARY_LINK */
496
497ALL_LDFLAGS = LD_SWITCH_SYSTEM LD_SWITCH_SYSTEM_TEMACS LD_SWITCH_MACHINE \
498 LD_SWITCH_MACHINE_TEMACS LD_SWITCH_SITE $(LDFLAGS)
499
500/* A macro which other sections of Makefile can redefine to munge the
501 flags before they're passed to LD. This is helpful if you have
502 redefined LD to something odd, like "gcc".
503 (The YMF prefix is a holdover from the old name "ymakefile".)
504 */
505#ifndef YMF_PASS_LDFLAGS
506#define YMF_PASS_LDFLAGS(flags) flags
507#endif
508
509/* Allow config.h to specify a replacement file for unexec.c. */
510#ifndef UNEXEC
511#define UNEXEC unexec.o
512#endif
513#ifndef UNEXEC_SRC
514#define UNEXEC_SRC unexec.c
515#endif
516
517INTERVAL_SRC = intervals.h composite.h
518
519GETLOADAVG_LIBS = @GETLOADAVG_LIBS@
520
521#ifdef MSDOS
522#ifdef HAVE_X_WINDOWS
523MSDOS_OBJ = dosfns.o msdos.o
524#else
525MSDOS_OBJ = dosfns.o msdos.o w16select.o
526#endif
527#endif
528
529
530/* lastfile must follow all files
531 whose initialized data areas should be dumped as pure by dump-emacs. */
532obj= dispnew.o frame.o scroll.o xdisp.o xmenu.o window.o \
533 charset.o coding.o category.o ccl.o\
534 cm.o term.o xfaces.o $(XOBJ) \
535 emacs.o keyboard.o macros.o keymap.o sysdep.o \
536 buffer.o filelock.o insdel.o marker.o \
537 minibuf.o fileio.o dired.o filemode.o \
538 cmds.o casetab.o casefiddle.o indent.o search.o regex.o undo.o \
539 alloc.o data.o doc.o editfns.o callint.o \
540 eval.o floatfns.o fns.o print.o lread.o \
541 abbrev.o syntax.o UNEXEC mocklisp.o bytecode.o \
542 process.o callproc.o \
543 region-cache.o sound.o atimer.o \
544 doprnt.o strftime.o intervals.o textprop.o composite.o md5.o \
545 $(MSDOS_OBJ)
546
547/* Object files used on some machine or other.
548 These go in the DOC file on all machines
549 in case they are needed there. */
550SOME_MACHINE_OBJECTS = sunfns.o dosfns.o msdos.o \
551 xterm.o xfns.o xmenu.o xselect.o xrdb.o
552
553
554#ifdef TERMINFO
555/* Used to be -ltermcap here. If your machine needs that,
556 define LIBS_TERMCAP in the m/MACHINE.h file. */
557#ifndef LIBS_TERMCAP
558#define LIBS_TERMCAP -lcurses
559#endif /* LIBS_TERMCAP */
560termcapobj = terminfo.o
561#else /* ! defined (TERMINFO) */
562#ifndef LIBS_TERMCAP
563#define LIBS_TERMCAP
564termcapobj = termcap.o tparam.o
565#else /* LIBS_TERMCAP */
566termcapobj = tparam.o
567#endif /* LIBS_TERMCAP */
568#endif /* ! defined (TERMINFO) */
569
570
571#ifndef SYSTEM_MALLOC
572
573#ifdef DOUG_LEA_MALLOC
574#ifdef REL_ALLOC
575mallocobj = ralloc.o vm-limit.o
576#else /* ! defined (REL_ALLOC) */
577mallocobj = vm-limit.o
578#endif /* ! defined (REL_ALLOC) */
579#else /* ! defined (DOUG_LEA_MALLOC) */
580#ifdef REL_ALLOC
581mallocobj = gmalloc.o ralloc.o vm-limit.o
582#else /* ! defined (REL_ALLOC) */
583mallocobj = gmalloc.o vm-limit.o
584#endif /* ! defined (REL_ALLOC) */
585#endif /* ! defined (DOUG_LEA_MALLOC) */
586
587#endif /* SYSTEM_MALLOC */
588
589
590#ifndef HAVE_ALLOCA
591allocaobj = alloca.o
592#else
593allocaobj =
594#endif
595
596#ifdef USE_X_TOOLKIT
597widgetobj= widget.o
598#else /* not USE_X_TOOLKIT */
599widgetobj=
600#endif /* not USE_X_TOOLKIT */
601
602
603/* define otherobj as list of object files that make-docfile
604 should not be told about. */
605otherobj= $(termcapobj) lastfile.o $(mallocobj) $(allocaobj) $(widgetobj) $(LIBOBJS)
606
607#ifdef HAVE_MOUSE
608#define MOUSE_SUPPORT ${lispsource}mouse.elc \
609 ${lispsource}select.elc ${lispsource}scroll-bar.elc
610#else
611#define MOUSE_SUPPORT
612#endif
613
614#ifdef VMS
615#define VMS_SUPPORT ${lispsource}vmsproc.elc ${lispsource}vms-patch.elc
616#else
617#define VMS_SUPPORT
618#endif
619
620#ifdef MSDOS
621#define MSDOS_SUPPORT ${lispsource}ls-lisp.elc ${lispsource}disp-table.elc \
622 ${lispsource}dos-fns.elc ${lispsource}dos-w32.elc ${lispsource}dos-vars.elc \
623 ${lispsource}international/ccl.elc ${lispsource}international/codepage.elc
624
625#else
626#define MSDOS_SUPPORT
627#endif
628
629#ifdef WINDOWSNT
630#define WINNT_SUPPORT ${lispsource}ls-lisp.elc ${lispsource}w32-fns.elc \
631 ${lispsource}dos-w32.elc
632#else
633#define WINNT_SUPPORT
634#endif
635
636/* List of Lisp files loaded into the dumped Emacs. It's arranged
637 like this because it's easier to generate it semi-mechanically from
638 loadup.el this way.
639
640 Note that this list should not include lisp files which might not
641 be present, like site-load.el and site-init.el; this makefile
642 expects them all to be either present or buildable.
643
644 Files which are loaded unconditionally should be in shortlisp as well.
645 Files included conditionally here should be included (unconditionally)
646 in SOME_MACHINE_LISP. */
647
648lisp= \
649 ${lispsource}abbrev.elc \
650 ${lispsource}buff-menu.elc \
651 ${lispsource}byte-run.elc \
652 ${lispsource}cus-start.el \
653 ${lispsource}custom.elc \
654 ${lispsource}emacs-lisp/lisp-mode.elc \
655 ${lispsource}emacs-lisp/lisp.elc \
656 ${lispsource}env.elc \
657 ${lispsource}faces.elc \
658 ${lispsource}files.elc \
659 ${lispsource}format.elc \
660 ${lispsource}facemenu.elc \
661 MOUSE_SUPPORT \
662 ${lispsource}float-sup.elc \
663 ${lispsource}frame.elc\
664 ${lispsource}help.elc \
665 ${lispsource}indent.elc \
666 ${lispsource}isearch.elc \
667 ${lispsource}loadup.el \
668 ${lispsource}loaddefs.el \
669 ${lispsource}bindings.el \
670 ${lispsource}map-ynp.elc \
671 ${lispsource}menu-bar.elc \
672 ${lispsource}international/mule.elc \
673 ${lispsource}international/mule-conf.el \
674 ${lispsource}international/mule-cmds.elc \
675 ${lispsource}international/characters.elc \
676 ${lispsource}international/utf-8.elc \
677 ${lispsource}case-table.elc \
678 ${lispsource}language/chinese.elc \
679 ${lispsource}language/cyrillic.elc \
680 ${lispsource}language/indian.elc \
681 ${lispsource}language/devanagari.elc \
682 ${lispsource}language/english.elc \
683 ${lispsource}language/ethiopic.elc \
684 ${lispsource}language/european.elc \
685 ${lispsource}language/czech.elc \
686 ${lispsource}language/slovak.elc \
687 ${lispsource}language/romanian.elc \
688 ${lispsource}language/greek.elc \
689 ${lispsource}language/hebrew.elc \
690 ${lispsource}language/japanese.elc \
691 ${lispsource}language/korean.elc \
692 ${lispsource}language/lao.elc \
693 ${lispsource}language/thai.elc \
694 ${lispsource}language/tibetan.elc \
695 ${lispsource}language/vietnamese.elc \
696 ${lispsource}language/misc-lang.elc \
697 ${lispsource}paths.el \
698 ${lispsource}register.elc \
699 ${lispsource}replace.elc \
700 ${lispsource}simple.elc \
701 ${lispsource}startup.elc \
702 ${lispsource}subr.elc \
703 ${lispsource}term/tty-colors.elc \
704 ${lispsource}textmodes/fill.elc \
705 ${lispsource}textmodes/page.elc \
706 ${lispsource}textmodes/paragraphs.elc \
707 ${lispsource}textmodes/text-mode.elc \
708 ${lispsource}vc-hooks.elc \
709 ${lispsource}ediff-hook.elc \
710 VMS_SUPPORT \
711 MSDOS_SUPPORT \
712 WINNT_SUPPORT \
713 ${lispsource}widget.elc \
714 ${lispsource}window.elc \
715 ${lispsource}version.el
716
717/* These are relative file names for the Lisp files
718 that are loaded unconditionally. This is used in make-docfile.
719 It need not contain the files that are loaded conditionally
720 because SOME_MACHINE_LISP has those. */
721shortlisp= \
722 ../lisp/abbrev.elc \
723 ../lisp/buff-menu.elc \
724 ../lisp/byte-run.elc \
725 ../lisp/cus-start.el \
726 ../lisp/custom.elc \
727 ../lisp/emacs-lisp/lisp-mode.elc \
728 ../lisp/emacs-lisp/lisp.elc \
729 ../lisp/facemenu.elc \
730 ../lisp/faces.elc \
731 ../lisp/files.elc \
732 ../lisp/float-sup.elc \
733 ../lisp/format.elc \
734 ../lisp/frame.elc \
735 ../lisp/help.elc \
736 ../lisp/indent.elc \
737 ../lisp/isearch.elc \
738 ../lisp/loadup.el \
739 ../lisp/loaddefs.el \
740 ../lisp/bindings.el \
741 ../lisp/map-ynp.elc \
742 ../lisp/international/mule.elc \
743 ../lisp/international/mule-conf.el \
744 ../lisp/international/mule-cmds.elc \
745 ../lisp/international/characters.elc \
746 ../lisp/case-table.elc \
747 ../lisp/language/chinese.elc \
748 ../lisp/language/cyrillic.elc \
749 ../lisp/language/indian.elc \
750 ../lisp/language/devanagari.elc \
751 ../lisp/language/english.elc \
752 ../lisp/language/ethiopic.elc \
753 ../lisp/language/european.elc \
754 ../lisp/language/czech.elc \
755 ../lisp/language/slovak.elc \
756 ../lisp/language/romanian.elc \
757 ../lisp/language/greek.elc \
758 ../lisp/language/hebrew.elc \
759 ../lisp/language/japanese.elc \
760 ../lisp/language/korean.elc \
761 ../lisp/language/lao.elc \
762 ../lisp/language/thai.elc \
763 ../lisp/language/tibetan.elc \
764 ../lisp/language/vietnamese.elc \
765 ../lisp/language/misc-lang.elc \
766 ../lisp/paths.el \
767 ../lisp/register.elc \
768 ../lisp/replace.elc \
769 ../lisp/simple.elc \
770 ../lisp/startup.elc \
771 ../lisp/subr.elc \
772 ../lisp/term/tty-colors.elc \
773 ../lisp/textmodes/fill.elc \
774 ../lisp/textmodes/page.elc \
775 ../lisp/textmodes/paragraphs.elc \
776 ../lisp/textmodes/text-mode.elc \
777 ../lisp/vc-hooks.elc \
778 ../lisp/ediff-hook.elc \
779 ../lisp/widget.elc \
780 ../lisp/window.elc \
781 ../lisp/version.el
782
783/* Lisp files that may or may not be used.
784 We must unconditionally put them in the DOC file.
785 We use ../lisp/ to start the file names
786 to reduce the size of the argument list for make-docfile
787 for the sake of systems which can't handle large ones. */
788SOME_MACHINE_LISP = ${dotdot}/lisp/menu-bar.elc ${dotdot}/lisp/mouse.elc \
789 ${dotdot}/lisp/select.elc ${dotdot}/lisp/scroll-bar.elc \
790 ${dotdot}/lisp/vmsproc.elc ${dotdot}/lisp/vms-patch.elc \
791 ${dotdot}/lisp/ls-lisp.elc ${dotdot}/lisp/dos-fns.elc \
792 ${dotdot}/lisp/w32-fns.elc ${dotdot}/lisp/dos-w32.elc \
793 ${dotdot}/lisp/disp-table.elc ${dotdot}/lisp/dos-vars.elc \
794 ${dotdot}/lisp/international/ccl.elc \
795 ${dotdot}/lisp/international/codepage.elc
796
797/* Construct full set of libraries to be linked.
798 Note that SunOS needs -lm to come before -lc; otherwise, you get
799 duplicated symbols. If the standard libraries were compiled
800 with GCC, we might need gnulib again after them. */
801LIBES = $(LOADLIBES) $(LIBS) $(LIBX) $(LIBSOUND) \
802 LIBS_SYSTEM LIBS_MACHINE LIBS_TERMCAP \
803 LIBS_DEBUG $(GETLOADAVG_LIBS) $(GNULIB_VAR) LIB_MATH LIB_STANDARD \
804 $(GNULIB_VAR)
805
806/* Enable recompilation of certain other files depending on system type. */
807
808#ifndef OTHER_FILES
809#define OTHER_FILES
810#endif
811
812#ifndef OBJECTS_MACHINE
813#define OBJECTS_MACHINE
814#endif
815
816all: emacs OTHER_FILES
817
818emacs: temacs ${etc}DOC ${lisp}
819#ifdef CANNOT_DUMP
820 rm -f emacs
821 ln temacs emacs
822#else
823#ifdef HAVE_SHM
824 LC_ALL=C ./temacs -nl -batch -l loadup dump
825#else /* ! defined (HAVE_SHM) */
826 LC_ALL=C ./temacs -batch -l loadup dump
827#endif /* ! defined (HAVE_SHM) */
828#endif /* ! defined (CANNOT_DUMP) */
829 -./emacs -q -batch -f list-load-path-shadows
830
831/* We run make-docfile twice because the command line may get too long
832 on some systems. */
833/* ${SOME_MACHINE_OBJECTS} comes before ${obj} because some files may
834 or may not be included in ${obj}, but they are always included in
835 ${SOME_MACHINE_OBJECTS}. Since a file is processed when it is mentioned
836 for the first time, this prevents any variation between configurations
837 in the contents of the DOC file.
838 Likewise for ${SOME_MACHINE_LISP}. */
839${etc}DOC: ${libsrc}make-docfile ${obj} ${shortlisp} ${SOME_MACHINE_LISP}
840 -rm -f ${etc}DOC
841 ${libsrc}make-docfile -d ${srcdir} ${SOME_MACHINE_OBJECTS} ${obj} > ${etc}DOC
842 ${libsrc}make-docfile -a ${etc}DOC -d ${srcdir} ${SOME_MACHINE_LISP} ${shortlisp}
843
844${libsrc}make-docfile:
845 cd ${libsrc}; ${MAKE} ${MFLAGS} make-docfile
846
847/* Some systems define this to cause parallel Make-ing. */
848#ifndef MAKE_PARALLEL
849#define MAKE_PARALLEL
850#endif
851
852temacs: MAKE_PARALLEL $(LOCALCPP) $(STARTFILES) stamp-oldxmenu ${obj} ${otherobj} OBJECTS_MACHINE prefix-args
853 $(LD) YMF_PASS_LDFLAGS (${STARTFLAGS} ${ALL_LDFLAGS}) \
854 -o temacs ${STARTFILES} ${obj} ${otherobj} \
855 OBJECTS_MACHINE ${LIBES}
856
857/* We don't use ALL_LDFLAGS because LD_SWITCH_SYSTEM and LD_SWITCH_MACHINE
858 often contain options that have to do with using Emacs's crt0,
859 which are only good with temacs. */
860prefix-args: prefix-args.c $(config_h)
861 $(CC) $(ALL_CFLAGS) $(LDFLAGS) ${srcdir}/prefix-args.c -o prefix-args
862
863/* Don't lose if this was not defined. */
864#ifndef OLDXMENU_OPTIONS
865#define OLDXMENU_OPTIONS
866#endif
867
868/* Don't lose if this was not defined. */
869#ifndef LWLIB_OPTIONS
870#define LWLIB_OPTIONS
871#endif
872
873#if defined (HAVE_X_WINDOWS) && defined (HAVE_X11) && defined (HAVE_MENUS)
874
875/* We use stamp-xmenu with these two deps
876 to both ensure that lwlib gets remade based on its dependencies
877 in its own makefile,
878 and remake temacs if lwlib gets changed by this. */
879stamp-oldxmenu: ${OLDXMENU} ../src/$(OLDXMENU)
880 touch stamp-oldxmenu
881/* Supply an ordering for parallel make. */
882../src/$(OLDXMENU): ${OLDXMENU}
883
884#ifdef USE_X_TOOLKIT
885$(OLDXMENU): really-lwlib
886
887/* Encode the values of these two macros in Make variables,
888 so we can use $(...) to substitute their values within "...". */
889C_SWITCH_MACHINE_1 = C_SWITCH_MACHINE
890C_SWITCH_SYSTEM_1 = C_SWITCH_SYSTEM
891C_SWITCH_SITE_1 = C_SWITCH_SITE
892C_SWITCH_X_SITE_1 = C_SWITCH_X_SITE
893C_SWITCH_X_MACHINE_1 = C_SWITCH_X_MACHINE
894C_SWITCH_X_SYSTEM_1 = C_SWITCH_X_SYSTEM
895really-lwlib:
896 cd ${lwlibdir}; ${MAKE} ${MFLAGS} LWLIB_OPTIONS \
897 CC='${CC}' CFLAGS='${CFLAGS}' MAKE='${MAKE}' \
898 "C_SWITCH_X_SITE=$(C_SWITCH_X_SITE_1)" \
899 "C_SWITCH_X_MACHINE=$(C_SWITCH_X_MACHINE_1)" \
900 "C_SWITCH_X_SYSTEM=$(C_SWITCH_X_SYSTEM_1)" \
901 "C_SWITCH_SITE=$(C_SWITCH_SITE_1)" \
902 "C_SWITCH_MACHINE=$(C_SWITCH_MACHINE_1)" \
903 "C_SWITCH_SYSTEM=$(C_SWITCH_SYSTEM_1)"
904 @true /* make -t should not create really-lwlib. */
905.PHONY: really-lwlib
906#else /* not USE_X_TOOLKIT */
907$(OLDXMENU): really-oldXMenu
908
909/* Encode the values of these two macros in Make variables,
910 so we can use $(...) to substitute their values within "...". */
911C_SWITCH_MACHINE_1 = C_SWITCH_MACHINE
912C_SWITCH_SYSTEM_1 = C_SWITCH_SYSTEM
913C_SWITCH_SITE_1 = C_SWITCH_SITE
914C_SWITCH_X_SITE_1 = C_SWITCH_X_SITE
915C_SWITCH_X_MACHINE_1 = C_SWITCH_X_MACHINE
916C_SWITCH_X_SYSTEM_1 = C_SWITCH_X_SYSTEM
917really-oldXMenu:
918 cd ${oldXMenudir}; ${MAKE} ${MFLAGS} OLDXMENU_OPTIONS \
919 CC='${CC}' CFLAGS='${CFLAGS}' MAKE='${MAKE}' \
920 "C_SWITCH_X_SITE=$(C_SWITCH_X_SITE_1)" \
921 "C_SWITCH_X_MACHINE=$(C_SWITCH_X_MACHINE_1)" \
922 "C_SWITCH_X_SYSTEM=$(C_SWITCH_X_SYSTEM_1)" \
923 "C_SWITCH_SITE=$(C_SWITCH_SITE_1)" \
924 "C_SWITCH_MACHINE=$(C_SWITCH_MACHINE_1)" \
925 "C_SWITCH_SYSTEM=$(C_SWITCH_SYSTEM_1)"
926 @true /* make -t should not create really-oldXMenu. */
927.PHONY: really-oldXMenu
928#endif /* not USE_X_TOOLKIT */
929#else /* not (HAVE_X_WINDOWS && HAVE_X11 && HAVE_MENUS) */
930
931/* We don't really need this, but satisfy the dependency. */
932stamp-oldxmenu:
933 touch stamp-oldxmenu
934#endif /* not (HAVE_X_WINDOWS && HAVE_X11 && HAVE_MENUS) */
935
936../config.status:: epaths.in
937 @echo "The file epaths.h needs to be set up from epaths.in."
938 @echo "Please run the `configure' script again."
939 exit 1
940
941../config.status:: config.in
942 @echo "The file config.h needs to be set up from config.in."
943 @echo "Please run the `configure' script again."
944 exit 1
945
946/* Some machines have alloca built-in.
947 They should define HAVE_ALLOCA, or may just let alloca.s
948 be used but generate no code.
949 Some have it written in assembler in alloca.s.
950 Some use the C version in alloca.c (these define C_ALLOCA in config.h).
951 */
952
953#ifdef C_ALLOCA
954/* We could put something in alloca.c to #define free and malloc
955 whenever emacs was #defined, but that's not appropriate for all
956 users of alloca in Emacs. Check out ../lib-src/getopt.c. */
957alloca.o : alloca.c
958 $(CC) -c $(CPPFLAGS) -DEMACS_FREE=xfree \
959 $(ALL_CFLAGS) ${srcdir}/alloca.c
960#else
961#ifndef HAVE_ALLOCA
962alloca.o : alloca.s $(config_h)
963/* $(CPP) is cc -E, which may get confused by filenames
964 that do not end in .c. So copy file to a safe name. */
965 -rm -f allocatem.c
966 cp ${srcdir}/alloca.s allocatem.c
967/* Remove any ^L, blank lines, and preprocessor comments,
968 since some assemblers barf on them. Use a different basename for the
969 output file, since some stupid compilers (Green Hill's) use that
970 name for the intermediate assembler file. */
971 $(CPP) $(CPPFLAGS) $(ALL_CFLAGS) allocatem.c | \
972 sed -e 's/ //' -e 's/^#.*//' | \
973 sed -n -e '/^..*$$/p' > allocax.s
974 -rm -f alloca.o
975/* Xenix, in particular, needs to run assembler via cc. */
976 $(CC) -c allocax.s
977 mv allocax.o alloca.o
978 -rm -f allocax.s allocatem.c
979#endif /* HAVE_ALLOCA */
980#endif /* ! defined (C_ALLOCA) */
981
982/* Nearly all the following files depend on lisp.h,
983 but it is not included as a dependency because
984 it is so often changed in ways that do not require any recompilation
985 and so rarely changed in ways that do require any. */
986
987abbrev.o: abbrev.c buffer.h window.h dispextern.h commands.h charset.h \
988 $(config_h)
989buffer.o: buffer.c buffer.h region-cache.h commands.h window.h \
990 dispextern.h $(INTERVAL_SRC) blockinput.h atimer.h systime.h charset.h \
991 $(config_h)
992callint.o: callint.c window.h commands.h buffer.h mocklisp.h \
993 keyboard.h dispextern.h $(config_h)
994callproc.o: callproc.c epaths.h buffer.h commands.h $(config_h) \
995 process.h systty.h syssignal.h charset.h coding.h ccl.h msdos.h \
996 composite.h
997casefiddle.o: casefiddle.c syntax.h commands.h buffer.h composite.h $(config_h)
998casetab.o: casetab.c buffer.h $(config_h)
999category.o: category.c category.h buffer.h charset.h $(config_h)
1000ccl.o: ccl.c ccl.h charset.h coding.h $(config_h)
1001charset.o: charset.c charset.h buffer.h coding.h composite.h disptab.h \
1002 $(config_h)
1003coding.o: coding.c coding.h ccl.h buffer.h charset.h $(config_h)
1004cm.o: cm.c cm.h termhooks.h $(config_h)
1005cmds.o: cmds.c syntax.h buffer.h charset.h commands.h window.h $(config_h) \
1006 msdos.h dispextern.h
1007pre-crt0.o: pre-crt0.c
1008ecrt0.o: ecrt0.c $(config_h)
1009 CRT0_COMPILE ${srcdir}/ecrt0.c
1010dired.o: dired.c commands.h buffer.h $(config_h) charset.h coding.h regex.h \
1011 systime.h
1012dispnew.o: dispnew.c commands.h frame.h window.h buffer.h dispextern.h \
1013 termchar.h termopts.h termhooks.h cm.h disptab.h systty.h systime.h \
1014 xterm.h blockinput.h atimer.h charset.h msdos.h composite.h keyboard.h \
1015 $(config_h)
1016doc.o: doc.c $(config_h) epaths.h buffer.h keyboard.h charset.h
1017doprnt.o: doprnt.c charset.h $(config_h)
1018dosfns.o: buffer.h termchar.h termhooks.h frame.h msdos.h dosfns.h $(config_h)
1019editfns.o: editfns.c window.h buffer.h systime.h $(INTERVAL_SRC) charset.h \
1020 coding.h dispextern.h $(config_h)
1021emacs.o: emacs.c commands.h systty.h syssignal.h blockinput.h process.h \
1022 termhooks.h buffer.h atimer.h systime.h $(INTERVAL_SRC) $(config_h)
1023fileio.o: fileio.c window.h buffer.h systime.h $(INTERVAL_SRC) charset.h \
1024 coding.h ccl.h msdos.h dispextern.h $(config_h)
1025filelock.o: filelock.c buffer.h systime.h epaths.h $(config_h)
1026filemode.o: filemode.c $(config_h)
1027frame.o: frame.c xterm.h window.h frame.h termhooks.h commands.h keyboard.h \
1028 buffer.h charset.h fontset.h msdos.h dosfns.h dispextern.h $(config_h)
1029fontset.o: dispextern.h fontset.h fontset.c ccl.h charset.h frame.h \
1030 keyboard.h $(config_h)
1031getloadavg.o: getloadavg.c $(config_h)
1032indent.o: indent.c frame.h window.h indent.h buffer.h $(config_h) termchar.h \
1033 termopts.h disptab.h region-cache.h charset.h composite.h dispextern.h \
1034 keyboard.h
1035insdel.o: insdel.c window.h buffer.h $(INTERVAL_SRC) blockinput.h charset.h\
1036 dispextern.h atimer.h systime.h $(config_h)
1037keyboard.o: keyboard.c termchar.h termhooks.h termopts.h buffer.h charset.h \
1038 commands.h frame.h window.h macros.h disptab.h keyboard.h syssignal.h \
1039 systty.h systime.h dispextern.h syntax.h $(INTERVAL_SRC) blockinput.h \
1040 atimer.h xterm.h puresize.h msdos.h $(config_h)
1041keymap.o: keymap.c buffer.h commands.h keyboard.h termhooks.h blockinput.h \
1042 atimer.h systime.h puresize.h charset.h intervals.h $(config_h)
1043lastfile.o: lastfile.c $(config_h)
1044macros.o: macros.c window.h buffer.h commands.h macros.h keyboard.h \
1045 dispextern.h $(config_h)
1046malloc.o: malloc.c $(config_h)
1047gmalloc.o: gmalloc.c $(config_h)
1048ralloc.o: ralloc.c $(config_h)
1049vm-limit.o: vm-limit.c mem-limits.h $(config_h)
1050marker.o: marker.c buffer.h charset.h $(config_h)
1051minibuf.o: minibuf.c syntax.h dispextern.h frame.h window.h keyboard.h \
1052 buffer.h commands.h charset.h msdos.h $(config_h)
1053mktime.o: mktime.c $(config_h)
1054mocklisp.o: mocklisp.c buffer.h $(config_h)
1055msdos.o: msdos.c msdos.h dosfns.h systime.h termhooks.h dispextern.h frame.h \
1056 termopts.h termchar.h charset.h coding.h ccl.h disptab.h window.h \
1057 keyboard.h $(config_h)
1058process.o: process.c process.h buffer.h window.h termhooks.h termopts.h \
1059 commands.h syssignal.h systime.h systty.h syswait.h frame.h dispextern.h \
1060 blockinput.h atimer.h charset.h coding.h ccl.h msdos.h composite.h \
1061 keyboard.h $(config_h)
1062regex.o: regex.c syntax.h buffer.h $(config_h) regex.h category.h charset.h
1063region-cache.o: region-cache.c buffer.h region-cache.h
1064scroll.o: scroll.c termchar.h dispextern.h frame.h msdos.h keyboard.h \
1065 $(config_h)
1066search.o: search.c regex.h commands.h buffer.h region-cache.h syntax.h \
1067 blockinput.h atimer.h systime.h category.h charset.h composite.h $(config_h)
1068strftime.o: strftime.c $(config_h)
1069syntax.o: syntax.c syntax.h buffer.h commands.h category.h charset.h \
1070 composite.h $(config_h)
1071sysdep.o: sysdep.c $(config_h) dispextern.h termhooks.h termchar.h termopts.h \
1072 frame.h syssignal.h systty.h systime.h syswait.h blockinput.h atimer.h \
1073 window.h msdos.h dosfns.h keyboard.h
1074term.o: term.c termchar.h termhooks.h termopts.h $(config_h) cm.h frame.h \
1075 disptab.h dispextern.h keyboard.h charset.h coding.h ccl.h msdos.h
1076termcap.o: termcap.c $(config_h)
1077terminfo.o: terminfo.c $(config_h)
1078tparam.o: tparam.c $(config_h)
1079undo.o: undo.c buffer.h commands.h $(config_h)
1080/* This hack is to discard any space that cpp might put at the beginning
1081 of UNEXEC when substituting it in. */
1082UNEXEC_ALIAS=UNEXEC
1083$(UNEXEC_ALIAS): UNEXEC_SRC $(config_h)
1084w16select.o: w16select.c dispextern.h frame.h blockinput.h atimer.h systime.h \
1085 msdos.h $(config_h)
1086widget.o: widget.c xterm.h frame.h dispextern.h widgetprv.h \
1087 $(srcdir)/../lwlib/lwlib.h $(config_h)
1088window.o: window.c indent.h commands.h frame.h window.h buffer.h termchar.h \
1089 termhooks.h disptab.h keyboard.h dispextern.h msdos.h composite.h \
1090 $(config_h)
1091xdisp.o: xdisp.c macros.h commands.h indent.h buffer.h dispextern.h coding.h \
1092 termchar.h frame.h window.h disptab.h termhooks.h charset.h $(config_h) \
1093 msdos.h composite.h fontset.h
1094xfaces.o: xfaces.c dispextern.h frame.h xterm.h buffer.h blockinput.h \
1095 window.h charset.h msdos.h dosfns.h composite.h atimer.h systime.h $(config_h)
1096xfns.o: xfns.c buffer.h frame.h window.h keyboard.h xterm.h dispextern.h \
1097 $(srcdir)/../lwlib/lwlib.h blockinput.h atimer.h systime.h epaths.h \
1098 charset.h $(config_h)
1099xmenu.o: xmenu.c xterm.h termhooks.h window.h dispextern.h frame.h keyboard.h \
1100 $(srcdir)/../lwlib/lwlib.h blockinput.h atimer.h systime.h msdos.h \
1101 $(config_h)
1102xterm.o: xterm.c xterm.h termhooks.h termopts.h termchar.h window.h \
1103 dispextern.h frame.h disptab.h blockinput.h atimer.h systime.h syssignal.h \
1104 keyboard.h gnu.h sink.h sinkmask.h charset.h ccl.h fontset.h composite.h \
1105 coding.h $(config_h)
1106xselect.o: xselect.c dispextern.h frame.h xterm.h blockinput.h charset.h \
1107 coding.h ccl.h buffer.h atimer.h systime.h $(config_h)
1108xrdb.o: xrdb.c $(config_h) epaths.h
1109hftctl.o: hftctl.c $(config_h)
1110sound.o: sound.c dispextern.h $(config_h)
1111atimer.o: atimer.c atimer.h systime.h $(config_h)
1112
1113/* The files of Lisp proper */
1114
1115alloc.o: alloc.c frame.h window.h buffer.h puresize.h syssignal.h keyboard.h \
1116 blockinput.h atimer.h systime.h charset.h dispextern.h $(config_h) $(INTERVAL_SRC)
1117bytecode.o: bytecode.c buffer.h syntax.h charset.h $(config_h)
1118data.o: data.c buffer.h puresize.h charset.h syssignal.h keyboard.h $(config_h)
1119eval.o: eval.c commands.h keyboard.h blockinput.h atimer.h systime.h \
1120 $(config_h)
1121floatfns.o: floatfns.c $(config_h)
1122fns.o: fns.c commands.h $(config_h) frame.h buffer.h charset.h keyboard.h \
1123 frame.h window.h dispextern.h $(INTERVAL_SRC)
1124print.o: print.c process.h frame.h window.h buffer.h keyboard.h charset.h\
1125 $(config_h) dispextern.h msdos.h composite.h
1126lread.o: lread.c commands.h keyboard.h buffer.h epaths.h charset.h $(config_h) \
1127 termhooks.h msdos.h
1128
1129/* Text properties support */
1130textprop.o: textprop.c buffer.h window.h dispextern.h $(INTERVAL_SRC) \
1131 $(config_h)
1132intervals.o: intervals.c buffer.h $(INTERVAL_SRC) keyboard.h puresize.h $(config_h)
1133composite.o: composite.c buffer.h charset.h $(INTERVAL_SRC) $(config_h)
1134
1135/* System-specific programs to be made.
1136 OTHER_FILES and OBJECTS_MACHINE
1137 select which of these should be compiled. */
1138
1139sunfns.o: sunfns.c buffer.h window.h dispextern.h $(config_h)
1140
1141${libsrc}emacstool: ${libsrc}emacstool.c
1142 cd ${libsrc}; ${MAKE} ${MFLAGS} emacstool
1143mostlyclean:
1144 rm -f temacs prefix-args core *.core \#* *.o libXMenu11.a liblw.a
1145 rm -f ../etc/DOC
1146clean: mostlyclean
1147 rm -f emacs-* emacs bootstrap-emacs
1148/**/# This is used in making a distribution.
1149/**/# Do not use it on development directories!
1150distclean: clean
1151 rm -f epaths.h config.h Makefile Makefile.c config.stamp stamp-oldxmenu ../etc/DOC-*
1152maintainer-clean: distclean
1153 @echo "This command is intended for maintainers to use;"
1154 @echo "it deletes files that may require special tools to rebuild."
1155 rm -f TAGS
1156versionclean:
1157 -rm -f emacs emacs-* ../etc/DOC*
1158extraclean: distclean
1159 -rm -f *~ \#* m/?*~ s/?*~
1160
1161/* The rule for the [sm] files has to be written a little funny to
1162 avoid looking like a C comment to CPP. */
1163SOURCES = *.[ch] [sm]/?* COPYING Makefile.in \
1164 config.in epaths.in README COPYING ChangeLog vms.pp-trans
1165unlock:
1166 chmod u+w $(SOURCES)
1167
1168relock:
1169 chmod -w $(SOURCES)
1170 chmod +w epaths.h
1171
1172/* Arrange to make a tags table TAGS-LISP for ../lisp,
1173 plus TAGS for the C files, which includes ../lisp/TAGS by reference. */
1174
1175ctagsfiles1 = [xyzXYZ]*.[hc]
1176ctagsfiles2 = [a-wA-W]*.[hc]
1177
1178TAGS: $(srcdir)/$(ctagsfiles1) $(srcdir)/$(ctagsfiles2)
1179 ../lib-src/etags --include=TAGS-LISP --include=${lwlibdir}/TAGS \
1180 --regex='/[ ]*DEFVAR_[A-Z_ (]+"\([^"]+\)"/' \
1181 $(srcdir)/$(ctagsfiles1) $(srcdir)/$(ctagsfiles2)
1182frc:
1183TAGS-LISP: frc
1184 $(MAKE) -f ${lispsource}Makefile TAGS-LISP ETAGS=../lib-src/etags
1185
1186$(lwlibdir)TAGS:
1187 (cd $(lwlibdir); $(MAKE) -f $(lwlibdir)Makefile tags ETAGS=../lib-src/etags)
1188
1189tags: TAGS TAGS-LISP $(lwlibdir)TAGS
1190.PHONY: tags
1191
1192
1193/* Bootstrapping. */
1194
1195bootstrap: bootstrap-emacs
1196
1197/* Build a temacs with a sufficiently large PURESIZE to load the
1198 Lisp files from loadup.el in source form. */
1199
1200bootstrap-temacs:
1201 LC_ALL=C $(MAKE) $(MFLAGS) temacs ALL_CFLAGS="$(ALL_CFLAGS) -DPURESIZE=5000000 -I../src"
1202
1203/* Build a DOC file. */
1204
1205bootstrap-doc: ${libsrc}make-docfile
1206 -rm -f ${etc}DOC
1207 els=`echo ${shortlisp} ${SOME_MACHINE_LISP} \
1208 | sed -e "s/\\.elc/.el/g"`; \
1209 ${libsrc}make-docfile -d ${srcdir} $$els ${obj} > ${etc}DOC
1210
1211/* Dump an Emacs executable named bootstrap-emacs containing the
1212 files from loadup.el in source form. */
1213
1214bootstrap-emacs: bootstrap-temacs bootstrap-doc
1215#ifdef CANNOT_DUMP
1216 ln temacs bootstrap-emacs
1217#else
1218#ifdef HAVE_SHM
1219 ./temacs -nl -batch -l loadup bootstrap
1220#else /* ! defined (HAVE_SHM) */
1221 ./temacs --batch --load loadup bootstrap
1222#endif /* ! defined (HAVE_SHM) */
1223#endif /* ! defined (CANNOT_DUMP) */
1224 mv -f emacs bootstrap-emacs
1225 rm -f temacs
1226
diff --git a/src/XTests.c b/src/XTests.c
deleted file mode 100644
index 4147ecd35d6..00000000000
--- a/src/XTests.c
+++ /dev/null
@@ -1,179 +0,0 @@
1#include <X11/Xlib.h>
2#include <X11/X.h>
3#include <X11/Xutil.h>
4#include <X11/Xresource.h>
5#include "XTests.h"
6#include <stdio.h>
7
8static Display *dpy;
9
10static void
11quit (dpy)
12 Display *dpy;
13{
14 XCloseDisplay (dpy);
15 exit (0);
16}
17
18static Colormap screen_colormap;
19
20static unsigned long
21obtain_color (color)
22 char *color;
23{
24 int exists;
25 XColor color_def;
26
27 if (!screen_colormap)
28 screen_colormap = DefaultColormap (dpy, DefaultScreen (dpy));
29
30 exists = XParseColor (dpy, screen_colormap, color, &color_def)
31 && XAllocColor (dpy, screen_colormap, &color_def);
32 if (exists)
33 return color_def.pixel;
34
35 fprintf (stderr, "Can't get color; using black.");
36 return BlackPixel (dpy, DefaultScreen (dpy));
37}
38
39static char *visual_strings[] =
40{
41 "StaticGray ",
42 "GrayScale ",
43 "StaticColor",
44 "PseudoColor",
45 "TrueColor ",
46 "DirectColor"
47};
48
49main (argc,argv)
50 int argc;
51 char *argv[];
52{
53 char *dpy_string;
54 int n;
55 long mask;
56 Visual *my_visual;
57 XVisualInfo *vinfo, visual_template;
58 XEvent event;
59 Window window;
60 Screen *scr;
61 XGCValues gc_values;
62 GC fill_gc, pix_gc, line_xor_gc, line_xor_inv_gc;
63 int i;
64 int x, y, width, height, geometry, gravity;
65 char *geo;
66 char default_geo[] = "80x40+0+0";
67 int depth;
68 Pixmap pix;
69 char *string = "Kill the head and the body will die.";
70 char dash_list[] = {4, 4};
71 int dashes = 2;
72
73 if (argc < 2)
74 dpy_string = "localhost:0.0";
75 else
76 dpy_string = argv[1];
77
78 if (argc >= 3)
79 {
80 XSizeHints hints;
81
82 printf ("Geometry: %s\t(default: %s)\n", argv[2], default_geo);
83 geo = argv[2];
84 XWMGeometry (dpy, DefaultScreen (dpy), geo, default_geo,
85 3, &hints, &x, &y, &width, &height, &gravity);
86 }
87
88 dpy = XOpenDisplay (dpy_string);
89 if (!dpy)
90 {
91 printf ("Can' open display %s\n", dpy_string);
92 exit (1);
93 }
94
95 window = XCreateSimpleWindow (dpy, DefaultRootWindow (dpy),
96 300, 300, 300, 300, 1,
97 BlackPixel (dpy, DefaultScreen (dpy)),
98 WhitePixel (dpy, DefaultScreen (dpy)));
99 XSelectInput (dpy, window, ButtonPressMask | KeyPressMask
100 | EnterWindowMask | LeaveWindowMask);
101
102 gc_values.foreground = obtain_color ("blue");
103 gc_values.background = WhitePixel (dpy, DefaultScreen (dpy));
104 fill_gc = XCreateGC (dpy, window, GCForeground | GCBackground,
105 &gc_values);
106
107 gc_values.foreground = obtain_color ("red");
108 gc_values.line_width = 3;
109 gc_values.line_style = LineOnOffDash;
110 gc_values.cap_style = CapRound;
111 gc_values.join_style = JoinRound;
112 line_xor_gc = XCreateGC (dpy, window,
113 GCForeground | GCBackground | GCLineStyle
114 | GCJoinStyle | GCCapStyle | GCLineWidth,
115 &gc_values);
116 XSetDashes (dpy, line_xor_gc, 0, dash_list, dashes);
117
118 line_xor_inv_gc = XCreateGC (dpy, window,
119 GCForeground | GCBackground | GCLineWidth,
120 &gc_values);
121
122 depth = DefaultDepthOfScreen (ScreenOfDisplay (dpy, DefaultScreen (dpy)));
123 pix = XCreateBitmapFromData (dpy, window, page_glyf_bits,
124 page_glyf_width, page_glyf_height);
125
126 XMapWindow (dpy, window);
127 XFlush (dpy);
128
129 while (1)
130 {
131 XNextEvent (dpy, &event);
132 switch (event.type)
133 {
134 case ButtonPress:
135 switch (event.xbutton.button)
136 {
137 case Button1:
138 XDrawLine (dpy, window, line_xor_gc, 25, 75, 300, 75);
139 break;
140
141 case Button2:
142 XDrawLine (dpy, window, line_xor_inv_gc, 25, 25, 300, 25);
143 break;
144
145 case Button3:
146 XDrawLine (dpy, window, line_xor_gc, 25, 25, 25, 125);
147 break;
148 }
149 break;
150
151 case KeyPress:
152 {
153 char buf[20];
154 int n;
155 XComposeStatus status;
156 KeySym keysym;
157
158 n = XLookupString (&event, buf, 20, &keysym,
159 (XComposeStatus *) &status);
160
161 if (n == 1 && buf[0] == 'q')
162 quit (dpy);
163 }
164 break;
165
166 case EnterNotify:
167 XCopyPlane (dpy, pix, window, fill_gc, 0, 0,
168 page_glyf_width, page_glyf_height, 100, 100, 1L);
169 XFillRectangle (dpy, window, fill_gc, 50, 50, 50, 50);
170 break;
171
172 case LeaveNotify:
173 XClearWindow (dpy, window);
174 break;
175 }
176
177 XFlush (dpy);
178 }
179}
diff --git a/src/XTests.h b/src/XTests.h
deleted file mode 100644
index e91445af7ef..00000000000
--- a/src/XTests.h
+++ /dev/null
@@ -1,7 +0,0 @@
1#define page_glyf_width 30
2#define page_glyf_height 10
3static char page_glyf_bits[] = {
4 0xf0, 0xff, 0xff, 0x03, 0x08, 0x00, 0x00, 0x04, 0xc4, 0x19, 0xf3, 0x08,
5 0x42, 0xa5, 0x14, 0x10, 0xc1, 0xa5, 0x70, 0x20, 0x41, 0xbc, 0x16, 0x20,
6 0x42, 0xa4, 0x14, 0x10, 0x44, 0x24, 0xf3, 0x08, 0x08, 0x00, 0x00, 0x04,
7 0xf0, 0xff, 0xff, 0x03};
diff --git a/src/convexos.h b/src/convexos.h
deleted file mode 100644
index 94cdbf68346..00000000000
--- a/src/convexos.h
+++ /dev/null
@@ -1,10 +0,0 @@
1/* Definitions file for GNU Emacs running on ConvexOS. */
2
3#include "bsd4-3.h"
4
5/* First pty name is /dev/pty?0. We have to search for it. */
6#undef FIRST_PTY_LETTER
7#define FIRST_PTY_LETTER first_pty_letter
8
9/* getpgrp requires no arguments. */
10#define GETPGRP_NO_ARG
diff --git a/src/environ.c b/src/environ.c
deleted file mode 100644
index 863f40ccd2a..00000000000
--- a/src/environ.c
+++ /dev/null
@@ -1,316 +0,0 @@
1/* Environment-hacking for GNU Emacs subprocess
2 Copyright (C) 1986 Free Software Foundation, Inc.
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 1, or (at your option)
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21#include "config.h"
22#include "lisp.h"
23
24#ifdef MAINTAIN_ENVIRONMENT
25
26#ifdef VMS
27you lose -- this is un*x-only
28#endif
29
30/* alist of (name-string . value-string) */
31Lisp_Object Venvironment_alist;
32extern char **environ;
33
34void
35set_environment_alist (str, val)
36 register Lisp_Object str, val;
37{
38 register Lisp_Object tem;
39
40 tem = Fassoc (str, Venvironment_alist);
41 if (NULL (tem))
42 if (NULL (val))
43 ;
44 else
45 Venvironment_alist = Fcons (Fcons (str, val), Venvironment_alist);
46 else
47 if (NULL (val))
48 Venvironment_alist = Fdelq (tem, Venvironment_alist);
49 else
50 XCONS (tem)->cdr = val;
51}
52
53
54
55static void
56initialize_environment_alist ()
57{
58 register unsigned char **e, *s;
59 extern char *index ();
60
61 for (e = (unsigned char **) environ; *e; e++)
62 {
63 s = (unsigned char *) index (*e, '=');
64 if (s)
65 set_environment_alist (make_string (*e, s - *e),
66 build_string (s + 1));
67 }
68}
69
70
71unsigned char *
72getenv_1 (str, ephemeral)
73 register unsigned char *str;
74 int ephemeral; /* if ephmeral, don't need to gc-proof */
75{
76 register Lisp_Object env;
77 int len = strlen (str);
78
79 for (env = Venvironment_alist; CONSP (env); env = XCONS (env)->cdr)
80 {
81 register Lisp_Object car = XCONS (env)->car;
82 register Lisp_Object tem = XCONS (car)->car;
83
84 if ((len == XSTRING (tem)->size) &&
85 (!bcmp (str, XSTRING (tem)->data, len)))
86 {
87 /* Found it in the lisp environment */
88 tem = XCONS (car)->cdr;
89 if (ephemeral)
90 /* Caller promises that gc won't make him lose */
91 return XSTRING (tem)->data;
92 else
93 {
94 register unsigned char **e;
95 unsigned char *s;
96 int ll = XSTRING (tem)->size;
97
98 /* Look for element in the original unix environment */
99 for (e = (unsigned char **) environ; *e; e++)
100 if (!bcmp (str, *e, len) && *(*e + len) == '=')
101 {
102 s = *e + len + 1;
103 if (strlen (s) >= ll)
104 /* User hasn't either hasn't munged it or has set it
105 to something shorter -- we don't have to cons */
106 goto copy;
107 else
108 goto cons;
109 };
110 cons:
111 /* User has setenv'ed it to a diferent value, and our caller
112 isn't guaranteeing that he won't stash it away somewhere.
113 We can't just return a pointer to the lisp string, as that
114 will be corrupted when gc happens. So, we cons (in such
115 a way that it can't be freed -- though this isn't such a
116 problem since the only callers of getenv (as opposed to
117 those of egetenv) are very early, before the user -could-
118 have frobbed the environment. */
119 s = (unsigned char *) xmalloc (ll + 1);
120 copy:
121 bcopy (XSTRING (tem)->data, s, ll + 1);
122 return (s);
123 }
124 }
125 }
126 return ((unsigned char *) 0);
127}
128
129/* unsigned -- stupid delcaration in lisp.h */ char *
130getenv (str)
131 register unsigned char *str;
132{
133 return ((char *) getenv_1 (str, 0));
134}
135
136unsigned char *
137egetenv (str)
138 register unsigned char *str;
139{
140 return (getenv_1 (str, 1));
141}
142
143
144#if (1 == 1) /* use caller-alloca versions, rather than callee-malloc */
145int
146size_of_current_environ ()
147{
148 register int size;
149 Lisp_Object tem;
150
151 tem = Flength (Venvironment_alist);
152
153 size = (XINT (tem) + 1) * sizeof (unsigned char *);
154 /* + 1 for environment-terminating 0 */
155
156 for (tem = Venvironment_alist; !NULL (tem); tem = XCONS (tem)->cdr)
157 {
158 register Lisp_Object str, val;
159
160 str = XCONS (XCONS (tem)->car)->car;
161 val = XCONS (XCONS (tem)->car)->cdr;
162
163 size += (XSTRING (str)->size +
164 XSTRING (val)->size +
165 2); /* 1 for '=', 1 for '\000' */
166 }
167 return size;
168}
169
170void
171get_current_environ (memory_block)
172 unsigned char **memory_block;
173{
174 register unsigned char **e, *s;
175 register int len;
176 register Lisp_Object tem;
177
178 e = memory_block;
179
180 tem = Flength (Venvironment_alist);
181
182 s = (unsigned char *) memory_block
183 + (XINT (tem) + 1) * sizeof (unsigned char *);
184
185 for (tem = Venvironment_alist; !NULL (tem); tem = XCONS (tem)->cdr)
186 {
187 register Lisp_Object str, val;
188
189 str = XCONS (XCONS (tem)->car)->car;
190 val = XCONS (XCONS (tem)->car)->cdr;
191
192 *e++ = s;
193 len = XSTRING (str)->size;
194 bcopy (XSTRING (str)->data, s, len);
195 s += len;
196 *s++ = '=';
197 len = XSTRING (val)->size;
198 bcopy (XSTRING (val)->data, s, len);
199 s += len;
200 *s++ = '\000';
201 }
202 *e = 0;
203}
204
205#else
206/* dead code (this function mallocs, caller frees) superseded by above (which allows caller to use alloca) */
207unsigned char **
208current_environ ()
209{
210 unsigned char **env;
211 register unsigned char **e, *s;
212 register int len, env_len;
213 Lisp_Object tem;
214 Lisp_Object str, val;
215
216 tem = Flength (Venvironment_alist);
217
218 env_len = (XINT (tem) + 1) * sizeof (char *);
219 /* + 1 for terminating 0 */
220
221 len = 0;
222 for (tem = Venvironment_alist; !NULL (tem); tem = XCONS (tem)->cdr)
223 {
224 str = XCONS (XCONS (tem)->car)->car;
225 val = XCONS (XCONS (tem)->car)->cdr;
226
227 len += (XSTRING (str)->size +
228 XSTRING (val)->size +
229 2);
230 }
231
232 e = env = (unsigned char **) xmalloc (env_len + len);
233 s = (unsigned char *) env + env_len;
234
235 for (tem = Venvironment_alist; !NULL (tem); tem = XCONS (tem)->cdr)
236 {
237 str = XCONS (XCONS (tem)->car)->car;
238 val = XCONS (XCONS (tem)->car)->cdr;
239
240 *e++ = s;
241 len = XSTRING (str)->size;
242 bcopy (XSTRING (str)->data, s, len);
243 s += len;
244 *s++ = '=';
245 len = XSTRING (val)->size;
246 bcopy (XSTRING (val)->data, s, len);
247 s += len;
248 *s++ = '\000';
249 }
250 *e = 0;
251
252 return env;
253}
254
255#endif /* dead code */
256
257
258DEFUN ("getenv", Fgetenv, Sgetenv, 1, 2, "sEnvironment variable: \np",
259 "Return the value of environment variable VAR, as a string.\n\
260When invoked interactively, print the value in the echo area.\n\
261VAR is a string, the name of the variable,\n\
262 or the symbol t, meaning to return an alist representing the\n\
263 current environment.")
264 (str, interactivep)
265 Lisp_Object str, interactivep;
266{
267 Lisp_Object val;
268
269 if (str == Qt) /* If arg is t, return whole environment */
270 return (Fcopy_alist (Venvironment_alist));
271
272 CHECK_STRING (str, 0);
273 val = Fcdr (Fassoc (str, Venvironment_alist));
274 if (!NULL (interactivep))
275 {
276 if (NULL (val))
277 message ("%s not defined in environment", XSTRING (str)->data);
278 else
279 message ("\"%s\"", XSTRING (val)->data);
280 }
281 return val;
282}
283
284DEFUN ("setenv", Fsetenv, Ssetenv, 1, 2,
285 "sEnvironment variable: \nsSet %s to value: ",
286 "Set the value of environment variable VAR to VALUE.\n\
287Both args must be strings. Returns VALUE.")
288 (str, val)
289 Lisp_Object str;
290 Lisp_Object val;
291{
292 Lisp_Object tem;
293
294 CHECK_STRING (str, 0);
295 if (!NULL (val))
296 CHECK_STRING (val, 0);
297
298 set_environment_alist (str, val);
299 return val;
300}
301
302
303syms_of_environ ()
304{
305 staticpro (&Venvironment_alist);
306 defsubr (&Ssetenv);
307 defsubr (&Sgetenv);
308}
309
310init_environ ()
311{
312 Venvironment_alist = Qnil;
313 initialize_environment_alist ();
314}
315
316#endif /* MAINTAIN_ENVIRONMENT */
diff --git a/src/m/dos386.h b/src/m/dos386.h
deleted file mode 100644
index 1fb38da656f..00000000000
--- a/src/m/dos386.h
+++ /dev/null
@@ -1,115 +0,0 @@
1/* Machine description file for MS-DOS
2
3 Copyright (C) 1993 Free Software Foundation, Inc.
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs; see the file COPYING. If not, write to
19the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21/* Note: lots of stuff here was taken from m-dos386.h in demacs. */
22
23
24/* The following three symbols give information on
25 the size of various data types. */
26
27#define SHORTBITS 16 /* Number of bits in a short */
28#define INTBITS 32 /* Number of bits in an int */
29#define LONGBITS 32 /* Number of bits in a long */
30
31/* Define BIG_ENDIAN iff lowest-numbered byte in a word
32 is the most significant byte. */
33
34/* #define BIG_ENDIAN */
35
36/* Define NO_ARG_ARRAY if you cannot take the address of the first of a
37 * group of arguments and treat it as an array of the arguments. */
38
39/* #define NO_ARG_ARRAY */
40
41/* Define WORD_MACHINE if addresses and such have
42 * to be corrected before they can be used as byte counts. */
43
44/* #define WORD_MACHINE */
45
46/* Define how to take a char and sign-extend into an int.
47 On machines where char is signed, this is a no-op. */
48
49#define SIGN_EXTEND_CHAR(c) (c)
50
51/* Now define a symbol for the cpu type, if your compiler
52 does not define it automatically:
53 Ones defined so far include vax, m68000, ns16000, pyramid,
54 orion, tahoe, APOLLO and many others */
55
56#define INTEL386
57
58/* Use type int rather than a union, to represent Lisp_Object */
59/* This is desirable for most machines. */
60
61#define NO_UNION_TYPE
62
63/* Define EXPLICIT_SIGN_EXTEND if XINT must explicitly sign-extend
64 the 24-bit bit field into an int. In other words, if bit fields
65 are always unsigned.
66
67 If you use NO_UNION_TYPE, this flag does not matter. */
68
69#define EXPLICIT_SIGN_EXTEND
70
71/* Data type of load average, as read out of kmem. */
72
73/* #define LOAD_AVE_TYPE long */
74
75/* Convert that into an integer that is 100 for a load average of 1.0 */
76
77/* #define LOAD_AVE_CVT(x) (int) (((double) (x)) * 100.0 / FSCALE) */
78
79/* Define CANNOT_DUMP on machines where unexec does not work.
80 Then the function dump-emacs will not be defined
81 and temacs will do (load "loadup") automatically unless told otherwise. */
82
83/* #define CANNOT_DUMP */
84
85/* Define VIRT_ADDR_VARIES if the virtual addresses of
86 pure and impure space as loaded can vary, and even their
87 relative order cannot be relied on.
88
89 Otherwise Emacs assumes that text space precedes data space,
90 numerically. */
91
92/* #define VIRT_ADDR_VARIES */
93
94/* Define C_ALLOCA if this machine does not support a true alloca
95 and the one written in C should be used instead.
96 Define HAVE_ALLOCA to say that the system provides a properly
97 working alloca function and it should be used.
98 Define neither one if an assembler-language alloca
99 in the file alloca.s should be used. */
100
101#define HAVE_ALLOCA
102#define alloca(x) __builtin_alloca(x)
103
104/* Define NO_REMAP if memory segmentation makes it not work well
105 to change the boundary between the text section and data section
106 when Emacs is dumped. If you define this, the preloaded Lisp
107 code will not be sharable; but that's better than failing completely. */
108
109#define NO_REMAP
110
111/* We need a little extra space, see ../../lisp/loadup.el */
112#define PURESIZE 240000
113
114/* We have (the code to control) a mouse. */
115#define HAVE_MOUSE
diff --git a/src/mach2.h b/src/mach2.h
deleted file mode 100644
index c941c5ff2cf..00000000000
--- a/src/mach2.h
+++ /dev/null
@@ -1,48 +0,0 @@
1/* Definitions for Emacs running on Mach version 2 (non-kernelized system).
2 Copyright (C) 1990 Free Software Foundation, Inc.
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20#include "bsd4-3.h"
21
22/* SYSTEM_TYPE should indicate the kind of system you are using.
23 It sets the Lisp variable system-type. We'll need to undo the bsd one. */
24
25#undef SYSTEM_TYPE
26#define SYSTEM_TYPE "next-mach"
27
28#define LD_SWITCH_SYSTEM -X -noseglinkedit
29
30/* Don't use -lc on the NeXT. */
31#define LIB_STANDARD -lsys_s
32#define LIB_MATH -lm
33
34#define environ _environ
35
36#define START_FILES pre-crt0.o
37#define UNEXEC unexnext.o
38
39/* start_of_text isn't actually used, so make it compile without error. */
40#define TEXT_START 0
41/* This seems to be right for end_of_text, but it may not be used anyway. */
42#define TEXT_END get_etext ()
43/* This seems to be right for end_of_data, but it may not be used anyway. */
44#define DATA_END get_edata ()
45
46/* Defining KERNEL_FILE causes lossage because sys/file.h
47 stupidly gets confused by it. */
48#undef KERNEL_FILE
diff --git a/src/old-ralloc.c b/src/old-ralloc.c
deleted file mode 100644
index 28562994e9a..00000000000
--- a/src/old-ralloc.c
+++ /dev/null
@@ -1,1069 +0,0 @@
1/* Block-relocating memory allocator.
2 Copyright (C) 1990 Free Software Foundation, Inc.
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 1, or (at your option)
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20/* This package works by allocating blocks from a zone of memory
21 above that used by malloc (). When malloc needs more space that
22 would enter our zone, we relocate blocks upward. The bottom of
23 our zone is kept in the variable `virtual_break_value'. The top
24 of our zone is indicated by `real_break_value'.
25
26 As blocks are freed, a free list is maintained and we attempt
27 to satisfy further requests for space using a first-fit policy.
28 If there are holes, but none fit, memory is compacted and a new
29 block is obtained at the top of the zone.
30
31 NOTE that our blocks are always rounded to page boundaries. */
32
33/*
34 NOTES:
35
36 Once this is stable, I can speed things up by intially leaving a large
37 gap between real_break_value and true_break_value, or maybe making
38 a large hole before the first block.
39
40 If we also kept track of size_wanted, we could gain some
41 extra space upon compactification.
42
43 Perhaps we should just note a hole when malloc does doing sbrk(-n)?
44
45 Relocating downward upon freeing the first block would simplify
46 other things.
47
48 When r_alloc places a block in a hole, we could easily check if there's
49 much more than required, and leave a hole.
50 */
51
52#include "mem_limits.h"
53
54static POINTER r_alloc_sbrk ();
55static POINTER sbrk ();
56static POINTER brk ();
57
58/* Variable `malloc' uses for the function which gets more space
59 from the system. */
60extern POINTER (*__morecore) ();
61
62/* List of variables which point into the associated data block. */
63struct other_pointer
64{
65 POINTER *location;
66 struct other_pointer *next;
67};
68
69/* List describing all the user's pointers to relocatable blocks. */
70typedef struct rel_pointers
71{
72 struct rel_pointers *next;
73 struct rel_pointers *prev;
74 struct other_pointer *others; /* Other variables which use this block. */
75 POINTER *location; /* Location of the block's pointer. */
76 POINTER block; /* Address of the actual data. */
77 int size; /* The size of the block. */
78} relocatable_pointer;
79
80#define REL_NIL ((struct rel_pointers *) 0)
81
82static relocatable_pointer *pointer_list;
83static relocatable_pointer *last_pointer;
84
85#define MAX_HOLES 2
86
87/* Vector of available holes among allocated blocks. This can include
88 a hole at the beginning of the list, but never the end. */
89typedef struct
90{
91 POINTER address;
92 unsigned int size;
93} hole_descriptor;
94
95static hole_descriptor r_alloc_holes[MAX_HOLES];
96
97/* Number of holes currently available. */
98static int holes;
99
100/* The process break value (i.e., curbrk) */
101static POINTER real_break_value;
102
103/* The REAL (i.e., page aligned) break value. */
104static POINTER true_break_value;
105
106/* Address of start of data space in use by relocatable blocks.
107 This is what `malloc' thinks is the process break value. */
108static POINTER virtual_break_value;
109
110/* Nonzero if we have told `malloc' to start using `r_alloc_sbrk'
111 instead of calling `sbrk' directly. */
112int r_alloc_in_use;
113
114#define PAGE (getpagesize ())
115#define ALIGNED(addr) (((unsigned int) (addr) & (PAGE - 1)) == 0)
116#define ROUNDUP(size) (((unsigned int) (size) + PAGE) & ~(PAGE - 1))
117
118/*
119 Level number of warnings already issued.
120 0 -- no warnings issued.
121 1 -- 75% warning already issued.
122 2 -- 85% warning already issued.
123*/
124static int warnlevel;
125
126/* Function to call to issue a warning;
127 0 means don't issue them. */
128static void (*warnfunction) ();
129
130/* Call this to start things off. It determines the current process
131 break value, as well as the `true' break value--because the system
132 allocates memory in page increments, if the break value is not page
133 aligned it means that space up to the next page boundary is actually
134 available. */
135
136void
137malloc_init (start, warn_func)
138 POINTER start;
139 void (*warn_func) ();
140{
141 r_alloc_in_use = 1;
142 __morecore = r_alloc_sbrk;
143
144 virtual_break_value = real_break_value = sbrk (0);
145 if (ALIGNED (real_break_value))
146 true_break_value = real_break_value;
147 else
148 true_break_value = (POINTER) ROUNDUP (real_break_value);
149
150 if (start)
151 data_space_start = start;
152 lim_data = 0;
153 warnlevel = 0;
154 warnfunction = warn_func;
155
156 get_lim_data ();
157}
158
159/* Get more space for us to use. Return a pointer to SIZE more
160 bytes of space. SIZE is internally rounded up to a page boundary,
161 and requests for integral pages prefetch an extra page. */
162
163static POINTER
164get_more_space (size)
165 unsigned int size;
166{
167 unsigned int margin = true_break_value - real_break_value;
168 unsigned int get;
169 POINTER old_break = real_break_value;
170
171 if (size == 0)
172 return real_break_value;
173
174 if (size <= margin)
175 {
176 real_break_value += size;
177 return old_break;
178 }
179
180 get = ROUNDUP (size - margin);
181 if (sbrk (get) < (POINTER) 0)
182 return NULL;
183
184 true_break_value += get;
185 real_break_value = (old_break + size);
186
187 return old_break;
188}
189
190/* Relinquish size bytes of space to the system. Space is only returned
191 in page increments. If successful, return real_break_value. */
192
193static POINTER
194return_space (size)
195 unsigned int size;
196{
197 unsigned int margin = (true_break_value - real_break_value) + size;
198 unsigned int to_return = (margin / PAGE) * PAGE;
199 unsigned new_margin = margin % PAGE;
200
201 true_break_value -= to_return;
202 if (! brk (true_break_value))
203 return NULL;
204
205 real_break_value = true_break_value - new_margin;
206 return real_break_value;
207}
208
209/* Record a new hole in memory beginning at ADDRESS of size SIZE.
210 Holes are ordered by location. Adjacent holes are merged.
211 Holes are zero filled before being noted. */
212
213static void
214note_hole (address, size)
215 POINTER address;
216 int size;
217{
218 register int this_hole = holes - 1; /* Start at the last hole. */
219 register POINTER end = address + size; /* End of the hole. */
220 register int i;
221
222 if (holes)
223 {
224 /* Find the hole which should precede this new one. */
225 while (this_hole >= 0 && r_alloc_holes[this_hole].address > address)
226 this_hole--;
227
228 /* Can we merge with preceding? */
229 if (this_hole >= 0
230 && r_alloc_holes[this_hole].address + r_alloc_holes[this_hole].size
231 == address)
232 {
233 r_alloc_holes[this_hole].size += size;
234
235 if (this_hole == holes - 1)
236 return;
237
238 /* Can we also merge with following? */
239 if (end == r_alloc_holes[this_hole + 1].address)
240 {
241 r_alloc_holes[this_hole].size
242 += r_alloc_holes[this_hole + 1].size;
243
244 for (i = this_hole + 1; i < holes - 1; i++)
245 r_alloc_holes[i] = r_alloc_holes[i + 1];
246 holes--;
247 }
248
249 return;
250 }
251
252 if (this_hole < holes - 1) /* there are following holes */
253 {
254 register int next_hole = this_hole + 1;
255
256 /* Can we merge with the next hole? */
257 if (end == r_alloc_holes[next_hole].address)
258 {
259 r_alloc_holes[next_hole].address = address;
260 r_alloc_holes[next_hole].size += size;
261 return;
262 }
263
264 /* Can't merge, so insert. */
265 for (i = holes; i > next_hole; i--)
266 r_alloc_holes[i] = r_alloc_holes[i - 1];
267 r_alloc_holes[next_hole].address = address;
268 r_alloc_holes[next_hole].size = size;
269 holes++;
270
271 return;
272 }
273 else /* Simply add this hole at the end. */
274 {
275 r_alloc_holes[holes].address = address;
276 r_alloc_holes[holes].size = size;
277 holes++;
278
279 return;
280 }
281
282 abort ();
283 }
284 else /* Make the first hole. */
285 {
286 holes = 1;
287 r_alloc_holes[0].address = address;
288 r_alloc_holes[0].size = size;
289 }
290}
291
292/* Mark hole HOLE as no longer available by re-organizing the vector.
293 HOLE is the Nth hole, beginning with 0. This doesn *not* affect memory
294 organization. */
295
296static void
297delete_hole (hole)
298 int hole;
299{
300 register int i;
301
302 for (i = hole; i < holes - 1; i++)
303 r_alloc_holes[i] = r_alloc_holes[i + 1];
304
305 holes--;
306}
307
308/* Insert a newly allocated pointer, NEW_PTR, at the appropriate
309 place in our list. */
310
311static void
312insert (new_ptr)
313 register relocatable_pointer *new_ptr;
314{
315 register relocatable_pointer *this_ptr = pointer_list;
316
317 while (this_ptr != REL_NIL && this_ptr->block < new_ptr->block)
318 this_ptr = this_ptr->next;
319
320 if (this_ptr == REL_NIL)
321 abort (); /* Use `attach' for appending. */
322
323 new_ptr->next = this_ptr;
324 new_ptr->prev = this_ptr->prev;
325 this_ptr->prev = new_ptr;
326
327 if (this_ptr == pointer_list)
328 pointer_list = new_ptr;
329 else
330 new_ptr->prev->next = new_ptr;
331}
332
333/* Attach a newly allocated pointer, NEW_PTR, to the end of our list. */
334
335static void
336attach (new_ptr)
337 relocatable_pointer *new_ptr;
338{
339 if (pointer_list == REL_NIL)
340 {
341 pointer_list = new_ptr;
342 last_pointer = new_ptr;
343 new_ptr->next = new_ptr->prev = REL_NIL;
344 }
345 else
346 {
347 new_ptr->next = REL_NIL;
348 last_pointer->next = new_ptr;
349 new_ptr->prev = last_pointer;
350 last_pointer = new_ptr;
351 }
352}
353
354static relocatable_pointer *
355find_block (block)
356 POINTER block;
357{
358 register relocatable_pointer *this_ptr = pointer_list;
359
360 while (this_ptr != REL_NIL && this_ptr->block != block)
361 this_ptr = this_ptr->next;
362
363 return this_ptr;
364}
365
366static relocatable_pointer *
367find_location (address)
368 POINTER *address;
369{
370 register relocatable_pointer *this_ptr = pointer_list;
371
372 while (this_ptr != REL_NIL && this_ptr->location != address)
373 {
374 struct other_pointer *op = this_ptr->others;
375
376 while (op != (struct other_pointer *) 0)
377 {
378 if (op->location == address)
379 return this_ptr;
380
381 op = op->next;
382 }
383
384 this_ptr = this_ptr->next;
385 }
386
387 return this_ptr;
388}
389
390
391static void compactify ();
392
393/* Record of last new block allocated. */
394static relocatable_pointer *last_record;
395
396/* Allocate a block of size SIZE and record that PTR points to it.
397 If successful, store the address of the block in *PTR and return
398 it as well. Otherwise return NULL. */
399
400POINTER
401r_alloc (ptr, size)
402 POINTER *ptr;
403 int size;
404{
405 register relocatable_pointer *record
406 = (relocatable_pointer *) malloc (sizeof (relocatable_pointer));
407 register POINTER block;
408
409 /* If we can't get space to record this pointer, fail. */
410 if (record == 0)
411 return NULL;
412
413 last_record = record;
414
415 if (holes) /* Search for a hole the right size. */
416 {
417 int i;
418
419 for (i = 0; i < holes; i++)
420 if (r_alloc_holes[i].size >= size)
421 {
422 record->location = ptr;
423 record->others = (struct other_pointer *) 0;
424 record->block = *ptr = r_alloc_holes[i].address;
425 if (r_alloc_holes[i].size > ROUNDUP (size))
426 {
427 record->size = ROUNDUP (size);
428 r_alloc_holes[i].size -= ROUNDUP (size);
429 r_alloc_holes[i].address += ROUNDUP (size);
430 }
431 else
432 {
433 record->size = r_alloc_holes[i].size;
434 delete_hole (i);
435 }
436 insert (record);
437
438 *ptr = record->block;
439 return record->block;
440 }
441
442 /* No holes large enough. Burp. */
443 compactify ();
444 }
445
446 /* No holes: grow the process. */
447 block = get_more_space (size);
448 if (block == NULL)
449 {
450 free (record);
451 return NULL;
452 }
453
454 /* Return the address of the block. */
455 *ptr = block;
456
457 /* Record and append this pointer to our list. */
458 record->location = ptr;
459 record->others = (struct other_pointer *) 0;
460 record->block = block;
461 record->size = size;
462 attach (record);
463
464 return block;
465}
466
467/* Declare VAR to be a pointer which points into the block of r_alloc'd
468 memory at BLOCK.
469
470 If VAR is already delcared for this block, simply return.
471 If VAR currently points to some other block, remove that declaration
472 of it, then install the new one.
473
474 Return 0 if successful, -1 otherwise. */
475
476int
477r_alloc_declare (var, block)
478 POINTER *var;
479 register POINTER block;
480{
481 register relocatable_pointer *block_ptr = find_block (block);
482 relocatable_pointer *var_ptr = find_location (var);
483 register struct other_pointer *other;
484
485 if (block_ptr == REL_NIL)
486 abort ();
487
488 if (var_ptr != REL_NIL) /* Var already declared somewhere. */
489 {
490 register struct other_pointer *po;
491
492 if (var_ptr == block_ptr) /* Var already points to this block. */
493 return 0;
494
495 po = (struct other_pointer *) 0;
496 other = var_ptr->others;
497 while (other && other->location != var)
498 {
499 po = other;
500 other = other->next;
501 }
502
503 if (!other) /* This only happens if the location is */
504 abort (); /* the main pointer and not an `other' */
505
506 if (po) /* In the chain */
507 {
508 po->next = other->next;
509 free (other);
510 }
511 else /* Only element of the chain */
512 {
513 free (var_ptr->others);
514 var_ptr->others = (struct other_pointer *) 0;
515 }
516 }
517
518 /* Install this variable as an `other' element */
519
520 other = (struct other_pointer *) malloc (sizeof (struct other_pointer));
521
522 if (other == 0)
523 return -1;
524
525 /* If the malloc relocated this data block, adjust this variable. */
526 if (block != block_ptr->block)
527 {
528 int offset = block_ptr->block - block;
529
530 *var += offset;
531 }
532
533 other->location = var;
534 other->next = (struct other_pointer *) 0;
535
536 if (block_ptr->others == (struct other_pointer *) 0)
537 block_ptr->others = other;
538 else
539 {
540 register struct other_pointer *op = block_ptr->others;
541
542 while (op->next != (struct other_pointer *) 0)
543 op = op->next;
544 op->next = other;
545 }
546
547 return 0;
548}
549
550/* Recursively free the linked list of `other' pointers to a block. */
551
552static void
553free_others (another)
554 struct other_pointer *another;
555{
556 if (another == (struct other_pointer *) 0)
557 return;
558
559 free_others (another->next);
560 free (another);
561}
562
563/* Remove the element pointed to by PTR from the doubly linked list.
564 Record the newly freed space in `holes', unless it was at the end,
565 in which case return that space to the system. Return 0 if successful,
566 -1 otherwise. */
567
568int
569r_alloc_free (ptr)
570 register POINTER *ptr;
571{
572 register relocatable_pointer *this_ptr = find_block (*ptr);
573
574 if (this_ptr == REL_NIL)
575 return -1;
576 else
577 {
578 register relocatable_pointer *prev = this_ptr->prev;
579 register relocatable_pointer *next = this_ptr->next;
580 if (next && prev) /* Somewhere in the middle */
581 {
582 next->prev = prev;
583 prev->next = next;
584 }
585 else if (prev) /* Last block */
586 {
587 prev->next = REL_NIL;
588 last_pointer = prev;
589 return_space (this_ptr->size);
590 free_others (this_ptr->others);
591 free (this_ptr);
592
593 return 0;
594 }
595 else if (next) /* First block */
596 {
597 next->prev = REL_NIL;
598 pointer_list = next;
599 }
600 else if (this_ptr = pointer_list) /* ONLY block */
601 {
602 pointer_list = REL_NIL;
603 last_pointer = REL_NIL;
604 if (holes) /* A hole precedes this block. */
605 {
606 holes = 0;
607 return_space (real_break_value - virtual_break_value);
608 }
609 else
610 return_space (this_ptr->size);
611
612 if (real_break_value != virtual_break_value)
613 abort ();
614
615 free_others (this_ptr->others);
616 free (this_ptr);
617 /* Turn off r_alloc_in_use? */
618
619 return 0;
620 }
621 else
622 abort (); /* Weird shit */
623
624 free_others (this_ptr->others);
625 free (this_ptr);
626 bzero (this_ptr->block, this_ptr->size);
627 note_hole (this_ptr->block, this_ptr->size);
628
629 if (holes == MAX_HOLES)
630 compactify ();
631 }
632
633 return 0;
634}
635
636/* Change the size of the block pointed to by the thing in PTR.
637 If neccessary, r_alloc a new block and copy the data there.
638 Return a pointer to the block if successfull, NULL otherwise.
639
640 Note that if the size requested is less than the actual bloc size,
641 nothing is done and the pointer is simply returned. */
642
643POINTER
644r_re_alloc (ptr, size)
645 POINTER *ptr;
646 int size;
647{
648 register relocatable_pointer *this_ptr = find_block (*ptr);
649 POINTER block;
650
651 if (! this_ptr)
652 return NULL;
653
654 if (this_ptr->size >= size) /* Already have enough space. */
655 return *ptr;
656
657 /* Here we could try relocating the blocks just above... */
658 block = r_alloc (ptr, size);
659 if (block)
660 {
661 bcopy (this_ptr->block, block, this_ptr->size);
662 if (this_ptr->others)
663 last_record->others = this_ptr->others;
664
665 if (! r_alloc_free (this_ptr->block))
666 abort ();
667
668 *ptr = block;
669 return block;
670 }
671
672 return NULL;
673}
674
675
676/* Move and relocate all blocks from FIRST_PTR to LAST_PTR, inclusive,
677 downwards to space starting at ADDRESS. */
678
679static int
680move_blocks_downward (first_ptr, last_ptr, address)
681 relocatable_pointer *first_ptr, *last_ptr;
682 POINTER address;
683{
684 int size = (last_ptr->block + last_ptr->size) - first_ptr->block;
685 register relocatable_pointer *this_ptr = first_ptr;
686 register offset = first_ptr->block - address;
687 register struct other_pointer *op;
688
689 /* Move all the data. */
690 bcopy (first_ptr->block, address, size);
691
692 /* Now relocate all the pointers to those blocks. */
693 while (1)
694 {
695 this_ptr->block -= offset;
696 *this_ptr->location = this_ptr->block;
697
698 op = this_ptr->others;
699 while (op != (struct other_pointer *) 0)
700 {
701 *op->location -= offset;
702 op = op->next;
703 }
704
705 if (this_ptr == last_ptr)
706 return;
707 else
708 this_ptr = this_ptr->next;
709 }
710
711 return size;
712}
713
714/* Burp our memory zone. */
715
716static void
717compactify ()
718{
719 register relocatable_pointer *this_ptr = pointer_list;
720 relocatable_pointer *first_to_move;
721 register relocatable_pointer *last_to_move;
722 hole_descriptor *this_hole = &r_alloc_holes[0];
723 register hole_descriptor *next_hole;
724 register POINTER end; /* First address after hole */
725 unsigned int space_regained = 0;
726
727 while (holes) /* While there are holes */
728 {
729 /* Find the first block after this hole. */
730 end = this_hole->address + this_hole->size;
731 while (this_ptr && this_ptr->block != end)
732 this_ptr = this_ptr->next;
733
734 if (! this_ptr)
735 abort ();
736
737 next_hole = this_hole + 1;
738 last_to_move = first_to_move = this_ptr;
739 this_ptr = this_ptr->next;
740
741 /* Note all blocks located before the next hole. */
742 while (this_ptr && this_ptr->block < next_hole->address)
743 {
744 last_to_move = this_ptr;
745 this_ptr = this_ptr->next;
746 }
747 space_regained +=
748 move_blocks_downward (first_to_move, last_to_move, this_hole->address);
749
750 holes--;
751 this_hole = next_hole;
752 }
753
754 return_space (space_regained);
755}
756
757/* Relocate the list elements from the beginning of the list up to and
758 including UP_TO_THIS_PTR to the area beginning at FREE_SPACE, which is
759 after all current blocks.
760
761 First copy all the data, then adjust the pointers and reorganize
762 the list. NOTE that this *only* works for contiguous blocks. */
763
764static unsigned int
765relocate_to_end (up_to_this_ptr, free_space)
766 register relocatable_pointer *up_to_this_ptr;
767 POINTER free_space;
768{
769 register relocatable_pointer *this_ptr;
770 POINTER block_start = pointer_list->block;
771 POINTER block_end = up_to_this_ptr->block + up_to_this_ptr->size;
772 unsigned int total_size = block_end - block_start;
773 unsigned int offset = (int) (free_space - block_start);
774
775 bcopy (block_start, free_space, total_size);
776 for (this_ptr = up_to_this_ptr; this_ptr; this_ptr = this_ptr->prev)
777 {
778 struct other_pointer *op = this_ptr->others;
779
780 *this_ptr->location += offset;
781 this_ptr->block += offset;
782
783 while (op != (struct other_pointer *) 0)
784 {
785 *op->location += offset;
786 op = op->next;
787 }
788 }
789
790 /* Connect the head to the tail. */
791 last_pointer->next = pointer_list;
792 pointer_list->prev = last_pointer;
793
794 /* Disconnect */
795 up_to_this_ptr->next->prev = REL_NIL;
796 pointer_list = up_to_this_ptr->next;
797 up_to_this_ptr->next = REL_NIL;
798 last_pointer = up_to_this_ptr;
799
800 return total_size; /* of space relocated. */
801}
802
803/* Relocate the list elements from FROM_THIS_PTR to (and including)
804 the last to the zone beginning at FREE_SPACE, which is located
805 before any blocks.
806
807 First copy all the data, then adjust the pointers and reorganize
808 the list. NOTE that this *only* works for contiguous blocks. */
809
810static unsigned int
811relocate_to_beginning (from_this_ptr, free_space)
812 register relocatable_pointer *from_this_ptr;
813 POINTER free_space;
814{
815 POINTER block_start = from_this_ptr->block;
816 POINTER block_end = last_pointer->block + last_pointer->size;
817 unsigned int total_size = (int) (block_end - block_start);
818 unsigned int offset = (int) (from_this_ptr->block - free_space);
819 register relocatable_pointer *this_ptr;
820
821 bcopy (block_start, free_space, total_size);
822 for (this_ptr = from_this_ptr; this_ptr; this_ptr = this_ptr->next)
823 {
824 struct other_pointer *op = this_ptr->others;
825
826 *this_ptr->location -= offset;
827 this_ptr->block -= offset;
828
829 while (op != (struct other_pointer *) 0)
830 {
831 *op->location -= offset;
832 op = op->next;
833 }
834 }
835
836 /* Connect the end to the beginning. */
837 last_pointer->next = pointer_list;
838 pointer_list->prev = last_pointer;
839
840 /* Disconnect and reset first and last. */
841 from_this_ptr->prev->next = REL_NIL;
842 last_pointer = from_this_ptr->prev;
843 pointer_list = from_this_ptr;
844 pointer_list->prev = REL_NIL;
845
846 return total_size; /* of space moved. */
847}
848
849/* Relocate any blocks neccessary, either upwards or downwards,
850 to obtain a space of SIZE bytes. Assumes we have at least one block. */
851
852static unsigned int
853relocate (size)
854 register int size;
855{
856 register relocatable_pointer *ptr;
857 register int got = 0;
858
859 if (size > 0) /* Up: Relocate enough blocs to get SIZE. */
860 {
861 register POINTER new_space;
862
863 for (ptr = pointer_list; got < size && ptr; ptr = ptr->next)
864 got += ptr->size;
865
866 if (ptr == REL_NIL)
867 ptr = last_pointer;
868
869 new_space = get_more_space (size);
870 if (!new_space)
871 return 0;
872
873 return (relocate_to_end (ptr, pointer_list->block + size));
874 }
875
876 if (size < 0) /* Down: relocate as many blocs as will
877 fit in SIZE bytes of space. */
878 {
879 register POINTER to_zone;
880 unsigned int moved;
881
882 for (ptr = last_pointer; got >= size && ptr; ptr = ptr->prev)
883 got -= ptr->size;
884
885 if (ptr == REL_NIL)
886 ptr = pointer_list;
887 else
888 {
889 /* Back off one block to be <= size */
890 got += ptr->size;
891 ptr = ptr->next;
892 }
893
894 if (got >= size)
895 {
896 to_zone = virtual_break_value - size + got;
897 moved = relocate_to_beginning (ptr, to_zone);
898 if (moved)
899 return_space (moved);
900
901 return moved;
902 }
903
904 return 0;
905 }
906
907 abort ();
908}
909
910/* This function encapsulates `sbrk' to preserve the relocatable blocks.
911 It is called just like `sbrk'. When relocatable blocks are in use,
912 `malloc' must use this function instead of `sbrk'. */
913
914POINTER
915r_alloc_sbrk (size)
916 unsigned int size;
917{
918 POINTER new_zone; /* Start of the zone we will return. */
919
920#if 0
921 if (! r_alloc_in_use)
922 return (POINTER) sbrk (size);
923#endif
924
925 if (size == 0)
926 return virtual_break_value;
927
928 if (size > 0) /* Get more space */
929 {
930 register unsigned int space;
931
932 if (pointer_list == REL_NIL)
933 {
934 POINTER space = get_more_space (size);
935
936 virtual_break_value = real_break_value;
937 return space;
938 }
939
940 new_zone = virtual_break_value;
941
942 /* Check if there is a hole just before the buffer zone. */
943 if (holes && r_alloc_holes[0].address == virtual_break_value)
944 {
945 if (r_alloc_holes[0].size > size)
946 {
947 /* Adjust the hole size. */
948 r_alloc_holes[0].size -= size;
949 r_alloc_holes[0].address += size;
950 virtual_break_value += size;
951
952 return new_zone;
953 }
954
955 if (r_alloc_holes[0].size == size)
956 {
957 virtual_break_value += size;
958 delete_hole (0);
959
960 return new_zone;
961 }
962
963 /* Adjust the size requested by space
964 already available in this hole. */
965 size -= r_alloc_holes[0].size;
966 virtual_break_value += r_alloc_holes[0].size;
967 delete_hole (0);
968 }
969
970 space = relocate (size);
971 if (!space)
972 return (POINTER) -1;
973
974#ifdef REL_ALLOC_SAVE_SPACE
975 move_blocks_downward
976#else
977 bzero (new_zone, space);
978 if (space > size)
979 note_hole (new_zone + size, space - size);
980#endif /* REL_ALLOC_SAVE_SPACE */
981
982 virtual_break_value += size;
983 return new_zone;
984 }
985 else /* Return space to system */
986 {
987 int moved;
988 int left_over;
989 POINTER old_break_value;
990
991 if (pointer_list == REL_NIL)
992 {
993 POINTER space = return_space (-size);
994 virtual_break_value = real_break_value;
995
996 return space;
997 }
998
999 if (holes && r_alloc_holes[0].address == virtual_break_value)
1000 {
1001 size -= r_alloc_holes[0].size;
1002 delete_hole (0);
1003 }
1004
1005 moved = relocate (size);
1006 old_break_value = virtual_break_value;
1007
1008 if (!moved)
1009 return (POINTER) -1;
1010
1011 left_over = moved + size;
1012 virtual_break_value += size;
1013
1014 if (left_over)
1015 {
1016#ifdef REL_ALLOC_SAVE_SPACE
1017 move_blocks_downward
1018#else
1019 bzero (virtual_break_value, left_over);
1020 note_hole (virtual_break_value, left_over);
1021#endif /* not REL_ALLOC_SAVE_SPACE */
1022 }
1023
1024 return old_break_value;
1025 }
1026}
1027
1028/* For debugging */
1029
1030#include <stdio.h>
1031
1032void
1033memory_trace ()
1034{
1035 relocatable_pointer *ptr;
1036 int i;
1037
1038 fprintf (stderr, "virtual: 0x%x\n real: 0x%x\n true: 0x%x\n\n",
1039 virtual_break_value, real_break_value, true_break_value);
1040 fprintf (stderr, "Blocks:\n");
1041 for (ptr = pointer_list; ptr; ptr = ptr->next)
1042 {
1043 fprintf (stderr, " address: 0x%x\n", ptr->block);
1044 fprintf (stderr, " size: 0x%x\n", ptr->size);
1045 if (ptr->others)
1046 {
1047 struct other_pointer *op = ptr->others;
1048 fprintf (stderr, " others:", ptr->size);
1049 while (op)
1050 {
1051 fprintf (stderr, " 0x%x", op->location);
1052 op = op->next;
1053 }
1054 fprintf (stderr, "\n");
1055 }
1056 }
1057
1058 if (holes)
1059 {
1060 fprintf (stderr, "\nHoles:\n");
1061 for (i = 0; i < holes; i++)
1062 {
1063 fprintf (stderr, " address: 0x%x\n", r_alloc_holes[i].address);
1064 fprintf (stderr, " size: 0x%x\n", r_alloc_holes[i].size);
1065 }
1066 }
1067
1068 fprintf (stderr, "\n\n");
1069}
diff --git a/src/sol2-2.h b/src/sol2-2.h
deleted file mode 100644
index 016f75e488a..00000000000
--- a/src/sol2-2.h
+++ /dev/null
@@ -1,18 +0,0 @@
1/* casper@fwi.uva.nl says this file is not needed
2 and sol2.h should work. */
3
4#include "sol2.h"
5
6/* Take care of libucb.a as well as X Windows. */
7#undef LD_SWITCH_SYSTEM
8#ifndef __GNUC__
9#define LD_SWITCH_SYSTEM -R/usr/openwin/lib:/usr/ucblib
10#else /* GCC */
11#define LD_SWITCH_SYSTEM -Xlinker -R/usr/openwin/lib:/usr/ucblib
12#endif /* GCC */
13
14/* Link with libucb.a. */
15#ifdef LIB_STANDARD
16#undef LIB_STANDARD
17#define LIB_STANDARD -lc -L/usr/ucblib -lucb
18#endif
diff --git a/src/unexelf1.c b/src/unexelf1.c
deleted file mode 100644
index a832755167e..00000000000
--- a/src/unexelf1.c
+++ /dev/null
@@ -1,952 +0,0 @@
1/* Copyright (C) 1985, 1986, 1987, 1988, 1990, 1992
2 Free Software Foundation, Inc.
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA.
20
21In other words, you are welcome to use, share and improve this program.
22You are forbidden to forbid anyone else to use, share and improve
23what you give them. Help stamp out software-hoarding! */
24
25
26/*
27 * unexec.c - Convert a running program into an a.out file.
28 *
29 * Author: Spencer W. Thomas
30 * Computer Science Dept.
31 * University of Utah
32 * Date: Tue Mar 2 1982
33 * Modified heavily since then.
34 *
35 * Synopsis:
36 * unexec (new_name, a_name, data_start, bss_start, entry_address)
37 * char *new_name, *a_name;
38 * unsigned data_start, bss_start, entry_address;
39 *
40 * Takes a snapshot of the program and makes an a.out format file in the
41 * file named by the string argument new_name.
42 * If a_name is non-NULL, the symbol table will be taken from the given file.
43 * On some machines, an existing a_name file is required.
44 *
45 * The boundaries within the a.out file may be adjusted with the data_start
46 * and bss_start arguments. Either or both may be given as 0 for defaults.
47 *
48 * Data_start gives the boundary between the text segment and the data
49 * segment of the program. The text segment can contain shared, read-only
50 * program code and literal data, while the data segment is always unshared
51 * and unprotected. Data_start gives the lowest unprotected address.
52 * The value you specify may be rounded down to a suitable boundary
53 * as required by the machine you are using.
54 *
55 * Specifying zero for data_start means the boundary between text and data
56 * should not be the same as when the program was loaded.
57 * If NO_REMAP is defined, the argument data_start is ignored and the
58 * segment boundaries are never changed.
59 *
60 * Bss_start indicates how much of the data segment is to be saved in the
61 * a.out file and restored when the program is executed. It gives the lowest
62 * unsaved address, and is rounded up to a page boundary. The default when 0
63 * is given assumes that the entire data segment is to be stored, including
64 * the previous data and bss as well as any additional storage allocated with
65 * break (2).
66 *
67 * The new file is set up to start at entry_address.
68 *
69 * If you make improvements I'd like to get them too.
70 * harpo!utah-cs!thomas, thomas@Utah-20
71 *
72 */
73
74/* Even more heavily modified by james@bigtex.cactus.org of Dell Computer Co.
75 * ELF support added.
76 *
77 * Basic theory: the data space of the running process needs to be
78 * dumped to the output file. Normally we would just enlarge the size
79 * of .data, scooting everything down. But we can't do that in ELF,
80 * because there is often something between the .data space and the
81 * .bss space.
82 *
83 * In the temacs dump below, notice that the Global Offset Table
84 * (.got) and the Dynamic link data (.dynamic) come between .data1 and
85 * .bss. It does not work to overlap .data with these fields.
86 *
87 * The solution is to create a new .data segment. This segment is
88 * filled with data from the current process. Since the contents of
89 * various sections refer to sections by index, the new .data segment
90 * is made the last in the table to avoid changing any existing index.
91
92 * This is an example of how the section headers are changed. "Addr"
93 * is a process virtual address. "Offset" is a file offset.
94
95raid:/nfs/raid/src/dist-18.56/src> dump -h temacs
96
97temacs:
98
99 **** SECTION HEADER TABLE ****
100[No] Type Flags Addr Offset Size Name
101 Link Info Adralgn Entsize
102
103[1] 1 2 0x80480d4 0xd4 0x13 .interp
104 0 0 0x1 0
105
106[2] 5 2 0x80480e8 0xe8 0x388 .hash
107 3 0 0x4 0x4
108
109[3] 11 2 0x8048470 0x470 0x7f0 .dynsym
110 4 1 0x4 0x10
111
112[4] 3 2 0x8048c60 0xc60 0x3ad .dynstr
113 0 0 0x1 0
114
115[5] 9 2 0x8049010 0x1010 0x338 .rel.plt
116 3 7 0x4 0x8
117
118[6] 1 6 0x8049348 0x1348 0x3 .init
119 0 0 0x4 0
120
121[7] 1 6 0x804934c 0x134c 0x680 .plt
122 0 0 0x4 0x4
123
124[8] 1 6 0x80499cc 0x19cc 0x3c56f .text
125 0 0 0x4 0
126
127[9] 1 6 0x8085f3c 0x3df3c 0x3 .fini
128 0 0 0x4 0
129
130[10] 1 2 0x8085f40 0x3df40 0x69c .rodata
131 0 0 0x4 0
132
133[11] 1 2 0x80865dc 0x3e5dc 0xd51 .rodata1
134 0 0 0x4 0
135
136[12] 1 3 0x8088330 0x3f330 0x20afc .data
137 0 0 0x4 0
138
139[13] 1 3 0x80a8e2c 0x5fe2c 0x89d .data1
140 0 0 0x4 0
141
142[14] 1 3 0x80a96cc 0x606cc 0x1a8 .got
143 0 0 0x4 0x4
144
145[15] 6 3 0x80a9874 0x60874 0x80 .dynamic
146 4 0 0x4 0x8
147
148[16] 8 3 0x80a98f4 0x608f4 0x449c .bss
149 0 0 0x4 0
150
151[17] 2 0 0 0x608f4 0x9b90 .symtab
152 18 371 0x4 0x10
153
154[18] 3 0 0 0x6a484 0x8526 .strtab
155 0 0 0x1 0
156
157[19] 3 0 0 0x729aa 0x93 .shstrtab
158 0 0 0x1 0
159
160[20] 1 0 0 0x72a3d 0x68b7 .comment
161 0 0 0x1 0
162
163raid:/nfs/raid/src/dist-18.56/src> dump -h xemacs
164
165xemacs:
166
167 **** SECTION HEADER TABLE ****
168[No] Type Flags Addr Offset Size Name
169 Link Info Adralgn Entsize
170
171[1] 1 2 0x80480d4 0xd4 0x13 .interp
172 0 0 0x1 0
173
174[2] 5 2 0x80480e8 0xe8 0x388 .hash
175 3 0 0x4 0x4
176
177[3] 11 2 0x8048470 0x470 0x7f0 .dynsym
178 4 1 0x4 0x10
179
180[4] 3 2 0x8048c60 0xc60 0x3ad .dynstr
181 0 0 0x1 0
182
183[5] 9 2 0x8049010 0x1010 0x338 .rel.plt
184 3 7 0x4 0x8
185
186[6] 1 6 0x8049348 0x1348 0x3 .init
187 0 0 0x4 0
188
189[7] 1 6 0x804934c 0x134c 0x680 .plt
190 0 0 0x4 0x4
191
192[8] 1 6 0x80499cc 0x19cc 0x3c56f .text
193 0 0 0x4 0
194
195[9] 1 6 0x8085f3c 0x3df3c 0x3 .fini
196 0 0 0x4 0
197
198[10] 1 2 0x8085f40 0x3df40 0x69c .rodata
199 0 0 0x4 0
200
201[11] 1 2 0x80865dc 0x3e5dc 0xd51 .rodata1
202 0 0 0x4 0
203
204[12] 1 3 0x8088330 0x3f330 0x20afc .data
205 0 0 0x4 0
206
207[13] 1 3 0x80a8e2c 0x5fe2c 0x89d .data1
208 0 0 0x4 0
209
210[14] 1 3 0x80a96cc 0x606cc 0x1a8 .got
211 0 0 0x4 0x4
212
213[15] 6 3 0x80a9874 0x60874 0x80 .dynamic
214 4 0 0x4 0x8
215
216[16] 8 3 0x80c6800 0x7d800 0 .bss
217 0 0 0x4 0
218
219[17] 2 0 0 0x7d800 0x9b90 .symtab
220 18 371 0x4 0x10
221
222[18] 3 0 0 0x87390 0x8526 .strtab
223 0 0 0x1 0
224
225[19] 3 0 0 0x8f8b6 0x93 .shstrtab
226 0 0 0x1 0
227
228[20] 1 0 0 0x8f949 0x68b7 .comment
229 0 0 0x1 0
230
231[21] 1 3 0x80a98f4 0x608f4 0x1cf0c .data
232 0 0 0x4 0
233
234 * This is an example of how the file header is changed. "Shoff" is
235 * the section header offset within the file. Since that table is
236 * after the new .data section, it is moved. "Shnum" is the number of
237 * sections, which we increment.
238 *
239 * "Phoff" is the file offset to the program header. "Phentsize" and
240 * "Shentsz" are the program and section header entries sizes respectively.
241 * These can be larger than the apparent struct sizes.
242
243raid:/nfs/raid/src/dist-18.56/src> dump -f temacs
244
245temacs:
246
247 **** ELF HEADER ****
248Class Data Type Machine Version
249Entry Phoff Shoff Flags Ehsize
250Phentsize Phnum Shentsz Shnum Shstrndx
251
2521 1 2 3 1
2530x80499cc 0x34 0x792f4 0 0x34
2540x20 5 0x28 21 19
255
256raid:/nfs/raid/src/dist-18.56/src> dump -f xemacs
257
258xemacs:
259
260 **** ELF HEADER ****
261Class Data Type Machine Version
262Entry Phoff Shoff Flags Ehsize
263Phentsize Phnum Shentsz Shnum Shstrndx
264
2651 1 2 3 1
2660x80499cc 0x34 0x96200 0 0x34
2670x20 5 0x28 22 19
268
269 * These are the program headers. "Offset" is the file offset to the
270 * segment. "Vaddr" is the memory load address. "Filesz" is the
271 * segment size as it appears in the file, and "Memsz" is the size in
272 * memory. Below, the third segment is the code and the fourth is the
273 * data: the difference between Filesz and Memsz is .bss
274
275raid:/nfs/raid/src/dist-18.56/src> dump -o temacs
276
277temacs:
278 ***** PROGRAM EXECUTION HEADER *****
279Type Offset Vaddr Paddr
280Filesz Memsz Flags Align
281
2826 0x34 0x8048034 0
2830xa0 0xa0 5 0
284
2853 0xd4 0 0
2860x13 0 4 0
287
2881 0x34 0x8048034 0
2890x3f2f9 0x3f2f9 5 0x1000
290
2911 0x3f330 0x8088330 0
2920x215c4 0x25a60 7 0x1000
293
2942 0x60874 0x80a9874 0
2950x80 0 7 0
296
297raid:/nfs/raid/src/dist-18.56/src> dump -o xemacs
298
299xemacs:
300 ***** PROGRAM EXECUTION HEADER *****
301Type Offset Vaddr Paddr
302Filesz Memsz Flags Align
303
3046 0x34 0x8048034 0
3050xa0 0xa0 5 0
306
3073 0xd4 0 0
3080x13 0 4 0
309
3101 0x34 0x8048034 0
3110x3f2f9 0x3f2f9 5 0x1000
312
3131 0x3f330 0x8088330 0
3140x3e4d0 0x3e4d0 7 0x1000
315
3162 0x60874 0x80a9874 0
3170x80 0 7 0
318
319
320 */
321
322/* Modified by wtien@urbana.mcd.mot.com of Motorola Inc.
323 *
324 * The above mechanism does not work if the unexeced ELF file is being
325 * re-layout by other applications (such as `strip'). All the applications
326 * that re-layout the internal of ELF will layout all sections in ascending
327 * order of their file offsets. After the re-layout, the data2 section will
328 * still be the LAST section in the section header vector, but its file offset
329 * is now being pushed far away down, and causes part of it not to be mapped
330 * in (ie. not covered by the load segment entry in PHDR vector), therefore
331 * causes the new binary to fail.
332 *
333 * The solution is to modify the unexec algorithm to insert the new data2
334 * section header right before the new bss section header, so their file
335 * offsets will be in the ascending order. Since some of the section's (all
336 * sections AFTER the bss section) indexes are now changed, we also need to
337 * modify some fields to make them point to the right sections. This is done
338 * by macro PATCH_INDEX. All the fields that need to be patched are:
339 *
340 * 1. ELF header e_shstrndx field.
341 * 2. section header sh_link and sh_info field.
342 * 3. symbol table entry st_shndx field.
343 *
344 * The above example now should look like:
345
346 **** SECTION HEADER TABLE ****
347[No] Type Flags Addr Offset Size Name
348 Link Info Adralgn Entsize
349
350[1] 1 2 0x80480d4 0xd4 0x13 .interp
351 0 0 0x1 0
352
353[2] 5 2 0x80480e8 0xe8 0x388 .hash
354 3 0 0x4 0x4
355
356[3] 11 2 0x8048470 0x470 0x7f0 .dynsym
357 4 1 0x4 0x10
358
359[4] 3 2 0x8048c60 0xc60 0x3ad .dynstr
360 0 0 0x1 0
361
362[5] 9 2 0x8049010 0x1010 0x338 .rel.plt
363 3 7 0x4 0x8
364
365[6] 1 6 0x8049348 0x1348 0x3 .init
366 0 0 0x4 0
367
368[7] 1 6 0x804934c 0x134c 0x680 .plt
369 0 0 0x4 0x4
370
371[8] 1 6 0x80499cc 0x19cc 0x3c56f .text
372 0 0 0x4 0
373
374[9] 1 6 0x8085f3c 0x3df3c 0x3 .fini
375 0 0 0x4 0
376
377[10] 1 2 0x8085f40 0x3df40 0x69c .rodata
378 0 0 0x4 0
379
380[11] 1 2 0x80865dc 0x3e5dc 0xd51 .rodata1
381 0 0 0x4 0
382
383[12] 1 3 0x8088330 0x3f330 0x20afc .data
384 0 0 0x4 0
385
386[13] 1 3 0x80a8e2c 0x5fe2c 0x89d .data1
387 0 0 0x4 0
388
389[14] 1 3 0x80a96cc 0x606cc 0x1a8 .got
390 0 0 0x4 0x4
391
392[15] 6 3 0x80a9874 0x60874 0x80 .dynamic
393 4 0 0x4 0x8
394
395[16] 1 3 0x80a98f4 0x608f4 0x1cf0c .data
396 0 0 0x4 0
397
398[17] 8 3 0x80c6800 0x7d800 0 .bss
399 0 0 0x4 0
400
401[18] 2 0 0 0x7d800 0x9b90 .symtab
402 19 371 0x4 0x10
403
404[19] 3 0 0 0x87390 0x8526 .strtab
405 0 0 0x1 0
406
407[20] 3 0 0 0x8f8b6 0x93 .shstrtab
408 0 0 0x1 0
409
410[21] 1 0 0 0x8f949 0x68b7 .comment
411 0 0 0x1 0
412
413 */
414
415#include <sys/types.h>
416#include <stdio.h>
417#include <sys/stat.h>
418#include <memory.h>
419#include <string.h>
420#include <errno.h>
421#include <unistd.h>
422#include <fcntl.h>
423#include <elf.h>
424#include <sys/mman.h>
425
426#ifdef __alpha__
427# include <sym.h> /* get COFF debugging symbol table declaration */
428#endif
429
430#if __GNU_LIBRARY__ - 0 >= 6
431# include <link.h> /* get ElfW etc */
432#endif
433
434#ifndef ElfW
435# ifdef __STDC__
436# define ElfW(type) Elf32_##type
437# else
438# define ElfW(type) Elf32_/**/type
439# endif
440#endif
441
442#ifndef emacs
443#define fatal(a, b, c) fprintf (stderr, a, b, c), exit (1)
444#else
445#include <config.h>
446extern void fatal (char *, ...);
447#endif
448
449#ifndef ELF_BSS_SECTION_NAME
450#define ELF_BSS_SECTION_NAME ".bss"
451#endif
452
453/* Get the address of a particular section or program header entry,
454 * accounting for the size of the entries.
455 */
456/*
457 On PPC Reference Platform running Solaris 2.5.1
458 the plt section is also of type NOBI like the bss section.
459 (not really stored) and therefore sections after the bss
460 section start at the plt offset. The plt section is always
461 the one just before the bss section.
462 Thus, we modify the test from
463 if (NEW_SECTION_H (nn).sh_offset >= new_data2_offset)
464 to
465 if (NEW_SECTION_H (nn).sh_offset >=
466 OLD_SECTION_H (old_bss_index-1).sh_offset)
467 This is just a hack. We should put the new data section
468 before the .plt section.
469 And we should not have this routine at all but use
470 the libelf library to read the old file and create the new
471 file.
472 The changed code is minimal and depends on prep set in m/prep.h
473 Erik Deumens
474 Quantum Theory Project
475 University of Florida
476 deumens@qtp.ufl.edu
477 Apr 23, 1996
478 */
479
480#define OLD_SECTION_H(n) \
481 (*(ElfW(Shdr) *) ((byte *) old_section_h + old_file_h->e_shentsize * (n)))
482#define NEW_SECTION_H(n) \
483 (*(ElfW(Shdr) *) ((byte *) new_section_h + new_file_h->e_shentsize * (n)))
484#define OLD_PROGRAM_H(n) \
485 (*(ElfW(Phdr) *) ((byte *) old_program_h + old_file_h->e_phentsize * (n)))
486#define NEW_PROGRAM_H(n) \
487 (*(ElfW(Phdr) *) ((byte *) new_program_h + new_file_h->e_phentsize * (n)))
488
489#define PATCH_INDEX(n) \
490 do { \
491 if ((int) (n) >= old_bss_index) \
492 (n)++; } while (0)
493typedef unsigned char byte;
494
495/* Round X up to a multiple of Y. */
496
497int
498round_up (x, y)
499 int x, y;
500{
501 int rem = x % y;
502 if (rem == 0)
503 return x;
504 return x - rem + y;
505}
506
507/* ****************************************************************
508 * unexec
509 *
510 * driving logic.
511 *
512 * In ELF, this works by replacing the old .bss section with a new
513 * .data section, and inserting an empty .bss immediately afterwards.
514 *
515 */
516void
517unexec (new_name, old_name, data_start, bss_start, entry_address)
518 char *new_name, *old_name;
519 unsigned data_start, bss_start, entry_address;
520{
521 int new_file, old_file, new_file_size;
522
523 /* Pointers to the base of the image of the two files. */
524 caddr_t old_base, new_base;
525
526 /* Pointers to the file, program and section headers for the old and new
527 * files.
528 */
529 ElfW(Ehdr) *old_file_h, *new_file_h;
530 ElfW(Phdr) *old_program_h, *new_program_h;
531 ElfW(Shdr) *old_section_h, *new_section_h;
532
533 /* Point to the section name table in the old file */
534 char *old_section_names;
535
536 ElfW(Addr) old_bss_addr, new_bss_addr;
537 ElfW(Word) old_bss_size, new_data2_size;
538 ElfW(Off) new_data2_offset;
539 ElfW(Addr) new_data2_addr;
540
541 int n, nn, old_bss_index, old_data_index, new_data2_index;
542 struct stat stat_buf;
543
544 /* Open the old file & map it into the address space. */
545
546 old_file = open (old_name, O_RDONLY);
547
548 if (old_file < 0)
549 fatal ("Can't open %s for reading: errno %d\n", old_name, errno);
550
551 if (fstat (old_file, &stat_buf) == -1)
552 fatal ("Can't fstat (%s): errno %d\n", old_name, errno);
553
554 old_base = mmap (0, stat_buf.st_size, PROT_READ, MAP_SHARED, old_file, 0);
555
556 if (old_base == (caddr_t) -1)
557 fatal ("Can't mmap (%s): errno %d\n", old_name, errno);
558
559#ifdef DEBUG
560 fprintf (stderr, "mmap (%s, %x) -> %x\n", old_name, stat_buf.st_size,
561 old_base);
562#endif
563
564 /* Get pointers to headers & section names */
565
566 old_file_h = (ElfW(Ehdr) *) old_base;
567 old_program_h = (ElfW(Phdr) *) ((byte *) old_base + old_file_h->e_phoff);
568 old_section_h = (ElfW(Shdr) *) ((byte *) old_base + old_file_h->e_shoff);
569 old_section_names = (char *) old_base
570 + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset;
571
572 /* Find the old .bss section. Figure out parameters of the new
573 * data2 and bss sections.
574 */
575
576 for (old_bss_index = 1; old_bss_index < (int) old_file_h->e_shnum;
577 old_bss_index++)
578 {
579#ifdef DEBUG
580 fprintf (stderr, "Looking for .bss - found %s\n",
581 old_section_names + OLD_SECTION_H (old_bss_index).sh_name);
582#endif
583 if (!strcmp (old_section_names + OLD_SECTION_H (old_bss_index).sh_name,
584 ELF_BSS_SECTION_NAME))
585 break;
586 }
587 if (old_bss_index == old_file_h->e_shnum)
588 fatal ("Can't find .bss in %s.\n", old_name, 0);
589
590 old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr;
591 old_bss_size = OLD_SECTION_H (old_bss_index).sh_size;
592#if defined(emacs) || !defined(DEBUG)
593 new_bss_addr = (ElfW(Addr)) sbrk (0);
594#else
595 new_bss_addr = old_bss_addr + old_bss_size + 0x1234;
596#endif
597 new_data2_addr = old_bss_addr;
598 new_data2_size = new_bss_addr - old_bss_addr;
599 new_data2_offset = OLD_SECTION_H (old_bss_index).sh_offset;
600
601#ifdef DEBUG
602 fprintf (stderr, "old_bss_index %d\n", old_bss_index);
603 fprintf (stderr, "old_bss_addr %x\n", old_bss_addr);
604 fprintf (stderr, "old_bss_size %x\n", old_bss_size);
605 fprintf (stderr, "new_bss_addr %x\n", new_bss_addr);
606 fprintf (stderr, "new_data2_addr %x\n", new_data2_addr);
607 fprintf (stderr, "new_data2_size %x\n", new_data2_size);
608 fprintf (stderr, "new_data2_offset %x\n", new_data2_offset);
609#endif
610
611 if ((unsigned) new_bss_addr < (unsigned) old_bss_addr + old_bss_size)
612 fatal (".bss shrank when undumping???\n", 0, 0);
613
614 /* Set the output file to the right size and mmap it. Set
615 * pointers to various interesting objects. stat_buf still has
616 * old_file data.
617 */
618
619 new_file = open (new_name, O_RDWR | O_CREAT, 0666);
620 if (new_file < 0)
621 fatal ("Can't creat (%s): errno %d\n", new_name, errno);
622
623 new_file_size = stat_buf.st_size + old_file_h->e_shentsize + new_data2_size;
624
625 if (ftruncate (new_file, new_file_size))
626 fatal ("Can't ftruncate (%s): errno %d\n", new_name, errno);
627
628#ifdef UNEXEC_USE_MAP_PRIVATE
629 new_base = mmap (0, new_file_size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
630 new_file, 0);
631#else
632 new_base = mmap (0, new_file_size, PROT_READ | PROT_WRITE, MAP_SHARED,
633 new_file, 0);
634#endif
635
636 if (new_base == (caddr_t) -1)
637 fatal ("Can't mmap (%s): errno %d\n", new_name, errno);
638
639 new_file_h = (ElfW(Ehdr) *) new_base;
640 new_program_h = (ElfW(Phdr) *) ((byte *) new_base + old_file_h->e_phoff);
641 new_section_h = (ElfW(Shdr) *)
642 ((byte *) new_base + old_file_h->e_shoff + new_data2_size);
643
644 /* Make our new file, program and section headers as copies of the
645 * originals.
646 */
647
648 memcpy (new_file_h, old_file_h, old_file_h->e_ehsize);
649 memcpy (new_program_h, old_program_h,
650 old_file_h->e_phnum * old_file_h->e_phentsize);
651
652 /* Modify the e_shstrndx if necessary. */
653 PATCH_INDEX (new_file_h->e_shstrndx);
654
655 /* Fix up file header. We'll add one section. Section header is
656 * further away now.
657 */
658
659 new_file_h->e_shoff += new_data2_size;
660 new_file_h->e_shnum += 1;
661
662#ifdef DEBUG
663 fprintf (stderr, "Old section offset %x\n", old_file_h->e_shoff);
664 fprintf (stderr, "Old section count %d\n", old_file_h->e_shnum);
665 fprintf (stderr, "New section offset %x\n", new_file_h->e_shoff);
666 fprintf (stderr, "New section count %d\n", new_file_h->e_shnum);
667#endif
668
669 /* Fix up a new program header. Extend the writable data segment so
670 * that the bss area is covered too. Find that segment by looking
671 * for a segment that ends just before the .bss area. Make sure
672 * that no segments are above the new .data2. Put a loop at the end
673 * to adjust the offset and address of any segment that is above
674 * data2, just in case we decide to allow this later.
675 */
676
677 for (n = new_file_h->e_phnum - 1; n >= 0; n--)
678 {
679 /* Compute maximum of all requirements for alignment of section. */
680 int alignment = (NEW_PROGRAM_H (n)).p_align;
681 if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment)
682 alignment = OLD_SECTION_H (old_bss_index).sh_addralign;
683
684 if (NEW_PROGRAM_H (n).p_vaddr + NEW_PROGRAM_H (n).p_filesz > old_bss_addr)
685 fatal ("Program segment above .bss in %s\n", old_name, 0);
686
687 if (NEW_PROGRAM_H (n).p_type == PT_LOAD
688 && (round_up ((NEW_PROGRAM_H (n)).p_vaddr
689 + (NEW_PROGRAM_H (n)).p_filesz,
690 alignment)
691 == round_up (old_bss_addr, alignment)))
692 break;
693 }
694 if (n < 0)
695 fatal ("Couldn't find segment next to .bss in %s\n", old_name, 0);
696
697 NEW_PROGRAM_H (n).p_filesz += new_data2_size;
698 NEW_PROGRAM_H (n).p_memsz = NEW_PROGRAM_H (n).p_filesz;
699
700#if 0 /* Maybe allow section after data2 - does this ever happen? */
701 for (n = new_file_h->e_phnum - 1; n >= 0; n--)
702 {
703 if (NEW_PROGRAM_H (n).p_vaddr
704 && NEW_PROGRAM_H (n).p_vaddr >= new_data2_addr)
705 NEW_PROGRAM_H (n).p_vaddr += new_data2_size - old_bss_size;
706
707 if (NEW_PROGRAM_H (n).p_offset >= new_data2_offset)
708 NEW_PROGRAM_H (n).p_offset += new_data2_size;
709 }
710#endif
711
712 /* Fix up section headers based on new .data2 section. Any section
713 * whose offset or virtual address is after the new .data2 section
714 * gets its value adjusted. .bss size becomes zero and new address
715 * is set. data2 section header gets added by copying the existing
716 * .data header and modifying the offset, address and size.
717 */
718 for (old_data_index = 1; old_data_index < (int) old_file_h->e_shnum;
719 old_data_index++)
720 if (!strcmp (old_section_names + OLD_SECTION_H (old_data_index).sh_name,
721 ".data"))
722 break;
723 if (old_data_index == old_file_h->e_shnum)
724 fatal ("Can't find .data in %s.\n", old_name, 0);
725
726 /* Walk through all section headers, insert the new data2 section right
727 before the new bss section. */
728 for (n = 1, nn = 1; n < (int) old_file_h->e_shnum; n++, nn++)
729 {
730 caddr_t src;
731 /* If it is bss section, insert the new data2 section before it. */
732 if (n == old_bss_index)
733 {
734 /* Steal the data section header for this data2 section. */
735 memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (old_data_index),
736 new_file_h->e_shentsize);
737
738 NEW_SECTION_H (nn).sh_addr = new_data2_addr;
739 NEW_SECTION_H (nn).sh_offset = new_data2_offset;
740 NEW_SECTION_H (nn).sh_size = new_data2_size;
741 /* Use the bss section's alignment. This will assure that the
742 new data2 section always be placed in the same spot as the old
743 bss section by any other application. */
744 NEW_SECTION_H (nn).sh_addralign = OLD_SECTION_H (n).sh_addralign;
745
746 /* Now copy over what we have in the memory now. */
747 memcpy (NEW_SECTION_H (nn).sh_offset + new_base,
748 (caddr_t) OLD_SECTION_H (n).sh_addr,
749 new_data2_size);
750 nn++;
751 }
752
753 memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (n),
754 old_file_h->e_shentsize);
755
756 /* The new bss section's size is zero, and its file offset and virtual
757 address should be off by NEW_DATA2_SIZE. */
758 if (n == old_bss_index)
759 {
760 /* NN should be `old_bss_index + 1' at this point. */
761 NEW_SECTION_H (nn).sh_offset += new_data2_size;
762 NEW_SECTION_H (nn).sh_addr += new_data2_size;
763 /* Let the new bss section address alignment be the same as the
764 section address alignment followed the old bss section, so
765 this section will be placed in exactly the same place. */
766 NEW_SECTION_H (nn).sh_addralign = OLD_SECTION_H (nn).sh_addralign;
767 NEW_SECTION_H (nn).sh_size = 0;
768 }
769 else
770 {
771 /* Any section that was original placed AFTER the bss
772 section should now be off by NEW_DATA2_SIZE. */
773#ifdef SOLARIS_POWERPC
774 /* On PPC Reference Platform running Solaris 2.5.1
775 the plt section is also of type NOBI like the bss section.
776 (not really stored) and therefore sections after the bss
777 section start at the plt offset. The plt section is always
778 the one just before the bss section.
779 It would be better to put the new data section before
780 the .plt section, or use libelf instead.
781 Erik Deumens, deumens@qtp.ufl.edu. */
782 if (NEW_SECTION_H (nn).sh_offset
783 >= OLD_SECTION_H (old_bss_index-1).sh_offset)
784 NEW_SECTION_H (nn).sh_offset += new_data2_size;
785#else
786 if (round_up (NEW_SECTION_H (nn).sh_offset,
787 OLD_SECTION_H (old_bss_index).sh_addralign)
788 >= new_data2_offset)
789 NEW_SECTION_H (nn).sh_offset += new_data2_size;
790#endif
791 /* Any section that was originally placed after the section
792 header table should now be off by the size of one section
793 header table entry. */
794 if (NEW_SECTION_H (nn).sh_offset > new_file_h->e_shoff)
795 NEW_SECTION_H (nn).sh_offset += new_file_h->e_shentsize;
796 }
797
798 /* If any section hdr refers to the section after the new .data
799 section, make it refer to next one because we have inserted
800 a new section in between. */
801
802 PATCH_INDEX (NEW_SECTION_H (nn).sh_link);
803 /* For symbol tables, info is a symbol table index,
804 so don't change it. */
805 if (NEW_SECTION_H (nn).sh_type != SHT_SYMTAB
806 && NEW_SECTION_H (nn).sh_type != SHT_DYNSYM)
807 PATCH_INDEX (NEW_SECTION_H (nn).sh_info);
808
809 /* Now, start to copy the content of sections. */
810 if (NEW_SECTION_H (nn).sh_type == SHT_NULL
811 || NEW_SECTION_H (nn).sh_type == SHT_NOBITS)
812 continue;
813
814 /* Write out the sections. .data and .data1 (and data2, called
815 ".data" in the strings table) get copied from the current process
816 instead of the old file. */
817 if (!strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data")
818 || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
819 ".data1"))
820 src = (caddr_t) OLD_SECTION_H (n).sh_addr;
821 else
822 src = old_base + OLD_SECTION_H (n).sh_offset;
823
824 memcpy (NEW_SECTION_H (nn).sh_offset + new_base, src,
825 NEW_SECTION_H (nn).sh_size);
826
827#ifdef __alpha__
828 /* Update Alpha COFF symbol table: */
829 if (strcmp (old_section_names + OLD_SECTION_H (n).sh_name, ".mdebug")
830 == 0)
831 {
832 pHDRR symhdr = (pHDRR) (NEW_SECTION_H (nn).sh_offset + new_base);
833
834 symhdr->cbLineOffset += new_data2_size;
835 symhdr->cbDnOffset += new_data2_size;
836 symhdr->cbPdOffset += new_data2_size;
837 symhdr->cbSymOffset += new_data2_size;
838 symhdr->cbOptOffset += new_data2_size;
839 symhdr->cbAuxOffset += new_data2_size;
840 symhdr->cbSsOffset += new_data2_size;
841 symhdr->cbSsExtOffset += new_data2_size;
842 symhdr->cbFdOffset += new_data2_size;
843 symhdr->cbRfdOffset += new_data2_size;
844 symhdr->cbExtOffset += new_data2_size;
845 }
846#endif /* __alpha__ */
847
848 /* If it is the symbol table, its st_shndx field needs to be patched. */
849 if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB
850 || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM)
851 {
852 ElfW(Shdr) *spt = &NEW_SECTION_H (nn);
853 unsigned int num = spt->sh_size / spt->sh_entsize;
854 ElfW(Sym) * sym = (ElfW(Sym) *) (NEW_SECTION_H (nn).sh_offset +
855 new_base);
856 for (; num--; sym++)
857 {
858 if ((sym->st_shndx == SHN_UNDEF)
859 || (sym->st_shndx == SHN_ABS)
860 || (sym->st_shndx == SHN_COMMON))
861 continue;
862
863 PATCH_INDEX (sym->st_shndx);
864 }
865 }
866 }
867
868 /* Update the symbol values of _edata and _end. */
869 for (n = new_file_h->e_shnum - 1; n; n--)
870 {
871 byte *symnames;
872 ElfW(Sym) *symp, *symendp;
873
874 if (NEW_SECTION_H (n).sh_type != SHT_DYNSYM
875 && NEW_SECTION_H (n).sh_type != SHT_SYMTAB)
876 continue;
877
878 symnames = ((byte *) new_base
879 + NEW_SECTION_H (NEW_SECTION_H (n).sh_link).sh_offset);
880 symp = (ElfW(Sym) *) (NEW_SECTION_H (n).sh_offset + new_base);
881 symendp = (ElfW(Sym) *) ((byte *)symp + NEW_SECTION_H (n).sh_size);
882
883 for (; symp < symendp; symp ++)
884 if (strcmp ((char *) (symnames + symp->st_name), "_end") == 0
885 || strcmp ((char *) (symnames + symp->st_name), "_edata") == 0)
886 memcpy (&symp->st_value, &new_bss_addr, sizeof (new_bss_addr));
887 }
888
889 /* This loop seeks out relocation sections for the data section, so
890 that it can undo relocations performed by the runtime linker. */
891 for (n = new_file_h->e_shnum - 1; n; n--)
892 {
893 ElfW(Shdr) section = NEW_SECTION_H (n);
894 switch (section.sh_type) {
895 default:
896 break;
897 case SHT_REL:
898 case SHT_RELA:
899 /* This code handles two different size structs, but there should
900 be no harm in that provided that r_offset is always the first
901 member. */
902 nn = section.sh_info;
903 if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data")
904 || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
905 ".data1"))
906 {
907 ElfW(Addr) offset = NEW_SECTION_H (nn).sh_addr -
908 NEW_SECTION_H (nn).sh_offset;
909 caddr_t reloc = old_base + section.sh_offset, end;
910 for (end = reloc + section.sh_size; reloc < end;
911 reloc += section.sh_entsize)
912 {
913 ElfW(Addr) addr = ((ElfW(Rel) *) reloc)->r_offset - offset;
914#ifdef __alpha__
915 /* The Alpha ELF binutils currently have a bug that
916 sometimes results in relocs that contain all
917 zeroes. Work around this for now... */
918 if (((ElfW(Rel) *) reloc)->r_offset == 0)
919 continue;
920#endif
921 memcpy (new_base + addr, old_base + addr, sizeof(ElfW(Addr)));
922 }
923 }
924 break;
925 }
926 }
927
928#ifdef UNEXEC_USE_MAP_PRIVATE
929 if (lseek (new_file, 0, SEEK_SET) == -1)
930 fatal ("Can't rewind (%s): errno %d\n", new_name, errno);
931
932 if (write (new_file, new_base, new_file_size) != new_file_size)
933 fatal ("Can't write (%s): errno %d\n", new_name, errno);
934#endif
935
936 /* Close the files and make the new file executable. */
937
938 if (close (old_file))
939 fatal ("Can't close (%s): errno %d\n", old_name, errno);
940
941 if (close (new_file))
942 fatal ("Can't close (%s): errno %d\n", new_name, errno);
943
944 if (stat (new_name, &stat_buf) == -1)
945 fatal ("Can't stat (%s): errno %d\n", new_name, errno);
946
947 n = umask (777);
948 umask (n);
949 stat_buf.st_mode |= 0111 & ~n;
950 if (chmod (new_name, stat_buf.st_mode) == -1)
951 fatal ("Can't chmod (%s): errno %d\n", new_name, errno);
952}
diff --git a/src/unexsgi.c b/src/unexsgi.c
deleted file mode 100644
index cd0067f08d9..00000000000
--- a/src/unexsgi.c
+++ /dev/null
@@ -1,900 +0,0 @@
1/* Copyright (C) 1985, 1986, 1987, 1988, 1990, 1992
2 Free Software Foundation, Inc.
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA.
20
21In other words, you are welcome to use, share and improve this program.
22You are forbidden to forbid anyone else to use, share and improve
23what you give them. Help stamp out software-hoarding! */
24
25
26/*
27 * unexec.c - Convert a running program into an a.out file.
28 *
29 * Author: Spencer W. Thomas
30 * Computer Science Dept.
31 * University of Utah
32 * Date: Tue Mar 2 1982
33 * Modified heavily since then.
34 *
35 * Synopsis:
36 * unexec (new_name, a_name, data_start, bss_start, entry_address)
37 * char *new_name, *a_name;
38 * unsigned data_start, bss_start, entry_address;
39 *
40 * Takes a snapshot of the program and makes an a.out format file in the
41 * file named by the string argument new_name.
42 * If a_name is non-NULL, the symbol table will be taken from the given file.
43 * On some machines, an existing a_name file is required.
44 *
45 * The boundaries within the a.out file may be adjusted with the data_start
46 * and bss_start arguments. Either or both may be given as 0 for defaults.
47 *
48 * Data_start gives the boundary between the text segment and the data
49 * segment of the program. The text segment can contain shared, read-only
50 * program code and literal data, while the data segment is always unshared
51 * and unprotected. Data_start gives the lowest unprotected address.
52 * The value you specify may be rounded down to a suitable boundary
53 * as required by the machine you are using.
54 *
55 * Specifying zero for data_start means the boundary between text and data
56 * should not be the same as when the program was loaded.
57 * If NO_REMAP is defined, the argument data_start is ignored and the
58 * segment boundaries are never changed.
59 *
60 * Bss_start indicates how much of the data segment is to be saved in the
61 * a.out file and restored when the program is executed. It gives the lowest
62 * unsaved address, and is rounded up to a page boundary. The default when 0
63 * is given assumes that the entire data segment is to be stored, including
64 * the previous data and bss as well as any additional storage allocated with
65 * break (2).
66 *
67 * The new file is set up to start at entry_address.
68 *
69 * If you make improvements I'd like to get them too.
70 * harpo!utah-cs!thomas, thomas@Utah-20
71 *
72 */
73
74/* Even more heavily modified by james@bigtex.cactus.org of Dell Computer Co.
75 * ELF support added.
76 *
77 * Basic theory: the data space of the running process needs to be
78 * dumped to the output file. Normally we would just enlarge the size
79 * of .data, scooting everything down. But we can't do that in ELF,
80 * because there is often something between the .data space and the
81 * .bss space.
82 *
83 * In the temacs dump below, notice that the Global Offset Table
84 * (.got) and the Dynamic link data (.dynamic) come between .data1 and
85 * .bss. It does not work to overlap .data with these fields.
86 *
87 * The solution is to create a new .data segment. This segment is
88 * filled with data from the current process. Since the contents of
89 * various sections refer to sections by index, the new .data segment
90 * is made the last in the table to avoid changing any existing index.
91
92 * This is an example of how the section headers are changed. "Addr"
93 * is a process virtual address. "Offset" is a file offset.
94
95raid:/nfs/raid/src/dist-18.56/src> dump -h temacs
96
97temacs:
98
99 **** SECTION HEADER TABLE ****
100[No] Type Flags Addr Offset Size Name
101 Link Info Adralgn Entsize
102
103[1] 1 2 0x80480d4 0xd4 0x13 .interp
104 0 0 0x1 0
105
106[2] 5 2 0x80480e8 0xe8 0x388 .hash
107 3 0 0x4 0x4
108
109[3] 11 2 0x8048470 0x470 0x7f0 .dynsym
110 4 1 0x4 0x10
111
112[4] 3 2 0x8048c60 0xc60 0x3ad .dynstr
113 0 0 0x1 0
114
115[5] 9 2 0x8049010 0x1010 0x338 .rel.plt
116 3 7 0x4 0x8
117
118[6] 1 6 0x8049348 0x1348 0x3 .init
119 0 0 0x4 0
120
121[7] 1 6 0x804934c 0x134c 0x680 .plt
122 0 0 0x4 0x4
123
124[8] 1 6 0x80499cc 0x19cc 0x3c56f .text
125 0 0 0x4 0
126
127[9] 1 6 0x8085f3c 0x3df3c 0x3 .fini
128 0 0 0x4 0
129
130[10] 1 2 0x8085f40 0x3df40 0x69c .rodata
131 0 0 0x4 0
132
133[11] 1 2 0x80865dc 0x3e5dc 0xd51 .rodata1
134 0 0 0x4 0
135
136[12] 1 3 0x8088330 0x3f330 0x20afc .data
137 0 0 0x4 0
138
139[13] 1 3 0x80a8e2c 0x5fe2c 0x89d .data1
140 0 0 0x4 0
141
142[14] 1 3 0x80a96cc 0x606cc 0x1a8 .got
143 0 0 0x4 0x4
144
145[15] 6 3 0x80a9874 0x60874 0x80 .dynamic
146 4 0 0x4 0x8
147
148[16] 8 3 0x80a98f4 0x608f4 0x449c .bss
149 0 0 0x4 0
150
151[17] 2 0 0 0x608f4 0x9b90 .symtab
152 18 371 0x4 0x10
153
154[18] 3 0 0 0x6a484 0x8526 .strtab
155 0 0 0x1 0
156
157[19] 3 0 0 0x729aa 0x93 .shstrtab
158 0 0 0x1 0
159
160[20] 1 0 0 0x72a3d 0x68b7 .comment
161 0 0 0x1 0
162
163raid:/nfs/raid/src/dist-18.56/src> dump -h xemacs
164
165xemacs:
166
167 **** SECTION HEADER TABLE ****
168[No] Type Flags Addr Offset Size Name
169 Link Info Adralgn Entsize
170
171[1] 1 2 0x80480d4 0xd4 0x13 .interp
172 0 0 0x1 0
173
174[2] 5 2 0x80480e8 0xe8 0x388 .hash
175 3 0 0x4 0x4
176
177[3] 11 2 0x8048470 0x470 0x7f0 .dynsym
178 4 1 0x4 0x10
179
180[4] 3 2 0x8048c60 0xc60 0x3ad .dynstr
181 0 0 0x1 0
182
183[5] 9 2 0x8049010 0x1010 0x338 .rel.plt
184 3 7 0x4 0x8
185
186[6] 1 6 0x8049348 0x1348 0x3 .init
187 0 0 0x4 0
188
189[7] 1 6 0x804934c 0x134c 0x680 .plt
190 0 0 0x4 0x4
191
192[8] 1 6 0x80499cc 0x19cc 0x3c56f .text
193 0 0 0x4 0
194
195[9] 1 6 0x8085f3c 0x3df3c 0x3 .fini
196 0 0 0x4 0
197
198[10] 1 2 0x8085f40 0x3df40 0x69c .rodata
199 0 0 0x4 0
200
201[11] 1 2 0x80865dc 0x3e5dc 0xd51 .rodata1
202 0 0 0x4 0
203
204[12] 1 3 0x8088330 0x3f330 0x20afc .data
205 0 0 0x4 0
206
207[13] 1 3 0x80a8e2c 0x5fe2c 0x89d .data1
208 0 0 0x4 0
209
210[14] 1 3 0x80a96cc 0x606cc 0x1a8 .got
211 0 0 0x4 0x4
212
213[15] 6 3 0x80a9874 0x60874 0x80 .dynamic
214 4 0 0x4 0x8
215
216[16] 8 3 0x80c6800 0x7d800 0 .bss
217 0 0 0x4 0
218
219[17] 2 0 0 0x7d800 0x9b90 .symtab
220 18 371 0x4 0x10
221
222[18] 3 0 0 0x87390 0x8526 .strtab
223 0 0 0x1 0
224
225[19] 3 0 0 0x8f8b6 0x93 .shstrtab
226 0 0 0x1 0
227
228[20] 1 0 0 0x8f949 0x68b7 .comment
229 0 0 0x1 0
230
231[21] 1 3 0x80a98f4 0x608f4 0x1cf0c .data
232 0 0 0x4 0
233
234 * This is an example of how the file header is changed. "Shoff" is
235 * the section header offset within the file. Since that table is
236 * after the new .data section, it is moved. "Shnum" is the number of
237 * sections, which we increment.
238 *
239 * "Phoff" is the file offset to the program header. "Phentsize" and
240 * "Shentsz" are the program and section header entries sizes respectively.
241 * These can be larger than the apparent struct sizes.
242
243raid:/nfs/raid/src/dist-18.56/src> dump -f temacs
244
245temacs:
246
247 **** ELF HEADER ****
248Class Data Type Machine Version
249Entry Phoff Shoff Flags Ehsize
250Phentsize Phnum Shentsz Shnum Shstrndx
251
2521 1 2 3 1
2530x80499cc 0x34 0x792f4 0 0x34
2540x20 5 0x28 21 19
255
256raid:/nfs/raid/src/dist-18.56/src> dump -f xemacs
257
258xemacs:
259
260 **** ELF HEADER ****
261Class Data Type Machine Version
262Entry Phoff Shoff Flags Ehsize
263Phentsize Phnum Shentsz Shnum Shstrndx
264
2651 1 2 3 1
2660x80499cc 0x34 0x96200 0 0x34
2670x20 5 0x28 22 19
268
269 * These are the program headers. "Offset" is the file offset to the
270 * segment. "Vaddr" is the memory load address. "Filesz" is the
271 * segment size as it appears in the file, and "Memsz" is the size in
272 * memory. Below, the third segment is the code and the fourth is the
273 * data: the difference between Filesz and Memsz is .bss
274
275raid:/nfs/raid/src/dist-18.56/src> dump -o temacs
276
277temacs:
278 ***** PROGRAM EXECUTION HEADER *****
279Type Offset Vaddr Paddr
280Filesz Memsz Flags Align
281
2826 0x34 0x8048034 0
2830xa0 0xa0 5 0
284
2853 0xd4 0 0
2860x13 0 4 0
287
2881 0x34 0x8048034 0
2890x3f2f9 0x3f2f9 5 0x1000
290
2911 0x3f330 0x8088330 0
2920x215c4 0x25a60 7 0x1000
293
2942 0x60874 0x80a9874 0
2950x80 0 7 0
296
297raid:/nfs/raid/src/dist-18.56/src> dump -o xemacs
298
299xemacs:
300 ***** PROGRAM EXECUTION HEADER *****
301Type Offset Vaddr Paddr
302Filesz Memsz Flags Align
303
3046 0x34 0x8048034 0
3050xa0 0xa0 5 0
306
3073 0xd4 0 0
3080x13 0 4 0
309
3101 0x34 0x8048034 0
3110x3f2f9 0x3f2f9 5 0x1000
312
3131 0x3f330 0x8088330 0
3140x3e4d0 0x3e4d0 7 0x1000
315
3162 0x60874 0x80a9874 0
3170x80 0 7 0
318
319
320 */
321
322/* Modified by wtien@urbana.mcd.mot.com of Motorola Inc.
323 *
324 * The above mechanism does not work if the unexeced ELF file is being
325 * re-layout by other applications (such as `strip'). All the applications
326 * that re-layout the internal of ELF will layout all sections in ascending
327 * order of their file offsets. After the re-layout, the data2 section will
328 * still be the LAST section in the section header vector, but its file offset
329 * is now being pushed far away down, and causes part of it not to be mapped
330 * in (ie. not covered by the load segment entry in PHDR vector), therefore
331 * causes the new binary to fail.
332 *
333 * The solution is to modify the unexec algorithm to insert the new data2
334 * section header right before the new bss section header, so their file
335 * offsets will be in the ascending order. Since some of the section's (all
336 * sections AFTER the bss section) indexes are now changed, we also need to
337 * modify some fields to make them point to the right sections. This is done
338 * by macro PATCH_INDEX. All the fields that need to be patched are:
339 *
340 * 1. ELF header e_shstrndx field.
341 * 2. section header sh_link and sh_info field.
342 * 3. symbol table entry st_shndx field.
343 *
344 * The above example now should look like:
345
346 **** SECTION HEADER TABLE ****
347[No] Type Flags Addr Offset Size Name
348 Link Info Adralgn Entsize
349
350[1] 1 2 0x80480d4 0xd4 0x13 .interp
351 0 0 0x1 0
352
353[2] 5 2 0x80480e8 0xe8 0x388 .hash
354 3 0 0x4 0x4
355
356[3] 11 2 0x8048470 0x470 0x7f0 .dynsym
357 4 1 0x4 0x10
358
359[4] 3 2 0x8048c60 0xc60 0x3ad .dynstr
360 0 0 0x1 0
361
362[5] 9 2 0x8049010 0x1010 0x338 .rel.plt
363 3 7 0x4 0x8
364
365[6] 1 6 0x8049348 0x1348 0x3 .init
366 0 0 0x4 0
367
368[7] 1 6 0x804934c 0x134c 0x680 .plt
369 0 0 0x4 0x4
370
371[8] 1 6 0x80499cc 0x19cc 0x3c56f .text
372 0 0 0x4 0
373
374[9] 1 6 0x8085f3c 0x3df3c 0x3 .fini
375 0 0 0x4 0
376
377[10] 1 2 0x8085f40 0x3df40 0x69c .rodata
378 0 0 0x4 0
379
380[11] 1 2 0x80865dc 0x3e5dc 0xd51 .rodata1
381 0 0 0x4 0
382
383[12] 1 3 0x8088330 0x3f330 0x20afc .data
384 0 0 0x4 0
385
386[13] 1 3 0x80a8e2c 0x5fe2c 0x89d .data1
387 0 0 0x4 0
388
389[14] 1 3 0x80a96cc 0x606cc 0x1a8 .got
390 0 0 0x4 0x4
391
392[15] 6 3 0x80a9874 0x60874 0x80 .dynamic
393 4 0 0x4 0x8
394
395[16] 1 3 0x80a98f4 0x608f4 0x1cf0c .data
396 0 0 0x4 0
397
398[17] 8 3 0x80c6800 0x7d800 0 .bss
399 0 0 0x4 0
400
401[18] 2 0 0 0x7d800 0x9b90 .symtab
402 19 371 0x4 0x10
403
404[19] 3 0 0 0x87390 0x8526 .strtab
405 0 0 0x1 0
406
407[20] 3 0 0 0x8f8b6 0x93 .shstrtab
408 0 0 0x1 0
409
410[21] 1 0 0 0x8f949 0x68b7 .comment
411 0 0 0x1 0
412
413 */
414
415#include <config.h>
416#include <sys/types.h>
417#include <stdio.h>
418#include <sys/stat.h>
419#include <memory.h>
420#include <string.h>
421#include <errno.h>
422#include <unistd.h>
423#include <fcntl.h>
424#include <elf.h>
425#include <syms.h> /* for HDRR declaration */
426#include <sys/mman.h>
427
428#ifndef emacs
429#define fatal(a, b, c) fprintf(stderr, a, b, c), exit(1)
430#else
431extern void fatal(char *, ...);
432#endif
433
434/* Get the address of a particular section or program header entry,
435 * accounting for the size of the entries.
436 */
437
438#define OLD_SECTION_H(n) \
439 (*(Elf32_Shdr *) ((byte *) old_section_h + old_file_h->e_shentsize * (n)))
440#define NEW_SECTION_H(n) \
441 (*(Elf32_Shdr *) ((byte *) new_section_h + new_file_h->e_shentsize * (n)))
442#define OLD_PROGRAM_H(n) \
443 (*(Elf32_Phdr *) ((byte *) old_program_h + old_file_h->e_phentsize * (n)))
444#define NEW_PROGRAM_H(n) \
445 (*(Elf32_Phdr *) ((byte *) new_program_h + new_file_h->e_phentsize * (n)))
446
447#define PATCH_INDEX(n) \
448 do { \
449 if ((n) >= old_bss_index) \
450 (n)++; } while (0)
451typedef unsigned char byte;
452
453/* Round X up to a multiple of Y. */
454
455int
456round_up (x, y)
457 int x, y;
458{
459 int rem = x % y;
460 if (rem == 0)
461 return x;
462 return x - rem + y;
463}
464
465/* Return the index of the section named NAME.
466 SECTION_NAMES, FILE_NAME and FILE_H give information
467 about the file we are looking in.
468
469 If we don't find the section NAME, that is a fatal error
470 if NOERROR is 0; we return -1 if NOERROR is nonzero. */
471
472static int
473find_section (name, section_names, file_name, old_file_h, old_section_h, noerror)
474 char *name;
475 char *section_names;
476 char *file_name;
477 Elf32_Ehdr *old_file_h;
478 Elf32_Shdr *old_section_h;
479 int noerror;
480{
481 int idx;
482
483 for (idx = 1; idx < old_file_h->e_shnum; idx++)
484 {
485#ifdef DEBUG
486 fprintf (stderr, "Looking for %s - found %s\n", name,
487 section_names + OLD_SECTION_H (idx).sh_name);
488#endif
489 if (!strcmp (section_names + OLD_SECTION_H (idx).sh_name,
490 name))
491 break;
492 }
493 if (idx == old_file_h->e_shnum)
494 {
495 if (noerror)
496 return -1;
497 else
498 fatal ("Can't find .bss in %s.\n", file_name, 0);
499 }
500
501 return idx;
502}
503
504/* ****************************************************************
505 * unexec
506 *
507 * driving logic.
508 *
509 * In ELF, this works by replacing the old .bss section with a new
510 * .data section, and inserting an empty .bss immediately afterwards.
511 *
512 */
513void
514unexec (new_name, old_name, data_start, bss_start, entry_address)
515 char *new_name, *old_name;
516 unsigned data_start, bss_start, entry_address;
517{
518 extern unsigned int bss_end;
519 int new_file, old_file, new_file_size;
520
521 /* Pointers to the base of the image of the two files. */
522 caddr_t old_base, new_base;
523
524 /* Pointers to the file, program and section headers for the old and new
525 files. */
526 Elf32_Ehdr *old_file_h, *new_file_h;
527 Elf32_Phdr *old_program_h, *new_program_h;
528 Elf32_Shdr *old_section_h, *new_section_h;
529
530 /* Point to the section name table in the old file. */
531 char *old_section_names;
532
533 Elf32_Addr old_bss_addr, new_bss_addr;
534 Elf32_Word old_bss_size, new_data2_size;
535 Elf32_Off new_data2_offset;
536 Elf32_Addr new_data2_addr;
537 Elf32_Addr new_offsets_shift;
538
539 int n, nn, old_bss_index, old_data_index, new_data2_index;
540 int old_mdebug_index;
541 struct stat stat_buf;
542
543 /* Open the old file & map it into the address space. */
544
545 old_file = open (old_name, O_RDONLY);
546
547 if (old_file < 0)
548 fatal ("Can't open %s for reading: errno %d\n", old_name, errno);
549
550 if (fstat (old_file, &stat_buf) == -1)
551 fatal ("Can't fstat(%s): errno %d\n", old_name, errno);
552
553 old_base = mmap (0, stat_buf.st_size, PROT_READ, MAP_SHARED, old_file, 0);
554
555 if (old_base == (caddr_t) -1)
556 fatal ("Can't mmap(%s): errno %d\n", old_name, errno);
557
558#ifdef DEBUG
559 fprintf (stderr, "mmap(%s, %x) -> %x\n", old_name, stat_buf.st_size,
560 old_base);
561#endif
562
563 /* Get pointers to headers & section names. */
564
565 old_file_h = (Elf32_Ehdr *) old_base;
566 old_program_h = (Elf32_Phdr *) ((byte *) old_base + old_file_h->e_phoff);
567 old_section_h = (Elf32_Shdr *) ((byte *) old_base + old_file_h->e_shoff);
568 old_section_names
569 = (char *) old_base + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset;
570
571 /* Find the mdebug section, if any. */
572
573 old_mdebug_index = find_section (".mdebug", old_section_names,
574 old_name, old_file_h, old_section_h, 1);
575
576 /* Find the old .bss section. */
577
578 old_bss_index = find_section (".bss", old_section_names,
579 old_name, old_file_h, old_section_h, 0);
580
581 /* Find the old .data section. Figure out parameters of
582 the new data2 and bss sections. */
583
584 old_data_index = find_section (".data", old_section_names,
585 old_name, old_file_h, old_section_h, 0);
586
587 old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr;
588 old_bss_size = OLD_SECTION_H (old_bss_index).sh_size;
589#if defined(emacs) || !defined(DEBUG)
590 bss_end = (unsigned int) sbrk (0);
591 new_bss_addr = (Elf32_Addr) bss_end;
592#else
593 new_bss_addr = old_bss_addr + old_bss_size + 0x1234;
594#endif
595 new_data2_addr = old_bss_addr;
596 new_data2_size = new_bss_addr - old_bss_addr;
597 new_data2_offset = OLD_SECTION_H (old_data_index).sh_offset +
598 (new_data2_addr - OLD_SECTION_H (old_data_index).sh_addr);
599 new_offsets_shift = new_bss_addr -
600 ((old_bss_addr & ~0xfff) + ((old_bss_addr & 0xfff) ? 0x1000 : 0));
601
602#ifdef DEBUG
603 fprintf (stderr, "old_bss_index %d\n", old_bss_index);
604 fprintf (stderr, "old_bss_addr %x\n", old_bss_addr);
605 fprintf (stderr, "old_bss_size %x\n", old_bss_size);
606 fprintf (stderr, "new_bss_addr %x\n", new_bss_addr);
607 fprintf (stderr, "new_data2_addr %x\n", new_data2_addr);
608 fprintf (stderr, "new_data2_size %x\n", new_data2_size);
609 fprintf (stderr, "new_data2_offset %x\n", new_data2_offset);
610 fprintf (stderr, "new_offsets_shift %x\n", new_offsets_shift);
611#endif
612
613 if ((unsigned) new_bss_addr < (unsigned) old_bss_addr + old_bss_size)
614 fatal (".bss shrank when undumping???\n", 0, 0);
615
616 /* Set the output file to the right size and mmap it. Set
617 pointers to various interesting objects. stat_buf still has
618 old_file data. */
619
620 new_file = open (new_name, O_RDWR | O_CREAT, 0666);
621 if (new_file < 0)
622 fatal ("Can't creat (%s): errno %d\n", new_name, errno);
623
624 new_file_size = stat_buf.st_size + old_file_h->e_shentsize + new_offsets_shift;
625
626 if (ftruncate (new_file, new_file_size))
627 fatal ("Can't ftruncate (%s): errno %d\n", new_name, errno);
628
629 new_base = mmap (0, new_file_size, PROT_READ | PROT_WRITE, MAP_SHARED,
630 new_file, 0);
631
632 if (new_base == (caddr_t) -1)
633 fatal ("Can't mmap (%s): errno %d\n", new_name, errno);
634
635 new_file_h = (Elf32_Ehdr *) new_base;
636 new_program_h = (Elf32_Phdr *) ((byte *) new_base + old_file_h->e_phoff);
637 new_section_h
638 = (Elf32_Shdr *) ((byte *) new_base + old_file_h->e_shoff
639 + new_offsets_shift);
640
641 /* Make our new file, program and section headers as copies of the
642 originals. */
643
644 memcpy (new_file_h, old_file_h, old_file_h->e_ehsize);
645 memcpy (new_program_h, old_program_h,
646 old_file_h->e_phnum * old_file_h->e_phentsize);
647
648 /* Modify the e_shstrndx if necessary. */
649 PATCH_INDEX (new_file_h->e_shstrndx);
650
651 /* Fix up file header. We'll add one section. Section header is
652 further away now. */
653
654 new_file_h->e_shoff += new_offsets_shift;
655 new_file_h->e_shnum += 1;
656
657#ifdef DEBUG
658 fprintf (stderr, "Old section offset %x\n", old_file_h->e_shoff);
659 fprintf (stderr, "Old section count %d\n", old_file_h->e_shnum);
660 fprintf (stderr, "New section offset %x\n", new_file_h->e_shoff);
661 fprintf (stderr, "New section count %d\n", new_file_h->e_shnum);
662#endif
663
664 /* Fix up a new program header. Extend the writable data segment so
665 that the bss area is covered too. Find that segment by looking
666 for a segment that ends just before the .bss area. Make sure
667 that no segments are above the new .data2. Put a loop at the end
668 to adjust the offset and address of any segment that is above
669 data2, just in case we decide to allow this later. */
670
671 for (n = new_file_h->e_phnum - 1; n >= 0; n--)
672 {
673 /* Compute maximum of all requirements for alignment of section. */
674 int alignment = (NEW_PROGRAM_H (n)).p_align;
675 if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment)
676 alignment = OLD_SECTION_H (old_bss_index).sh_addralign;
677
678 /* Supposedly this condition is okay for the SGI. */
679#if 0
680 if (NEW_PROGRAM_H (n).p_vaddr + NEW_PROGRAM_H (n).p_filesz > old_bss_addr)
681 fatal ("Program segment above .bss in %s\n", old_name, 0);
682#endif
683
684 if (NEW_PROGRAM_H (n).p_type == PT_LOAD
685 && (round_up ((NEW_PROGRAM_H (n)).p_vaddr
686 + (NEW_PROGRAM_H (n)).p_filesz,
687 alignment)
688 == round_up (old_bss_addr, alignment)))
689 break;
690 }
691 if (n < 0)
692 fatal ("Couldn't find segment next to .bss in %s\n", old_name, 0);
693
694 NEW_PROGRAM_H (n).p_filesz += new_offsets_shift;
695 NEW_PROGRAM_H (n).p_memsz = NEW_PROGRAM_H (n).p_filesz;
696
697#if 1 /* Maybe allow section after data2 - does this ever happen? */
698 for (n = new_file_h->e_phnum - 1; n >= 0; n--)
699 {
700 if (NEW_PROGRAM_H (n).p_vaddr
701 && NEW_PROGRAM_H (n).p_vaddr >= new_data2_addr)
702 NEW_PROGRAM_H (n).p_vaddr += new_offsets_shift - old_bss_size;
703
704 if (NEW_PROGRAM_H (n).p_offset >= new_data2_offset)
705 NEW_PROGRAM_H (n).p_offset += new_offsets_shift;
706 }
707#endif
708
709 /* Fix up section headers based on new .data2 section. Any section
710 whose offset or virtual address is after the new .data2 section
711 gets its value adjusted. .bss size becomes zero and new address
712 is set. data2 section header gets added by copying the existing
713 .data header and modifying the offset, address and size. */
714 for (old_data_index = 1; old_data_index < old_file_h->e_shnum;
715 old_data_index++)
716 if (!strcmp (old_section_names + OLD_SECTION_H (old_data_index).sh_name,
717 ".data"))
718 break;
719 if (old_data_index == old_file_h->e_shnum)
720 fatal ("Can't find .data in %s.\n", old_name, 0);
721
722 /* Walk through all section headers, insert the new data2 section right
723 before the new bss section. */
724 for (n = 1, nn = 1; n < old_file_h->e_shnum; n++, nn++)
725 {
726 caddr_t src;
727
728 /* If it is bss section, insert the new data2 section before it. */
729 if (n == old_bss_index)
730 {
731 /* Steal the data section header for this data2 section. */
732 memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (old_data_index),
733 new_file_h->e_shentsize);
734
735 NEW_SECTION_H (nn).sh_addr = new_data2_addr;
736 NEW_SECTION_H (nn).sh_offset = new_data2_offset;
737 NEW_SECTION_H (nn).sh_size = new_data2_size;
738 /* Use the bss section's alignment. This will assure that the
739 new data2 section always be placed in the same spot as the old
740 bss section by any other application. */
741 NEW_SECTION_H (nn).sh_addralign = OLD_SECTION_H (n).sh_addralign;
742
743 /* Now copy over what we have in the memory now. */
744 memcpy (NEW_SECTION_H (nn).sh_offset + new_base,
745 (caddr_t) OLD_SECTION_H (n).sh_addr,
746 new_data2_size);
747 nn++;
748 memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (n),
749 old_file_h->e_shentsize);
750
751 /* The new bss section's size is zero, and its file offset and virtual
752 address should be off by NEW_OFFSETS_SHIFT. */
753 NEW_SECTION_H (nn).sh_offset += new_offsets_shift;
754 NEW_SECTION_H (nn).sh_addr = new_bss_addr;
755 /* Let the new bss section address alignment be the same as the
756 section address alignment followed the old bss section, so
757 this section will be placed in exactly the same place. */
758 NEW_SECTION_H (nn).sh_addralign = OLD_SECTION_H (nn).sh_addralign;
759 NEW_SECTION_H (nn).sh_size = 0;
760 }
761 else
762 {
763 memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (n),
764 old_file_h->e_shentsize);
765
766 /* Any section that was original placed AFTER the bss
767 section must now be adjusted by NEW_OFFSETS_SHIFT. */
768
769 if (NEW_SECTION_H (nn).sh_offset >= new_data2_offset)
770 NEW_SECTION_H (nn).sh_offset += new_offsets_shift;
771 }
772
773 /* If any section hdr refers to the section after the new .data
774 section, make it refer to next one because we have inserted
775 a new section in between. */
776
777 PATCH_INDEX (NEW_SECTION_H (nn).sh_link);
778 /* For symbol tables, info is a symbol table index,
779 so don't change it. */
780 if (NEW_SECTION_H (nn).sh_type != SHT_SYMTAB
781 && NEW_SECTION_H (nn).sh_type != SHT_DYNSYM)
782 PATCH_INDEX (NEW_SECTION_H (nn).sh_info);
783
784 /* Now, start to copy the content of sections. */
785 if (NEW_SECTION_H (nn).sh_type == SHT_NULL
786 || NEW_SECTION_H (nn).sh_type == SHT_NOBITS)
787 continue;
788
789 /* Write out the sections. .data and .data1 (and data2, called
790 ".data" in the strings table) get copied from the current process
791 instead of the old file. */
792 if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data")
793 || !strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data1")
794#ifdef IRIX6_5
795 /* Under IRIX 6.5 gcc places objects with adresses relative to
796 shared symbols in the section .rodata, which are adjusted at
797 startup time. Unfortunately they aren't adjusted after unexec,
798 so with this configuration we must get .rodata also from memory.
799 Do any other configurations need this, too?
800 <Wolfgang.Glas@hfm.tu-graz.ac.at> 1999-06-08. */
801 || !strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".rodata")
802#endif
803 || !strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".got"))
804 src = (caddr_t) OLD_SECTION_H (n).sh_addr;
805 else
806 src = old_base + OLD_SECTION_H (n).sh_offset;
807
808 memcpy (NEW_SECTION_H (nn).sh_offset + new_base, src,
809 NEW_SECTION_H (nn).sh_size);
810
811 /* Adjust the HDRR offsets in .mdebug and copy the
812 line data if it's in its usual 'hole' in the object.
813 Makes the new file debuggable with dbx.
814 patches up two problems: the absolute file offsets
815 in the HDRR record of .mdebug (see /usr/include/syms.h), and
816 the ld bug that gets the line table in a hole in the
817 elf file rather than in the .mdebug section proper.
818 David Anderson. davea@sgi.com Jan 16,1994. */
819 if (n == old_mdebug_index)
820 {
821#define MDEBUGADJUST(__ct,__fileaddr) \
822 if (n_phdrr->__ct > 0) \
823 { \
824 n_phdrr->__fileaddr += movement; \
825 }
826
827 HDRR * o_phdrr = (HDRR *)((byte *)old_base + OLD_SECTION_H (n).sh_offset);
828 HDRR * n_phdrr = (HDRR *)((byte *)new_base + NEW_SECTION_H (nn).sh_offset);
829 unsigned movement = new_offsets_shift;
830
831 MDEBUGADJUST (idnMax, cbDnOffset);
832 MDEBUGADJUST (ipdMax, cbPdOffset);
833 MDEBUGADJUST (isymMax, cbSymOffset);
834 MDEBUGADJUST (ioptMax, cbOptOffset);
835 MDEBUGADJUST (iauxMax, cbAuxOffset);
836 MDEBUGADJUST (issMax, cbSsOffset);
837 MDEBUGADJUST (issExtMax, cbSsExtOffset);
838 MDEBUGADJUST (ifdMax, cbFdOffset);
839 MDEBUGADJUST (crfd, cbRfdOffset);
840 MDEBUGADJUST (iextMax, cbExtOffset);
841 /* The Line Section, being possible off in a hole of the object,
842 requires special handling. */
843 if (n_phdrr->cbLine > 0)
844 {
845 if (o_phdrr->cbLineOffset > (OLD_SECTION_H (n).sh_offset
846 + OLD_SECTION_H (n).sh_size))
847 {
848 /* line data is in a hole in elf. do special copy and adjust
849 for this ld mistake.
850 */
851 n_phdrr->cbLineOffset += movement;
852
853 memcpy (n_phdrr->cbLineOffset + new_base,
854 o_phdrr->cbLineOffset + old_base, n_phdrr->cbLine);
855 }
856 else
857 {
858 /* somehow line data is in .mdebug as it is supposed to be. */
859 MDEBUGADJUST (cbLine, cbLineOffset);
860 }
861 }
862 }
863
864 /* If it is the symbol table, its st_shndx field needs to be patched. */
865 if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB
866 || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM)
867 {
868 Elf32_Shdr *spt = &NEW_SECTION_H (nn);
869 unsigned int num = spt->sh_size / spt->sh_entsize;
870 Elf32_Sym * sym = (Elf32_Sym *) (NEW_SECTION_H (nn).sh_offset
871 + new_base);
872 for (; num--; sym++)
873 {
874 /* don't patch special section indices. */
875 if (sym->st_shndx == SHN_UNDEF
876 || sym->st_shndx >= SHN_LORESERVE)
877 continue;
878
879 PATCH_INDEX (sym->st_shndx);
880 }
881 }
882 }
883
884 /* Close the files and make the new file executable. */
885
886 if (close (old_file))
887 fatal ("Can't close (%s): errno %d\n", old_name, errno);
888
889 if (close (new_file))
890 fatal ("Can't close (%s): errno %d\n", new_name, errno);
891
892 if (stat (new_name, &stat_buf) == -1)
893 fatal ("Can't stat (%s): errno %d\n", new_name, errno);
894
895 n = umask (777);
896 umask (n);
897 stat_buf.st_mode |= 0111 & ~n;
898 if (chmod (new_name, stat_buf.st_mode) == -1)
899 fatal ("Can't chmod (%s): errno %d\n", new_name, errno);
900}
diff --git a/src/x11term.h b/src/x11term.h
deleted file mode 100644
index 367eeaacc95..00000000000
--- a/src/x11term.h
+++ /dev/null
@@ -1,24 +0,0 @@
1#include <X11/Xlib.h>
2#include <X11/Xatom.h>
3#include <X11/keysym.h>
4#include <X11/cursorfont.h>
5#include <X11/Xutil.h>
6#include <X11/X10.h>
7
8#define XMOUSEBUFSIZE 64
9
10#ifndef sigmask
11#define sigmask(no) (1L << ((no) - 1))
12#endif
13
14#define BLOCK_INPUT_DECLARE() int BLOCK_INPUT_mask
15#ifdef SIGIO
16#define BLOCK_INPUT() EMACS_SIGBLOCKX (SIGIO, BLOCK_INPUT_mask)
17#define UNBLOCK_INPUT() \
18 do { int _dummy; EMACS_SIGSETMASK (BLOCK_INPUT_mask, _dummy); } while (0)
19#else /* not SIGIO */
20#define BLOCK_INPUT()
21#define UNBLOCK_INPUT()
22#endif /* SIGIO */
23
24#define CLASS "Emacs" /* class id for GNU Emacs, used in .Xdefaults, etc. */
diff --git a/src/xscrollbar.h b/src/xscrollbar.h
deleted file mode 100644
index e1a3f45d247..00000000000
--- a/src/xscrollbar.h
+++ /dev/null
@@ -1,123 +0,0 @@
1/* Bitmaps and things for scrollbars.
2 Copyright (C) 1989 Free Software Foundation.
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 1, or (at your option)
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21static void install_vertical_scrollbar ();
22static void install_horizontal_scrollbar ();
23static void x_set_horizontal_scrollbar ();
24static void x_set_vertical_scrollbar ();
25
26/* Prefix-characters for scroll bar commands in Vglobal_mouse_map.
27 Choice of prefix depends on which region of the scroll bar. */
28
29enum scroll_bar_prefix
30 { VSCROLL_BAR_PREFIX = 050, VSCROLL_SLIDER_PREFIX /* unused */,
31 VSCROLL_THUMBUP_PREFIX, VSCROLL_THUMBDOWN_PREFIX,
32 HSCROLL_BAR_PREFIX, HSCROLL_SLIDER_PREFIX /* unused */,
33 HSCROLL_THUMBLEFT_PREFIX, HSCROLL_THUMBRIGHT_PREFIX };
34
35#define CROSS_WIDTH 16
36#define CROSS_HEIGHT 16
37
38#define CROSS_MASK_WIDTH 16
39#define CROSS_MASK_HEIGHT 16
40
41/* Vertical and Horizontal scroll bar widths. */
42#define VSCROLL_WIDTH 18
43#define HSCROLL_HEIGHT 18
44
45#ifdef HAVE_X11
46
47/* Arrow cursors for scroll bars. */
48
49Cursor up_arrow_cursor, down_arrow_cursor, v_double_arrow_cursor;
50Cursor left_arrow_cursor, right_arrow_cursor, h_double_arrow_cursor;
51
52static char cross_bits[] =
53 {
54 0x00, 0x00, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
55 0x80, 0x01, 0xfe, 0x7f, 0xfe, 0x7f, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
56 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x00, 0x00
57 };
58
59static char gray_bits[] =
60 {
61 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
62 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
63 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
64 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa
65 };
66
67static char up_arrow_bits[] =
68 {
69 0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f, 0xf8, 0x1f,
70 0xfc, 0x3f, 0xfe, 0x7f, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
71 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xff, 0xff
72 };
73
74static char down_arrow_bits[] =
75 {
76 0xff, 0xff, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
77 0x80, 0x01, 0x80, 0x01, 0xfe, 0x7f, 0xfc, 0x3f, 0xf8, 0x1f, 0xf0, 0x0f,
78 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00
79 };
80
81static char left_arrow_bits[] =
82 {
83 0x00, 0x80, 0x80, 0x80, 0xc0, 0x80, 0xe0, 0x80, 0xf0, 0x80, 0xf8, 0x80,
84 0xfc, 0x80, 0xfe, 0xff, 0xfe, 0xff, 0xfc, 0x80, 0xf8, 0x80, 0xf0, 0x80,
85 0xe0, 0x80, 0xc0, 0x80, 0x80, 0x80, 0x00, 0x80
86 };
87
88static char right_arrow_bits[] =
89 {
90 0x01, 0x00, 0x01, 0x01, 0x01, 0x03, 0x01, 0x07, 0x01, 0x0f, 0x01, 0x1f,
91 0x01, 0x3f, 0xff, 0x7f, 0xff, 0x7f, 0x01, 0x3f, 0x01, 0x1f, 0x01, 0x0f,
92 0x01, 0x07, 0x01, 0x03, 0x01, 0x01, 0x01, 0x00
93 };
94
95static char cross_mask_bits[] =
96 {
97 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03,
98 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x03, 0xc0, 0x03,
99 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03
100 };
101#else /* not HAVE_X11 */
102static short cross_bits[] =
103 {
104 0x0000, 0x0180, 0x0180, 0x0180,
105 0x0180, 0x0180, 0x0180, 0x7ffe,
106 0x7ffe, 0x0180, 0x0180, 0x0180,
107 0x0180, 0x0180, 0x0180, 0x0000,
108 };
109
110static short gray_bits[] = {
111 0xaaaa, 0x5555, 0xaaaa, 0x5555,
112 0xaaaa, 0x5555, 0xaaaa, 0x5555,
113 0xaaaa, 0x5555, 0xaaaa, 0x5555,
114 0xaaaa, 0x5555, 0xaaaa, 0x5555};
115
116static short cross_mask_bits[] =
117 {
118 0x03c0, 0x03c0, 0x03c0, 0x03c0,
119 0x03c0, 0x03c0, 0xffff, 0xffff,
120 0xffff, 0xffff, 0x03c0, 0x03c0,
121 0x03c0, 0x03c0, 0x03c0, 0x03c0,
122 };
123#endif /* X10 */
diff --git a/src/xselect.c.old b/src/xselect.c.old
deleted file mode 100644
index 8a3e0443270..00000000000
--- a/src/xselect.c.old
+++ /dev/null
@@ -1,950 +0,0 @@
1/* X Selection processing for emacs
2 Copyright (C) 1990, 1992, 1993 Free Software Foundation.
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20#include "config.h"
21#include "lisp.h"
22#include "xterm.h"
23#include "buffer.h"
24#include "frame.h"
25
26#ifdef HAVE_X11
27
28/* Macros for X Selections */
29#define MAX_SELECTION(dpy) (((dpy)->max_request_size << 2) - 100)
30#define SELECTION_LENGTH(len,format) ((len) * ((format) >> 2))
31
32/* The timestamp of the last input event we received from the X server. */
33unsigned long last_event_timestamp;
34
35/* t if a mouse button is depressed. */
36extern Lisp_Object Vmouse_grabbed;
37
38/* When emacs became the PRIMARY selection owner. */
39Time x_begin_selection_own;
40
41/* When emacs became the SECONDARY selection owner. */
42Time x_begin_secondary_selection_own;
43
44/* When emacs became the CLIPBOARD selection owner. */
45Time x_begin_clipboard_own;
46
47/* The value of the current CLIPBOARD selection. */
48Lisp_Object Vx_clipboard_value;
49
50/* The value of the current PRIMARY selection. */
51Lisp_Object Vx_selection_value;
52
53/* The value of the current SECONDARY selection. */
54Lisp_Object Vx_secondary_selection_value;
55
56/* Types of selections we may make. */
57Lisp_Object Qprimary, Qsecondary, Qclipboard;
58
59/* Emacs' selection property identifiers. */
60Atom Xatom_emacs_selection;
61Atom Xatom_emacs_secondary_selection;
62
63/* Clipboard selection atom. */
64Atom Xatom_clipboard_selection;
65
66/* Clipboard atom. */
67Atom Xatom_clipboard;
68
69/* Atom for indicating incremental selection transfer. */
70Atom Xatom_incremental;
71
72/* Atom for indicating multiple selection request list */
73Atom Xatom_multiple;
74
75/* Atom for what targets emacs handles. */
76Atom Xatom_targets;
77
78/* Atom for indicating timstamp selection request */
79Atom Xatom_timestamp;
80
81/* Atom requesting we delete our selection. */
82Atom Xatom_delete;
83
84/* Selection magic. */
85Atom Xatom_insert_selection;
86
87/* Type of property for INSERT_SELECTION. */
88Atom Xatom_pair;
89
90/* More selection magic. */
91Atom Xatom_insert_property;
92
93/* Atom for indicating property type TEXT */
94Atom Xatom_text;
95
96/* Kinds of protocol things we may receive. */
97Atom Xatom_wm_take_focus;
98Atom Xatom_wm_save_yourself;
99Atom Xatom_wm_delete_window;
100
101/* Communication with window managers. */
102Atom Xatom_wm_protocols;
103
104/* These are to handle incremental selection transfer. */
105Window incr_requestor;
106Atom incr_property;
107int incr_nbytes;
108unsigned char *incr_value;
109unsigned char *incr_ptr;
110
111/* Declarations for handling cut buffers.
112
113 Whenever we set a cut buffer or read a cut buffer's value, we cache
114 it in cut_buffer_value. We look for PropertyNotify events about
115 the CUT_BUFFER properties, and invalidate our cache accordingly.
116 We ignore PropertyNotify events that we suspect were caused by our
117 own changes to the cut buffers, so we can keep the cache valid
118 longer.
119
120 IS ALL THIS HAIR WORTH IT? Well, these functions get called every
121 time an element goes into or is retrieved from the kill ring, and
122 those ought to be quick. It's not fun in time or space to wait for
123 50k cut buffers to fly back and forth across the net. */
124
125/* The number of CUT_BUFFER properties defined under X. */
126#define NUM_CUT_BUFFERS (8)
127
128/* cut_buffer_atom[n] is the atom naming the nth cut buffer. */
129static Atom cut_buffer_atom[NUM_CUT_BUFFERS] = {
130 XA_CUT_BUFFER0, XA_CUT_BUFFER1, XA_CUT_BUFFER2, XA_CUT_BUFFER3,
131 XA_CUT_BUFFER4, XA_CUT_BUFFER5, XA_CUT_BUFFER6, XA_CUT_BUFFER7
132};
133
134/* cut_buffer_value is an eight-element vector;
135 (aref cut_buffer_value n) is the cached value of cut buffer n, or
136 Qnil if cut buffer n is unset. */
137static Lisp_Object cut_buffer_value;
138
139/* Bit N of cut_buffer_cached is true if (aref cut_buffer_value n) is
140 known to be valid. This is cleared by PropertyNotify events
141 handled by x_invalidate_cut_buffer_cache. It would be wonderful if
142 that routine could just set the appropriate element of
143 cut_buffer_value to some special value meaning "uncached", but that
144 would lose if a GC happened to be in progress.
145
146 Bit N of cut_buffer_just_set is true if cut buffer N has been set since
147 the last PropertyNotify event; since we get an event even when we set
148 the property ourselves, we should ignore one event after setting
149 a cut buffer, so we don't have to throw away our cache. */
150#ifdef __STDC__
151volatile
152#endif
153static cut_buffer_cached, cut_buffer_just_set;
154
155
156/* Acquiring ownership of a selection. */
157
158
159/* Request selection ownership if we do not already have it. */
160
161static int
162own_selection (selection_type, time)
163 Atom selection_type;
164 Time time;
165{
166 Window owner_window, selecting_window;
167
168 if ((selection_type == XA_PRIMARY
169 && !NILP (Vx_selection_value))
170 || (selection_type == XA_SECONDARY
171 && !NILP (Vx_secondary_selection_value))
172 || (selection_type == Xatom_clipboard
173 && !NILP (Vx_clipboard_value)))
174 return 1;
175
176 selecting_window = FRAME_X_WINDOW (selected_frame);
177 XSetSelectionOwner (x_current_display, selection_type,
178 selecting_window, time);
179 owner_window = XGetSelectionOwner (x_current_display, selection_type);
180
181 if (owner_window != selecting_window)
182 return 0;
183
184 return 1;
185}
186
187/* Become the selection owner and make our data the selection value.
188 If we are already the owner, merely change data and timestamp values.
189 This avoids generating SelectionClear events for ourselves. */
190
191DEFUN ("x-set-selection", Fx_set_selection, Sx_set_selection,
192 2, 2, "",
193 "Set the value of SELECTION to STRING.\n\
194SELECTION may be `primary', `secondary', or `clipboard'.\n\
195\n\
196Selections are a mechanism for cutting and pasting information between\n\
197X Windows clients. Emacs's kill ring commands set the `primary'\n\
198selection to the top string of the kill ring, making it available to\n\
199other clients, like xterm. Those commands also use the `primary'\n\
200selection to retrieve information from other clients.\n\
201\n\
202According to the Inter-Client Communications Conventions Manual:\n\
203\n\
204The `primary' selection \"... is used for all commands that take only a\n\
205 single argument and is the principal means of communication between\n\
206 clients that use the selection mechanism.\" In Emacs, this means\n\
207 that the kill ring commands set the primary selection to the text\n\
208 put in the kill ring.\n\
209\n\
210The `secondary' selection \"... is used as the second argument to\n\
211 commands taking two arguments (for example, `exchange primary and\n\
212 secondary selections'), and as a means of obtaining data when there\n\
213 is a primary selection and the user does not want to disturb it.\"\n\
214 I am not sure how Emacs should use the secondary selection; if you\n\
215 come up with ideas, this function will at least let you get at it.\n\
216\n\
217The `clipboard' selection \"... is used to hold data that is being\n\
218 transferred between clients, that is, data that usually is being\n\
219 cut or copied, and then pasted.\" It seems that the `clipboard'\n\
220 selection is for the most part equivalent to the `primary'\n\
221 selection, so Emacs sets them both.\n\
222\n\
223Also see `x-selection', and the `interprogram-cut-function' variable.")
224 (selection, string)
225 register Lisp_Object selection, string;
226{
227 Atom selection_type;
228 Lisp_Object val;
229 Time event_time = last_event_timestamp;
230 CHECK_STRING (string, 0);
231
232 val = Qnil;
233
234 if (NILP (selection) || EQ (selection, Qprimary))
235 {
236 BLOCK_INPUT;
237 if (own_selection (XA_PRIMARY, event_time))
238 {
239 x_begin_selection_own = event_time;
240 val = Vx_selection_value = string;
241 }
242 UNBLOCK_INPUT;
243 }
244 else if (EQ (selection, Qsecondary))
245 {
246 BLOCK_INPUT;
247 if (own_selection (XA_SECONDARY, event_time))
248 {
249 x_begin_secondary_selection_own = event_time;
250 val = Vx_secondary_selection_value = string;
251 }
252 UNBLOCK_INPUT;
253 }
254 else if (EQ (selection, Qclipboard))
255 {
256 BLOCK_INPUT;
257 if (own_selection (Xatom_clipboard, event_time))
258 {
259 x_begin_clipboard_own = event_time;
260 val = Vx_clipboard_value = string;
261 }
262 UNBLOCK_INPUT;
263 }
264 else
265 error ("Invalid X selection type");
266
267 return val;
268}
269
270/* Clear our selection ownership data, as some other client has
271 become the owner. */
272
273void
274x_disown_selection (old_owner, selection, changed_owner_time)
275 Window *old_owner;
276 Atom selection;
277 Time changed_owner_time;
278{
279 struct frame *s = x_window_to_frame (old_owner);
280
281 if (s) /* We are the owner */
282 {
283 if (selection == XA_PRIMARY)
284 {
285 x_begin_selection_own = 0;
286 Vx_selection_value = Qnil;
287 }
288 else if (selection == XA_SECONDARY)
289 {
290 x_begin_secondary_selection_own = 0;
291 Vx_secondary_selection_value = Qnil;
292 }
293 else if (selection == Xatom_clipboard)
294 {
295 x_begin_clipboard_own = 0;
296 Vx_clipboard_value = Qnil;
297 }
298 else
299 abort ();
300 }
301 else
302 abort (); /* Inconsistent state. */
303}
304
305
306/* Answering selection requests. */
307
308int x_selection_alloc_error;
309int x_converting_selection;
310
311/* Reply to some client's request for our selection data.
312 Data is placed in a property supplied by the requesting window.
313
314 If the data exceeds the maximum amount the server can send,
315 then prepare to send it incrementally, and reply to the client with
316 the total size of the data.
317
318 But first, check for all the other crufty stuff we could get. */
319
320void
321x_answer_selection_request (event)
322 XSelectionRequestEvent event;
323{
324 Time emacs_own_time;
325 Lisp_Object selection_value;
326 XSelectionEvent evt;
327 int format = 8; /* We have only byte sized (text) data. */
328
329 evt.type = SelectionNotify; /* Construct reply event */
330 evt.display = event.display;
331 evt.requestor = event.requestor;
332 evt.selection = event.selection;
333 evt.time = event.time;
334 evt.target = event.target;
335
336 if (event.selection == XA_PRIMARY)
337 {
338 emacs_own_time = x_begin_selection_own;
339 selection_value = Vx_selection_value;
340 }
341 else if (event.selection == XA_SECONDARY)
342 {
343 emacs_own_time = x_begin_secondary_selection_own;
344 selection_value = Vx_secondary_selection_value;
345 }
346 else if (event.selection == Xatom_clipboard)
347 {
348 emacs_own_time = x_begin_clipboard_own;
349 selection_value = Vx_clipboard_value;
350 }
351 else
352 abort ();
353
354 if (event.time != CurrentTime
355 && event.time < emacs_own_time)
356 evt.property = None;
357 else
358 {
359 if (event.property == None) /* obsolete client */
360 evt.property = event.target;
361 else
362 evt.property = event.property;
363 }
364
365 if (event.target == Xatom_targets) /* Send List of target atoms */
366 {
367 }
368 else if (event.target == Xatom_multiple) /* Recvd list: <target, prop> */
369 {
370 Atom type;
371 int return_format;
372 unsigned long items, bytes_left;
373 unsigned char *data;
374 int result, i;
375
376 if (event.property == 0 /* 0 == NILP */
377 || event.property == None)
378 return;
379
380 result = XGetWindowProperty (event.display, event.requestor,
381 event.property, 0L, 10000000L,
382 True, Xatom_pair, &type, &return_format,
383 &items, &bytes_left, &data);
384
385 if (result == Success && type == Xatom_pair)
386 for (i = items; i > 0; i--)
387 {
388 /* Convert each element of the list. */
389 }
390
391 (void) XSendEvent (x_current_display, evt.requestor, False,
392 0L, (XEvent *) &evt);
393 return;
394 }
395 else if (event.target == Xatom_timestamp) /* Send ownership timestamp */
396 {
397 if (! emacs_own_time)
398 abort ();
399
400 format = 32;
401 XChangeProperty (evt.display, evt.requestor, evt.property,
402 evt.target, format, PropModeReplace,
403 (unsigned char *) &emacs_own_time, 1);
404 return;
405 }
406 else if (event.target == Xatom_delete) /* Delete our selection. */
407 {
408 if (EQ (Qnil, selection_value))
409 abort ();
410
411 x_disown_selection (event.owner, event.selection, event.time);
412
413 /* Now return property of type NILP, length 0. */
414 XChangeProperty (event.display, event.requestor, event.property,
415 0, format, PropModeReplace, (unsigned char *) 0, 0);
416 return;
417 }
418 else if (event.target == Xatom_insert_selection)
419 {
420 Atom type;
421 int return_format;
422 unsigned long items, bytes_left;
423 unsigned char *data;
424 int result = XGetWindowProperty (event.display, event.requestor,
425 event.property, 0L, 10000000L,
426 True, Xatom_pair, &type, &return_format,
427 &items, &bytes_left, &data);
428 if (result == Success && type == Xatom_pair)
429 {
430 /* Convert the first atom to (a selection) to the target
431 indicated by the second atom. */
432 }
433 }
434 else if (event.target == Xatom_insert_property)
435 {
436 Atom type;
437 int return_format;
438 unsigned long items, bytes_left;
439 unsigned char *data;
440 int result = XGetWindowProperty (event.display, event.requestor,
441 event.property, 0L, 10000000L,
442 True, XA_STRING, &type, &return_format,
443 &items, &bytes_left, &data);
444
445 if (result == Success && type == XA_STRING && return_format == 8)
446 {
447 if (event.selection == Xatom_emacs_selection)
448 Vx_selection_value = make_string (data);
449 else if (event.selection == Xatom_emacs_secondary_selection)
450 Vx_secondary_selection_value = make_string (data);
451 else if (event.selection == Xatom_clipboard_selection)
452 Vx_clipboard_value = make_string (data);
453 else
454 abort ();
455 }
456
457 return;
458 }
459 else if ((event.target == Xatom_text
460 || event.target == XA_STRING))
461 {
462 int size = XSTRING (selection_value)->size;
463 unsigned char *data = XSTRING (selection_value)->data;
464
465 if (EQ (Qnil, selection_value))
466 abort ();
467
468 /* Place data on requestor window's property. */
469 if (SELECTION_LENGTH (size, format)
470 <= MAX_SELECTION (x_current_display))
471 {
472 x_converting_selection = 1;
473 XChangeProperty (evt.display, evt.requestor, evt.property,
474 evt.target, format, PropModeReplace,
475 data, size);
476 if (x_selection_alloc_error)
477 {
478 x_selection_alloc_error = 0;
479 abort ();
480 }
481 x_converting_selection = 0;
482 }
483 else /* Send incrementally */
484 {
485 evt.target = Xatom_incremental;
486 incr_requestor = evt.requestor;
487 incr_property = evt.property;
488 x_converting_selection = 1;
489
490 /* Need to handle Alloc errors on these requests. */
491 XChangeProperty (evt.display, incr_requestor, incr_property,
492 Xatom_incremental, 32,
493 PropModeReplace,
494 (unsigned char *) &size, 1);
495 if (x_selection_alloc_error)
496 {
497 x_selection_alloc_error = 0;
498 x_converting_selection = 0;
499 abort ();
500 /* Now abort the send. */
501 }
502
503 incr_nbytes = size;
504 incr_value = data;
505 incr_ptr = data;
506
507 /* Ask for notification when requestor deletes property. */
508 XSelectInput (x_current_display, incr_requestor, PropertyChangeMask);
509
510 /* If we're sending incrementally, perhaps block here
511 until all sent? */
512 }
513 }
514 else
515 evt.property = None;
516
517 /* Don't do this if there was an Alloc error: abort the transfer
518 by sending None. */
519 (void) XSendEvent (x_current_display, evt.requestor, False,
520 0L, (XEvent *) &evt);
521}
522
523/* Send an increment of selection data in response to a PropertyNotify event.
524 The increment is placed in a property on the requestor's window.
525 When the requestor has processed the increment, it deletes the property,
526 which sends us another PropertyNotify event.
527
528 When there is no more data to send, we send a zero-length increment. */
529
530void
531x_send_incremental (event)
532 XPropertyEvent event;
533{
534 if (incr_requestor
535 && incr_requestor == event.window
536 && incr_property == event.atom
537 && event.state == PropertyDelete)
538 {
539 int format = 8;
540 int length = MAX_SELECTION (x_current_display);
541 int bytes_left = (incr_nbytes - (incr_ptr - incr_value));
542
543 if (length > bytes_left) /* Also sends 0 len when finished. */
544 length = bytes_left;
545 XChangeProperty (x_current_display, incr_requestor,
546 incr_property, XA_STRING, format,
547 PropModeAppend, incr_ptr, length);
548 if (x_selection_alloc_error)
549 {
550 x_selection_alloc_error = 0;
551 x_converting_selection = 0;
552 /* Abandon the transmission. */
553 abort ();
554 }
555 if (length > 0)
556 incr_ptr += length;
557 else
558 { /* Everything's sent */
559 XSelectInput (x_current_display, incr_requestor, 0L);
560 incr_requestor = (Window) 0;
561 incr_property = (Atom) 0;
562 incr_nbytes = 0;
563 incr_value = (unsigned char *) 0;
564 incr_ptr = (unsigned char *) 0;
565 x_converting_selection = 0;
566 }
567 }
568}
569
570
571/* Requesting the value of a selection. */
572
573static Lisp_Object x_selection_arrival ();
574
575/* Predicate function used to match a requested event. */
576
577Bool
578XCheckSelectionEvent (dpy, event, window)
579 Display *dpy;
580 XEvent *event;
581 char *window;
582{
583 if (event->type == SelectionNotify)
584 if (event->xselection.requestor == (Window) window)
585 return True;
586
587 return False;
588}
589
590/* Request a selection value from its owner. This will block until
591 all the data is arrived. */
592
593static Lisp_Object
594get_selection_value (type)
595 Atom type;
596{
597 XEvent event;
598 Lisp_Object val;
599 Time requestor_time; /* Timestamp of selection request. */
600 Window requestor_window;
601
602 BLOCK_INPUT;
603 requestor_time = last_event_timestamp;
604 requestor_window = FRAME_X_WINDOW (selected_frame);
605 XConvertSelection (x_current_display, type, XA_STRING,
606 Xatom_emacs_selection, requestor_window, requestor_time);
607 XIfEvent (x_current_display,
608 &event,
609 XCheckSelectionEvent,
610 (char *) requestor_window);
611 val = x_selection_arrival (&event, requestor_window, requestor_time);
612 UNBLOCK_INPUT;
613
614 return val;
615}
616
617/* Request a selection value from the owner. If we are the owner,
618 simply return our selection value. If we are not the owner, this
619 will block until all of the data has arrived. */
620
621DEFUN ("x-selection", Fx_selection, Sx_selection,
622 1, 1, "",
623 "Return the value of SELECTION.\n\
624SELECTION is one of `primary', `secondary', or `clipboard'.\n\
625\n\
626Selections are a mechanism for cutting and pasting information between\n\
627X Windows clients. When the user selects text in an X application,\n\
628the application should set the primary selection to that text; Emacs's\n\
629kill ring commands will then check the value of the `primary'\n\
630selection, and return it as the most recent kill.\n\
631The documentation for `x-set-selection' gives more information on how\n\
632the different selection types are intended to be used.\n\
633Also see the `interprogram-paste-function' variable.")
634 (selection)
635 register Lisp_Object selection;
636{
637 Atom selection_type;
638
639 if (NILP (selection) || EQ (selection, Qprimary))
640 {
641 if (!NILP (Vx_selection_value))
642 return Vx_selection_value;
643
644 return get_selection_value (XA_PRIMARY);
645 }
646 else if (EQ (selection, Qsecondary))
647 {
648 if (!NILP (Vx_secondary_selection_value))
649 return Vx_secondary_selection_value;
650
651 return get_selection_value (XA_SECONDARY);
652 }
653 else if (EQ (selection, Qclipboard))
654 {
655 if (!NILP (Vx_clipboard_value))
656 return Vx_clipboard_value;
657
658 return get_selection_value (Xatom_clipboard);
659 }
660 else
661 error ("Invalid X selection type");
662}
663
664static Lisp_Object
665x_selection_arrival (event, requestor_window, requestor_time)
666 register XSelectionEvent *event;
667 Window requestor_window;
668 Time requestor_time;
669{
670 int result;
671 Atom type, selection;
672 int format;
673 unsigned long items;
674 unsigned long bytes_left;
675 unsigned char *data = 0;
676 int offset = 0;
677
678 if (event->selection == XA_PRIMARY)
679 selection = Xatom_emacs_selection;
680 else if (event->selection == XA_SECONDARY)
681 selection = Xatom_emacs_secondary_selection;
682 else if (event->selection == Xatom_clipboard)
683 selection = Xatom_clipboard_selection;
684 else
685 abort ();
686
687 if (event->requestor == requestor_window
688 && event->time == requestor_time
689 && event->property != None)
690 if (event->target != Xatom_incremental)
691 {
692 unsigned char *return_string =
693 (unsigned char *) alloca (MAX_SELECTION (x_current_display));
694
695 do
696 {
697 result = XGetWindowProperty (x_current_display, requestor_window,
698 event->property, 0L,
699 10000000L, True, XA_STRING,
700 &type, &format, &items,
701 &bytes_left, &data);
702 if (result == Success && type == XA_STRING && format == 8
703 && offset < MAX_SELECTION (x_current_display))
704 {
705 bcopy (data, return_string + offset, items);
706 offset += items;
707 }
708 XFree ((char *) data);
709 }
710 while (bytes_left);
711
712 return make_string (return_string, offset);
713 }
714 else /* Prepare incremental transfer. */
715 {
716 unsigned char *increment_value;
717 unsigned char *increment_ptr;
718 int total_size;
719 int *increment_nbytes = 0;
720
721 result = XGetWindowProperty (x_current_display, requestor_window,
722 selection, 0L, 10000000L, False,
723 event->property, &type, &format,
724 &items, &bytes_left,
725 (unsigned char **) &increment_nbytes);
726 if (result == Success)
727 {
728 XPropertyEvent property_event;
729
730 total_size = *increment_nbytes;
731 increment_value = (unsigned char *) alloca (total_size);
732 increment_ptr = increment_value;
733
734 XDeleteProperty (x_current_display, event->requestor,
735 event->property);
736 XFlush (x_current_display);
737 XFree ((char *) increment_nbytes);
738
739 do
740 { /* NOTE: this blocks. */
741 XWindowEvent (x_current_display, requestor_window,
742 PropertyChangeMask,
743 (XEvent *) &property_event);
744
745 if (property_event.atom == selection
746 && property_event.state == PropertyNewValue)
747 do
748 {
749 result = XGetWindowProperty (x_current_display,
750 requestor_window,
751 selection, 0L,
752 10000000L, True,
753 AnyPropertyType,
754 &type, &format,
755 &items, &bytes_left,
756 &data);
757 if (result == Success && type == XA_STRING
758 && format == 8)
759 {
760 bcopy (data, increment_ptr, items);
761 increment_ptr += items;
762 }
763 }
764 while (bytes_left);
765
766 }
767 while (increment_ptr < (increment_value + total_size));
768
769 return make_string (increment_value,
770 (increment_ptr - increment_value));
771 }
772 }
773
774 return Qnil;
775}
776
777
778/* Cut buffer management. */
779
780DEFUN ("x-get-cut-buffer", Fx_get_cut_buffer, Sx_get_cut_buffer, 0, 1, "",
781 "Return the value of cut buffer N, or nil if it is unset.\n\
782If N is omitted, it defaults to zero.\n\
783Note that cut buffers have some problems that selections don't; try to\n\
784write your code to use cut buffers only for backward compatibility,\n\
785and use selections for the serious work.")
786 (n)
787 Lisp_Object n;
788{
789 int buf_num;
790
791 if (NILP (n))
792 buf_num = 0;
793 else
794 {
795 CHECK_NUMBER (n, 0);
796 buf_num = XINT (n);
797 }
798
799 if (buf_num < 0 || buf_num >= NUM_CUT_BUFFERS)
800 error ("cut buffer numbers must be from zero to seven");
801
802 {
803 Lisp_Object value;
804
805 /* Note that no PropertyNotify events will be processed while
806 input is blocked. */
807 BLOCK_INPUT;
808
809 if (cut_buffer_cached & (1 << buf_num))
810 value = XVECTOR (cut_buffer_value)->contents[buf_num];
811 else
812 {
813 /* Our cache is invalid; retrieve the property's value from
814 the server. */
815 int buf_len;
816 char *buf = XFetchBuffer (x_current_display, &buf_len, buf_num);
817
818 if (buf_len == 0)
819 value = Qnil;
820 else
821 value = make_string (buf, buf_len);
822
823 XVECTOR (cut_buffer_value)->contents[buf_num] = value;
824 cut_buffer_cached |= (1 << buf_num);
825
826 XFree (buf);
827 }
828
829 UNBLOCK_INPUT;
830
831 return value;
832 }
833}
834
835DEFUN ("x-set-cut-buffer", Fx_set_cut_buffer, Sx_set_cut_buffer, 2, 2, "",
836 "Set the value of cut buffer N to STRING.\n\
837Note that cut buffers have some problems that selections don't; try to\n\
838write your code to use cut buffers only for backward compatibility,\n\
839and use selections for the serious work.")
840 (n, string)
841 Lisp_Object n, string;
842{
843 int buf_num;
844
845 CHECK_NUMBER (n, 0);
846 CHECK_STRING (string, 1);
847
848 buf_num = XINT (n);
849
850 if (buf_num < 0 || buf_num >= NUM_CUT_BUFFERS)
851 error ("cut buffer numbers must be from zero to seven");
852
853 BLOCK_INPUT;
854
855 /* DECwindows and some other servers don't seem to like setting
856 properties to values larger than about 20k. For very large
857 values, they signal an error, but for intermediate values they
858 just seem to hang.
859
860 We could just truncate the request, but it's better to let the
861 user know that the strategy he/she's using isn't going to work
862 than to have it work partially, but incorrectly. */
863
864 if (XSTRING (string)->size == 0
865 || XSTRING (string)->size > MAX_SELECTION (x_current_display))
866 {
867 XStoreBuffer (x_current_display, (char *) 0, 0, buf_num);
868 string = Qnil;
869 }
870 else
871 {
872 XStoreBuffer (x_current_display,
873 (char *) XSTRING (string)->data, XSTRING (string)->size,
874 buf_num);
875 }
876
877 XVECTOR (cut_buffer_value)->contents[buf_num] = string;
878 cut_buffer_cached |= (1 << buf_num);
879 cut_buffer_just_set |= (1 << buf_num);
880
881 UNBLOCK_INPUT;
882
883 return string;
884}
885
886/* Ask the server to send us an event if any cut buffer is modified. */
887
888void
889x_watch_cut_buffer_cache ()
890{
891 XSelectInput (x_current_display, ROOT_WINDOW, PropertyChangeMask);
892}
893
894/* The server has told us that a cut buffer has been modified; deal with that.
895 Note that this function is called at interrupt level. */
896void
897x_invalidate_cut_buffer_cache (XPropertyEvent *event)
898{
899 int i;
900
901 /* See which cut buffer this is about, if any. */
902 for (i = 0; i < NUM_CUT_BUFFERS; i++)
903 if (event->atom == cut_buffer_atom[i])
904 {
905 int mask = (1 << i);
906
907 if (cut_buffer_just_set & mask)
908 cut_buffer_just_set &= ~mask;
909 else
910 cut_buffer_cached &= ~mask;
911
912 break;
913 }
914}
915
916
917/* Bureaucracy. */
918
919void
920syms_of_xselect ()
921{
922 DEFVAR_LISP ("x-selection-value", &Vx_selection_value,
923 "The value of emacs' last cut-string.");
924 Vx_selection_value = Qnil;
925
926 DEFVAR_LISP ("x-secondary-selection-value", &Vx_secondary_selection_value,
927 "The value of emacs' last secondary cut-string.");
928 Vx_secondary_selection_value = Qnil;
929
930 DEFVAR_LISP ("x-clipboard-value", &Vx_clipboard_value,
931 "The string emacs last sent to the clipboard.");
932 Vx_clipboard_value = Qnil;
933
934 Qprimary = intern ("primary");
935 staticpro (&Qprimary);
936 Qsecondary = intern ("secondary");
937 staticpro (&Qsecondary);
938 Qclipboard = intern ("clipboard");
939 staticpro (&Qclipboard);
940
941 defsubr (&Sx_set_selection);
942 defsubr (&Sx_selection);
943
944 cut_buffer_value = Fmake_vector (make_number (NUM_CUT_BUFFERS), Qnil);
945 staticpro (&cut_buffer_value);
946
947 defsubr (&Sx_get_cut_buffer);
948 defsubr (&Sx_set_cut_buffer);
949}
950#endif /* X11 */