X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/cce7d53002e8abc346b67ea4100507b0e7c4d68e..b59a2e9edb562fce9c63a73242db323cd4a9dc0f:/src/unexaix.c diff --git a/src/unexaix.c b/src/unexaix.c index fe9d13d3e4..da44480fdc 100644 --- a/src/unexaix.c +++ b/src/unexaix.c @@ -1,5 +1,6 @@ /* Dump an executable image. - Copyright (C) 1985-1988, 1999, 2001-2011 Free Software Foundation, Inc. + Copyright (C) 1985-1988, 1999, 2001-2013 Free Software Foundation, + Inc. This file is part of GNU Emacs. @@ -40,6 +41,8 @@ what you give them. Help stamp out software-hoarding! */ */ #include +#include "unexec.h" + #define PERROR(file) report_error (file, new) #include /* Define getpagesize () if the system does not. @@ -48,17 +51,18 @@ 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 */ +#include "mem-limits.h" -extern int _data; -extern int _text; +extern char _data[]; +extern char _text[]; #include #include @@ -67,51 +71,57 @@ 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 int unrelocate_symbols (int, int, char *, char *); +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 #define MAX_SECTIONS 10 #endif -static int adjust_lnnoptrs (int, int, char *); +static int adjust_lnnoptrs (int, int, const char *); static int pagemask; -#include #include "lisp.h" -static void -report_error (char *file, int fd) +static _Noreturn void +report_error (const char *file, int fd) { if (fd) - close (fd); + { + int failed_errno = errno; + close (fd); + errno = failed_errno; + } report_file_error ("Cannot unexec", Fcons (build_string (file), Qnil)); } -#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, char *msg, int a1, int a2) +static _Noreturn void ATTRIBUTE_FORMAT_PRINTF (2, 3) +report_error_1 (int fd, const char *msg, ...) { + va_list ap; close (fd); - error (msg, a1, a2); + va_start (ap, msg); + verror (msg, ap); + va_end (ap); } -static int make_hdr (int, int, unsigned, unsigned, unsigned, char *, char *); -static void mark_x (char *); +static int make_hdr (int, int, const char *, const char *); +static void mark_x (const char *); static int copy_text_and_data (int); -static int copy_sym (int, int, char *, char *); +static int copy_sym (int, int, const char *, const char *); static void write_segment (int, char *, char *); /* **************************************************************** @@ -119,7 +129,8 @@ static void write_segment (int, char *, char *); * * driving logic. */ -int unexec (const char *new_name, const char *a_name) +void +unexec (const char *new_name, const char *a_name) { int new = -1, a_out = -1; @@ -139,14 +150,13 @@ int unexec (const char *new_name, const char *a_name) || unrelocate_symbols (new, a_out, a_name, new_name) < 0) { close (new); - return -1; + return; } close (new); if (a_out >= 0) close (a_out); mark_x (new_name); - return 0; } /* **************************************************************** @@ -157,11 +167,11 @@ int unexec (const char *new_name, const char *a_name) */ static int make_hdr (int new, int a_out, - char *a_name, char *new_name) + 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 */ @@ -176,17 +186,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); } @@ -219,24 +229,24 @@ make_hdr (int new, int a_out, } #define CHECK_SCNHDR(ptr, name, flags) \ - if (strcmp(s->s_name, name) == 0) { \ + if (strcmp (s->s_name, name) == 0) { \ if (s->s_flags != flags) { \ - fprintf(stderr, "unexec: %lx flags where %x expected in %s section.\n", \ - (unsigned long)s->s_flags, flags, name); \ + fprintf (stderr, "unexec: %lx flags where %x expected in %s section.\n", \ + (unsigned long)s->s_flags, flags, name); \ } \ if (ptr) { \ - fprintf(stderr, "unexec: duplicate section header for section %s.\n", \ - name); \ + fprintf (stderr, "unexec: duplicate section header for section %s.\n", \ + name); \ } \ ptr = s; \ } - CHECK_SCNHDR(f_thdr, _TEXT, STYP_TEXT); - CHECK_SCNHDR(f_dhdr, _DATA, STYP_DATA); - CHECK_SCNHDR(f_bhdr, _BSS, STYP_BSS); - CHECK_SCNHDR(f_lhdr, _LOADER, STYP_LOADER); - CHECK_SCNHDR(f_dbhdr, _DEBUG, STYP_DEBUG); - CHECK_SCNHDR(f_tchdr, _TYPCHK, STYP_TYPCHK); - CHECK_SCNHDR(f_xhdr, _EXCEPT, STYP_EXCEPT); + CHECK_SCNHDR (f_thdr, _TEXT, STYP_TEXT); + CHECK_SCNHDR (f_dhdr, _DATA, STYP_DATA); + CHECK_SCNHDR (f_bhdr, _BSS, STYP_BSS); + CHECK_SCNHDR (f_lhdr, _LOADER, STYP_LOADER); + CHECK_SCNHDR (f_dbhdr, _DEBUG, STYP_DEBUG); + CHECK_SCNHDR (f_tchdr, _TYPCHK, STYP_TYPCHK); + CHECK_SCNHDR (f_xhdr, _EXCEPT, STYP_EXCEPT); } if (f_thdr == 0) @@ -276,7 +286,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++) @@ -372,12 +382,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); @@ -390,7 +400,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;) @@ -411,9 +420,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; @@ -427,7 +440,7 @@ write_segment (int new, char *ptr, char *end) * Copy the relocation information and symbol table from the a.out to the new */ static int -copy_sym (int new, int a_out, char *a_name, char *new_name) +copy_sym (int new, int a_out, const char *a_name, const char *new_name) { char page[UnexBlockSz]; int n; @@ -463,7 +476,7 @@ copy_sym (int new, int a_out, char *a_name, char *new_name) * After successfully building the new a.out, mark it executable */ static void -mark_x (char *name) +mark_x (const char *name) { struct stat sbuf; int um; @@ -481,7 +494,7 @@ mark_x (char *name) } static int -adjust_lnnoptrs (int writedesc, int readdesc, char *new_name) +adjust_lnnoptrs (int writedesc, int readdesc, const char *new_name) { int nsyms; int naux; @@ -528,18 +541,19 @@ adjust_lnnoptrs (int writedesc, int readdesc, char *new_name) } static int -unrelocate_symbols (int new, int a_out, char *a_name, char *new_name) +unrelocate_symbols (int new, int a_out, + const char *a_name, const char *new_name) { 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; @@ -624,17 +638,3 @@ unrelocate_symbols (int new, int a_out, char *a_name, char *new_name) } 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); -} -