aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2013-02-14 12:05:10 -0800
committerPaul Eggert2013-02-14 12:05:10 -0800
commit35b3a27e67b60e547ac8bc9388e7724d1f829959 (patch)
tree42aabed9384e977d28c33039d7ec6bfffe28e371
parent9e16c3b44bcf407678563f0bd679c0887ec3011c (diff)
downloademacs-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--ChangeLog8
-rw-r--r--configure.ac7
-rw-r--r--src/ChangeLog13
-rw-r--r--src/lisp.h4
-rw-r--r--src/unexaix.c96
5 files changed, 78 insertions, 50 deletions
diff --git a/ChangeLog b/ChangeLog
index cddaaa58a5f..6bd8f213c17 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
12013-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
12013-01-16 Glenn Morris <rgm@gnu.org> 92013-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
3829case $opsys in 3834case $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 @@
12013-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
12013-02-13 Eli Zaretskii <eliz@gnu.org> 142013-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
64extern char _data[]; 62char *start_of_text (void); /* Start of text */
65extern char _text[]; 63
64extern int _data;
65extern 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
72static struct filehdr f_hdr; /* File header */ 72static struct filehdr f_hdr; /* File header */
73static struct aouthdr f_ohdr; /* Optional file header (a.out) */ 73static struct aouthdr f_ohdr; /* Optional file header (a.out) */
74static off_t bias; /* Bias to add for growth */ 74static long bias; /* Bias to add for growth */
75static off_t lnnoptr; /* Pointer to line-number info within file */ 75static long lnnoptr; /* Pointer to line-number info within file */
76 76
77static off_t text_scnptr; 77static long text_scnptr;
78static off_t data_scnptr; 78static 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))
80static off_t load_scnptr; 80static long load_scnptr;
81static off_t orig_load_scnptr; 81static long orig_load_scnptr;
82static off_t orig_data_scnptr; 82static long orig_data_scnptr;
83static int unrelocate_symbols (int, int, const char *, const char *); 83static 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
95static _Noreturn void 95static void
96report_error (const char *file, int fd) 96report_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
111static _Noreturn void ATTRIBUTE_FORMAT_PRINTF (2, 3) 107#undef ADDR_CORRECT
112report_error_1 (int fd, const char *msg, ...) 108#define ADDR_CORRECT(x) ((int)(x))
109
110static void
111report_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
121static int make_hdr (int, int, const char *, const char *); 117static 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
400write_segment (int new, char *ptr, char *end) 396write_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
642char *
643start_of_text (void)
644{
645 return ((char *) 0x10000000);
646}