/* Copyright (C) 1985, 1986, 1987, 1988, 1992, 1993, 1994, 2001, 2002, 2003,
- 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+ 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
This file is part of GNU Emacs.
-GNU Emacs is free software; you can redistribute it and/or modify
+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 3, or (at your option)
-any later version.
+the Free Software Foundation, either version 3 of the License, 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
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., 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA. */
+along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
/*
Define this if your system uses COFF for executables.
-* COFF_ENCAPSULATE
-
-Define this if you are using the GNU coff encapsulated a.out format.
-This is closer to a.out than COFF. You should *not* define COFF if
-you define COFF_ENCAPSULATE
-
-Otherwise we assume you use Berkeley format.
-
* NO_REMAP
Define this if you do not want to try to save Emacs's pure data areas
boundary is needed, define SEGMENT_MASK to a mask of
the bits that must be zero on such a boundary.
-* A_TEXT_OFFSET(HDR)
-
-Some machines count the a.out header as part of the size of the text
-segment (a_text); they may actually load the header into core as the
-first data in the text segment. Some have additional padding between
-the header and the real text of the program that is counted in a_text.
-
-For these machines, define A_TEXT_OFFSET(HDR) to examine the header
-structure HDR and return the number of bytes to add to `a_text'
-before writing it (above and beyond the number of bytes of actual
-program text). HDR's standard fields are already correct, except that
-this adjustment to the `a_text' field has not yet been made;
-thus, the amount of offset can depend on the data in the file.
-
-* A_TEXT_SEEK(HDR)
-
-If defined, this macro specifies the number of bytes to seek into the
-a.out file before starting to write the text segment.
-
-* EXEC_MAGIC
-
-For machines using COFF, this macro, if defined, is a value stored
-into the magic number field of the output file.
-
* ADJUST_EXEC_HEADER
This macro can be used to generate statements to adjust or
initialize nonstandard fields in the file header
-* ADDR_CORRECT(ADDR)
-
-Macro to correct an int which is the bit pattern of a pointer to a byte
-into an int which is the number of a byte.
-
-This macro has a default definition which is usually right.
-This default definition is a no-op on most machines (where a
-pointer looks like an int) but not on all machines.
-
*/
#ifndef emacs
#define PERROR(arg) perror (arg); return -1
#else
-#define IN_UNEXEC
#include <config.h>
#define PERROR(file) report_error (file, new)
#endif
#ifndef CANNOT_DUMP /* all rest of file! */
-#if defined(COFF) && defined(HAVE_COFF_H)
+#ifdef HAVE_COFF_H
#include <coff.h>
#ifdef MSDOS
-#if __DJGPP__ > 1
#include <fcntl.h> /* for O_RDONLY, O_RDWR */
#include <crt0.h> /* for _crt0_startup_flags and its bits */
static int save_djgpp_startup_flags;
-#endif /* __DJGPP__ > 1 */
#define filehdr external_filehdr
#define scnhdr external_scnhdr
#define syment external_syment
unsigned long data_start;/* base of data used for this file */
};
#endif /* not MSDOS */
-#else /* not COFF */
-#ifdef COFF_ENCAPSULATE
-int need_coff_header = 1;
-#include <coff-encap/a.out.encap.h> /* The location might be a poor assumption */
-#else /* not COFF_ENCAPSULATE */
+#else /* not HAVE_COFF_H */
#include <a.out.h>
-#endif /* not COFF_ENCAPSULATE */
-#endif /* not COFF */
+#endif /* not HAVE_COFF_H */
/* Define getpagesize if the system does not.
Note that this may depend on symbols defined in a.out.h. */
#include <sys/stat.h>
#include <errno.h>
-#include <sys/file.h> /* Must be after sys/types.h for USG and BSD4_1*/
-
-#ifdef USG5
-#include <fcntl.h>
-#endif
+#include <sys/file.h>
#ifndef O_RDONLY
#define O_RDONLY 0
extern char *start_of_text (); /* Start of text */
extern char *start_of_data (); /* Start of initialized data */
-#ifdef COFF
static long block_copy_start; /* Old executable start point */
static struct filehdr f_hdr; /* File header */
static struct aouthdr f_ohdr; /* Optional file header (a.out) */
static long coff_offset;
-#else /* not COFF */
-
-#ifdef HPUX
-extern void *sbrk ();
-#else
-#if 0
-/* Some systems with __STDC__ compilers still declare this `char *' in some
- header file, and our declaration conflicts. The return value is always
- cast, so it should be harmless to leave it undefined. Hopefully
- machines with different size pointers and ints declare sbrk in a header
- file. */
-#ifdef __STDC__
-extern void *sbrk ();
-#else
-extern char *sbrk ();
-#endif /* __STDC__ */
-#endif
-#endif /* HPUX */
-
-#define SYMS_START ((long) N_SYMOFF (ohdr))
-
-/* Some machines override the structure name for an a.out header. */
-#ifndef EXEC_HDR_TYPE
-#define EXEC_HDR_TYPE struct exec
-#endif
-
-#ifdef HPUX
-#ifdef HP9000S200_ID
-#define MY_ID HP9000S200_ID
-#else
-#include <model.h>
-#define MY_ID MYSYS
-#endif /* no HP9000S200_ID */
-static MAGIC OLDMAGIC = {MY_ID, SHARE_MAGIC};
-static MAGIC NEWMAGIC = {MY_ID, DEMAND_MAGIC};
-#define N_TXTOFF(x) TEXT_OFFSET(x)
-#define N_SYMOFF(x) LESYM_OFFSET(x)
-static EXEC_HDR_TYPE hdr, ohdr;
-
-#else /* not HPUX */
-
-#if defined (USG) && !defined (IBMAIX) && !defined (IRIS) && !defined (COFF_ENCAPSULATE) && !defined (GNU_LINUX)
-static struct bhdr hdr, ohdr;
-#define a_magic fmagic
-#define a_text tsize
-#define a_data dsize
-#define a_bss bsize
-#define a_syms ssize
-#define a_trsize rtsize
-#define a_drsize rdsize
-#define a_entry entry
-#define N_BADMAG(x) \
- (((x).fmagic)!=OMAGIC && ((x).fmagic)!=NMAGIC &&\
- ((x).fmagic)!=FMAGIC && ((x).fmagic)!=IMAGIC)
-#define NEWMAGIC FMAGIC
-#else /* IRIS or IBMAIX or not USG */
-static EXEC_HDR_TYPE hdr, ohdr;
-#define NEWMAGIC ZMAGIC
-#endif /* IRIS or IBMAIX not USG */
-#endif /* not HPUX */
-
-static int unexec_text_start;
-static int unexec_data_start;
-
-#ifdef COFF_ENCAPSULATE
-/* coffheader is defined in the GNU a.out.encap.h file. */
-struct coffheader coffheader;
-#endif
-
-#endif /* not COFF */
-
static int pagemask;
/* Correct an int which is the bit pattern of a pointer to a byte
into an int which is the number of a byte.
This is a no-op on ordinary machines, but not on all. */
-#ifndef ADDR_CORRECT /* Let m-*.h files override this definition */
#define ADDR_CORRECT(x) ((char *)(x) - (char*)0)
-#endif
#ifdef emacs
+#include <setjmp.h>
#include "lisp.h"
static
char *new_name;
{
int tem;
-#ifdef COFF
auto struct scnhdr f_thdr; /* Text section header */
auto struct scnhdr f_dhdr; /* Data section header */
auto struct scnhdr f_bhdr; /* Bss section header */
auto struct scnhdr scntemp; /* Temporary section header */
register int scns;
-#endif /* COFF */
-#ifdef USG_SHARED_LIBRARIES
- extern unsigned int bss_end;
-#else
unsigned int bss_end;
-#endif
pagemask = getpagesize () - 1;
data_start, bss_start);
}
-#ifdef COFF
coff_offset = 0L; /* stays zero, except in DJGPP */
/* Salvage as much info from the existing file as possible */
if (a_out >= 0)
{
#ifdef MSDOS
-#if __DJGPP__ > 1
/* Support the coff-go32-exe format with a prepended stub, since
this is what GCC 2.8.0 and later generates by default in DJGPP. */
unsigned short mz_header[3];
}
else
lseek (a_out, 0L, 0);
-#endif /* __DJGPP__ > 1 */
#endif /* MSDOS */
if (read (a_out, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr))
{
/* Now we alter the contents of all the f_*hdr variables
to correspond to what we want to dump. */
-#ifdef USG_SHARED_LIBRARIES
-
- /* The amount of data we're adding to the file is distance from the
- * end of the original .data space to the current end of the .data
- * space.
- */
-
- bias = bss_start - (f_ohdr.data_start + f_dhdr.s_size);
-
-#endif
-
f_hdr.f_flags |= (F_RELFLG | F_EXEC);
-#ifdef TPIX
- f_hdr.f_nscns = 3;
-#endif
-#ifdef EXEC_MAGIC
- f_ohdr.magic = EXEC_MAGIC;
-#endif
#ifndef NO_REMAP
f_ohdr.text_start = (long) start_of_text ();
f_ohdr.tsize = data_start - f_ohdr.text_start;
#endif /* NO_REMAP */
f_ohdr.dsize = bss_start - f_ohdr.data_start;
f_ohdr.bsize = bss_end - bss_start;
-#ifndef KEEP_OLD_TEXT_SCNPTR
/* On some machines, the old values are right.
??? Maybe on all machines with NO_REMAP. */
f_thdr.s_size = f_ohdr.tsize;
f_thdr.s_scnptr = sizeof (f_hdr) + sizeof (f_ohdr);
f_thdr.s_scnptr += (f_hdr.f_nscns) * (sizeof (f_thdr));
-#endif /* KEEP_OLD_TEXT_SCNPTR */
-#ifdef ADJUST_TEXT_SCNHDR_SIZE
- /* On some machines, `text size' includes all headers. */
- f_thdr.s_size -= f_thdr.s_scnptr;
-#endif /* ADJUST_TEST_SCNHDR_SIZE */
lnnoptr = f_thdr.s_lnnoptr;
#ifdef SECTION_ALIGNMENT
/* Some systems require special alignment
f_thdr.s_scnptr
= (f_thdr.s_scnptr + SECTION_ALIGNMENT) & ~SECTION_ALIGNMENT;
#endif /* SECTION_ALIGNMENT */
-#ifdef TPIX
- f_thdr.s_scnptr = 0xd0;
-#endif
text_scnptr = f_thdr.s_scnptr;
-#ifdef ADJUST_TEXTBASE
- text_scnptr = sizeof (f_hdr) + sizeof (f_ohdr) + (f_hdr.f_nscns) * (sizeof (f_thdr));
-#endif
-#ifndef KEEP_OLD_PADDR
f_dhdr.s_paddr = f_ohdr.data_start;
-#endif /* KEEP_OLD_PADDR */
f_dhdr.s_vaddr = f_ohdr.data_start;
f_dhdr.s_size = f_ohdr.dsize;
f_dhdr.s_scnptr = f_thdr.s_scnptr + f_thdr.s_size;
= (f_dhdr.s_scnptr + DATA_SECTION_ALIGNMENT) & ~DATA_SECTION_ALIGNMENT;
#endif /* DATA_SECTION_ALIGNMENT */
data_scnptr = f_dhdr.s_scnptr;
-#ifndef KEEP_OLD_PADDR
f_bhdr.s_paddr = f_ohdr.data_start + f_ohdr.dsize;
-#endif /* KEEP_OLD_PADDR */
f_bhdr.s_vaddr = f_ohdr.data_start + f_ohdr.dsize;
f_bhdr.s_size = f_ohdr.bsize;
f_bhdr.s_scnptr = 0L;
-#ifndef USG_SHARED_LIBRARIES
bias = f_dhdr.s_scnptr + f_dhdr.s_size - block_copy_start;
-#endif
if (f_hdr.f_symptr > 0L)
{
PERROR (new_name);
}
-#ifndef USG_SHARED_LIBRARIES
-
if (write (new, &f_thdr, sizeof (f_thdr)) != sizeof (f_thdr))
{
PERROR (new_name);
PERROR (new_name);
}
-#else /* USG_SHARED_LIBRARIES */
-
- /* The purpose of this code is to write out the new file's section
- * header table.
- *
- * Scan through the original file's sections. If the encountered
- * section is one we know (.text, .data or .bss), write out the
- * correct header. If it is a section we do not know (such as
- * .lib), adjust the address of where the section data is in the
- * file, and write out the header.
- *
- * If any section precedes .text or .data in the file, this code
- * will not adjust the file pointer for that section correctly.
- */
-
- /* This used to use sizeof (f_ohdr) instead of .f_opthdr.
- .f_opthdr is said to be right when there is no optional header. */
- lseek (a_out, sizeof (f_hdr) + f_hdr.f_opthdr, 0);
-
- for (scns = f_hdr.f_nscns; scns > 0; scns--)
- {
- if (read (a_out, &scntemp, sizeof (scntemp)) != sizeof (scntemp))
- PERROR (a_name);
-
- if (!strcmp (scntemp.s_name, f_thdr.s_name)) /* .text */
- {
- if (write (new, &f_thdr, sizeof (f_thdr)) != sizeof (f_thdr))
- PERROR (new_name);
- }
- else if (!strcmp (scntemp.s_name, f_dhdr.s_name)) /* .data */
- {
- if (write (new, &f_dhdr, sizeof (f_dhdr)) != sizeof (f_dhdr))
- PERROR (new_name);
- }
- else if (!strcmp (scntemp.s_name, f_bhdr.s_name)) /* .bss */
- {
- if (write (new, &f_bhdr, sizeof (f_bhdr)) != sizeof (f_bhdr))
- PERROR (new_name);
- }
- else
- {
- if (scntemp.s_scnptr)
- scntemp.s_scnptr += bias;
- if (write (new, &scntemp, sizeof (scntemp)) != sizeof (scntemp))
- PERROR (new_name);
- }
- }
-#endif /* USG_SHARED_LIBRARIES */
-
return (0);
-#else /* if not COFF */
-
- /* Get symbol table info from header of a.out file if given one. */
- if (a_out >= 0)
- {
-#ifdef COFF_ENCAPSULATE
- if (read (a_out, &coffheader, sizeof coffheader) != sizeof coffheader)
- {
- PERROR(a_name);
- }
- if (coffheader.f_magic != COFF_MAGIC)
- {
- ERROR1("%s doesn't have legal coff magic number\n", a_name);
- }
-#endif
- if (read (a_out, &ohdr, sizeof hdr) != sizeof hdr)
- {
- PERROR (a_name);
- }
-
- if (N_BADMAG (ohdr))
- {
- ERROR1 ("invalid magic number in %s", a_name);
- }
- hdr = ohdr;
- }
- else
- {
-#ifdef COFF_ENCAPSULATE
- /* We probably could without too much trouble. The code is in gld
- * but I don't have that much time or incentive.
- */
- ERROR0 ("can't build a COFF file from scratch yet");
-#else
-#ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
- bzero ((void *)&hdr, sizeof hdr);
-#else
- bzero (&hdr, sizeof hdr);
-#endif
-#endif
- }
-
- unexec_text_start = (long) start_of_text ();
- unexec_data_start = data_start;
-
- /* Machine-dependent fixup for header, or maybe for unexec_text_start */
-#ifdef ADJUST_EXEC_HEADER
- ADJUST_EXEC_HEADER;
-#endif /* ADJUST_EXEC_HEADER */
-
- hdr.a_trsize = 0;
- hdr.a_drsize = 0;
- if (entry_address != 0)
- hdr.a_entry = entry_address;
-
- hdr.a_bss = bss_end - bss_start;
- hdr.a_data = bss_start - data_start;
-#ifdef NO_REMAP
- hdr.a_text = ohdr.a_text;
-#else /* not NO_REMAP */
- hdr.a_text = data_start - unexec_text_start;
-
-#ifdef A_TEXT_OFFSET
- hdr.a_text += A_TEXT_OFFSET (ohdr);
-#endif
-
-#endif /* not NO_REMAP */
-
-#ifdef COFF_ENCAPSULATE
- /* We are encapsulating BSD format within COFF format. */
- {
- struct coffscn *tp, *dp, *bp;
- tp = &coffheader.scns[0];
- dp = &coffheader.scns[1];
- bp = &coffheader.scns[2];
- tp->s_size = hdr.a_text + sizeof(struct exec);
- dp->s_paddr = data_start;
- dp->s_vaddr = data_start;
- dp->s_size = hdr.a_data;
- bp->s_paddr = dp->s_vaddr + dp->s_size;
- bp->s_vaddr = bp->s_paddr;
- bp->s_size = hdr.a_bss;
- coffheader.tsize = tp->s_size;
- coffheader.dsize = dp->s_size;
- coffheader.bsize = bp->s_size;
- coffheader.text_start = tp->s_vaddr;
- coffheader.data_start = dp->s_vaddr;
- }
- if (write (new, &coffheader, sizeof coffheader) != sizeof coffheader)
- {
- PERROR(new_name);
- }
-#endif /* COFF_ENCAPSULATE */
-
- if (write (new, &hdr, sizeof hdr) != sizeof hdr)
- {
- PERROR (new_name);
- }
-
-#if 0 /* This #ifndef caused a bug on GNU/Linux when using QMAGIC. */
- /* This adjustment was done above only #ifndef NO_REMAP,
- so only undo it now #ifndef NO_REMAP. */
- /* #ifndef NO_REMAP */
-#endif
-#ifdef A_TEXT_OFFSET
- hdr.a_text -= A_TEXT_OFFSET (ohdr);
-#endif
-
- return 0;
-
-#endif /* not COFF */
}
\f
write_segment (new, ptr, end)
{
register int i, nwrite, ret;
char buf[80];
-#ifndef USE_CRT_DLL
- extern int errno;
-#endif
/* This is the normal amount to write at once.
It is the size of block that NFS uses. */
int writesize = 1 << 13;
int pagesize = getpagesize ();
char zeros[1 << 13];
- bzero (zeros, sizeof (zeros));
+ memset (zeros, 0, sizeof (zeros));
for (i = 0; ptr < end;)
{
)
{
/* Write only a page of zeros at once,
- so that we we don't overshoot the start
+ so that we don't overshoot the start
of the valid memory in the old data segment. */
if (nwrite > pagesize)
nwrite = pagesize;
register char *end;
register char *ptr;
-#ifdef COFF
-
-#ifdef USG_SHARED_LIBRARIES
-
- int scns;
- struct scnhdr scntemp; /* Temporary section header */
-
- /* The purpose of this code is to write out the new file's section
- * contents.
- *
- * Step through the section table. If we know the section (.text,
- * .data) do the appropriate thing. Otherwise, if the section has
- * no allocated space in the file (.bss), do nothing. Otherwise,
- * the section has space allocated in the file, and is not a section
- * we know. So just copy it.
- */
-
- lseek (a_out, sizeof (struct filehdr) + sizeof (struct aouthdr), 0);
-
- for (scns = f_hdr.f_nscns; scns > 0; scns--)
- {
- if (read (a_out, &scntemp, sizeof (scntemp)) != sizeof (scntemp))
- PERROR ("temacs");
-
- if (!strcmp (scntemp.s_name, ".text"))
- {
- lseek (new, (long) text_scnptr, 0);
- ptr = (char *) f_ohdr.text_start;
- end = ptr + f_ohdr.tsize;
- write_segment (new, ptr, end);
- }
- else if (!strcmp (scntemp.s_name, ".data"))
- {
- lseek (new, (long) data_scnptr, 0);
- ptr = (char *) f_ohdr.data_start;
- end = ptr + f_ohdr.dsize;
- write_segment (new, ptr, end);
- }
- else if (!scntemp.s_scnptr)
- ; /* do nothing - no data for this section */
- else
- {
- char page[BUFSIZ];
- int size, n;
- long old_a_out_ptr = lseek (a_out, 0, 1);
-
- lseek (a_out, scntemp.s_scnptr, 0);
- for (size = scntemp.s_size; size > 0; size -= sizeof (page))
- {
- n = size > sizeof (page) ? sizeof (page) : size;
- if (read (a_out, page, n) != n || write (new, page, n) != n)
- PERROR ("emacs");
- }
- lseek (a_out, old_a_out_ptr, 0);
- }
- }
-
-#else /* COFF, but not USG_SHARED_LIBRARIES */
-
#ifdef MSDOS
-#if __DJGPP__ >= 2
/* Dump the original table of exception handlers, not the one
where our exception hooks are registered. */
__djgpp_exception_toggle ();
and which might change the way that dumped Emacs works. */
save_djgpp_startup_flags = _crt0_startup_flags;
_crt0_startup_flags &= ~(_CRT0_FLAG_NO_LFN | _CRT0_FLAG_NEARPTR);
-#endif
#endif
lseek (new, (long) text_scnptr, 0);
ptr = (char *) f_ohdr.text_start;
-#ifdef HEADER_INCL_IN_TEXT
- /* For Gould UTX/32, text starts after headers */
- ptr = (char *) (ptr + text_scnptr);
-#endif /* HEADER_INCL_IN_TEXT */
end = ptr + f_ohdr.tsize;
write_segment (new, ptr, end);
write_segment (new, ptr, end);
#ifdef MSDOS
-#if __DJGPP__ >= 2
/* Restore our exception hooks. */
__djgpp_exception_toggle ();
/* Restore the startup flags. */
_crt0_startup_flags = save_djgpp_startup_flags;
#endif
-#endif
-
-#endif /* USG_SHARED_LIBRARIES */
-#else /* if not COFF */
-
-/* Some machines count the header as part of the text segment.
- That is to say, the header appears in core
- just before the address that start_of_text returns.
- For them, N_TXTOFF is the place where the header goes.
- We must adjust the seek to the place after the header.
- Note that at this point hdr.a_text does *not* count
- the extra A_TEXT_OFFSET bytes, only the actual bytes of code. */
-
-#ifdef A_TEXT_SEEK
- lseek (new, (long) A_TEXT_SEEK (hdr), 0);
-#else
- lseek (new, (long) N_TXTOFF (hdr), 0);
-#endif /* no A_TEXT_SEEK */
-
- ptr = (char *) unexec_text_start;
- end = ptr + hdr.a_text;
- write_segment (new, ptr, end);
-
- ptr = (char *) unexec_data_start;
- end = ptr + hdr.a_data;
-/* This lseek is certainly incorrect when A_TEXT_OFFSET
- and I believe it is a no-op otherwise.
- Let's see if its absence ever fails. */
-/* lseek (new, (long) N_TXTOFF (hdr) + hdr.a_text, 0); */
- write_segment (new, ptr, end);
-
-#endif /* not COFF */
return 0;
}
if (a_out < 0)
return 0;
-#ifdef COFF
if (SYMS_START == 0L)
return 0;
-#endif /* COFF */
-#ifdef COFF
if (lnnoptr) /* if there is line number info */
lseek (a_out, coff_offset + lnnoptr, 0); /* start copying from there */
else
lseek (a_out, coff_offset + SYMS_START, 0); /* Position a.out to symtab. */
-#else /* not COFF */
- lseek (a_out, SYMS_START, 0); /* Position a.out to symtab. */
-#endif /* not COFF */
while ((n = read (a_out, page, sizeof page)) > 0)
{
PERROR (name);
}
\f
-#ifdef COFF
-#ifndef COFF_BSD_SYMBOLS
/*
* If the COFF file contains a symbol table and a line number section,
return 0;
}
-#endif /* COFF_BSD_SYMBOLS */
-
-#endif /* COFF */
-
/* ****************************************************************
* unexec
*
if (make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name) < 0
|| copy_text_and_data (new, a_out) < 0
|| copy_sym (new, a_out, a_name, new_name) < 0
-#ifdef COFF
-#ifndef COFF_BSD_SYMBOLS
|| adjust_lnnoptrs (new, a_out, new_name) < 0
-#endif
-#endif
)
{
close (new);