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.
This commit is contained in:
parent
2345325552
commit
27f3c6378b
3 changed files with 39 additions and 17 deletions
|
@ -1,3 +1,14 @@
|
|||
2012-02-25 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
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.
|
||||
|
||||
2012-02-25 Chong Yidong <cyd@gnu.org>
|
||||
|
||||
* fileio.c (Ffile_selinux_context, Fset_file_selinux_context):
|
||||
|
|
27
src/alloc.c
27
src/alloc.c
|
@ -1582,6 +1582,21 @@ make_number (EMACS_INT n)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Convert the pointer-sized word P to EMACS_INT while preserving its
|
||||
type and ptr fields. */
|
||||
static Lisp_Object
|
||||
widen_to_Lisp_Object (void *p)
|
||||
{
|
||||
intptr_t i = (intptr_t) p;
|
||||
#ifdef USE_LISP_UNION_TYPE
|
||||
Lisp_Object obj;
|
||||
obj.i = i;
|
||||
return obj;
|
||||
#else
|
||||
return i;
|
||||
#endif
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
String Allocation
|
||||
***********************************************************************/
|
||||
|
@ -4293,7 +4308,17 @@ mark_memory (void *start, void *end)
|
|||
|
||||
for (pp = start; (void *) pp < end; pp++)
|
||||
for (i = 0; i < sizeof *pp; i += GC_POINTER_ALIGNMENT)
|
||||
mark_maybe_pointer (*(void **) ((char *) pp + i));
|
||||
{
|
||||
void *w = *(void **) ((char *) pp + i);
|
||||
mark_maybe_pointer (w);
|
||||
|
||||
/* A host where a Lisp_Object is wider than a pointer might
|
||||
allocate a Lisp_Object in non-adjacent halves. If
|
||||
USE_LSB_TAG, the bottom half is not a valid pointer, so
|
||||
widen it to to a Lisp_Object and check it that way. */
|
||||
if (sizeof w < sizeof (Lisp_Object))
|
||||
mark_maybe_object (widen_to_Lisp_Object (w));
|
||||
}
|
||||
}
|
||||
|
||||
/* setjmp will work with GCC unless NON_SAVING_SETJMP is defined in
|
||||
|
|
18
src/lisp.h
18
src/lisp.h
|
@ -197,22 +197,8 @@ extern int suppress_checking EXTERNALLY_VISIBLE;
|
|||
# if defined DECL_ALIGN
|
||||
/* On hosts where VALBITS is greater than the pointer width in bits,
|
||||
USE_LSB_TAG is:
|
||||
|
||||
a. unnecessary, because the top bits of an EMACS_INT are unused,
|
||||
|
||||
b. slower, because it typically requires extra masking, and
|
||||
|
||||
c. harmful, because it can create Lisp_Object values that are so scrambled
|
||||
that mark_maybe_object cannot decipher them. mark_maybe_object assumes
|
||||
that EMACS_INT values are contiguous, but a host where EMACS_INT is
|
||||
wider than a pointer might allocate the top half of an EMACS_INT in
|
||||
(say) a 32-bit word on the stack, putting the bottom half in a 32-bit
|
||||
register that is saved elsewhere in a jmp_buf. When this happens,
|
||||
since USE_LSB_TAG is not defined the bottom half alone is a valid
|
||||
pointer that mark_maybe_pointer can follow; but if USE_LSB_TAG were
|
||||
defined, the bottom half would not be a valid pointer and neither
|
||||
mark_maybe_object nor mark_maybe_pointer would follow it.
|
||||
|
||||
a. unnecessary, because the top bits of an EMACS_INT are unused, and
|
||||
b. slower, because it typically requires extra masking.
|
||||
So, define USE_LSB_TAG only on hosts where it might be useful. */
|
||||
# if UINTPTR_MAX >> VALBITS != 0
|
||||
# define USE_LSB_TAG
|
||||
|
|
Loading…
Add table
Reference in a new issue