[PATCH 05/43] Improve support for linker lists in data structures

Simon Glass sjg at chromium.org
Wed Jan 15 14:30:35 CET 2025


A limitation of most linker_list macros is that they cannot easily be
used in data structures. This is because they include code inside their
expressions.

Provide a way to support this, with new ll_start_decl() and
ll_end_decl() macros.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

 include/linker_lists.h | 51 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/include/linker_lists.h b/include/linker_lists.h
index f9a2ee0c762..c05b99c886f 100644
--- a/include/linker_lists.h
+++ b/include/linker_lists.h
@@ -186,6 +186,57 @@
 		_ll_result;						\
 	})
 
+/**
+ * Declares a symbol that points to the start/end of the list. The name of the
+ * (new) symbol is arbitrary and can be anything that is not already declared in
+ * the file where it appears. It is provided in _sym and can then be used (later
+ * in the same file) within a data structure.
+ *
+ * The _type and _list arguments must match those passed to ll_entry_start/end()
+ *
+ * Example:
+ *
+ * ::
+ *   Here we want to record the start of each sub-command in a list. We have two
+ *   sub-commands, 'bob' and 'mary'.
+ *
+ *   In bob.c:
+ *     ll_entry_declare(struct my_sub_cmd, bob_cmd, cmd_sub) = {...}
+ *
+ *   In mary.c:
+ *     ll_entry_declare(struct my_sub_cmd, mary_cmd, cmd_sub) = {...}
+ *
+ *   In a different file where we want a list the start of all sub-commands.
+ *   It is not possible to use ll_entry_start() in a data structure, due to its
+ *   use of code inside expressions - ({ ... }) - so this fails to compile:
+ *
+ *   In sub_cmds.c:
+ *     struct cmd_sub *my_list[] = {
+ *       ll_entry_start(cmd_sub, bob),
+ *       ll_entry_start(cmd_sub, bob),
+ *     }
+ *
+ *   Instead, we can use:
+ *
+ *     ll_start_decl(bob, struct my_sub_cmd, cmd_sub);
+ *     ll_start_decl(mary, struct my_sub_cmd, cmd_sub);
+ *
+ *     struct cmd_sub *my_list[] = {
+ *       bob,
+ *       mary,
+ *     }
+ *
+ *     So 'bob' is declared as symbol, a struct my_list * which points to the
+ *     start of the bob sub-commands. It is then used in my_list[]
+ */
+#define ll_start_decl(_sym, _type, _list)					\
+	static _type _sym[0] __aligned(CONFIG_LINKER_LIST_ALIGN)	\
+		__maybe_unused __section("__u_boot_list_2_" #_list "_1")
+
+#define ll_end_decl(_sym, _type, _list)					\
+	static _type _sym[0] __aligned(CONFIG_LINKER_LIST_ALIGN)	\
+		__maybe_unused __section("__u_boot_list_2_" #_list "_3")
+
 /**
  * ll_entry_get() - Retrieve entry from linker-generated array by name
  * @_type:	Data type of the entry
-- 
2.34.1



More information about the U-Boot mailing list