hush/include/busybox.h
Ron Yorston 610c4c385b applet_tables: save space by removing applet name offsets
The array applet_nameofs consumes two bytes per applet.  It encodes

   nofork/noexec flags
   suid flags
   the offset of the applet name in the applet_name string

Change the applet_table build tool to store the flags in two separate
arrays (applet_flags and applet_suid).  Replace applet_nameofs[] with a
smaller version that only stores a limited number of offsets.

This requires changes to the macros APPLET_IS_NOFORK, APPLET_IS_NOEXEC
and APPLET_SUID.

   According to Valgrind the original find_applet_by_name required
   353 cycles per call, averaged over all names.  Adjusting the number
   of known offsets allows space to be traded off against execution time:

      KNOWN_OFFSETS     cycles     bytes (wrt KNOWN_OFFSETS = 0)

           0             9057        -
           2             4604       32
           4             2407       75
           8             1342       98
          16              908      130
          32              884      194

   This patch uses KNOWN_OFFSETS = 8.

v2:
   Remove some dead code from the applet_table tool;
   Treat the applet in the middle of the table as a special case.

v3:
   Use the middle applet to adjust the start of the linear search as
   well as the last applet found.

v4:
   Use an augmented linear search in find_applet_by_name.
   Drop the special treatment of the middle name from get_applet_name:
   most of the advantage now derives from the last stored value.

v5:
   Don't store index in applet_nameofs, it can be calculated.

v6:
   Tweaks by Denys

function                                             old     new   delta
find_applet_by_name                                   25     125    +100
applet_suid                                            -      92     +92
run_applet_no_and_exit                               452     460      +8
run_applet_and_exit                                  695     697      +2
applet_name_compare                                   31       -     -31
applet_nameofs                                       734      14    -720
------------------------------------------------------------------------------
(add/remove: 1/1 grow/shrink: 3/1 up/down: 202/-751)         Total: -549 bytes
   text       data        bss        dec        hex    filename
 925464        906      17160     943530      e65aa    busybox_old
 924915        906      17160     942981      e6385    busybox_unstripped

Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2016-03-30 00:44:11 +02:00

57 lines
1.5 KiB
C

/* vi: set sw=4 ts=4: */
/*
* Licensed under GPLv2 or later, see file LICENSE in this source tree.
*/
#ifndef BUSYBOX_H
#define BUSYBOX_H 1
#include "libbb.h"
/* BB_DIR_foo and BB_SUID_bar constants: */
#include "applet_metadata.h"
PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
/* Defined in appletlib.c (by including generated applet_tables.h) */
/* Keep in sync with applets/applet_tables.c! */
extern const char applet_names[] ALIGN1;
extern int (*const applet_main[])(int argc, char **argv);
extern const uint8_t applet_flags[] ALIGN1;
extern const uint8_t applet_suid[] ALIGN1;
extern const uint8_t applet_install_loc[] ALIGN1;
#if ENABLE_FEATURE_PREFER_APPLETS
# define APPLET_IS_NOFORK(i) (applet_flags[(i)/4] & (1 << (2 * ((i)%4))))
# define APPLET_IS_NOEXEC(i) (applet_flags[(i)/4] & (1 << ((2 * ((i)%4))+1)))
#else
# define APPLET_IS_NOFORK(i) 0
# define APPLET_IS_NOEXEC(i) 0
#endif
#if ENABLE_FEATURE_SUID
# define APPLET_SUID(i) ((applet_suid[(i)/4] >> (2 * ((i)%4)) & 3))
#endif
#if ENABLE_FEATURE_INSTALLER
#define APPLET_INSTALL_LOC(i) ({ \
unsigned v = (i); \
if (v & 1) v = applet_install_loc[v/2] >> 4; \
else v = applet_install_loc[v/2] & 0xf; \
v; })
#endif
/* Length of these names has effect on size of libbusybox
* and "individual" binaries. Keep them short.
*/
#if ENABLE_BUILD_LIBBUSYBOX
#if ENABLE_FEATURE_SHARED_BUSYBOX
int lbb_main(char **argv) EXTERNALLY_VISIBLE;
#else
int lbb_main(char **argv);
#endif
#endif
POP_SAVED_FUNCTION_VISIBILITY
#endif