aboutsummaryrefslogtreecommitdiff
blob: 33e82ce64c60bbdb4567010449a7166dd5482b04 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
http://bugs.gentoo.org/220899
temacs segfaults in dump-emacs under Linux 2.6.25
Patch backported from Emacs 22, it comprises the following changes:

2005-07-01  Masatake YAMATO  <jet@gyve.org>

	* emacs.c (main): Passing ADD_NO_RANDOMIZE to `personality'.

2004-10-20  Jan Djärv  <jan.h.d@swipnet.se>

	* emacs.c (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 exec ourself again.

	* lastfile.c: Make my_endbss and my_endbss_static available on all
	platforms.

	* configure.in (HAVE_PERSONALITY_LINUX32): New test if PER_LINUX32
	can be set.

--- emacs-21.4-orig/configure.in	2008-05-11 00:02:58.000000000 +0200
+++ emacs-21.4/configure.in	2008-05-11 00:29:23.000000000 +0200
@@ -1358,6 +1358,18 @@
 AC_CHECK_HEADERS(sys/select.h sys/timeb.h sys/time.h unistd.h utime.h \
   linux/version.h sys/systeminfo.h termios.h limits.h string.h stdlib.h \
   termcap.h stdio_ext.h fcntl.h term.h strings.h)
+
+AC_MSG_CHECKING(if personality LINUX32 can be set)
+AC_TRY_COMPILE([#include <sys/personality.h>], [personality (PER_LINUX32)],
+	       emacs_cv_personality_linux32=yes,
+	       emacs_cv_personality_linux32=no)
+AC_MSG_RESULT($emacs_cv_personality_linux32)
+
+if test $emacs_cv_personality_linux32 = yes; then
+  AC_DEFINE(HAVE_PERSONALITY_LINUX32, 1,
+	    [Define to 1 if personality LINUX32 can be set.])
+fi
+
 AC_HEADER_STDC
 AC_HEADER_TIME
 AC_DECL_SYS_SIGLIST
--- emacs-21.4-orig/src/config.in	2002-07-09 00:23:31.000000000 +0200
+++ emacs-21.4/src/config.in	2008-05-11 00:13:38.000000000 +0200
@@ -183,6 +183,7 @@
 #undef HAVE_UALARM
 #undef HAVE_SYS_WAIT_H
 #undef HAVE_STRINGS_H
+#undef HAVE_PERSONALITY_LINUX32
 
 #undef HAVE_LIBDNET
 #undef HAVE_LIBPTHREADS
--- emacs-21.4-orig/src/emacs.c	2002-08-29 21:27:07.000000000 +0200
+++ emacs-21.4/src/emacs.c	2008-05-11 00:26:38.000000000 +0200
@@ -61,6 +61,10 @@
 #include <sys/resource.h>
 #endif
 
+#ifdef HAVE_PERSONALITY_LINUX32
+#include <sys/personality.h>
+#endif
+
 #ifndef O_RDWR
 #define O_RDWR 2
 #endif
@@ -181,6 +185,16 @@
    Tells GC how to save a copy of the stack.  */
 char *stack_bottom;
 
+/* 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 HAVE_WINDOW_SYSTEM
 extern Lisp_Object Vwindow_system;
 #endif /* HAVE_WINDOW_SYSTEM */
@@ -692,7 +706,11 @@
       free (malloc_state_ptr);
     }
   else
-    malloc_using_checking = getenv ("MALLOC_CHECK_") != NULL;
+    {
+      if (my_heap_start == 0)
+	my_heap_start = sbrk (0);
+      malloc_using_checking = getenv ("MALLOC_CHECK_") != NULL;
+    }
 }
 
 void (*__malloc_initialize_hook) () = malloc_initialize_hook;
@@ -725,6 +743,18 @@
   stack_base = &dummy;
 #endif
 
+  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 LINUX_SBRK_BUG
   __sbrk (1);
 #endif
@@ -763,6 +793,33 @@
 	}
     }
 
+#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
+	  || strcmp (argv[argc-1], "bootstrap") == 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 (argmatch (argv, argc, "-nl", "--no-shared-memory", 6, NULL, &skip_args))
--- emacs-21.4-orig/src/lastfile.c	1999-01-17 20:16:08.000000000 +0100
+++ emacs-21.4/src/lastfile.c	2008-05-11 00:01:55.000000000 +0200
@@ -40,7 +40,6 @@
 
 char my_edata[] = "End of Emacs initialized data";
 
-#ifdef WINDOWSNT
 /* 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];
@@ -50,4 +49,3 @@
    of the bss area used by Emacs.  */
 static char _my_endbss[1];
 char * my_endbss_static = _my_endbss;
-#endif