aboutsummaryrefslogtreecommitdiff
path: root/cmake/Common
diff options
context:
space:
mode:
authorTamas Ban <tamas.ban@arm.com>2020-10-26 13:03:13 +0000
committerTamas Ban <tamas.ban@arm.com>2020-12-17 13:06:19 +0000
commitf8b0b2df5e9b954fd5d59ae95684659e73b38c8c (patch)
treed76ac5d0545608363ba59aca869bdd6f188357b0 /cmake/Common
parent73946a89d4e1b839878f0599516dc5ae6e01efe7 (diff)
downloadtrusted-firmware-m-f8b0b2df5e9b954fd5d59ae95684659e73b38c8c.tar.gz
Build: Enable code sharing between bootloader and SPE
Add CMake functions to allow sharing regions of code between independently linked binaries. Signed-off-by: Tamas Ban <tamas.ban@arm.com> Change-Id: I6a6132d6c1558b242d8da1dedab14f93a852f81a
Diffstat (limited to 'cmake/Common')
-rw-r--r--cmake/Common/FilterSharedSymbols.cmake56
-rw-r--r--cmake/Common/StripUnsharedCode.cmake40
-rw-r--r--cmake/Common/WeakenSymbols.cmake77
3 files changed, 173 insertions, 0 deletions
diff --git a/cmake/Common/FilterSharedSymbols.cmake b/cmake/Common/FilterSharedSymbols.cmake
new file mode 100644
index 0000000000..feac8919c5
--- /dev/null
+++ b/cmake/Common/FilterSharedSymbols.cmake
@@ -0,0 +1,56 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# A CMake script which is meant to filter some wanted symbols based on a template file
+# from another text file, which contains all the extracted symbols from an executable.
+#
+# INPUT parameters:
+# SHARED_SYMBOL_TEMPLATE - Text file contains wanted symbol name templates to be shared (i.e.: mbedtls_)
+# ALL_SYMBOLS - Text file, which contains all the extracted symbols from an executable.
+# Produced in previous step of the code sharing process.
+#
+# OUTPUTS produced by this script:
+# - shared_symbols_addr.txt List of the name, type and absolute address of symbols which
+# match with the patterns in the symbol template file
+# - shared_symbols_name.txt List of only the names of symbols which match with the
+# patterns in the symbol template file
+
+file(STRINGS ${SHARED_SYMBOL_TEMPLATE} SHARED_SYMBOL_TEMPLATE)
+file(STRINGS ${ALL_SYMBOLS} ALL_SYMBOLS)
+
+# In 'arm-none-eabi-nm' and 'armclang --symdefs' output 'T' indicates the global
+# symbols which can be shared between independently linked executables.
+set(_GLOBAL_TEXT_SYMBOL "T")
+
+foreach(_SYMBOL_TEMPLATE IN LISTS SHARED_SYMBOL_TEMPLATE)
+ string(SUBSTRING _SYMBOL_TEMPLATE 0 1 FIRST_CHAR)
+ if(NOT _SYMBOL_TEMPLATE STREQUAL "" AND NOT FIRST_CHAR STREQUAL "#")
+ foreach(_ONE_SYMBOL IN LISTS ALL_SYMBOLS)
+ string(FIND ${_ONE_SYMBOL} "${_GLOBAL_TEXT_SYMBOL} ${_SYMBOL_TEMPLATE}" POSITION)
+ if (NOT POSITION EQUAL -1)
+ # Get matching symbol name and its address
+ list(APPEND SHARED_SYMBOL_ADDR_LIST "${_ONE_SYMBOL}")
+
+ # Get matching symbol name
+ string(SUBSTRING ${_ONE_SYMBOL} ${POSITION} 200 _ONE_SYMBOL_NAME)
+ string(REPLACE "${_GLOBAL_TEXT_SYMBOL} " "" _ONE_SYMBOL_NAME ${_ONE_SYMBOL_NAME})
+ list(APPEND SHARED_SYMBOL_NAME_LIST "${_ONE_SYMBOL_NAME}")
+ endif()
+ endforeach()
+ endif()
+endforeach()
+
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/shared_symbols_addr.txt "#<SYMDEFS>#\n")
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/shared_symbols_name.txt "")
+
+foreach(_SYMBOL IN LISTS SHARED_SYMBOL_ADDR_LIST)
+ file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/shared_symbols_addr.txt "${_SYMBOL}\n")
+endforeach()
+
+foreach(_SYMBOL IN LISTS SHARED_SYMBOL_NAME_LIST)
+ file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/shared_symbols_name.txt "${_SYMBOL}\n")
+endforeach()
diff --git a/cmake/Common/StripUnsharedCode.cmake b/cmake/Common/StripUnsharedCode.cmake
new file mode 100644
index 0000000000..a2df391f78
--- /dev/null
+++ b/cmake/Common/StripUnsharedCode.cmake
@@ -0,0 +1,40 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# A CMake script to strip that part of an executable which is not meant to be
+# shared among distinct binaries (code reuse). Only used by GNUARM tool chain.
+#
+# INPUT parameters:
+# SHARED_SYMBOLS_FILE - File which contains the list of shared symbols.
+# EXECUTABLE_TO_STRIP - A copy of the original executable, which contains the sharable code.
+# From this copy of the executable the unshared code and symbols
+# are removed.
+#
+# OUTPUTS produced by this script:
+# - EXECUTABLE_TO_STRIP - Output file (stripped) has the same name as input file.
+
+find_program(GNUARM_STRIP arm-none-eabi-strip)
+if (GNUARM_STRIP STREQUAL "GNUARM_STRIP-NOTFOUND")
+ message(FATAL_ERROR "StripUnsharedCode.cmake: mandatory tool '${GNUARM_STRIP}' is missing.")
+endif()
+
+# Want to strip all unwanted symbols in one go, so concatenate those which must be kept
+file(STRINGS ${SHARED_SYMBOLS_FILE} SHARED_SYMBOL_NAME)
+foreach(_SYMBOL IN LISTS SHARED_SYMBOL_NAME)
+ list(APPEND ARGUMENT "-K${_SYMBOL}")
+endforeach()
+
+execute_process(COMMAND ${GNUARM_STRIP} ${ARGUMENT} ${EXECUTABLE_TO_STRIP}
+ TIMEOUT 120
+ OUTPUT_VARIABLE _RES
+ ERROR_VARIABLE _RES
+ RESULT_VARIABLE _STATUS_CODE
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+if (_STATUS_CODE GREATER 0)
+ message(FATAL_ERROR "ERROR: Failed to execute ${GNUARM_STRIP} ${_RES}")
+endif()
diff --git a/cmake/Common/WeakenSymbols.cmake b/cmake/Common/WeakenSymbols.cmake
new file mode 100644
index 0000000000..0ae53d3ac9
--- /dev/null
+++ b/cmake/Common/WeakenSymbols.cmake
@@ -0,0 +1,77 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# A CMake script to weaken identical symbols in the target linked libraries to avoid
+# symbol collision at linking time between shared code and other libraries.
+# i.e.: Shared cryptographic code between MCUBoot and secure runtime firmware.
+#
+# INPUT parameters:
+# LIB_LIST - List of all libraries which are linked to the target, and are using
+# the shared code.
+# SHARED_CODE_PATH - The location of the shared code. It could be outside of TF-M repository.
+#
+# OUTPUTS produced by this script:
+# The libraries might be modified by this script, if they contain the same symbols
+# as the shared code.
+
+# TODO: Library search path is modified manually to include path for platform
+# related libraries.
+
+find_program(OBJCOPY arm-none-eabi-objcopy)
+if (OBJCOPY STREQUAL "OBJCOPY-NOTFOUND")
+ message(FATAL_ERROR "WeakenSymbols.cmake: mandatory tool 'arm-none-eabi-objcopy' is missing.")
+endif()
+
+# Macro to collect all libraries where an *.a file is found
+macro(LIBRARY_DIRECTORIES return_list)
+ file(GLOB_RECURSE new_list *.a)
+ set(dir_list "")
+ foreach(file_path ${new_list})
+ get_filename_component(dir_path ${file_path} PATH)
+ set(dir_list ${dir_list} ${dir_path})
+ endforeach()
+ list(REMOVE_DUPLICATES dir_list)
+ set(${return_list} ${dir_list})
+endmacro()
+
+# Create a library search path for static libraries
+LIBRARY_DIRECTORIES(LIBRARY_PATH)
+
+# Workaround to include directories outside of 'secure_fw' folder for platform
+list(APPEND LIBRARY_PATH ${CMAKE_CURRENT_BINARY_DIR}/../platform/ext/accelerator/cc312/crypto_service_cc312 # Musca-B1: libcrypto_service_cc312.a
+ ${CMAKE_CURRENT_BINARY_DIR}/../platform/ext/accelerator
+ ${CMAKE_CURRENT_BINARY_DIR}/../platform
+)
+
+# When invoking the CMake scripts the original list separator(;) is replaced with space.
+# Need to convert back to be able to handle as a list.
+string(REPLACE " " ";" _LIB_LIST ${LIB_LIST})
+
+# Want to weaken all shared symbols in one go, so first concatenate them.
+# There are libraries which might not contain any of these, but it does
+# not cause any issue, the command does not return with error code.
+file(STRINGS ${SHARED_CODE_PATH}/shared_symbols_name.txt SHARED_SYMBOL_NAME)
+foreach(_SYMBOL IN LISTS SHARED_SYMBOL_NAME)
+ list(APPEND ARGUMENT "-W${_SYMBOL}")
+endforeach()
+
+# Iterate over each library and set potentially colliding symbols to be weak
+foreach(LIB IN LISTS _LIB_LIST)
+ find_file(LIB_FULL_PATH "lib${LIB}.a" PATHS ${LIBRARY_PATH} PATH_SUFFIXES Common NO_DEFAULT_PATH)
+ if (NOT ${LIB_FULL_PATH} STREQUAL "LIB_FULL_PATH-NOTFOUND")
+ execute_process(COMMAND ${OBJCOPY} ${ARGUMENT} ${LIB_FULL_PATH}
+ TIMEOUT 120
+ OUTPUT_VARIABLE _RES
+ ERROR_VARIABLE _RES
+ RESULT_VARIABLE _STATUS_CODE
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if (_STATUS_CODE GREATER 0)
+ message(FATAL_ERROR "ERROR: Failed to execute ${OBJCOPY} ${_RES}")
+ endif()
+ endif()
+ unset(LIB_FULL_PATH CACHE)
+endforeach()