aboutsummaryrefslogtreecommitdiffstats
path: root/libtest
diff options
context:
space:
mode:
Diffstat (limited to 'libtest')
-rw-r--r--libtest/alloc.c124
-rw-r--r--libtest/alloc_have_custom.c14
-rw-r--r--libtest/common.h4
-rw-r--r--libtest/config.mk2
-rw-r--r--libtest/globals.c3
-rw-r--r--libtest/libtest.h19
-rw-r--r--libtest/mmap.c12
7 files changed, 173 insertions, 5 deletions
diff --git a/libtest/alloc.c b/libtest/alloc.c
index 7752091..f89ba94 100644
--- a/libtest/alloc.c
+++ b/libtest/alloc.c
@@ -427,6 +427,121 @@ void *
}
+int
+libtest_check_custom_mmap(void)
+{
+ static _Thread_local int in_check_custom_mmap = 0;
+ char *volatile test_dummy = NULL;
+
+ if (in_check_custom_mmap)
+ return libtest_mmap_is_custom;
+ in_check_custom_mmap = 1;
+
+ if (libtest_mmap_is_custom >= 0 &&
+ libtest_mremap_is_custom >= 0 &&
+ libtest_munmap_is_custom >= 0) {
+ if (libtest_mmap_is_custom & libtest_mremap_is_custom & libtest_munmap_is_custom)
+ goto custom;
+ goto real_deallocated;
+ }
+
+ test_dummy = mmap(NULL, 1u, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ assert(test_dummy != MAP_FAILED);
+ assert(test_dummy != NULL);
+ *test_dummy = 0;
+
+ if (libtest_mmap_is_custom == 0)
+ goto real;
+
+ if (libtest_mremap_is_custom < 0) {
+ test_dummy = mremap(test_dummy, 1u, 1u, MREMAP_MAYMOVE);
+ assert(test_dummy != MAP_FAILED);
+ assert(test_dummy != NULL);
+ }
+ if (libtest_mremap_is_custom == 0)
+ goto real;
+
+ if (libtest_munmap_is_custom < 0)
+ assert(!munmap(test_dummy, 1u));
+ if (libtest_munmap_is_custom == 0)
+ goto real_deallocated;
+
+custom:
+ in_check_custom_mmap = 0;
+ return 1;
+
+real:
+ assert(!munmap(test_dummy, 1u));
+real_deallocated:
+ in_check_custom_mmap = 0;
+ libtest_mmap_is_custom = 0;
+ libtest_mremap_is_custom = 0;
+ libtest_munmap_is_custom = 0;
+ return 0;
+}
+
+
+void *
+(mmap)(void *addr, size_t len, int prot, int flags, int fd, off_t off)
+{
+ /* TODO implement tracking */
+
+ libtest_mmap_is_custom = 1;
+ if (!libtest_check_custom_mmap())
+ goto real;
+
+ if (!libtest_malloc_internal_usage) {
+ if (libtest_malloc_fail_in && !--libtest_malloc_fail_in) {
+ errno = ENOMEM;
+ return MAP_FAILED;
+ }
+ }
+
+real:
+ return libtest_real_mmap(addr, len, prot, flags, fd, off);
+}
+
+
+int
+(munmap)(void *addr, size_t len)
+{
+ libtest_munmap_is_custom = 1;
+ if (!libtest_check_custom_mmap())
+ goto real;
+
+real:
+ return libtest_real_munmap(addr, len);
+}
+
+
+void *
+(mremap)(void *old_addr, size_t old_len, size_t new_len, int flags, ...)
+{
+ va_list args;
+ void *new_addr = NULL;
+
+ if (flags & MREMAP_FIXED) {
+ va_start(args, flags);
+ new_addr = va_arg(args, void *);
+ va_end(args);
+ }
+
+ libtest_mremap_is_custom = 1;
+ if (!libtest_check_custom_mmap())
+ goto real;
+
+ if (!libtest_malloc_internal_usage) {
+ if (libtest_malloc_fail_in && !--libtest_malloc_fail_in) {
+ errno = ENOMEM;
+ return MAP_FAILED;
+ }
+ }
+
+real:
+ return libtest_real_mremap(old_addr, old_len, new_len, flags, new_addr);
+}
+
#else
@@ -454,6 +569,9 @@ char *(strndup)(const char *s, size_t n);
wchar_t *(wcsdup)(const wchar_t *s);
wchar_t *(wcsndup)(const wchar_t *s, size_t n);
void *(memdup)(const void *s, size_t n);
+void *(mmap)(void *addr, size_t len, int prot, int flags, int fd, off_t off);
+int (munmap)(void *addr, size_t len);
+void *(mremap)(void *old_addr, size_t old_len, size_t new_len, int flags, ...);
static void
@@ -599,6 +717,8 @@ check(int use_free)
free(p);
else
free_aligned_sized(p, sizeof(void *), 11u);
+
+ /* TODO mmap, munmap, mremap */
}
@@ -696,6 +816,8 @@ check_successfuls(void)
assert(GET_MEMINFO(w)->requested_alloc_size == 3u * sizeof(wchar_t));
EXPECT(!memcmp(w, (wchar_t[]){11, 22, 0}, 3u * sizeof(wchar_t)));
free(w);
+
+ /* TODO mmap, munmap, mremap */
}
@@ -802,6 +924,8 @@ check_failures(void)
EXPECT(!memdup("x", 1u));
EXPECT(errno == ENOMEM);
EXPECT(!libtest_get_alloc_failure_in());
+
+ /* TODO mmap, munmap, mremap */
}
diff --git a/libtest/alloc_have_custom.c b/libtest/alloc_have_custom.c
index 9c213bb..0800e5e 100644
--- a/libtest/alloc_have_custom.c
+++ b/libtest/alloc_have_custom.c
@@ -26,6 +26,9 @@ char *(strndup)(const char *s, size_t n);
wchar_t *(wcsdup)(const wchar_t *s);
wchar_t *(wcsndup)(const wchar_t *s, size_t n);
void *(memdup)(const void *s, size_t n);
+void *(mmap)(void *addr, size_t len, int prot, int flags, int fd, off_t off);
+int (munmap)(void *addr, size_t len);
+void *(mremap)(void *old_addr, size_t old_len, size_t new_len, int flags, ...);
#if defined(__GNUC__)
# pragma GCC diagnostic pop
@@ -210,6 +213,16 @@ libtest_have_custom_free_aligned_sized(void)
}
+int
+libtest_have_custom_mmap(void)
+{
+ static int r = -1;
+ if (r < 0)
+ r = libtest_check_custom_mmap();
+ return r;
+}
+
+
#else
@@ -243,6 +256,7 @@ main(void)
CHECK(libtest_have_custom_wcsdup);
CHECK(libtest_have_custom_wcsndup);
CHECK(libtest_have_custom_memdup);
+ CHECK(libtest_have_custom_mmap);
return 0;
}
diff --git a/libtest/common.h b/libtest/common.h
index b78b69d..8d22b5b 100644
--- a/libtest/common.h
+++ b/libtest/common.h
@@ -147,6 +147,9 @@ extern volatile int libtest_strndup_is_custom;
extern volatile int libtest_wcsdup_is_custom;
extern volatile int libtest_wcsndup_is_custom;
extern volatile int libtest_memdup_is_custom;
+extern volatile int libtest_mmap_is_custom;
+extern volatile int libtest_munmap_is_custom;
+extern volatile int libtest_mremap_is_custom;
extern struct meminfo libtest_allocs_head;
extern struct meminfo libtest_allocs_tail;
@@ -174,6 +177,7 @@ libtest_base_pointer(void *ptr)
HIDDEN size_t libtest_get_pagesize(void);
HIDDEN void *libtest_alloc(struct meminfo *);
HIDDEN void libtest_free(void *, enum libtest_zero_check);
+HIDDEN int libtest_check_custom_mmap(void);
#ifdef WITH_BACKTRACE
HIDDEN void libtest_print_backtrace(FILE *, const char *prefix, const char *indent,
diff --git a/libtest/config.mk b/libtest/config.mk
index aa20790..6dff8a9 100644
--- a/libtest/config.mk
+++ b/libtest/config.mk
@@ -1,5 +1,5 @@
WITH_BACKTRACE = true
-IMPLEMENT_MMAP = false
+IMPLEMENT_MMAP = true
TEST_CONFIGFILE = config_backtraces=$(WITH_BACKTRACE).mk
include $(TEST_INCLUDE_PREFIX)$(TEST_CONFIGFILE)
diff --git a/libtest/globals.c b/libtest/globals.c
index 430f037..cf8164e 100644
--- a/libtest/globals.c
+++ b/libtest/globals.c
@@ -21,6 +21,9 @@ volatile int libtest_strndup_is_custom = -1;
volatile int libtest_wcsdup_is_custom = -1;
volatile int libtest_wcsndup_is_custom = -1;
volatile int libtest_memdup_is_custom = -1;
+volatile int libtest_mmap_is_custom = -1;
+volatile int libtest_munmap_is_custom = -1;
+volatile int libtest_mremap_is_custom = -1;
struct meminfo libtest_allocs_head;
struct meminfo libtest_allocs_tail;
diff --git a/libtest/libtest.h b/libtest/libtest.h
index 41d1a41..9fa7e56 100644
--- a/libtest/libtest.h
+++ b/libtest/libtest.h
@@ -324,6 +324,25 @@ int libtest_have_custom_free_sized(void);
*/
int libtest_have_custom_free_aligned_sized(void);
+/**
+ * Test whether mmap(3), munmap(3), and mremap(3) has
+ * been overridden, allowing allocations to be tracked,
+ * and memory allocation failures to be injected
+ *
+ * Tools like valgrind(1) prevent resource allocation
+ * functions from being overridden as they may override
+ * such functions themselves in order to detect leaks
+ * and invalid memory access patterns
+ *
+ * @return 1 if all three overridden,
+ * 0 if none have been overridden
+ *
+ * The case that only some of the three functions have
+ * been overriden, those will redirect to the real
+ * implementation and identify as non-overridden
+ */
+int libtest_have_custom_mmap(void);
+
/**
* Print a stack trace, to standard error, provided
diff --git a/libtest/mmap.c b/libtest/mmap.c
index 62ef06e..c3b3067 100644
--- a/libtest/mmap.c
+++ b/libtest/mmap.c
@@ -24,6 +24,7 @@ void *
libtest_real_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t off)
{
size_t pagesize = libtest_get_pagesize();
+ uintptr_t ret;
IF_MMAP2(assert(pagesize == 4096u));
if (off < 0 || off % (off_t)pagesize)
@@ -34,10 +35,11 @@ libtest_real_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t off
goto einval;
#ifdef SYS_mmap2
- return (void *)syscall(SYS_mmap2, addr, len, prot, flags, fd, off);
+ ret = (uintptr_t)syscall(SYS_mmap2, addr, len, prot, flags, fd, off);
#else
- return (void *)syscall(SYS_mmap, addr, len, prot, flags, fd, off);
+ ret = (uintptr_t)syscall(SYS_mmap, addr, len, prot, flags, fd, off);
#endif
+ return (void *)ret;
einval:
errno = EINVAL;
@@ -48,7 +50,7 @@ einval:
int
libtest_real_munmap(void *addr, size_t len)
{
- return syscall(SYS_munmap, addr, len);
+ return (int)syscall(SYS_munmap, addr, len);
}
@@ -57,6 +59,7 @@ libtest_real_mremap(void *old_addr, size_t old_len, size_t new_len, int flags, .
{
va_list args;
void *new_addr = NULL;
+ uintptr_t ret;
if (flags & MREMAP_FIXED) {
va_start(args, flags);
@@ -64,7 +67,8 @@ libtest_real_mremap(void *old_addr, size_t old_len, size_t new_len, int flags, .
va_end(args);
}
- return (void *)syscall(SYS_mremap, old_addr, old_len, new_len, flags, new_addr);
+ ret = (uintptr_t)syscall(SYS_mremap, old_addr, old_len, new_len, flags, new_addr);
+ return (void *)ret;
}