diff options
author | Tamas Ban <tamas.ban@arm.com> | 2020-10-26 13:03:13 +0000 |
---|---|---|
committer | Tamas Ban <tamas.ban@arm.com> | 2020-12-17 13:06:19 +0000 |
commit | f8b0b2df5e9b954fd5d59ae95684659e73b38c8c (patch) | |
tree | d76ac5d0545608363ba59aca869bdd6f188357b0 /cmake/Common | |
parent | 73946a89d4e1b839878f0599516dc5ae6e01efe7 (diff) | |
download | trusted-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.cmake | 56 | ||||
-rw-r--r-- | cmake/Common/StripUnsharedCode.cmake | 40 | ||||
-rw-r--r-- | cmake/Common/WeakenSymbols.cmake | 77 |
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() |