diff options
| author | Paul Eggert | 2013-11-06 21:31:04 -0800 |
|---|---|---|
| committer | Paul Eggert | 2013-11-06 21:31:04 -0800 |
| commit | aea07e2c6e54733804d0be54e97d44fcb3df63dd (patch) | |
| tree | 1f84e37d28aa136603322428a81c2f0046bf9844 /src | |
| parent | e6e4db3cac4630fc83e4bc520f99823572c3e592 (diff) | |
| download | emacs-aea07e2c6e54733804d0be54e97d44fcb3df63dd.tar.gz emacs-aea07e2c6e54733804d0be54e97d44fcb3df63dd.zip | |
Port to C11 aligned_alloc, and fix some integer overflows.
* 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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 14 | ||||
| -rw-r--r-- | src/alloc.c | 31 | ||||
| -rw-r--r-- | src/conf_post.h | 2 | ||||
| -rw-r--r-- | src/gmalloc.c | 42 |
4 files changed, 65 insertions, 24 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index d008f670867..2f774b87b13 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,17 @@ | |||
| 1 | 2013-11-07 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | Port to C11 aligned_alloc, and fix some integer overflows. | ||
| 4 | * alloc.c (USE_ALIGNED_ALLOC): New symbol. | ||
| 5 | (USE_POSIX_MEMALIGN): Remove. All uses replaced with USE_ALIGNED_ALLOC, | ||
| 6 | and use of posix_memalign replaced with aligned_alloc. | ||
| 7 | (aligned_alloc): New function, defined or declared as needed. | ||
| 8 | * conf_post.h (HAVE_POSIX_MEMALIGN) [DARWIN_OS]: | ||
| 9 | Don't undef; configure.ac now does this. | ||
| 10 | * gmalloc.c (aligned_alloc) [MSDOS]: New decl. | ||
| 11 | (calloc, aligned_alloc): Check for integer overflow. | ||
| 12 | (aligned_alloc): Rename from memalign. All uses changed. | ||
| 13 | (memalign): New function, an alias for aligned_alloc. | ||
| 14 | |||
| 1 | 2013-11-06 Stefan Monnier <monnier@iro.umontreal.ca> | 15 | 2013-11-06 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 16 | ||
| 3 | * xdisp.c (redisplay_internal): Fix typo in last change. | 17 | * xdisp.c (redisplay_internal): Fix typo in last change. |
diff --git a/src/alloc.c b/src/alloc.c index 7054083acba..bc5ed6d94bb 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -920,8 +920,20 @@ lisp_free (void *block) | |||
| 920 | /* The entry point is lisp_align_malloc which returns blocks of at most | 920 | /* The entry point is lisp_align_malloc which returns blocks of at most |
| 921 | BLOCK_BYTES and guarantees they are aligned on a BLOCK_ALIGN boundary. */ | 921 | BLOCK_BYTES and guarantees they are aligned on a BLOCK_ALIGN boundary. */ |
| 922 | 922 | ||
| 923 | #if defined (HAVE_POSIX_MEMALIGN) && defined (SYSTEM_MALLOC) | 923 | #if !defined SYSTEM_MALLOC && !defined DOUG_LEA_MALLOC |
| 924 | #define USE_POSIX_MEMALIGN 1 | 924 | # define USE_ALIGNED_ALLOC 1 |
| 925 | /* Defined in gmalloc.c. */ | ||
| 926 | void *aligned_alloc (size_t, size_t); | ||
| 927 | #elif defined HAVE_ALIGNED_ALLOC | ||
| 928 | # define USE_ALIGNED_ALLOC 1 | ||
| 929 | #elif defined HAVE_POSIX_MEMALIGN | ||
| 930 | # define USE_ALIGNED_ALLOC 1 | ||
| 931 | static void * | ||
| 932 | aligned_alloc (size_t alignment, size_t size) | ||
| 933 | { | ||
| 934 | void *p; | ||
| 935 | return posix_memalign (&p, alignment, size) == 0 ? p : 0; | ||
| 936 | } | ||
| 925 | #endif | 937 | #endif |
| 926 | 938 | ||
| 927 | /* BLOCK_ALIGN has to be a power of 2. */ | 939 | /* BLOCK_ALIGN has to be a power of 2. */ |
| @@ -931,7 +943,7 @@ lisp_free (void *block) | |||
| 931 | malloc a chance to minimize the amount of memory wasted to alignment. | 943 | malloc a chance to minimize the amount of memory wasted to alignment. |
| 932 | It should be tuned to the particular malloc library used. | 944 | It should be tuned to the particular malloc library used. |
| 933 | On glibc-2.3.2, malloc never tries to align, so a padding of 0 is best. | 945 | On glibc-2.3.2, malloc never tries to align, so a padding of 0 is best. |
| 934 | posix_memalign on the other hand would ideally prefer a value of 4 | 946 | aligned_alloc on the other hand would ideally prefer a value of 4 |
| 935 | because otherwise, there's 1020 bytes wasted between each ablocks. | 947 | because otherwise, there's 1020 bytes wasted between each ablocks. |
| 936 | In Emacs, testing shows that those 1020 can most of the time be | 948 | In Emacs, testing shows that those 1020 can most of the time be |
| 937 | efficiently used by malloc to place other objects, so a value of 0 can | 949 | efficiently used by malloc to place other objects, so a value of 0 can |
| @@ -976,7 +988,7 @@ struct ablocks | |||
| 976 | struct ablock blocks[ABLOCKS_SIZE]; | 988 | struct ablock blocks[ABLOCKS_SIZE]; |
| 977 | }; | 989 | }; |
| 978 | 990 | ||
| 979 | /* Size of the block requested from malloc or posix_memalign. */ | 991 | /* Size of the block requested from malloc or aligned_alloc. */ |
| 980 | #define ABLOCKS_BYTES (sizeof (struct ablocks) - BLOCK_PADDING) | 992 | #define ABLOCKS_BYTES (sizeof (struct ablocks) - BLOCK_PADDING) |
| 981 | 993 | ||
| 982 | #define ABLOCK_ABASE(block) \ | 994 | #define ABLOCK_ABASE(block) \ |
| @@ -988,7 +1000,7 @@ struct ablocks | |||
| 988 | #define ABLOCKS_BUSY(abase) ((abase)->blocks[0].abase) | 1000 | #define ABLOCKS_BUSY(abase) ((abase)->blocks[0].abase) |
| 989 | 1001 | ||
| 990 | /* Pointer to the (not necessarily aligned) malloc block. */ | 1002 | /* Pointer to the (not necessarily aligned) malloc block. */ |
| 991 | #ifdef USE_POSIX_MEMALIGN | 1003 | #ifdef USE_ALIGNED_ALLOC |
| 992 | #define ABLOCKS_BASE(abase) (abase) | 1004 | #define ABLOCKS_BASE(abase) (abase) |
| 993 | #else | 1005 | #else |
| 994 | #define ABLOCKS_BASE(abase) \ | 1006 | #define ABLOCKS_BASE(abase) \ |
| @@ -1027,13 +1039,8 @@ lisp_align_malloc (size_t nbytes, enum mem_type type) | |||
| 1027 | mallopt (M_MMAP_MAX, 0); | 1039 | mallopt (M_MMAP_MAX, 0); |
| 1028 | #endif | 1040 | #endif |
| 1029 | 1041 | ||
| 1030 | #ifdef USE_POSIX_MEMALIGN | 1042 | #ifdef USE_ALIGNED_ALLOC |
| 1031 | { | 1043 | abase = base = aligned_alloc (BLOCK_ALIGN, ABLOCKS_BYTES); |
| 1032 | int err = posix_memalign (&base, BLOCK_ALIGN, ABLOCKS_BYTES); | ||
| 1033 | if (err) | ||
| 1034 | base = NULL; | ||
| 1035 | abase = base; | ||
| 1036 | } | ||
| 1037 | #else | 1044 | #else |
| 1038 | base = malloc (ABLOCKS_BYTES); | 1045 | base = malloc (ABLOCKS_BYTES); |
| 1039 | abase = ALIGN (base, BLOCK_ALIGN); | 1046 | abase = ALIGN (base, BLOCK_ALIGN); |
diff --git a/src/conf_post.h b/src/conf_post.h index 786105864f2..2d967c0fefc 100644 --- a/src/conf_post.h +++ b/src/conf_post.h | |||
| @@ -49,8 +49,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 49 | #define malloc unexec_malloc | 49 | #define malloc unexec_malloc |
| 50 | #define realloc unexec_realloc | 50 | #define realloc unexec_realloc |
| 51 | #define free unexec_free | 51 | #define free unexec_free |
| 52 | /* Don't use posix_memalign because it is not compatible with unexmacosx.c. */ | ||
| 53 | #undef HAVE_POSIX_MEMALIGN | ||
| 54 | #endif | 52 | #endif |
| 55 | /* The following solves the problem that Emacs hangs when evaluating | 53 | /* The following solves the problem that Emacs hangs when evaluating |
| 56 | (make-comint "test0" "/nodir/nofile" nil "") when /nodir/nofile | 54 | (make-comint "test0" "/nodir/nofile" nil "") when /nodir/nofile |
diff --git a/src/gmalloc.c b/src/gmalloc.c index bc1d85ac5fb..fc728eeea7e 100644 --- a/src/gmalloc.c +++ b/src/gmalloc.c | |||
| @@ -58,6 +58,7 @@ extern void free (void *ptr); | |||
| 58 | 58 | ||
| 59 | /* Allocate SIZE bytes allocated to ALIGNMENT bytes. */ | 59 | /* Allocate SIZE bytes allocated to ALIGNMENT bytes. */ |
| 60 | #ifdef MSDOS | 60 | #ifdef MSDOS |
| 61 | extern void *aligned_alloc (size_t, size_t); | ||
| 61 | extern void *memalign (size_t, size_t); | 62 | extern void *memalign (size_t, size_t); |
| 62 | extern int posix_memalign (void **, size_t, size_t); | 63 | extern int posix_memalign (void **, size_t, size_t); |
| 63 | #endif | 64 | #endif |
| @@ -143,11 +144,11 @@ struct list | |||
| 143 | /* Free list headers for each fragment size. */ | 144 | /* Free list headers for each fragment size. */ |
| 144 | extern struct list _fraghead[]; | 145 | extern struct list _fraghead[]; |
| 145 | 146 | ||
| 146 | /* List of blocks allocated with `memalign' (or `valloc'). */ | 147 | /* List of blocks allocated with aligned_alloc and friends. */ |
| 147 | struct alignlist | 148 | struct alignlist |
| 148 | { | 149 | { |
| 149 | struct alignlist *next; | 150 | struct alignlist *next; |
| 150 | void *aligned; /* The address that memaligned returned. */ | 151 | void *aligned; /* The address that aligned_alloc returned. */ |
| 151 | void *exact; /* The address that malloc returned. */ | 152 | void *exact; /* The address that malloc returned. */ |
| 152 | }; | 153 | }; |
| 153 | extern struct alignlist *_aligned_blocks; | 154 | extern struct alignlist *_aligned_blocks; |
| @@ -977,7 +978,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>. | |||
| 977 | /* Debugging hook for free. */ | 978 | /* Debugging hook for free. */ |
| 978 | void (*__free_hook) (void *__ptr); | 979 | void (*__free_hook) (void *__ptr); |
| 979 | 980 | ||
| 980 | /* List of blocks allocated by memalign. */ | 981 | /* List of blocks allocated by aligned_alloc. */ |
| 981 | struct alignlist *_aligned_blocks = NULL; | 982 | struct alignlist *_aligned_blocks = NULL; |
| 982 | 983 | ||
| 983 | /* Return memory to the heap. | 984 | /* Return memory to the heap. |
| @@ -1487,13 +1488,20 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>. | |||
| 1487 | /* Allocate an array of NMEMB elements each SIZE bytes long. | 1488 | /* Allocate an array of NMEMB elements each SIZE bytes long. |
| 1488 | The entire array is initialized to zeros. */ | 1489 | The entire array is initialized to zeros. */ |
| 1489 | void * | 1490 | void * |
| 1490 | calloc (register size_t nmemb, register size_t size) | 1491 | calloc (size_t nmemb, size_t size) |
| 1491 | { | 1492 | { |
| 1492 | register void *result = malloc (nmemb * size); | 1493 | void *result; |
| 1494 | size_t bytes = nmemb * size; | ||
| 1493 | 1495 | ||
| 1494 | if (result != NULL) | 1496 | if (size != 0 && bytes / size != nmemb) |
| 1495 | (void) memset (result, 0, nmemb * size); | 1497 | { |
| 1498 | errno = ENOMEM; | ||
| 1499 | return NULL; | ||
| 1500 | } | ||
| 1496 | 1501 | ||
| 1502 | result = malloc (bytes); | ||
| 1503 | if (result) | ||
| 1504 | memset (result, 0, bytes); | ||
| 1497 | return result; | 1505 | return result; |
| 1498 | } | 1506 | } |
| 1499 | /* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. | 1507 | /* 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/>. * | |||
| 1559 | void *(*__memalign_hook) (size_t size, size_t alignment); | 1567 | void *(*__memalign_hook) (size_t size, size_t alignment); |
| 1560 | 1568 | ||
| 1561 | void * | 1569 | void * |
| 1562 | memalign (size_t alignment, size_t size) | 1570 | aligned_alloc (size_t alignment, size_t size) |
| 1563 | { | 1571 | { |
| 1564 | void *result; | 1572 | void *result; |
| 1565 | size_t adj, lastadj; | 1573 | size_t adj, lastadj; |
| @@ -1570,6 +1578,11 @@ memalign (size_t alignment, size_t size) | |||
| 1570 | 1578 | ||
| 1571 | /* Allocate a block with enough extra space to pad the block with up to | 1579 | /* Allocate a block with enough extra space to pad the block with up to |
| 1572 | (ALIGNMENT - 1) bytes if necessary. */ | 1580 | (ALIGNMENT - 1) bytes if necessary. */ |
| 1581 | if (- size < alignment) | ||
| 1582 | { | ||
| 1583 | errno = ENOMEM; | ||
| 1584 | return NULL; | ||
| 1585 | } | ||
| 1573 | result = malloc (size + alignment - 1); | 1586 | result = malloc (size + alignment - 1); |
| 1574 | if (result == NULL) | 1587 | if (result == NULL) |
| 1575 | return NULL; | 1588 | return NULL; |
| @@ -1631,6 +1644,15 @@ memalign (size_t alignment, size_t size) | |||
| 1631 | return result; | 1644 | return result; |
| 1632 | } | 1645 | } |
| 1633 | 1646 | ||
| 1647 | /* An obsolete alias for aligned_alloc, for any old libraries that use | ||
| 1648 | this alias. */ | ||
| 1649 | |||
| 1650 | void * | ||
| 1651 | memalign (size_t alignment, size_t size) | ||
| 1652 | { | ||
| 1653 | return aligned_alloc (alignment, size); | ||
| 1654 | } | ||
| 1655 | |||
| 1634 | int | 1656 | int |
| 1635 | posix_memalign (void **memptr, size_t alignment, size_t size) | 1657 | posix_memalign (void **memptr, size_t alignment, size_t size) |
| 1636 | { | 1658 | { |
| @@ -1641,7 +1663,7 @@ posix_memalign (void **memptr, size_t alignment, size_t size) | |||
| 1641 | || (alignment & (alignment - 1)) != 0) | 1663 | || (alignment & (alignment - 1)) != 0) |
| 1642 | return EINVAL; | 1664 | return EINVAL; |
| 1643 | 1665 | ||
| 1644 | mem = memalign (alignment, size); | 1666 | mem = aligned_alloc (alignment, size); |
| 1645 | if (mem == NULL) | 1667 | if (mem == NULL) |
| 1646 | return ENOMEM; | 1668 | return ENOMEM; |
| 1647 | 1669 | ||
| @@ -1686,7 +1708,7 @@ valloc (size_t size) | |||
| 1686 | if (pagesize == 0) | 1708 | if (pagesize == 0) |
| 1687 | pagesize = getpagesize (); | 1709 | pagesize = getpagesize (); |
| 1688 | 1710 | ||
| 1689 | return memalign (pagesize, size); | 1711 | return aligned_alloc (pagesize, size); |
| 1690 | } | 1712 | } |
| 1691 | 1713 | ||
| 1692 | #ifdef GC_MCHECK | 1714 | #ifdef GC_MCHECK |