build/core: Add MCTP_CUSTOM_ALLOC option

This avoids storing the allocator function pointers in mutable memory,
which is a problem when building on platforms with memory protection.
Instead the application/platform defines custom functions that are
linked with libmctp.

Change-Id: Icaf88968b50c88bbd2305d325f9530658465e21f
Signed-off-by: Matt Johnston <matt@codeconstruct.com.au>
diff --git a/alloc.c b/alloc.c
index 0639e87..650ea7e 100644
--- a/alloc.c
+++ b/alloc.c
@@ -11,6 +11,10 @@
 
 #include "compiler.h"
 
+#if defined(MCTP_DEFAULT_ALLOC) && defined(MCTP_CUSTOM_ALLOC)
+#error Default and Custom alloc are incompatible
+#endif
+
 #ifdef MCTP_DEFAULT_ALLOC
 static void *default_msg_malloc(size_t size, void *ctx __unused)
 {
@@ -24,7 +28,18 @@
 }
 #endif
 
-struct {
+/* Allocators provided as functions to call */
+#ifdef MCTP_CUSTOM_ALLOC
+extern void *mctp_custom_malloc(size_t size);
+extern void mctp_custom_free(void *ptr);
+extern void *mctp_custom_msg_alloc(size_t size, void *ctx);
+extern void mctp_custom_msg_free(void *msg, void *ctx);
+#endif
+
+#ifdef MCTP_CUSTOM_ALLOC
+const
+#endif
+	struct {
 	void *(*m_alloc)(size_t);
 	void (*m_free)(void *);
 	/* Final argument is ctx */
@@ -37,6 +52,12 @@
 	default_msg_malloc,
 	default_msg_free,
 #endif
+#ifdef MCTP_CUSTOM_ALLOC
+	mctp_custom_malloc,
+	mctp_custom_free,
+	mctp_custom_msg_alloc,
+	mctp_custom_msg_free,
+#endif
 };
 
 /* internal-only allocation functions */
@@ -72,6 +93,7 @@
 		alloc_ops.m_msg_free(ptr, ctx);
 }
 
+#ifndef MCTP_CUSTOM_ALLOC
 void mctp_set_alloc_ops(void *(*m_alloc)(size_t), void (*m_free)(void *),
 			void *(*m_msg_alloc)(size_t, void *),
 			void (*m_msg_free)(void *, void *))
@@ -81,3 +103,4 @@
 	alloc_ops.m_msg_alloc = m_msg_alloc;
 	alloc_ops.m_msg_free = m_msg_free;
 }
+#endif // MCTP_CUSTOM_ALLOC
diff --git a/meson.build b/meson.build
index d884c6a..7f44a46 100644
--- a/meson.build
+++ b/meson.build
@@ -53,7 +53,7 @@
 
 compiler = meson.get_compiler('c')
 
-if get_option('default_alloc').require(
+if not get_option('custom_alloc') and get_option('default_alloc').require(
     compiler.links('''
         #include <stdlib.h>
         void main()
@@ -64,6 +64,10 @@
     add_project_arguments('-DMCTP_DEFAULT_ALLOC', language : 'c')
 endif
 
+if get_option('custom_alloc')
+    add_project_arguments('-DMCTP_CUSTOM_ALLOC', language : 'c')
+endif
+
 feat_fileio = get_option('fileio').require(
     compiler.links('''
         #include <poll.h>
diff --git a/meson.options b/meson.options
index f919ad8..73c23be 100644
--- a/meson.options
+++ b/meson.options
@@ -31,3 +31,9 @@
     type: 'feature',
     description: 'Support logging to syslog',
 )
+option(
+    'custom_alloc',
+    type: 'boolean',
+    value: false,
+    description: 'Use fixed application-provided allocators',
+)