From: YU Jincheng <[email protected]>

- This can act as memory barrier in clang to avoid
  read before assign of a const ptr

Signed-off-by: LoveSy <[email protected]>
---
 coreutils/test.c   |  2 +-
 include/libbb.h    | 16 +++++++++-------
 libbb/Kbuild.src   |  1 +
 libbb/appletlib.c  |  2 +-
 libbb/const_hack.c | 16 ++++++++++++++++
 libbb/lineedit.c   |  2 +-
 shell/ash.c        |  6 +++---
 7 files changed, 32 insertions(+), 13 deletions(-)
 create mode 100644 libbb/const_hack.c

diff --git a/coreutils/test.c b/coreutils/test.c
index fc956724b..a914c7490 100644
--- a/coreutils/test.c
+++ b/coreutils/test.c
@@ -446,7 +446,7 @@ extern struct test_statics *BB_GLOBAL_CONST 
test_ptr_to_statics;
 #define leaving         (S.leaving      )
 
 #define INIT_S() do { \
-       ASSIGN_CONST_PTR(test_ptr_to_statics, xzalloc(sizeof(S))); \
+       XZALLOC_CONST_PTR(&test_ptr_to_statics, sizeof(S)); \
 } while (0)
 #define DEINIT_S() do { \
        free(group_array); \
diff --git a/include/libbb.h b/include/libbb.h
index 296417dae..75ac4ddf5 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -2290,6 +2290,12 @@ extern struct globals *const ptr_to_globals;
 
 #define barrier() asm volatile ("":::"memory")
 
+#define ASSIGN_CONST_PTR(p, v) do { \
+       *(void**)not_const_pp(p) = (void*)(v); \
+       /* At least gcc 3.4.6 on mipsel needs optimization barrier */ \
+       barrier(); \
+} while (0)
+
 #if defined(__clang_major__) && __clang_major__ >= 9
 /* Clang/llvm drops assignment to "constant" storage. Silently.
  * Needs serious convincing to not eliminate the store.
@@ -2304,17 +2310,13 @@ static ALWAYS_INLINE void* not_const_pp(const void *p)
        );
        return pp;
 }
+void XZALLOC_CONST_PTR(const void** ptr, size_t size);
 #else
 static ALWAYS_INLINE void* not_const_pp(const void *p) { return (void*)p; }
+# define XZALLOC_CONST_PTR(ptr, size) ASSIGN_CONST_PTR(ptr, xzalloc(size))
 #endif
 
-#define ASSIGN_CONST_PTR(p, v) do { \
-       *(void**)not_const_pp(&p) = (void*)(v); \
-       /* At least gcc 3.4.6 on mipsel needs optimization barrier */ \
-       barrier(); \
-} while (0)
-
-#define SET_PTR_TO_GLOBALS(x) ASSIGN_CONST_PTR(ptr_to_globals, x)
+#define SET_PTR_TO_GLOBALS(x) ASSIGN_CONST_PTR(&ptr_to_globals, x)
 #define FREE_PTR_TO_GLOBALS() do { \
        if (ENABLE_FEATURE_CLEAN_UP) { \
                free(ptr_to_globals); \
diff --git a/libbb/Kbuild.src b/libbb/Kbuild.src
index 676300801..2fa239857 100644
--- a/libbb/Kbuild.src
+++ b/libbb/Kbuild.src
@@ -24,6 +24,7 @@ lib-y += chomp.o
 lib-y += compare_string_array.o
 lib-y += concat_path_file.o
 lib-y += concat_subpath_file.o
+lib-y += const_hack.o
 lib-y += copy_file.o
 lib-y += copyfd.o
 lib-y += crc32.o
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index bf26c99e9..e8c308467 100644
--- a/libbb/appletlib.c
+++ b/libbb/appletlib.c
@@ -247,7 +247,7 @@ void lbb_prepare(const char *applet
                IF_FEATURE_INDIVIDUAL(, char **argv))
 {
 #ifdef bb_cached_errno_ptr
-       ASSIGN_CONST_PTR(bb_errno, get_perrno());
+       ASSIGN_CONST_PTR(&bb_errno, get_perrno());
 #endif
        applet_name = applet;
 
diff --git a/libbb/const_hack.c b/libbb/const_hack.c
new file mode 100644
index 000000000..d5fd161bf
--- /dev/null
+++ b/libbb/const_hack.c
@@ -0,0 +1,16 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Trick to assign a const ptr with barrier for clang
+ *
+ * Copyright (C) 2021 by YU Jincheng <[email protected]>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
+ */
+
+#include "libbb.h"
+
+#if defined(__clang_major__) && __clang_major__ >= 9
+void XZALLOC_CONST_PTR(const void** ptr, size_t size) {
+       ASSIGN_CONST_PTR(ptr, xzalloc(size));
+}
+#endif
\ No newline at end of file
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index 3c87abcf9..9960448ec 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -214,7 +214,7 @@ extern struct lineedit_statics *BB_GLOBAL_CONST 
lineedit_ptr_to_statics;
 #define delbuf           (S.delbuf          )
 
 #define INIT_S() do { \
-       ASSIGN_CONST_PTR(lineedit_ptr_to_statics, xzalloc(sizeof(S))); \
+       XZALLOC_CONST_PTR(&lineedit_ptr_to_statics, sizeof(S)); \
 } while (0)
 
 static void deinit_S(void)
diff --git a/shell/ash.c b/shell/ash.c
index 199975191..2d3cc8a61 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -504,7 +504,7 @@ extern struct globals_misc *BB_GLOBAL_CONST 
ash_ptr_to_globals_misc;
 #define random_gen  (G_misc.random_gen )
 #define backgndpid  (G_misc.backgndpid )
 #define INIT_G_misc() do { \
-       ASSIGN_CONST_PTR(ash_ptr_to_globals_misc, xzalloc(sizeof(G_misc))); \
+       XZALLOC_CONST_PTR(&ash_ptr_to_globals_misc, sizeof(G_misc)); \
        savestatus = -1; \
        curdir = nullstr; \
        physdir = nullstr; \
@@ -1582,7 +1582,7 @@ extern struct globals_memstack *BB_GLOBAL_CONST 
ash_ptr_to_globals_memstack;
 #define g_stacknleft (G_memstack.g_stacknleft)
 #define stackbase    (G_memstack.stackbase   )
 #define INIT_G_memstack() do { \
-       ASSIGN_CONST_PTR(ash_ptr_to_globals_memstack, 
xzalloc(sizeof(G_memstack))); \
+       XZALLOC_CONST_PTR(&ash_ptr_to_globals_memstack, sizeof(G_memstack)); \
        g_stackp = &stackbase; \
        g_stacknxt = stackbase.space; \
        g_stacknleft = MINSIZE; \
@@ -2213,7 +2213,7 @@ extern struct globals_var *BB_GLOBAL_CONST 
ash_ptr_to_globals_var;
 #endif
 #define INIT_G_var() do { \
        unsigned i; \
-       ASSIGN_CONST_PTR(ash_ptr_to_globals_var, xzalloc(sizeof(G_var))); \
+       XZALLOC_CONST_PTR(&ash_ptr_to_globals_var, sizeof(G_var)); \
        for (i = 0; i < ARRAY_SIZE(varinit_data); i++) { \
                varinit[i].flags    = varinit_data[i].flags; \
                varinit[i].var_text = varinit_data[i].var_text; \
-- 
2.25.1

_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to