linker_script_common.cmake 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673
  1. #
  2. # Create functions - start
  3. #
  4. function(create_system)
  5. cmake_parse_arguments(OBJECT "" "ENTRY;FORMAT;NAME;OBJECT" "" ${ARGN})
  6. set_property(GLOBAL PROPERTY SYSTEM_${OBJECT_NAME} TRUE)
  7. set_property(GLOBAL PROPERTY SYSTEM_${OBJECT_NAME}_OBJ_TYPE SYSTEM)
  8. set_property(GLOBAL PROPERTY SYSTEM_${OBJECT_NAME}_NAME ${OBJECT_NAME})
  9. set_property(GLOBAL PROPERTY SYSTEM_${OBJECT_NAME}_FORMAT ${OBJECT_FORMAT})
  10. set_property(GLOBAL PROPERTY SYSTEM_${OBJECT_NAME}_ENTRY ${OBJECT_ENTRY})
  11. set(${OBJECT_OBJECT} SYSTEM_${OBJECT_NAME} PARENT_SCOPE)
  12. endfunction()
  13. function(create_region)
  14. cmake_parse_arguments(OBJECT "" "NAME;OBJECT;SIZE;START;FLAGS" "" ${ARGN})
  15. if(DEFINED OBJECT_SIZE)
  16. if(${OBJECT_SIZE} MATCHES "^([0-9]*)[kK]$")
  17. math(EXPR OBJECT_SIZE "1024 * ${CMAKE_MATCH_1}" OUTPUT_FORMAT HEXADECIMAL)
  18. elseif(${OBJECT_SIZE} MATCHES "^([0-9]*)[mM]$")
  19. math(EXPR OBJECT_SIZE "1024 * 1024 * ${CMAKE_MATCH_1}" OUTPUT_FORMAT HEXADECIMAL)
  20. elseif(NOT (${OBJECT_SIZE} MATCHES "^([0-9]*)$" OR ${OBJECT_SIZE} MATCHES "^0x([0-9a-fA-F]*)$"))
  21. message(FATAL_ERROR "SIZE format is unknown.")
  22. endif()
  23. endif()
  24. set_property(GLOBAL PROPERTY REGION_${OBJECT_NAME} TRUE)
  25. set_property(GLOBAL PROPERTY REGION_${OBJECT_NAME}_OBJ_TYPE REGION)
  26. set_property(GLOBAL PROPERTY REGION_${OBJECT_NAME}_NAME ${OBJECT_NAME})
  27. set_property(GLOBAL PROPERTY REGION_${OBJECT_NAME}_ADDRESS ${OBJECT_START})
  28. set_property(GLOBAL PROPERTY REGION_${OBJECT_NAME}_FLAGS ${OBJECT_FLAGS})
  29. set_property(GLOBAL PROPERTY REGION_${OBJECT_NAME}_SIZE ${OBJECT_SIZE})
  30. set(${OBJECT_OBJECT} REGION_${OBJECT_NAME} PARENT_SCOPE)
  31. endfunction()
  32. function(get_parent)
  33. cmake_parse_arguments(GET_PARENT "" "OBJECT;PARENT;TYPE" "" ${ARGN})
  34. get_property(type GLOBAL PROPERTY ${GET_PARENT_OBJECT}_OBJ_TYPE)
  35. if(${type} STREQUAL ${GET_PARENT_TYPE})
  36. # Already the right type, so just set and return.
  37. set(${GET_PARENT_PARENT} ${GET_PARENT_OBJECT} PARENT_SCOPE)
  38. return()
  39. endif()
  40. get_property(parent GLOBAL PROPERTY ${GET_PARENT_OBJECT}_PARENT)
  41. get_property(type GLOBAL PROPERTY ${parent}_OBJ_TYPE)
  42. while(NOT ${type} STREQUAL ${GET_PARENT_TYPE})
  43. get_property(parent GLOBAL PROPERTY ${parent}_PARENT)
  44. get_property(type GLOBAL PROPERTY ${parent}_OBJ_TYPE)
  45. endwhile()
  46. set(${GET_PARENT_PARENT} ${parent} PARENT_SCOPE)
  47. endfunction()
  48. function(create_group)
  49. cmake_parse_arguments(OBJECT "" "GROUP;LMA;NAME;OBJECT;SYMBOL;VMA" "" ${ARGN})
  50. set_property(GLOBAL PROPERTY GROUP_${OBJECT_NAME} TRUE)
  51. set_property(GLOBAL PROPERTY GROUP_${OBJECT_NAME}_OBJ_TYPE GROUP)
  52. set_property(GLOBAL PROPERTY GROUP_${OBJECT_NAME}_NAME ${OBJECT_NAME})
  53. set_property(GLOBAL PROPERTY GROUP_${OBJECT_NAME}_SYMBOL ${OBJECT_SYMBOL})
  54. if(DEFINED OBJECT_GROUP)
  55. find_object(OBJECT parent NAME ${OBJECT_GROUP})
  56. else()
  57. if(DEFINED OBJECT_VMA)
  58. find_object(OBJECT obj NAME ${OBJECT_VMA})
  59. get_parent(OBJECT ${obj} PARENT parent TYPE REGION)
  60. get_property(vma GLOBAL PROPERTY ${parent}_NAME)
  61. set_property(GLOBAL PROPERTY GROUP_${OBJECT_NAME}_VMA ${vma})
  62. endif()
  63. if(DEFINED OBJECT_LMA)
  64. find_object(OBJECT obj NAME ${OBJECT_LMA})
  65. get_parent(OBJECT ${obj} PARENT parent TYPE REGION)
  66. get_property(lma GLOBAL PROPERTY ${parent}_NAME)
  67. set_property(GLOBAL PROPERTY GROUP_${OBJECT_NAME}_LMA ${lma})
  68. endif()
  69. endif()
  70. get_property(GROUP_FLAGS_INHERITED GLOBAL PROPERTY ${parent}_FLAGS)
  71. set_property(GLOBAL PROPERTY GROUP_${OBJECT_NAME}_FLAGS ${GROUP_FLAGS_INHERITED})
  72. set_property(GLOBAL PROPERTY GROUP_${OBJECT_NAME}_PARENT ${parent})
  73. add_group(OBJECT ${parent} GROUP GROUP_${OBJECT_NAME})
  74. set(${OBJECT_OBJECT} GROUP_${OBJECT_NAME} PARENT_SCOPE)
  75. endfunction()
  76. function(create_section)
  77. set(single_args "NAME;ADDRESS;ALIGN_WITH_INPUT;TYPE;ALIGN;ENDALIGN;SUBALIGN;VMA;LMA;NOINPUT;NOINIT;NOSYMBOLS;GROUP;SYSTEM")
  78. set(multi_args "PASS")
  79. cmake_parse_arguments(SECTION "" "${single_args}" "${multi_args}" ${ARGN})
  80. if(DEFINED SECTION_PASS AND NOT "${PASS}" IN_LIST SECTION_PASS)
  81. # This section is not active in this pass, ignore.
  82. return()
  83. endif()
  84. set_property(GLOBAL PROPERTY SECTION_${SECTION_NAME} TRUE)
  85. set_property(GLOBAL PROPERTY SECTION_${SECTION_NAME}_OBJ_TYPE SECTION)
  86. set_property(GLOBAL PROPERTY SECTION_${SECTION_NAME}_NAME ${SECTION_NAME})
  87. set_property(GLOBAL PROPERTY SECTION_${SECTION_NAME}_ADDRESS ${SECTION_ADDRESS})
  88. set_property(GLOBAL PROPERTY SECTION_${SECTION_NAME}_TYPE ${SECTION_TYPE})
  89. set_property(GLOBAL PROPERTY SECTION_${SECTION_NAME}_ALIGN ${SECTION_ALIGN})
  90. set_property(GLOBAL PROPERTY SECTION_${SECTION_NAME}_ALIGN_WITH_INPUT ${SECTION_ALIGN_WITH_INPUT})
  91. set_property(GLOBAL PROPERTY SECTION_${SECTION_NAME}_SUBALIGN ${SECTION_SUBALIGN})
  92. set_property(GLOBAL PROPERTY SECTION_${SECTION_NAME}_ENDALIGN ${SECTION_ENDALIGN})
  93. set_property(GLOBAL PROPERTY SECTION_${SECTION_NAME}_NOINPUT ${SECTION_NOINPUT})
  94. set_property(GLOBAL PROPERTY SECTION_${SECTION_NAME}_NOINIT ${SECTION_NOINIT})
  95. set_property(GLOBAL PROPERTY SECTION_${SECTION_NAME}_NOSYMBOLS ${SECTION_NOSYMBOLS})
  96. string(REGEX REPLACE "^[\.]" "" name_clean "${SECTION_NAME}")
  97. string(REPLACE "." "_" name_clean "${name_clean}")
  98. set_property(GLOBAL PROPERTY SECTION_${SECTION_NAME}_NAME_CLEAN ${name_clean})
  99. set_property(GLOBAL PROPERTY SYMBOL_TABLE___${name_clean}_start ${name_clean})
  100. set_property(GLOBAL PROPERTY SYMBOL_TABLE___${name_clean}_size ${name_clean})
  101. set_property(GLOBAL PROPERTY SYMBOL_TABLE___${name_clean}_load_start ${name_clean})
  102. set_property(GLOBAL PROPERTY SYMBOL_TABLE___${name_clean}_end ${name_clean})
  103. set(INDEX 100)
  104. set(settings_single "ALIGN;ANY;FIRST;KEEP;OFFSET;PASS;PRIO;SECTION;SORT")
  105. set(settings_multi "FLAGS;INPUT;SYMBOLS")
  106. foreach(settings ${SECTION_SETTINGS})
  107. if("${settings}" MATCHES "^{(.*)}$")
  108. cmake_parse_arguments(SETTINGS "" "${settings_single}" "${settings_multi}" ${CMAKE_MATCH_1})
  109. if(NOT ("${SETTINGS_SECTION}" STREQUAL "${SECTION_NAME}"))
  110. continue()
  111. endif()
  112. if(DEFINED SETTINGS_PASS AND NOT "${PASS}" IN_LIST SETTINGS_PASS)
  113. # This section setting is not active in this pass, ignore.
  114. continue()
  115. endif()
  116. if(DEFINED SETTINGS_PRIO)
  117. set(idx ${SETTINGS_PRIO})
  118. else()
  119. set(idx ${INDEX})
  120. math(EXPR INDEX "${INDEX} + 1")
  121. endif()
  122. foreach(setting ${settings_single} ${settings_multi})
  123. set_property(GLOBAL PROPERTY
  124. SECTION_${SECTION_NAME}_SETTING_${idx}_${setting}
  125. ${SETTINGS_${setting}}
  126. )
  127. if(DEFINED SETTINGS_SORT)
  128. set_property(GLOBAL PROPERTY SYMBOL_TABLE___${name_clean}_end ${name_clean}_end)
  129. endif()
  130. endforeach()
  131. set_property(GLOBAL APPEND PROPERTY SECTION_${SECTION_NAME}_SETTINGS_INDICIES ${idx})
  132. endif()
  133. endforeach()
  134. get_property(indicies GLOBAL PROPERTY SECTION_${SECTION_NAME}_SETTINGS_INDICIES)
  135. if(DEFINED indicies)
  136. list(SORT indicies COMPARE NATURAL)
  137. set_property(GLOBAL PROPERTY SECTION_${SECTION_NAME}_SETTINGS_INDICIES ${indicies})
  138. endif()
  139. if(DEFINED SECTION_GROUP)
  140. find_object(OBJECT parent NAME ${SECTION_GROUP})
  141. elseif(DEFINED SECTION_VMA OR DEFINED SECTION_LMA)
  142. if(DEFINED SECTION_VMA)
  143. find_object(OBJECT object NAME ${SECTION_VMA})
  144. get_parent(OBJECT ${object} PARENT parent TYPE REGION)
  145. get_property(vma GLOBAL PROPERTY ${parent}_NAME)
  146. set_property(GLOBAL PROPERTY SECTION_${SECTION_NAME}_VMA ${vma})
  147. set(SECTION_VMA ${vma})
  148. endif()
  149. if(DEFINED SECTION_LMA)
  150. find_object(OBJECT object NAME ${SECTION_LMA})
  151. get_parent(OBJECT ${object} PARENT parent TYPE REGION)
  152. get_property(lma GLOBAL PROPERTY ${parent}_NAME)
  153. set_property(GLOBAL PROPERTY SECTION_${SECTION_NAME}_LMA ${lma})
  154. set(SECTION_LMA ${lma})
  155. endif()
  156. else()
  157. set(parent ${SECTION_SYSTEM})
  158. endif()
  159. set_property(GLOBAL PROPERTY SECTION_${SECTION_NAME}_PARENT ${parent})
  160. add_section(OBJECT ${parent} SECTION ${SECTION_NAME} ADDRESS ${SECTION_ADDRESS} VMA ${SECTION_VMA})
  161. endfunction()
  162. function(create_symbol)
  163. cmake_parse_arguments(SYM "" "OBJECT;EXPR;SIZE;SUBALIGN;SYMBOL" "" ${ARGN})
  164. set_property(GLOBAL PROPERTY SYMBOL_${SYM_SYMBOL} TRUE)
  165. set_property(GLOBAL PROPERTY SYMBOL_${SYM_SYMBOL}_OBJ_TYPE SYMBOL)
  166. set_property(GLOBAL PROPERTY SYMBOL_${SYM_SYMBOL}_NAME ${SYM_SYMBOL})
  167. set_property(GLOBAL PROPERTY SYMBOL_${SYM_SYMBOL}_EXPR ${SYM_EXPR})
  168. set_property(GLOBAL PROPERTY SYMBOL_${SYM_SYMBOL}_SIZE ${SYM_SIZE})
  169. set_property(GLOBAL PROPERTY SYMBOL_${SYM_SYMBOL}_SYMBOL ${SYM_SYMBOL})
  170. set_property(GLOBAL PROPERTY SYMBOL_TABLE_${SYM_SYMBOL} ${SYM_SYMBOL})
  171. add_symbol(OBJECT ${SYM_OBJECT} SYMBOL SYMBOL_${SYM_SYMBOL})
  172. endfunction()
  173. #
  174. # Create functions - end
  175. #
  176. #
  177. # Add functions - start
  178. #
  179. function(add_region)
  180. cmake_parse_arguments(ADD_REGION "" "OBJECT;REGION" "" ${ARGN})
  181. get_property(exists GLOBAL PROPERTY ${ADD_REGION_OBJECT})
  182. if(NOT exists)
  183. message(FATAL_ERROR
  184. "Adding region ${ADD_REGION_REGION} to none-existing object: "
  185. "${ADD_REGION_OBJECT}"
  186. )
  187. endif()
  188. set_property(GLOBAL PROPERTY ${ADD_REGION_REGION}_PARENT ${ADD_REGION_OBJECT})
  189. set_property(GLOBAL APPEND PROPERTY ${ADD_REGION_OBJECT}_REGIONS ${ADD_REGION_REGION})
  190. endfunction()
  191. function(add_group)
  192. cmake_parse_arguments(ADD_GROUP "" "OBJECT;GROUP" "" ${ARGN})
  193. get_property(exists GLOBAL PROPERTY ${ADD_GROUP_OBJECT})
  194. if(NOT exists)
  195. message(FATAL_ERROR
  196. "Adding group ${ADD_GROUP_GROUP} to none-existing object: "
  197. "${ADD_GROUP_OBJECT}"
  198. )
  199. endif()
  200. get_property(vma GLOBAL PROPERTY ${ADD_GROUP_GROUP}_VMA)
  201. get_property(object_name GLOBAL PROPERTY ${ADD_GROUP_OBJECT}_NAME)
  202. if((NOT DEFINED vma) OR ("${vma}" STREQUAL ${object_name}))
  203. set_property(GLOBAL APPEND PROPERTY ${ADD_GROUP_OBJECT}_GROUPS ${ADD_GROUP_GROUP})
  204. else()
  205. set_property(GLOBAL APPEND PROPERTY ${ADD_GROUP_OBJECT}_${vma}_GROUPS ${ADD_GROUP_GROUP})
  206. endif()
  207. endfunction()
  208. function(add_section)
  209. cmake_parse_arguments(ADD_SECTION "" "OBJECT;SECTION;ADDRESS;VMA" "" ${ARGN})
  210. if(DEFINED ADD_SECTION_OBJECT)
  211. get_property(type GLOBAL PROPERTY ${ADD_SECTION_OBJECT}_OBJ_TYPE)
  212. get_property(object_name GLOBAL PROPERTY ${ADD_SECTION_OBJECT}_NAME)
  213. if(NOT DEFINED type)
  214. message(FATAL_ERROR
  215. "Adding section ${ADD_SECTION_SECTION} to "
  216. "none-existing object: ${ADD_SECTION_OBJECT}"
  217. )
  218. endif()
  219. else()
  220. set(ADD_SECTION_OBJECT RELOCATEABLE)
  221. endif()
  222. if("${ADD_SECTION_VMA}" STREQUAL "${object_name}" AND DEFINED ADD_SECTION_ADDRESS)
  223. set_property(GLOBAL APPEND PROPERTY
  224. ${ADD_SECTION_OBJECT}_SECTIONS_FIXED
  225. SECTION_${ADD_SECTION_SECTION}
  226. )
  227. elseif(NOT DEFINED ADD_SECTION_VMA AND DEFINED SECTION_ADDRESS)
  228. set_property(GLOBAL APPEND PROPERTY
  229. ${ADD_SECTION_OBJECT}_SECTIONS_FIXED
  230. SECTION_${ADD_SECTION_SECTION}
  231. )
  232. elseif("${ADD_SECTION_VMA}" STREQUAL "${object_name}")
  233. set_property(GLOBAL APPEND PROPERTY
  234. ${ADD_SECTION_OBJECT}_SECTIONS
  235. SECTION_${ADD_SECTION_SECTION}
  236. )
  237. elseif(NOT DEFINED ADD_SECTION_VMA)
  238. set_property(GLOBAL APPEND PROPERTY
  239. ${ADD_SECTION_OBJECT}_SECTIONS
  240. SECTION_${ADD_SECTION_SECTION}
  241. )
  242. elseif(DEFINED SECTION_ADDRESS)
  243. set_property(GLOBAL APPEND PROPERTY
  244. ${ADD_SECTION_OBJECT}_${ADD_SECTION_VMA}_SECTIONS_FIXED
  245. SECTION_${ADD_SECTION_SECTION}
  246. )
  247. else()
  248. set_property(GLOBAL APPEND PROPERTY
  249. ${ADD_SECTION_OBJECT}_${ADD_SECTION_VMA}_SECTIONS
  250. SECTION_${ADD_SECTION_SECTION}
  251. )
  252. endif()
  253. endfunction()
  254. function(add_symbol)
  255. cmake_parse_arguments(ADD_SYMBOL "" "OBJECT;SYMBOL" "" ${ARGN})
  256. # Section can be fixed address or not, VMA == LMA, .
  257. #
  258. get_property(exists GLOBAL PROPERTY ${ADD_SYMBOL_OBJECT})
  259. if(NOT exists)
  260. message(FATAL_ERROR
  261. "Adding symbol ${ADD_SYMBOL_SYMBOL} to none-existing object: "
  262. "${ADD_SYMBOL_OBJECT}"
  263. )
  264. endif()
  265. set_property(GLOBAL APPEND PROPERTY ${ADD_SYMBOL_OBJECT}_SYMBOLS ${ADD_SYMBOL_SYMBOL})
  266. endfunction()
  267. #
  268. # Add functions - end
  269. #
  270. #
  271. # Retrieval functions - start
  272. #
  273. function(find_object)
  274. cmake_parse_arguments(FIND "" "OBJECT;NAME" "" ${ARGN})
  275. get_property(REGION GLOBAL PROPERTY REGION_${FIND_NAME})
  276. get_property(GROUP GLOBAL PROPERTY GROUP_${FIND_NAME})
  277. get_property(SECTION GLOBAL PROPERTY SECTION_${FIND_NAME})
  278. if(REGION)
  279. set(${FIND_OBJECT} REGION_${FIND_NAME} PARENT_SCOPE)
  280. elseif(GROUP)
  281. set(${FIND_OBJECT} GROUP_${FIND_NAME} PARENT_SCOPE)
  282. elseif(SECTION)
  283. set(${FIND_OBJECT} SECTION_${FIND_NAME} PARENT_SCOPE)
  284. else()
  285. message(WARNING "No object with name ${FIND_NAME} could be found.")
  286. endif()
  287. endfunction()
  288. function(get_objects)
  289. cmake_parse_arguments(GET "" "LIST;OBJECT;TYPE" "" ${ARGN})
  290. get_property(type GLOBAL PROPERTY ${GET_OBJECT}_OBJ_TYPE)
  291. if(${type} STREQUAL SECTION)
  292. # A section doesn't have sub-items.
  293. return()
  294. endif()
  295. if(NOT (${GET_TYPE} STREQUAL SECTION
  296. OR ${GET_TYPE} STREQUAL GROUP)
  297. )
  298. message(WARNING "Only retrieval of SECTION GROUP objects are supported.")
  299. return()
  300. endif()
  301. set(out)
  302. get_parent(OBJECT ${GET_OBJECT} PARENT parent TYPE SYSTEM)
  303. get_property(regions GLOBAL PROPERTY ${parent}_REGIONS)
  304. list(REMOVE_ITEM regions ${GET_OBJECT})
  305. if(${GET_TYPE} STREQUAL SECTION)
  306. get_property(sections GLOBAL PROPERTY ${GET_OBJECT}_SECTIONS_FIXED)
  307. list(APPEND out ${sections})
  308. get_property(groups GLOBAL PROPERTY ${GET_OBJECT}_GROUPS)
  309. foreach(group ${groups})
  310. get_objects(LIST sections OBJECT ${group} TYPE ${GET_TYPE})
  311. list(APPEND out ${sections})
  312. endforeach()
  313. get_property(sections GLOBAL PROPERTY ${GET_OBJECT}_SECTIONS)
  314. list(APPEND out ${sections})
  315. foreach(region ${regions})
  316. get_property(vma GLOBAL PROPERTY ${region}_NAME)
  317. get_property(sections GLOBAL PROPERTY ${GET_OBJECT}_${vma}_SECTIONS_FIXED)
  318. list(APPEND out ${sections})
  319. get_property(groups GLOBAL PROPERTY ${GET_OBJECT}_${vma}_GROUPS)
  320. foreach(group ${groups})
  321. get_objects(LIST sections OBJECT ${group} TYPE ${GET_TYPE})
  322. list(APPEND out ${sections})
  323. endforeach()
  324. get_property(sections GLOBAL PROPERTY ${GET_OBJECT}_${vma}_SECTIONS)
  325. list(APPEND out ${sections})
  326. endforeach()
  327. endif()
  328. if(${GET_TYPE} STREQUAL GROUP)
  329. get_property(groups GLOBAL PROPERTY ${GET_OBJECT}_GROUPS)
  330. list(APPEND out ${groups})
  331. foreach(group ${groups})
  332. get_objects(LIST subgroups OBJECT ${group} TYPE ${GET_TYPE})
  333. list(APPEND out ${subgroups})
  334. endforeach()
  335. foreach(region ${regions})
  336. get_property(vma GLOBAL PROPERTY ${region}_NAME)
  337. get_property(groups GLOBAL PROPERTY ${GET_OBJECT}_${vma}_GROUPS)
  338. list(APPEND out ${groups})
  339. foreach(group ${groups})
  340. get_objects(LIST subgroups OBJECT ${group} TYPE ${GET_TYPE})
  341. list(APPEND out ${subgroups})
  342. endforeach()
  343. endforeach()
  344. endif()
  345. set(${GET_LIST} ${out} PARENT_SCOPE)
  346. endfunction()
  347. #
  348. # Retrieval functions - end
  349. #
  350. function(is_empty)
  351. cmake_parse_arguments(IS_EMPTY "" "OBJECT" "" ${ARGN})
  352. get_property(sections GLOBAL PROPERTY ${IS_EMPTY_OBJECT}_SECTIONS_FIXED)
  353. if(DEFINED sections)
  354. set_property(GLOBAL PROPERTY ${IS_EMPTY_OBJECT}_EMPTY FALSE)
  355. return()
  356. endif()
  357. get_property(groups GLOBAL PROPERTY ${IS_EMPTY_OBJECT}_GROUPS)
  358. if(DEFINED groups)
  359. set_property(GLOBAL PROPERTY ${IS_EMPTY_OBJECT}_EMPTY FALSE)
  360. return()
  361. endif()
  362. get_property(sections GLOBAL PROPERTY ${IS_EMPTY_OBJECT}_SECTIONS)
  363. if(DEFINED sections)
  364. set_property(GLOBAL PROPERTY ${IS_EMPTY_OBJECT}_EMPTY FALSE)
  365. return()
  366. endif()
  367. get_parent(OBJECT ${IS_EMPTY_OBJECT} PARENT parent TYPE SYSTEM)
  368. get_property(regions GLOBAL PROPERTY ${parent}_REGIONS)
  369. list(REMOVE_ITEM regions ${IS_EMPTY_OBJECT})
  370. foreach(region ${regions})
  371. get_property(vma GLOBAL PROPERTY ${region}_NAME)
  372. get_property(sections GLOBAL PROPERTY ${IS_EMPTY_OBJECT}_${vma}_SECTIONS_FIXED)
  373. if(DEFINED sections)
  374. set_property(GLOBAL PROPERTY ${IS_EMPTY_OBJECT}_EMPTY FALSE)
  375. return()
  376. endif()
  377. get_property(groups GLOBAL PROPERTY ${IS_EMPTY_OBJECT}_${vma}_GROUPS)
  378. if(DEFINED groups)
  379. set_property(GLOBAL PROPERTY ${IS_EMPTY_OBJECT}_EMPTY FALSE)
  380. return()
  381. endif()
  382. get_property(sections GLOBAL PROPERTY ${IS_EMPTY_OBJECT}_${vma}_SECTIONS)
  383. if(DEFINED sections)
  384. set_property(GLOBAL PROPERTY ${IS_EMPTY_OBJECT}_EMPTY FALSE)
  385. return()
  386. endif()
  387. endforeach()
  388. set_property(GLOBAL PROPERTY ${IS_EMPTY_OBJECT}_EMPTY TRUE)
  389. endfunction()
  390. # This function post process the region for easier use.
  391. #
  392. # This is common post processing.
  393. # If the calling <linker>_script.cmake generator implements its own
  394. # process_region(), then the process_region_common() must be called explicitly
  395. # from the process_region() from the <linker>_script.cmake generator.
  396. #
  397. # This allows a custom <linker>_script.cmake generator to completely disable
  398. # the common post processing of regions.
  399. #
  400. # Tasks:
  401. # - Apply missing settings, such as initial address for first section in a region.
  402. # - Symbol names on sections
  403. # - Ordered list of all sections for easier retrival on printing and configuration.
  404. function(process_region_common)
  405. cmake_parse_arguments(REGION_COMMON "" "OBJECT" "" ${ARGN})
  406. is_empty(OBJECT ${REGION_COMMON_OBJECT})
  407. set(sections)
  408. get_objects(LIST sections OBJECT ${REGION_COMMON_OBJECT} TYPE SECTION)
  409. set_property(GLOBAL PROPERTY ${REGION_COMMON_OBJECT}_SECTION_LIST_ORDERED ${sections})
  410. set(groups)
  411. get_objects(LIST groups OBJECT ${REGION_COMMON_OBJECT} TYPE GROUP)
  412. set_property(GLOBAL PROPERTY ${REGION_COMMON_OBJECT}_GROUP_LIST_ORDERED ${groups})
  413. list(LENGTH sections section_count)
  414. if(section_count GREATER 0)
  415. list(GET sections 0 section)
  416. get_property(address GLOBAL PROPERTY ${section}_ADDRESS)
  417. if(NOT DEFINED address)
  418. get_parent(OBJECT ${REGION_COMMON_OBJECT} PARENT parent TYPE REGION)
  419. get_property(address GLOBAL PROPERTY ${parent}_ADDRESS)
  420. set_property(GLOBAL PROPERTY ${section}_ADDRESS ${address})
  421. endif()
  422. endif()
  423. get_parent(OBJECT ${REGION_COMMON_OBJECT} PARENT parent TYPE SYSTEM)
  424. get_property(regions GLOBAL PROPERTY ${parent}_REGIONS)
  425. list(REMOVE_ITEM regions ${REGION_COMMON_OBJECT})
  426. foreach(region ${regions})
  427. get_property(vma GLOBAL PROPERTY ${region}_NAME)
  428. set(sections_${vma})
  429. get_property(sections GLOBAL PROPERTY ${REGION_COMMON_OBJECT}_${vma}_SECTIONS_FIXED)
  430. list(APPEND sections_${vma} ${sections})
  431. get_property(groups GLOBAL PROPERTY ${REGION_COMMON_OBJECT}_${vma}_GROUPS)
  432. foreach(group ${groups})
  433. get_objects(LIST sections OBJECT ${group} TYPE SECTION)
  434. list(APPEND sections_${vma} ${sections})
  435. endforeach()
  436. get_property(sections GLOBAL PROPERTY ${REGION_COMMON_OBJECT}_${vma}_SECTIONS)
  437. list(APPEND sections_${vma} ${sections})
  438. list(LENGTH sections_${vma} section_count)
  439. if(section_count GREATER 0)
  440. list(GET sections_${vma} 0 section)
  441. get_property(address GLOBAL PROPERTY ${section}_ADDRESS)
  442. if(NOT DEFINED address)
  443. get_property(address GLOBAL PROPERTY ${region}_ADDRESS)
  444. set_property(GLOBAL PROPERTY ${section}_ADDRESS ${address})
  445. endif()
  446. endif()
  447. endforeach()
  448. endfunction()
  449. if(NOT COMMAND process_region)
  450. function(process_region)
  451. process_region_common(${ARGN})
  452. endfunction()
  453. endif()
  454. #
  455. # String functions - start
  456. #
  457. # Each linker must implement their own <type>_to_string() functions to
  458. # generate a correct linker script.
  459. #
  460. if(NOT COMMAND system_to_string)
  461. function(system_to_string)
  462. message(WARNING "No linker defined function found. Please implement a "
  463. "system_to_string() function for this linker."
  464. )
  465. endfunction()
  466. endif()
  467. if(NOT COMMAND group_to_string)
  468. function(group_to_string)
  469. message(WARNING "No linker defined function found. Please implement a "
  470. "group_to_string() function for this linker."
  471. )
  472. endfunction()
  473. endif()
  474. if(NOT COMMAND section_to_string)
  475. function(section_to_string)
  476. message(WARNING "No linker defined function found. Please implement a "
  477. "section_to_string() function for this linker."
  478. )
  479. endfunction()
  480. endif()
  481. if(NOT COMMAND symbol_to_string)
  482. function(symbol_to_string)
  483. message(WARNING "No linker defined function found. Please implement a "
  484. "symbol_to_string() function for this linker."
  485. )
  486. endfunction()
  487. endif()
  488. function(to_string)
  489. cmake_parse_arguments(STRING "" "OBJECT;STRING" "" ${ARGN})
  490. get_property(type GLOBAL PROPERTY ${STRING_OBJECT}_OBJ_TYPE)
  491. if("${type}" STREQUAL SYSTEM)
  492. system_to_string(OBJECT ${STRING_OBJECT} STRING ${STRING_STRING})
  493. elseif(("${type}" STREQUAL REGION) OR ("${type}" STREQUAL GROUP))
  494. group_to_string(OBJECT ${STRING_OBJECT} STRING ${STRING_STRING})
  495. elseif("${type}" STREQUAL SECTION)
  496. section_to_string(SECTION ${STRING_OBJECT} STRING ${STRING_STRING})
  497. elseif("${type}" STREQUAL SYMBOL)
  498. symbol_to_string(SYMBOL ${STRING_OBJECT} STRING ${STRING_STRING})
  499. endif()
  500. set(${STRING_STRING} ${${STRING_STRING}} PARENT_SCOPE)
  501. endfunction()
  502. #
  503. # String functions - end
  504. #
  505. create_system(OBJECT new_system NAME ZEPHYR_LINKER_v1 FORMAT ${FORMAT} ENTRY ${ENTRY})
  506. # Sorting the memory sections in ascending order.
  507. foreach(region ${MEMORY_REGIONS})
  508. if("${region}" MATCHES "^{(.*)}$")
  509. cmake_parse_arguments(REGION "" "NAME;START" "" ${CMAKE_MATCH_1})
  510. math(EXPR start_dec "${REGION_START}" OUTPUT_FORMAT DECIMAL)
  511. set(region_id ${start_dec}_${REGION_NAME})
  512. set(region_${region_id} ${region})
  513. string(REPLACE ";" "\;" region_${region_id} "${region_${region_id}}")
  514. list(APPEND region_sort ${region_id})
  515. endif()
  516. endforeach()
  517. list(SORT region_sort COMPARE NATURAL)
  518. set(MEMORY_REGIONS_SORTED)
  519. foreach(region_start ${region_sort})
  520. list(APPEND MEMORY_REGIONS_SORTED "${region_${region_start}}")
  521. endforeach()
  522. # sorting complete.
  523. foreach(region ${MEMORY_REGIONS_SORTED})
  524. if("${region}" MATCHES "^{(.*)}$")
  525. create_region(OBJECT new_region ${CMAKE_MATCH_1})
  526. add_region(OBJECT ${new_system} REGION ${new_region})
  527. endif()
  528. endforeach()
  529. foreach(group ${GROUPS})
  530. if("${group}" MATCHES "^{(.*)}$")
  531. create_group(OBJECT new_group ${CMAKE_MATCH_1})
  532. endif()
  533. endforeach()
  534. foreach(section ${SECTIONS})
  535. if("${section}" MATCHES "^{(.*)}$")
  536. create_section(${CMAKE_MATCH_1} SYSTEM ${new_system})
  537. endif()
  538. endforeach()
  539. foreach(symbol ${SYMBOLS})
  540. if("${symbol}" MATCHES "^{(.*)}$")
  541. create_symbol(OBJECT ${new_system} ${CMAKE_MATCH_1})
  542. endif()
  543. endforeach()
  544. get_property(regions GLOBAL PROPERTY ${new_system}_REGIONS)
  545. foreach(region ${regions})
  546. process_region(OBJECT ${region})
  547. endforeach()
  548. set(OUT)
  549. to_string(OBJECT ${new_system} STRING OUT)
  550. if(OUT_FILE)
  551. file(WRITE ${OUT_FILE} "${OUT}")
  552. endif()