Blame view
include/linker_lists.h
9.74 KB
42ebaae3a common: Implement... |
1 2 3 4 5 6 7 |
/* * include/linker_lists.h * * Implementation of linker-generated arrays * * Copyright (C) 2012 Marek Vasut <marex@denx.de> * |
1a4596601 Add GPL-2.0+ SPDX... |
8 |
* SPDX-License-Identifier: GPL-2.0+ |
42ebaae3a common: Implement... |
9 |
*/ |
ef123c525 Refactor linker-g... |
10 |
|
babb4440c kernel-doc: fix s... |
11 12 |
#ifndef __LINKER_LISTS_H__ #define __LINKER_LISTS_H__ |
ef123c525 Refactor linker-g... |
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
/* * There is no use in including this from ASM files, but that happens * anyway, e.g. PPC kgdb.S includes command.h which incluse us. * So just don't define anything when included from ASM. */ #if !defined(__ASSEMBLY__) /** * A linker list is constructed by grouping together linker input * sections, each containning one entry of the list. Each input section * contains a constant initialized variable which holds the entry's * content. Linker list input sections are constructed from the list * and entry names, plus a prefix which allows grouping all lists * together. Assuming _list and _entry are the list and entry names, * then the corresponding input section name is * * _u_boot_list + _2_ + @_list + _2_ + @_entry * * and the C variable name is * * .u_boot_list_ + 2_ + @_list + _2_ + @_entry * * This ensures uniqueness for both input section and C variable name. * * Note that the names differ only in the first character, "." for the * setion and "_" for the variable, so that the linker cannot confuse * section and symbol names. From now on, both names will be referred * to as * * %u_boot_list_ + 2_ + @_list + _2_ + @_entry * * Entry variables need never be referred to directly. * * The naming scheme for input sections allows grouping all linker lists * into a single linker output section and grouping all entries for a * single list. * * Note the two '_2_' constant components in the names: their presence * allows putting a start and end symbols around a list, by mapping * these symbols to sections names with components "1" (before) and * "3" (after) instead of "2" (within). * Start and end symbols for a list can generally be defined as * * %u_boot_list_2_ + @_list + _1_... * %u_boot_list_2_ + @_list + _3_... * * Start and end symbols for the whole of the linker lists area can be * defined as * * %u_boot_list_1_... * %u_boot_list_3_... * * Here is an example of the sorted sections which result from a list * "array" made up of three entries : "first", "second" and "third", * iterated at least once. * * .u_boot_list_2_array_1 * .u_boot_list_2_array_2_first * .u_boot_list_2_array_2_second * .u_boot_list_2_array_2_third * .u_boot_list_2_array_3 * * If lists must be divided into sublists (e.g. for iterating only on * part of a list), one can simply give the list a name of the form * 'outer_2_inner', where 'outer' is the global list name and 'inner' * is the sub-list name. Iterators for the whole list should use the * global list name ("outer"); iterators for only a sub-list should use * the full sub-list name ("outer_2_inner"). * * Here is an example of the sections generated from a global list * named "drivers", two sub-lists named "i2c" and "pci", and iterators * defined for the whole list and each sub-list: * * %u_boot_list_2_drivers_1 * %u_boot_list_2_drivers_2_i2c_1 * %u_boot_list_2_drivers_2_i2c_2_first * %u_boot_list_2_drivers_2_i2c_2_first * %u_boot_list_2_drivers_2_i2c_2_second * %u_boot_list_2_drivers_2_i2c_2_third * %u_boot_list_2_drivers_2_i2c_3 * %u_boot_list_2_drivers_2_pci_1 * %u_boot_list_2_drivers_2_pci_2_first * %u_boot_list_2_drivers_2_pci_2_second * %u_boot_list_2_drivers_2_pci_2_third * %u_boot_list_2_drivers_2_pci_3 * %u_boot_list_2_drivers_3 */ |
42ebaae3a common: Implement... |
101 102 103 104 |
/** * ll_entry_declare() - Declare linker-generated array entry * @_type: Data type of the entry * @_name: Name of the entry |
ef123c525 Refactor linker-g... |
105 106 |
* @_list: name of the list. Should contain only characters allowed * in a C variable name! |
42ebaae3a common: Implement... |
107 108 109 110 111 112 |
* * This macro declares a variable that is placed into a linker-generated * array. This is a basic building block for more advanced use of linker- * generated arrays. The user is expected to build their own macro wrapper * around this one. * |
ef123c525 Refactor linker-g... |
113 |
* A variable declared using this macro must be compile-time initialized. |
42ebaae3a common: Implement... |
114 115 |
* * Special precaution must be made when using this macro: |
42ebaae3a common: Implement... |
116 |
* |
ef123c525 Refactor linker-g... |
117 118 119 |
* 1) The _type must not contain the "static" keyword, otherwise the * entry is generated and can be iterated but is listed in the map * file and cannot be retrieved by name. |
42ebaae3a common: Implement... |
120 |
* |
ef123c525 Refactor linker-g... |
121 122 123 |
* 2) In case a section is declared that contains some array elements AND * a subsection of this section is declared and contains some elements, * it is imperative that the elements are of the same type. |
42ebaae3a common: Implement... |
124 125 |
* * 4) In case an outer section is declared that contains some array elements |
ef123c525 Refactor linker-g... |
126 |
* AND an inner subsection of this section is declared and contains some |
42ebaae3a common: Implement... |
127 128 129 130 131 132 133 134 135 |
* elements, then when traversing the outer section, even the elements of * the inner sections are present in the array. * * Example: * ll_entry_declare(struct my_sub_cmd, my_sub_cmd, cmd_sub, cmd.sub) = { * .x = 3, * .y = 4, * }; */ |
ef123c525 Refactor linker-g... |
136 137 138 139 140 141 142 143 144 145 146 147 148 |
#define ll_entry_declare(_type, _name, _list) \ _type _u_boot_list_2_##_list##_2_##_name __aligned(4) \ __attribute__((unused, \ section(".u_boot_list_2_"#_list"_2_"#_name))) /** * We need a 0-byte-size type for iterator symbols, and the compiler * does not allow defining objects of C type 'void'. Using an empty * struct is allowed by the compiler, but causes gcc versions 4.4 and * below to complain about aliasing. Therefore we use the next best * thing: zero-sized arrays, which are both 0-byte-size and exempt from * aliasing warnings. */ |
42ebaae3a common: Implement... |
149 150 151 152 |
/** * ll_entry_start() - Point to first entry of linker-generated array * @_type: Data type of the entry |
ef123c525 Refactor linker-g... |
153 |
* @_list: Name of the list in which this entry is placed |
42ebaae3a common: Implement... |
154 155 156 |
* * This function returns (_type *) pointer to the very first entry of a * linker-generated array placed into subsection of .u_boot_list section |
ef123c525 Refactor linker-g... |
157 158 159 160 |
* specified by _list argument. * * Since this macro defines an array start symbol, its leftmost index * must be 2 and its rightmost index must be 1. |
42ebaae3a common: Implement... |
161 162 163 164 |
* * Example: * struct my_sub_cmd *msc = ll_entry_start(struct my_sub_cmd, cmd_sub); */ |
ef123c525 Refactor linker-g... |
165 166 167 168 169 170 |
#define ll_entry_start(_type, _list) \ ({ \ static char start[0] __aligned(4) __attribute__((unused, \ section(".u_boot_list_2_"#_list"_1"))); \ (_type *)&start; \ }) |
42ebaae3a common: Implement... |
171 172 |
/** |
ef123c525 Refactor linker-g... |
173 |
* ll_entry_end() - Point after last entry of linker-generated array |
42ebaae3a common: Implement... |
174 |
* @_type: Data type of the entry |
ef123c525 Refactor linker-g... |
175 |
* @_list: Name of the list in which this entry is placed |
42ebaae3a common: Implement... |
176 177 |
* (with underscores instead of dots) * |
ef123c525 Refactor linker-g... |
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
* This function returns (_type *) pointer after the very last entry of * a linker-generated array placed into subsection of .u_boot_list * section specified by _list argument. * * Since this macro defines an array end symbol, its leftmost index * must be 2 and its rightmost index must be 3. * * Example: * struct my_sub_cmd *msc = ll_entry_end(struct my_sub_cmd, cmd_sub); */ #define ll_entry_end(_type, _list) \ ({ \ static char end[0] __aligned(4) __attribute__((unused, \ section(".u_boot_list_2_"#_list"_3"))); \ (_type *)&end; \ }) /** * ll_entry_count() - Return the number of elements in linker-generated array * @_type: Data type of the entry * @_list: Name of the list of which the number of elements is computed * |
42ebaae3a common: Implement... |
199 |
* This function returns the number of elements of a linker-generated array |
ef123c525 Refactor linker-g... |
200 |
* placed into subsection of .u_boot_list section specified by _list |
42ebaae3a common: Implement... |
201 202 203 204 205 206 207 208 209 210 |
* argument. The result is of an unsigned int type. * * Example: * int i; * const unsigned int count = ll_entry_count(struct my_sub_cmd, cmd_sub); * struct my_sub_cmd *msc = ll_entry_start(struct my_sub_cmd, cmd_sub); * for (i = 0; i < count; i++, msc++) * printf("Entry %i, x=%i y=%i ", i, msc->x, msc->y); */ |
ef123c525 Refactor linker-g... |
211 |
#define ll_entry_count(_type, _list) \ |
42ebaae3a common: Implement... |
212 |
({ \ |
ef123c525 Refactor linker-g... |
213 214 215 |
_type *start = ll_entry_start(_type, _list); \ _type *end = ll_entry_end(_type, _list); \ unsigned int _ll_result = end - start; \ |
42ebaae3a common: Implement... |
216 217 |
_ll_result; \ }) |
42ebaae3a common: Implement... |
218 219 220 221 |
/** * ll_entry_get() - Retrieve entry from linker-generated array by name * @_type: Data type of the entry * @_name: Name of the entry |
ef123c525 Refactor linker-g... |
222 |
* @_list: Name of the list in which this entry is placed |
42ebaae3a common: Implement... |
223 224 225 226 227 228 |
* * This function returns a pointer to a particular entry in LG-array * identified by the subsection of u_boot_list where the entry resides * and it's name. * * Example: |
af41d6b4c common: fixed lin... |
229 |
* ll_entry_declare(struct my_sub_cmd, my_sub_cmd, cmd_sub) = { |
42ebaae3a common: Implement... |
230 231 232 233 234 235 |
* .x = 3, * .y = 4, * }; * ... * struct my_sub_cmd *c = ll_entry_get(struct my_sub_cmd, my_sub_cmd, cmd_sub); */ |
ef123c525 Refactor linker-g... |
236 |
#define ll_entry_get(_type, _name, _list) \ |
42ebaae3a common: Implement... |
237 |
({ \ |
ef123c525 Refactor linker-g... |
238 239 240 |
extern _type _u_boot_list_2_##_list##_2_##_name; \ _type *_ll_result = \ &_u_boot_list_2_##_list##_2_##_name; \ |
42ebaae3a common: Implement... |
241 242 |
_ll_result; \ }) |
ef123c525 Refactor linker-g... |
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 |
/** * ll_start() - Point to first entry of first linker-generated array * @_type: Data type of the entry * * This function returns (_type *) pointer to the very first entry of * the very first linker-generated array. * * Since this macro defines the start of the linker-generated arrays, * its leftmost index must be 1. * * Example: * struct my_sub_cmd *msc = ll_start(struct my_sub_cmd); */ #define ll_start(_type) \ ({ \ static char start[0] __aligned(4) __attribute__((unused, \ section(".u_boot_list_1"))); \ (_type *)&start; \ }) /** * ll_entry_end() - Point after last entry of last linker-generated array * @_type: Data type of the entry * * This function returns (_type *) pointer after the very last entry of * the very last linker-generated array. * * Since this macro defines the end of the linker-generated arrays, * its leftmost index must be 3. * * Example: * struct my_sub_cmd *msc = ll_end(struct my_sub_cmd); */ #define ll_end(_type) \ ({ \ static char end[0] __aligned(4) __attribute__((unused, \ section(".u_boot_list_3"))); \ (_type *)&end; \ }) #endif /* __ASSEMBLY__ */ |
42ebaae3a common: Implement... |
284 |
#endif /* __LINKER_LISTS_H__ */ |