diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/libbb.h | 75 |
1 files changed, 49 insertions, 26 deletions
diff --git a/include/libbb.h b/include/libbb.h index 3a958b555..098619305 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -324,9 +324,13 @@ typedef unsigned long long uoff_t; | |||
324 | # endif | 324 | # endif |
325 | #else | 325 | #else |
326 | /* CONFIG_LFS is off */ | 326 | /* CONFIG_LFS is off */ |
327 | # if UINT_MAX == 0xffffffff | 327 | /* sizeof(off_t) == sizeof(long). |
328 | /* While sizeof(off_t) == sizeof(int), off_t is typedef'ed to long anyway. | 328 | * May or may not be == sizeof(int). If it is, use xatoi_positive() |
329 | * gcc will throw warnings on printf("%d", off_t). Crap... */ | 329 | * and bb_strtou() instead of xatoul_range() and bb_strtoul(). |
330 | * Even if sizeof(off_t) == sizeof(int), off_t is typedef'ed to long anyway. | ||
331 | * gcc will throw warnings on printf("%d", off_t)... Have to use %ld etc. | ||
332 | */ | ||
333 | # if UINT_MAX == ULONG_MAX | ||
330 | typedef unsigned long uoff_t; | 334 | typedef unsigned long uoff_t; |
331 | # define XATOOFF(a) xatoi_positive(a) | 335 | # define XATOOFF(a) xatoi_positive(a) |
332 | # define BB_STRTOOFF bb_strtou | 336 | # define BB_STRTOOFF bb_strtou |
@@ -384,13 +388,27 @@ struct BUG_off_t_size_is_misdetected { | |||
384 | #endif | 388 | #endif |
385 | #endif | 389 | #endif |
386 | 390 | ||
391 | /* We use a trick to have more optimized code (fewer pointer reloads | ||
392 | * and reduced binary size by a few kilobytes) like: | ||
393 | * ash.c: extern struct globals *const ash_ptr_to_globals; | ||
394 | * ash_ptr_hack.c: struct globals *ash_ptr_to_globals; | ||
395 | * This way, compiler in ash.c knows the pointer can not change. | ||
396 | * | ||
397 | * However, this may break on weird arches or toolchains. In this case, | ||
398 | * set "-DBB_GLOBAL_CONST=''" in CONFIG_EXTRA_CFLAGS to disable | ||
399 | * this optimization. | ||
400 | */ | ||
401 | #ifndef BB_GLOBAL_CONST | ||
402 | # define BB_GLOBAL_CONST const | ||
403 | #endif | ||
404 | |||
387 | #if defined(errno) | 405 | #if defined(errno) |
388 | /* If errno is a define, assume it's "define errno (*__errno_location())" | 406 | /* If errno is a define, assume it's "define errno (*__errno_location())" |
389 | * and we will cache it's result in this variable */ | 407 | * and we will cache it's result in this variable */ |
390 | extern int *const bb_errno; | 408 | extern int *BB_GLOBAL_CONST bb_errno; |
391 | #undef errno | 409 | # undef errno |
392 | #define errno (*bb_errno) | 410 | # define errno (*bb_errno) |
393 | #define bb_cached_errno_ptr 1 | 411 | # define bb_cached_errno_ptr 1 |
394 | #endif | 412 | #endif |
395 | 413 | ||
396 | #if !(ULONG_MAX > 0xffffffff) | 414 | #if !(ULONG_MAX > 0xffffffff) |
@@ -579,7 +597,7 @@ DIR *xopendir(const char *path) FAST_FUNC; | |||
579 | DIR *warn_opendir(const char *path) FAST_FUNC; | 597 | DIR *warn_opendir(const char *path) FAST_FUNC; |
580 | 598 | ||
581 | char *xmalloc_realpath(const char *path) FAST_FUNC RETURNS_MALLOC; | 599 | char *xmalloc_realpath(const char *path) FAST_FUNC RETURNS_MALLOC; |
582 | char *xmalloc_realpath_coreutils(const char *path) FAST_FUNC RETURNS_MALLOC; | 600 | char *xmalloc_realpath_coreutils(char *path) FAST_FUNC RETURNS_MALLOC; |
583 | char *xmalloc_readlink(const char *path) FAST_FUNC RETURNS_MALLOC; | 601 | char *xmalloc_readlink(const char *path) FAST_FUNC RETURNS_MALLOC; |
584 | char *xmalloc_readlink_or_warn(const char *path) FAST_FUNC RETURNS_MALLOC; | 602 | char *xmalloc_readlink_or_warn(const char *path) FAST_FUNC RETURNS_MALLOC; |
585 | /* !RETURNS_MALLOC: it's a realloc-like function */ | 603 | /* !RETURNS_MALLOC: it's a realloc-like function */ |
@@ -1297,8 +1315,10 @@ void run_applet_no_and_exit(int a, const char *name, char **argv) NORETURN FAST_ | |||
1297 | #endif | 1315 | #endif |
1298 | void show_usage_if_dash_dash_help(int applet_no, char **argv) FAST_FUNC; | 1316 | void show_usage_if_dash_dash_help(int applet_no, char **argv) FAST_FUNC; |
1299 | #if defined(__linux__) | 1317 | #if defined(__linux__) |
1318 | int re_execed_comm(void) FAST_FUNC; | ||
1300 | void set_task_comm(const char *comm) FAST_FUNC; | 1319 | void set_task_comm(const char *comm) FAST_FUNC; |
1301 | #else | 1320 | #else |
1321 | # define re_execed_comm() 0 | ||
1302 | # define set_task_comm(name) ((void)0) | 1322 | # define set_task_comm(name) ((void)0) |
1303 | #endif | 1323 | #endif |
1304 | 1324 | ||
@@ -1526,16 +1546,8 @@ int scripted_main(int argc, char** argv) MAIN_EXTERNALLY_VISIBLE; | |||
1526 | 1546 | ||
1527 | /* Applets which are useful from another applets */ | 1547 | /* Applets which are useful from another applets */ |
1528 | int bb_cat(char** argv) FAST_FUNC; | 1548 | int bb_cat(char** argv) FAST_FUNC; |
1529 | int ash_main(int argc, char** argv) | 1549 | int ash_main(int argc, char** argv) IF_SHELL_ASH(MAIN_EXTERNALLY_VISIBLE); |
1530 | #if ENABLE_ASH || ENABLE_SH_IS_ASH || ENABLE_BASH_IS_ASH | 1550 | int hush_main(int argc, char** argv) IF_SHELL_HUSH(MAIN_EXTERNALLY_VISIBLE); |
1531 | MAIN_EXTERNALLY_VISIBLE | ||
1532 | #endif | ||
1533 | ; | ||
1534 | int hush_main(int argc, char** argv) | ||
1535 | #if ENABLE_HUSH || ENABLE_SH_IS_HUSH || ENABLE_BASH_IS_HUSH | ||
1536 | MAIN_EXTERNALLY_VISIBLE | ||
1537 | #endif | ||
1538 | ; | ||
1539 | /* If shell needs them, they exist even if not enabled as applets */ | 1551 | /* If shell needs them, they exist even if not enabled as applets */ |
1540 | int echo_main(int argc, char** argv) IF_ECHO(MAIN_EXTERNALLY_VISIBLE); | 1552 | int echo_main(int argc, char** argv) IF_ECHO(MAIN_EXTERNALLY_VISIBLE); |
1541 | int printf_main(int argc, char **argv) IF_PRINTF(MAIN_EXTERNALLY_VISIBLE); | 1553 | int printf_main(int argc, char **argv) IF_PRINTF(MAIN_EXTERNALLY_VISIBLE); |
@@ -2331,6 +2343,7 @@ extern const char bb_PATH_root_path[] ALIGN1; /* BB_PATH_ROOT_PATH */ | |||
2331 | extern const int const_int_0; | 2343 | extern const int const_int_0; |
2332 | //extern const int const_int_1; | 2344 | //extern const int const_int_1; |
2333 | 2345 | ||
2346 | |||
2334 | /* This struct is deliberately not defined. */ | 2347 | /* This struct is deliberately not defined. */ |
2335 | /* See docs/keep_data_small.txt */ | 2348 | /* See docs/keep_data_small.txt */ |
2336 | struct globals; | 2349 | struct globals; |
@@ -2339,6 +2352,8 @@ struct globals; | |||
2339 | * If you want to assign a value, use SET_PTR_TO_GLOBALS(x) */ | 2352 | * If you want to assign a value, use SET_PTR_TO_GLOBALS(x) */ |
2340 | extern struct globals *const ptr_to_globals; | 2353 | extern struct globals *const ptr_to_globals; |
2341 | 2354 | ||
2355 | #define barrier() asm volatile ("":::"memory") | ||
2356 | |||
2342 | #if defined(__clang_major__) && __clang_major__ >= 9 | 2357 | #if defined(__clang_major__) && __clang_major__ >= 9 |
2343 | /* Clang/llvm drops assignment to "constant" storage. Silently. | 2358 | /* Clang/llvm drops assignment to "constant" storage. Silently. |
2344 | * Needs serious convincing to not eliminate the store. | 2359 | * Needs serious convincing to not eliminate the store. |
@@ -2346,30 +2361,38 @@ extern struct globals *const ptr_to_globals; | |||
2346 | static ALWAYS_INLINE void* not_const_pp(const void *p) | 2361 | static ALWAYS_INLINE void* not_const_pp(const void *p) |
2347 | { | 2362 | { |
2348 | void *pp; | 2363 | void *pp; |
2349 | __asm__ __volatile__( | 2364 | asm volatile ( |
2350 | "# forget that p points to const" | 2365 | "# forget that p points to const" |
2351 | : /*outputs*/ "=r" (pp) | 2366 | : /*outputs*/ "=r" (pp) |
2352 | : /*inputs*/ "0" (p) | 2367 | : /*inputs*/ "0" (p) |
2353 | ); | 2368 | ); |
2354 | return pp; | 2369 | return pp; |
2355 | } | 2370 | } |
2371 | # define ASSIGN_CONST_PTR(pptr, v) do { \ | ||
2372 | *(void**)not_const_pp(pptr) = (void*)(v); \ | ||
2373 | barrier(); \ | ||
2374 | } while (0) | ||
2375 | /* XZALLOC_CONST_PTR() is an out-of-line function to prevent | ||
2376 | * clang from reading pointer before it is assigned. | ||
2377 | */ | ||
2378 | void XZALLOC_CONST_PTR(const void *pptr, size_t size) FAST_FUNC; | ||
2356 | #else | 2379 | #else |
2357 | static ALWAYS_INLINE void* not_const_pp(const void *p) { return (void*)p; } | 2380 | # define ASSIGN_CONST_PTR(pptr, v) do { \ |
2358 | #endif | 2381 | *(void**)(pptr) = (void*)(v); \ |
2359 | 2382 | /* At least gcc 3.4.6 on mipsel needs optimization barrier */ \ | |
2360 | /* At least gcc 3.4.6 on mipsel system needs optimization barrier */ | ||
2361 | #define barrier() __asm__ __volatile__("":::"memory") | ||
2362 | #define SET_PTR_TO_GLOBALS(x) do { \ | ||
2363 | (*(struct globals**)not_const_pp(&ptr_to_globals)) = (void*)(x); \ | ||
2364 | barrier(); \ | 2383 | barrier(); \ |
2365 | } while (0) | 2384 | } while (0) |
2385 | # define XZALLOC_CONST_PTR(pptr, size) ASSIGN_CONST_PTR(pptr, xzalloc(size)) | ||
2386 | #endif | ||
2366 | 2387 | ||
2388 | #define SET_PTR_TO_GLOBALS(x) ASSIGN_CONST_PTR(&ptr_to_globals, x) | ||
2367 | #define FREE_PTR_TO_GLOBALS() do { \ | 2389 | #define FREE_PTR_TO_GLOBALS() do { \ |
2368 | if (ENABLE_FEATURE_CLEAN_UP) { \ | 2390 | if (ENABLE_FEATURE_CLEAN_UP) { \ |
2369 | free(ptr_to_globals); \ | 2391 | free(ptr_to_globals); \ |
2370 | } \ | 2392 | } \ |
2371 | } while (0) | 2393 | } while (0) |
2372 | 2394 | ||
2395 | |||
2373 | /* You can change LIBBB_DEFAULT_LOGIN_SHELL, but don't use it, | 2396 | /* You can change LIBBB_DEFAULT_LOGIN_SHELL, but don't use it, |
2374 | * use bb_default_login_shell and following defines. | 2397 | * use bb_default_login_shell and following defines. |
2375 | * If you change LIBBB_DEFAULT_LOGIN_SHELL, | 2398 | * If you change LIBBB_DEFAULT_LOGIN_SHELL, |