]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
linker_lists: Rework start/end macros to not rely on undefined behavior
authorTom Rini <trini@konsulko.com>
Tue, 28 Mar 2023 18:54:51 +0000 (14:54 -0400)
committerTom Rini <trini@konsulko.com>
Tue, 4 Apr 2023 16:24:29 +0000 (12:24 -0400)
Per the GCC bug listed below, the way we do linker lists is relying on
undefined behavior that seems to work in gcc, but doesn't always work in
clang. Andrew suggests rewriting our start/end macros in a different way
(as implemented here, from what he said in comment 1) to avoid these
problems.

Reported-by: AdityaK <appujee@google.com>
Suggested-by: Andrew Pinski <apinski@marvell.com>
Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108915
Signed-off-by: Tom Rini <trini@konsulko.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Andrew Pinski <apinski@marvell.com>
include/linker_lists.h

index d3da9d44e8530b8bb17743e57a537da027af3ffc..f9a2ee0c762ac93501f36a0178250a81367e077e 100644 (file)
        static char start[0] __aligned(CONFIG_LINKER_LIST_ALIGN)        \
                __attribute__((unused))                                 \
                __section("__u_boot_list_2_"#_list"_1");                        \
-       (_type *)&start;                                                \
+       _type * tmp = (_type *)&start;                                  \
+       asm("":"+r"(tmp));                                              \
+       tmp;                                                            \
 })
 
 /**
 ({                                                                     \
        static char end[0] __aligned(4) __attribute__((unused))         \
                __section("__u_boot_list_2_"#_list"_3");                        \
-       (_type *)&end;                                                  \
+       _type * tmp = (_type *)&end;                                    \
+       asm("":"+r"(tmp));                                              \
+       tmp;                                                            \
 })
 /**
  * ll_entry_count() - Return the number of elements in linker-generated array
 ({                                                                     \
        static char start[0] __aligned(4) __attribute__((unused))       \
                __section("__u_boot_list_1");                           \
-       (_type *)&start;                                                \
+       _type * tmp = (_type *)&start;                                  \
+       asm("":"+r"(tmp));                                              \
+       tmp;                                                            \
 })
 
 /**
 ({                                                                     \
        static char end[0] __aligned(4) __attribute__((unused))         \
                __section("__u_boot_list_3");                           \
-       (_type *)&end;                                                  \
+       _type * tmp = (_type *)&end;                                    \
+       asm("":"+r"(tmp));                                              \
+       tmp;                                                            \
 })
 
 #endif /* __ASSEMBLY__ */