Skip to content

Commit 28ba86d

Browse files
tejlmandnashif
authored andcommitted
armclang: armlinker: armlink symbol steering file
This commit introduces armlink steering file. A steering file in armlink allows Zephyr to keep using existing linker symbols defined in ld scripts and used throughout the code tree. The steering file is generated at build time in order to resolve Zephyr linker symbols to their corresponding armlink symbols. As example, Zephyr defines __ramfunc_start which corresponds to the armlink auto defined Image$$ramfunc$$Base symbol. Or __init_PRE_KERNEL_1_start which corresponds to Image$$init_0$$Base. Signed-off-by: Torsten Rasmussen <[email protected]>
1 parent 5dfbd22 commit 28ba86d

File tree

2 files changed

+196
-0
lines changed

2 files changed

+196
-0
lines changed

cmake/linker/armlink/scatter_script.cmake

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,151 @@ cmake_minimum_required(VERSION 3.17)
22

33
set(SORT_TYPE_NAME Lexical)
44

5+
# This function post process the region for easier use.
6+
#
7+
# Tasks:
8+
# - Symbol translation using a steering file is configured.
9+
function(process_region)
10+
cmake_parse_arguments(REGION "" "OBJECT" "" ${ARGN})
11+
12+
process_region_common(${ARGN})
13+
14+
get_property(empty GLOBAL PROPERTY ${REGION_OBJECT}_EMPTY)
15+
if(NOT empty)
16+
# For scatter files we move any system symbols into first non-empty load section.
17+
get_parent(OBJECT ${REGION_OBJECT} PARENT parent TYPE SYSTEM)
18+
get_property(symbols GLOBAL PROPERTY ${parent}_SYMBOLS)
19+
set_property(GLOBAL APPEND PROPERTY ${REGION_OBJECT}_SYMBOLS ${symbols})
20+
set_property(GLOBAL PROPERTY ${parent}_SYMBOLS)
21+
endif()
22+
23+
get_property(sections GLOBAL PROPERTY ${REGION_OBJECT}_SECTION_LIST_ORDERED)
24+
foreach(section ${sections})
25+
26+
get_property(name_clean GLOBAL PROPERTY ${section}_NAME_CLEAN)
27+
get_property(noinput GLOBAL PROPERTY ${section}_NOINPUT)
28+
get_property(type GLOBAL PROPERTY ${section}_TYPE)
29+
30+
get_property(indicies GLOBAL PROPERTY ${section}_SETTINGS_INDICIES)
31+
list(LENGTH indicies length)
32+
foreach(idx ${indicies})
33+
set(steering_postfixes Base Limit)
34+
get_property(symbols GLOBAL PROPERTY ${section}_SETTING_${idx}_SYMBOLS)
35+
get_property(sort GLOBAL PROPERTY ${section}_SETTING_${idx}_SORT)
36+
get_property(offset GLOBAL PROPERTY ${section}_SETTING_${idx}_OFFSET)
37+
if(DEFINED offset)
38+
foreach(symbol ${symbols})
39+
list(POP_FRONT steering_postfixes postfix)
40+
math(EXPR offset_dec "${offset}")
41+
set_property(GLOBAL APPEND PROPERTY SYMBOL_STEERING_C
42+
"Image$$${name_clean}_${offset_dec}$$${postfix}"
43+
)
44+
set_property(GLOBAL APPEND PROPERTY SYMBOL_STEERING_FILE
45+
"RESOLVE ${symbol} AS Image$$${name_clean}_${offset_dec}$$${postfix}\n"
46+
)
47+
endforeach()
48+
elseif(sort)
49+
foreach(symbol ${symbols})
50+
list(POP_FRONT steering_postfixes postfix)
51+
set_property(GLOBAL APPEND PROPERTY SYMBOL_STEERING_C
52+
"Image$$${name_clean}_${idx}$$${postfix}"
53+
)
54+
set_property(GLOBAL APPEND PROPERTY SYMBOL_STEERING_FILE
55+
"RESOLVE ${symbol} AS Image$$${name_clean}_${idx}$$${postfix}\n"
56+
)
57+
endforeach()
58+
elseif(DEFINED symbols AND ${length} EQUAL 1 AND noinput)
59+
set(steering_postfixes Base Limit)
60+
foreach(symbol ${symbols})
61+
list(POP_FRONT steering_postfixes postfix)
62+
set_property(GLOBAL APPEND PROPERTY SYMBOL_STEERING_C
63+
"Image$$${name_clean}$$${postfix}"
64+
)
65+
set_property(GLOBAL APPEND PROPERTY SYMBOL_STEERING_FILE
66+
"RESOLVE ${symbol} AS Image$$${name_clean}$$${postfix}\n"
67+
)
68+
endforeach()
69+
endif()
70+
endforeach()
71+
72+
if("${type}" STREQUAL BSS)
73+
set(ZI "$$ZI")
74+
endif()
75+
76+
# Symbols translation here.
77+
set_property(GLOBAL APPEND PROPERTY SYMBOL_STEERING_C "Image$$${name_clean}${ZI}$$Base")
78+
set_property(GLOBAL APPEND PROPERTY SYMBOL_STEERING_C "Image$$${name_clean}${ZI}$$Length")
79+
set_property(GLOBAL APPEND PROPERTY SYMBOL_STEERING_C "Load$$${name_clean}${ZI}$$Base")
80+
81+
set_property(GLOBAL APPEND PROPERTY SYMBOL_STEERING_FILE
82+
"RESOLVE __${name_clean}_start AS Image$$${name_clean}${ZI}$$Base\n"
83+
"RESOLVE __${name_clean}_load_start AS Load$$${name_clean}${ZI}$$Base\n"
84+
"EXPORT __${name_clean}_start AS __${name_clean}_start\n"
85+
)
86+
87+
get_property(symbol_val GLOBAL PROPERTY SYMBOL_TABLE___${name_clean}_end)
88+
set_property(GLOBAL APPEND PROPERTY SYMBOL_STEERING_C "Image$$${symbol_val}${ZI}$$Limit")
89+
set_property(GLOBAL APPEND PROPERTY SYMBOL_STEERING_FILE
90+
"RESOLVE __${name_clean}_end AS Image$$${symbol_val}${ZI}$$Limit\n"
91+
)
92+
93+
if("${symbol_val}" STREQUAL "${name_clean}")
94+
set_property(GLOBAL APPEND PROPERTY SYMBOL_STEERING_FILE
95+
"RESOLVE __${name_clean}_size AS Image$$${name_clean}${ZI}$$Length\n"
96+
)
97+
else()
98+
create_symbol(OBJECT ${REGION_OBJECT} SYMBOL __${name_clean}_size
99+
EXPR "(ImageLimit(${symbol_val}${ZI}) - ImageBase(${name_clean}${ZI}))"
100+
)
101+
endif()
102+
set(ZI)
103+
104+
endforeach()
105+
106+
get_property(groups GLOBAL PROPERTY ${REGION_OBJECT}_GROUP_LIST_ORDERED)
107+
foreach(group ${groups})
108+
get_property(name GLOBAL PROPERTY ${group}_NAME)
109+
string(TOLOWER ${name} name)
110+
111+
get_objects(LIST sections OBJECT ${group} TYPE SECTION)
112+
list(GET sections 0 section)
113+
get_property(first_section_name GLOBAL PROPERTY ${section}_NAME_CLEAN)
114+
list(POP_BACK sections section)
115+
get_property(last_section_name GLOBAL PROPERTY ${section}_NAME_CLEAN)
116+
117+
# Symbols translation here.
118+
set_property(GLOBAL APPEND PROPERTY SYMBOL_STEERING_C "Image$$${first_section_name}$$Base")
119+
set_property(GLOBAL APPEND PROPERTY SYMBOL_STEERING_C "Load$$${first_section_name}$$Base")
120+
set_property(GLOBAL APPEND PROPERTY SYMBOL_STEERING_C "Image$$${last_section_name}$$Limit")
121+
122+
set_property(GLOBAL APPEND PROPERTY SYMBOL_STEERING_FILE
123+
"RESOLVE __${name}_start AS Image$$${first_section_name}$$Base\n"
124+
"EXPORT __${name}_start AS __${name}_start\n"
125+
"RESOLVE __${name}_load_start AS Load$$${first_section_name}$$Base\n"
126+
"EXPORT __${name}_load_start AS __${name}_load_start\n"
127+
)
128+
129+
set_property(GLOBAL APPEND PROPERTY SYMBOL_STEERING_FILE
130+
"RESOLVE __${name}_end AS Image$$${last_section_name}$$Limit\n"
131+
)
132+
133+
create_symbol(OBJECT ${REGION_OBJECT} SYMBOL __${name}_size
134+
EXPR "(ImageLimit(${last_section_name}) - ImageBase(${first_section_name}))"
135+
)
136+
endforeach()
137+
138+
get_property(symbols GLOBAL PROPERTY ${REGION_OBJECT}_SYMBOLS)
139+
foreach(symbol ${symbols})
140+
get_property(name GLOBAL PROPERTY ${symbol}_NAME)
141+
set_property(GLOBAL APPEND PROPERTY SYMBOL_STEERING_C "Image$$${name}$$Base")
142+
143+
set_property(GLOBAL APPEND PROPERTY SYMBOL_STEERING_FILE
144+
"RESOLVE ${name} AS Image$$${name}$$Base\n"
145+
)
146+
endforeach()
147+
148+
endfunction()
149+
5150
#
6151
# String functions - start
7152
#
@@ -230,6 +375,10 @@ function(section_to_string)
230375
set(TEMP "${TEMP}")
231376
# ToDo: add patterns here.
232377

378+
if("${type}" STREQUAL BSS)
379+
set(ZI "$$ZI")
380+
endif()
381+
233382
set(TEMP "${TEMP}\n }")
234383

235384
set(${STRING_STRING} "${${STRING_STRING}}\n${TEMP}\n" PARENT_SCOPE)
@@ -268,3 +417,28 @@ function(symbol_to_string)
268417
endfunction()
269418

270419
include(${CMAKE_CURRENT_LIST_DIR}/../linker_script_common.cmake)
420+
421+
if(DEFINED STEERING_C)
422+
get_property(symbols_c GLOBAL PROPERTY SYMBOL_STEERING_C)
423+
file(WRITE ${STEERING_C} "/* AUTO-GENERATED - Do not modify\n")
424+
file(APPEND ${STEERING_C} " * AUTO-GENERATED - All changes will be lost\n")
425+
file(APPEND ${STEERING_C} " */\n")
426+
foreach(symbol ${symbols_c})
427+
file(APPEND ${STEERING_C} "extern char ${symbol}[];\n")
428+
endforeach()
429+
430+
file(APPEND ${STEERING_C} "\nint __armlink_symbol_steering(void) {\n")
431+
file(APPEND ${STEERING_C} "\treturn\n")
432+
foreach(symbol ${symbols_c})
433+
file(APPEND ${STEERING_C} "\t\t${OPERAND} (int)${symbol}\n")
434+
set(OPERAND "&")
435+
endforeach()
436+
file(APPEND ${STEERING_C} "\t;\n}\n")
437+
endif()
438+
439+
if(DEFINED STEERING_FILE)
440+
get_property(steering_content GLOBAL PROPERTY SYMBOL_STEERING_FILE)
441+
file(WRITE ${STEERING_FILE} "; AUTO-GENERATED - Do not modify\n")
442+
file(APPEND ${STEERING_FILE} "; AUTO-GENERATED - All changes will be lost\n")
443+
file(APPEND ${STEERING_FILE} ${steering_content})
444+
endif()

cmake/linker/armlink/target.cmake

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,25 @@ macro(toolchain_ld_baremetal)
2626
endmacro()
2727

2828
macro(configure_linker_script linker_script_gen linker_pass_define)
29+
set(STEERING_FILE)
30+
set(STEERING_C)
31+
set(STEERING_FILE_ARG)
32+
set(STEERING_C_ARG)
33+
2934
if("${linker_pass_define}" STREQUAL "-DLINKER_ZEPHYR_PREBUILT")
3035
set(PASS 1)
3136
elseif("${linker_pass_define}" STREQUAL "-DLINKER_ZEPHYR_FINAL;-DLINKER_PASS2")
3237
set(PASS 2)
38+
set(STEERING_FILE ${CMAKE_CURRENT_BINARY_DIR}/armlink_symbol_steering.steer)
39+
set(STEERING_C ${CMAKE_CURRENT_BINARY_DIR}/armlink_symbol_steering.c)
40+
set(STEERING_FILE_ARG "-DSTEERING_FILE=${STEERING_FILE}")
41+
set(STEERING_C_ARG "-DSTEERING_C=${STEERING_C}")
3342
endif()
3443

3544
add_custom_command(
3645
OUTPUT ${linker_script_gen}
46+
${STEERING_FILE}
47+
${STEERING_C}
3748
COMMAND ${CMAKE_COMMAND}
3849
-DPASS=${PASS}
3950
-DMEMORY_REGIONS="$<TARGET_PROPERTY:linker,MEMORY_REGIONS>"
@@ -46,6 +57,11 @@ macro(configure_linker_script linker_script_gen linker_pass_define)
4657
-DOUT_FILE=${CMAKE_CURRENT_BINARY_DIR}/${linker_script_gen}
4758
-P ${ZEPHYR_BASE}/cmake/linker/armlink/scatter_script.cmake
4859
)
60+
61+
if("${PASS}" EQUAL 2)
62+
add_library(armlink_steering OBJECT ${STEERING_C})
63+
target_link_libraries(armlink_steering PRIVATE zephyr_interface)
64+
endif()
4965
endmacro()
5066

5167
function(toolchain_ld_link_elf)
@@ -78,6 +94,12 @@ function(toolchain_ld_link_elf)
7894
--entry=$<TARGET_PROPERTY:linker,ENTRY>
7995
"--keep=\"*.o(.init_*)\""
8096
"--keep=\"*.o(.device_*)\""
97+
$<TARGET_OBJECTS:armlink_steering>
98+
--edit=${CMAKE_CURRENT_BINARY_DIR}/armlink_symbol_steering.steer
99+
# Resolving symbols using generated steering files will emit the warnings 6331 and 6332.
100+
# Steering files are used because we want to be able to use `__device_end` instead of `Image$$device$$Limit`.
101+
# Thus silence those two warnings.
102+
--diag_suppress=6331,6332
81103
# The scatter file is generated, and thus sometimes input sections are specified
82104
# even though there will be no such sections found in the libraries linked.
83105
--diag_suppress=6314

0 commit comments

Comments
 (0)