aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiles Bader2004-04-19 07:12:41 +0000
committerMiles Bader2004-04-19 07:12:41 +0000
commitcda62d166b91e203451aa038f791ee9d4503791a (patch)
tree8d8ab5d056745a812a673d9974319e57672cc896
parentfbaf0946b2013186454e8f44ded2ea9079df4050 (diff)
downloademacs-cda62d166b91e203451aa038f791ee9d4503791a.tar.gz
emacs-cda62d166b91e203451aa038f791ee9d4503791a.zip
Added on unicode branch
-rw-r--r--INSTALL.CVS76
-rw-r--r--src/sheap.c104
-rw-r--r--src/unexcw.c307
3 files changed, 487 insertions, 0 deletions
diff --git a/INSTALL.CVS b/INSTALL.CVS
new file mode 100644
index 00000000000..94025678ac3
--- /dev/null
+++ b/INSTALL.CVS
@@ -0,0 +1,76 @@
1 Building and Installing Emacs from CVS
2
3Some of the files that are included in the Emacs tarball, such as
4byte-compiled Lisp files, are not stored in the CVS repository.
5Therefore, to build from CVS you must run "make bootstrap"
6instead of just "make":
7
8 $ ./configure
9 $ make bootstrap
10
11The bootstrap process makes sure all necessary files are rebuilt
12before it builds the final Emacs binary.
13
14Normally, it is not necessary to use "make bootstrap" after every CVS
15update. Unless there are problems, we suggest the following
16procedure:
17
18 $ ./configure
19 $ make
20 $ cd lisp
21 $ make recompile EMACS=../src/emacs
22 $ cd ..
23 $ make
24
25(If you want to install the Emacs binary, type "make install" instead
26of "make" in the last command.)
27
28Occasionally the file "lisp/loaddefs.el" will need be updated to reflect
29new autoloaded functions. If you see errors about undefined lisp
30functions during compilation, that may be the reason. Another symptom
31may be an error saying that "loaddefs.el" could not be found; this is
32due to a change in the way loaddefs.el was handled in CVS, and should
33only happen once, for users that are updating old CVS trees.
34
35To update loaddefs.el, do:
36
37 $ cd lisp
38 $ make autoloads EMACS=../src/emacs
39
40If either of above procedures fails, try "make bootstrap".
41
42Users of non-Posix systems (MS-Windows etc.) should run the
43platform-specific configuration scripts (nt/configure.bat, config.bat,
44etc.) before "make bootstrap" or "make"; the rest of the procedure is
45applicable to those systems as well.
46
47Questions, requests, and bug reports about the CVS versions of Emacs
48should be sent to emacs-pretest-bug@gnu.org rather than gnu.emacs.help
49or gnu.emacs.bug. Ideally, use M-x report-emacs-bug RET which will
50send it to the proper place.
51
52
53Note on using SSH to access the CVS repository from inside Emacs
54----------------------------------------------------------------
55
56Write access to the CVS repository requires using SSH v2.
57
58If you execute cvs commands inside Emacs, specifically if you use
59pcl-cvs, output from CVS may be lost due to a problem in the
60interface between ssh, cvs, and libc. Corrupted checkins have
61also been rumored to have happened.
62
63To fix the problem, save the following script into a file, make it
64executable, and set CVS_RSH to the file name of the script:
65
66#!/bin/bash
67exec 2> >(exec cat >&2 2>/dev/null)
68exec ssh "$@"
69
70This may be combined with the following entry in ~/.ssh/config to
71simplify accessing the CVS repository:
72
73Host subversions.gnu.org
74 Protocol 2
75 ForwardX11 no
76 User YOUR_USERID
diff --git a/src/sheap.c b/src/sheap.c
new file mode 100644
index 00000000000..714eb9a710d
--- /dev/null
+++ b/src/sheap.c
@@ -0,0 +1,104 @@
1/* simulate sbrk() with an array in .bss, for unexec() support for Cygwin;
2 complete rewrite of xemacs Cygwin unexec() code
3
4 Copyright (C) 2004
5 Free Software Foundation, Inc.
6
7This file is part of GNU Emacs.
8
9GNU Emacs is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2, or (at your option)
12any later version.
13
14GNU Emacs is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with GNU Emacs; see the file COPYING. If not, write to
21the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22Boston, MA 02111-1307, USA. */
23
24#include <config.h>
25#include <stdio.h>
26#include "lisp.h"
27
28#include <unistd.h>
29
30#ifdef HAVE_X_WINDOWS
31#define STATIC_HEAP_SIZE (7 * 1024 * 1024)
32#else
33#define STATIC_HEAP_SIZE (7 * 1024 * 1024)
34#endif
35
36int debug_sheap = 0;
37
38#define BLOCKSIZE 4096
39
40char bss_sbrk_buffer[STATIC_HEAP_SIZE];
41char *bss_sbrk_ptr;
42int bss_sbrk_did_unexec;
43
44void *
45bss_sbrk (ptrdiff_t request_size)
46{
47 if (!bss_sbrk_ptr)
48 {
49 bss_sbrk_ptr = bss_sbrk_buffer;
50#ifdef CYGWIN
51 sbrk (BLOCKSIZE); /* force space for fork to work */
52#endif
53 }
54
55 if (!(int) request_size)
56 {
57 return (bss_sbrk_ptr);
58 }
59 else if (bss_sbrk_ptr + (int) request_size < bss_sbrk_buffer)
60 {
61 printf
62 ("attempt to free too much: avail %d used %d failed request %d\n",
63 STATIC_HEAP_SIZE, bss_sbrk_ptr - bss_sbrk_buffer,
64 (int) request_size);
65 exit (-1);
66 return 0;
67 }
68 else if (bss_sbrk_ptr + (int) request_size >
69 bss_sbrk_buffer + STATIC_HEAP_SIZE)
70 {
71 printf ("static heap exhausted: avail %d used %d failed request %d\n",
72 STATIC_HEAP_SIZE,
73 bss_sbrk_ptr - bss_sbrk_buffer, (int) request_size);
74 exit (-1);
75 return 0;
76 }
77 else if ((int) request_size < 0)
78 {
79 bss_sbrk_ptr += (int) request_size;
80 if (debug_sheap)
81 printf ("freed size %d\n", request_size);
82 return bss_sbrk_ptr;
83 }
84 else
85 {
86 char *ret = bss_sbrk_ptr;
87 if (debug_sheap)
88 printf ("allocated 0x%08x size %d\n", ret, request_size);
89 bss_sbrk_ptr += (int) request_size;
90 return ret;
91 }
92}
93
94void
95report_sheap_usage (int die_if_pure_storage_exceeded)
96{
97 char buf[200];
98 sprintf (buf, "Static heap usage: %d of %d bytes",
99 bss_sbrk_ptr - bss_sbrk_buffer, STATIC_HEAP_SIZE);
100 message ("%s", buf);
101}
102
103/* arch-tag: 1bc386e8-71c2-4da4-b8b5-c1674a9cf926
104 (do not change this comment) */
diff --git a/src/unexcw.c b/src/unexcw.c
new file mode 100644
index 00000000000..046c8f796ef
--- /dev/null
+++ b/src/unexcw.c
@@ -0,0 +1,307 @@
1/* unexec() support for Cygwin;
2 complete rewrite of xemacs Cygwin unexec() code
3
4 Copyright (C) 2004
5 Free Software Foundation, Inc.
6
7This file is part of GNU Emacs.
8
9GNU Emacs is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2, or (at your option)
12any later version.
13
14GNU Emacs is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with GNU Emacs; see the file COPYING. If not, write to
21the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22Boston, MA 02111-1307, USA. */
23
24#include <config.h>
25#include <lisp.h>
26#include <stdio.h>
27#include <fcntl.h>
28#include <a.out.h>
29#include <unistd.h>
30#include <assert.h>
31
32#define DOTEXE ".exe"
33
34extern int bss_sbrk_did_unexec;
35
36/* emacs symbols that indicate where bss and data end for emacs internals */
37extern char my_endbss[];
38extern char my_edata[];
39
40/*
41** header for Windows executable files
42*/
43typedef struct
44{
45 FILHDR file_header;
46 PEAOUTHDR file_optional_header;
47 SCNHDR section_header[32];
48} exe_header_t;
49
50int debug_unexcw = 0;
51
52/*
53** Read the header from the executable into memory so we can more easily access it.
54*/
55static exe_header_t *
56read_exe_header (int fd, exe_header_t * exe_header_buffer)
57{
58 int i;
59 int ret;
60
61 assert (fd >= 0);
62 assert (exe_header_buffer != 0);
63
64 ret = lseek (fd, 0L, SEEK_SET);
65 assert (ret != -1);
66
67 ret =
68 read (fd, &exe_header_buffer->file_header,
69 sizeof (exe_header_buffer->file_header));
70 assert (ret == sizeof (exe_header_buffer->file_header));
71
72 assert (exe_header_buffer->file_header.e_magic == 0x5a4d);
73 assert (exe_header_buffer->file_header.nt_signature == 0x4550);
74 assert (exe_header_buffer->file_header.f_magic == 0x014c);
75 assert (exe_header_buffer->file_header.f_nscns > 0);
76 assert (exe_header_buffer->file_header.f_nscns <=
77 sizeof (exe_header_buffer->section_header) /
78 sizeof (exe_header_buffer->section_header[0]));
79 assert (exe_header_buffer->file_header.f_opthdr > 0);
80
81 ret =
82 read (fd, &exe_header_buffer->file_optional_header,
83 sizeof (exe_header_buffer->file_optional_header));
84 assert (ret == sizeof (exe_header_buffer->file_optional_header));
85
86 assert (exe_header_buffer->file_optional_header.magic == 0x010b);
87
88 for (i = 0; i < exe_header_buffer->file_header.f_nscns; ++i)
89 {
90 ret =
91 read (fd, &exe_header_buffer->section_header[i],
92 sizeof (exe_header_buffer->section_header[i]));
93 assert (ret == sizeof (exe_header_buffer->section_header[i]));
94 }
95
96 return (exe_header_buffer);
97}
98
99/*
100** Fix the dumped emacs executable:
101**
102** - copy .data section data of interest from running executable into
103** output .exe file
104**
105** - convert .bss section into an initialized data section (like
106** .data) and copy .bss section data of interest from running
107** executable into output .exe file
108*/
109static void
110fixup_executable (int fd)
111{
112 exe_header_t exe_header_buffer;
113 exe_header_t *exe_header;
114 int i;
115 int ret;
116 int found_data = 0;
117 int found_bss = 0;
118
119 exe_header = read_exe_header (fd, &exe_header_buffer);
120 assert (exe_header != 0);
121
122 assert (exe_header->file_header.f_nscns > 0);
123 for (i = 0; i < exe_header->file_header.f_nscns; ++i)
124 {
125 unsigned long start_address =
126 exe_header->section_header[i].s_vaddr +
127 exe_header->file_optional_header.ImageBase;
128 unsigned long end_address =
129 exe_header->section_header[i].s_vaddr +
130 exe_header->file_optional_header.ImageBase +
131 exe_header->section_header[i].s_paddr;
132 if (debug_unexcw)
133 printf ("%8s start 0x%08x end 0x%08x\n",
134 exe_header->section_header[i].s_name,
135 start_address, end_address);
136 if (my_edata >= (char *) start_address
137 && my_edata < (char *) end_address)
138 {
139 /* data section */
140 ret =
141 lseek (fd, (long) (exe_header->section_header[i].s_scnptr),
142 SEEK_SET);
143 assert (ret != -1);
144 ret =
145 write (fd, (char *) start_address,
146 my_edata - (char *) start_address);
147 assert (ret == my_edata - (char *) start_address);
148 ++found_data;
149 if (debug_unexcw)
150 printf (" .data, mem start 0x%08x mem length %d\n",
151 start_address, my_edata - (char *) start_address);
152 if (debug_unexcw)
153 printf (" .data, file start %d file length %d\n",
154 (int) exe_header->section_header[i].s_scnptr,
155 (int) exe_header->section_header[i].s_paddr);
156 }
157 else if (my_endbss >= (char *) start_address
158 && my_endbss < (char *) end_address)
159 {
160 /* bss section */
161 ++found_bss;
162 if (exe_header->section_header[i].s_flags & 0x00000080)
163 {
164 /* convert uninitialized data section to initialized data section */
165 struct stat statbuf;
166 ret = fstat (fd, &statbuf);
167 assert (ret != -1);
168
169 exe_header->section_header[i].s_flags &= ~0x00000080;
170 exe_header->section_header[i].s_flags |= 0x00000040;
171
172 exe_header->section_header[i].s_scnptr =
173 (statbuf.st_size +
174 exe_header->file_optional_header.FileAlignment) /
175 exe_header->file_optional_header.FileAlignment *
176 exe_header->file_optional_header.FileAlignment;
177
178 exe_header->section_header[i].s_size =
179 (exe_header->section_header[i].s_paddr +
180 exe_header->file_optional_header.FileAlignment) /
181 exe_header->file_optional_header.FileAlignment *
182 exe_header->file_optional_header.FileAlignment;
183
184 ret =
185 lseek (fd,
186 (long) (exe_header->section_header[i].s_scnptr +
187 exe_header->section_header[i].s_size - 1),
188 SEEK_SET);
189 assert (ret != -1);
190 ret = write (fd, "", 1);
191 assert (ret == 1);
192
193 ret =
194 lseek (fd,
195 (long) ((char *) &exe_header->section_header[i] -
196 (char *) exe_header), SEEK_SET);
197 assert (ret != -1);
198 ret =
199 write (fd, &exe_header->section_header[i],
200 sizeof (exe_header->section_header[i]));
201 assert (ret == sizeof (exe_header->section_header[i]));
202 if (debug_unexcw)
203 printf (" seek to %ld, write %d\n",
204 (long) ((char *) &exe_header->section_header[i] -
205 (char *) exe_header),
206 sizeof (exe_header->section_header[i]));
207 }
208 /* write initialized data section */
209 ret =
210 lseek (fd, (long) (exe_header->section_header[i].s_scnptr),
211 SEEK_SET);
212 assert (ret != -1);
213 ret =
214 write (fd, (char *) start_address,
215 my_endbss - (char *) start_address);
216 assert (ret == (my_endbss - (char *) start_address));
217 if (debug_unexcw)
218 printf (" .bss, mem start 0x%08x mem length %d\n",
219 start_address, my_endbss - (char *) start_address);
220 if (debug_unexcw)
221 printf (" .bss, file start %d file length %d\n",
222 (int) exe_header->section_header[i].s_scnptr,
223 (int) exe_header->section_header[i].s_paddr);
224 }
225 }
226 assert (found_bss == 1);
227 assert (found_data == 1);
228}
229
230/*
231** Windows likes .exe suffixes on executables.
232*/
233static char *
234add_exe_suffix_if_necessary (const char *name, char *modified)
235{
236 int i = strlen (name);
237 if (i <= (sizeof (DOTEXE) - 1))
238 {
239 sprintf (modified, "%s%s", name, DOTEXE);
240 }
241 else if (!strcasecmp (name + i - (sizeof (DOTEXE) - 1), DOTEXE))
242 {
243 strcpy (modified, name);
244 }
245 else
246 {
247 sprintf (modified, "%s%s", name, DOTEXE);
248 }
249 return (modified);
250}
251
252int
253unexec (char *outfile, char *infile, unsigned start_data, unsigned d1,
254 unsigned d2)
255{
256 char infile_buffer[FILENAME_MAX];
257 char outfile_buffer[FILENAME_MAX];
258 int fd_in;
259 int fd_out;
260 int ret;
261 int ret2;
262
263 if (bss_sbrk_did_unexec)
264 {
265 /* can only dump once */
266 printf ("You can only dump emacs once on this platform.\n");
267 return (1);
268 }
269
270 report_sheap_usage (1);
271
272 infile = add_exe_suffix_if_necessary (infile, infile_buffer);
273 outfile = add_exe_suffix_if_necessary (outfile, outfile_buffer);
274
275 fd_in = open (infile, O_RDONLY | O_BINARY);
276 assert (fd_in >= 0);
277 fd_out = open (outfile, O_RDWR | O_TRUNC | O_CREAT | O_BINARY, 0755);
278 assert (fd_out >= 0);
279 for (;;)
280 {
281 char buffer[4096];
282 ret = read (fd_in, buffer, sizeof (buffer));
283 if (ret == 0)
284 {
285 /* eof */
286 break;
287 }
288 assert (ret > 0);
289 /* data */
290 ret2 = write (fd_out, buffer, ret);
291 assert (ret2 == ret);
292 }
293 ret = close (fd_in);
294 assert (ret == 0);
295
296 bss_sbrk_did_unexec = 1;
297 fixup_executable (fd_out);
298 bss_sbrk_did_unexec = 0;
299
300 ret = close (fd_out);
301 assert (ret == 0);
302
303 return (0);
304}
305
306/* arch-tag: fc44f6c3-ca0a-45e0-a5a2-58b6101b1e65
307 (do not change this comment) */