fix(esp_tee): Add standard newlib function stubs to resolve build warnings

- Disable C++ exceptions for TEE build to reduce flash footprint
This commit is contained in:
Laukik Hase
2025-04-08 15:02:39 +05:30
parent 3bb3f9362e
commit 033397b877
5 changed files with 178 additions and 39 deletions

View File

@ -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 $<TARGET_FILE:${pthread}> $<TARGET_FILE:${newlib}>)
else()
target_link_libraries(stdcpp_deps INTERFACE stdc++ $<TARGET_FILE:${pthread}> $<TARGET_FILE:${newlib}>)
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 $<TARGET_FILE:${pthread}> $<TARGET_FILE:${newlib}>)
else()
target_link_libraries(stdcpp_deps INTERFACE stdc++ $<TARGET_FILE:${pthread}> $<TARGET_FILE:${newlib}>)
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_FILE:${cxx}>)
target_link_libraries(${COMPONENT_LIB} PUBLIC libgcc_cxx)

View File

@ -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)

View File

@ -0,0 +1,136 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <pthread.h>
#include <unistd.h>
#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)
{
}

View File

@ -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) {}

View File

@ -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}"