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
This commit is contained in:
Paul Eggert 2013-02-14 12:05:10 -08:00
parent 9e16c3b44b
commit 35b3a27e67
5 changed files with 78 additions and 50 deletions

View file

@ -1,3 +1,11 @@
2013-02-14 Paul Eggert <eggert@cs.ucla.edu>
Fix AIX port (Bug#13650).
* configure.ac (DATA_START, DATA_SEG_BITS): Set to 0x20000000 on AIX.
(GC_MARK_STACK): Do not set to GC_USE_GCPROS_AS_BEFORE on AIX, as that
runs afoul of some other bug in Emacs, and the default value
GC_MAKE_GCPROS_NOOPS has been tested and works.
2013-01-16 Glenn Morris <rgm@gnu.org> 2013-01-16 Glenn Morris <rgm@gnu.org>
* Makefile.in (install-arch-indep): Put back a chmod that was * Makefile.in (install-arch-indep): Put back a chmod that was

View file

@ -3764,6 +3764,11 @@ case $opsys in
AC_DEFINE(DATA_START, [({ extern int data_start; (char *) &data_start; })]) AC_DEFINE(DATA_START, [({ extern int data_start; (char *) &data_start; })])
;; ;;
aix*)
dnl This works with 32-bit executables; Emacs doesn't support 64-bit.
AC_DEFINE(DATA_START, [0x20000000])
AC_DEFINE(DATA_SEG_BITS, [0x20000000])
;;
hpux*) hpux*)
dnl The data segment on this machine always starts at address 0x40000000. dnl The data segment on this machine always starts at address 0x40000000.
AC_DEFINE(DATA_START, [0x40000000]) AC_DEFINE(DATA_START, [0x40000000])
@ -3827,7 +3832,7 @@ AH_TEMPLATE(GC_MARK_STACK, [Define to GC_USE_GCPROS_AS_BEFORE if
case $opsys in case $opsys in
aix4-2 | hpux* | unixware) hpux* | unixware)
dnl Conservative garbage collection has not been tested, so for now dnl Conservative garbage collection has not been tested, so for now
dnl play it safe and stick with the old-fashioned way of marking. dnl play it safe and stick with the old-fashioned way of marking.
AC_DEFINE(GC_MARK_STACK, [GC_USE_GCPROS_AS_BEFORE]) AC_DEFINE(GC_MARK_STACK, [GC_USE_GCPROS_AS_BEFORE])

View file

@ -1,3 +1,16 @@
2013-02-14 Paul Eggert <eggert@cs.ucla.edu>
Fix AIX port (Bug#13650).
* 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.
* 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.
2013-02-13 Eli Zaretskii <eliz@gnu.org> 2013-02-13 Eli Zaretskii <eliz@gnu.org>
* w32proc.c (new_child): If no vacant slots are found in * w32proc.c (new_child): If no vacant slots are found in

View file

@ -496,13 +496,9 @@ static EMACS_INT const VALMASK
(XIL ((EMACS_INT) ((EMACS_UINT) (type) << VALBITS) \ (XIL ((EMACS_INT) ((EMACS_UINT) (type) << VALBITS) \
+ ((intptr_t) (ptr) & VALMASK))) + ((intptr_t) (ptr) & VALMASK)))
#if DATA_SEG_BITS
/* DATA_SEG_BITS forces extra bits to be or'd in with any pointers /* DATA_SEG_BITS forces extra bits to be or'd in with any pointers
which were stored in a Lisp_Object. */ which were stored in a Lisp_Object. */
#define XPNTR(a) ((uintptr_t) ((XLI (a) & VALMASK)) | DATA_SEG_BITS)) #define XPNTR(a) ((uintptr_t) ((XLI (a) & VALMASK)) | DATA_SEG_BITS))
#else
#define XPNTR(a) ((uintptr_t) (XLI (a) & VALMASK))
#endif
#endif /* not USE_LSB_TAG */ #endif /* not USE_LSB_TAG */

View file

@ -51,8 +51,6 @@ what you give them. Help stamp out software-hoarding! */
#include "getpagesize.h" #include "getpagesize.h"
#include <sys/types.h> #include <sys/types.h>
#include <inttypes.h>
#include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <errno.h> #include <errno.h>
@ -61,8 +59,10 @@ what you give them. Help stamp out software-hoarding! */
#include "mem-limits.h" #include "mem-limits.h"
extern char _data[]; char *start_of_text (void); /* Start of text */
extern char _text[];
extern int _data;
extern int _text;
#include <filehdr.h> #include <filehdr.h>
#include <aouthdr.h> #include <aouthdr.h>
@ -71,15 +71,15 @@ extern char _text[];
static struct filehdr f_hdr; /* File header */ static struct filehdr f_hdr; /* File header */
static struct aouthdr f_ohdr; /* Optional file header (a.out) */ static struct aouthdr f_ohdr; /* Optional file header (a.out) */
static off_t bias; /* Bias to add for growth */ static long bias; /* Bias to add for growth */
static off_t lnnoptr; /* Pointer to line-number info within file */ static long lnnoptr; /* Pointer to line-number info within file */
static off_t text_scnptr; static long text_scnptr;
static off_t data_scnptr; static long data_scnptr;
#define ALIGN(val, pwr) (((val) + ((1L<<(pwr))-1)) & ~((1L<<(pwr))-1)) #define ALIGN(val, pwr) (((val) + ((1L<<(pwr))-1)) & ~((1L<<(pwr))-1))
static off_t load_scnptr; static long load_scnptr;
static off_t orig_load_scnptr; static long orig_load_scnptr;
static off_t orig_data_scnptr; static long orig_data_scnptr;
static int unrelocate_symbols (int, int, const char *, const char *); static int unrelocate_symbols (int, int, const char *, const char *);
#ifndef MAX_SECTIONS #ifndef MAX_SECTIONS
@ -92,30 +92,26 @@ static int pagemask;
#include "lisp.h" #include "lisp.h"
static _Noreturn void static void
report_error (const char *file, int fd) report_error (const char *file, int fd)
{ {
if (fd) if (fd)
{ close (fd);
int failed_errno = errno;
close (fd);
errno = failed_errno;
}
report_file_error ("Cannot unexec", Fcons (build_string (file), Qnil)); report_file_error ("Cannot unexec", Fcons (build_string (file), Qnil));
} }
#define ERROR0(msg) report_error_1 (new, msg) #define ERROR0(msg) report_error_1 (new, msg, 0, 0); return -1
#define ERROR1(msg,x) report_error_1 (new, msg, x) #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) #define ERROR2(msg,x,y) report_error_1 (new, msg, x, y); return -1
static _Noreturn void ATTRIBUTE_FORMAT_PRINTF (2, 3) #undef ADDR_CORRECT
report_error_1 (int fd, const char *msg, ...) #define ADDR_CORRECT(x) ((int)(x))
static void
report_error_1 (int fd, const char *msg, int a1, int a2)
{ {
va_list ap;
close (fd); close (fd);
va_start (ap, msg); error (msg, a1, a2);
verror (msg, ap);
va_end (ap);
} }
static int make_hdr (int, int, const char *, const char *); static int make_hdr (int, int, const char *, const char *);
@ -170,8 +166,8 @@ make_hdr (int new, int a_out,
const char *a_name, const char *new_name) const char *a_name, const char *new_name)
{ {
int scns; int scns;
uintptr_t bss_start; unsigned int bss_start;
uintptr_t data_start; unsigned int data_start;
struct scnhdr section[MAX_SECTIONS]; struct scnhdr section[MAX_SECTIONS];
struct scnhdr * f_thdr; /* Text section header */ struct scnhdr * f_thdr; /* Text section header */
@ -186,17 +182,17 @@ make_hdr (int new, int a_out,
pagemask = getpagesize () - 1; pagemask = getpagesize () - 1;
/* Adjust text/data boundary. */ /* Adjust text/data boundary. */
data_start = (uintptr_t) _data; data_start = (long) start_of_data ();
data_start = ADDR_CORRECT (data_start);
data_start = data_start & ~pagemask; /* (Down) to page boundary. */ data_start = data_start & ~pagemask; /* (Down) to page boundary. */
bss_start = (uintptr_t) sbrk (0) + pagemask; bss_start = ADDR_CORRECT (sbrk (0)) + pagemask;
bss_start &= ~ pagemask; bss_start &= ~ pagemask;
if (data_start > bss_start) /* Can't have negative data size. */ if (data_start > bss_start) /* Can't have negative data size. */
{ {
ERROR2 (("unexec: data_start (0x%"PRIxPTR ERROR2 ("unexec: data_start (%u) can't be greater than bss_start (%u)",
") can't be greater than bss_start (0x%"PRIxPTR")"),
data_start, bss_start); data_start, bss_start);
} }
@ -286,7 +282,7 @@ make_hdr (int new, int a_out,
/* fix scnptr's */ /* fix scnptr's */
{ {
off_t ptr = section[0].s_scnptr; ulong ptr = section[0].s_scnptr;
bias = -1; bias = -1;
for (scns = 0; scns < f_hdr.f_nscns; scns++) for (scns = 0; scns < f_hdr.f_nscns; scns++)
@ -382,12 +378,12 @@ copy_text_and_data (int new)
char *end; char *end;
char *ptr; char *ptr;
lseek (new, text_scnptr, SEEK_SET); lseek (new, (long) text_scnptr, SEEK_SET);
ptr = _text + text_scnptr; ptr = start_of_text () + text_scnptr;
end = ptr + f_ohdr.tsize; end = ptr + f_ohdr.tsize;
write_segment (new, ptr, end); write_segment (new, ptr, end);
lseek (new, data_scnptr, SEEK_SET); lseek (new, (long) data_scnptr, SEEK_SET);
ptr = (char *) f_ohdr.data_start; ptr = (char *) f_ohdr.data_start;
end = ptr + f_ohdr.dsize; end = ptr + f_ohdr.dsize;
write_segment (new, ptr, end); write_segment (new, ptr, end);
@ -400,6 +396,7 @@ static void
write_segment (int new, char *ptr, char *end) write_segment (int new, char *ptr, char *end)
{ {
int i, nwrite, ret; int i, nwrite, ret;
char buf[80];
char zeros[UnexBlockSz]; char zeros[UnexBlockSz];
for (i = 0; ptr < end;) for (i = 0; ptr < end;)
@ -420,13 +417,9 @@ write_segment (int new, char *ptr, char *end)
} }
else if (nwrite != ret) else if (nwrite != ret)
{ {
int write_errno = errno;
char buf[1000];
void *addr = ptr;
sprintf (buf, sprintf (buf,
"unexec write failure: addr %p, fileno %d, size 0x%x, wrote 0x%x, errno %d", "unexec write failure: addr 0x%lx, fileno %d, size 0x%x, wrote 0x%x, errno %d",
addr, new, nwrite, ret, errno); (unsigned long)ptr, new, nwrite, ret, errno);
errno = write_errno;
PERROR (buf); PERROR (buf);
} }
i += nwrite; i += nwrite;
@ -547,13 +540,13 @@ unrelocate_symbols (int new, int a_out,
int i; int i;
LDHDR ldhdr; LDHDR ldhdr;
LDREL ldrel; LDREL ldrel;
off_t t_reloc = (intptr_t) _text - f_ohdr.text_start; ulong t_reloc = (ulong) &_text - f_ohdr.text_start;
#ifndef ALIGN_DATA_RELOC #ifndef ALIGN_DATA_RELOC
off_t d_reloc = (intptr_t) _data - f_ohdr.data_start; ulong d_reloc = (ulong) &_data - f_ohdr.data_start;
#else #else
/* This worked (and was needed) before AIX 4.2. /* This worked (and was needed) before AIX 4.2.
I have no idea why. -- Mike */ I have no idea why. -- Mike */
off_t d_reloc = (intptr_t) _data - ALIGN (f_ohdr.data_start, 2); ulong d_reloc = (ulong) &_data - ALIGN (f_ohdr.data_start, 2);
#endif #endif
int * p; int * p;
@ -638,3 +631,16 @@ unrelocate_symbols (int new, int a_out,
} }
return 0; 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);
}