X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/d02fe47dd3be7310d1bfd6e802d1fac2ea5f5e9d..ed68db4d2cf55caf6847151079e1b3861e5d0879:/src/unexec.c diff --git a/src/unexec.c b/src/unexec.c index 2ca70b752e..6cb27b35c3 100644 --- a/src/unexec.c +++ b/src/unexec.c @@ -1,12 +1,12 @@ /* 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 @@ -14,9 +14,7 @@ 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., 51 Franklin Street, Fifth Floor, -Boston, MA 02110-1301, USA. */ +along with GNU Emacs. If not, see . */ /* @@ -114,39 +112,11 @@ boundary is sufficient. That is the default. When a larger 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. - * 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 @@ -158,14 +128,12 @@ pointer looks like an int) but not on all machines. #ifndef CANNOT_DUMP /* all rest of file! */ -#if defined(COFF) && defined(HAVE_COFF_H) +#ifdef HAVE_COFF_H #include #ifdef MSDOS -#if __DJGPP__ > 1 #include /* for O_RDONLY, O_RDWR */ #include /* 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 @@ -184,9 +152,9 @@ struct aouthdr unsigned long data_start;/* base of data used for this file */ }; #endif /* not MSDOS */ -#else /* not COFF */ +#else /* not HAVE_COFF_H */ #include -#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. */ @@ -199,11 +167,7 @@ struct aouthdr #include #include -#include /* Must be after sys/types.h for USG and BSD4_1*/ - -#ifdef USG5 -#include -#endif +#include #ifndef O_RDONLY #define O_RDONLY 0 @@ -216,7 +180,6 @@ struct aouthdr 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) */ @@ -229,79 +192,17 @@ static long data_scnptr; 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)) - -#ifdef HPUX -#ifdef HP9000S200_ID -#define MY_ID HP9000S200_ID -#else -#include -#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 struct exec hdr, ohdr; - -#else /* not HPUX */ - -#if defined (USG) && !defined (IRIS) && !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 not USG */ -static struct exec hdr, ohdr; -#define NEWMAGIC ZMAGIC -#endif /* IRIS or not USG */ -#endif /* not HPUX */ - -static int unexec_text_start; -static int unexec_data_start; - -#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 #include "lisp.h" static @@ -353,18 +254,12 @@ make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name) 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; @@ -407,14 +302,12 @@ make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name) 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]; @@ -432,7 +325,6 @@ make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name) } else lseek (a_out, 0L, 0); -#endif /* __DJGPP__ > 1 */ #endif /* MSDOS */ if (read (a_out, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr)) { @@ -481,17 +373,6 @@ make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name) /* 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); #ifndef NO_REMAP f_ohdr.text_start = (long) start_of_text (); @@ -505,10 +386,6 @@ make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name) 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)); -#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 @@ -538,9 +415,7 @@ make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name) 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) { @@ -566,8 +441,6 @@ make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name) PERROR (new_name); } -#ifndef USG_SHARED_LIBRARIES - if (write (new, &f_thdr, sizeof (f_thdr)) != sizeof (f_thdr)) { PERROR (new_name); @@ -583,125 +456,8 @@ make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, 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) - { - 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 MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */ - bzero ((void *)&hdr, sizeof hdr); -#else - bzero (&hdr, sizeof hdr); -#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 */ - - 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 */ } write_segment (new, ptr, end) @@ -739,7 +495,7 @@ write_segment (new, 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; @@ -771,67 +527,7 @@ copy_text_and_data (new, a_out) 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 (); @@ -840,7 +536,6 @@ copy_text_and_data (new, a_out) 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); @@ -854,46 +549,13 @@ copy_text_and_data (new, a_out) 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; } @@ -914,19 +576,13 @@ copy_sym (new, a_out, a_name, new_name) 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) { @@ -966,8 +622,6 @@ mark_x (name) PERROR (name); } -#ifdef COFF -#ifndef COFF_BSD_SYMBOLS /* * If the COFF file contains a symbol table and a line number section, @@ -1036,10 +690,6 @@ adjust_lnnoptrs (writedesc, readdesc, new_name) return 0; } -#endif /* COFF_BSD_SYMBOLS */ - -#endif /* COFF */ - /* **************************************************************** * unexec * @@ -1063,11 +713,7 @@ unexec (new_name, a_name, data_start, bss_start, entry_address) 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);