aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2018-03-04 08:56:04 +0000
committerRon Yorston <rmy@pobox.com>2018-03-04 08:56:04 +0000
commit31997b1796bdaf5734f5fff1a20a637d8872419d (patch)
tree9c27f6741a1149059cb4f2cb324f6b2ee913e428
parent13cb88b0f6f2a69076e91858fbbdd0c65697e621 (diff)
downloadbusybox-w32-31997b1796bdaf5734f5fff1a20a637d8872419d.tar.gz
busybox-w32-31997b1796bdaf5734f5fff1a20a637d8872419d.tar.bz2
busybox-w32-31997b1796bdaf5734f5fff1a20a637d8872419d.zip
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.
-rw-r--r--win32/isaac.c96
-rw-r--r--win32/mingw.c24
-rw-r--r--win32/mntent.c46
-rw-r--r--win32/process.c62
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.
19*/ 19*/
20#include "libbb.h" 20#include "libbb.h"
21 21
22/* external results */ 22typedef struct {
23static uint32_t randrsl[256]; 23 /* external results */
24 uint32_t randrsl[256];
24 25
25/* internal state */ 26 /* internal state */
26static uint32_t mm[256]; 27 uint32_t mm[256];
27static uint32_t aa=0, bb=0, cc=0; 28 uint32_t aa, bb, cc;
29} isaac_t;
28 30
29 31
30static void isaac(void) 32static void isaac(isaac_t *t)
31{ 33{
32 register uint32_t i,x,y; 34 register uint32_t i,x,y;
33 35
34 cc = cc + 1; /* cc just gets incremented once per 256 results */ 36 t->cc = t->cc + 1; /* cc just gets incremented once per 256 results */
35 bb = bb + cc; /* then combined with bb */ 37 t->bb = t->bb + t->cc; /* then combined with bb */
36 38
37 for (i=0; i<256; ++i) 39 for (i=0; i<256; ++i)
38 { 40 {
39 x = mm[i]; 41 x = t->mm[i];
40 switch (i%4) 42 switch (i%4)
41 { 43 {
42 case 0: aa = aa^(aa<<13); break; 44 case 0: t->aa = t->aa^(t->aa<<13); break;
43 case 1: aa = aa^(aa>>6); break; 45 case 1: t->aa = t->aa^(t->aa>>6); break;
44 case 2: aa = aa^(aa<<2); break; 46 case 2: t->aa = t->aa^(t->aa<<2); break;
45 case 3: aa = aa^(aa>>16); break; 47 case 3: t->aa = t->aa^(t->aa>>16); break;
46 } 48 }
47 aa = mm[(i+128)%256] + aa; 49 t->aa = t->mm[(i+128)%256] + t->aa;
48 mm[i] = y = mm[(x>>2)%256] + aa + bb; 50 t->mm[i] = y = t->mm[(x>>2)%256] + t->aa + t->bb;
49 randrsl[i] = bb = mm[(y>>10)%256] + x; 51 t->randrsl[i] = t->bb = t->mm[(y>>10)%256] + x;
50 52
51 /* Note that bits 2..9 are chosen from x but 10..17 are chosen 53 /* Note that bits 2..9 are chosen from x but 10..17 are chosen
52 from y. The only important thing here is that 2..9 and 10..17 54 from y. The only important thing here is that 2..9 and 10..17
@@ -71,11 +73,11 @@ static void isaac(void)
71 h^=a>>9; c+=h; a+=b; \ 73 h^=a>>9; c+=h; a+=b; \
72} 74}
73 75
74static void randinit(int flag) 76static void randinit(isaac_t *t, int flag)
75{ 77{
76 int i; 78 int i;
77 uint32_t a,b,c,d,e,f,g,h; 79 uint32_t a,b,c,d,e,f,g,h;
78 aa=bb=cc=0; 80 t->aa = t->bb = t->cc = 0;
79 a=b=c=d=e=f=g=h=0x9e3779b9; /* the golden ratio */ 81 a=b=c=d=e=f=g=h=0x9e3779b9; /* the golden ratio */
80 82
81 for (i=0; i<4; ++i) /* scramble it */ 83 for (i=0; i<4; ++i) /* scramble it */
@@ -87,27 +89,28 @@ static void randinit(int flag)
87 { 89 {
88 if (flag) /* use all the information in the seed */ 90 if (flag) /* use all the information in the seed */
89 { 91 {
90 a+=randrsl[i ]; b+=randrsl[i+1]; c+=randrsl[i+2]; d+=randrsl[i+3]; 92 a+=t->randrsl[i ]; b+=t->randrsl[i+1]; c+=t->randrsl[i+2];
91 e+=randrsl[i+4]; f+=randrsl[i+5]; g+=randrsl[i+6]; h+=randrsl[i+7]; 93 d+=t->randrsl[i+3]; e+=t->randrsl[i+4]; f+=t->randrsl[i+5];
94 g+=t->randrsl[i+6]; h+=t->randrsl[i+7];
92 } 95 }
93 mix(a,b,c,d,e,f,g,h); 96 mix(a,b,c,d,e,f,g,h);
94 mm[i ]=a; mm[i+1]=b; mm[i+2]=c; mm[i+3]=d; 97 t->mm[i ]=a; t->mm[i+1]=b; t->mm[i+2]=c; t->mm[i+3]=d;
95 mm[i+4]=e; mm[i+5]=f; mm[i+6]=g; mm[i+7]=h; 98 t->mm[i+4]=e; t->mm[i+5]=f; t->mm[i+6]=g; t->mm[i+7]=h;
96 } 99 }
97 100
98 if (flag) 101 if (flag)
99 { /* do a second pass to make all of the seed affect all of mm */ 102 { /* do a second pass to make all of the seed affect all of mm */
100 for (i=0; i<256; i+=8) 103 for (i=0; i<256; i+=8)
101 { 104 {
102 a+=mm[i ]; b+=mm[i+1]; c+=mm[i+2]; d+=mm[i+3]; 105 a+=t->mm[i ]; b+=t->mm[i+1]; c+=t->mm[i+2]; d+=t->mm[i+3];
103 e+=mm[i+4]; f+=mm[i+5]; g+=mm[i+6]; h+=mm[i+7]; 106 e+=t->mm[i+4]; f+=t->mm[i+5]; g+=t->mm[i+6]; h+=t->mm[i+7];
104 mix(a,b,c,d,e,f,g,h); 107 mix(a,b,c,d,e,f,g,h);
105 mm[i ]=a; mm[i+1]=b; mm[i+2]=c; mm[i+3]=d; 108 t->mm[i ]=a; t->mm[i+1]=b; t->mm[i+2]=c; t->mm[i+3]=d;
106 mm[i+4]=e; mm[i+5]=f; mm[i+6]=g; mm[i+7]=h; 109 t->mm[i+4]=e; t->mm[i+5]=f; t->mm[i+6]=g; t->mm[i+7]=h;
107 } 110 }
108 } 111 }
109 112
110 isaac(); /* fill in the first set of results */ 113 isaac(t); /* fill in the first set of results */
111} 114}
112 115
113/* call 'fn' to put data in 'dt' then copy it to generator state */ 116/* call 'fn' to put data in 'dt' then copy it to generator state */
@@ -115,7 +118,7 @@ static void randinit(int flag)
115 fn(&dt); \ 118 fn(&dt); \
116 u = (uint32_t *)&dt; \ 119 u = (uint32_t *)&dt; \
117 for (j=0; j<sizeof(dt)/sizeof(uint32_t); ++j) { \ 120 for (j=0; j<sizeof(dt)/sizeof(uint32_t); ++j) { \
118 randrsl[i++] = *u++; \ 121 t->randrsl[i++] = *u++; \
119 } 122 }
120 123
121/* 124/*
@@ -123,7 +126,7 @@ static void randinit(int flag)
123 * This is unlikely to be very robust: don't rely on it for 126 * This is unlikely to be very robust: don't rely on it for
124 * anything that needs to be secure. 127 * anything that needs to be secure.
125 */ 128 */
126static void get_entropy(void) 129static void get_entropy(isaac_t *t)
127{ 130{
128 int i, j, len; 131 int i, j, len;
129 SYSTEMTIME tm; 132 SYSTEMTIME tm;
@@ -136,9 +139,9 @@ static void get_entropy(void)
136 unsigned char buf[16]; 139 unsigned char buf[16];
137 140
138 i = 0; 141 i = 0;
139 randrsl[i++] = (uint32_t)GetCurrentProcessId(); 142 t->randrsl[i++] = (uint32_t)GetCurrentProcessId();
140 randrsl[i++] = (uint32_t)GetCurrentThreadId(); 143 t->randrsl[i++] = (uint32_t)GetCurrentThreadId();
141 randrsl[i++] = (uint32_t)GetTickCount(); 144 t->randrsl[i++] = (uint32_t)GetTickCount();
142 145
143 GET_DATA(GetLocalTime, tm) 146 GET_DATA(GetLocalTime, tm)
144 GET_DATA(GlobalMemoryStatus, ms) 147 GET_DATA(GlobalMemoryStatus, ms)
@@ -159,12 +162,12 @@ static void get_entropy(void)
159 162
160 u = (uint32_t *)buf; 163 u = (uint32_t *)buf;
161 for (j=0; j<sizeof(buf)/sizeof(uint32_t); ++j) { 164 for (j=0; j<sizeof(buf)/sizeof(uint32_t); ++j) {
162 randrsl[i++] = *u++; 165 t->randrsl[i++] = *u++;
163 } 166 }
164 167
165#if 0 168#if 0
166 { 169 {
167 unsigned char *p = (unsigned char *)randrsl; 170 unsigned char *p = (unsigned char *)t->randrsl;
168 171
169 for (j=0; j<i*sizeof(uint32_t); ++j) { 172 for (j=0; j<i*sizeof(uint32_t); ++j) {
170 fprintf(stderr, "%02x", *p++); 173 fprintf(stderr, "%02x", *p++);
@@ -180,8 +183,8 @@ static void get_entropy(void)
180#endif 183#endif
181} 184}
182 185
183#define RAND_BYTES sizeof(randrsl) 186#define RAND_BYTES sizeof(t->randrsl)
184#define RAND_WORDS (sizeof(randrsl)/sizeof(randrsl[0])) 187#define RAND_WORDS (sizeof(t->randrsl)/sizeof(t->randrsl[0]))
185 188
186/* 189/*
187 * Place 'count' random bytes in the buffer 'buf'. You're responsible 190 * Place 'count' random bytes in the buffer 'buf'. You're responsible
@@ -189,29 +192,26 @@ static void get_entropy(void)
189 */ 192 */
190ssize_t get_random_bytes(void *buf, ssize_t count) 193ssize_t get_random_bytes(void *buf, ssize_t count)
191{ 194{
192 static int initialised = 0; 195 static isaac_t *t = NULL;
193 static int rand_index = 0; 196 static int rand_index = 0;
194 int i;
195 ssize_t save_count = count; 197 ssize_t save_count = count;
196 unsigned char *ptr = (unsigned char *)randrsl; 198 unsigned char *ptr;
197 199
198 if (buf == NULL || count < 0) { 200 if (buf == NULL || count < 0) {
199 errno = EINVAL; 201 errno = EINVAL;
200 return -1; 202 return -1;
201 } 203 }
202 204
203 if (!initialised) { 205 if (!t) {
204 aa = bb = cc = (uint32_t)0; 206 t = xzalloc(sizeof(isaac_t));
205 for (i=0; i<RAND_WORDS; ++i)
206 mm[i] = randrsl[i] = (uint32_t)0;
207 207
208 get_entropy(); 208 get_entropy(t);
209 randinit(1); 209 randinit(t, 1);
210 isaac(); 210 isaac(t);
211 rand_index = 0; 211 rand_index = 0;
212 initialised = 1;
213 } 212 }
214 213
214 ptr = (unsigned char *)t->randrsl;
215 while (count > 0) { 215 while (count > 0) {
216 int bytes_left = RAND_BYTES - rand_index; 216 int bytes_left = RAND_BYTES - rand_index;
217 217
@@ -231,7 +231,7 @@ ssize_t get_random_bytes(void *buf, ssize_t count)
231 231
232 if (rand_index >= RAND_BYTES) { 232 if (rand_index >= RAND_BYTES) {
233 /* generate more */ 233 /* generate more */
234 isaac(); 234 isaac(t);
235 rand_index = 0; 235 rand_index = 0;
236 } 236 }
237 } 237 }
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)
676 676
677static char *gethomedir(void) 677static char *gethomedir(void)
678{ 678{
679 static char buf[PATH_MAX]; 679 static char *buf = NULL;
680 DWORD len = sizeof(buf); 680 DWORD len = PATH_MAX;
681 HANDLE h; 681 HANDLE h;
682 char *s; 682 char *s;
683 683
684 if (!buf)
685 buf = xmalloc(PATH_MAX);
686
684 buf[0] = '\0'; 687 buf[0] = '\0';
685 if ( !OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &h) ) 688 if ( !OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &h) )
686 return buf; 689 return buf;
@@ -701,11 +704,17 @@ static char *gethomedir(void)
701 return buf; 704 return buf;
702} 705}
703 706
707#define NAME_LEN 100
704static char *get_user_name(void) 708static char *get_user_name(void)
705{ 709{
706 static char user_name[100] = ""; 710 static char *user_name = NULL;
707 char *s; 711 char *s;
708 DWORD len = sizeof(user_name); 712 DWORD len = NAME_LEN;
713
714 if ( user_name == NULL ) {
715 user_name = xmalloc(NAME_LEN);
716 user_name[0] = '\0';
717 }
709 718
710 if ( user_name[0] != '\0' ) { 719 if ( user_name[0] != '\0' ) {
711 return user_name; 720 return user_name;
@@ -857,7 +866,12 @@ char *realpath(const char *path, char *resolved_path)
857 866
858const char *get_busybox_exec_path(void) 867const char *get_busybox_exec_path(void)
859{ 868{
860 static char path[PATH_MAX] = ""; 869 static char *path = NULL;
870
871 if (!path) {
872 path = xmalloc(PATH_MAX);
873 path[0] = '\0';
874 }
861 875
862 if (!*path) 876 if (!*path)
863 GetModuleFileName(NULL, path, PATH_MAX); 877 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 @@
7struct mntdata { 7struct mntdata {
8 DWORD flags; 8 DWORD flags;
9 int index; 9 int index;
10 struct mntent me;
11 char mnt_fsname[4];
12 char mnt_dir[4];
13 char mnt_type[100];
14 char mnt_opts[4];
10}; 15};
11 16
12FILE *setmntent(const char *file UNUSED_PARAM, const char *mode UNUSED_PARAM) 17FILE *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)
26struct mntent *getmntent(FILE *stream) 31struct mntent *getmntent(FILE *stream)
27{ 32{
28 struct mntdata *data = (struct mntdata *)stream; 33 struct mntdata *data = (struct mntdata *)stream;
29 static char mnt_fsname[4];
30 static char mnt_dir[4];
31 static char mnt_type[100];
32 static char mnt_opts[4];
33 static struct mntent my_mount_entry =
34 { mnt_fsname, mnt_dir, mnt_type, mnt_opts, 0, 0 };
35 struct mntent *entry; 34 struct mntent *entry;
36 35
36 data->me.mnt_fsname = data->mnt_fsname;
37 data->me.mnt_dir = data->mnt_dir;
38 data->me.mnt_type = data->mnt_type;
39 data->me.mnt_opts = data->mnt_opts;
40 data->me.mnt_freq = 0;
41 data->me.mnt_passno = 0;
42
37 entry = NULL; 43 entry = NULL;
38 while ( ++data->index < 26 ) { 44 while ( ++data->index < 26 ) {
39 if ( (data->flags & 1<<data->index) != 0 ) { 45 if ( (data->flags & 1<<data->index) != 0 ) {
40 mnt_fsname[0] = 'A' + data->index; 46 data->mnt_fsname[0] = 'A' + data->index;
41 mnt_fsname[1] = ':'; 47 data->mnt_fsname[1] = ':';
42 mnt_fsname[2] = '\0'; 48 data->mnt_fsname[2] = '\0';
43 mnt_dir[0] = 'A' + data->index; 49 data->mnt_dir[0] = 'A' + data->index;
44 mnt_dir[1] = ':'; 50 data->mnt_dir[1] = ':';
45 mnt_dir[2] = '\\'; 51 data->mnt_dir[2] = '\\';
46 mnt_dir[3] = '\0'; 52 data->mnt_dir[3] = '\0';
47 mnt_type[0] = '\0'; 53 data->mnt_type[0] = '\0';
48 mnt_opts[0] = '\0'; 54 data->mnt_opts[0] = '\0';
49 55
50 if ( GetDriveType(mnt_dir) == DRIVE_FIXED ) { 56 if ( GetDriveType(data->mnt_dir) == DRIVE_FIXED ) {
51 if ( !GetVolumeInformation(mnt_dir, NULL, 0, NULL, NULL, 57 if ( !GetVolumeInformation(data->mnt_dir, NULL, 0, NULL, NULL,
52 NULL, mnt_type, 100) ) { 58 NULL, data->mnt_type, 100) ) {
53 mnt_type[0] = '\0'; 59 data->mnt_type[0] = '\0';
54 } 60 }
55 61
56 entry = &my_mount_entry; 62 entry = &data->me;
57 break; 63 break;
58 } 64 }
59 } 65 }
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)
39 return strchr(has_dos_drive_prefix(path) ? path+2 : path, ':'); 39 return strchr(has_dos_drive_prefix(path) ? path+2 : path, ':');
40} 40}
41 41
42static char * 42typedef struct {
43parse_interpreter(const char *cmd, char **name, char **opts) 43 char *path;
44 char *name;
45 char *opts;
46 char buf[100];
47} interp_t;
48
49static int
50parse_interpreter(const char *cmd, interp_t *interp)
44{ 51{
45 static char buf[100];
46 char *path, *t; 52 char *path, *t;
47 int n, fd; 53 int n, fd;
48 54
49 fd = open(cmd, O_RDONLY); 55 fd = open(cmd, O_RDONLY);
50 if (fd < 0) 56 if (fd < 0)
51 return NULL; 57 return 0;
52 n = read(fd, buf, sizeof(buf)-1); 58 n = read(fd, interp->buf, sizeof(interp->buf)-1);
53 close(fd); 59 close(fd);
54 if (n < 4) /* at least '#!/x' and not error */ 60 if (n < 4) /* at least '#!/x' and not error */
55 return NULL; 61 return 0;
56 62
57 /* 63 /*
58 * See http://www.in-ulm.de/~mascheck/various/shebang/ for trivia 64 * See http://www.in-ulm.de/~mascheck/various/shebang/ for trivia
59 * relating to '#!'. 65 * relating to '#!'.
60 */ 66 */
61 if (buf[0] != '#' || buf[1] != '!') 67 if (interp->buf[0] != '#' || interp->buf[1] != '!')
62 return NULL; 68 return 0;
63 buf[n] = '\0'; 69 interp->buf[n] = '\0';
64 if ((t=strchr(buf, '\n')) == NULL) 70 if ((t=strchr(interp->buf, '\n')) == NULL)
65 return NULL; 71 return 0;
66 t[1] = '\0'; 72 t[1] = '\0';
67 73
68 if ((path=strtok(buf+2, " \t\r\n")) == NULL) 74 if ((path=strtok(interp->buf+2, " \t\r\n")) == NULL)
69 return NULL; 75 return 0;
70 76
71 t = (char *)bb_basename(path); 77 t = (char *)bb_basename(path);
72 if (*t == '\0') 78 if (*t == '\0')
73 return NULL; 79 return 0;
74 80
75 *name = t; 81 interp->path = path;
76 *opts = strtok(NULL, "\r\n"); 82 interp->name = t;
83 interp->opts = strtok(NULL, "\r\n");
77 84
78 return path; 85 return 1;
79} 86}
80 87
81/* 88/*
@@ -284,36 +291,35 @@ mingw_spawn_interpreter(int mode, const char *prog, char *const *argv, char *con
284{ 291{
285 intptr_t ret; 292 intptr_t ret;
286 int nopts; 293 int nopts;
287 char *int_name, *opts; 294 interp_t interp;
288 char *int_path = parse_interpreter(prog, &int_name, &opts);
289 char **new_argv; 295 char **new_argv;
290 int argc = -1; 296 int argc = -1;
291 char *fullpath = NULL; 297 char *fullpath = NULL;
292 298
293 if (!int_path) 299 if (!parse_interpreter(prog, &interp))
294 return spawnveq(mode, prog, argv, envp); 300 return spawnveq(mode, prog, argv, envp);
295 301
296 nopts = opts != NULL; 302 nopts = interp.opts != NULL;
297 while (argv[++argc]) 303 while (argv[++argc])
298 ; 304 ;
299 305
300 new_argv = xmalloc(sizeof(*argv)*(argc+nopts+2)); 306 new_argv = xmalloc(sizeof(*argv)*(argc+nopts+2));
301 new_argv[1] = opts; 307 new_argv[1] = interp.opts;
302 new_argv[nopts+1] = (char *)prog; /* pass absolute path */ 308 new_argv[nopts+1] = (char *)prog; /* pass absolute path */
303 memcpy(new_argv+nopts+2, argv+1, sizeof(*argv)*argc); 309 memcpy(new_argv+nopts+2, argv+1, sizeof(*argv)*argc);
304 310
305 if ((fullpath=add_win32_extension(int_path)) != NULL || 311 if ((fullpath=add_win32_extension(interp.path)) != NULL ||
306 file_is_executable(int_path)) { 312 file_is_executable(interp.path)) {
307 new_argv[0] = fullpath ? fullpath : int_path; 313 new_argv[0] = fullpath ? fullpath : interp.path;
308 ret = spawnveq(mode, new_argv[0], new_argv, envp); 314 ret = spawnveq(mode, new_argv[0], new_argv, envp);
309 } else 315 } else
310#if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_FEATURE_SH_STANDALONE 316#if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_FEATURE_SH_STANDALONE
311 if (find_applet_by_name(int_name) >= 0) { 317 if (find_applet_by_name(interp.name) >= 0) {
312 new_argv[0] = int_name; 318 new_argv[0] = interp.name;
313 ret = mingw_spawn_applet(mode, new_argv, envp); 319 ret = mingw_spawn_applet(mode, new_argv, envp);
314 } else 320 } else
315#endif 321#endif
316 if ((fullpath=find_first_executable(int_name)) != NULL) { 322 if ((fullpath=find_first_executable(interp.name)) != NULL) {
317 new_argv[0] = fullpath; 323 new_argv[0] = fullpath;
318 ret = spawnveq(mode, fullpath, new_argv, envp); 324 ret = spawnveq(mode, fullpath, new_argv, envp);
319 } 325 }