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