Add environ as a link seam for platform APIs

Allow precise redirection of platform-related APIs (such as those
provided by libc) for the purpose of unit tests.

Change-Id: I615b25805fc7a24eb5d67e87237bf35c8e262b93
Signed-off-by: Amithash Prasad <amithash@meta.com>
Signed-off-by: Andrew Jeffery <andrew@codeconstruct.com.au>
diff --git a/src/compiler.h b/src/compiler.h
index c10ebfe..75b746a 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -21,6 +21,7 @@
 		      "`unused` attribute is required");
 	static_assert(__has_attribute(warn_unused_result),
 		      "`warn_unused_result` attribute is required");
+	static_assert(__has_attribute(weak), "`weak` attribute is required");
 	int compliance;
 } pldm_required_attributes __attribute__((unused));
 
@@ -36,6 +37,7 @@
 #define LIBPLDM_CC_NONNULL_ARGS(...)  __attribute__((nonnull(__VA_ARGS__)))
 #define LIBPLDM_CC_UNUSED	      __attribute__((unused))
 #define LIBPLDM_CC_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+#define LIBPLDM_CC_WEAK		      __attribute__((weak))
 
 // NOLINTBEGIN(bugprone-macro-parentheses)
 /**
diff --git a/src/environ/meson.build b/src/environ/meson.build
new file mode 100644
index 0000000..24d6ce7
--- /dev/null
+++ b/src/environ/meson.build
@@ -0,0 +1 @@
+libpldm_sources += files('time.c')
diff --git a/src/environ/time.c b/src/environ/time.c
new file mode 100644
index 0000000..f70022b
--- /dev/null
+++ b/src/environ/time.c
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
+#include "compiler.h"
+#include "environ/time.h"
+
+#include <time.h>
+
+LIBPLDM_ABI_TESTING LIBPLDM_CC_WEAK int
+libpldm_clock_gettime(clockid_t clockid, struct timespec *ts)
+{
+	return clock_gettime(clockid, ts);
+}
diff --git a/src/environ/time.h b/src/environ/time.h
new file mode 100644
index 0000000..eed558e
--- /dev/null
+++ b/src/environ/time.h
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+#ifndef LIBPLDM_ENVIRON_TIME_H
+#define LIBPLDM_ENVIRON_TIME_H
+#include <sys/time.h>
+#include <time.h>
+
+/** @brief Weak symbol wrapping clock_gettime() */
+int libpldm_clock_gettime(clockid_t clockid, struct timespec *ts);
+
+#endif
diff --git a/src/meson.build b/src/meson.build
index 13f7d9e..c49d1bb 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -16,6 +16,7 @@
 endif
 
 subdir('firmware_device')
+subdir('environ')
 
 libpldm_link_args = []
 foreach alias : libpldm_deprecated_aliases
diff --git a/src/transport/transport.c b/src/transport/transport.c
index 24c264a..f0aa730 100644
--- a/src/transport/transport.c
+++ b/src/transport/transport.c
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
 #include "compiler.h"
 #include "transport.h"
+#include "environ/time.h"
 
 #include <libpldm/transport.h>
 #include <libpldm/base.h>
@@ -133,7 +134,7 @@
 	struct timespec now;
 	int rc;
 
-	rc = clock_gettime(clockid, &now);
+	rc = libpldm_clock_gettime(clockid, &now);
 	if (rc < 0) {
 		return rc;
 	}