diff options
author | Ron Yorston <rmy@pobox.com> | 2020-01-18 10:30:42 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2020-01-18 11:18:57 +0000 |
commit | dd15e2a2d6fcd93486f01f8ad8f8c2b7f6a7a317 (patch) | |
tree | 0a0dbb1e8613381236b528027b14078677ffb8b7 | |
parent | fbdd9862764c4693d8d1c1825adbadc0abb3d5ce (diff) | |
download | busybox-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.c | 147 |
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 | ||
15527 | struct datasize { | ||
15528 | int funcblocksize; | ||
15529 | int funcstringsize; | ||
15530 | }; | ||
15531 | |||
15527 | #define SLIST_SIZE_BEGIN(name,type) \ | 15532 | #define SLIST_SIZE_BEGIN(name,type) \ |
15528 | static int \ | 15533 | static struct datasize \ |
15529 | name(int funcblocksize, type *p) \ | 15534 | name(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 | */ |
15563 | SLIST_SIZE_BEGIN(var_size,struct var) | 15568 | SLIST_SIZE_BEGIN(var_size,struct var) |
15564 | funcblocksize += align_len(p->var_text); | 15569 | ds.funcstringsize += align_len(p->var_text); |
15565 | SLIST_SIZE_END() | 15570 | SLIST_SIZE_END() |
15566 | 15571 | ||
15567 | SLIST_COPY_BEGIN(var_copy,struct var) | 15572 | SLIST_COPY_BEGIN(var_copy,struct var) |
@@ -15575,7 +15580,7 @@ SLIST_COPY_END() | |||
15575 | * struct strlist | 15580 | * struct strlist |
15576 | */ | 15581 | */ |
15577 | SLIST_SIZE_BEGIN(strlist_size,struct strlist) | 15582 | SLIST_SIZE_BEGIN(strlist_size,struct strlist) |
15578 | funcblocksize += align_len(p->text); | 15583 | ds.funcstringsize += align_len(p->text); |
15579 | SLIST_SIZE_END() | 15584 | SLIST_SIZE_END() |
15580 | 15585 | ||
15581 | SLIST_COPY_BEGIN(strlist_copy,struct strlist) | 15586 | SLIST_COPY_BEGIN(strlist_copy,struct strlist) |
@@ -15586,19 +15591,19 @@ SLIST_COPY_END() | |||
15586 | /* | 15591 | /* |
15587 | * struct tblentry | 15592 | * struct tblentry |
15588 | */ | 15593 | */ |
15589 | static int | 15594 | static struct datasize |
15590 | tblentry_size(int funcblocksize, struct tblentry *tep) | 15595 | tblentry_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 | ||
15604 | static struct tblentry * | 15609 | static struct tblentry * |
@@ -15637,14 +15642,14 @@ tblentry_copy(struct tblentry *tep) | |||
15637 | return start; | 15642 | return start; |
15638 | } | 15643 | } |
15639 | 15644 | ||
15640 | static int | 15645 | static struct datasize |
15641 | cmdtable_size(int funcblocksize, struct tblentry **cmdtablep) | 15646 | cmdtable_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 | ||
15650 | static struct tblentry ** | 15655 | static struct tblentry ** |
@@ -15666,8 +15671,8 @@ cmdtable_copy(struct tblentry **cmdtablep) | |||
15666 | * struct alias | 15671 | * struct alias |
15667 | */ | 15672 | */ |
15668 | SLIST_SIZE_BEGIN(alias_size,struct alias) | 15673 | SLIST_SIZE_BEGIN(alias_size,struct alias) |
15669 | funcblocksize += align_len(p->name); | 15674 | ds.funcstringsize += align_len(p->name); |
15670 | funcblocksize += align_len(p->val); | 15675 | ds.funcstringsize += align_len(p->val); |
15671 | SLIST_SIZE_END() | 15676 | SLIST_SIZE_END() |
15672 | 15677 | ||
15673 | SLIST_COPY_BEGIN(alias_copy,struct alias) | 15678 | SLIST_COPY_BEGIN(alias_copy,struct alias) |
@@ -15678,14 +15683,14 @@ SAVE_PTR((*vpp)->name, xasprintf("(*vpp)->name '%s'", vp->name ?: "NULL"), FREE) | |||
15678 | SAVE_PTR((*vpp)->val, xasprintf("(*vpp)->val '%s'", vp->val ?: "NULL"), FREE); | 15683 | SAVE_PTR((*vpp)->val, xasprintf("(*vpp)->val '%s'", vp->val ?: "NULL"), FREE); |
15679 | SLIST_COPY_END() | 15684 | SLIST_COPY_END() |
15680 | 15685 | ||
15681 | static int | 15686 | static struct datasize |
15682 | atab_size(int funcblocksize, struct alias **atabp) | 15687 | atab_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 | ||
15691 | static struct alias ** | 15696 | static struct alias ** |
@@ -15706,16 +15711,16 @@ atab_copy(struct alias **atabp) | |||
15706 | /* | 15711 | /* |
15707 | * char ** | 15712 | * char ** |
15708 | */ | 15713 | */ |
15709 | static int | 15714 | static struct datasize |
15710 | argv_size(int funcblocksize, char **p) | 15715 | argv_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 | ||
15721 | static char ** | 15726 | static char ** |
@@ -15740,16 +15745,16 @@ argv_copy(char **p) | |||
15740 | } | 15745 | } |
15741 | 15746 | ||
15742 | #if MAX_HISTORY | 15747 | #if MAX_HISTORY |
15743 | static int | 15748 | static struct datasize |
15744 | history_size(int funcblocksize, line_input_t *st) | 15749 | history_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 | ||
15755 | static char ** | 15760 | static 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 |
15807 | static int | 15812 | static struct datasize |
15808 | globals_var_size(int funcblocksize, struct globals_var *gvp) | 15813 | globals_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 | ||
15820 | static struct globals_var * | 15825 | static 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 |
15852 | static int | 15857 | static struct datasize |
15853 | globals_misc_size(int funcblocksize, struct globals_misc *p) | 15858 | globals_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 | ||
15866 | static struct globals_misc * | 15871 | static struct globals_misc * |
@@ -15887,31 +15892,31 @@ globals_misc_copy(struct globals_misc *p) | |||
15887 | return new; | 15892 | return new; |
15888 | } | 15893 | } |
15889 | 15894 | ||
15890 | static int | 15895 | static struct datasize |
15891 | forkshell_size(struct forkshell *fs) | 15896 | forkshell_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 | ||
15917 | static void | 15922 | static void |
@@ -16054,6 +16059,7 @@ static struct forkshell * | |||
16054 | forkshell_prepare(struct forkshell *fs) | 16059 | forkshell_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; |