regression: add case 1019

Test the dynamically linked TA feature if CFG_TA_DYNLINK=y. Android is not
supported at the moment (xtest 1019 will do nothing).

Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Tested-by: Jerome Forissier <jerome.forissier@linaro.org> (QEMU make & cmake)
Reviewed-by: Joakim Bech <joakim.bech@linaro.org>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
diff --git a/host/xtest/regression_1000.c b/host/xtest/regression_1000.c
index 933dff7..9d701a1 100644
--- a/host/xtest/regression_1000.c
+++ b/host/xtest/regression_1000.c
@@ -61,6 +61,9 @@
 static void xtest_tee_test_1016(ADBG_Case_t *Case_p);
 static void xtest_tee_test_1017(ADBG_Case_t *Case_p);
 static void xtest_tee_test_1018(ADBG_Case_t *Case_p);
+#if defined(CFG_TA_DYNLINK) && !defined(__ANDROID__)
+static void xtest_tee_test_1019(ADBG_Case_t *Case_p);
+#endif
 
 ADBG_CASE_DEFINE(regression, 1001, xtest_tee_test_1001, "Core self tests");
 ADBG_CASE_DEFINE(regression, 1002, xtest_tee_test_1002, "PTA parameters");
@@ -94,6 +97,10 @@
 		"Test coalescing memrefs");
 ADBG_CASE_DEFINE(regression, 1018, xtest_tee_test_1018,
 		"Test memref out of bounds");
+#if defined(CFG_TA_DYNLINK) && !defined(__ANDROID__)
+ADBG_CASE_DEFINE(regression, 1019, xtest_tee_test_1019,
+		"Test dynamically linked TA");
+#endif
 
 struct xtest_crypto_session {
 	ADBG_Case_t *c;
@@ -1435,3 +1442,29 @@
 out:
 	TEEC_ReleaseSharedMemory(&shm);
 }
+
+#if defined(CFG_TA_DYNLINK) && !defined(__ANDROID__)
+static void xtest_tee_test_1019(ADBG_Case_t *c)
+{
+	TEEC_Session session = { 0 };
+	uint32_t ret_orig;
+
+	if (!ADBG_EXPECT_TEEC_SUCCESS(c,
+		xtest_teec_open_session(&session, &os_test_ta_uuid, NULL,
+		                        &ret_orig)))
+		return;
+
+	(void)ADBG_EXPECT_TEEC_SUCCESS(c,
+		TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CALL_LIB, NULL,
+				   &ret_orig));
+
+	(void)ADBG_EXPECT_TEEC_RESULT(c,
+		TEEC_ERROR_TARGET_DEAD,
+		TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CALL_LIB_PANIC,
+				   NULL, &ret_orig));
+
+	(void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TEE, ret_orig);
+
+	TEEC_CloseSession(&session);
+}
+#endif
diff --git a/ta/Makefile b/ta/Makefile
index dd5a9fe..620169c 100644
--- a/ta/Makefile
+++ b/ta/Makefile
@@ -14,8 +14,13 @@
 # LDFLAGS that are suitable for the client applications, not for TAs
 LDFLAGS=
 
+ifeq ($(CFG_TA_DYNLINK),y)
+OS_TEST_LIB := os_test_lib
+endif
+
 TA_DIRS := create_fail_test \
 	   crypt \
+	   $(OS_TEST_LIB) \
 	   os_test \
 	   rpc_test \
 	   sims \
diff --git a/ta/os_test/Makefile b/ta/os_test/Makefile
index bc08905..0f2e8ff 100644
--- a/ta/os_test/Makefile
+++ b/ta/os_test/Makefile
@@ -1,2 +1,13 @@
+include $(TA_DEV_KIT_DIR)/mk/conf.mk
+
 BINARY = 5b9e0e40-2636-11e1-ad9e-0002a5d5c51b
+
+ifeq ($(CFG_TA_DYNLINK),y)
+# Hack: to locate the os_test library, we assume that its output path
+# follows the same scheme as the output path of the os_test application.
+# Therefore, simply replacing os_test by os_test_lib in the absolute path
+# should get us a valid path
+LDADD = -L$(subst os_test,os_test_lib,$(abspath $(link-out-dir))) -los_test
+endif
+
 include ../ta_common.mk
diff --git a/ta/os_test/include/os_test.h b/ta/os_test/include/os_test.h
index f576aed..57f8470 100644
--- a/ta/os_test/include/os_test.h
+++ b/ta/os_test/include/os_test.h
@@ -42,5 +42,7 @@
 TEE_Result ta_entry_ta2ta_memref_mix(uint32_t param_types,
 				     TEE_Param params[4]);
 TEE_Result ta_entry_params(uint32_t param_types, TEE_Param params[4]);
+TEE_Result ta_entry_call_lib(uint32_t param_types, TEE_Param params[4]);
+TEE_Result ta_entry_call_lib_panic(uint32_t param_types, TEE_Param params[4]);
 
 #endif /*OS_TEST_H */
diff --git a/ta/os_test/include/ta_os_test.h b/ta/os_test/include/ta_os_test.h
index 1462e52..4292823 100644
--- a/ta/os_test/include/ta_os_test.h
+++ b/ta/os_test/include/ta_os_test.h
@@ -44,5 +44,7 @@
 #define TA_OS_TEST_CMD_TA2TA_MEMREF         11
 #define TA_OS_TEST_CMD_TA2TA_MEMREF_MIX     12
 #define TA_OS_TEST_CMD_PARAMS               13
+#define TA_OS_TEST_CMD_CALL_LIB             14
+#define TA_OS_TEST_CMD_CALL_LIB_PANIC       15
 
 #endif /*TA_OS_TEST_H */
diff --git a/ta/os_test/os_test.c b/ta/os_test/os_test.c
index a61466b..10bd9d3 100644
--- a/ta/os_test/os_test.c
+++ b/ta/os_test/os_test.c
@@ -35,6 +35,7 @@
 #include "os_test.h"
 #include "testframework.h"
 #include "test_float_subj.h"
+#include "os_test_lib.h"
 
 enum p_type {
 	P_TYPE_BOOL,
@@ -1064,3 +1065,32 @@
 
 	return TEE_SUCCESS;
 }
+
+TEE_Result ta_entry_call_lib(uint32_t param_types,
+			     TEE_Param params[4] __unused)
+{
+	if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
+					   TEE_PARAM_TYPE_NONE,
+					   TEE_PARAM_TYPE_NONE,
+					   TEE_PARAM_TYPE_NONE))
+		return TEE_ERROR_BAD_PARAMETERS;
+
+	if (os_test_shlib_add(1, 2) != 3)
+		return TEE_ERROR_GENERIC;
+
+	return TEE_SUCCESS;
+}
+
+TEE_Result ta_entry_call_lib_panic(uint32_t param_types,
+				   TEE_Param params[4] __unused)
+{
+	if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
+					   TEE_PARAM_TYPE_NONE,
+					   TEE_PARAM_TYPE_NONE,
+					   TEE_PARAM_TYPE_NONE))
+		return TEE_ERROR_BAD_PARAMETERS;
+
+	os_test_shlib_panic();
+
+	return TEE_ERROR_GENERIC;
+}
diff --git a/ta/os_test/sub.mk b/ta/os_test/sub.mk
index 95980f7..bec0c49 100644
--- a/ta/os_test/sub.mk
+++ b/ta/os_test/sub.mk
@@ -2,6 +2,7 @@
 
 global-incdirs-y += include
 global-incdirs-y += ../crypt/include
+global-incdirs-y += ../os_test_lib/include
 cflags-y += -Wno-float-equal
 srcs-y += init.c
 srcs-y += os_test.c
diff --git a/ta/os_test/ta_entry.c b/ta/os_test/ta_entry.c
index a3ea5e1..e35e75a 100644
--- a/ta/os_test/ta_entry.c
+++ b/ta/os_test/ta_entry.c
@@ -109,6 +109,12 @@
 	case TA_OS_TEST_CMD_PARAMS:
 		return ta_entry_params(nParamTypes, pParams);
 
+	case TA_OS_TEST_CMD_CALL_LIB:
+		return ta_entry_call_lib(nParamTypes, pParams);
+
+	case TA_OS_TEST_CMD_CALL_LIB_PANIC:
+		return ta_entry_call_lib_panic(nParamTypes, pParams);
+
 	default:
 		return TEE_ERROR_BAD_PARAMETERS;
 	}
diff --git a/ta/os_test_lib/Makefile b/ta/os_test_lib/Makefile
new file mode 100644
index 0000000..cfa31d6
--- /dev/null
+++ b/ta/os_test_lib/Makefile
@@ -0,0 +1,14 @@
+include $(TA_DEV_KIT_DIR)/mk/conf.mk
+
+ifeq ($(CFG_TA_DYNLINK),y)
+
+SHLIBNAME = libos_test
+SHLIBUUID = ffd2bded-ab7d-4988-95ee-e4962fff7154
+include ../ta_common.mk
+
+else
+
+# For the buildroot environment
+all:
+
+endif
diff --git a/ta/os_test_lib/include/os_test_lib.h b/ta/os_test_lib/include/os_test_lib.h
new file mode 100644
index 0000000..51cf69c
--- /dev/null
+++ b/ta/os_test_lib/include/os_test_lib.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+/*
+ * Copyright (c) 2018, Linaro Limited
+ */
+
+#ifndef _OS_TEST_LIB_H_
+#define _OS_TEST_LIB_H_
+
+#if defined(CFG_TA_DYNLINK) && !defined(__ANDROID__)
+
+int os_test_shlib_add(int a, int b);
+void os_test_shlib_panic(void);
+
+#else
+
+#include <compiler.h>
+#include <tee_internal_api.h>
+
+static inline int os_test_shlib_add(int a __unused, int b __unused)
+{
+	TEE_Panic(0);
+	return 0;
+}
+
+static inline void os_test_shlib_panic(void)
+{
+}
+
+#endif /* CFG_TA_DYNLINK && !__ANDROID__ */
+
+#endif /* _OS_TEST_LIB_H_ */
diff --git a/ta/os_test_lib/os_test_lib.c b/ta/os_test_lib/os_test_lib.c
new file mode 100644
index 0000000..c97a039
--- /dev/null
+++ b/ta/os_test_lib/os_test_lib.c
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: BSD-2-Clause
+/*
+ * Copyright (c) 2018, Linaro Limited
+ */
+
+#include "os_test_lib.h"
+#include <tee_internal_api.h>
+
+int os_test_shlib_add(int a, int b)
+{
+	return a + b;
+}
+
+void os_test_shlib_panic(void)
+{
+	TEE_Panic(0);
+}
diff --git a/ta/os_test_lib/sub.mk b/ta/os_test_lib/sub.mk
new file mode 100644
index 0000000..0102cc8
--- /dev/null
+++ b/ta/os_test_lib/sub.mk
@@ -0,0 +1,2 @@
+global-incdirs-y += include
+srcs-y += os_test_lib.c