Added on unicode branch

This commit is contained in:
Miles Bader 2004-04-19 07:12:41 +00:00
parent fbaf0946b2
commit cda62d166b
3 changed files with 487 additions and 0 deletions

76
INSTALL.CVS Normal file
View 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
View 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
View 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) */