Added on unicode branch
This commit is contained in:
parent
fbaf0946b2
commit
cda62d166b
3 changed files with 487 additions and 0 deletions
76
INSTALL.CVS
Normal file
76
INSTALL.CVS
Normal file
|
@ -0,0 +1,76 @@
|
|||
Building and Installing Emacs from CVS
|
||||
|
||||
Some of the files that are included in the Emacs tarball, such as
|
||||
byte-compiled Lisp files, are not stored in the CVS repository.
|
||||
Therefore, to build from CVS you must run "make bootstrap"
|
||||
instead of just "make":
|
||||
|
||||
$ ./configure
|
||||
$ make bootstrap
|
||||
|
||||
The bootstrap process makes sure all necessary files are rebuilt
|
||||
before it builds the final Emacs binary.
|
||||
|
||||
Normally, it is not necessary to use "make bootstrap" after every CVS
|
||||
update. Unless there are problems, we suggest the following
|
||||
procedure:
|
||||
|
||||
$ ./configure
|
||||
$ make
|
||||
$ cd lisp
|
||||
$ make recompile EMACS=../src/emacs
|
||||
$ cd ..
|
||||
$ make
|
||||
|
||||
(If you want to install the Emacs binary, type "make install" instead
|
||||
of "make" in the last command.)
|
||||
|
||||
Occasionally the file "lisp/loaddefs.el" will need be updated to reflect
|
||||
new autoloaded functions. If you see errors about undefined lisp
|
||||
functions during compilation, that may be the reason. Another symptom
|
||||
may be an error saying that "loaddefs.el" could not be found; this is
|
||||
due to a change in the way loaddefs.el was handled in CVS, and should
|
||||
only happen once, for users that are updating old CVS trees.
|
||||
|
||||
To update loaddefs.el, do:
|
||||
|
||||
$ cd lisp
|
||||
$ make autoloads EMACS=../src/emacs
|
||||
|
||||
If either of above procedures fails, try "make bootstrap".
|
||||
|
||||
Users of non-Posix systems (MS-Windows etc.) should run the
|
||||
platform-specific configuration scripts (nt/configure.bat, config.bat,
|
||||
etc.) before "make bootstrap" or "make"; the rest of the procedure is
|
||||
applicable to those systems as well.
|
||||
|
||||
Questions, requests, and bug reports about the CVS versions of Emacs
|
||||
should be sent to emacs-pretest-bug@gnu.org rather than gnu.emacs.help
|
||||
or gnu.emacs.bug. Ideally, use M-x report-emacs-bug RET which will
|
||||
send it to the proper place.
|
||||
|
||||
|
||||
Note on using SSH to access the CVS repository from inside Emacs
|
||||
----------------------------------------------------------------
|
||||
|
||||
Write access to the CVS repository requires using SSH v2.
|
||||
|
||||
If you execute cvs commands inside Emacs, specifically if you use
|
||||
pcl-cvs, output from CVS may be lost due to a problem in the
|
||||
interface between ssh, cvs, and libc. Corrupted checkins have
|
||||
also been rumored to have happened.
|
||||
|
||||
To fix the problem, save the following script into a file, make it
|
||||
executable, and set CVS_RSH to the file name of the script:
|
||||
|
||||
#!/bin/bash
|
||||
exec 2> >(exec cat >&2 2>/dev/null)
|
||||
exec ssh "$@"
|
||||
|
||||
This may be combined with the following entry in ~/.ssh/config to
|
||||
simplify accessing the CVS repository:
|
||||
|
||||
Host subversions.gnu.org
|
||||
Protocol 2
|
||||
ForwardX11 no
|
||||
User YOUR_USERID
|
104
src/sheap.c
Normal file
104
src/sheap.c
Normal file
|
@ -0,0 +1,104 @@
|
|||
/* simulate sbrk() with an array in .bss, for unexec() support for Cygwin;
|
||||
complete rewrite of xemacs Cygwin unexec() code
|
||||
|
||||
Copyright (C) 2004
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Emacs is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Emacs; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include "lisp.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef HAVE_X_WINDOWS
|
||||
#define STATIC_HEAP_SIZE (7 * 1024 * 1024)
|
||||
#else
|
||||
#define STATIC_HEAP_SIZE (7 * 1024 * 1024)
|
||||
#endif
|
||||
|
||||
int debug_sheap = 0;
|
||||
|
||||
#define BLOCKSIZE 4096
|
||||
|
||||
char bss_sbrk_buffer[STATIC_HEAP_SIZE];
|
||||
char *bss_sbrk_ptr;
|
||||
int bss_sbrk_did_unexec;
|
||||
|
||||
void *
|
||||
bss_sbrk (ptrdiff_t request_size)
|
||||
{
|
||||
if (!bss_sbrk_ptr)
|
||||
{
|
||||
bss_sbrk_ptr = bss_sbrk_buffer;
|
||||
#ifdef CYGWIN
|
||||
sbrk (BLOCKSIZE); /* force space for fork to work */
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!(int) request_size)
|
||||
{
|
||||
return (bss_sbrk_ptr);
|
||||
}
|
||||
else if (bss_sbrk_ptr + (int) request_size < bss_sbrk_buffer)
|
||||
{
|
||||
printf
|
||||
("attempt to free too much: avail %d used %d failed request %d\n",
|
||||
STATIC_HEAP_SIZE, bss_sbrk_ptr - bss_sbrk_buffer,
|
||||
(int) request_size);
|
||||
exit (-1);
|
||||
return 0;
|
||||
}
|
||||
else if (bss_sbrk_ptr + (int) request_size >
|
||||
bss_sbrk_buffer + STATIC_HEAP_SIZE)
|
||||
{
|
||||
printf ("static heap exhausted: avail %d used %d failed request %d\n",
|
||||
STATIC_HEAP_SIZE,
|
||||
bss_sbrk_ptr - bss_sbrk_buffer, (int) request_size);
|
||||
exit (-1);
|
||||
return 0;
|
||||
}
|
||||
else if ((int) request_size < 0)
|
||||
{
|
||||
bss_sbrk_ptr += (int) request_size;
|
||||
if (debug_sheap)
|
||||
printf ("freed size %d\n", request_size);
|
||||
return bss_sbrk_ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *ret = bss_sbrk_ptr;
|
||||
if (debug_sheap)
|
||||
printf ("allocated 0x%08x size %d\n", ret, request_size);
|
||||
bss_sbrk_ptr += (int) request_size;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
report_sheap_usage (int die_if_pure_storage_exceeded)
|
||||
{
|
||||
char buf[200];
|
||||
sprintf (buf, "Static heap usage: %d of %d bytes",
|
||||
bss_sbrk_ptr - bss_sbrk_buffer, STATIC_HEAP_SIZE);
|
||||
message ("%s", buf);
|
||||
}
|
||||
|
||||
/* arch-tag: 1bc386e8-71c2-4da4-b8b5-c1674a9cf926
|
||||
(do not change this comment) */
|
307
src/unexcw.c
Normal file
307
src/unexcw.c
Normal file
|
@ -0,0 +1,307 @@
|
|||
/* unexec() support for Cygwin;
|
||||
complete rewrite of xemacs Cygwin unexec() code
|
||||
|
||||
Copyright (C) 2004
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Emacs is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Emacs; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <config.h>
|
||||
#include <lisp.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <a.out.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define DOTEXE ".exe"
|
||||
|
||||
extern int bss_sbrk_did_unexec;
|
||||
|
||||
/* emacs symbols that indicate where bss and data end for emacs internals */
|
||||
extern char my_endbss[];
|
||||
extern char my_edata[];
|
||||
|
||||
/*
|
||||
** header for Windows executable files
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
FILHDR file_header;
|
||||
PEAOUTHDR file_optional_header;
|
||||
SCNHDR section_header[32];
|
||||
} exe_header_t;
|
||||
|
||||
int debug_unexcw = 0;
|
||||
|
||||
/*
|
||||
** Read the header from the executable into memory so we can more easily access it.
|
||||
*/
|
||||
static exe_header_t *
|
||||
read_exe_header (int fd, exe_header_t * exe_header_buffer)
|
||||
{
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
assert (fd >= 0);
|
||||
assert (exe_header_buffer != 0);
|
||||
|
||||
ret = lseek (fd, 0L, SEEK_SET);
|
||||
assert (ret != -1);
|
||||
|
||||
ret =
|
||||
read (fd, &exe_header_buffer->file_header,
|
||||
sizeof (exe_header_buffer->file_header));
|
||||
assert (ret == sizeof (exe_header_buffer->file_header));
|
||||
|
||||
assert (exe_header_buffer->file_header.e_magic == 0x5a4d);
|
||||
assert (exe_header_buffer->file_header.nt_signature == 0x4550);
|
||||
assert (exe_header_buffer->file_header.f_magic == 0x014c);
|
||||
assert (exe_header_buffer->file_header.f_nscns > 0);
|
||||
assert (exe_header_buffer->file_header.f_nscns <=
|
||||
sizeof (exe_header_buffer->section_header) /
|
||||
sizeof (exe_header_buffer->section_header[0]));
|
||||
assert (exe_header_buffer->file_header.f_opthdr > 0);
|
||||
|
||||
ret =
|
||||
read (fd, &exe_header_buffer->file_optional_header,
|
||||
sizeof (exe_header_buffer->file_optional_header));
|
||||
assert (ret == sizeof (exe_header_buffer->file_optional_header));
|
||||
|
||||
assert (exe_header_buffer->file_optional_header.magic == 0x010b);
|
||||
|
||||
for (i = 0; i < exe_header_buffer->file_header.f_nscns; ++i)
|
||||
{
|
||||
ret =
|
||||
read (fd, &exe_header_buffer->section_header[i],
|
||||
sizeof (exe_header_buffer->section_header[i]));
|
||||
assert (ret == sizeof (exe_header_buffer->section_header[i]));
|
||||
}
|
||||
|
||||
return (exe_header_buffer);
|
||||
}
|
||||
|
||||
/*
|
||||
** Fix the dumped emacs executable:
|
||||
**
|
||||
** - copy .data section data of interest from running executable into
|
||||
** output .exe file
|
||||
**
|
||||
** - convert .bss section into an initialized data section (like
|
||||
** .data) and copy .bss section data of interest from running
|
||||
** executable into output .exe file
|
||||
*/
|
||||
static void
|
||||
fixup_executable (int fd)
|
||||
{
|
||||
exe_header_t exe_header_buffer;
|
||||
exe_header_t *exe_header;
|
||||
int i;
|
||||
int ret;
|
||||
int found_data = 0;
|
||||
int found_bss = 0;
|
||||
|
||||
exe_header = read_exe_header (fd, &exe_header_buffer);
|
||||
assert (exe_header != 0);
|
||||
|
||||
assert (exe_header->file_header.f_nscns > 0);
|
||||
for (i = 0; i < exe_header->file_header.f_nscns; ++i)
|
||||
{
|
||||
unsigned long start_address =
|
||||
exe_header->section_header[i].s_vaddr +
|
||||
exe_header->file_optional_header.ImageBase;
|
||||
unsigned long end_address =
|
||||
exe_header->section_header[i].s_vaddr +
|
||||
exe_header->file_optional_header.ImageBase +
|
||||
exe_header->section_header[i].s_paddr;
|
||||
if (debug_unexcw)
|
||||
printf ("%8s start 0x%08x end 0x%08x\n",
|
||||
exe_header->section_header[i].s_name,
|
||||
start_address, end_address);
|
||||
if (my_edata >= (char *) start_address
|
||||
&& my_edata < (char *) end_address)
|
||||
{
|
||||
/* data section */
|
||||
ret =
|
||||
lseek (fd, (long) (exe_header->section_header[i].s_scnptr),
|
||||
SEEK_SET);
|
||||
assert (ret != -1);
|
||||
ret =
|
||||
write (fd, (char *) start_address,
|
||||
my_edata - (char *) start_address);
|
||||
assert (ret == my_edata - (char *) start_address);
|
||||
++found_data;
|
||||
if (debug_unexcw)
|
||||
printf (" .data, mem start 0x%08x mem length %d\n",
|
||||
start_address, my_edata - (char *) start_address);
|
||||
if (debug_unexcw)
|
||||
printf (" .data, file start %d file length %d\n",
|
||||
(int) exe_header->section_header[i].s_scnptr,
|
||||
(int) exe_header->section_header[i].s_paddr);
|
||||
}
|
||||
else if (my_endbss >= (char *) start_address
|
||||
&& my_endbss < (char *) end_address)
|
||||
{
|
||||
/* bss section */
|
||||
++found_bss;
|
||||
if (exe_header->section_header[i].s_flags & 0x00000080)
|
||||
{
|
||||
/* convert uninitialized data section to initialized data section */
|
||||
struct stat statbuf;
|
||||
ret = fstat (fd, &statbuf);
|
||||
assert (ret != -1);
|
||||
|
||||
exe_header->section_header[i].s_flags &= ~0x00000080;
|
||||
exe_header->section_header[i].s_flags |= 0x00000040;
|
||||
|
||||
exe_header->section_header[i].s_scnptr =
|
||||
(statbuf.st_size +
|
||||
exe_header->file_optional_header.FileAlignment) /
|
||||
exe_header->file_optional_header.FileAlignment *
|
||||
exe_header->file_optional_header.FileAlignment;
|
||||
|
||||
exe_header->section_header[i].s_size =
|
||||
(exe_header->section_header[i].s_paddr +
|
||||
exe_header->file_optional_header.FileAlignment) /
|
||||
exe_header->file_optional_header.FileAlignment *
|
||||
exe_header->file_optional_header.FileAlignment;
|
||||
|
||||
ret =
|
||||
lseek (fd,
|
||||
(long) (exe_header->section_header[i].s_scnptr +
|
||||
exe_header->section_header[i].s_size - 1),
|
||||
SEEK_SET);
|
||||
assert (ret != -1);
|
||||
ret = write (fd, "", 1);
|
||||
assert (ret == 1);
|
||||
|
||||
ret =
|
||||
lseek (fd,
|
||||
(long) ((char *) &exe_header->section_header[i] -
|
||||
(char *) exe_header), SEEK_SET);
|
||||
assert (ret != -1);
|
||||
ret =
|
||||
write (fd, &exe_header->section_header[i],
|
||||
sizeof (exe_header->section_header[i]));
|
||||
assert (ret == sizeof (exe_header->section_header[i]));
|
||||
if (debug_unexcw)
|
||||
printf (" seek to %ld, write %d\n",
|
||||
(long) ((char *) &exe_header->section_header[i] -
|
||||
(char *) exe_header),
|
||||
sizeof (exe_header->section_header[i]));
|
||||
}
|
||||
/* write initialized data section */
|
||||
ret =
|
||||
lseek (fd, (long) (exe_header->section_header[i].s_scnptr),
|
||||
SEEK_SET);
|
||||
assert (ret != -1);
|
||||
ret =
|
||||
write (fd, (char *) start_address,
|
||||
my_endbss - (char *) start_address);
|
||||
assert (ret == (my_endbss - (char *) start_address));
|
||||
if (debug_unexcw)
|
||||
printf (" .bss, mem start 0x%08x mem length %d\n",
|
||||
start_address, my_endbss - (char *) start_address);
|
||||
if (debug_unexcw)
|
||||
printf (" .bss, file start %d file length %d\n",
|
||||
(int) exe_header->section_header[i].s_scnptr,
|
||||
(int) exe_header->section_header[i].s_paddr);
|
||||
}
|
||||
}
|
||||
assert (found_bss == 1);
|
||||
assert (found_data == 1);
|
||||
}
|
||||
|
||||
/*
|
||||
** Windows likes .exe suffixes on executables.
|
||||
*/
|
||||
static char *
|
||||
add_exe_suffix_if_necessary (const char *name, char *modified)
|
||||
{
|
||||
int i = strlen (name);
|
||||
if (i <= (sizeof (DOTEXE) - 1))
|
||||
{
|
||||
sprintf (modified, "%s%s", name, DOTEXE);
|
||||
}
|
||||
else if (!strcasecmp (name + i - (sizeof (DOTEXE) - 1), DOTEXE))
|
||||
{
|
||||
strcpy (modified, name);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf (modified, "%s%s", name, DOTEXE);
|
||||
}
|
||||
return (modified);
|
||||
}
|
||||
|
||||
int
|
||||
unexec (char *outfile, char *infile, unsigned start_data, unsigned d1,
|
||||
unsigned d2)
|
||||
{
|
||||
char infile_buffer[FILENAME_MAX];
|
||||
char outfile_buffer[FILENAME_MAX];
|
||||
int fd_in;
|
||||
int fd_out;
|
||||
int ret;
|
||||
int ret2;
|
||||
|
||||
if (bss_sbrk_did_unexec)
|
||||
{
|
||||
/* can only dump once */
|
||||
printf ("You can only dump emacs once on this platform.\n");
|
||||
return (1);
|
||||
}
|
||||
|
||||
report_sheap_usage (1);
|
||||
|
||||
infile = add_exe_suffix_if_necessary (infile, infile_buffer);
|
||||
outfile = add_exe_suffix_if_necessary (outfile, outfile_buffer);
|
||||
|
||||
fd_in = open (infile, O_RDONLY | O_BINARY);
|
||||
assert (fd_in >= 0);
|
||||
fd_out = open (outfile, O_RDWR | O_TRUNC | O_CREAT | O_BINARY, 0755);
|
||||
assert (fd_out >= 0);
|
||||
for (;;)
|
||||
{
|
||||
char buffer[4096];
|
||||
ret = read (fd_in, buffer, sizeof (buffer));
|
||||
if (ret == 0)
|
||||
{
|
||||
/* eof */
|
||||
break;
|
||||
}
|
||||
assert (ret > 0);
|
||||
/* data */
|
||||
ret2 = write (fd_out, buffer, ret);
|
||||
assert (ret2 == ret);
|
||||
}
|
||||
ret = close (fd_in);
|
||||
assert (ret == 0);
|
||||
|
||||
bss_sbrk_did_unexec = 1;
|
||||
fixup_executable (fd_out);
|
||||
bss_sbrk_did_unexec = 0;
|
||||
|
||||
ret = close (fd_out);
|
||||
assert (ret == 0);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* arch-tag: fc44f6c3-ca0a-45e0-a5a2-58b6101b1e65
|
||||
(do not change this comment) */
|
Loading…
Add table
Reference in a new issue