--- emacs-18.59-orig/src/ChangeLog 2007-01-30 01:00:00.000000000 +0100 +++ emacs-18.59-orig/src/ChangeLog 2008-05-11 02:12:37.000000000 +0200 @@ -1,3 +1,18 @@ +2008-05-11 Ulrich Mueller + + * emacs.c: Handle gap between end of BSS and heap, backported + from Emacs 22. Original changes by Jan Djarv and Masatake YAMATO. + This fixes dumping on Linux 2.6.25. + (my_heap_start, heap_bss_diff, MAX_HEAP_BSS_DIFF): New variables + and constant. + (main): Calculate heap_bss_diff. If we are dumping and the + heap_bss_diff is greater than MAX_HEAP_BSS_DIFF, set PER_LINUX32 + and ADD_NO_RANDOMIZE and exec ourself again. + + * lastfile.c: (my_endbss, my_endbss_static) New variables. + + * s-linux.h (HAVE_PERSONALITY_LINUX32): Define. + 2007-01-30 Ulrich Mueller * x11term.c (internal_socket_read): Handle XK_BackSpace key. --- emacs-18.59-orig/src/emacs.c 2007-01-29 21:47:56.000000000 +0100 +++ emacs-18.59-orig/src/emacs.c 2008-05-11 01:49:58.000000000 +0200 @@ -78,6 +78,10 @@ #endif #endif +#ifdef HAVE_PERSONALITY_LINUX32 +#include +#endif + #ifndef O_RDWR #define O_RDWR 2 #endif @@ -110,6 +114,16 @@ int xargc; #endif /* HAVE_X_WINDOWS */ +/* The address where the heap starts (from the first sbrk (0) call). */ +static void *my_heap_start; + +/* The gap between BSS end and heap start as far as we can tell. */ +static unsigned long heap_bss_diff; + +/* If the gap between BSS end and heap start is larger than this we try to + work around it, and if that fails, output a warning in dump-emacs. */ +#define MAX_HEAP_BSS_DIFF (1024*1024) + #ifdef USG_SHARED_LIBRARIES /* If nonzero, this is the place to put the end of the writable segment at startup. */ @@ -241,7 +255,46 @@ int skip_args = 0; extern int errno; extern void malloc_warning (); + extern char *sbrk (); + if (!initialized) + { + extern char my_endbss[]; + extern char *my_endbss_static; + + if (my_heap_start == 0) + my_heap_start = sbrk (0); + + heap_bss_diff = (char *)my_heap_start + - (my_endbss > my_endbss_static ? my_endbss : my_endbss_static); + } + +#ifdef HAVE_PERSONALITY_LINUX32 + /* See if there is a gap between the end of BSS and the heap. + In that case, set personality and exec ourself again. */ + if (!initialized + && strcmp (argv[argc-1], "dump") == 0 + && heap_bss_diff > MAX_HEAP_BSS_DIFF) + { + if (! getenv ("EMACS_HEAP_EXEC")) + { + /* Set this so we only do this once. */ + putenv("EMACS_HEAP_EXEC=true"); + + /* A flag to turn off address randomization which is introduced + in linux kernel shipped with fedora core 4 */ +#define ADD_NO_RANDOMIZE 0x0040000 + personality (PER_LINUX32 | ADD_NO_RANDOMIZE); +#undef ADD_NO_RANDOMIZE + + execvp (argv[0], argv); + + /* If the exec fails, try to dump anyway. */ + perror ("execvp"); + } + } +#endif /* HAVE_PERSONALITY_LINUX32 */ + /* Map in shared memory, if we are using that. */ #ifdef HAVE_SHM if (argc > 1 && !strcmp (argv[1], "-nl")) --- emacs-18.59-orig/src/lastfile.c 1991-03-31 00:05:55.000000000 +0100 +++ emacs-18.59-orig/src/lastfile.c 2008-05-11 01:52:45.000000000 +0200 @@ -41,3 +41,13 @@ #endif char my_edata = 0; + +/* Help unexec locate the end of the .bss area used by Emacs (which + isn't always a separate section in NT executables). */ +char my_endbss[1]; + +/* The Alpha MSVC linker globally segregates all static and public bss + data, so we must take both into account to determine the true extent + of the bss area used by Emacs. */ +static char _my_endbss[1]; +char * my_endbss_static = _my_endbss; --- emacs-18.59-orig/src/s-linux.h 2007-01-29 21:47:56.000000000 +0100 +++ emacs-18.59-orig/src/s-linux.h 2008-05-11 01:58:40.000000000 +0200 @@ -161,6 +161,7 @@ #define HAVE_SYS_SIGLIST /* we have a (non-standard) sys_siglist */ #define SYS_SIGLIST_DECLARED #define HAVE_GETWD /* cure conflict with getcwd? */ +#define HAVE_PERSONALITY_LINUX32 /* personality LINUX32 can be set */ #define NO_SIOCTL_H /* don't have sioctl.h */ #define SYSV_SYSTEM_DIR /* use dirent.h */