Port to C11 aligned_alloc, and fix some integer overflows.
authorPaul Eggert <eggert@cs.ucla.edu>
Thu, 7 Nov 2013 05:31:04 +0000 (21:31 -0800)
committerPaul Eggert <eggert@cs.ucla.edu>
Thu, 7 Nov 2013 05:31:04 +0000 (21:31 -0800)
* configure.ac (GMALLOC_OBJ): Initialize to empty if !system_malloc
and doug_lea_malloc.
(aligned_alloc): Test for existence if !GMALLOC_OBJ and not darwin.
(posix_memalign): Test for existence only if !GMALLOC_OBJ and
not darwin and !aligned_alloc.
* src/alloc.c (USE_ALIGNED_ALLOC): New symbol.
(USE_POSIX_MEMALIGN): Remove.  All uses replaced with USE_ALIGNED_ALLOC,
and use of posix_memalign replaced with aligned_alloc.
(aligned_alloc): New function, defined or declared as needed.
* src/conf_post.h (HAVE_POSIX_MEMALIGN) [DARWIN_OS]:
Don't undef; configure.ac now does this.
* src/gmalloc.c (aligned_alloc) [MSDOS]: New decl.
(calloc, aligned_alloc): Check for integer overflow.
(aligned_alloc): Rename from memalign.  All uses changed.
(memalign): New function, an alias for aligned_alloc.

ChangeLog
configure.ac
src/ChangeLog
src/alloc.c
src/conf_post.h
src/gmalloc.c

index 5ae941a..05ab15e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2013-11-07  Paul Eggert  <eggert@cs.ucla.edu>
+
+       Port to C11 aligned_alloc.
+       * configure.ac (GMALLOC_OBJ): Initialize to empty if !system_malloc
+       and doug_lea_malloc.
+       (aligned_alloc): Test for existence if !GMALLOC_OBJ and not darwin.
+       (posix_memalign): Test for existence only if !GMALLOC_OBJ and
+       not darwin and !aligned_alloc.
+
 2013-11-05  Glenn Morris  <rgm@gnu.org>
 
        * configure.ac (abs_srcdir) [MINGW32]: No point setting it here,
index a8fb34b..bd8278d 100644 (file)
@@ -1895,12 +1895,14 @@ case "$opsys" in
   darwin|sol2-10) system_malloc=yes ;;
 esac
 
+GMALLOC_OBJ=
 if test "${system_malloc}" = "yes"; then
-  AC_DEFINE(SYSTEM_MALLOC, 1, [Define to use system malloc.])
+  AC_DEFINE([SYSTEM_MALLOC], 1,
+    [Define to 1 to use the system memory allocator, even if it is not
+     Doug Lea style.])
   GNU_MALLOC=no
   GNU_MALLOC_reason="
     (The GNU allocators don't work with this system configuration.)"
-  GMALLOC_OBJ=
   VMLIMIT_OBJ=
 else
   test "$doug_lea_malloc" != "yes" && GMALLOC_OBJ=gmalloc.o
@@ -1929,7 +1931,8 @@ if test "$doug_lea_malloc" = "yes" ; then
       (Using Doug Lea's new malloc from the GNU C Library.)"
   fi
   AC_DEFINE(DOUG_LEA_MALLOC, 1,
-           [Define to 1 if you are using the GNU C Library.])
+    [Define to 1 if the system memory allocator is Doug Lea style,
+     with malloc hooks and malloc_set_state.])
 
   ## Use mmap directly for allocating larger buffers.
   ## FIXME this comes from src/s/{gnu,gnu-linux}.h:
@@ -3372,11 +3375,18 @@ getrlimit setrlimit shutdown getaddrinfo \
 strsignal setitimer \
 sendto recvfrom getsockname getpeername getifaddrs freeifaddrs \
 gai_strerror getline getdelim sync \
-difftime posix_memalign \
+difftime \
 getpwent endpwent getgrent endgrent \
 touchlock \
 cfmakeraw cfsetspeed copysign __executable_start log2)
 
+dnl No need to check for aligned_alloc and posix_memalign if using
+dnl gmalloc.o, as it supplies them.  Don't use these functions on
+dnl Darwin as they are incompatible with unexmacosx.c.
+if test -z "$GMALLOC_OBJ" && test "$opsys" != darwin; then
+  AC_CHECK_FUNCS([aligned_alloc posix_memalign], [break])
+fi
+
 ## Eric Backus <ericb@lsid.hp.com> says, HP-UX 9.x on HP 700 machines
 ## has a broken `rint' in some library versions including math library
 ## version number A.09.05.
index d008f67..2f774b8 100644 (file)
@@ -1,3 +1,17 @@
+2013-11-07  Paul Eggert  <eggert@cs.ucla.edu>
+
+       Port to C11 aligned_alloc, and fix some integer overflows.
+       * alloc.c (USE_ALIGNED_ALLOC): New symbol.
+       (USE_POSIX_MEMALIGN): Remove.  All uses replaced with USE_ALIGNED_ALLOC,
+       and use of posix_memalign replaced with aligned_alloc.
+       (aligned_alloc): New function, defined or declared as needed.
+       * conf_post.h (HAVE_POSIX_MEMALIGN) [DARWIN_OS]:
+       Don't undef; configure.ac now does this.
+       * gmalloc.c (aligned_alloc) [MSDOS]: New decl.
+       (calloc, aligned_alloc): Check for integer overflow.
+       (aligned_alloc): Rename from memalign.  All uses changed.
+       (memalign): New function, an alias for aligned_alloc.
+
 2013-11-06  Stefan Monnier  <monnier@iro.umontreal.ca>
 
        * xdisp.c (redisplay_internal): Fix typo in last change.
index 7054083..bc5ed6d 100644 (file)
@@ -920,8 +920,20 @@ lisp_free (void *block)
 /* The entry point is lisp_align_malloc which returns blocks of at most
    BLOCK_BYTES and guarantees they are aligned on a BLOCK_ALIGN boundary.  */
 
-#if defined (HAVE_POSIX_MEMALIGN) && defined (SYSTEM_MALLOC)
-#define USE_POSIX_MEMALIGN 1
+#if !defined SYSTEM_MALLOC && !defined DOUG_LEA_MALLOC
+# define USE_ALIGNED_ALLOC 1
+/* Defined in gmalloc.c.  */
+void *aligned_alloc (size_t, size_t);
+#elif defined HAVE_ALIGNED_ALLOC
+# define USE_ALIGNED_ALLOC 1
+#elif defined HAVE_POSIX_MEMALIGN
+# define USE_ALIGNED_ALLOC 1
+static void *
+aligned_alloc (size_t alignment, size_t size)
+{
+  void *p;
+  return posix_memalign (&p, alignment, size) == 0 ? p : 0;
+}
 #endif
 
 /* BLOCK_ALIGN has to be a power of 2.  */
@@ -931,7 +943,7 @@ lisp_free (void *block)
    malloc a chance to minimize the amount of memory wasted to alignment.
    It should be tuned to the particular malloc library used.
    On glibc-2.3.2, malloc never tries to align, so a padding of 0 is best.
-   posix_memalign on the other hand would ideally prefer a value of 4
+   aligned_alloc on the other hand would ideally prefer a value of 4
    because otherwise, there's 1020 bytes wasted between each ablocks.
    In Emacs, testing shows that those 1020 can most of the time be
    efficiently used by malloc to place other objects, so a value of 0 can
@@ -976,7 +988,7 @@ struct ablocks
   struct ablock blocks[ABLOCKS_SIZE];
 };
 
-/* Size of the block requested from malloc or posix_memalign.  */
+/* Size of the block requested from malloc or aligned_alloc.  */
 #define ABLOCKS_BYTES (sizeof (struct ablocks) - BLOCK_PADDING)
 
 #define ABLOCK_ABASE(block) \
@@ -988,7 +1000,7 @@ struct ablocks
 #define ABLOCKS_BUSY(abase) ((abase)->blocks[0].abase)
 
 /* Pointer to the (not necessarily aligned) malloc block.  */
-#ifdef USE_POSIX_MEMALIGN
+#ifdef USE_ALIGNED_ALLOC
 #define ABLOCKS_BASE(abase) (abase)
 #else
 #define ABLOCKS_BASE(abase) \
@@ -1027,13 +1039,8 @@ lisp_align_malloc (size_t nbytes, enum mem_type type)
       mallopt (M_MMAP_MAX, 0);
 #endif
 
-#ifdef USE_POSIX_MEMALIGN
-      {
-       int err = posix_memalign (&base, BLOCK_ALIGN, ABLOCKS_BYTES);
-       if (err)
-         base = NULL;
-       abase = base;
-      }
+#ifdef USE_ALIGNED_ALLOC
+      abase = base = aligned_alloc (BLOCK_ALIGN, ABLOCKS_BYTES);
 #else
       base = malloc (ABLOCKS_BYTES);
       abase = ALIGN (base, BLOCK_ALIGN);
index 7861058..2d967c0 100644 (file)
@@ -49,8 +49,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #define malloc unexec_malloc
 #define realloc unexec_realloc
 #define free unexec_free
-/* Don't use posix_memalign because it is not compatible with unexmacosx.c.  */
-#undef HAVE_POSIX_MEMALIGN
 #endif
 /* The following solves the problem that Emacs hangs when evaluating
    (make-comint "test0" "/nodir/nofile" nil "") when /nodir/nofile
index bc1d85a..fc728ee 100644 (file)
@@ -58,6 +58,7 @@ extern void free (void *ptr);
 
 /* Allocate SIZE bytes allocated to ALIGNMENT bytes.  */
 #ifdef MSDOS
+extern void *aligned_alloc (size_t, size_t);
 extern void *memalign (size_t, size_t);
 extern int posix_memalign (void **, size_t, size_t);
 #endif
@@ -143,11 +144,11 @@ struct list
 /* Free list headers for each fragment size.  */
 extern struct list _fraghead[];
 
-/* List of blocks allocated with `memalign' (or `valloc').  */
+/* List of blocks allocated with aligned_alloc and friends.  */
 struct alignlist
   {
     struct alignlist *next;
-    void *aligned;             /* The address that memaligned returned.  */
+    void *aligned;             /* The address that aligned_alloc returned.  */
     void *exact;               /* The address that malloc returned.  */
   };
 extern struct alignlist *_aligned_blocks;
@@ -977,7 +978,7 @@ License along with this library.  If not, see <http://www.gnu.org/licenses/>.
 /* Debugging hook for free.  */
 void (*__free_hook) (void *__ptr);
 
-/* List of blocks allocated by memalign.  */
+/* List of blocks allocated by aligned_alloc.  */
 struct alignlist *_aligned_blocks = NULL;
 
 /* Return memory to the heap.
@@ -1487,13 +1488,20 @@ License along with this library.  If not, see <http://www.gnu.org/licenses/>.
 /* Allocate an array of NMEMB elements each SIZE bytes long.
    The entire array is initialized to zeros.  */
 void *
-calloc (register size_t nmemb, register size_t size)
+calloc (size_t nmemb, size_t size)
 {
-  register void *result = malloc (nmemb * size);
+  void *result;
+  size_t bytes = nmemb * size;
 
-  if (result != NULL)
-    (void) memset (result, 0, nmemb * size);
+  if (size != 0 && bytes / size != nmemb)
+    {
+      errno = ENOMEM;
+      return NULL;
+    }
 
+  result = malloc (bytes);
+  if (result)
+    memset (result, 0, bytes);
   return result;
 }
 /* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
@@ -1559,7 +1567,7 @@ License along with this library.  If not, see <http://www.gnu.org/licenses/>.  *
 void *(*__memalign_hook) (size_t size, size_t alignment);
 
 void *
-memalign (size_t alignment, size_t size)
+aligned_alloc (size_t alignment, size_t size)
 {
   void *result;
   size_t adj, lastadj;
@@ -1570,6 +1578,11 @@ memalign (size_t alignment, size_t size)
 
   /* Allocate a block with enough extra space to pad the block with up to
      (ALIGNMENT - 1) bytes if necessary.  */
+  if (- size < alignment)
+    {
+      errno = ENOMEM;
+      return NULL;
+    }
   result = malloc (size + alignment - 1);
   if (result == NULL)
     return NULL;
@@ -1631,6 +1644,15 @@ memalign (size_t alignment, size_t size)
   return result;
 }
 
+/* An obsolete alias for aligned_alloc, for any old libraries that use
+   this alias.  */
+
+void *
+memalign (size_t alignment, size_t size)
+{
+  return aligned_alloc (alignment, size);
+}
+
 int
 posix_memalign (void **memptr, size_t alignment, size_t size)
 {
@@ -1641,7 +1663,7 @@ posix_memalign (void **memptr, size_t alignment, size_t size)
       || (alignment & (alignment - 1)) != 0)
     return EINVAL;
 
-  mem = memalign (alignment, size);
+  mem = aligned_alloc (alignment, size);
   if (mem == NULL)
     return ENOMEM;
 
@@ -1686,7 +1708,7 @@ valloc (size_t size)
   if (pagesize == 0)
     pagesize = getpagesize ();
 
-  return memalign (pagesize, size);
+  return aligned_alloc (pagesize, size);
 }
 
 #ifdef GC_MCHECK