From 31997b1796bdaf5734f5fff1a20a637d8872419d Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Sun, 4 Mar 2018 08:56:04 +0000 Subject: win32: reduce amount of static data It appears that uninitialised static variables are placed in the data section rather than bss, increasing the size of the binary. Rewrite some code to reduce the amount of static data. --- win32/isaac.c | 96 ++++++++++++++++++++++++++++----------------------------- win32/mingw.c | 24 ++++++++++++--- win32/mntent.c | 46 +++++++++++++++------------ win32/process.c | 62 ++++++++++++++++++++----------------- 4 files changed, 127 insertions(+), 101 deletions(-) diff --git a/win32/isaac.c b/win32/isaac.c index 8e9da9baf..ba51d199a 100644 --- a/win32/isaac.c +++ b/win32/isaac.c @@ -19,34 +19,36 @@ You may use this code in any way you wish, and it is free. No warrantee. */ #include "libbb.h" -/* external results */ -static uint32_t randrsl[256]; +typedef struct { + /* external results */ + uint32_t randrsl[256]; -/* internal state */ -static uint32_t mm[256]; -static uint32_t aa=0, bb=0, cc=0; + /* internal state */ + uint32_t mm[256]; + uint32_t aa, bb, cc; +} isaac_t; -static void isaac(void) +static void isaac(isaac_t *t) { register uint32_t i,x,y; - cc = cc + 1; /* cc just gets incremented once per 256 results */ - bb = bb + cc; /* then combined with bb */ + t->cc = t->cc + 1; /* cc just gets incremented once per 256 results */ + t->bb = t->bb + t->cc; /* then combined with bb */ for (i=0; i<256; ++i) { - x = mm[i]; + x = t->mm[i]; switch (i%4) { - case 0: aa = aa^(aa<<13); break; - case 1: aa = aa^(aa>>6); break; - case 2: aa = aa^(aa<<2); break; - case 3: aa = aa^(aa>>16); break; + case 0: t->aa = t->aa^(t->aa<<13); break; + case 1: t->aa = t->aa^(t->aa>>6); break; + case 2: t->aa = t->aa^(t->aa<<2); break; + case 3: t->aa = t->aa^(t->aa>>16); break; } - aa = mm[(i+128)%256] + aa; - mm[i] = y = mm[(x>>2)%256] + aa + bb; - randrsl[i] = bb = mm[(y>>10)%256] + x; + t->aa = t->mm[(i+128)%256] + t->aa; + t->mm[i] = y = t->mm[(x>>2)%256] + t->aa + t->bb; + t->randrsl[i] = t->bb = t->mm[(y>>10)%256] + x; /* Note that bits 2..9 are chosen from x but 10..17 are chosen from y. The only important thing here is that 2..9 and 10..17 @@ -71,11 +73,11 @@ static void isaac(void) h^=a>>9; c+=h; a+=b; \ } -static void randinit(int flag) +static void randinit(isaac_t *t, int flag) { int i; uint32_t a,b,c,d,e,f,g,h; - aa=bb=cc=0; + t->aa = t->bb = t->cc = 0; a=b=c=d=e=f=g=h=0x9e3779b9; /* the golden ratio */ for (i=0; i<4; ++i) /* scramble it */ @@ -87,27 +89,28 @@ static void randinit(int flag) { if (flag) /* use all the information in the seed */ { - a+=randrsl[i ]; b+=randrsl[i+1]; c+=randrsl[i+2]; d+=randrsl[i+3]; - e+=randrsl[i+4]; f+=randrsl[i+5]; g+=randrsl[i+6]; h+=randrsl[i+7]; + a+=t->randrsl[i ]; b+=t->randrsl[i+1]; c+=t->randrsl[i+2]; + d+=t->randrsl[i+3]; e+=t->randrsl[i+4]; f+=t->randrsl[i+5]; + g+=t->randrsl[i+6]; h+=t->randrsl[i+7]; } mix(a,b,c,d,e,f,g,h); - mm[i ]=a; mm[i+1]=b; mm[i+2]=c; mm[i+3]=d; - mm[i+4]=e; mm[i+5]=f; mm[i+6]=g; mm[i+7]=h; + t->mm[i ]=a; t->mm[i+1]=b; t->mm[i+2]=c; t->mm[i+3]=d; + t->mm[i+4]=e; t->mm[i+5]=f; t->mm[i+6]=g; t->mm[i+7]=h; } if (flag) { /* do a second pass to make all of the seed affect all of mm */ for (i=0; i<256; i+=8) { - a+=mm[i ]; b+=mm[i+1]; c+=mm[i+2]; d+=mm[i+3]; - e+=mm[i+4]; f+=mm[i+5]; g+=mm[i+6]; h+=mm[i+7]; + a+=t->mm[i ]; b+=t->mm[i+1]; c+=t->mm[i+2]; d+=t->mm[i+3]; + e+=t->mm[i+4]; f+=t->mm[i+5]; g+=t->mm[i+6]; h+=t->mm[i+7]; mix(a,b,c,d,e,f,g,h); - mm[i ]=a; mm[i+1]=b; mm[i+2]=c; mm[i+3]=d; - mm[i+4]=e; mm[i+5]=f; mm[i+6]=g; mm[i+7]=h; + t->mm[i ]=a; t->mm[i+1]=b; t->mm[i+2]=c; t->mm[i+3]=d; + t->mm[i+4]=e; t->mm[i+5]=f; t->mm[i+6]=g; t->mm[i+7]=h; } } - isaac(); /* fill in the first set of results */ + isaac(t); /* fill in the first set of results */ } /* call 'fn' to put data in 'dt' then copy it to generator state */ @@ -115,7 +118,7 @@ static void randinit(int flag) fn(&dt); \ u = (uint32_t *)&dt; \ for (j=0; jrandrsl[i++] = *u++; \ } /* @@ -123,7 +126,7 @@ static void randinit(int flag) * This is unlikely to be very robust: don't rely on it for * anything that needs to be secure. */ -static void get_entropy(void) +static void get_entropy(isaac_t *t) { int i, j, len; SYSTEMTIME tm; @@ -136,9 +139,9 @@ static void get_entropy(void) unsigned char buf[16]; i = 0; - randrsl[i++] = (uint32_t)GetCurrentProcessId(); - randrsl[i++] = (uint32_t)GetCurrentThreadId(); - randrsl[i++] = (uint32_t)GetTickCount(); + t->randrsl[i++] = (uint32_t)GetCurrentProcessId(); + t->randrsl[i++] = (uint32_t)GetCurrentThreadId(); + t->randrsl[i++] = (uint32_t)GetTickCount(); GET_DATA(GetLocalTime, tm) GET_DATA(GlobalMemoryStatus, ms) @@ -159,12 +162,12 @@ static void get_entropy(void) u = (uint32_t *)buf; for (j=0; jrandrsl[i++] = *u++; } #if 0 { - unsigned char *p = (unsigned char *)randrsl; + unsigned char *p = (unsigned char *)t->randrsl; for (j=0; jrandrsl) +#define RAND_WORDS (sizeof(t->randrsl)/sizeof(t->randrsl[0])) /* * Place 'count' random bytes in the buffer 'buf'. You're responsible @@ -189,29 +192,26 @@ static void get_entropy(void) */ ssize_t get_random_bytes(void *buf, ssize_t count) { - static int initialised = 0; + static isaac_t *t = NULL; static int rand_index = 0; - int i; ssize_t save_count = count; - unsigned char *ptr = (unsigned char *)randrsl; + unsigned char *ptr; if (buf == NULL || count < 0) { errno = EINVAL; return -1; } - if (!initialised) { - aa = bb = cc = (uint32_t)0; - for (i=0; irandrsl; while (count > 0) { int bytes_left = RAND_BYTES - rand_index; @@ -231,7 +231,7 @@ ssize_t get_random_bytes(void *buf, ssize_t count) if (rand_index >= RAND_BYTES) { /* generate more */ - isaac(); + isaac(t); rand_index = 0; } } diff --git a/win32/mingw.c b/win32/mingw.c index bedf14784..4c449514a 100644 --- a/win32/mingw.c +++ b/win32/mingw.c @@ -676,11 +676,14 @@ int mingw_rename(const char *pold, const char *pnew) static char *gethomedir(void) { - static char buf[PATH_MAX]; - DWORD len = sizeof(buf); + static char *buf = NULL; + DWORD len = PATH_MAX; HANDLE h; char *s; + if (!buf) + buf = xmalloc(PATH_MAX); + buf[0] = '\0'; if ( !OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &h) ) return buf; @@ -701,11 +704,17 @@ static char *gethomedir(void) return buf; } +#define NAME_LEN 100 static char *get_user_name(void) { - static char user_name[100] = ""; + static char *user_name = NULL; char *s; - DWORD len = sizeof(user_name); + DWORD len = NAME_LEN; + + if ( user_name == NULL ) { + user_name = xmalloc(NAME_LEN); + user_name[0] = '\0'; + } if ( user_name[0] != '\0' ) { return user_name; @@ -857,7 +866,12 @@ char *realpath(const char *path, char *resolved_path) const char *get_busybox_exec_path(void) { - static char path[PATH_MAX] = ""; + static char *path = NULL; + + if (!path) { + path = xmalloc(PATH_MAX); + path[0] = '\0'; + } if (!*path) GetModuleFileName(NULL, path, PATH_MAX); diff --git a/win32/mntent.c b/win32/mntent.c index 9b04a9c5e..f9a2d26d4 100644 --- a/win32/mntent.c +++ b/win32/mntent.c @@ -7,6 +7,11 @@ struct mntdata { DWORD flags; int index; + struct mntent me; + char mnt_fsname[4]; + char mnt_dir[4]; + char mnt_type[100]; + char mnt_opts[4]; }; FILE *setmntent(const char *file UNUSED_PARAM, const char *mode UNUSED_PARAM) @@ -26,34 +31,35 @@ FILE *setmntent(const char *file UNUSED_PARAM, const char *mode UNUSED_PARAM) struct mntent *getmntent(FILE *stream) { struct mntdata *data = (struct mntdata *)stream; - static char mnt_fsname[4]; - static char mnt_dir[4]; - static char mnt_type[100]; - static char mnt_opts[4]; - static struct mntent my_mount_entry = - { mnt_fsname, mnt_dir, mnt_type, mnt_opts, 0, 0 }; struct mntent *entry; + data->me.mnt_fsname = data->mnt_fsname; + data->me.mnt_dir = data->mnt_dir; + data->me.mnt_type = data->mnt_type; + data->me.mnt_opts = data->mnt_opts; + data->me.mnt_freq = 0; + data->me.mnt_passno = 0; + entry = NULL; while ( ++data->index < 26 ) { if ( (data->flags & 1<index) != 0 ) { - mnt_fsname[0] = 'A' + data->index; - mnt_fsname[1] = ':'; - mnt_fsname[2] = '\0'; - mnt_dir[0] = 'A' + data->index; - mnt_dir[1] = ':'; - mnt_dir[2] = '\\'; - mnt_dir[3] = '\0'; - mnt_type[0] = '\0'; - mnt_opts[0] = '\0'; + data->mnt_fsname[0] = 'A' + data->index; + data->mnt_fsname[1] = ':'; + data->mnt_fsname[2] = '\0'; + data->mnt_dir[0] = 'A' + data->index; + data->mnt_dir[1] = ':'; + data->mnt_dir[2] = '\\'; + data->mnt_dir[3] = '\0'; + data->mnt_type[0] = '\0'; + data->mnt_opts[0] = '\0'; - if ( GetDriveType(mnt_dir) == DRIVE_FIXED ) { - if ( !GetVolumeInformation(mnt_dir, NULL, 0, NULL, NULL, - NULL, mnt_type, 100) ) { - mnt_type[0] = '\0'; + if ( GetDriveType(data->mnt_dir) == DRIVE_FIXED ) { + if ( !GetVolumeInformation(data->mnt_dir, NULL, 0, NULL, NULL, + NULL, data->mnt_type, 100) ) { + data->mnt_type[0] = '\0'; } - entry = &my_mount_entry; + entry = &data->me; break; } } diff --git a/win32/process.c b/win32/process.c index 96561c482..0d6d70970 100644 --- a/win32/process.c +++ b/win32/process.c @@ -39,43 +39,50 @@ next_path_sep(const char *path) return strchr(has_dos_drive_prefix(path) ? path+2 : path, ':'); } -static char * -parse_interpreter(const char *cmd, char **name, char **opts) +typedef struct { + char *path; + char *name; + char *opts; + char buf[100]; +} interp_t; + +static int +parse_interpreter(const char *cmd, interp_t *interp) { - static char buf[100]; char *path, *t; int n, fd; fd = open(cmd, O_RDONLY); if (fd < 0) - return NULL; - n = read(fd, buf, sizeof(buf)-1); + return 0; + n = read(fd, interp->buf, sizeof(interp->buf)-1); close(fd); if (n < 4) /* at least '#!/x' and not error */ - return NULL; + return 0; /* * See http://www.in-ulm.de/~mascheck/various/shebang/ for trivia * relating to '#!'. */ - if (buf[0] != '#' || buf[1] != '!') - return NULL; - buf[n] = '\0'; - if ((t=strchr(buf, '\n')) == NULL) - return NULL; + if (interp->buf[0] != '#' || interp->buf[1] != '!') + return 0; + interp->buf[n] = '\0'; + if ((t=strchr(interp->buf, '\n')) == NULL) + return 0; t[1] = '\0'; - if ((path=strtok(buf+2, " \t\r\n")) == NULL) - return NULL; + if ((path=strtok(interp->buf+2, " \t\r\n")) == NULL) + return 0; t = (char *)bb_basename(path); if (*t == '\0') - return NULL; + return 0; - *name = t; - *opts = strtok(NULL, "\r\n"); + interp->path = path; + interp->name = t; + interp->opts = strtok(NULL, "\r\n"); - return path; + return 1; } /* @@ -284,36 +291,35 @@ mingw_spawn_interpreter(int mode, const char *prog, char *const *argv, char *con { intptr_t ret; int nopts; - char *int_name, *opts; - char *int_path = parse_interpreter(prog, &int_name, &opts); + interp_t interp; char **new_argv; int argc = -1; char *fullpath = NULL; - if (!int_path) + if (!parse_interpreter(prog, &interp)) return spawnveq(mode, prog, argv, envp); - nopts = opts != NULL; + nopts = interp.opts != NULL; while (argv[++argc]) ; new_argv = xmalloc(sizeof(*argv)*(argc+nopts+2)); - new_argv[1] = opts; + new_argv[1] = interp.opts; new_argv[nopts+1] = (char *)prog; /* pass absolute path */ memcpy(new_argv+nopts+2, argv+1, sizeof(*argv)*argc); - if ((fullpath=add_win32_extension(int_path)) != NULL || - file_is_executable(int_path)) { - new_argv[0] = fullpath ? fullpath : int_path; + if ((fullpath=add_win32_extension(interp.path)) != NULL || + file_is_executable(interp.path)) { + new_argv[0] = fullpath ? fullpath : interp.path; ret = spawnveq(mode, new_argv[0], new_argv, envp); } else #if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_FEATURE_SH_STANDALONE - if (find_applet_by_name(int_name) >= 0) { - new_argv[0] = int_name; + if (find_applet_by_name(interp.name) >= 0) { + new_argv[0] = interp.name; ret = mingw_spawn_applet(mode, new_argv, envp); } else #endif - if ((fullpath=find_first_executable(int_name)) != NULL) { + if ((fullpath=find_first_executable(interp.name)) != NULL) { new_argv[0] = fullpath; ret = spawnveq(mode, fullpath, new_argv, envp); } -- cgit v1.2.3-55-g6feb