test: stop using lots of bss.
function old new delta test_main 425 456 +31 t_lex 69 73 +4 syntax 100 104 +4 ptr_to_statics 8 12 +4 t_wp_op 4 - -4 t_wp 4 - -4 ngroups 4 - -4 group_array 4 - -4 binop 590 585 -5 oexpr 104 97 -7 aexpr 101 94 -7 nexpr 831 820 -11 leaving 156 - -156 ------------------------------------------------------------------------------ (add/remove: 0/5 grow/shrink: 4/4 up/down: 43/-202) Total: -159 bytes text data bss dec hex filename 775098 929 9084 785111 bfad7 busybox_old 775107 933 8908 784948 bfa34 busybox_unstripped
This commit is contained in:
parent
b539c8452f
commit
6672c8e480
@ -23,7 +23,11 @@
|
|||||||
#include "libbb.h"
|
#include "libbb.h"
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
|
|
||||||
/* This is a NOEXEC applet. Be very careful! */
|
/* This is a NOFORK applet. Be very careful! */
|
||||||
|
|
||||||
|
/* test_main() is called from shells, and we need to be extra careful here.
|
||||||
|
* This is true regardless of PREFER_APPLETS and STANDALONE_SHELL
|
||||||
|
* state. */
|
||||||
|
|
||||||
|
|
||||||
/* test(1) accepts the following grammar:
|
/* test(1) accepts the following grammar:
|
||||||
@ -85,12 +89,12 @@ enum token {
|
|||||||
RPAREN,
|
RPAREN,
|
||||||
OPERAND
|
OPERAND
|
||||||
};
|
};
|
||||||
#define is_int_op(a) (((unsigned char)((a) - INTEQ)) <= 5)
|
#define is_int_op(a) (((unsigned char)((a) - INTEQ)) <= 5)
|
||||||
#define is_str_op(a) (((unsigned char)((a) - STREZ)) <= 5)
|
#define is_str_op(a) (((unsigned char)((a) - STREZ)) <= 5)
|
||||||
#define is_file_op(a) (((unsigned char)((a) - FILNT)) <= 2)
|
#define is_file_op(a) (((unsigned char)((a) - FILNT)) <= 2)
|
||||||
#define is_file_access(a) (((unsigned char)((a) - FILRD)) <= 2)
|
#define is_file_access(a) (((unsigned char)((a) - FILRD)) <= 2)
|
||||||
#define is_file_type(a) (((unsigned char)((a) - FILREG)) <= 5)
|
#define is_file_type(a) (((unsigned char)((a) - FILREG)) <= 5)
|
||||||
#define is_file_bit(a) (((unsigned char)((a) - FILSUID)) <= 2)
|
#define is_file_bit(a) (((unsigned char)((a) - FILSUID)) <= 2)
|
||||||
enum token_types {
|
enum token_types {
|
||||||
UNOP,
|
UNOP,
|
||||||
BINOP,
|
BINOP,
|
||||||
@ -153,13 +157,33 @@ typedef int64_t arith_t;
|
|||||||
typedef int arith_t;
|
typedef int arith_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Cannot eliminate these static data (do the G trick)
|
|
||||||
* because of test_main usage from other applets */
|
/* We try to minimize both static and stack usage. */
|
||||||
static char **t_wp;
|
struct statics {
|
||||||
static const struct t_op *t_wp_op;
|
char **t_wp;
|
||||||
static gid_t *group_array;
|
const struct t_op *t_wp_op;
|
||||||
static int ngroups;
|
gid_t *group_array;
|
||||||
static jmp_buf leaving;
|
int ngroups;
|
||||||
|
jmp_buf leaving;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Make it reside in writable memory, yet make compiler understand
|
||||||
|
* that it is not going to change. */
|
||||||
|
static struct statics *const ptr_to_statics __attribute__ ((section (".data")));
|
||||||
|
|
||||||
|
#define S (*ptr_to_statics)
|
||||||
|
#define t_wp (S.t_wp )
|
||||||
|
#define t_wp_op (S.t_wp_op )
|
||||||
|
#define group_array (S.group_array )
|
||||||
|
#define ngroups (S.ngroups )
|
||||||
|
#define leaving (S.leaving )
|
||||||
|
|
||||||
|
#define INIT_S() do { \
|
||||||
|
(*(struct statics**)&ptr_to_statics) = xzalloc(sizeof(S)); \
|
||||||
|
} while (0)
|
||||||
|
#define DEINIT_S() do { \
|
||||||
|
free(ptr_to_statics); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
static arith_t primary(enum token n);
|
static arith_t primary(enum token n);
|
||||||
|
|
||||||
@ -550,9 +574,13 @@ int test_main(int argc, char **argv)
|
|||||||
argv[argc] = NULL;
|
argv[argc] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We must do DEINIT_S() prior to returning */
|
||||||
|
INIT_S();
|
||||||
|
|
||||||
res = setjmp(leaving);
|
res = setjmp(leaving);
|
||||||
if (res)
|
if (res) {
|
||||||
return res;
|
goto ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* resetting ngroups is probably unnecessary. it will
|
/* resetting ngroups is probably unnecessary. it will
|
||||||
* force a new call to getgroups(), which prevents using
|
* force a new call to getgroups(), which prevents using
|
||||||
@ -565,24 +593,30 @@ int test_main(int argc, char **argv)
|
|||||||
ngroups = 0;
|
ngroups = 0;
|
||||||
|
|
||||||
/* Implement special cases from POSIX.2, section 4.62.4 */
|
/* Implement special cases from POSIX.2, section 4.62.4 */
|
||||||
if (argc == 1)
|
if (argc == 1) {
|
||||||
return 1;
|
res = 1;
|
||||||
if (argc == 2)
|
goto ret;
|
||||||
return *argv[1] == '\0';
|
}
|
||||||
//assert(argc);
|
if (argc == 2) {
|
||||||
|
res = (*argv[1] == '\0');
|
||||||
|
goto ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* remember if we saw argc==4 which wants *no* '!' test */
|
/* remember if we saw argc==4 which wants *no* '!' test */
|
||||||
_off = argc - 4;
|
_off = argc - 4;
|
||||||
if (_off ?
|
if (_off ? (LONE_CHAR(argv[1], '!'))
|
||||||
(LONE_CHAR(argv[1], '!'))
|
: (argv[1][0] != '!' || argv[1][1] != '\0')
|
||||||
: (argv[1][0] != '!' || argv[1][1] != '\0'))
|
) {
|
||||||
{
|
if (argc == 3) {
|
||||||
if (argc == 3)
|
res = (*argv[2] != '\0');
|
||||||
return *argv[2] != '\0';
|
goto ret;
|
||||||
|
}
|
||||||
|
|
||||||
t_lex(argv[2 + _off]);
|
t_lex(argv[2 + _off]);
|
||||||
if (t_wp_op && t_wp_op->op_type == BINOP) {
|
if (t_wp_op && t_wp_op->op_type == BINOP) {
|
||||||
t_wp = &argv[1 + _off];
|
t_wp = &argv[1 + _off];
|
||||||
return binop() == _off;
|
res = (binop() == _off);
|
||||||
|
goto ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t_wp = &argv[1];
|
t_wp = &argv[1];
|
||||||
@ -590,7 +624,9 @@ int test_main(int argc, char **argv)
|
|||||||
|
|
||||||
if (*t_wp != NULL && *++t_wp != NULL) {
|
if (*t_wp != NULL && *++t_wp != NULL) {
|
||||||
bb_error_msg("%s: unknown operand", *t_wp);
|
bb_error_msg("%s: unknown operand", *t_wp);
|
||||||
return 2;
|
res = 2;
|
||||||
}
|
}
|
||||||
|
ret:
|
||||||
|
DEINIT_S();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ s - suid type:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
USE_TEST(APPLET_NOEXEC([, test, _BB_DIR_USR_BIN, _BB_SUID_NEVER, test))
|
USE_TEST(APPLET_NOFORK([, test, _BB_DIR_USR_BIN, _BB_SUID_NEVER, test))
|
||||||
USE_TEST(APPLET_NOUSAGE([[, test, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
|
USE_TEST(APPLET_NOUSAGE([[, test, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
|
||||||
USE_ADDGROUP(APPLET(addgroup, _BB_DIR_BIN, _BB_SUID_NEVER))
|
USE_ADDGROUP(APPLET(addgroup, _BB_DIR_BIN, _BB_SUID_NEVER))
|
||||||
USE_ADDUSER(APPLET(adduser, _BB_DIR_BIN, _BB_SUID_NEVER))
|
USE_ADDUSER(APPLET(adduser, _BB_DIR_BIN, _BB_SUID_NEVER))
|
||||||
|
@ -121,6 +121,8 @@ struct statics {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Make it reside in writable memory, yet make compiler understand
|
||||||
|
* that it is not going to change. */
|
||||||
static struct statics *const ptr_to_statics __attribute__ ((section (".data")));
|
static struct statics *const ptr_to_statics __attribute__ ((section (".data")));
|
||||||
|
|
||||||
#define S (*ptr_to_statics)
|
#define S (*ptr_to_statics)
|
||||||
|
Loading…
Reference in New Issue
Block a user