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