From 1a205ae33440f603e0579155505ce48215169e58 Mon Sep 17 00:00:00 2001 From: Jerome Forissier Date: Wed, 17 Jun 2020 17:55:00 +0200 Subject: [PATCH] Add regression 1031 (C++ support in TAs) This commit adds C++ source files to the os_test TA and libraries. Regression 1031 is added which tests the following: - Construction of global objects in the TA main executable and in shared libraries (loaded automatically and via dlopen()) - Exception handling in the main program only (EH in shared libraries is not supported). - A "mixed frame" exception test, in which a C++ function calls a C function which calls a C++ function which throws. The initial caller is expected to be able to catch the exception. Signed-off-by: Jerome Forissier Acked-by: Jens Wiklander Acked-by: Etienne Carriere --- host/xtest/regression_1000.c | 54 +++++++++++ ta/os_test/cxx_tests.cpp | 107 +++++++++++++++++++++ ta/os_test/cxx_tests.h | 12 +++ ta/os_test/cxx_tests_c.c | 11 +++ ta/os_test/include/os_test.h | 5 + ta/os_test/include/ta_os_test.h | 5 + ta/os_test/sub.mk | 4 + ta/os_test/ta_entry.c | 24 +++++ ta/os_test_lib/os_test_lib_cxx.cpp | 26 +++++ ta/os_test_lib/sub.mk | 3 + ta/os_test_lib_dl/include/os_test_lib_dl.h | 3 + ta/os_test_lib_dl/os_test_lib_dl_cxx.cpp | 26 +++++ ta/os_test_lib_dl/sub.mk | 3 + 13 files changed, 283 insertions(+) create mode 100644 ta/os_test/cxx_tests.cpp create mode 100644 ta/os_test/cxx_tests.h create mode 100644 ta/os_test/cxx_tests_c.c create mode 100644 ta/os_test_lib/os_test_lib_cxx.cpp create mode 100644 ta/os_test_lib_dl/os_test_lib_dl_cxx.cpp diff --git a/host/xtest/regression_1000.c b/host/xtest/regression_1000.c index dfc13990a..5cc4d640e 100644 --- a/host/xtest/regression_1000.c +++ b/host/xtest/regression_1000.c @@ -2253,3 +2253,57 @@ static void xtest_tee_test_1030(ADBG_Case_t *c) } ADBG_CASE_DEFINE(regression, 1030, xtest_tee_test_1030, "Test dl_iterate_phdr()"); + +#ifndef __clang__ +static void xtest_tee_test_1031(ADBG_Case_t *c) +{ + TEEC_Result ret = TEE_SUCCESS; + TEEC_Session session = { 0 }; + uint32_t ret_orig = 0; + + if (!ADBG_EXPECT_TEEC_SUCCESS(c, + xtest_teec_open_session(&session, &os_test_ta_uuid, + NULL, &ret_orig))) + return; + + Do_ADBG_BeginSubCase(c, "Global object constructor (main program)"); + ret = TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CXX_CTOR_MAIN, NULL, + &ret_orig); + if (ret == TEEC_ERROR_NOT_SUPPORTED) { + printf("TA not built with C++ support, skipping C++ tests\n"); + Do_ADBG_EndSubCase(c, "Global object constructor (main program)"); + goto out; + + } + ADBG_EXPECT_TEEC_SUCCESS(c, ret); + Do_ADBG_EndSubCase(c, "Global object constructor (main program)"); + + Do_ADBG_BeginSubCase(c, "Global object constructor (shared library)"); + ADBG_EXPECT_TEEC_SUCCESS(c, + TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CXX_CTOR_SHLIB, + NULL, &ret_orig)); + Do_ADBG_EndSubCase(c, "Global object constructor (shared library)"); + + Do_ADBG_BeginSubCase(c, "Global object constructor (dlopen()ed lib)"); + ADBG_EXPECT_TEEC_SUCCESS(c, + TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CXX_CTOR_SHLIB_DL, + NULL, &ret_orig)); + Do_ADBG_EndSubCase(c, "Global object constructor (dlopen()ed lib)"); + + Do_ADBG_BeginSubCase(c, "Exceptions (simple)"); + ADBG_EXPECT_TEEC_SUCCESS(c, + TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CXX_EXC_MAIN, NULL, + &ret_orig)); + Do_ADBG_EndSubCase(c, "Exceptions (simple)"); + + Do_ADBG_BeginSubCase(c, "Exceptions (mixed C/C++ frames)"); + ADBG_EXPECT_TEEC_SUCCESS(c, + TEEC_InvokeCommand(&session, TA_OS_TEST_CMD_CXX_EXC_MIXED, NULL, + &ret_orig)); + Do_ADBG_EndSubCase(c, "Exceptions (mixed C/C++ frames)"); +out: + TEEC_CloseSession(&session); +} +ADBG_CASE_DEFINE(regression, 1031, xtest_tee_test_1031, + "Test C++ features"); +#endif diff --git a/ta/os_test/cxx_tests.cpp b/ta/os_test/cxx_tests.cpp new file mode 100644 index 000000000..176184369 --- /dev/null +++ b/ta/os_test/cxx_tests.cpp @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (c) 2020 Huawei Technologies Co., Ltd + */ + +extern "C" { + +#include +#include +#include +#include + +#include "cxx_tests.h" +#include "os_test.h" + +}; + +class CtorTest { +public: + CtorTest() : val(1) {} + + int val; +}; + +static CtorTest ctor_test; + +TEE_Result ta_entry_cxx_ctor_main(void) +{ + if (ctor_test.val != 1) + return TEE_ERROR_GENERIC; + + return TEE_SUCCESS; +} + +TEE_Result ta_entry_cxx_ctor_shlib(void) +{ + return os_test_shlib_cxx_ctor(); +} + +TEE_Result ta_entry_cxx_ctor_shlib_dl(void) +{ + TEE_Result res = TEE_ERROR_GENERIC; + TEE_Result (*ctor_test_fn)(void); + void *handle = NULL; + + handle = dlopen("b3091a65-9751-4784-abf7-0298a7cc35ba", + RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE); + if (!handle) + return TEE_ERROR_GENERIC; + + ctor_test_fn = (TEE_Result (*)(void))dlsym(handle, + "os_test_shlib_dl_cxx_ctor"); + if (ctor_test_fn) + res = ctor_test_fn(); + + dlclose(handle); + return res; +} + +class MyException { +}; + +TEE_Result ta_entry_cxx_exc_main(void) +{ + try { + throw MyException(); + } catch (MyException &e) { + return TEE_SUCCESS; + } + + return TEE_ERROR_GENERIC; +} + +class MixedFrameException { +}; + +void throw_mfe(void) +{ + throw MixedFrameException(); +} + +class MixedFrameExceptionTest { +public: + MixedFrameExceptionTest() {} + + bool test(); +}; + +bool MixedFrameExceptionTest::test() +{ + try { + throwing_c_func(); + } catch (MixedFrameException e) { + return true; + } + return false; +} + +TEE_Result ta_entry_cxx_exc_mixed(void) +{ + MixedFrameExceptionTest test; + + if (test.test()) + return TEE_SUCCESS; + + return TEE_ERROR_GENERIC; +} diff --git a/ta/os_test/cxx_tests.h b/ta/os_test/cxx_tests.h new file mode 100644 index 000000000..a27c37eed --- /dev/null +++ b/ta/os_test/cxx_tests.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (c) 2020 Huawei Technologies Co., Ltd + */ + +#ifndef CXX_TESTS_H +#define CXX_TESTS_H + +void throw_mfe(void); +void throwing_c_func(void); + +#endif /* CXX_TESTS_H */ diff --git a/ta/os_test/cxx_tests_c.c b/ta/os_test/cxx_tests_c.c new file mode 100644 index 000000000..2e3d0a912 --- /dev/null +++ b/ta/os_test/cxx_tests_c.c @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (c) 2020 Huawei Technologies Co., Ltd + */ + +#include "cxx_tests.h" + +void throwing_c_func(void) +{ + throw_mfe(); +} diff --git a/ta/os_test/include/os_test.h b/ta/os_test/include/os_test.h index ee17cc9f0..1b3022a21 100644 --- a/ta/os_test/include/os_test.h +++ b/ta/os_test/include/os_test.h @@ -32,5 +32,10 @@ TEE_Result ta_entry_tls_test_main(void); TEE_Result ta_entry_tls_test_shlib(void); TEE_Result ta_entry_dl_phdr(void); TEE_Result ta_entry_dl_phdr_dl(void); +TEE_Result ta_entry_cxx_ctor_main(void); +TEE_Result ta_entry_cxx_ctor_shlib(void); +TEE_Result ta_entry_cxx_ctor_shlib_dl(void); +TEE_Result ta_entry_cxx_exc_main(void); +TEE_Result ta_entry_cxx_exc_mixed(void); #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 89cdb0282..60e5cb0ba 100644 --- a/ta/os_test/include/ta_os_test.h +++ b/ta/os_test/include/ta_os_test.h @@ -34,5 +34,10 @@ #define TA_OS_TEST_CMD_TLS_TEST_SHLIB 22 #define TA_OS_TEST_CMD_DL_PHDR 23 #define TA_OS_TEST_CMD_DL_PHDR_DL 24 +#define TA_OS_TEST_CMD_CXX_CTOR_MAIN 25 +#define TA_OS_TEST_CMD_CXX_CTOR_SHLIB 26 +#define TA_OS_TEST_CMD_CXX_CTOR_SHLIB_DL 27 +#define TA_OS_TEST_CMD_CXX_EXC_MAIN 28 +#define TA_OS_TEST_CMD_CXX_EXC_MIXED 29 #endif /*TA_OS_TEST_H */ diff --git a/ta/os_test/sub.mk b/ta/os_test/sub.mk index 2da14aa58..f9a04f5ff 100644 --- a/ta/os_test/sub.mk +++ b/ta/os_test/sub.mk @@ -8,3 +8,7 @@ srcs-y += init.c srcs-y += os_test.c srcs-y += ta_entry.c srcs-$(CFG_TA_FLOAT_SUPPORT) += test_float_subj.c +ifneq ($(COMPILER),clang) +srcs-y += cxx_tests.cpp +srcs-y += cxx_tests_c.c +endif diff --git a/ta/os_test/ta_entry.c b/ta/os_test/ta_entry.c index 890d1746d..1d8db883c 100644 --- a/ta/os_test/ta_entry.c +++ b/ta/os_test/ta_entry.c @@ -121,6 +121,30 @@ TEE_Result TA_InvokeCommandEntryPoint(void *pSessionContext, case TA_OS_TEST_CMD_DL_PHDR_DL: return ta_entry_dl_phdr_dl(); +#ifdef __clang__ + case TA_OS_TEST_CMD_CXX_CTOR_MAIN: + case TA_OS_TEST_CMD_CXX_CTOR_SHLIB: + case TA_OS_TEST_CMD_CXX_CTOR_SHLIB_DL: + case TA_OS_TEST_CMD_CXX_EXC_MAIN: + case TA_OS_TEST_CMD_CXX_EXC_MIXED: + return TEE_ERROR_NOT_SUPPORTED; +#else + case TA_OS_TEST_CMD_CXX_CTOR_MAIN: + return ta_entry_cxx_ctor_main(); + + case TA_OS_TEST_CMD_CXX_CTOR_SHLIB: + return ta_entry_cxx_ctor_shlib(); + + case TA_OS_TEST_CMD_CXX_CTOR_SHLIB_DL: + return ta_entry_cxx_ctor_shlib_dl(); + + case TA_OS_TEST_CMD_CXX_EXC_MAIN: + return ta_entry_cxx_exc_main(); + + case TA_OS_TEST_CMD_CXX_EXC_MIXED: + return ta_entry_cxx_exc_mixed(); +#endif + default: return TEE_ERROR_BAD_PARAMETERS; } diff --git a/ta/os_test_lib/os_test_lib_cxx.cpp b/ta/os_test_lib/os_test_lib_cxx.cpp new file mode 100644 index 000000000..1a57b4bee --- /dev/null +++ b/ta/os_test_lib/os_test_lib_cxx.cpp @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (c) 2020 Huawei Technologies Co., Ltd + */ + +extern "C" { +#include "os_test_lib.h" +#include +} + +class OsTestLibCtorTest { +public: + OsTestLibCtorTest() : val(2) {} + + int val; +}; + +static OsTestLibCtorTest os_test_lib_ctor_test; + +TEE_Result os_test_shlib_cxx_ctor(void) +{ + if (os_test_lib_ctor_test.val != 2) + return TEE_ERROR_GENERIC; + + return TEE_SUCCESS; +} diff --git a/ta/os_test_lib/sub.mk b/ta/os_test_lib/sub.mk index 0102cc815..b479c0ed6 100644 --- a/ta/os_test_lib/sub.mk +++ b/ta/os_test_lib/sub.mk @@ -1,2 +1,5 @@ global-incdirs-y += include srcs-y += os_test_lib.c +ifneq ($(COMPILER),clang) +srcs-y += os_test_lib_cxx.cpp +endif diff --git a/ta/os_test_lib_dl/include/os_test_lib_dl.h b/ta/os_test_lib_dl/include/os_test_lib_dl.h index 42637881b..a9db7c35f 100644 --- a/ta/os_test_lib_dl/include/os_test_lib_dl.h +++ b/ta/os_test_lib_dl/include/os_test_lib_dl.h @@ -6,7 +6,10 @@ #ifndef _OS_TEST_LIB_DL_H_ #define _OS_TEST_LIB_DL_H_ +#include + int os_test_shlib_dl_add(int a, int b); void os_test_shlib_dl_panic(void); +TEE_Result os_test_shlib_dl_cxx_ctor(void); #endif /* _OS_TEST_LIB_DL_H_ */ diff --git a/ta/os_test_lib_dl/os_test_lib_dl_cxx.cpp b/ta/os_test_lib_dl/os_test_lib_dl_cxx.cpp new file mode 100644 index 000000000..15c4b879b --- /dev/null +++ b/ta/os_test_lib_dl/os_test_lib_dl_cxx.cpp @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (c) 2018, Linaro Limited + */ + +extern "C" { +#include "os_test_lib_dl.h" +#include +} + +class OsTestLibDlCtorTest { +public: + OsTestLibDlCtorTest() : val(2) {} + + int val; +}; + +static OsTestLibDlCtorTest os_test_lib_dl_ctor_test; + +TEE_Result os_test_shlib_dl_cxx_ctor(void) +{ + if (os_test_lib_dl_ctor_test.val != 2) + return TEE_ERROR_GENERIC; + + return TEE_SUCCESS; +} diff --git a/ta/os_test_lib_dl/sub.mk b/ta/os_test_lib_dl/sub.mk index bfe78bbd4..dd7503541 100644 --- a/ta/os_test_lib_dl/sub.mk +++ b/ta/os_test_lib_dl/sub.mk @@ -1,2 +1,5 @@ global-incdirs-y += include srcs-y += os_test_lib_dl.c +ifneq ($(COMPILER),clang) +srcs-y += os_test_lib_dl_cxx.cpp +endif