diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/libbb.h | 34 |
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 */ |
371 | extern int *const bb_errno; | 385 | extern 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) */ |
2271 | extern struct globals *const ptr_to_globals; | 2285 | extern 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; | |||
2277 | static ALWAYS_INLINE void* not_const_pp(const void *p) | 2293 | static 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) | |||
2288 | static ALWAYS_INLINE void* not_const_pp(const void *p) { return (void*)p; } | 2304 | static 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); \ |