diff options
| author | Paul Eggert | 2013-02-14 12:05:10 -0800 |
|---|---|---|
| committer | Paul Eggert | 2013-02-14 12:05:10 -0800 |
| commit | 35b3a27e67b60e547ac8bc9388e7724d1f829959 (patch) | |
| tree | 42aabed9384e977d28c33039d7ec6bfffe28e371 | |
| parent | 9e16c3b44bcf407678563f0bd679c0887ec3011c (diff) | |
| download | emacs-35b3a27e67b60e547ac8bc9388e7724d1f829959.tar.gz emacs-35b3a27e67b60e547ac8bc9388e7724d1f829959.zip | |
Fix AIX port.
* configure.ac (DATA_START, DATA_SEG_BITS): Set to 0x20000000 on AIX.
(GC_MARK_STACK): Do not set to GC_USE_GCPROS_AS_BEFORE, as that
runs afoul of some other bug in Emacs, and the default value
GC_MAKE_GCPROS_NOOPS has been tested and works.
* src/lisp.h (XPNTR) [!USE_LSB_TAG && DATA_SEG_BITS]:
Fix bug introduced in 2012-07-27 change. DATA_SEG_BITS, if set,
was #undeffed earlier, so it cannot be used as a macro here.
Use the constant and not the macro. Tested on AIX.
* src/unexaix.c: Revert 2013-02-11 and 2013-02-12 changes to this
file. They're almost surely OK but we're just before a release so
we should avoid changes unless they're clearly needed. Instead,
make the following minor change:
(ADDR_CORRECT): New macro.
Fixes: debbugs:13650
| -rw-r--r-- | ChangeLog | 8 | ||||
| -rw-r--r-- | configure.ac | 7 | ||||
| -rw-r--r-- | src/ChangeLog | 13 | ||||
| -rw-r--r-- | src/lisp.h | 4 | ||||
| -rw-r--r-- | src/unexaix.c | 96 |
5 files changed, 78 insertions, 50 deletions
| @@ -1,3 +1,11 @@ | |||
| 1 | 2013-02-14 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | Fix AIX port (Bug#13650). | ||
| 4 | * configure.ac (DATA_START, DATA_SEG_BITS): Set to 0x20000000 on AIX. | ||
| 5 | (GC_MARK_STACK): Do not set to GC_USE_GCPROS_AS_BEFORE on AIX, as that | ||
| 6 | runs afoul of some other bug in Emacs, and the default value | ||
| 7 | GC_MAKE_GCPROS_NOOPS has been tested and works. | ||
| 8 | |||
| 1 | 2013-01-16 Glenn Morris <rgm@gnu.org> | 9 | 2013-01-16 Glenn Morris <rgm@gnu.org> |
| 2 | 10 | ||
| 3 | * Makefile.in (install-arch-indep): Put back a chmod that was | 11 | * Makefile.in (install-arch-indep): Put back a chmod that was |
diff --git a/configure.ac b/configure.ac index c163ecee3fe..7f6defa7059 100644 --- a/configure.ac +++ b/configure.ac | |||
| @@ -3764,6 +3764,11 @@ case $opsys in | |||
| 3764 | AC_DEFINE(DATA_START, [({ extern int data_start; (char *) &data_start; })]) | 3764 | AC_DEFINE(DATA_START, [({ extern int data_start; (char *) &data_start; })]) |
| 3765 | ;; | 3765 | ;; |
| 3766 | 3766 | ||
| 3767 | aix*) | ||
| 3768 | dnl This works with 32-bit executables; Emacs doesn't support 64-bit. | ||
| 3769 | AC_DEFINE(DATA_START, [0x20000000]) | ||
| 3770 | AC_DEFINE(DATA_SEG_BITS, [0x20000000]) | ||
| 3771 | ;; | ||
| 3767 | hpux*) | 3772 | hpux*) |
| 3768 | dnl The data segment on this machine always starts at address 0x40000000. | 3773 | dnl The data segment on this machine always starts at address 0x40000000. |
| 3769 | AC_DEFINE(DATA_START, [0x40000000]) | 3774 | AC_DEFINE(DATA_START, [0x40000000]) |
| @@ -3827,7 +3832,7 @@ AH_TEMPLATE(GC_MARK_STACK, [Define to GC_USE_GCPROS_AS_BEFORE if | |||
| 3827 | 3832 | ||
| 3828 | 3833 | ||
| 3829 | case $opsys in | 3834 | case $opsys in |
| 3830 | aix4-2 | hpux* | unixware) | 3835 | hpux* | unixware) |
| 3831 | dnl Conservative garbage collection has not been tested, so for now | 3836 | dnl Conservative garbage collection has not been tested, so for now |
| 3832 | dnl play it safe and stick with the old-fashioned way of marking. | 3837 | dnl play it safe and stick with the old-fashioned way of marking. |
| 3833 | AC_DEFINE(GC_MARK_STACK, [GC_USE_GCPROS_AS_BEFORE]) | 3838 | AC_DEFINE(GC_MARK_STACK, [GC_USE_GCPROS_AS_BEFORE]) |
diff --git a/src/ChangeLog b/src/ChangeLog index e1b8a23e6b2..e283d2bb48c 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,16 @@ | |||
| 1 | 2013-02-14 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | Fix AIX port (Bug#13650). | ||
| 4 | * lisp.h (XPNTR) [!USE_LSB_TAG && DATA_SEG_BITS]: | ||
| 5 | Fix bug introduced in 2012-07-27 change. DATA_SEG_BITS, if set, | ||
| 6 | was #undeffed earlier, so it cannot be used as a macro here. | ||
| 7 | Use the constant and not the macro. | ||
| 8 | * unexaix.c: Revert 2013-02-11 and 2013-02-12 changes to this | ||
| 9 | file. They're almost surely OK but we're just before a release so | ||
| 10 | we should avoid changes unless they're clearly needed. Instead, | ||
| 11 | make the following minor change: | ||
| 12 | (ADDR_CORRECT): New macro. | ||
| 13 | |||
| 1 | 2013-02-13 Eli Zaretskii <eliz@gnu.org> | 14 | 2013-02-13 Eli Zaretskii <eliz@gnu.org> |
| 2 | 15 | ||
| 3 | * w32proc.c (new_child): If no vacant slots are found in | 16 | * w32proc.c (new_child): If no vacant slots are found in |
diff --git a/src/lisp.h b/src/lisp.h index a62842c117a..eca3caefd8c 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -496,13 +496,9 @@ static EMACS_INT const VALMASK | |||
| 496 | (XIL ((EMACS_INT) ((EMACS_UINT) (type) << VALBITS) \ | 496 | (XIL ((EMACS_INT) ((EMACS_UINT) (type) << VALBITS) \ |
| 497 | + ((intptr_t) (ptr) & VALMASK))) | 497 | + ((intptr_t) (ptr) & VALMASK))) |
| 498 | 498 | ||
| 499 | #if DATA_SEG_BITS | ||
| 500 | /* DATA_SEG_BITS forces extra bits to be or'd in with any pointers | 499 | /* DATA_SEG_BITS forces extra bits to be or'd in with any pointers |
| 501 | which were stored in a Lisp_Object. */ | 500 | which were stored in a Lisp_Object. */ |
| 502 | #define XPNTR(a) ((uintptr_t) ((XLI (a) & VALMASK)) | DATA_SEG_BITS)) | 501 | #define XPNTR(a) ((uintptr_t) ((XLI (a) & VALMASK)) | DATA_SEG_BITS)) |
| 503 | #else | ||
| 504 | #define XPNTR(a) ((uintptr_t) (XLI (a) & VALMASK)) | ||
| 505 | #endif | ||
| 506 | 502 | ||
| 507 | #endif /* not USE_LSB_TAG */ | 503 | #endif /* not USE_LSB_TAG */ |
| 508 | 504 | ||
diff --git a/src/unexaix.c b/src/unexaix.c index da44480fdca..885d7a9f6d7 100644 --- a/src/unexaix.c +++ b/src/unexaix.c | |||
| @@ -51,8 +51,6 @@ what you give them. Help stamp out software-hoarding! */ | |||
| 51 | #include "getpagesize.h" | 51 | #include "getpagesize.h" |
| 52 | 52 | ||
| 53 | #include <sys/types.h> | 53 | #include <sys/types.h> |
| 54 | #include <inttypes.h> | ||
| 55 | #include <stdarg.h> | ||
| 56 | #include <stdio.h> | 54 | #include <stdio.h> |
| 57 | #include <sys/stat.h> | 55 | #include <sys/stat.h> |
| 58 | #include <errno.h> | 56 | #include <errno.h> |
| @@ -61,8 +59,10 @@ what you give them. Help stamp out software-hoarding! */ | |||
| 61 | 59 | ||
| 62 | #include "mem-limits.h" | 60 | #include "mem-limits.h" |
| 63 | 61 | ||
| 64 | extern char _data[]; | 62 | char *start_of_text (void); /* Start of text */ |
| 65 | extern char _text[]; | 63 | |
| 64 | extern int _data; | ||
| 65 | extern int _text; | ||
| 66 | 66 | ||
| 67 | #include <filehdr.h> | 67 | #include <filehdr.h> |
| 68 | #include <aouthdr.h> | 68 | #include <aouthdr.h> |
| @@ -71,15 +71,15 @@ extern char _text[]; | |||
| 71 | 71 | ||
| 72 | static struct filehdr f_hdr; /* File header */ | 72 | static struct filehdr f_hdr; /* File header */ |
| 73 | static struct aouthdr f_ohdr; /* Optional file header (a.out) */ | 73 | static struct aouthdr f_ohdr; /* Optional file header (a.out) */ |
| 74 | static off_t bias; /* Bias to add for growth */ | 74 | static long bias; /* Bias to add for growth */ |
| 75 | static off_t lnnoptr; /* Pointer to line-number info within file */ | 75 | static long lnnoptr; /* Pointer to line-number info within file */ |
| 76 | 76 | ||
| 77 | static off_t text_scnptr; | 77 | static long text_scnptr; |
| 78 | static off_t data_scnptr; | 78 | static long data_scnptr; |
| 79 | #define ALIGN(val, pwr) (((val) + ((1L<<(pwr))-1)) & ~((1L<<(pwr))-1)) | 79 | #define ALIGN(val, pwr) (((val) + ((1L<<(pwr))-1)) & ~((1L<<(pwr))-1)) |
| 80 | static off_t load_scnptr; | 80 | static long load_scnptr; |
| 81 | static off_t orig_load_scnptr; | 81 | static long orig_load_scnptr; |
| 82 | static off_t orig_data_scnptr; | 82 | static long orig_data_scnptr; |
| 83 | static int unrelocate_symbols (int, int, const char *, const char *); | 83 | static int unrelocate_symbols (int, int, const char *, const char *); |
| 84 | 84 | ||
| 85 | #ifndef MAX_SECTIONS | 85 | #ifndef MAX_SECTIONS |
| @@ -92,30 +92,26 @@ static int pagemask; | |||
| 92 | 92 | ||
| 93 | #include "lisp.h" | 93 | #include "lisp.h" |
| 94 | 94 | ||
| 95 | static _Noreturn void | 95 | static void |
| 96 | report_error (const char *file, int fd) | 96 | report_error (const char *file, int fd) |
| 97 | { | 97 | { |
| 98 | if (fd) | 98 | if (fd) |
| 99 | { | 99 | close (fd); |
| 100 | int failed_errno = errno; | ||
| 101 | close (fd); | ||
| 102 | errno = failed_errno; | ||
| 103 | } | ||
| 104 | report_file_error ("Cannot unexec", Fcons (build_string (file), Qnil)); | 100 | report_file_error ("Cannot unexec", Fcons (build_string (file), Qnil)); |
| 105 | } | 101 | } |
| 106 | 102 | ||
| 107 | #define ERROR0(msg) report_error_1 (new, msg) | 103 | #define ERROR0(msg) report_error_1 (new, msg, 0, 0); return -1 |
| 108 | #define ERROR1(msg,x) report_error_1 (new, msg, x) | 104 | #define ERROR1(msg,x) report_error_1 (new, msg, x, 0); return -1 |
| 109 | #define ERROR2(msg,x,y) report_error_1 (new, msg, x, y) | 105 | #define ERROR2(msg,x,y) report_error_1 (new, msg, x, y); return -1 |
| 110 | 106 | ||
| 111 | static _Noreturn void ATTRIBUTE_FORMAT_PRINTF (2, 3) | 107 | #undef ADDR_CORRECT |
| 112 | report_error_1 (int fd, const char *msg, ...) | 108 | #define ADDR_CORRECT(x) ((int)(x)) |
| 109 | |||
| 110 | static void | ||
| 111 | report_error_1 (int fd, const char *msg, int a1, int a2) | ||
| 113 | { | 112 | { |
| 114 | va_list ap; | ||
| 115 | close (fd); | 113 | close (fd); |
| 116 | va_start (ap, msg); | 114 | error (msg, a1, a2); |
| 117 | verror (msg, ap); | ||
| 118 | va_end (ap); | ||
| 119 | } | 115 | } |
| 120 | 116 | ||
| 121 | static int make_hdr (int, int, const char *, const char *); | 117 | static int make_hdr (int, int, const char *, const char *); |
| @@ -170,8 +166,8 @@ make_hdr (int new, int a_out, | |||
| 170 | const char *a_name, const char *new_name) | 166 | const char *a_name, const char *new_name) |
| 171 | { | 167 | { |
| 172 | int scns; | 168 | int scns; |
| 173 | uintptr_t bss_start; | 169 | unsigned int bss_start; |
| 174 | uintptr_t data_start; | 170 | unsigned int data_start; |
| 175 | 171 | ||
| 176 | struct scnhdr section[MAX_SECTIONS]; | 172 | struct scnhdr section[MAX_SECTIONS]; |
| 177 | struct scnhdr * f_thdr; /* Text section header */ | 173 | struct scnhdr * f_thdr; /* Text section header */ |
| @@ -186,17 +182,17 @@ make_hdr (int new, int a_out, | |||
| 186 | pagemask = getpagesize () - 1; | 182 | pagemask = getpagesize () - 1; |
| 187 | 183 | ||
| 188 | /* Adjust text/data boundary. */ | 184 | /* Adjust text/data boundary. */ |
| 189 | data_start = (uintptr_t) _data; | 185 | data_start = (long) start_of_data (); |
| 186 | data_start = ADDR_CORRECT (data_start); | ||
| 190 | 187 | ||
| 191 | data_start = data_start & ~pagemask; /* (Down) to page boundary. */ | 188 | data_start = data_start & ~pagemask; /* (Down) to page boundary. */ |
| 192 | 189 | ||
| 193 | bss_start = (uintptr_t) sbrk (0) + pagemask; | 190 | bss_start = ADDR_CORRECT (sbrk (0)) + pagemask; |
| 194 | bss_start &= ~ pagemask; | 191 | bss_start &= ~ pagemask; |
| 195 | 192 | ||
| 196 | if (data_start > bss_start) /* Can't have negative data size. */ | 193 | if (data_start > bss_start) /* Can't have negative data size. */ |
| 197 | { | 194 | { |
| 198 | ERROR2 (("unexec: data_start (0x%"PRIxPTR | 195 | ERROR2 ("unexec: data_start (%u) can't be greater than bss_start (%u)", |
| 199 | ") can't be greater than bss_start (0x%"PRIxPTR")"), | ||
| 200 | data_start, bss_start); | 196 | data_start, bss_start); |
| 201 | } | 197 | } |
| 202 | 198 | ||
| @@ -286,7 +282,7 @@ make_hdr (int new, int a_out, | |||
| 286 | 282 | ||
| 287 | /* fix scnptr's */ | 283 | /* fix scnptr's */ |
| 288 | { | 284 | { |
| 289 | off_t ptr = section[0].s_scnptr; | 285 | ulong ptr = section[0].s_scnptr; |
| 290 | 286 | ||
| 291 | bias = -1; | 287 | bias = -1; |
| 292 | for (scns = 0; scns < f_hdr.f_nscns; scns++) | 288 | for (scns = 0; scns < f_hdr.f_nscns; scns++) |
| @@ -382,12 +378,12 @@ copy_text_and_data (int new) | |||
| 382 | char *end; | 378 | char *end; |
| 383 | char *ptr; | 379 | char *ptr; |
| 384 | 380 | ||
| 385 | lseek (new, text_scnptr, SEEK_SET); | 381 | lseek (new, (long) text_scnptr, SEEK_SET); |
| 386 | ptr = _text + text_scnptr; | 382 | ptr = start_of_text () + text_scnptr; |
| 387 | end = ptr + f_ohdr.tsize; | 383 | end = ptr + f_ohdr.tsize; |
| 388 | write_segment (new, ptr, end); | 384 | write_segment (new, ptr, end); |
| 389 | 385 | ||
| 390 | lseek (new, data_scnptr, SEEK_SET); | 386 | lseek (new, (long) data_scnptr, SEEK_SET); |
| 391 | ptr = (char *) f_ohdr.data_start; | 387 | ptr = (char *) f_ohdr.data_start; |
| 392 | end = ptr + f_ohdr.dsize; | 388 | end = ptr + f_ohdr.dsize; |
| 393 | write_segment (new, ptr, end); | 389 | write_segment (new, ptr, end); |
| @@ -400,6 +396,7 @@ static void | |||
| 400 | write_segment (int new, char *ptr, char *end) | 396 | write_segment (int new, char *ptr, char *end) |
| 401 | { | 397 | { |
| 402 | int i, nwrite, ret; | 398 | int i, nwrite, ret; |
| 399 | char buf[80]; | ||
| 403 | char zeros[UnexBlockSz]; | 400 | char zeros[UnexBlockSz]; |
| 404 | 401 | ||
| 405 | for (i = 0; ptr < end;) | 402 | for (i = 0; ptr < end;) |
| @@ -420,13 +417,9 @@ write_segment (int new, char *ptr, char *end) | |||
| 420 | } | 417 | } |
| 421 | else if (nwrite != ret) | 418 | else if (nwrite != ret) |
| 422 | { | 419 | { |
| 423 | int write_errno = errno; | ||
| 424 | char buf[1000]; | ||
| 425 | void *addr = ptr; | ||
| 426 | sprintf (buf, | 420 | sprintf (buf, |
| 427 | "unexec write failure: addr %p, fileno %d, size 0x%x, wrote 0x%x, errno %d", | 421 | "unexec write failure: addr 0x%lx, fileno %d, size 0x%x, wrote 0x%x, errno %d", |
| 428 | addr, new, nwrite, ret, errno); | 422 | (unsigned long)ptr, new, nwrite, ret, errno); |
| 429 | errno = write_errno; | ||
| 430 | PERROR (buf); | 423 | PERROR (buf); |
| 431 | } | 424 | } |
| 432 | i += nwrite; | 425 | i += nwrite; |
| @@ -547,13 +540,13 @@ unrelocate_symbols (int new, int a_out, | |||
| 547 | int i; | 540 | int i; |
| 548 | LDHDR ldhdr; | 541 | LDHDR ldhdr; |
| 549 | LDREL ldrel; | 542 | LDREL ldrel; |
| 550 | off_t t_reloc = (intptr_t) _text - f_ohdr.text_start; | 543 | ulong t_reloc = (ulong) &_text - f_ohdr.text_start; |
| 551 | #ifndef ALIGN_DATA_RELOC | 544 | #ifndef ALIGN_DATA_RELOC |
| 552 | off_t d_reloc = (intptr_t) _data - f_ohdr.data_start; | 545 | ulong d_reloc = (ulong) &_data - f_ohdr.data_start; |
| 553 | #else | 546 | #else |
| 554 | /* This worked (and was needed) before AIX 4.2. | 547 | /* This worked (and was needed) before AIX 4.2. |
| 555 | I have no idea why. -- Mike */ | 548 | I have no idea why. -- Mike */ |
| 556 | off_t d_reloc = (intptr_t) _data - ALIGN (f_ohdr.data_start, 2); | 549 | ulong d_reloc = (ulong) &_data - ALIGN (f_ohdr.data_start, 2); |
| 557 | #endif | 550 | #endif |
| 558 | int * p; | 551 | int * p; |
| 559 | 552 | ||
| @@ -638,3 +631,16 @@ unrelocate_symbols (int new, int a_out, | |||
| 638 | } | 631 | } |
| 639 | return 0; | 632 | return 0; |
| 640 | } | 633 | } |
| 634 | |||
| 635 | /* | ||
| 636 | * Return the address of the start of the text segment prior to | ||
| 637 | * doing an unexec. After unexec the return value is undefined. | ||
| 638 | * See crt0.c for further explanation and _start. | ||
| 639 | * | ||
| 640 | */ | ||
| 641 | |||
| 642 | char * | ||
| 643 | start_of_text (void) | ||
| 644 | { | ||
| 645 | return ((char *) 0x10000000); | ||
| 646 | } | ||