From 033397b8770238d7c00dcaf1114dbcea917484fa Mon Sep 17 00:00:00 2001 From: Laukik Hase Date: Tue, 8 Apr 2025 15:02:39 +0530 Subject: [PATCH] fix(esp_tee): Add standard newlib function stubs to resolve build warnings - Disable C++ exceptions for TEE build to reduce flash footprint --- components/cxx/CMakeLists.txt | 57 +++++--- .../esp_tee/subproject/main/CMakeLists.txt | 6 + .../subproject/main/common/syscall_stubs.c | 136 ++++++++++++++++++ .../subproject/main/core/esp_tee_init.c | 16 --- components/nvs_flash/CMakeLists.txt | 2 +- 5 files changed, 178 insertions(+), 39 deletions(-) create mode 100644 components/esp_tee/subproject/main/common/syscall_stubs.c diff --git a/components/cxx/CMakeLists.txt b/components/cxx/CMakeLists.txt index a14aa9b148..bce5de3233 100644 --- a/components/cxx/CMakeLists.txt +++ b/components/cxx/CMakeLists.txt @@ -1,16 +1,23 @@ idf_build_get_property(target IDF_TARGET) +idf_build_get_property(esp_tee_build ESP_TEE_BUILD) if(${target} STREQUAL "linux") return() # This component is not necessary on the POSIX/Linux simulator endif() -idf_component_register(SRCS "cxx_exception_stubs.cpp" - "cxx_guards.cpp" - "cxx_init.cpp" - # Make sure that pthread is in component list - PRIV_REQUIRES pthread esp_system) +set(srcs "cxx_exception_stubs.cpp") +set(priv_requires esp_system) -if(NOT CONFIG_CXX_EXCEPTIONS) +if(NOT esp_tee_build) + list(APPEND srcs "cxx_guards.cpp" "cxx_init.cpp") + # Make sure that pthread is in component list + list(APPEND priv_requires pthread) +endif() + +idf_component_register(SRCS ${srcs} + PRIV_REQUIRES ${priv_requires}) + +if(esp_tee_build OR NOT CONFIG_CXX_EXCEPTIONS) set(WRAP_FUNCTIONS __register_frame_info_bases __register_frame_info @@ -55,25 +62,31 @@ if(CMAKE_C_COMPILER_ID MATCHES "Clang") else() target_link_libraries(${COMPONENT_LIB} PUBLIC stdc++ gcc) endif() -target_link_libraries(${COMPONENT_LIB} INTERFACE "-u __cxa_guard_dummy") -target_link_libraries(${COMPONENT_LIB} INTERFACE "-u __cxx_init_dummy") -# Force libpthread to appear later than libstdc++ in link line since libstdc++ depends on libpthread. -# Furthermore, force libcxx to appear later than libgcc because some libgcc unwind code is wrapped, if C++ -# exceptions are disabled. libcxx (this component) provides the unwind code wrappers. -# This is to prevent linking of libgcc's unwind code which considerably increases the binary size. -# Also force libnewlib to appear later than libstdc++ in link line since libstdc++ depends on -# some functions in libnewlib, e.g. getentropy(). -idf_component_get_property(pthread pthread COMPONENT_LIB) -idf_component_get_property(newlib newlib COMPONENT_LIB) -idf_component_get_property(cxx cxx COMPONENT_LIB) add_library(stdcpp_deps INTERFACE) -if(CMAKE_C_COMPILER_ID MATCHES "Clang") - target_link_libraries(stdcpp_deps INTERFACE stdc++ c $ $) -else() - target_link_libraries(stdcpp_deps INTERFACE stdc++ $ $) -endif() target_link_libraries(${COMPONENT_LIB} PUBLIC stdcpp_deps) + +if(NOT esp_tee_build) + target_link_libraries(${COMPONENT_LIB} INTERFACE "-u __cxa_guard_dummy") + target_link_libraries(${COMPONENT_LIB} INTERFACE "-u __cxx_init_dummy") + + # Force libpthread to appear later than libstdc++ in link line since libstdc++ depends on libpthread. + # Furthermore, force libcxx to appear later than libgcc because some libgcc unwind code is wrapped, if C++ + # exceptions are disabled. libcxx (this component) provides the unwind code wrappers. + # This is to prevent linking of libgcc's unwind code which considerably increases the binary size. + # Also force libnewlib to appear later than libstdc++ in link line since libstdc++ depends on + # some functions in libnewlib, e.g. getentropy(). + idf_component_get_property(pthread pthread COMPONENT_LIB) + idf_component_get_property(newlib newlib COMPONENT_LIB) + + if(CMAKE_C_COMPILER_ID MATCHES "Clang") + target_link_libraries(stdcpp_deps INTERFACE stdc++ c $ $) + else() + target_link_libraries(stdcpp_deps INTERFACE stdc++ $ $) + endif() +endif() + +idf_component_get_property(cxx cxx COMPONENT_LIB) add_library(libgcc_cxx INTERFACE) target_link_libraries(libgcc_cxx INTERFACE ${CONFIG_COMPILER_RT_LIB_NAME} $) target_link_libraries(${COMPONENT_LIB} PUBLIC libgcc_cxx) diff --git a/components/esp_tee/subproject/main/CMakeLists.txt b/components/esp_tee/subproject/main/CMakeLists.txt index 819fe00070..3d6ad4399f 100644 --- a/components/esp_tee/subproject/main/CMakeLists.txt +++ b/components/esp_tee/subproject/main/CMakeLists.txt @@ -46,6 +46,9 @@ list(APPEND include "${heap_dir}/tlsf") # esp_app_desc_t configuration structure for TEE list(APPEND srcs "common/esp_app_desc_tee.c") +# Newlib syscalls stub implementation +list(APPEND srcs "common/syscall_stubs.c") + idf_component_register(SRCS ${srcs} INCLUDE_DIRS ${include}) @@ -57,6 +60,9 @@ include(${CMAKE_CURRENT_LIST_DIR}/ld/esp_tee_ld.cmake) # esp_app_desc_t configuration structure for TEE: Linking symbol and trimming project version and name target_link_libraries(${COMPONENT_LIB} PRIVATE "-u esp_app_desc_tee_include_impl") +# Newlib syscalls stub implementation: Linking symbol +target_link_libraries(${COMPONENT_LIB} PRIVATE "-u esp_tee_include_syscalls_impl") + # cut PROJECT_VER and PROJECT_NAME to required 32 characters. idf_build_get_property(project_ver PROJECT_VER) idf_build_get_property(project_name PROJECT_NAME) diff --git a/components/esp_tee/subproject/main/common/syscall_stubs.c b/components/esp_tee/subproject/main/common/syscall_stubs.c new file mode 100644 index 0000000000..76e79f6e68 --- /dev/null +++ b/components/esp_tee/subproject/main/common/syscall_stubs.c @@ -0,0 +1,136 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "esp_random.h" + +// NOTE: Remove compile-time warnings for the below newlib-provided functions +struct _reent *__getreent(void) +{ + return _GLOBAL_REENT; +} + +int _fstat_r(struct _reent *r, int fd, struct stat *st) +{ + errno = ENOSYS; + return -1; +} + +int _close_r(struct _reent *r, int fd) +{ + errno = ENOSYS; + return -1; +} + +off_t _lseek_r(struct _reent *r, int fd, off_t offset, int whence) +{ + errno = ENOSYS; + return -1; +} + +ssize_t _read_r(struct _reent *r, int fd, void *ptr, size_t len) +{ + errno = ENOSYS; + return -1; +} + +ssize_t _write_r(struct _reent *r, int fd, const void *ptr, size_t len) +{ + errno = ENOSYS; + return -1; +} + +int _getpid_r(struct _reent *r) +{ + return 1; +} + +int _kill_r(struct _reent *r, int pid, int sig) +{ + errno = ENOSYS; + return -1; +} + +int _getentropy_r(struct _reent *r, void *buffer, size_t length) +{ + esp_fill_random(buffer, length); + return 0; +} + +void *pthread_getspecific(pthread_key_t key) +{ + return NULL; +} + +int pthread_setspecific(pthread_key_t key, const void *value) +{ + return 0; +} + +int pthread_key_create(pthread_key_t *key, void (*destructor)(void*)) +{ + errno = ENOSYS; + return -1; +} + +int pthread_key_delete(pthread_key_t key) +{ + errno = ENOSYS; + return -1; +} + +int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) +{ + errno = ENOSYS; + return -1; +} + +int pthread_mutex_destroy(pthread_mutex_t *mutex) +{ + errno = ENOSYS; + return -1; +} + +int pthread_mutex_lock(pthread_mutex_t *mutex) +{ + errno = ENOSYS; + return -1; +} + +int pthread_mutex_unlock(pthread_mutex_t *mutex) +{ + errno = ENOSYS; + return -1; +} + +void *__cxa_get_globals(void) +{ + return NULL; +} + +void *__cxa_get_globals_fast(void) +{ + return NULL; +} + +int __cxa_thread_atexit(void (*func)(void *), void *arg, void *dso) +{ + return 0; +} + +void esp_tee_include_syscalls_impl(void) +{ + +} diff --git a/components/esp_tee/subproject/main/core/esp_tee_init.c b/components/esp_tee/subproject/main/core/esp_tee_init.c index 9bdfb06f99..8225c8faf5 100644 --- a/components/esp_tee/subproject/main/core/esp_tee_init.c +++ b/components/esp_tee/subproject/main/core/esp_tee_init.c @@ -187,19 +187,3 @@ void __attribute__((noreturn)) esp_tee_init(uint32_t ree_entry_addr, uint32_t re /* App entry function should not return here. */ ESP_INFINITE_LOOP(); /* WDT will reset us */ } - -// NOTE: Remove compile-time warnings for the below newlib-provided functions -struct _reent *__getreent(void) -{ - return _GLOBAL_REENT; -} - -void _fstat_r(void) {} - -void _close_r(void) {} - -void _lseek_r(void) {} - -void _read_r(void) {} - -void _write_r(void) {} diff --git a/components/nvs_flash/CMakeLists.txt b/components/nvs_flash/CMakeLists.txt index edbfeaa36e..693e510de9 100644 --- a/components/nvs_flash/CMakeLists.txt +++ b/components/nvs_flash/CMakeLists.txt @@ -32,7 +32,7 @@ elseif(esp_tee_build) "src/nvs_platform.cpp") set(requires esp_partition mbedtls) - set(priv_requires spi_flash newlib) + set(priv_requires spi_flash newlib cxx) idf_component_register(SRCS "${srcs}" REQUIRES "${requires}"