aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2018-05-18 15:45:42 -0700
committerPaul Eggert2018-05-18 15:49:48 -0700
commita1c925fd41818cb8ad209762739b220efb919d1e (patch)
tree4d3c95a065057114a49a9a3435d26479a086d8a1 /src
parentf4d9fd3dd45f767eca33fbf1beee40da790fa74e (diff)
downloademacs-a1c925fd41818cb8ad209762739b220efb919d1e.tar.gz
emacs-a1c925fd41818cb8ad209762739b220efb919d1e.zip
Port to GCC 8 -fsanitize=undefined
In GCC 8, gcc -fsanitize=undefined flags the undefined behavior that Emacs relies on in its XPNTR and XSYMBOL low-level functions. Disable undefined sanitization in these functions. Although this disabling doesn’t suffice if DEFINE_KEY_OPS_AS_MACROS is true, it works for -fsanitize=undefined -DINLINING=0, which is good enough. * src/alloc.c (macro_PNTR_ADD): New macro. (PNTR_ADD): New function and macro. The function disables -fsanitize=undefined. (macro_XPNTR): Use it. * src/conf_post.h (ATTRIBUTE_NO_SANITIZE_UNDEFINED): New macro. * src/lisp.h (XSYMBOL): Disable -fsanitize=undefined.
Diffstat (limited to 'src')
-rw-r--r--src/alloc.c32
-rw-r--r--src/conf_post.h12
-rw-r--r--src/lisp.h2
3 files changed, 37 insertions, 9 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 8264e0623cf..231ade5cf80 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -503,18 +503,34 @@ pointer_align (void *ptr, int alignment)
503 return (void *) ROUNDUP ((uintptr_t) ptr, alignment); 503 return (void *) ROUNDUP ((uintptr_t) ptr, alignment);
504} 504}
505 505
506/* Extract the pointer hidden within O. Define this as a function, as 506/* Define PNTR_ADD and XPNTR as functions, which are cleaner and can
507 functions are cleaner and can be used in debuggers. Also, define 507 be used in debuggers. Also, define them as macros if
508 it as a macro if being compiled with GCC without optimization, for 508 DEFINE_KEY_OPS_AS_MACROS, for performance in that case.
509 performance in that case. macro_XPNTR is private to this section 509 The macro_* macros are private to this section of code. */
510 of code. */ 510
511/* Add a pointer an an integer without complaint about a pointer going
512 out of range of the underlying array. */
513
514#define macro_PNTR_ADD(p, i) ((p) + (i))
515
516static char * ATTRIBUTE_NO_SANITIZE_UNDEFINED ATTRIBUTE_UNUSED
517PNTR_ADD (char *p, EMACS_UINT i)
518{
519 return macro_PNTR_ADD (p, i);
520}
521
522#if DEFINE_KEY_OPS_AS_MACROS
523# define PNTR_ADD(p, i) macro_PNTR_ADD (p, i)
524#endif
525
526/* Extract the pointer hidden within O. */
511 527
512#define macro_XPNTR(o) \ 528#define macro_XPNTR(o) \
513 ((void *) \ 529 ((void *) \
514 (SYMBOLP (o) \ 530 (SYMBOLP (o) \
515 ? ((char *) lispsym \ 531 ? PNTR_ADD ((char *) lispsym, \
516 - ((EMACS_UINT) Lisp_Symbol << (USE_LSB_TAG ? 0 : VALBITS)) \ 532 (XLI (o) \
517 + XLI (o)) \ 533 - ((EMACS_UINT) Lisp_Symbol << (USE_LSB_TAG ? 0 : VALBITS)))) \
518 : (char *) XLP (o) - (XLI (o) & ~VALMASK))) 534 : (char *) XLP (o) - (XLI (o) & ~VALMASK)))
519 535
520static ATTRIBUTE_UNUSED void * 536static ATTRIBUTE_UNUSED void *
diff --git a/src/conf_post.h b/src/conf_post.h
index 00e283d289c..bf2cfc4f05f 100644
--- a/src/conf_post.h
+++ b/src/conf_post.h
@@ -67,6 +67,7 @@ typedef bool bool_bf;
67# define __has_attribute_externally_visible GNUC_PREREQ (4, 1, 0) 67# define __has_attribute_externally_visible GNUC_PREREQ (4, 1, 0)
68# define __has_attribute_no_address_safety_analysis false 68# define __has_attribute_no_address_safety_analysis false
69# define __has_attribute_no_sanitize_address GNUC_PREREQ (4, 8, 0) 69# define __has_attribute_no_sanitize_address GNUC_PREREQ (4, 8, 0)
70# define __has_attribute_no_sanitize_undefined GNUC_PREREQ (4, 9, 0)
70#endif 71#endif
71 72
72/* Simulate __has_builtin on compilers that lack it. It is used only 73/* Simulate __has_builtin on compilers that lack it. It is used only
@@ -338,6 +339,17 @@ extern int emacs_setenv_TZ (char const *);
338# define ATTRIBUTE_NO_SANITIZE_ADDRESS 339# define ATTRIBUTE_NO_SANITIZE_ADDRESS
339#endif 340#endif
340 341
342/* Attribute of functions whose undefined behavior should not be sanitized. */
343
344#if __has_attribute (no_sanitize_undefined)
345# define ATTRIBUTE_NO_SANITIZE_UNDEFINED __attribute__ ((no_sanitize_undefined))
346#elif __has_attribute (no_sanitize)
347# define ATTRIBUTE_NO_SANITIZE_UNDEFINED \
348 __attribute__ ((no_sanitize ("undefined")))
349#else
350# define ATTRIBUTE_NO_SANITIZE_UNDEFINED
351#endif
352
341/* gcc -fsanitize=address does not work with vfork in Fedora 25 x86-64. 353/* gcc -fsanitize=address does not work with vfork in Fedora 25 x86-64.
342 For now, assume that this problem occurs on all platforms. */ 354 For now, assume that this problem occurs on all platforms. */
343#if ADDRESS_SANITIZER && !defined vfork 355#if ADDRESS_SANITIZER && !defined vfork
diff --git a/src/lisp.h b/src/lisp.h
index a18b64a588f..ee2e72d32b7 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -900,7 +900,7 @@ INLINE bool
900 return lisp_h_SYMBOLP (x); 900 return lisp_h_SYMBOLP (x);
901} 901}
902 902
903INLINE struct Lisp_Symbol * 903INLINE struct Lisp_Symbol * ATTRIBUTE_NO_SANITIZE_UNDEFINED
904(XSYMBOL) (Lisp_Object a) 904(XSYMBOL) (Lisp_Object a)
905{ 905{
906#if USE_LSB_TAG 906#if USE_LSB_TAG