aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2020-01-18 10:30:42 +0000
committerRon Yorston <rmy@pobox.com>2020-01-18 11:18:57 +0000
commitdd15e2a2d6fcd93486f01f8ad8f8c2b7f6a7a317 (patch)
tree0a0dbb1e8613381236b528027b14078677ffb8b7
parentfbdd9862764c4693d8d1c1825adbadc0abb3d5ce (diff)
downloadbusybox-w32-dd15e2a2d6fcd93486f01f8ad8f8c2b7f6a7a317.tar.gz
busybox-w32-dd15e2a2d6fcd93486f01f8ad8f8c2b7f6a7a317.tar.bz2
busybox-w32-dd15e2a2d6fcd93486f01f8ad8f8c2b7f6a7a317.zip
ash: reduce size of forkshell relocation map
The functions to calculate the size of the forkshell data block returned the total size of funcblock and funcstring. The relocation map only needs to cover the size of the forkshell structure plus funcblock, not funcstring. Revise the *_size() functions to distinguish between funcblock and funcstring. Avoid complicating the calculation of node sizes (calcsize() and related functions). This slightly overestimates the size of funcblock by including strings stored in node structures. This change increases the binary by 96 bytes but can save several thousand bytes at runtime.
-rw-r--r--shell/ash.c147
1 files changed, 77 insertions, 70 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 9f4e6a7cb..20c2590db 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -15524,17 +15524,22 @@ static int align_len(const char *s)
15524 return s ? SHELL_ALIGN(strlen(s)+1) : 0; 15524 return s ? SHELL_ALIGN(strlen(s)+1) : 0;
15525} 15525}
15526 15526
15527struct datasize {
15528 int funcblocksize;
15529 int funcstringsize;
15530};
15531
15527#define SLIST_SIZE_BEGIN(name,type) \ 15532#define SLIST_SIZE_BEGIN(name,type) \
15528static int \ 15533static struct datasize \
15529name(int funcblocksize, type *p) \ 15534name(struct datasize ds, type *p) \
15530{ \ 15535{ \
15531 while (p) { \ 15536 while (p) { \
15532 funcblocksize += sizeof(type); 15537 ds.funcblocksize += sizeof(type);
15533 /* do something here with p */ 15538 /* do something here with p */
15534#define SLIST_SIZE_END() \ 15539#define SLIST_SIZE_END() \
15535 p = p->next; \ 15540 p = p->next; \
15536 } \ 15541 } \
15537 return funcblocksize; \ 15542 return ds; \
15538} 15543}
15539 15544
15540#define SLIST_COPY_BEGIN(name,type) \ 15545#define SLIST_COPY_BEGIN(name,type) \
@@ -15561,7 +15566,7 @@ name(type *vp) \
15561 * struct var 15566 * struct var
15562 */ 15567 */
15563SLIST_SIZE_BEGIN(var_size,struct var) 15568SLIST_SIZE_BEGIN(var_size,struct var)
15564funcblocksize += align_len(p->var_text); 15569ds.funcstringsize += align_len(p->var_text);
15565SLIST_SIZE_END() 15570SLIST_SIZE_END()
15566 15571
15567SLIST_COPY_BEGIN(var_copy,struct var) 15572SLIST_COPY_BEGIN(var_copy,struct var)
@@ -15575,7 +15580,7 @@ SLIST_COPY_END()
15575 * struct strlist 15580 * struct strlist
15576 */ 15581 */
15577SLIST_SIZE_BEGIN(strlist_size,struct strlist) 15582SLIST_SIZE_BEGIN(strlist_size,struct strlist)
15578funcblocksize += align_len(p->text); 15583ds.funcstringsize += align_len(p->text);
15579SLIST_SIZE_END() 15584SLIST_SIZE_END()
15580 15585
15581SLIST_COPY_BEGIN(strlist_copy,struct strlist) 15586SLIST_COPY_BEGIN(strlist_copy,struct strlist)
@@ -15586,19 +15591,19 @@ SLIST_COPY_END()
15586/* 15591/*
15587 * struct tblentry 15592 * struct tblentry
15588 */ 15593 */
15589static int 15594static struct datasize
15590tblentry_size(int funcblocksize, struct tblentry *tep) 15595tblentry_size(struct datasize ds, struct tblentry *tep)
15591{ 15596{
15592 while (tep) { 15597 while (tep) {
15593 funcblocksize += sizeof(struct tblentry) + align_len(tep->cmdname); 15598 ds.funcblocksize += sizeof(struct tblentry) + align_len(tep->cmdname);
15594 /* CMDBUILTIN, e->param.cmd needs no pointer relocation */ 15599 /* CMDBUILTIN, e->param.cmd needs no pointer relocation */
15595 if (tep->cmdtype == CMDFUNCTION) { 15600 if (tep->cmdtype == CMDFUNCTION) {
15596 funcblocksize += offsetof(struct funcnode, n); 15601 ds.funcblocksize += offsetof(struct funcnode, n);
15597 funcblocksize = calcsize(funcblocksize, &tep->param.func->n); 15602 ds.funcblocksize = calcsize(ds.funcblocksize, &tep->param.func->n);
15598 } 15603 }
15599 tep = tep->next; 15604 tep = tep->next;
15600 } 15605 }
15601 return funcblocksize; 15606 return ds;
15602} 15607}
15603 15608
15604static struct tblentry * 15609static struct tblentry *
@@ -15637,14 +15642,14 @@ tblentry_copy(struct tblentry *tep)
15637 return start; 15642 return start;
15638} 15643}
15639 15644
15640static int 15645static struct datasize
15641cmdtable_size(int funcblocksize, struct tblentry **cmdtablep) 15646cmdtable_size(struct datasize ds, struct tblentry **cmdtablep)
15642{ 15647{
15643 int i; 15648 int i;
15644 funcblocksize += sizeof(struct tblentry *)*CMDTABLESIZE; 15649 ds.funcblocksize += sizeof(struct tblentry *)*CMDTABLESIZE;
15645 for (i = 0; i < CMDTABLESIZE; i++) 15650 for (i = 0; i < CMDTABLESIZE; i++)
15646 funcblocksize = tblentry_size(funcblocksize, cmdtablep[i]); 15651 ds = tblentry_size(ds, cmdtablep[i]);
15647 return funcblocksize; 15652 return ds;
15648} 15653}
15649 15654
15650static struct tblentry ** 15655static struct tblentry **
@@ -15666,8 +15671,8 @@ cmdtable_copy(struct tblentry **cmdtablep)
15666 * struct alias 15671 * struct alias
15667 */ 15672 */
15668SLIST_SIZE_BEGIN(alias_size,struct alias) 15673SLIST_SIZE_BEGIN(alias_size,struct alias)
15669funcblocksize += align_len(p->name); 15674ds.funcstringsize += align_len(p->name);
15670funcblocksize += align_len(p->val); 15675ds.funcstringsize += align_len(p->val);
15671SLIST_SIZE_END() 15676SLIST_SIZE_END()
15672 15677
15673SLIST_COPY_BEGIN(alias_copy,struct alias) 15678SLIST_COPY_BEGIN(alias_copy,struct alias)
@@ -15678,14 +15683,14 @@ SAVE_PTR((*vpp)->name, xasprintf("(*vpp)->name '%s'", vp->name ?: "NULL"), FREE)
15678SAVE_PTR((*vpp)->val, xasprintf("(*vpp)->val '%s'", vp->val ?: "NULL"), FREE); 15683SAVE_PTR((*vpp)->val, xasprintf("(*vpp)->val '%s'", vp->val ?: "NULL"), FREE);
15679SLIST_COPY_END() 15684SLIST_COPY_END()
15680 15685
15681static int 15686static struct datasize
15682atab_size(int funcblocksize, struct alias **atabp) 15687atab_size(struct datasize ds, struct alias **atabp)
15683{ 15688{
15684 int i; 15689 int i;
15685 funcblocksize += sizeof(struct alias *)*ATABSIZE; 15690 ds.funcblocksize += sizeof(struct alias *)*ATABSIZE;
15686 for (i = 0; i < ATABSIZE; i++) 15691 for (i = 0; i < ATABSIZE; i++)
15687 funcblocksize = alias_size(funcblocksize, atabp[i]); 15692 ds = alias_size(ds, atabp[i]);
15688 return funcblocksize; 15693 return ds;
15689} 15694}
15690 15695
15691static struct alias ** 15696static struct alias **
@@ -15706,16 +15711,16 @@ atab_copy(struct alias **atabp)
15706/* 15711/*
15707 * char ** 15712 * char **
15708 */ 15713 */
15709static int 15714static struct datasize
15710argv_size(int funcblocksize, char **p) 15715argv_size(struct datasize ds, char **p)
15711{ 15716{
15712 while (p && *p) { 15717 while (p && *p) {
15713 funcblocksize += sizeof(char *); 15718 ds.funcblocksize += sizeof(char *);
15714 funcblocksize += align_len(*p); 15719 ds.funcstringsize += align_len(*p);
15715 p++; 15720 p++;
15716 } 15721 }
15717 funcblocksize += sizeof(char *); 15722 ds.funcblocksize += sizeof(char *);
15718 return funcblocksize; 15723 return ds;
15719} 15724}
15720 15725
15721static char ** 15726static char **
@@ -15740,16 +15745,16 @@ argv_copy(char **p)
15740} 15745}
15741 15746
15742#if MAX_HISTORY 15747#if MAX_HISTORY
15743static int 15748static struct datasize
15744history_size(int funcblocksize, line_input_t *st) 15749history_size(struct datasize ds, line_input_t *st)
15745{ 15750{
15746 int i; 15751 int i;
15747 15752
15748 funcblocksize += sizeof(char *) * st->cnt_history; 15753 ds.funcblocksize += sizeof(char *) * st->cnt_history;
15749 for (i = 0; i < st->cnt_history; i++) { 15754 for (i = 0; i < st->cnt_history; i++) {
15750 funcblocksize += align_len(st->history[i]); 15755 ds.funcstringsize += align_len(st->history[i]);
15751 } 15756 }
15752 return funcblocksize; 15757 return ds;
15753} 15758}
15754 15759
15755static char ** 15760static char **
@@ -15804,17 +15809,17 @@ redirtab_copy(struct redirtab *rdtp)
15804#undef shellparam 15809#undef shellparam
15805#undef redirlist 15810#undef redirlist
15806#undef vartab 15811#undef vartab
15807static int 15812static struct datasize
15808globals_var_size(int funcblocksize, struct globals_var *gvp) 15813globals_var_size(struct datasize ds, struct globals_var *gvp)
15809{ 15814{
15810 int i; 15815 int i;
15811 15816
15812 funcblocksize += sizeof(struct globals_var); 15817 ds.funcblocksize += sizeof(struct globals_var);
15813 funcblocksize = argv_size(funcblocksize, gvp->shellparam.p); 15818 ds = argv_size(ds, gvp->shellparam.p);
15814 funcblocksize = redirtab_size(funcblocksize, gvp->redirlist); 15819 ds.funcblocksize = redirtab_size(ds.funcblocksize, gvp->redirlist);
15815 for (i = 0; i < VTABSIZE; i++) 15820 for (i = 0; i < VTABSIZE; i++)
15816 funcblocksize = var_size(funcblocksize, gvp->vartab[i]); 15821 ds = var_size(ds, gvp->vartab[i]);
15817 return funcblocksize; 15822 return ds;
15818} 15823}
15819 15824
15820static struct globals_var * 15825static struct globals_var *
@@ -15849,18 +15854,18 @@ globals_var_copy(struct globals_var *gvp)
15849#undef arg0 15854#undef arg0
15850#undef commandname 15855#undef commandname
15851#undef nullstr 15856#undef nullstr
15852static int 15857static struct datasize
15853globals_misc_size(int funcblocksize, struct globals_misc *p) 15858globals_misc_size(struct datasize ds, struct globals_misc *p)
15854{ 15859{
15855 funcblocksize += sizeof(struct globals_misc); 15860 ds.funcblocksize += sizeof(struct globals_misc);
15856 funcblocksize += align_len(p->minusc); 15861 ds.funcstringsize += align_len(p->minusc);
15857 if (p->curdir != p->nullstr) 15862 if (p->curdir != p->nullstr)
15858 funcblocksize += align_len(p->curdir); 15863 ds.funcstringsize += align_len(p->curdir);
15859 if (p->physdir != p->nullstr) 15864 if (p->physdir != p->nullstr)
15860 funcblocksize += align_len(p->physdir); 15865 ds.funcstringsize += align_len(p->physdir);
15861 funcblocksize += align_len(p->arg0); 15866 ds.funcstringsize += align_len(p->arg0);
15862 funcblocksize += align_len(p->commandname); 15867 ds.funcstringsize += align_len(p->commandname);
15863 return funcblocksize; 15868 return ds;
15864} 15869}
15865 15870
15866static struct globals_misc * 15871static struct globals_misc *
@@ -15887,31 +15892,31 @@ globals_misc_copy(struct globals_misc *p)
15887 return new; 15892 return new;
15888} 15893}
15889 15894
15890static int 15895static struct datasize
15891forkshell_size(struct forkshell *fs) 15896forkshell_size(struct forkshell *fs)
15892{ 15897{
15893 int funcblocksize = 0; 15898 struct datasize ds = {0, 0};
15894 15899
15895 funcblocksize = globals_var_size(funcblocksize, fs->gvp); 15900 ds = globals_var_size(ds, fs->gvp);
15896 funcblocksize = globals_misc_size(funcblocksize, fs->gmp); 15901 ds = globals_misc_size(ds, fs->gmp);
15897 funcblocksize = cmdtable_size(funcblocksize, fs->cmdtable); 15902 ds = cmdtable_size(ds, fs->cmdtable);
15898#if ENABLE_ASH_ALIAS 15903#if ENABLE_ASH_ALIAS
15899 funcblocksize = atab_size(funcblocksize, fs->atab); 15904 ds = atab_size(ds, fs->atab);
15900#endif 15905#endif
15901 /* optlist_transfer(sending, fd); */ 15906 /* optlist_transfer(sending, fd); */
15902 /* misc_transfer(sending, fd); */ 15907 /* misc_transfer(sending, fd); */
15903 15908
15904 funcblocksize = calcsize(funcblocksize, fs->n); 15909 ds.funcblocksize = calcsize(ds.funcblocksize, fs->n);
15905 funcblocksize = argv_size(funcblocksize, fs->argv); 15910 ds = argv_size(ds, fs->argv);
15906 funcblocksize += align_len(fs->path); 15911 ds.funcstringsize += align_len(fs->path);
15907 funcblocksize = strlist_size(funcblocksize, fs->varlist); 15912 ds = strlist_size(ds, fs->varlist);
15908 15913
15909#if MAX_HISTORY 15914#if MAX_HISTORY
15910 if (line_input_state) { 15915 if (line_input_state) {
15911 funcblocksize = history_size(funcblocksize, line_input_state); 15916 ds = history_size(ds, line_input_state);
15912 } 15917 }
15913#endif 15918#endif
15914 return funcblocksize; 15919 return ds;
15915} 15920}
15916 15921
15917static void 15922static void
@@ -16054,6 +16059,7 @@ static struct forkshell *
16054forkshell_prepare(struct forkshell *fs) 16059forkshell_prepare(struct forkshell *fs)
16055{ 16060{
16056 struct forkshell *new; 16061 struct forkshell *new;
16062 struct datasize ds;
16057 int size, relocatesize; 16063 int size, relocatesize;
16058 HANDLE h; 16064 HANDLE h;
16059 SECURITY_ATTRIBUTES sa; 16065 SECURITY_ATTRIBUTES sa;
@@ -16072,8 +16078,9 @@ forkshell_prepare(struct forkshell *fs)
16072#endif 16078#endif
16073 16079
16074 /* calculate size of structure, funcblock and funcstring */ 16080 /* calculate size of structure, funcblock and funcstring */
16075 size = sizeof(struct forkshell) + forkshell_size(fs); 16081 ds = forkshell_size(fs);
16076 relocatesize = size; 16082 size = sizeof(struct forkshell) + ds.funcblocksize + ds.funcstringsize;
16083 relocatesize = sizeof(struct forkshell) + ds.funcblocksize;
16077 16084
16078 /* Allocate shared memory region. We allocate twice 'size' to allow 16085 /* Allocate shared memory region. We allocate twice 'size' to allow
16079 * for the relocation map. This is an overestimate as the relocation 16086 * for the relocation map. This is an overestimate as the relocation
@@ -16125,15 +16132,15 @@ forkshell_prepare(struct forkshell *fs)
16125 forkshell_print(fp, new, annot); 16132 forkshell_print(fp, new, annot);
16126 16133
16127 for (i = 0; i < relocatesize; ++i) { 16134 for (i = 0; i < relocatesize; ++i) {
16128 if (relocate[i] == FREE) {
16129 free((void *)annot[i]);
16130 }
16131 /* check relocations are only present for structure and funcblock */ 16135 /* check relocations are only present for structure and funcblock */
16132 if (i >= sizeof(*new)+new->funcblocksize && annot[i] != NULL) { 16136 if (i >= sizeof(*new)+new->funcblocksize && annot[i] != NULL) {
16133 fprintf(fp, "\nnon-NULL annotation at offset %d (> %d)\n", 16137 fprintf(fp, "\nnon-NULL annotation at offset %d (> %d) %s\n",
16134 i, (int)sizeof(*new)+new->funcblocksize); 16138 i, (int)sizeof(*new)+new->funcblocksize, annot[i]);
16135 break; 16139 break;
16136 } 16140 }
16141 if (relocate[i] == FREE) {
16142 free((void *)annot[i]);
16143 }
16137 } 16144 }
16138 free(annot); 16145 free(annot);
16139 annot = NULL; 16146 annot = NULL;