X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/34e39c95429da90b1576aea8acfba8abe1138050..03da5d089a8ed035cec443a27259e7d21487a22e:/src/unexec.c diff --git a/src/unexec.c b/src/unexec.c index 8242756859..ebf813306d 100644 --- a/src/unexec.c +++ b/src/unexec.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1985,86,87,88,92,93,94 Free Software Foundation, Inc. +/* Copyright (C) 1985, 1986, 1987, 1988, 1992, 1993, 1994, 2002, 2003, 2004, + 2005 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -14,8 +15,8 @@ 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. */ +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. */ /* @@ -134,7 +135,7 @@ 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 @@ -367,48 +368,6 @@ static int copy_text_and_data (); static int copy_sym (); static void mark_x (); -/* **************************************************************** - * unexec - * - * driving logic. - */ -unexec (new_name, a_name, data_start, bss_start, entry_address) - char *new_name, *a_name; - unsigned data_start, bss_start, entry_address; -{ - int new, a_out = -1; - - if (a_name && (a_out = open (a_name, O_RDONLY)) < 0) - { - PERROR (a_name); - } - if ((new = creat (new_name, 0666)) < 0) - { - PERROR (new_name); - } - - 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); - /* unlink (new_name); /* Failed, unlink new a.out */ - return -1; - } - - close (new); - if (a_out >= 0) - close (a_out); - mark_x (new_name); - return 0; -} - /* **************************************************************** * make_hdr * @@ -821,7 +780,7 @@ make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name) PERROR (new_name); } -#if 0 /* This #ifndef caused a bug on Linux when using QMAGIC. */ +#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 */ @@ -835,6 +794,61 @@ make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name) #endif /* not COFF */ } +write_segment (new, ptr, end) + int new; + register char *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)); + + for (i = 0; ptr < end;) + { + /* Distance to next multiple of writesize. */ + nwrite = (((int) ptr + writesize) & -writesize) - (int) ptr; + /* But not beyond specified end. */ + if (nwrite > end - ptr) nwrite = end - ptr; + ret = write (new, ptr, nwrite); + /* If write gets a page fault, it means we reached + a gap between the old text segment and the old data segment. + This gap has probably been remapped into part of the text segment. + So write zeros for it. */ + if (ret == -1 +#ifdef EFAULT + && errno == EFAULT +#endif + ) + { + /* Write only a page of zeros at once, + so that we we don't overshoot the start + of the valid memory in the old data segment. */ + if (nwrite > pagesize) + nwrite = pagesize; + write (new, zeros, nwrite); + } +#if 0 /* Now that we have can ask `write' to write more than a page, + it is legit for write do less than the whole amount specified. */ + else if (nwrite != ret) + { + sprintf (buf, + "unexec write failure: addr 0x%x, fileno %d, size 0x%x, wrote 0x%x, errno %d", + ptr, new, nwrite, ret, errno); + PERROR (buf); + } +#endif + i += nwrite; + ptr += nwrite; + } +} /* **************************************************************** * copy_text_and_data * @@ -992,7 +1006,7 @@ copy_text_and_data (new, a_out) char c; int mcount_address, mcount_offset, count; extern char *_execname; - + /* The use of _execname is incompatible with RISCiX 1.1 */ sprintf (command, "nm %s | fgrep mcount", _execname); @@ -1012,7 +1026,7 @@ copy_text_and_data (new, a_out) { sprintf (errbuf, "Failed to execute the command '%s'\n", command); PERROR (errbuf); - } + } sscanf(address_text, "%x", &mcount_address); ptr = (char *) unexec_text_start; @@ -1060,62 +1074,6 @@ copy_text_and_data (new, a_out) return 0; } - -write_segment (new, ptr, end) - int new; - register char *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)); - - for (i = 0; ptr < end;) - { - /* Distance to next multiple of writesize. */ - nwrite = (((int) ptr + writesize) & -writesize) - (int) ptr; - /* But not beyond specified end. */ - if (nwrite > end - ptr) nwrite = end - ptr; - ret = write (new, ptr, nwrite); - /* If write gets a page fault, it means we reached - a gap between the old text segment and the old data segment. - This gap has probably been remapped into part of the text segment. - So write zeros for it. */ - if (ret == -1 -#ifdef EFAULT - && errno == EFAULT -#endif - ) - { - /* Write only a page of zeros at once, - so that we we don't overshoot the start - of the valid memory in the old data segment. */ - if (nwrite > pagesize) - nwrite = pagesize; - write (new, zeros, nwrite); - } -#if 0 /* Now that we have can ask `write' to write more than a page, - it is legit for write do less than the whole amount specified. */ - else if (nwrite != ret) - { - sprintf (buf, - "unexec write failure: addr 0x%x, fileno %d, size 0x%x, wrote 0x%x, errno %d", - ptr, new, nwrite, ret, errno); - PERROR (buf); - } -#endif - i += nwrite; - ptr += nwrite; - } -} /* **************************************************************** * copy_sym @@ -1264,4 +1222,49 @@ adjust_lnnoptrs (writedesc, readdesc, new_name) #endif /* COFF */ +/* **************************************************************** + * unexec + * + * driving logic. + */ +unexec (new_name, a_name, data_start, bss_start, entry_address) + char *new_name, *a_name; + unsigned data_start, bss_start, entry_address; +{ + int new, a_out = -1; + + if (a_name && (a_out = open (a_name, O_RDONLY)) < 0) + { + PERROR (a_name); + } + if ((new = creat (new_name, 0666)) < 0) + { + PERROR (new_name); + } + + 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); + /* unlink (new_name); /* Failed, unlink new a.out */ + return -1; + } + + close (new); + if (a_out >= 0) + close (a_out); + mark_x (new_name); + return 0; +} + #endif /* not CANNOT_DUMP */ + +/* arch-tag: 62409b69-e27a-4a7c-9413-0210d6b54e7f + (do not change this comment) */