-/* Copyright (C) 1985, 1986, 1987, 1988, 1990, 1992, 1999, 2000, 2001,
- 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+/* Copyright (C) 1985-1988, 1990, 1992, 1999-2011
Free Software Foundation, Inc.
This file is part of GNU Emacs.
* Modified heavily since then.
*
* Synopsis:
- * unexec (new_name, old_name, data_start, bss_start, entry_address)
- * char *new_name, *old_name;
- * unsigned data_start, bss_start, entry_address;
+ * unexec (const char *new_name, const char *old_name);
*
* Takes a snapshot of the program and makes an a.out format file in the
* file named by the string argument new_name.
* If old_name is non-NULL, the symbol table will be taken from the given file.
* On some machines, an existing old_name file is required.
*
- * The boundaries within the a.out file may be adjusted with the data_start
- * and bss_start arguments. Either or both may be given as 0 for defaults.
- *
- * Data_start gives the boundary between the text segment and the data
- * segment of the program. The text segment can contain shared, read-only
- * program code and literal data, while the data segment is always unshared
- * and unprotected. Data_start gives the lowest unprotected address.
- * The value you specify may be rounded down to a suitable boundary
- * as required by the machine you are using.
- *
- * Bss_start indicates how much of the data segment is to be saved in the
- * a.out file and restored when the program is executed. It gives the lowest
- * unsaved address, and is rounded up to a page boundary. The default when 0
- * is given assumes that the entire data segment is to be stored, including
- * the previous data and bss as well as any additional storage allocated with
- * break (2).
- *
- * The new file is set up to start at entry_address.
- *
*/
/* Even more heavily modified by james@bigtex.cactus.org of Dell Computer Co.
/* We do not use mmap because that fails with NFS.
Instead we read the whole file, modify it, and write it out. */
-#ifndef emacs
-#define fatal(a, b, c) fprintf (stderr, a, b, c), exit (1)
-#include <string.h>
-#else
#include <config.h>
+#include <unexec.h>
+
extern void fatal (const char *msgid, ...);
-#endif
#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>
#if !defined (__NetBSD__) && !defined (__OpenBSD__)
#include <elf.h>
-#endif
+#endif /* not __NetBSD__ and not __OpenBSD__ */
#include <sys/mman.h>
#if defined (_SYSTYPE_SYSV)
#include <sys/elf_mips.h>
# define ElfW(type) ElfExpandBitsW (ELFSIZE, type)
#endif
-#ifndef ELF_BSS_SECTION_NAME
-#define ELF_BSS_SECTION_NAME ".bss"
-#endif
-
/* Get the address of a particular section or program header entry,
* accounting for the size of the entries.
*/
(*(ElfW(Shdr) *) ((byte *) old_section_h + old_file_h->e_shentsize * (n)))
#define NEW_SECTION_H(n) \
(*(ElfW(Shdr) *) ((byte *) new_section_h + new_file_h->e_shentsize * (n)))
-#define OLD_PROGRAM_H(n) \
- (*(ElfW(Phdr) *) ((byte *) old_program_h + old_file_h->e_phentsize * (n)))
#define NEW_PROGRAM_H(n) \
(*(ElfW(Phdr) *) ((byte *) new_program_h + new_file_h->e_phentsize * (n)))
if NOERROR is 0; we return -1 if NOERROR is nonzero. */
static int
-find_section (const char *name, char *section_names, char *file_name,
+find_section (const char *name, const char *section_names, const char *file_name,
ElfW(Ehdr) *old_file_h, ElfW(Shdr) *old_section_h, int noerror)
{
int idx;
*
*/
void
-unexec (char *new_name, char *old_name, unsigned int data_start,
- unsigned int bss_start, unsigned int entry_address)
+unexec (const char *new_name, const char *old_name)
{
int new_file, old_file, new_file_size;
+#if defined (emacs) || !defined (DEBUG)
+ void *new_break;
+#endif
+
/* Pointers to the base of the image of the two files. */
caddr_t old_base, new_base;
int n, nn;
int old_bss_index, old_sbss_index, old_plt_index;
int old_data_index, new_data2_index;
+#if defined _SYSTYPE_SYSV || defined __sgi
int old_mdebug_index;
+#endif
struct stat stat_buf;
int old_file_size;
/* Find the mdebug section, if any. */
+#if defined _SYSTYPE_SYSV || defined __sgi
old_mdebug_index = find_section (".mdebug", old_section_names,
old_name, old_file_h, old_section_h, 1);
+#endif
/* Find the old .bss section. Figure out parameters of the new
data2 and bss sections. */
old_name, old_file_h, old_section_h, 0);
#if defined (emacs) || !defined (DEBUG)
- new_bss_addr = (ElfW(Addr)) sbrk (0);
+ new_break = sbrk (0);
+ new_bss_addr = (ElfW(Addr)) new_break;
#else
new_bss_addr = old_bss_addr + old_bss_size + 0x1234;
#endif
Link Info Adralgn Entsize
[22] 1 3 0x335150 0x315150 0x4 .data.rel.local
- 0 0 0x4 0
+ 0 0 0x4 0
[23] 8 3 0x335158 0x315158 0x42720 .bss
- 0 0 0x8 0
+ 0 0 0x8 0
[24] 2 0 0 0x315154 0x1c9d0 .symtab
- 25 1709 0x4 0x10
+ 25 1709 0x4 0x10
*/
if (NEW_SECTION_H (nn).sh_offset >= old_bss_offset
ElfW(Shdr) section = NEW_SECTION_H (n);
/* Cause a compilation error if anyone uses n instead of nn below. */
- struct {int a;} n;
- (void)n.a; /* Prevent `unused variable' warnings. */
+ #define n ((void) 0);
+ n /* Prevent 'macro "n" is not used' warnings. */
switch (section.sh_type)
{
}
break;
}
+
+ #undef n
}
/* Write out new_file, and free the buffers. */
if (write (new_file, new_base, new_file_size) != new_file_size)
-#ifndef emacs
- fatal ("Didn't write %d bytes: errno %d\n",
- new_file_size, errno);
-#else
fatal ("Didn't write %d bytes to %s: errno %d\n",
new_file_size, new_name, errno);
-#endif
munmap (old_base, old_file_size);
munmap (new_base, new_file_size);
if (chmod (new_name, stat_buf.st_mode) == -1)
fatal ("Can't chmod (%s): errno %d\n", new_name, errno);
}
-
-/* arch-tag: e02e1512-95e2-4ef0-bba7-b6bce658f1e3
- (do not change this comment) */