aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/libbb.h34
1 files changed, 25 insertions, 9 deletions
diff --git a/include/libbb.h b/include/libbb.h
index dfcaa05ec..02cc008f0 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -365,13 +365,27 @@ struct BUG_off_t_size_is_misdetected {
365#endif 365#endif
366#endif 366#endif
367 367
368/* We use a trick to have more optimized code (fewer pointer reloads
369 * and reduced binary size by a few kilobytes) like:
370 * ash.c: extern struct globals *const ash_ptr_to_globals;
371 * ash_ptr_hack.c: struct globals *ash_ptr_to_globals;
372 * This way, compiler in ash.c knows the pointer can not change.
373 *
374 * However, this may break on weird arches or toolchains. In this case,
375 * set "-DBB_GLOBAL_CONST=''" in CONFIG_EXTRA_CFLAGS to disable
376 * this optimization.
377 */
378#ifndef BB_GLOBAL_CONST
379# define BB_GLOBAL_CONST const
380#endif
381
368#if defined(errno) 382#if defined(errno)
369/* If errno is a define, assume it's "define errno (*__errno_location())" 383/* If errno is a define, assume it's "define errno (*__errno_location())"
370 * and we will cache it's result in this variable */ 384 * and we will cache it's result in this variable */
371extern int *const bb_errno; 385extern int *BB_GLOBAL_CONST bb_errno;
372#undef errno 386# undef errno
373#define errno (*bb_errno) 387# define errno (*bb_errno)
374#define bb_cached_errno_ptr 1 388# define bb_cached_errno_ptr 1
375#endif 389#endif
376 390
377#if !(ULONG_MAX > 0xffffffff) 391#if !(ULONG_MAX > 0xffffffff)
@@ -2270,6 +2284,8 @@ struct globals;
2270 * If you want to assign a value, use SET_PTR_TO_GLOBALS(x) */ 2284 * If you want to assign a value, use SET_PTR_TO_GLOBALS(x) */
2271extern struct globals *const ptr_to_globals; 2285extern struct globals *const ptr_to_globals;
2272 2286
2287#define barrier() asm volatile ("":::"memory")
2288
2273#if defined(__clang_major__) && __clang_major__ >= 9 2289#if defined(__clang_major__) && __clang_major__ >= 9
2274/* Clang/llvm drops assignment to "constant" storage. Silently. 2290/* Clang/llvm drops assignment to "constant" storage. Silently.
2275 * Needs serious convincing to not eliminate the store. 2291 * Needs serious convincing to not eliminate the store.
@@ -2277,7 +2293,7 @@ extern struct globals *const ptr_to_globals;
2277static ALWAYS_INLINE void* not_const_pp(const void *p) 2293static ALWAYS_INLINE void* not_const_pp(const void *p)
2278{ 2294{
2279 void *pp; 2295 void *pp;
2280 __asm__ __volatile__( 2296 asm volatile (
2281 "# forget that p points to const" 2297 "# forget that p points to const"
2282 : /*outputs*/ "=r" (pp) 2298 : /*outputs*/ "=r" (pp)
2283 : /*inputs*/ "0" (p) 2299 : /*inputs*/ "0" (p)
@@ -2288,13 +2304,13 @@ static ALWAYS_INLINE void* not_const_pp(const void *p)
2288static ALWAYS_INLINE void* not_const_pp(const void *p) { return (void*)p; } 2304static ALWAYS_INLINE void* not_const_pp(const void *p) { return (void*)p; }
2289#endif 2305#endif
2290 2306
2291/* At least gcc 3.4.6 on mipsel system needs optimization barrier */ 2307#define ASSIGN_CONST_PTR(p, v) do { \
2292#define barrier() __asm__ __volatile__("":::"memory") 2308 *(void**)not_const_pp(&p) = (void*)(v); \
2293#define SET_PTR_TO_GLOBALS(x) do { \ 2309 /* At least gcc 3.4.6 on mipsel needs optimization barrier */ \
2294 (*(struct globals**)not_const_pp(&ptr_to_globals)) = (void*)(x); \
2295 barrier(); \ 2310 barrier(); \
2296} while (0) 2311} while (0)
2297 2312
2313#define SET_PTR_TO_GLOBALS(x) ASSIGN_CONST_PTR(ptr_to_globals, x)
2298#define FREE_PTR_TO_GLOBALS() do { \ 2314#define FREE_PTR_TO_GLOBALS() do { \
2299 if (ENABLE_FEATURE_CLEAN_UP) { \ 2315 if (ENABLE_FEATURE_CLEAN_UP) { \
2300 free(ptr_to_globals); \ 2316 free(ptr_to_globals); \