X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/3a427266b688e084e908ae2ede9b6e373d8b0032..0ec6c340e90369b5921b35bed3bd4cfc0368723e:/src/unexaix.c diff --git a/src/unexaix.c b/src/unexaix.c index 29fa0fd628..fc1acc9ab4 100644 --- a/src/unexaix.c +++ b/src/unexaix.c @@ -1,5 +1,6 @@ /* Dump an executable image. - Copyright (C) 1985-1988, 1999, 2001-2012 Free Software Foundation, Inc. + Copyright (C) 1985-1988, 1999, 2001-2013 Free Software Foundation, + Inc. This file is part of GNU Emacs. @@ -41,6 +42,7 @@ what you give them. Help stamp out software-hoarding! */ #include #include "unexec.h" +#include "lisp.h" #define PERROR(file) report_error (file, new) #include @@ -50,17 +52,16 @@ what you give them. Help stamp out software-hoarding! */ #include "getpagesize.h" #include +#include +#include #include #include #include #include #include -char *start_of_text (void); /* Start of text */ -extern char *start_of_data (void); /* Start of initialized data */ - -extern int _data; -extern int _text; +extern char _data[]; +extern char _text[]; #include #include @@ -69,15 +70,15 @@ extern int _text; static struct filehdr f_hdr; /* File header */ static struct aouthdr f_ohdr; /* Optional file header (a.out) */ -static long bias; /* Bias to add for growth */ -static long lnnoptr; /* Pointer to line-number info within file */ +static off_t bias; /* Bias to add for growth */ +static off_t lnnoptr; /* Pointer to line-number info within file */ -static long text_scnptr; -static long data_scnptr; +static off_t text_scnptr; +static off_t data_scnptr; #define ALIGN(val, pwr) (((val) + ((1L<<(pwr))-1)) & ~((1L<<(pwr))-1)) -static long load_scnptr; -static long orig_load_scnptr; -static long orig_data_scnptr; +static off_t load_scnptr; +static off_t orig_load_scnptr; +static off_t orig_data_scnptr; static int unrelocate_symbols (int, int, const char *, const char *); #ifndef MAX_SECTIONS @@ -88,26 +89,29 @@ static int adjust_lnnoptrs (int, int, const char *); static int pagemask; -#include #include "lisp.h" -static void +static _Noreturn void report_error (const char *file, int fd) { + int err = errno; if (fd) - close (fd); - report_file_error ("Cannot unexec", Fcons (build_string (file), Qnil)); + emacs_close (fd); + report_file_errno ("Cannot unexec", build_string (file), err); } -#define ERROR0(msg) report_error_1 (new, msg, 0, 0); return -1 -#define ERROR1(msg,x) report_error_1 (new, msg, x, 0); return -1 -#define ERROR2(msg,x,y) report_error_1 (new, msg, x, y); return -1 +#define ERROR0(msg) report_error_1 (new, msg) +#define ERROR1(msg,x) report_error_1 (new, msg, x) +#define ERROR2(msg,x,y) report_error_1 (new, msg, x, y) -static void -report_error_1 (int fd, const char *msg, int a1, int a2) +static _Noreturn void ATTRIBUTE_FORMAT_PRINTF (2, 3) +report_error_1 (int fd, const char *msg, ...) { - close (fd); - error (msg, a1, a2); + va_list ap; + emacs_close (fd); + va_start (ap, msg); + verror (msg, ap); + va_end (ap); } static int make_hdr (int, int, const char *, const char *); @@ -126,11 +130,11 @@ unexec (const char *new_name, const char *a_name) { int new = -1, a_out = -1; - if (a_name && (a_out = open (a_name, O_RDONLY)) < 0) + if (a_name && (a_out = emacs_open (a_name, O_RDONLY, 0)) < 0) { PERROR (a_name); } - if ((new = creat (new_name, 0666)) < 0) + if ((new = emacs_open (new_name, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) { PERROR (new_name); } @@ -141,13 +145,13 @@ unexec (const char *new_name, const char *a_name) || adjust_lnnoptrs (new, a_out, new_name) < 0 || unrelocate_symbols (new, a_out, a_name, new_name) < 0) { - close (new); + emacs_close (new); return; } - close (new); + emacs_close (new); if (a_out >= 0) - close (a_out); + emacs_close (a_out); mark_x (new_name); } @@ -162,8 +166,8 @@ make_hdr (int new, int a_out, const char *a_name, const char *new_name) { int scns; - unsigned int bss_start; - unsigned int data_start; + uintptr_t bss_start; + uintptr_t data_start; struct scnhdr section[MAX_SECTIONS]; struct scnhdr * f_thdr; /* Text section header */ @@ -178,17 +182,17 @@ make_hdr (int new, int a_out, pagemask = getpagesize () - 1; /* Adjust text/data boundary. */ - data_start = (long) start_of_data (); - data_start = ADDR_CORRECT (data_start); + data_start = (uintptr_t) _data; data_start = data_start & ~pagemask; /* (Down) to page boundary. */ - bss_start = ADDR_CORRECT (sbrk (0)) + pagemask; + bss_start = (uintptr_t) sbrk (0) + pagemask; bss_start &= ~ pagemask; if (data_start > bss_start) /* Can't have negative data size. */ { - ERROR2 ("unexec: data_start (%u) can't be greater than bss_start (%u)", + ERROR2 (("unexec: data_start (0x%"PRIxPTR + ") can't be greater than bss_start (0x%"PRIxPTR")"), data_start, bss_start); } @@ -278,7 +282,7 @@ make_hdr (int new, int a_out, /* fix scnptr's */ { - ulong ptr = section[0].s_scnptr; + off_t ptr = section[0].s_scnptr; bias = -1; for (scns = 0; scns < f_hdr.f_nscns; scns++) @@ -374,12 +378,12 @@ copy_text_and_data (int new) char *end; char *ptr; - lseek (new, (long) text_scnptr, SEEK_SET); - ptr = start_of_text () + text_scnptr; + lseek (new, text_scnptr, SEEK_SET); + ptr = _text + text_scnptr; end = ptr + f_ohdr.tsize; write_segment (new, ptr, end); - lseek (new, (long) data_scnptr, SEEK_SET); + lseek (new, data_scnptr, SEEK_SET); ptr = (char *) f_ohdr.data_start; end = ptr + f_ohdr.dsize; write_segment (new, ptr, end); @@ -392,7 +396,6 @@ static void write_segment (int new, char *ptr, char *end) { int i, nwrite, ret; - char buf[80]; char zeros[UnexBlockSz]; for (i = 0; ptr < end;) @@ -413,9 +416,13 @@ write_segment (int new, char *ptr, char *end) } else if (nwrite != ret) { + int write_errno = errno; + char buf[1000]; + void *addr = ptr; sprintf (buf, - "unexec write failure: addr 0x%lx, fileno %d, size 0x%x, wrote 0x%x, errno %d", - (unsigned long)ptr, new, nwrite, ret, errno); + "unexec write failure: addr %p, fileno %d, size 0x%x, wrote 0x%x, errno %d", + addr, new, nwrite, ret, errno); + errno = write_errno; PERROR (buf); } i += nwrite; @@ -494,7 +501,7 @@ adjust_lnnoptrs (int writedesc, int readdesc, const char *new_name) if (!lnnoptr || !f_hdr.f_symptr) return 0; - if ((new = open (new_name, O_RDWR)) < 0) + if ((new = emacs_open (new_name, O_RDWR, 0)) < 0) { PERROR (new_name); return -1; @@ -524,7 +531,7 @@ adjust_lnnoptrs (int writedesc, int readdesc, const char *new_name) } } } - close (new); + emacs_close (new); return 0; } @@ -536,13 +543,13 @@ unrelocate_symbols (int new, int a_out, int i; LDHDR ldhdr; LDREL ldrel; - ulong t_reloc = (ulong) &_text - f_ohdr.text_start; + off_t t_reloc = (intptr_t) _text - f_ohdr.text_start; #ifndef ALIGN_DATA_RELOC - ulong d_reloc = (ulong) &_data - f_ohdr.data_start; + off_t d_reloc = (intptr_t) _data - f_ohdr.data_start; #else /* This worked (and was needed) before AIX 4.2. I have no idea why. -- Mike */ - ulong d_reloc = (ulong) &_data - ALIGN (f_ohdr.data_start, 2); + off_t d_reloc = (intptr_t) _data - ALIGN (f_ohdr.data_start, 2); #endif int * p; @@ -627,16 +634,3 @@ unrelocate_symbols (int new, int a_out, } return 0; } - -/* - * Return the address of the start of the text segment prior to - * doing an unexec. After unexec the return value is undefined. - * See crt0.c for further explanation and _start. - * - */ - -char * -start_of_text (void) -{ - return ((char *) 0x10000000); -}