emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master a1c925f: Port to GCC 8 -fsanitize=undefined


From: Paul Eggert
Subject: [Emacs-diffs] master a1c925f: Port to GCC 8 -fsanitize=undefined
Date: Fri, 18 May 2018 18:49:54 -0400 (EDT)

branch: master
commit a1c925fd41818cb8ad209762739b220efb919d1e
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>

    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.
---
 src/alloc.c     | 32 ++++++++++++++++++++++++--------
 src/conf_post.h | 12 ++++++++++++
 src/lisp.h      |  2 +-
 3 files changed, 37 insertions(+), 9 deletions(-)

diff --git a/src/alloc.c b/src/alloc.c
index 8264e06..231ade5 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -503,18 +503,34 @@ pointer_align (void *ptr, int alignment)
   return (void *) ROUNDUP ((uintptr_t) ptr, alignment);
 }
 
-/* Extract the pointer hidden within O.  Define this as a function, as
-   functions are cleaner and can be used in debuggers.  Also, define
-   it as a macro if being compiled with GCC without optimization, for
-   performance in that case.  macro_XPNTR is private to this section
-   of code.  */
+/* Define PNTR_ADD and XPNTR as functions, which are cleaner and can
+   be used in debuggers.  Also, define them as macros if
+   DEFINE_KEY_OPS_AS_MACROS, for performance in that case.
+   The macro_* macros are private to this section of code.  */
+
+/* Add a pointer an an integer without complaint about a pointer going
+   out of range of the underlying array.  */
+
+#define macro_PNTR_ADD(p, i) ((p) + (i))
+
+static char * ATTRIBUTE_NO_SANITIZE_UNDEFINED ATTRIBUTE_UNUSED
+PNTR_ADD (char *p, EMACS_UINT i)
+{
+  return macro_PNTR_ADD (p, i);
+}
+
+#if DEFINE_KEY_OPS_AS_MACROS
+# define PNTR_ADD(p, i) macro_PNTR_ADD (p, i)
+#endif
+
+/* Extract the pointer hidden within O.  */
 
 #define macro_XPNTR(o)                                                 \
   ((void *) \
    (SYMBOLP (o)                                                               \
-    ? ((char *) lispsym                                                       \
-       - ((EMACS_UINT) Lisp_Symbol << (USE_LSB_TAG ? 0 : VALBITS))     \
-       + XLI (o))                                                     \
+    ? PNTR_ADD ((char *) lispsym,                                     \
+               (XLI (o)                                                \
+                - ((EMACS_UINT) Lisp_Symbol << (USE_LSB_TAG ? 0 : VALBITS)))) \
     : (char *) XLP (o) - (XLI (o) & ~VALMASK)))
 
 static ATTRIBUTE_UNUSED void *
diff --git a/src/conf_post.h b/src/conf_post.h
index 00e283d..bf2cfc4 100644
--- a/src/conf_post.h
+++ b/src/conf_post.h
@@ -67,6 +67,7 @@ typedef bool bool_bf;
 # define __has_attribute_externally_visible GNUC_PREREQ (4, 1, 0)
 # define __has_attribute_no_address_safety_analysis false
 # define __has_attribute_no_sanitize_address GNUC_PREREQ (4, 8, 0)
+# define __has_attribute_no_sanitize_undefined GNUC_PREREQ (4, 9, 0)
 #endif
 
 /* Simulate __has_builtin on compilers that lack it.  It is used only
@@ -338,6 +339,17 @@ extern int emacs_setenv_TZ (char const *);
 # define ATTRIBUTE_NO_SANITIZE_ADDRESS
 #endif
 
+/* Attribute of functions whose undefined behavior should not be sanitized.  */
+
+#if __has_attribute (no_sanitize_undefined)
+# define ATTRIBUTE_NO_SANITIZE_UNDEFINED __attribute__ 
((no_sanitize_undefined))
+#elif __has_attribute (no_sanitize)
+# define ATTRIBUTE_NO_SANITIZE_UNDEFINED \
+    __attribute__ ((no_sanitize ("undefined")))
+#else
+# define ATTRIBUTE_NO_SANITIZE_UNDEFINED
+#endif
+
 /* gcc -fsanitize=address does not work with vfork in Fedora 25 x86-64.
    For now, assume that this problem occurs on all platforms.  */
 #if ADDRESS_SANITIZER && !defined vfork
diff --git a/src/lisp.h b/src/lisp.h
index a18b64a..ee2e72d 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -900,7 +900,7 @@ INLINE bool
   return lisp_h_SYMBOLP (x);
 }
 
-INLINE struct Lisp_Symbol *
+INLINE struct Lisp_Symbol * ATTRIBUTE_NO_SANITIZE_UNDEFINED
 (XSYMBOL) (Lisp_Object a)
 {
 #if USE_LSB_TAG



reply via email to

[Prev in Thread] Current Thread [Next in Thread]