aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYU Jincheng <shana@zju.edu.cn>2021-10-10 02:19:51 +0800
committerDenys Vlasenko <vda.linux@googlemail.com>2021-10-09 22:30:45 +0200
commit5156b245536ce0f07165793f07c63fd9fa5dd3b7 (patch)
tree3b73b7ea8ed1830d9cc13cbce1da6918926553e2
parent04ad683bf99333c2a6c6fd6549faa67978ad9a98 (diff)
downloadbusybox-w32-5156b245536ce0f07165793f07c63fd9fa5dd3b7.tar.gz
busybox-w32-5156b245536ce0f07165793f07c63fd9fa5dd3b7.tar.bz2
busybox-w32-5156b245536ce0f07165793f07c63fd9fa5dd3b7.zip
Make const ptr assign as function call in clang
- This can act as memory barrier in clang to avoid read before assign of a const ptr Signed-off-by: LoveSy <shana@zju.edu.cn> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--coreutils/test.c2
-rw-r--r--include/libbb.h21
-rw-r--r--libbb/Kbuild.src1
-rw-r--r--libbb/appletlib.c2
-rw-r--r--libbb/const_hack.c16
-rw-r--r--libbb/lineedit.c2
-rw-r--r--shell/ash.c6
7 files changed, 38 insertions, 12 deletions
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;
446#define leaving (S.leaving ) 446#define leaving (S.leaving )
447 447
448#define INIT_S() do { \ 448#define INIT_S() do { \
449 ASSIGN_CONST_PTR(test_ptr_to_statics, xzalloc(sizeof(S))); \ 449 XZALLOC_CONST_PTR(&test_ptr_to_statics, sizeof(S)); \
450} while (0) 450} while (0)
451#define DEINIT_S() do { \ 451#define DEINIT_S() do { \
452 free(group_array); \ 452 free(group_array); \
diff --git a/include/libbb.h b/include/libbb.h
index 296417dae..a340f27d2 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -2280,6 +2280,7 @@ extern const char bb_PATH_root_path[] ALIGN1; /* BB_PATH_ROOT_PATH */
2280extern const int const_int_0; 2280extern const int const_int_0;
2281//extern const int const_int_1; 2281//extern const int const_int_1;
2282 2282
2283
2283/* This struct is deliberately not defined. */ 2284/* This struct is deliberately not defined. */
2284/* See docs/keep_data_small.txt */ 2285/* See docs/keep_data_small.txt */
2285struct globals; 2286struct globals;
@@ -2304,23 +2305,31 @@ static ALWAYS_INLINE void* not_const_pp(const void *p)
2304 ); 2305 );
2305 return pp; 2306 return pp;
2306} 2307}
2308# define ASSIGN_CONST_PTR(pptr, v) do { \
2309 *(void**)not_const_pp(pptr) = (void*)(v); \
2310 barrier(); \
2311} while (0)
2312/* XZALLOC_CONST_PTR() is an out-of-line function to prevent
2313 * clang from reading pointer before it is assigned.
2314 */
2315void XZALLOC_CONST_PTR(const void *pptr, size_t size) FAST_FUNC;
2307#else 2316#else
2308static ALWAYS_INLINE void* not_const_pp(const void *p) { return (void*)p; } 2317# define ASSIGN_CONST_PTR(pptr, v) do { \
2309#endif 2318 *(void**)(pptr) = (void*)(v); \
2310
2311#define ASSIGN_CONST_PTR(p, v) do { \
2312 *(void**)not_const_pp(&p) = (void*)(v); \
2313 /* At least gcc 3.4.6 on mipsel needs optimization barrier */ \ 2319 /* At least gcc 3.4.6 on mipsel needs optimization barrier */ \
2314 barrier(); \ 2320 barrier(); \
2315} while (0) 2321} while (0)
2322# define XZALLOC_CONST_PTR(pptr, size) ASSIGN_CONST_PTR(pptr, xzalloc(size))
2323#endif
2316 2324
2317#define SET_PTR_TO_GLOBALS(x) ASSIGN_CONST_PTR(ptr_to_globals, x) 2325#define SET_PTR_TO_GLOBALS(x) ASSIGN_CONST_PTR(&ptr_to_globals, x)
2318#define FREE_PTR_TO_GLOBALS() do { \ 2326#define FREE_PTR_TO_GLOBALS() do { \
2319 if (ENABLE_FEATURE_CLEAN_UP) { \ 2327 if (ENABLE_FEATURE_CLEAN_UP) { \
2320 free(ptr_to_globals); \ 2328 free(ptr_to_globals); \
2321 } \ 2329 } \
2322} while (0) 2330} while (0)
2323 2331
2332
2324/* You can change LIBBB_DEFAULT_LOGIN_SHELL, but don't use it, 2333/* You can change LIBBB_DEFAULT_LOGIN_SHELL, but don't use it,
2325 * use bb_default_login_shell and following defines. 2334 * use bb_default_login_shell and following defines.
2326 * If you change LIBBB_DEFAULT_LOGIN_SHELL, 2335 * If you change LIBBB_DEFAULT_LOGIN_SHELL,
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
24lib-y += compare_string_array.o 24lib-y += compare_string_array.o
25lib-y += concat_path_file.o 25lib-y += concat_path_file.o
26lib-y += concat_subpath_file.o 26lib-y += concat_subpath_file.o
27lib-y += const_hack.o
27lib-y += copy_file.o 28lib-y += copy_file.o
28lib-y += copyfd.o 29lib-y += copyfd.o
29lib-y += crc32.o 30lib-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
247 IF_FEATURE_INDIVIDUAL(, char **argv)) 247 IF_FEATURE_INDIVIDUAL(, char **argv))
248{ 248{
249#ifdef bb_cached_errno_ptr 249#ifdef bb_cached_errno_ptr
250 ASSIGN_CONST_PTR(bb_errno, get_perrno()); 250 ASSIGN_CONST_PTR(&bb_errno, get_perrno());
251#endif 251#endif
252 applet_name = applet; 252 applet_name = applet;
253 253
diff --git a/libbb/const_hack.c b/libbb/const_hack.c
new file mode 100644
index 000000000..9575e6d67
--- /dev/null
+++ b/libbb/const_hack.c
@@ -0,0 +1,16 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * Trick to assign a const ptr with barrier for clang
4 *
5 * Copyright (C) 2021 by YU Jincheng <shana@zju.edu.cn>
6 *
7 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
8 */
9#include "libbb.h"
10
11#if defined(__clang_major__) && __clang_major__ >= 9
12void FAST_FUNC XZALLOC_CONST_PTR(const void *pptr, size_t size)
13{
14 ASSIGN_CONST_PTR(pptr, xzalloc(size));
15}
16#endif
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;
214#define delbuf (S.delbuf ) 214#define delbuf (S.delbuf )
215 215
216#define INIT_S() do { \ 216#define INIT_S() do { \
217 ASSIGN_CONST_PTR(lineedit_ptr_to_statics, xzalloc(sizeof(S))); \ 217 XZALLOC_CONST_PTR(&lineedit_ptr_to_statics, sizeof(S)); \
218} while (0) 218} while (0)
219 219
220static void deinit_S(void) 220static 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;
504#define random_gen (G_misc.random_gen ) 504#define random_gen (G_misc.random_gen )
505#define backgndpid (G_misc.backgndpid ) 505#define backgndpid (G_misc.backgndpid )
506#define INIT_G_misc() do { \ 506#define INIT_G_misc() do { \
507 ASSIGN_CONST_PTR(ash_ptr_to_globals_misc, xzalloc(sizeof(G_misc))); \ 507 XZALLOC_CONST_PTR(&ash_ptr_to_globals_misc, sizeof(G_misc)); \
508 savestatus = -1; \ 508 savestatus = -1; \
509 curdir = nullstr; \ 509 curdir = nullstr; \
510 physdir = nullstr; \ 510 physdir = nullstr; \
@@ -1582,7 +1582,7 @@ extern struct globals_memstack *BB_GLOBAL_CONST ash_ptr_to_globals_memstack;
1582#define g_stacknleft (G_memstack.g_stacknleft) 1582#define g_stacknleft (G_memstack.g_stacknleft)
1583#define stackbase (G_memstack.stackbase ) 1583#define stackbase (G_memstack.stackbase )
1584#define INIT_G_memstack() do { \ 1584#define INIT_G_memstack() do { \
1585 ASSIGN_CONST_PTR(ash_ptr_to_globals_memstack, xzalloc(sizeof(G_memstack))); \ 1585 XZALLOC_CONST_PTR(&ash_ptr_to_globals_memstack, sizeof(G_memstack)); \
1586 g_stackp = &stackbase; \ 1586 g_stackp = &stackbase; \
1587 g_stacknxt = stackbase.space; \ 1587 g_stacknxt = stackbase.space; \
1588 g_stacknleft = MINSIZE; \ 1588 g_stacknleft = MINSIZE; \
@@ -2213,7 +2213,7 @@ extern struct globals_var *BB_GLOBAL_CONST ash_ptr_to_globals_var;
2213#endif 2213#endif
2214#define INIT_G_var() do { \ 2214#define INIT_G_var() do { \
2215 unsigned i; \ 2215 unsigned i; \
2216 ASSIGN_CONST_PTR(ash_ptr_to_globals_var, xzalloc(sizeof(G_var))); \ 2216 XZALLOC_CONST_PTR(&ash_ptr_to_globals_var, sizeof(G_var)); \
2217 for (i = 0; i < ARRAY_SIZE(varinit_data); i++) { \ 2217 for (i = 0; i < ARRAY_SIZE(varinit_data); i++) { \
2218 varinit[i].flags = varinit_data[i].flags; \ 2218 varinit[i].flags = varinit_data[i].flags; \
2219 varinit[i].var_text = varinit_data[i].var_text; \ 2219 varinit[i].var_text = varinit_data[i].var_text; \