build: Add IAR support to Corstone-315

Signed-off-by: Dávid Házi <david.hazi@arm.com>
Change-Id: Id0cc1e1c3a485567e50140968e9c6553f6bbb446
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()