Commit c47f71551714006ee1aba26c49fdd1f187251da2

Patrick Steinhardt 2018-03-14T10:34:59

util: extract `stdalloc` allocator into its own module Right now, the standard allocator is being declared as part of the "util.h" header as a set of inline functions. As with the crtdbg allocator functions, these inline functions make it hard to convert to function pointers for our allocators. Create a new "stdalloc" module containing our standard allocations functions to split these out. Convert the existing allocators to macros which make use of the stdalloc functions.

diff --git a/src/stdalloc.c b/src/stdalloc.c
new file mode 100644
index 0000000..1735be7
--- /dev/null
+++ b/src/stdalloc.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "stdalloc.h"
+
+void *git__stdalloc__malloc(size_t len)
+{
+	void *ptr = malloc(len);
+	if (!ptr) giterr_set_oom();
+	return ptr;
+}
+
+void *git__stdalloc__calloc(size_t nelem, size_t elsize)
+{
+	void *ptr = calloc(nelem, elsize);
+	if (!ptr) giterr_set_oom();
+	return ptr;
+}
+
+char *git__stdalloc__strdup(const char *str)
+{
+	char *ptr = strdup(str);
+	if (!ptr) giterr_set_oom();
+	return ptr;
+}
+
+char *git__stdalloc__strndup(const char *str, size_t n)
+{
+	size_t length = 0, alloclength;
+	char *ptr;
+
+	length = p_strnlen(str, n);
+
+	if (GIT_ADD_SIZET_OVERFLOW(&alloclength, length, 1) ||
+		!(ptr = git__stdalloc__malloc(alloclength)))
+		return NULL;
+
+	if (length)
+		memcpy(ptr, str, length);
+
+	ptr[length] = '\0';
+
+	return ptr;
+}
+
+char *git__stdalloc__substrdup(const char *start, size_t n)
+{
+	char *ptr;
+	size_t alloclen;
+
+	if (GIT_ADD_SIZET_OVERFLOW(&alloclen, n, 1) ||
+		!(ptr = git__stdalloc__malloc(alloclen)))
+		return NULL;
+
+	memcpy(ptr, start, n);
+	ptr[n] = '\0';
+	return ptr;
+}
+
+void *git__stdalloc__realloc(void *ptr, size_t size)
+{
+	void *new_ptr = realloc(ptr, size);
+	if (!new_ptr) giterr_set_oom();
+	return new_ptr;
+}
+
+void *git__stdalloc__reallocarray(void *ptr, size_t nelem, size_t elsize)
+{
+	size_t newsize;
+	return GIT_MULTIPLY_SIZET_OVERFLOW(&newsize, nelem, elsize) ?
+		NULL : realloc(ptr, newsize);
+}
+
+void *git__stdalloc__mallocarray(size_t nelem, size_t elsize)
+{
+	return git__stdalloc__reallocarray(NULL, nelem, elsize);
+}
+
+void git__stdalloc__free(void *ptr)
+{
+	free(ptr);
+}
diff --git a/src/stdalloc.h b/src/stdalloc.h
new file mode 100644
index 0000000..17c2072
--- /dev/null
+++ b/src/stdalloc.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#ifndef INCLUDE_stdalloc_h__
+#define INCLUDE_stdalloc_h__
+
+#include "common.h"
+
+/*
+ * Custom memory allocation wrappers
+ * that set error code and error message
+ * on allocation failure
+ */
+void *git__stdalloc__malloc(size_t len);
+void *git__stdalloc__calloc(size_t nelem, size_t elsize);
+char *git__stdalloc__strdup(const char *str);
+char *git__stdalloc__strndup(const char *str, size_t n);
+/* NOTE: This doesn't do null or '\0' checking.  Watch those boundaries! */
+char *git__stdalloc__substrdup(const char *start, size_t n);
+void *git__stdalloc__realloc(void *ptr, size_t size);
+
+/**
+ * Similar to `git__stdalloc__realloc`, except that it is suitable for reallocing an
+ * array to a new number of elements of `nelem`, each of size `elsize`.
+ * The total size calculation is checked for overflow.
+ */
+void *git__stdalloc__reallocarray(void *ptr, size_t nelem, size_t elsize);
+
+/**
+ * Similar to `git__stdalloc__calloc`, except that it does not zero memory.
+ */
+void *git__stdalloc__mallocarray(size_t nelem, size_t elsize);
+
+void git__stdalloc__free(void *ptr);
+
+#endif
diff --git a/src/util.h b/src/util.h
index 5b1354c..1d60223 100644
--- a/src/util.h
+++ b/src/util.h
@@ -83,97 +83,17 @@
 
 #else
 
-/*
- * Custom memory allocation wrappers
- * that set error code and error message
- * on allocation failure
- */
-GIT_INLINE(void *) git__malloc(size_t len)
-{
-	void *ptr = malloc(len);
-	if (!ptr) giterr_set_oom();
-	return ptr;
-}
-
-GIT_INLINE(void *) git__calloc(size_t nelem, size_t elsize)
-{
-	void *ptr = calloc(nelem, elsize);
-	if (!ptr) giterr_set_oom();
-	return ptr;
-}
-
-GIT_INLINE(char *) git__strdup(const char *str)
-{
-	char *ptr = strdup(str);
-	if (!ptr) giterr_set_oom();
-	return ptr;
-}
-
-GIT_INLINE(char *) git__strndup(const char *str, size_t n)
-{
-	size_t length = 0, alloclength;
-	char *ptr;
-
-	length = p_strnlen(str, n);
-
-	if (GIT_ADD_SIZET_OVERFLOW(&alloclength, length, 1) ||
-		!(ptr = git__malloc(alloclength)))
-		return NULL;
-
-	if (length)
-		memcpy(ptr, str, length);
-
-	ptr[length] = '\0';
-
-	return ptr;
-}
-
-/* NOTE: This doesn't do null or '\0' checking.  Watch those boundaries! */
-GIT_INLINE(char *) git__substrdup(const char *start, size_t n)
-{
-	char *ptr;
-	size_t alloclen;
-
-	if (GIT_ADD_SIZET_OVERFLOW(&alloclen, n, 1) ||
-		!(ptr = git__malloc(alloclen)))
-		return NULL;
-
-	memcpy(ptr, start, n);
-	ptr[n] = '\0';
-	return ptr;
-}
-
-GIT_INLINE(void *) git__realloc(void *ptr, size_t size)
-{
-	void *new_ptr = realloc(ptr, size);
-	if (!new_ptr) giterr_set_oom();
-	return new_ptr;
-}
-
-/**
- * Similar to `git__realloc`, except that it is suitable for reallocing an
- * array to a new number of elements of `nelem`, each of size `elsize`.
- * The total size calculation is checked for overflow.
- */
-GIT_INLINE(void *) git__reallocarray(void *ptr, size_t nelem, size_t elsize)
-{
-	size_t newsize;
-	return GIT_MULTIPLY_SIZET_OVERFLOW(&newsize, nelem, elsize) ?
-		NULL : realloc(ptr, newsize);
-}
-
-/**
- * Similar to `git__calloc`, except that it does not zero memory.
- */
-GIT_INLINE(void *) git__mallocarray(size_t nelem, size_t elsize)
-{
-	return git__reallocarray(NULL, nelem, elsize);
-}
-
-GIT_INLINE(void) git__free(void *ptr)
-{
-	free(ptr);
-}
+#include "stdalloc.h"
+
+#define git__malloc(len)                      git__stdalloc__malloc(len)
+#define git__calloc(nelem, elsize)            git__stdalloc__calloc(nelem, elsize)
+#define git__strdup(str)                      git__stdalloc__strdup(str)
+#define git__strndup(str, n)                  git__stdalloc__strndup(str, n)
+#define git__substrdup(str, n)                git__stdalloc__substrdup(str, n)
+#define git__realloc(ptr, size)               git__stdalloc__realloc(ptr, size)
+#define git__reallocarray(ptr, nelem, elsize) git__stdalloc__reallocarray(ptr, nelem, elsize)
+#define git__mallocarray(nelem, elsize)       git__stdalloc__mallocarray(nelem, elsize)
+#define git__free                             git__stdalloc__free
 
 #endif /* !MSVC_CTRDBG */