aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2012-02-25 11:39:42 -0800
committerPaul Eggert2012-02-25 11:39:42 -0800
commit27f3c6378b0e09d6e3c1b4b55b7e2fc5c22c8e65 (patch)
tree2e47f4531248214cbb4bd6ceb3bb152741e96aff /src
parent23453255524411eaae5c79d7e4ae6c22f6f05f3f (diff)
downloademacs-27f3c6378b0e09d6e3c1b4b55b7e2fc5c22c8e65.tar.gz
emacs-27f3c6378b0e09d6e3c1b4b55b7e2fc5c22c8e65.zip
Generalize fix for crash due to non-contiguous EMACS_INT (Bug#10780).
Suggested by Stefan Monnier in <http://lists.gnu.org/archive/html/emacs-devel/2012-02/msg00692.html>. * alloc.c (widen_to_Lisp_Object): New static function. (mark_memory): Also mark Lisp_Objects by fetching pointer words and widening them to Lisp_Objects. This would work even if USE_LSB_TAG is defined and wide integers are used, which might happen in a future version of Emacs.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog11
-rw-r--r--src/alloc.c27
-rw-r--r--src/lisp.h18
3 files changed, 39 insertions, 17 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 1566d6258af..9221041da52 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,14 @@
12012-02-25 Paul Eggert <eggert@cs.ucla.edu>
2
3 Generalize fix for crash due to non-contiguous EMACS_INT (Bug#10780).
4 Suggested by Stefan Monnier in
5 <http://lists.gnu.org/archive/html/emacs-devel/2012-02/msg00692.html>.
6 * alloc.c (widen_to_Lisp_Object): New static function.
7 (mark_memory): Also mark Lisp_Objects by fetching pointer words
8 and widening them to Lisp_Objects. This would work even if
9 USE_LSB_TAG is defined and wide integers are used, which might
10 happen in a future version of Emacs.
11
12012-02-25 Chong Yidong <cyd@gnu.org> 122012-02-25 Chong Yidong <cyd@gnu.org>
2 13
3 * fileio.c (Ffile_selinux_context, Fset_file_selinux_context): 14 * fileio.c (Ffile_selinux_context, Fset_file_selinux_context):
diff --git a/src/alloc.c b/src/alloc.c
index 044e750413b..21c4db4ddca 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -1582,6 +1582,21 @@ make_number (EMACS_INT n)
1582} 1582}
1583#endif 1583#endif
1584 1584
1585/* Convert the pointer-sized word P to EMACS_INT while preserving its
1586 type and ptr fields. */
1587static Lisp_Object
1588widen_to_Lisp_Object (void *p)
1589{
1590 intptr_t i = (intptr_t) p;
1591#ifdef USE_LISP_UNION_TYPE
1592 Lisp_Object obj;
1593 obj.i = i;
1594 return obj;
1595#else
1596 return i;
1597#endif
1598}
1599
1585/*********************************************************************** 1600/***********************************************************************
1586 String Allocation 1601 String Allocation
1587 ***********************************************************************/ 1602 ***********************************************************************/
@@ -4293,7 +4308,17 @@ mark_memory (void *start, void *end)
4293 4308
4294 for (pp = start; (void *) pp < end; pp++) 4309 for (pp = start; (void *) pp < end; pp++)
4295 for (i = 0; i < sizeof *pp; i += GC_POINTER_ALIGNMENT) 4310 for (i = 0; i < sizeof *pp; i += GC_POINTER_ALIGNMENT)
4296 mark_maybe_pointer (*(void **) ((char *) pp + i)); 4311 {
4312 void *w = *(void **) ((char *) pp + i);
4313 mark_maybe_pointer (w);
4314
4315 /* A host where a Lisp_Object is wider than a pointer might
4316 allocate a Lisp_Object in non-adjacent halves. If
4317 USE_LSB_TAG, the bottom half is not a valid pointer, so
4318 widen it to to a Lisp_Object and check it that way. */
4319 if (sizeof w < sizeof (Lisp_Object))
4320 mark_maybe_object (widen_to_Lisp_Object (w));
4321 }
4297} 4322}
4298 4323
4299/* setjmp will work with GCC unless NON_SAVING_SETJMP is defined in 4324/* setjmp will work with GCC unless NON_SAVING_SETJMP is defined in
diff --git a/src/lisp.h b/src/lisp.h
index 375d376702b..36f58d05b42 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -197,22 +197,8 @@ extern int suppress_checking EXTERNALLY_VISIBLE;
197# if defined DECL_ALIGN 197# if defined DECL_ALIGN
198/* On hosts where VALBITS is greater than the pointer width in bits, 198/* On hosts where VALBITS is greater than the pointer width in bits,
199 USE_LSB_TAG is: 199 USE_LSB_TAG is:
200 200 a. unnecessary, because the top bits of an EMACS_INT are unused, and
201 a. unnecessary, because the top bits of an EMACS_INT are unused, 201 b. slower, because it typically requires extra masking.
202
203 b. slower, because it typically requires extra masking, and
204
205 c. harmful, because it can create Lisp_Object values that are so scrambled
206 that mark_maybe_object cannot decipher them. mark_maybe_object assumes
207 that EMACS_INT values are contiguous, but a host where EMACS_INT is
208 wider than a pointer might allocate the top half of an EMACS_INT in
209 (say) a 32-bit word on the stack, putting the bottom half in a 32-bit
210 register that is saved elsewhere in a jmp_buf. When this happens,
211 since USE_LSB_TAG is not defined the bottom half alone is a valid
212 pointer that mark_maybe_pointer can follow; but if USE_LSB_TAG were
213 defined, the bottom half would not be a valid pointer and neither
214 mark_maybe_object nor mark_maybe_pointer would follow it.
215
216 So, define USE_LSB_TAG only on hosts where it might be useful. */ 202 So, define USE_LSB_TAG only on hosts where it might be useful. */
217# if UINTPTR_MAX >> VALBITS != 0 203# if UINTPTR_MAX >> VALBITS != 0
218# define USE_LSB_TAG 204# define USE_LSB_TAG