/memcheck/tests/darwin/Makefile
/memcheck/tests/darwin/Makefile.in
/memcheck/tests/darwin/aio
+/memcheck/tests/darwin/aligned_alloc
/memcheck/tests/darwin/deep_badparam
/memcheck/tests/darwin/env
/memcheck/tests/darwin/ioctl-tiocsbrk
/memcheck/tests/linux/*.stdout.diff
/memcheck/tests/linux/*.stdout.out
/memcheck/tests/linux/.deps
+/memcheck/tests/linux/aligned_alloc
/memcheck/tests/linux/brk
/memcheck/tests/linux/capget
/memcheck/tests/linux/check_preadv2_pwritev2
/memcheck/tests/solaris/.deps
/memcheck/tests/solaris/Makefile
/memcheck/tests/solaris/Makefile.in
+/memcheck/tests/solaris/aligned_alloc
/memcheck/tests/solaris/brk
/memcheck/tests/solaris/context_stack_die
/memcheck/tests/solaris/door_data
* alignment supported by the implementation the function shall
* fail by returning a null pointer".
*
- * Linux glibc, the man page claims that the alignment must be
+ * Linux glibc. The man page claims that the alignment must be
* a power of two and that size should be a multiple of alignment.
* However the only case that returns EINVAL (glibc 2.34)
* is if the alignement is > SIZE_MAX / 2 + 1
* Also this is just a weak alias for memalign so this wrapper
- * has no effect on Linux.
+ * has no effect on Linux glibc.
*
- * Linux musl, the alignment must be a power of 2 else
+ * Linux musl. The alignment must be a power of 2 else
* returns einval. The value of the alignment is clamped
* to a minumum of UNIT (16).
*
* The code checks that the alignment is a power of
* 2 and not less than the minumum alignment (1)
*
- * Solaris: doesn't seem to exist on 11.3
- * Illumos: invalid if the size is 0, the alignment is 0, the
+ * Solaris. Doesn't seem to exist on 11.3
+ * Illumos. Invalid if the size is 0, the alignment is 0, the
* alignment is not a multiple of 4 (no power of 2
* requirement even though the manpage claims is) or the
* alignment is greater than MAX_ALIGN (whatever that is).
* Wrapper function that just calls memalign
*
+ * Darwin. Does enforce size bing an integer multiple of
+ * alignment.
+ *
*/
-#if defined (VGO_linux)
+#if defined(VGO_darwin)
+#define VG_ALIGNED_ALLOC_SIZE_MULTIPLE_ALIGN 1
+#else
+#define VG_ALIGNED_ALLOC_SIZE_MULTIPLE_ALIGN 0
+#endif
+
+#if defined (VGO_linux) && !defined(MUSL_LIBC)
#define ALIGNED_ALLOC(soname, fnname) \
\
{ \
void *mem; \
\
- TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(alignment); \
TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(size); \
MALLOC_TRACE("aligned_alloc(al %llu, size %llu)", \
(ULong)alignment, (ULong)size ); \
MALLOC_TRACE("aligned_alloc(al %llu, size %llu)", \
(ULong)alignment, (ULong)size ); \
if (alignment == 0 \
- || size % alignment != 0 \
+ || (VG_ALIGNED_ALLOC_SIZE_MULTIPLE_ALIGN && (size % alignment != 0)) \
|| (alignment & (alignment - 1)) != 0) { \
SET_ERRNO_EINVAL; \
return 0; \
} \
\
+ /* Round up to minimum alignment if necessary. */ \
+ if (alignment < VG_MIN_MALLOC_SZB) \
+ alignment = VG_MIN_MALLOC_SZB; \
+ \
mem = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, \
alignment, size ); \
\
EXTRA_DIST = \
aio.stderr.exp aio.vgtest \
+ aligned_alloc.stderr.exp aligned_alloc.vgtest \
deep_badparam.stderr.exp deep_badparam.stdout.exp deep_badparam.vgtest \
env.stderr.exp env.vgtest \
ioctl-tiocsbrk.stderr.exp ioctl-tiocsbrk.vgtest \
check_PROGRAMS = \
aio \
+ aligned_alloc \
deep_badparam \
env \
ioctl-tiocsbrk \
--- /dev/null
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+
+int main(void)
+{
+ char* p = NULL;
+ int res;
+
+ // zero size
+ p = aligned_alloc(0, 8);
+ assert(p == NULL && errno == EINVAL);
+ errno = 0;
+ // non multiple of alignment fails on Darwin
+ p = aligned_alloc(8, 25);
+ assert(p == NULL && errno == EINVAL);
+ errno = 0;
+ // align not power of 2
+ p = aligned_alloc(40, 160);
+ assert(p == NULL && errno == EINVAL);
+ errno = 0;
+ // the test below causes a segfault with musl 1.2.2
+ // apparently it has been
+
+ // too big
+ if (sizeof(size_t) == 8)
+ {
+ p = aligned_alloc(16, 1UL<<48);
+ }
+ else
+ {
+ p = NULL;
+ errno = ENOMEM;
+ }
+
+ assert(p == NULL && errno == ENOMEM);
+
+}
+
+
--- /dev/null
+prog: aligned_alloc
+vgopts: -q
assert(p == NULL && errno == EINVAL);
errno = 0;
// non multiple of alignment passes on FreeBSD
- //p = aligned_alloc(8, 25);
- //assert(p == NULL && errno == EINVAL);
+ p = aligned_alloc(8, 25);
+ assert(p && ((size_t)p % 8U == 0U));
+ free(p);
//errno = 0;
// align not power of 2
p = aligned_alloc(40, 160);
HEAP SUMMARY:
in use at exit: 0 bytes in 0 blocks
- total heap usage: 0 allocs, 0 frees, 0 bytes allocated
+ total heap usage: 1 allocs, 1 frees, 25 bytes allocated
For a detailed leak analysis, rerun with: --leak-check=full
dist_noinst_SCRIPTS = filter_stderr
EXTRA_DIST = \
+ aligned_alloc.c aligned_alloc.vgtest aligned_alloc.stderr.exp \
brk.stderr.exp brk.vgtest \
capget.vgtest capget.stderr.exp capget.stderr.exp2 capget.stderr.exp3 \
debuginfod-check.stderr.exp debuginfod-check.vgtest.in \
--- /dev/null
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+#include "../../../config.h"
+
+int main(void)
+{
+#if defined(MUSL_LIBC)
+ char* p = NULL;
+ int res;
+
+ // zero size
+ p = aligned_alloc(0, 8);
+ assert(p == NULL && errno == EINVAL);
+ errno = 0;
+ // non multiple of alignment passes on FreeBSD
+ p = aligned_alloc(8, 25);
+ assert(p && ((size_t)p % 8U == 0U));
+ free(p);
+ //errno = 0;
+ // align not power of 2
+ p = aligned_alloc(40, 160);
+ assert(p == NULL && errno == EINVAL);
+ errno = 0;
+ // the test below causes a segfault with musl 1.2.2
+ // apparently it has been fixed in 1.2.3
+#if 0
+ // too big
+ if (sizeof(size_t) == 8)
+ {
+ p = aligned_alloc(16, 1UL<<48);
+ }
+ else
+ {
+ p = NULL;
+ errno = ENOMEM;
+ }
+#endif
+ assert(p == NULL && errno == ENOMEM);
+#endif
+}
+
+
--- /dev/null
+prog: aligned_alloc
noinst_HEADERS = scalar.h
EXTRA_DIST = \
+ aligned_alloc.stderr.exp aligned_alloc.vgtest \
brk.stderr.exp brk.stdout.exp brk.vgtest \
context_stack_die.stderr.exp context_stack_die.stdout.exp context_stack_die.vgtest \
door_data.stderr.exp door_data.stdout.exp door_data.vgtest \
memalign.vgtest memalign.stderr.exp
check_PROGRAMS = \
+ aligned_alloc \
brk \
context_stack_die \
door_data \
--- /dev/null
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+
+int main(void)
+{
+ char* p = NULL;
+ int res;
+
+ // zero size
+ p = aligned_alloc(0, 8);
+ assert(p == NULL && errno == EINVAL);
+ errno = 0;
+ // non multiple of alignment passes on Solaris
+ p = aligned_alloc(8, 25);
+ assert(p && ((size_t)p % 8U == 0U));
+ free(p);
+ //errno = 0;
+ // align not power of 2
+ p = aligned_alloc(40, 160);
+ assert(p == NULL && errno == EINVAL);
+ errno = 0;
+ // the test below causes a segfault with musl 1.2.2
+ // apparently it has been
+
+ // too big
+ if (sizeof(size_t) == 8)
+ {
+ p = aligned_alloc(16, 1UL<<48);
+ }
+ else
+ {
+ p = NULL;
+ errno = ENOMEM;
+ }
+
+ assert(p == NULL && errno == ENOMEM);
+
+}
+
+
--- /dev/null
+prog: aligned_alloc