build: Add IAR support to Corstone-315
Signed-off-by: Dávid Házi <david.hazi@arm.com>
Change-Id: Id0cc1e1c3a485567e50140968e9c6553f6bbb446
diff --git a/bl1/bl1_1/shared_lib/CMakeLists.txt b/bl1/bl1_1/shared_lib/CMakeLists.txt
index ff1d99e..1e4cda4 100644
--- a/bl1/bl1_1/shared_lib/CMakeLists.txt
+++ b/bl1/bl1_1/shared_lib/CMakeLists.txt
@@ -47,7 +47,8 @@
target_compile_options(bl1_1_shared_lib_interface
INTERFACE
#Prevents warnings caused by C99 static assert workaround
- -Wno-unused-local-typedefs
+ $<$<C_COMPILER_ID:GNU>:-Wno-unused-local-typedefs>
+ $<$<C_COMPILER_ID:ARMClang>:-Wno-unused-local-typedefs>
)
target_compile_definitions(bl1_1_shared_lib_interface
diff --git a/platform/ext/common/boot_hal_bl1_1.c b/platform/ext/common/boot_hal_bl1_1.c
index 5f5c738..8bc5273 100644
--- a/platform/ext/common/boot_hal_bl1_1.c
+++ b/platform/ext/common/boot_hal_bl1_1.c
@@ -36,11 +36,6 @@
#endif /* defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__) \
|| defined(__ARM_ARCH_8_1M_MAIN__) */
-REGION_DECLARE(Image$$, BL1_1_ER_DATA_START, $$Base)[];
-REGION_DECLARE(Image$$, BL1_1_ER_DATA_LIMIT, $$Base)[];
-REGION_DECLARE(Image$$, BL1_2_ER_DATA_START, $$Base)[];
-REGION_DECLARE(Image$$, BL1_2_ER_DATA_LIMIT, $$Base)[];
-
/*!
* \brief Chain-loading the next image in the boot sequence.
*
@@ -53,9 +48,6 @@
* - There are secrets in the memory: KDF parameter, symmetric key,
* manufacturer sensitive code/data, etc.
*/
-#if defined(__ICCARM__)
-#pragma required = boot_clear_ram_area
-#endif
__WEAK __attribute__((naked)) void boot_jump_to_next_image(uint32_t reset_handler_addr)
{
diff --git a/platform/ext/common/boot_hal_bl1_2.c b/platform/ext/common/boot_hal_bl1_2.c
index d8d022f..f237cd2 100644
--- a/platform/ext/common/boot_hal_bl1_2.c
+++ b/platform/ext/common/boot_hal_bl1_2.c
@@ -35,11 +35,17 @@
#endif /* defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__) \
|| defined(__ARM_ARCH_8_1M_MAIN__) */
+#if defined(__ICCARM__)
+REGION_DECLARE(Image$$, BL1_1_ER_DATA, $$Base)[];
+REGION_DECLARE(Image$$, BL1_1_ER_DATA, $$Limit)[];
+REGION_DECLARE(Image$$, BL1_2_ER_DATA, $$Base)[];
+REGION_DECLARE(Image$$, BL1_2_ER_DATA, $$Limit)[];
+#else
REGION_DECLARE(Image$$, BL1_1_ER_DATA_START, $$Base)[];
REGION_DECLARE(Image$$, BL1_1_ER_DATA_LIMIT, $$Base)[];
REGION_DECLARE(Image$$, BL1_2_ER_DATA_START, $$Base)[];
REGION_DECLARE(Image$$, BL1_2_ER_DATA_LIMIT, $$Base)[];
-
+#endif
/* Erase both BL1 data sections at the end of BL1_2
* At the point this function is called, the SP has been set to the next image's
* initial SP and this function itself will wipe the executing image's data
@@ -54,8 +60,13 @@
#endif
/* Clear the entire BL1_1 data section */
"movs r0, #0 \n"
+#if defined(__ICCARM__)
+ "ldr r1, =BL1_1_ER_DATA$$Base \n"
+ "ldr r2, =BL1_1_ER_DATA$$Limit \n"
+#else
"ldr r1, =Image$$BL1_1_ER_DATA_START$$Base \n"
"ldr r2, =Image$$BL1_1_ER_DATA_LIMIT$$Base \n"
+#endif
"subs r2, r2, r1 \n"
"Loop_1: \n"
"subs r2, #4 \n"
@@ -65,8 +76,13 @@
"Clear_done_1: \n"
/* Clear the entire BL1_2 data section */
"movs r0, #0 \n"
+#if defined(__ICCARM__)
+ "ldr r1, =BL1_2_ER_DATA$$Base \n"
+ "ldr r2, =BL1_2_ER_DATA$$Limit \n"
+#else
"ldr r1, =Image$$BL1_2_ER_DATA_START$$Base \n"
"ldr r2, =Image$$BL1_2_ER_DATA_LIMIT$$Base \n"
+#endif
"subs r2, r2, r1 \n"
"Loop_2: \n"
"subs r2, #4 \n"
diff --git a/platform/ext/target/arm/mps4/corstone315/CMakeLists.txt b/platform/ext/target/arm/mps4/corstone315/CMakeLists.txt
index 481ec50..7a9f807 100644
--- a/platform/ext/target/arm/mps4/corstone315/CMakeLists.txt
+++ b/platform/ext/target/arm/mps4/corstone315/CMakeLists.txt
@@ -339,13 +339,13 @@
target_add_scatter_file(bl1_1
$<$<C_COMPILER_ID:ARMClang>:${CMAKE_CURRENT_SOURCE_DIR}/device/source/armclang/corstone315_bl1_1.sct>
$<$<C_COMPILER_ID:GNU>:${CMAKE_CURRENT_SOURCE_DIR}/device/source/gcc/corstone315_bl1_1.ld>
+ $<$<C_COMPILER_ID:IAR>:${CMAKE_CURRENT_SOURCE_DIR}/device/source/iar/corstone315_bl1_1.icf>
)
target_sources(platform_bl1_1
PRIVATE
nv_counters.c
otp_lcm.c
- bl1/boot_hal_bl1_1.c
cmsis_drivers/Driver_USART.c
device/source/system_core_init.c
device/source/startup_corstone315.c
@@ -365,22 +365,36 @@
cmsis_includes_bl1
)
+# If this is not added to the bl1_1 it will not correctly override the weak
+# functions and will instead be discarded as they are not in use.
+target_sources(bl1_1
+ PUBLIC
+ bl1/boot_hal_bl1_1.c
+)
+
#========================= Platform BL1_2 =====================================#
target_add_scatter_file(bl1_2
$<$<C_COMPILER_ID:ARMClang>:${CMAKE_CURRENT_SOURCE_DIR}/device/source/armclang/corstone315_bl1_2.sct>
$<$<C_COMPILER_ID:GNU>:${CMAKE_CURRENT_SOURCE_DIR}/device/source/gcc/corstone315_bl1_2.ld>
+ $<$<C_COMPILER_ID:IAR>:${CMAKE_CURRENT_SOURCE_DIR}/device/source/iar/corstone315_bl1_2.icf>
)
target_sources(platform_bl1_2
PUBLIC
device/source/startup_corstone315.c
PRIVATE
- bl1/boot_hal_bl1_2.c
${PLATFORM_DIR}/ext/target/arm/drivers/mpu/armv8m/mpu_armv8m_drv.c
)
+# If this is not added to the bl1_2 it will not correctly override the weak
+# functions and will instead be discarded as they are not in use.
+target_sources(bl1_2
+ PRIVATE
+ bl1/boot_hal_bl1_2.c
+)
+
target_compile_definitions(platform_bl1_2
PUBLIC
$<$<AND:$<BOOL:${CONFIG_TFM_BOOT_STORE_MEASUREMENTS}>,$<BOOL:${TFM_PARTITION_MEASURED_BOOT}>>:MEASURED_BOOT_API>
diff --git a/platform/ext/target/arm/mps4/corstone315/device/source/iar/corstone315_bl1_1.icf b/platform/ext/target/arm/mps4/corstone315/device/source/iar/corstone315_bl1_1.icf
new file mode 100644
index 0000000..2d424c1
--- /dev/null
+++ b/platform/ext/target/arm/mps4/corstone315/device/source/iar/corstone315_bl1_1.icf
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/* Linker script to configure memory regions. */
+/* This file will be run trough the pre-processor. */
+
+#include "region_defs.h"
+
+do not initialize { section .noinit };
+initialize by copy { readwrite };
+
+define block ER_CODE with fixed order, alignment = 8, size = BL1_1_CODE_SIZE {
+ section .intvec,
+ readonly
+};
+define block LR_CODE with fixed order {block ER_CODE};
+place at address BL1_1_CODE_START {block LR_CODE};
+
+define block TFM_SHARED_DATA with alignment = 32, size = BOOT_TFM_SHARED_DATA_SIZE { };
+define block ER_DATA with alignment = 32 {readwrite};
+define block CSTACK with alignment = 32, size = BL1_1_MSP_STACK_SIZE { };
+define block ARM_LIB_STACK with alignment = 32, size = BL1_1_MSP_STACK_SIZE { };
+define block HEAP with alignment = 8, size = BL1_1_HEAP_SIZE { };
+define block ARM_LIB_HEAP with alignment = 8, size = BL1_1_HEAP_SIZE { };
+define block SRAM_WATERMARK with size = 0 { };
+define overlay HEAP_OVL {block HEAP};
+define overlay HEAP_OVL {block ARM_LIB_HEAP};
+define overlay STACK_OVL {block CSTACK};
+define overlay STACK_OVL {block ARM_LIB_STACK};
+keep {block TFM_SHARED_DATA,
+ block CSTACK,
+ block ARM_LIB_STACK,
+ block HEAP,
+ block ARM_LIB_HEAP,
+ block SRAM_WATERMARK,
+};
+
+if (isdefinedsymbol(__USE_DLIB_PERTHREAD))
+{
+ // Required in a multi-threaded application
+ initialize by copy with packing = none { section __DLIB_PERTHREAD };
+}
+
+define block BL1_1_ER_DATA with fixed order, maximum size = BL1_1_DATA_SIZE {
+ block TFM_SHARED_DATA,
+ block ER_DATA,
+ overlay STACK_OVL,
+ overlay HEAP_OVL,
+ block SRAM_WATERMARK,
+};
+place at address BL1_1_DATA_START {block BL1_1_ER_DATA};
+
+define block BL1_2_ER_DATA with fixed order, size = BL1_2_DATA_SIZE {
+};
+place at address BL1_2_DATA_START {block BL1_2_ER_DATA};
+keep {block BL1_2_ER_DATA,
+};
diff --git a/platform/ext/target/arm/mps4/corstone315/device/source/iar/corstone315_bl1_2.icf b/platform/ext/target/arm/mps4/corstone315/device/source/iar/corstone315_bl1_2.icf
new file mode 100644
index 0000000..f2a86a7
--- /dev/null
+++ b/platform/ext/target/arm/mps4/corstone315/device/source/iar/corstone315_bl1_2.icf
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/* Linker script to configure memory regions. */
+/* This file will be run trough the pre-processor. */
+
+#include "region_defs.h"
+
+do not initialize { section .noinit };
+initialize by copy { readwrite };
+
+define block ER_CODE with fixed order, alignment = 8, size = BL1_2_CODE_SIZE {
+ section .intvec,
+ readonly
+};
+define block LR_CODE with fixed order {block ER_CODE};
+place at address BL1_2_CODE_START {block LR_CODE};
+
+define block TFM_SHARED_DATA with alignment = 32, size = BOOT_TFM_SHARED_DATA_SIZE { };
+define block ER_DATA with alignment = 32 {readwrite};
+define block CSTACK with alignment = 32, size = BL1_2_MSP_STACK_SIZE { };
+define block ARM_LIB_STACK with alignment = 32, size = BL1_2_MSP_STACK_SIZE { };
+define block HEAP with alignment = 8, size = BL1_2_HEAP_SIZE { };
+define block ARM_LIB_HEAP with alignment = 8, size = BL1_2_HEAP_SIZE { };
+define block SRAM_WATERMARK with size = 0 { };
+define overlay HEAP_OVL {block HEAP};
+define overlay HEAP_OVL {block ARM_LIB_HEAP};
+define overlay STACK_OVL {block CSTACK};
+define overlay STACK_OVL {block ARM_LIB_STACK};
+keep {block TFM_SHARED_DATA,
+ block CSTACK,
+ block ARM_LIB_STACK,
+ block HEAP,
+ block ARM_LIB_HEAP,
+ block SRAM_WATERMARK,
+};
+
+if (isdefinedsymbol(__USE_DLIB_PERTHREAD))
+{
+ // Required in a multi-threaded application
+ initialize by copy with packing = none { section __DLIB_PERTHREAD };
+}
+
+define block BL1_2_ER_DATA with fixed order, maximum size = BL1_2_DATA_SIZE {
+ block TFM_SHARED_DATA,
+ block ER_DATA,
+ overlay STACK_OVL,
+ overlay HEAP_OVL,
+ block SRAM_WATERMARK,
+};
+place at address BL1_2_DATA_START {block BL1_2_ER_DATA};
+
+define block BL1_1_ER_DATA with fixed order, size = BL1_1_DATA_SIZE {
+};
+place at address BL1_1_DATA_START {block BL1_1_ER_DATA};
+keep {block BL1_1_ER_DATA,
+};
diff --git a/platform/ext/target/arm/mps4/corstone315/provisioning/bundle_cm/CMakeLists.txt b/platform/ext/target/arm/mps4/corstone315/provisioning/bundle_cm/CMakeLists.txt
index 5217c78..2861449 100644
--- a/platform/ext/target/arm/mps4/corstone315/provisioning/bundle_cm/CMakeLists.txt
+++ b/platform/ext/target/arm/mps4/corstone315/provisioning/bundle_cm/CMakeLists.txt
@@ -30,6 +30,7 @@
target_add_scatter_file(cm_provisioning_bundle
$<$<C_COMPILER_ID:ARMClang>:${CMAKE_CURRENT_SOURCE_DIR}/../bundle_common/provisioning_bundle.sct>
$<$<C_COMPILER_ID:GNU>:${CMAKE_CURRENT_SOURCE_DIR}/../bundle_common/provisioning_bundle.ld>
+ $<$<C_COMPILER_ID:IAR>:${CMAKE_CURRENT_SOURCE_DIR}/../bundle_common/provisioning_bundle.icf>
)
target_link_options(cm_provisioning_bundle
@@ -95,13 +96,8 @@
DEPENDS $<TARGET_FILE_DIR:bl2>/bl2_signed_hash.bin
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/../create_provisioning_bundle.py
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE_DIR:cm_provisioning_bundle>/cm_provisioning_bundle.axf cm_provisioning_bundle.axf
- COMMAND ${CMAKE_OBJCOPY} $<TARGET_FILE_DIR:cm_provisioning_bundle>/cm_provisioning_bundle.axf
- --dump-section CODE=cm_provisioning_code.bin
- COMMAND ${CMAKE_OBJCOPY} $<TARGET_FILE_DIR:cm_provisioning_bundle>/cm_provisioning_bundle.axf
- --dump-section VALUES=cm_provisioning_values.bin
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../create_provisioning_bundle.py
- --provisioning_code cm_provisioning_code.bin
- --provisioning_values cm_provisioning_values.bin
+ --provisioning_bundle_axf $<TARGET_FILE_DIR:cm_provisioning_bundle>/cm_provisioning_bundle.axf
--bl1_2_padded_hash_input_file $<TARGET_FILE_DIR:bl1_2>/bl1_2_padded_hash.bin
--bl1_2_input_file $<TARGET_FILE_DIR:bl1_2>/bl1_2_padded.bin
--bl2_signed_hash_input_file $<TARGET_FILE_DIR:bl2>/bl2_signed_hash.bin
diff --git a/platform/ext/target/arm/mps4/corstone315/provisioning/bundle_common/provisioning_bundle.icf b/platform/ext/target/arm/mps4/corstone315/provisioning/bundle_common/provisioning_bundle.icf
new file mode 100644
index 0000000..6e061a0
--- /dev/null
+++ b/platform/ext/target/arm/mps4/corstone315/provisioning/bundle_common/provisioning_bundle.icf
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "region_defs.h"
+
+do not initialize { section .noinit };
+do not initialize { readwrite };
+
+define block VALUES with fixed order, maximum size = PROVISIONING_BUNDLE_VALUES_SIZE {
+ ro object *provisioning_data.o
+};
+"VALUES": place at address PROVISIONING_BUNDLE_VALUES_START { block VALUES };
+
+define ram region DATA = [from PROVISIONING_BUNDLE_DATA_START size PROVISIONING_BUNDLE_DATA_SIZE];
+
+define block RW_DATA {
+ rw data
+};
+"RW_DATA": place at start of DATA { block RW_DATA };
+
+define block RO_DATA {
+ ro data
+} except {
+ ro object *provisioning_data.o
+};
+"RO_DATA": place in DATA { block RO_DATA };
+
+define block BSS_DATA {
+ zi section .bss
+};
+"BSS_DATA": place in DATA { block BSS_DATA };
+
+define block CODE with fixed order, alignment = 4, maximum size = PROVISIONING_BUNDLE_CODE_SIZE {
+ ro section DO_PROVISION,
+ ro code,
+};
+"CODE": place at address PROVISIONING_BUNDLE_CODE_START { block CODE };
diff --git a/platform/ext/target/arm/mps4/corstone315/provisioning/bundle_dm/CMakeLists.txt b/platform/ext/target/arm/mps4/corstone315/provisioning/bundle_dm/CMakeLists.txt
index 43219ae..4dcf152 100644
--- a/platform/ext/target/arm/mps4/corstone315/provisioning/bundle_dm/CMakeLists.txt
+++ b/platform/ext/target/arm/mps4/corstone315/provisioning/bundle_dm/CMakeLists.txt
@@ -33,6 +33,7 @@
target_add_scatter_file(dm_provisioning_bundle
$<$<C_COMPILER_ID:ARMClang>:${CMAKE_CURRENT_SOURCE_DIR}/../bundle_common/provisioning_bundle.sct>
$<$<C_COMPILER_ID:GNU>:${CMAKE_CURRENT_SOURCE_DIR}/../bundle_common/provisioning_bundle.ld>
+ $<$<C_COMPILER_ID:IAR>:${CMAKE_CURRENT_SOURCE_DIR}/../bundle_common/provisioning_bundle.icf>
)
target_link_options(dm_provisioning_bundle
@@ -108,13 +109,8 @@
DEPENDS $<TARGET_FILE_DIR:bl1_2>/bl1_2_padded.bin
bl1_2_padded_bin bl2_signed_bin dm_provisioning_bundle
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/../create_provisioning_bundle.py
- COMMAND ${CMAKE_OBJCOPY} $<TARGET_FILE_DIR:dm_provisioning_bundle>/dm_provisioning_bundle.axf
- --dump-section CODE=dm_provisioning_code.bin
- COMMAND ${CMAKE_OBJCOPY} $<TARGET_FILE_DIR:dm_provisioning_bundle>/dm_provisioning_bundle.axf
- --dump-section VALUES=dm_provisioning_values.bin
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../create_provisioning_bundle.py
- --provisioning_code dm_provisioning_code.bin
- --provisioning_values dm_provisioning_values.bin
+ --provisioning_bundle_axf $<TARGET_FILE_DIR:dm_provisioning_bundle>/dm_provisioning_bundle.axf
--bundle_output_file dm_provisioning_bundle.bin
--magic "0xBEEFFEED"
--tp_mode ${TP_MODE}
diff --git a/platform/ext/target/arm/mps4/corstone315/provisioning/create_provisioning_bundle.py b/platform/ext/target/arm/mps4/corstone315/provisioning/create_provisioning_bundle.py
index f6efad1..01aa5e2 100755
--- a/platform/ext/target/arm/mps4/corstone315/provisioning/create_provisioning_bundle.py
+++ b/platform/ext/target/arm/mps4/corstone315/provisioning/create_provisioning_bundle.py
@@ -8,6 +8,7 @@
import argparse
import struct
import secrets
+from elftools.elf.elffile import ELFFile
def struct_pack(objects, pad_to=0):
defstring = "<"
@@ -24,10 +25,7 @@
return (bytes(struct.pack(defstring, *objects)))
parser = argparse.ArgumentParser()
-parser.add_argument("--provisioning_code", help="the input provisioning code", required=True)
-parser.add_argument("--provisioning_rwdata", help="the input provisioning rwdata", required=False)
-parser.add_argument("--provisioning_rodata", help="the input provisioning rodata", required=False)
-parser.add_argument("--provisioning_values", help="the input provisioning values", required=True)
+parser.add_argument("--provisioning_bundle_axf", help="the input provisioning bundle elf/axf", required=True)
parser.add_argument("--magic", help="the magic constant to insert at the start and end", required=True)
parser.add_argument("--bl1_2_padded_hash_input_file", help="the hash of the final bl1_2 image", required=False)
parser.add_argument("--bl2_signed_hash_input_file", help="the hash of the final bl2 image", required=False)
@@ -43,23 +41,34 @@
args = parser.parse_args()
-with open(args.provisioning_code, "rb") as in_file:
- code = in_file.read()
+elffile = ELFFile(open(args.provisioning_bundle_axf, 'rb'))
-if args.provisioning_rwdata:
- with open(args.provisioning_rwdata, "rb") as in_file:
- rwdata = in_file.read()
+values_section = elffile.get_section_by_name("VALUES")
+rodata_section = elffile.get_section_by_name("RO_DATA")
+rwdata_section = elffile.get_section_by_name("RW_DATA")
+code_section = elffile.get_section_by_name("CODE")
+
+if code_section is not None:
+ code = code_section.data()
+else:
+ print("provisioning_bundle's code sections is mandatory")
+ exit(1)
+
+if rwdata_section is not None:
+ rwdata = rwdata_section.data()
else:
rwdata = bytes(0)
-if args.provisioning_rodata:
- with open(args.provisioning_rodata, "rb") as in_file:
- rodata = in_file.read()
+if rodata_section is not None:
+ rodata = rodata_section.data()
else:
rodata = bytes(0)
-with open(args.provisioning_values, "rb") as in_file:
- values = in_file.read()
+if values_section is not None:
+ values = values_section.data()
+else:
+ print("provisioning_bundle's values sections is mandatory")
+ exit(1)
with open(args.key_file, "rb") as in_file:
input_key = in_file.read()
diff --git a/toolchain_IARARM.cmake b/toolchain_IARARM.cmake
index 46e8556..949b737 100644
--- a/toolchain_IARARM.cmake
+++ b/toolchain_IARARM.cmake
@@ -1,6 +1,6 @@
#-------------------------------------------------------------------------------
# Copyright (c) 2020, IAR Systems AB. All rights reserved.
-# Copyright (c) 2020-2023, Arm Limited. All rights reserved.
+# Copyright (c) 2020-2024, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -58,7 +58,7 @@
--silent
--semihosting
--redirect __write=__write_buffered
- --diag_suppress=lp005
+ --diag_suppress=lp005,Lp023
"SHELL:--fpu none"
)
endmacro()
@@ -200,6 +200,58 @@
)
endmacro()
+macro(target_share_symbols target)
+ get_target_property(TARGET_TYPE ${target} TYPE)
+ if (NOT TARGET_TYPE STREQUAL "EXECUTABLE")
+ message(FATAL_ERROR "${target} is not an executable. Symbols cannot be shared from libraries.")
+ endif()
+
+ foreach(symbol_file ${ARGN})
+ FILE(STRINGS ${symbol_file} SYMBOLS
+ LENGTH_MINIMUM 1
+ )
+ list(APPEND KEEP_SYMBOL_LIST ${SYMBOLS})
+ endforeach()
+
+ set(IAR_STEERING_FILE ${KEEP_SYMBOL_LIST})
+
+ list(TRANSFORM IAR_STEERING_FILE PREPEND "show ")
+ list(TRANSFORM IAR_STEERING_FILE APPEND " \n")
+ list(INSERT IAR_STEERING_FILE 0 "hide *\n")
+ string(REPLACE ";" "" IAR_STEERING_FILE ${IAR_STEERING_FILE})
+ file( GENERATE OUTPUT "$<TARGET_FILE_DIR:${target}>/iar_steering_file" CONTENT "${IAR_STEERING_FILE}")
+
+ add_custom_command(
+ TARGET ${target}
+ POST_BUILD
+ COMMAND ${CMAKE_IAR_SYMEXPORT}
+ ARGS --edit $<TARGET_FILE_DIR:${target}>/iar_steering_file $<TARGET_FILE:${target}> $<TARGET_FILE_DIR:${target}>/${target}${CODE_SHARING_OUTPUT_FILE_SUFFIX}
+ )
+
+ # Force the target to not remove the symbols if they're unused.
+ list(TRANSFORM KEEP_SYMBOL_LIST PREPEND --keep=)
+ target_link_options(${target}
+ PRIVATE
+ ${KEEP_SYMBOL_LIST}
+ )
+endmacro()
+
+macro(target_link_shared_code target)
+ get_target_property(TARGET_SOURCE_DIR ${target} SOURCE_DIR)
+
+ foreach(symbol_provider ${ARGN})
+ if (TARGET ${symbol_provider})
+ get_target_property(SYMBOL_PROVIDER_TYPE ${symbol_provider} TYPE)
+ if (NOT SYMBOL_PROVIDER_TYPE STREQUAL "EXECUTABLE")
+ message(FATAL_ERROR "${symbol_provider} is not an executable. Symbols cannot be shared from libraries.")
+ endif()
+ endif()
+
+ add_dependencies(${target} ${symbol_provider})
+ target_link_options(${target} PRIVATE LINKER:$<TARGET_FILE_DIR:${symbol_provider}>/${symbol_provider}${CODE_SHARING_INPUT_FILE_SUFFIX})
+ endforeach()
+endmacro()
+
macro(compiler_create_shared_code TARGET SHARED_SYMBOL_TEMPLATE)
message(FATAL_ERROR "Code sharing support is not implemented by IAR.")
endmacro()