|
| 1 | +cmake_minimum_required(VERSION 3.17) |
| 2 | + |
| 3 | +set(SORT_TYPE_NAME Lexical) |
| 4 | + |
| 5 | +# |
| 6 | +# String functions - start |
| 7 | +# |
| 8 | + |
| 9 | +function(system_to_string) |
| 10 | + cmake_parse_arguments(STRING "" "OBJECT;STRING" "" ${ARGN}) |
| 11 | + |
| 12 | + get_property(name GLOBAL PROPERTY ${STRING_OBJECT}_NAME) |
| 13 | + get_property(regions GLOBAL PROPERTY ${STRING_OBJECT}_REGIONS) |
| 14 | + get_property(format GLOBAL PROPERTY ${STRING_OBJECT}_FORMAT) |
| 15 | + |
| 16 | + foreach(region ${regions}) |
| 17 | + get_property(empty GLOBAL PROPERTY ${region}_EMPTY) |
| 18 | + if(NOT empty) |
| 19 | + to_string(OBJECT ${region} STRING ${STRING_STRING}) |
| 20 | + endif() |
| 21 | + endforeach() |
| 22 | + |
| 23 | + set(${STRING_STRING} ${${STRING_STRING}} PARENT_SCOPE) |
| 24 | +endfunction() |
| 25 | + |
| 26 | +function(group_to_string) |
| 27 | + cmake_parse_arguments(STRING "" "OBJECT;STRING" "" ${ARGN}) |
| 28 | + |
| 29 | + get_property(type GLOBAL PROPERTY ${STRING_OBJECT}_OBJ_TYPE) |
| 30 | + if(${type} STREQUAL REGION) |
| 31 | + get_property(name GLOBAL PROPERTY ${STRING_OBJECT}_NAME) |
| 32 | + get_property(address GLOBAL PROPERTY ${STRING_OBJECT}_ADDRESS) |
| 33 | + get_property(size GLOBAL PROPERTY ${STRING_OBJECT}_SIZE) |
| 34 | + set(${STRING_STRING} "${${STRING_STRING}}\n${name} ${address} NOCOMPRESS ${size}\n{\n") |
| 35 | + endif() |
| 36 | + |
| 37 | + get_property(sections GLOBAL PROPERTY ${STRING_OBJECT}_SECTIONS_FIXED) |
| 38 | + foreach(section ${sections}) |
| 39 | + to_string(OBJECT ${section} STRING ${STRING_STRING}) |
| 40 | + endforeach() |
| 41 | + |
| 42 | + get_property(groups GLOBAL PROPERTY ${STRING_OBJECT}_GROUPS) |
| 43 | + foreach(group ${groups}) |
| 44 | + to_string(OBJECT ${group} STRING ${STRING_STRING}) |
| 45 | + endforeach() |
| 46 | + |
| 47 | + get_property(sections GLOBAL PROPERTY ${STRING_OBJECT}_SECTIONS) |
| 48 | + foreach(section ${sections}) |
| 49 | + to_string(OBJECT ${section} STRING ${STRING_STRING}) |
| 50 | + endforeach() |
| 51 | + |
| 52 | + get_parent(OBJECT ${STRING_OBJECT} PARENT parent TYPE SYSTEM) |
| 53 | + get_property(regions GLOBAL PROPERTY ${parent}_REGIONS) |
| 54 | + list(REMOVE_ITEM regions ${STRING_OBJECT}) |
| 55 | + foreach(region ${regions}) |
| 56 | + get_property(vma GLOBAL PROPERTY ${region}_NAME) |
| 57 | + get_property(sections GLOBAL PROPERTY ${STRING_OBJECT}_${vma}_SECTIONS_FIXED) |
| 58 | + foreach(section ${sections}) |
| 59 | + to_string(OBJECT ${section} STRING ${STRING_STRING}) |
| 60 | + endforeach() |
| 61 | + |
| 62 | + get_property(groups GLOBAL PROPERTY ${STRING_OBJECT}_${vma}_GROUPS) |
| 63 | + foreach(group ${groups}) |
| 64 | + to_string(OBJECT ${group} STRING ${STRING_STRING}) |
| 65 | + endforeach() |
| 66 | + |
| 67 | + get_property(sections GLOBAL PROPERTY ${STRING_OBJECT}_${vma}_SECTIONS) |
| 68 | + foreach(section ${sections}) |
| 69 | + to_string(OBJECT ${section} STRING ${STRING_STRING}) |
| 70 | + endforeach() |
| 71 | + endforeach() |
| 72 | + |
| 73 | + get_property(symbols GLOBAL PROPERTY ${STRING_OBJECT}_SYMBOLS) |
| 74 | + foreach(symbol ${symbols}) |
| 75 | + to_string(OBJECT ${symbol} STRING ${STRING_STRING}) |
| 76 | + endforeach() |
| 77 | + |
| 78 | + if(${type} STREQUAL REGION) |
| 79 | + set(${STRING_STRING} "${${STRING_STRING}}\n}\n") |
| 80 | + endif() |
| 81 | + set(${STRING_STRING} ${${STRING_STRING}} PARENT_SCOPE) |
| 82 | +endfunction() |
| 83 | + |
| 84 | + |
| 85 | +function(section_to_string) |
| 86 | + cmake_parse_arguments(STRING "" "SECTION;STRING" "" ${ARGN}) |
| 87 | + |
| 88 | + get_property(name GLOBAL PROPERTY ${STRING_SECTION}_NAME) |
| 89 | + get_property(address GLOBAL PROPERTY ${STRING_SECTION}_ADDRESS) |
| 90 | + get_property(type GLOBAL PROPERTY ${STRING_SECTION}_TYPE) |
| 91 | + get_property(align GLOBAL PROPERTY ${STRING_SECTION}_ALIGN) |
| 92 | + get_property(subalign GLOBAL PROPERTY ${STRING_SECTION}_SUBALIGN) |
| 93 | + get_property(endalign GLOBAL PROPERTY ${STRING_SECTION}_ENDALIGN) |
| 94 | + get_property(vma GLOBAL PROPERTY ${STRING_SECTION}_VMA) |
| 95 | + get_property(lma GLOBAL PROPERTY ${STRING_SECTION}_LMA) |
| 96 | + get_property(noinput GLOBAL PROPERTY ${STRING_SECTION}_NOINPUT) |
| 97 | + get_property(noinit GLOBAL PROPERTY ${STRING_SECTION}_NOINIT) |
| 98 | + |
| 99 | + string(REGEX REPLACE "^[\.]" "" name_clean "${name}") |
| 100 | + string(REPLACE "." "_" name_clean "${name_clean}") |
| 101 | + |
| 102 | + set(TEMP " ${name_clean}") |
| 103 | + if(DEFINED address) |
| 104 | + set(TEMP "${TEMP} ${address}") |
| 105 | + else() |
| 106 | + set(TEMP "${TEMP} +0") |
| 107 | + endif() |
| 108 | + |
| 109 | + if(noinit) |
| 110 | + # Currently we simply uses offset +0, but we must support offset defined |
| 111 | + # externally. |
| 112 | + set(TEMP "${TEMP} UNINIT") |
| 113 | + endif() |
| 114 | + |
| 115 | + if(subalign) |
| 116 | + # Currently we simply uses offset +0, but we must support offset defined |
| 117 | + # externally. |
| 118 | + set(TEMP "${TEMP} ALIGN ${subalign}") |
| 119 | + endif() |
| 120 | + |
| 121 | + if(NOT noinput) |
| 122 | + set(TEMP "${TEMP}\n {") |
| 123 | + |
| 124 | + if("${type}" STREQUAL NOLOAD) |
| 125 | + set(TEMP "${TEMP}\n *.o(${name}*)") |
| 126 | + set(TEMP "${TEMP}\n *.o(${name}*.*)") |
| 127 | + elseif(VMA_FLAGS) |
| 128 | + # ToDo: Proper names as provided by armclang |
| 129 | +# set(TEMP "${TEMP}\n *.o(${SEC_NAME}*, +${VMA_FLAGS})") |
| 130 | +# set(TEMP "${TEMP}\n *.o(${SEC_NAME}*.*, +${VMA_FLAGS})") |
| 131 | + set(TEMP "${TEMP}\n *.o(${name}*)") |
| 132 | + set(TEMP "${TEMP}\n *.o(${name}*.*)") |
| 133 | + else() |
| 134 | + set(TEMP "${TEMP}\n *.o(${name}*)") |
| 135 | + set(TEMP "${TEMP}\n *.o(${name}*.*)") |
| 136 | + endif() |
| 137 | + else() |
| 138 | + set(empty TRUE) |
| 139 | + endif() |
| 140 | + |
| 141 | + get_property(indicies GLOBAL PROPERTY ${STRING_SECTION}_SETTINGS_INDICIES) |
| 142 | + foreach(idx ${indicies}) |
| 143 | + get_property(align GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx}_ALIGN) |
| 144 | + get_property(any GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx}_ANY) |
| 145 | + get_property(first GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx}_FIRST) |
| 146 | + get_property(keep GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx}_KEEP) |
| 147 | + get_property(sort GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx}_SORT) |
| 148 | + get_property(flags GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx}_FLAGS) |
| 149 | + get_property(input GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx}_INPUT) |
| 150 | + get_property(offset GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx}_OFFSET) |
| 151 | + if(DEFINED offset) |
| 152 | + set(section_close TRUE) |
| 153 | + math(EXPR offset_dec "${offset} + 0") |
| 154 | + if(empty) |
| 155 | + set(TEMP "${TEMP} EMPTY 0x0\n {") |
| 156 | + set(empty FALSE) |
| 157 | + endif() |
| 158 | + set(last_index ${offset_dec}) |
| 159 | + if(sort) |
| 160 | + set(sorttype "SORTTYPE ${SORT_TYPE_${sort}}") |
| 161 | + endif() |
| 162 | + set(TEMP "${TEMP}\n }") |
| 163 | + set(TEMP "${TEMP}\n ${name_clean}_${offset_dec} (ImageBase(${name_clean}) + ${offset}) ${sorttype}\n {") |
| 164 | + elseif(sort) |
| 165 | + set(section_close TRUE) |
| 166 | + if(empty) |
| 167 | + set(TEMP "${TEMP} EMPTY 0x0\n {") |
| 168 | + set(empty FALSE) |
| 169 | + endif() |
| 170 | + set(last_index ${idx}) |
| 171 | + set(TEMP "${TEMP}\n }") |
| 172 | + set(TEMP "${TEMP}\n ${name_clean}_${idx} +0 SORTTYPE ${SORT_TYPE_${sort}}\n {") |
| 173 | + endif() |
| 174 | + |
| 175 | + if(empty) |
| 176 | + set(TEMP "${TEMP}\n {") |
| 177 | + set(empty FALSE) |
| 178 | + endif() |
| 179 | + |
| 180 | + foreach(setting ${input}) |
| 181 | + #set(SETTINGS ${SETTINGS_INPUT}) |
| 182 | + |
| 183 | +# # ToDo: The code below had en error in original implementation, causing |
| 184 | +# # settings not to be applied |
| 185 | +# # Verify behaviour and activate if working as intended. |
| 186 | +# if(align) |
| 187 | +# set(setting "${setting}, OVERALIGN ${align}") |
| 188 | +# endif() |
| 189 | + |
| 190 | + #if(SETTINGS_KEEP) |
| 191 | + # armlink has --keep=<section_id>, but is there an scatter equivalant ? |
| 192 | + #endif() |
| 193 | + |
| 194 | + if(first) |
| 195 | + set(setting "${setting}, +First") |
| 196 | + set(first "") |
| 197 | + endif() |
| 198 | + |
| 199 | + set(TEMP "${TEMP}\n *.o(${setting})") |
| 200 | + endforeach() |
| 201 | + |
| 202 | + if(any) |
| 203 | + if(NOT flags) |
| 204 | + message(FATAL_ERROR ".ANY requires flags to be set.") |
| 205 | + endif() |
| 206 | + string(REPLACE ";" " " flags "${flags}") |
| 207 | + |
| 208 | + set(TEMP "${TEMP}\n .ANY (${flags})") |
| 209 | + endif() |
| 210 | + endforeach() |
| 211 | + |
| 212 | + if(section_close OR DEFINED endalign) |
| 213 | + set(section_close) |
| 214 | + set(TEMP "${TEMP}\n }") |
| 215 | + |
| 216 | + if(DEFINED endalign) |
| 217 | + if(DEFINED last_index) |
| 218 | + set(align_expr "AlignExpr(ImageLimit(${name_clean}_${last_index}), ${endalign}) FIXED") |
| 219 | + else() |
| 220 | + set(align_expr "AlignExpr(ImageLimit(${name_clean}), ${endalign}) FIXED") |
| 221 | + endif() |
| 222 | + else() |
| 223 | + set(align_expr "+0") |
| 224 | + endif() |
| 225 | + |
| 226 | + set(TEMP "${TEMP}\n ${name_clean}_end ${align_expr} EMPTY 0x0\n {") |
| 227 | + set(last_index) |
| 228 | + endif() |
| 229 | + |
| 230 | + set(TEMP "${TEMP}") |
| 231 | + # ToDo: add patterns here. |
| 232 | + |
| 233 | + set(TEMP "${TEMP}\n }") |
| 234 | + |
| 235 | + set(${STRING_STRING} "${${STRING_STRING}}\n${TEMP}\n" PARENT_SCOPE) |
| 236 | +endfunction() |
| 237 | + |
| 238 | +function(symbol_to_string) |
| 239 | + cmake_parse_arguments(STRING "" "SYMBOL;STRING" "" ${ARGN}) |
| 240 | + |
| 241 | + get_property(name GLOBAL PROPERTY ${STRING_SYMBOL}_NAME) |
| 242 | + get_property(expr GLOBAL PROPERTY ${STRING_SYMBOL}_EXPR) |
| 243 | + get_property(size GLOBAL PROPERTY ${STRING_SYMBOL}_SIZE) |
| 244 | + get_property(symbol GLOBAL PROPERTY ${STRING_SYMBOL}_SYMBOL) |
| 245 | + get_property(subalign GLOBAL PROPERTY ${STRING_SYMBOL}_SUBALIGN) |
| 246 | + |
| 247 | + string(REPLACE "\\" "" expr "${expr}") |
| 248 | + string(REGEX MATCHALL "%([^%]*)%" match_res ${expr}) |
| 249 | + |
| 250 | + foreach(match ${match_res}) |
| 251 | + string(REPLACE "%" "" match ${match}) |
| 252 | + get_property(symbol_val GLOBAL PROPERTY SYMBOL_TABLE_${match}) |
| 253 | + string(REPLACE "%${match}%" "ImageBase(${symbol_val})" expr ${expr}) |
| 254 | + endforeach() |
| 255 | + |
| 256 | + if(DEFINED subalign) |
| 257 | + set(subalign "ALIGN ${subalign}") |
| 258 | + endif() |
| 259 | + |
| 260 | + if(NOT DEFINED size) |
| 261 | + set(size "0x0") |
| 262 | + endif() |
| 263 | + |
| 264 | + set(${STRING_STRING} |
| 265 | + "${${STRING_STRING}}\n ${symbol} ${expr} ${subalign} ${size} { }\n" |
| 266 | + PARENT_SCOPE |
| 267 | + ) |
| 268 | +endfunction() |
| 269 | + |
| 270 | +include(${CMAKE_CURRENT_LIST_DIR}/../linker_script_common.cmake) |
0 commit comments