diff options
author | Ron Yorston <rmy@pobox.com> | 2020-01-16 14:26:53 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2020-01-16 14:26:53 +0000 |
commit | df87b596a3c4f404a06b3e902f9e085980ca62e0 (patch) | |
tree | 36bdd3062fa6cf5ce3f54351f6ff4126a63a9705 | |
parent | 2ffcb860ea478d4b8d553fe59af5982c5939f7fa (diff) | |
download | busybox-w32-df87b596a3c4f404a06b3e902f9e085980ca62e0.tar.gz busybox-w32-df87b596a3c4f404a06b3e902f9e085980ca62e0.tar.bz2 busybox-w32-df87b596a3c4f404a06b3e902f9e085980ca62e0.zip |
ash: rework how pointers are adjusted during forkshell
The original code kept an array of pointers to pointers that needed
to be adjusted after forkshell (nodeptr). Switch to using a map to
indicate which locations in the data block need to be adjusted.
This requires a larger data block. However the *_size() functions
which calculate the data block size need less information about the
data structures. Saves about 100 bytes in the binary.
-rw-r--r-- | shell/ash.c | 414 |
1 files changed, 185 insertions, 229 deletions
diff --git a/shell/ash.c b/shell/ash.c index a2b798cad..853fafcc1 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -361,9 +361,9 @@ struct forkshell { | |||
361 | HANDLE hMapFile; | 361 | HANDLE hMapFile; |
362 | char *old_base; | 362 | char *old_base; |
363 | # if FORKSHELL_DEBUG | 363 | # if FORKSHELL_DEBUG |
364 | int nodeptrcount; | ||
365 | int funcblocksize; | 364 | int funcblocksize; |
366 | int funcstringsize; | 365 | int funcstringsize; |
366 | int relocatesize; | ||
367 | # endif | 367 | # endif |
368 | int size; | 368 | int size; |
369 | 369 | ||
@@ -381,9 +381,6 @@ struct forkshell { | |||
381 | char **argv; | 381 | char **argv; |
382 | char *path; | 382 | char *path; |
383 | struct strlist *varlist; | 383 | struct strlist *varlist; |
384 | |||
385 | /* start of data block */ | ||
386 | char **nodeptr[1]; | ||
387 | }; | 384 | }; |
388 | 385 | ||
389 | enum { | 386 | enum { |
@@ -405,7 +402,7 @@ static void sticky_free(void *p); | |||
405 | static void spawn_forkshell(struct forkshell *fs, struct job *jp, | 402 | static void spawn_forkshell(struct forkshell *fs, struct job *jp, |
406 | union node *n, int mode); | 403 | union node *n, int mode); |
407 | # if FORKSHELL_DEBUG | 404 | # if FORKSHELL_DEBUG |
408 | static void forkshell_print(FILE *fp0, struct forkshell *fs, char **notes); | 405 | static void forkshell_print(FILE *fp0, struct forkshell *fs, const char **notes); |
409 | # endif | 406 | # endif |
410 | #endif | 407 | #endif |
411 | 408 | ||
@@ -9283,11 +9280,10 @@ commandcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
9283 | static void *funcblock; /* block to allocate function from */ | 9280 | static void *funcblock; /* block to allocate function from */ |
9284 | static char *funcstring_end; /* end of block to allocate strings from */ | 9281 | static char *funcstring_end; /* end of block to allocate strings from */ |
9285 | #if ENABLE_PLATFORM_MINGW32 | 9282 | #if ENABLE_PLATFORM_MINGW32 |
9286 | static int nodeptrcount; | 9283 | static char *relocate; |
9287 | static char ***nodeptr; | 9284 | static void *fs_start; |
9288 | # if FORKSHELL_DEBUG | 9285 | # if FORKSHELL_DEBUG |
9289 | static int annot_count; | 9286 | static const char **annot; |
9290 | static char **annot; | ||
9291 | # endif | 9287 | # endif |
9292 | #endif | 9288 | #endif |
9293 | 9289 | ||
@@ -9330,7 +9326,6 @@ sizenodelist(int funcblocksize, struct nodelist *lp) | |||
9330 | { | 9326 | { |
9331 | while (lp) { | 9327 | while (lp) { |
9332 | funcblocksize += SHELL_ALIGN(sizeof(struct nodelist)); | 9328 | funcblocksize += SHELL_ALIGN(sizeof(struct nodelist)); |
9333 | IF_PLATFORM_MINGW32(nodeptrcount += 2); | ||
9334 | funcblocksize = calcsize(funcblocksize, lp->n); | 9329 | funcblocksize = calcsize(funcblocksize, lp->n); |
9335 | lp = lp->next; | 9330 | lp = lp->next; |
9336 | } | 9331 | } |
@@ -9348,18 +9343,15 @@ calcsize(int funcblocksize, union node *n) | |||
9348 | funcblocksize = calcsize(funcblocksize, n->ncmd.redirect); | 9343 | funcblocksize = calcsize(funcblocksize, n->ncmd.redirect); |
9349 | funcblocksize = calcsize(funcblocksize, n->ncmd.args); | 9344 | funcblocksize = calcsize(funcblocksize, n->ncmd.args); |
9350 | funcblocksize = calcsize(funcblocksize, n->ncmd.assign); | 9345 | funcblocksize = calcsize(funcblocksize, n->ncmd.assign); |
9351 | IF_PLATFORM_MINGW32(nodeptrcount += 3); | ||
9352 | break; | 9346 | break; |
9353 | case NPIPE: | 9347 | case NPIPE: |
9354 | funcblocksize = sizenodelist(funcblocksize, n->npipe.cmdlist); | 9348 | funcblocksize = sizenodelist(funcblocksize, n->npipe.cmdlist); |
9355 | IF_PLATFORM_MINGW32(nodeptrcount++); | ||
9356 | break; | 9349 | break; |
9357 | case NREDIR: | 9350 | case NREDIR: |
9358 | case NBACKGND: | 9351 | case NBACKGND: |
9359 | case NSUBSHELL: | 9352 | case NSUBSHELL: |
9360 | funcblocksize = calcsize(funcblocksize, n->nredir.redirect); | 9353 | funcblocksize = calcsize(funcblocksize, n->nredir.redirect); |
9361 | funcblocksize = calcsize(funcblocksize, n->nredir.n); | 9354 | funcblocksize = calcsize(funcblocksize, n->nredir.n); |
9362 | IF_PLATFORM_MINGW32(nodeptrcount += 2); | ||
9363 | break; | 9355 | break; |
9364 | case NAND: | 9356 | case NAND: |
9365 | case NOR: | 9357 | case NOR: |
@@ -9368,41 +9360,34 @@ calcsize(int funcblocksize, union node *n) | |||
9368 | case NUNTIL: | 9360 | case NUNTIL: |
9369 | funcblocksize = calcsize(funcblocksize, n->nbinary.ch2); | 9361 | funcblocksize = calcsize(funcblocksize, n->nbinary.ch2); |
9370 | funcblocksize = calcsize(funcblocksize, n->nbinary.ch1); | 9362 | funcblocksize = calcsize(funcblocksize, n->nbinary.ch1); |
9371 | IF_PLATFORM_MINGW32(nodeptrcount += 2); | ||
9372 | break; | 9363 | break; |
9373 | case NIF: | 9364 | case NIF: |
9374 | funcblocksize = calcsize(funcblocksize, n->nif.elsepart); | 9365 | funcblocksize = calcsize(funcblocksize, n->nif.elsepart); |
9375 | funcblocksize = calcsize(funcblocksize, n->nif.ifpart); | 9366 | funcblocksize = calcsize(funcblocksize, n->nif.ifpart); |
9376 | funcblocksize = calcsize(funcblocksize, n->nif.test); | 9367 | funcblocksize = calcsize(funcblocksize, n->nif.test); |
9377 | IF_PLATFORM_MINGW32(nodeptrcount += 3); | ||
9378 | break; | 9368 | break; |
9379 | case NFOR: | 9369 | case NFOR: |
9380 | funcblocksize += SHELL_ALIGN(strlen(n->nfor.var) + 1); /* was funcstringsize += ... */ | 9370 | funcblocksize += SHELL_ALIGN(strlen(n->nfor.var) + 1); /* was funcstringsize += ... */ |
9381 | funcblocksize = calcsize(funcblocksize, n->nfor.body); | 9371 | funcblocksize = calcsize(funcblocksize, n->nfor.body); |
9382 | funcblocksize = calcsize(funcblocksize, n->nfor.args); | 9372 | funcblocksize = calcsize(funcblocksize, n->nfor.args); |
9383 | IF_PLATFORM_MINGW32(nodeptrcount += 3); | ||
9384 | break; | 9373 | break; |
9385 | case NCASE: | 9374 | case NCASE: |
9386 | funcblocksize = calcsize(funcblocksize, n->ncase.cases); | 9375 | funcblocksize = calcsize(funcblocksize, n->ncase.cases); |
9387 | funcblocksize = calcsize(funcblocksize, n->ncase.expr); | 9376 | funcblocksize = calcsize(funcblocksize, n->ncase.expr); |
9388 | IF_PLATFORM_MINGW32(nodeptrcount += 2); | ||
9389 | break; | 9377 | break; |
9390 | case NCLIST: | 9378 | case NCLIST: |
9391 | funcblocksize = calcsize(funcblocksize, n->nclist.body); | 9379 | funcblocksize = calcsize(funcblocksize, n->nclist.body); |
9392 | funcblocksize = calcsize(funcblocksize, n->nclist.pattern); | 9380 | funcblocksize = calcsize(funcblocksize, n->nclist.pattern); |
9393 | funcblocksize = calcsize(funcblocksize, n->nclist.next); | 9381 | funcblocksize = calcsize(funcblocksize, n->nclist.next); |
9394 | IF_PLATFORM_MINGW32(nodeptrcount += 3); | ||
9395 | break; | 9382 | break; |
9396 | case NDEFUN: | 9383 | case NDEFUN: |
9397 | funcblocksize = calcsize(funcblocksize, n->ndefun.body); | 9384 | funcblocksize = calcsize(funcblocksize, n->ndefun.body); |
9398 | funcblocksize += SHELL_ALIGN(strlen(n->ndefun.text) + 1); | 9385 | funcblocksize += SHELL_ALIGN(strlen(n->ndefun.text) + 1); |
9399 | IF_PLATFORM_MINGW32(nodeptrcount += 2); | ||
9400 | break; | 9386 | break; |
9401 | case NARG: | 9387 | case NARG: |
9402 | funcblocksize = sizenodelist(funcblocksize, n->narg.backquote); | 9388 | funcblocksize = sizenodelist(funcblocksize, n->narg.backquote); |
9403 | funcblocksize += SHELL_ALIGN(strlen(n->narg.text) + 1); /* was funcstringsize += ... */ | 9389 | funcblocksize += SHELL_ALIGN(strlen(n->narg.text) + 1); /* was funcstringsize += ... */ |
9404 | funcblocksize = calcsize(funcblocksize, n->narg.next); | 9390 | funcblocksize = calcsize(funcblocksize, n->narg.next); |
9405 | IF_PLATFORM_MINGW32(nodeptrcount += 3); | ||
9406 | break; | 9391 | break; |
9407 | case NTO: | 9392 | case NTO: |
9408 | #if BASH_REDIR_OUTPUT | 9393 | #if BASH_REDIR_OUTPUT |
@@ -9414,23 +9399,19 @@ calcsize(int funcblocksize, union node *n) | |||
9414 | case NAPPEND: | 9399 | case NAPPEND: |
9415 | funcblocksize = calcsize(funcblocksize, n->nfile.fname); | 9400 | funcblocksize = calcsize(funcblocksize, n->nfile.fname); |
9416 | funcblocksize = calcsize(funcblocksize, n->nfile.next); | 9401 | funcblocksize = calcsize(funcblocksize, n->nfile.next); |
9417 | IF_PLATFORM_MINGW32(nodeptrcount += 2); | ||
9418 | break; | 9402 | break; |
9419 | case NTOFD: | 9403 | case NTOFD: |
9420 | case NFROMFD: | 9404 | case NFROMFD: |
9421 | funcblocksize = calcsize(funcblocksize, n->ndup.vname); | 9405 | funcblocksize = calcsize(funcblocksize, n->ndup.vname); |
9422 | funcblocksize = calcsize(funcblocksize, n->ndup.next); | 9406 | funcblocksize = calcsize(funcblocksize, n->ndup.next); |
9423 | IF_PLATFORM_MINGW32(nodeptrcount += 2); | ||
9424 | break; | 9407 | break; |
9425 | case NHERE: | 9408 | case NHERE: |
9426 | case NXHERE: | 9409 | case NXHERE: |
9427 | funcblocksize = calcsize(funcblocksize, n->nhere.doc); | 9410 | funcblocksize = calcsize(funcblocksize, n->nhere.doc); |
9428 | funcblocksize = calcsize(funcblocksize, n->nhere.next); | 9411 | funcblocksize = calcsize(funcblocksize, n->nhere.next); |
9429 | IF_PLATFORM_MINGW32(nodeptrcount += 2); | ||
9430 | break; | 9412 | break; |
9431 | case NNOT: | 9413 | case NNOT: |
9432 | funcblocksize = calcsize(funcblocksize, n->nnot.com); | 9414 | funcblocksize = calcsize(funcblocksize, n->nnot.com); |
9433 | IF_PLATFORM_MINGW32(nodeptrcount++); | ||
9434 | break; | 9415 | break; |
9435 | }; | 9416 | }; |
9436 | return funcblocksize; | 9417 | return funcblocksize; |
@@ -9449,28 +9430,40 @@ nodeckstrdup(const char *s) | |||
9449 | 9430 | ||
9450 | static union node *copynode(union node *); | 9431 | static union node *copynode(union node *); |
9451 | 9432 | ||
9452 | #if ENABLE_PLATFORM_MINGW32 | 9433 | #if ENABLE_PLATFORM_MINGW32 && FORKSHELL_DEBUG |
9453 | # define SAVE_PTR(dst) {if (nodeptr) *nodeptr++ = (char **)&(dst);} | 9434 | # define FREE 1 |
9454 | # define SAVE_PTR2(dst1,dst2) {if (nodeptr) { *nodeptr++ = (char **)&(dst1);*nodeptr++ = (char **)&(dst2);}} | 9435 | # define NO_FREE 2 |
9455 | # define SAVE_PTR3(dst1,dst2,dst3) {if (nodeptr) { *nodeptr++ = (char **)&(dst1);*nodeptr++ = (char **)&(dst2);*nodeptr++ = (char **)&(dst3);}} | 9436 | # define ANNOT(dst,note) {if (annot) annot[(char *)&dst - (char *)fs_start] = note;} |
9456 | #else | 9437 | #else |
9457 | # define SAVE_PTR(dst) | 9438 | # define FREE 1 |
9458 | # define SAVE_PTR2(dst,dst2) | 9439 | # define NO_FREE 1 |
9459 | # define SAVE_PTR3(dst,dst2,dst3) | 9440 | # define ANNOT(dst,note) |
9460 | #endif | 9441 | #endif |
9461 | 9442 | ||
9462 | #if ENABLE_PLATFORM_MINGW32 && FORKSHELL_DEBUG | 9443 | #if ENABLE_PLATFORM_MINGW32 |
9463 | # define ANNOT_NO_DUP(note) {if (annot) annot[annot_count++] = note;} | 9444 | # define MARK_PTR(dst,flag) {relocate[(char *)&dst - (char *)fs_start] = flag;} |
9464 | # define ANNOT(note) {ANNOT_NO_DUP(xstrdup(note));} | 9445 | # define SAVE_PTR(dst,note,flag) { \ |
9465 | # define ANNOT2(n1,n2) {ANNOT(n1); ANNOT(n2)} | 9446 | if (relocate) { \ |
9466 | # define ANNOT3(n1,n2,n3) {ANNOT2(n1,n2); ANNOT(n3);} | 9447 | MARK_PTR(dst,flag); ANNOT(dst,note); \ |
9467 | # define ANNOT4(n1,n2,n3,n4) {ANNOT3(n1,n2,n3); ANNOT(n4);} | 9448 | } \ |
9449 | } | ||
9450 | # define SAVE_PTR2(dst1,note1,flag1,dst2,note2,flag2) { \ | ||
9451 | if (relocate) { \ | ||
9452 | MARK_PTR(dst1,flag1); ANNOT(dst1,note1); \ | ||
9453 | MARK_PTR(dst2,flag2); ANNOT(dst2,note2); \ | ||
9454 | } \ | ||
9455 | } | ||
9456 | # define SAVE_PTR3(dst1,note1,flag1,dst2,note2,flag2,dst3,note3,flag3) { \ | ||
9457 | if (relocate) { \ | ||
9458 | MARK_PTR(dst1,flag1); ANNOT(dst1,note1); \ | ||
9459 | MARK_PTR(dst2,flag2); ANNOT(dst2,note2); \ | ||
9460 | MARK_PTR(dst3,flag3); ANNOT(dst3,note3); \ | ||
9461 | } \ | ||
9462 | } | ||
9468 | #else | 9463 | #else |
9469 | # define ANNOT_NO_DUP(note) | 9464 | # define SAVE_PTR(dst,note,flag) |
9470 | # define ANNOT(note) | 9465 | # define SAVE_PTR2(dst1,note1,flag1,dst2,note2,flag2) |
9471 | # define ANNOT2(n1,n2) | 9466 | # define SAVE_PTR3(dst1,note1,flag1,dst2,note2,flag2,dst3,note3,flag3) |
9472 | # define ANNOT3(n1,n2,n3) | ||
9473 | # define ANNOT4(n1,n2,n3,n4) | ||
9474 | #endif | 9467 | #endif |
9475 | 9468 | ||
9476 | static struct nodelist * | 9469 | static struct nodelist * |
@@ -9484,8 +9477,8 @@ copynodelist(struct nodelist *lp) | |||
9484 | *lpp = funcblock; | 9477 | *lpp = funcblock; |
9485 | funcblock = (char *) funcblock + SHELL_ALIGN(sizeof(struct nodelist)); | 9478 | funcblock = (char *) funcblock + SHELL_ALIGN(sizeof(struct nodelist)); |
9486 | (*lpp)->n = copynode(lp->n); | 9479 | (*lpp)->n = copynode(lp->n); |
9487 | SAVE_PTR2((*lpp)->n, (*lpp)->next); | 9480 | SAVE_PTR2((*lpp)->n, "(*lpp)->next", NO_FREE, |
9488 | ANNOT2("(*lpp)->n","(*lpp)->next"); | 9481 | (*lpp)->next, "(*lpp)->next", NO_FREE); |
9489 | lp = lp->next; | 9482 | lp = lp->next; |
9490 | lpp = &(*lpp)->next; | 9483 | lpp = &(*lpp)->next; |
9491 | } | 9484 | } |
@@ -9509,14 +9502,14 @@ copynode(union node *n) | |||
9509 | new->ncmd.args = copynode(n->ncmd.args); | 9502 | new->ncmd.args = copynode(n->ncmd.args); |
9510 | new->ncmd.assign = copynode(n->ncmd.assign); | 9503 | new->ncmd.assign = copynode(n->ncmd.assign); |
9511 | new->ncmd.linno = n->ncmd.linno; | 9504 | new->ncmd.linno = n->ncmd.linno; |
9512 | SAVE_PTR3(new->ncmd.redirect,new->ncmd.args, new->ncmd.assign); | 9505 | SAVE_PTR3(new->ncmd.redirect, "ncmd.redirect", NO_FREE, |
9513 | ANNOT3("ncmd.redirect","ncmd.args","ncmd.assign"); | 9506 | new->ncmd.args, "ncmd.args", NO_FREE, |
9507 | new->ncmd.assign, "ncmd.assign", NO_FREE); | ||
9514 | break; | 9508 | break; |
9515 | case NPIPE: | 9509 | case NPIPE: |
9516 | new->npipe.cmdlist = copynodelist(n->npipe.cmdlist); | 9510 | new->npipe.cmdlist = copynodelist(n->npipe.cmdlist); |
9517 | new->npipe.pipe_backgnd = n->npipe.pipe_backgnd; | 9511 | new->npipe.pipe_backgnd = n->npipe.pipe_backgnd; |
9518 | SAVE_PTR(new->npipe.cmdlist); | 9512 | SAVE_PTR(new->npipe.cmdlist, "npipe.cmdlist", NO_FREE); |
9519 | ANNOT("npipe.cmdlist"); | ||
9520 | break; | 9513 | break; |
9521 | case NREDIR: | 9514 | case NREDIR: |
9522 | case NBACKGND: | 9515 | case NBACKGND: |
@@ -9524,8 +9517,8 @@ copynode(union node *n) | |||
9524 | new->nredir.redirect = copynode(n->nredir.redirect); | 9517 | new->nredir.redirect = copynode(n->nredir.redirect); |
9525 | new->nredir.n = copynode(n->nredir.n); | 9518 | new->nredir.n = copynode(n->nredir.n); |
9526 | new->nredir.linno = n->nredir.linno; | 9519 | new->nredir.linno = n->nredir.linno; |
9527 | SAVE_PTR2(new->nredir.redirect,new->nredir.n); | 9520 | SAVE_PTR2(new->nredir.redirect, "nredir.redirect", NO_FREE, |
9528 | ANNOT2("nredir.redirect","nredir.n"); | 9521 | new->nredir.n, "nredir.n", NO_FREE); |
9529 | break; | 9522 | break; |
9530 | case NAND: | 9523 | case NAND: |
9531 | case NOR: | 9524 | case NOR: |
@@ -9534,54 +9527,58 @@ copynode(union node *n) | |||
9534 | case NUNTIL: | 9527 | case NUNTIL: |
9535 | new->nbinary.ch2 = copynode(n->nbinary.ch2); | 9528 | new->nbinary.ch2 = copynode(n->nbinary.ch2); |
9536 | new->nbinary.ch1 = copynode(n->nbinary.ch1); | 9529 | new->nbinary.ch1 = copynode(n->nbinary.ch1); |
9537 | SAVE_PTR2(new->nbinary.ch1,new->nbinary.ch2); | 9530 | SAVE_PTR2(new->nbinary.ch1, "nbinary.ch1", NO_FREE, |
9538 | ANNOT2("nbinary.ch1","nbinary.ch2"); | 9531 | new->nbinary.ch2, "nbinary.ch2", NO_FREE); |
9539 | break; | 9532 | break; |
9540 | case NIF: | 9533 | case NIF: |
9541 | new->nif.elsepart = copynode(n->nif.elsepart); | 9534 | new->nif.elsepart = copynode(n->nif.elsepart); |
9542 | new->nif.ifpart = copynode(n->nif.ifpart); | 9535 | new->nif.ifpart = copynode(n->nif.ifpart); |
9543 | new->nif.test = copynode(n->nif.test); | 9536 | new->nif.test = copynode(n->nif.test); |
9544 | SAVE_PTR3(new->nif.elsepart,new->nif.ifpart,new->nif.test); | 9537 | SAVE_PTR3(new->nif.elsepart, "nif.elsepart", NO_FREE, |
9545 | ANNOT3("nif.elsepart","nif.ifpart","nif.test"); | 9538 | new->nif.ifpart, "nif.ifpart", NO_FREE, |
9539 | new->nif.test, "nif.test", NO_FREE); | ||
9546 | break; | 9540 | break; |
9547 | case NFOR: | 9541 | case NFOR: |
9548 | new->nfor.var = nodeckstrdup(n->nfor.var); | 9542 | new->nfor.var = nodeckstrdup(n->nfor.var); |
9549 | new->nfor.body = copynode(n->nfor.body); | 9543 | new->nfor.body = copynode(n->nfor.body); |
9550 | new->nfor.args = copynode(n->nfor.args); | 9544 | new->nfor.args = copynode(n->nfor.args); |
9551 | new->nfor.linno = n->nfor.linno; | 9545 | new->nfor.linno = n->nfor.linno; |
9552 | SAVE_PTR3(new->nfor.var,new->nfor.body,new->nfor.args); | 9546 | SAVE_PTR3(new->nfor.var, |
9553 | ANNOT_NO_DUP(xasprintf("nfor.var '%s'", n->nfor.var ?: "NULL")); | 9547 | xasprintf("nfor.var '%s'", n->nfor.var ?: "NULL"), FREE, |
9554 | ANNOT2("nfor.body","nfor.args"); | 9548 | new->nfor.body, "nfor.body", NO_FREE, |
9549 | new->nfor.args, "nfor.args", NO_FREE); | ||
9555 | break; | 9550 | break; |
9556 | case NCASE: | 9551 | case NCASE: |
9557 | new->ncase.cases = copynode(n->ncase.cases); | 9552 | new->ncase.cases = copynode(n->ncase.cases); |
9558 | new->ncase.expr = copynode(n->ncase.expr); | 9553 | new->ncase.expr = copynode(n->ncase.expr); |
9559 | new->ncase.linno = n->ncase.linno; | 9554 | new->ncase.linno = n->ncase.linno; |
9560 | SAVE_PTR2(new->ncase.cases,new->ncase.expr); | 9555 | SAVE_PTR2(new->ncase.cases, "ncase.cases", NO_FREE, |
9561 | ANNOT2("ncase.cases","ncase.expr"); | 9556 | new->ncase.expr, "ncase.expr", NO_FREE); |
9562 | break; | 9557 | break; |
9563 | case NCLIST: | 9558 | case NCLIST: |
9564 | new->nclist.body = copynode(n->nclist.body); | 9559 | new->nclist.body = copynode(n->nclist.body); |
9565 | new->nclist.pattern = copynode(n->nclist.pattern); | 9560 | new->nclist.pattern = copynode(n->nclist.pattern); |
9566 | new->nclist.next = copynode(n->nclist.next); | 9561 | new->nclist.next = copynode(n->nclist.next); |
9567 | SAVE_PTR3(new->nclist.body,new->nclist.pattern,new->nclist.next); | 9562 | SAVE_PTR3(new->nclist.body, "nclist.body", NO_FREE, |
9568 | ANNOT3("nclist.body","nclist.pattern","nclist.next"); | 9563 | new->nclist.pattern, "nclist.pattern", NO_FREE, |
9564 | new->nclist.next, "nclist.next", NO_FREE); | ||
9569 | break; | 9565 | break; |
9570 | case NDEFUN: | 9566 | case NDEFUN: |
9571 | new->ndefun.body = copynode(n->ndefun.body); | 9567 | new->ndefun.body = copynode(n->ndefun.body); |
9572 | new->ndefun.text = nodeckstrdup(n->ndefun.text); | 9568 | new->ndefun.text = nodeckstrdup(n->ndefun.text); |
9573 | new->ndefun.linno = n->ndefun.linno; | 9569 | new->ndefun.linno = n->ndefun.linno; |
9574 | SAVE_PTR2(new->ndefun.body,new->ndefun.text); | 9570 | SAVE_PTR2(new->ndefun.body, "ndefun.body", NO_FREE, |
9575 | ANNOT("ndefun.body"); | 9571 | new->ndefun.text, |
9576 | ANNOT_NO_DUP(xasprintf("ndefun.text '%s'", n->ndefun.text ?: "NULL")); | 9572 | xasprintf("ndefun.text '%s'", n->ndefun.text ?: "NULL"), FREE); |
9577 | break; | 9573 | break; |
9578 | case NARG: | 9574 | case NARG: |
9579 | new->narg.backquote = copynodelist(n->narg.backquote); | 9575 | new->narg.backquote = copynodelist(n->narg.backquote); |
9580 | new->narg.text = nodeckstrdup(n->narg.text); | 9576 | new->narg.text = nodeckstrdup(n->narg.text); |
9581 | new->narg.next = copynode(n->narg.next); | 9577 | new->narg.next = copynode(n->narg.next); |
9582 | SAVE_PTR3(new->narg.backquote,new->narg.text,new->narg.next); | 9578 | SAVE_PTR3(new->narg.backquote, "narg.backquote", NO_FREE, |
9583 | ANNOT2("narg.backquote","narg.next"); | 9579 | new->narg.text, |
9584 | ANNOT_NO_DUP(xasprintf("narg.text '%s'", n->narg.text ?: "NULL")); | 9580 | xasprintf("narg.text '%s'", n->narg.text ?: "NULL"), FREE, |
9581 | new->narg.next, "narg.next", NO_FREE); | ||
9585 | break; | 9582 | break; |
9586 | case NTO: | 9583 | case NTO: |
9587 | #if BASH_REDIR_OUTPUT | 9584 | #if BASH_REDIR_OUTPUT |
@@ -9594,8 +9591,8 @@ copynode(union node *n) | |||
9594 | new->nfile.fname = copynode(n->nfile.fname); | 9591 | new->nfile.fname = copynode(n->nfile.fname); |
9595 | new->nfile.fd = n->nfile.fd; | 9592 | new->nfile.fd = n->nfile.fd; |
9596 | new->nfile.next = copynode(n->nfile.next); | 9593 | new->nfile.next = copynode(n->nfile.next); |
9597 | SAVE_PTR2(new->nfile.fname,new->nfile.next); | 9594 | SAVE_PTR2(new->nfile.fname, "nfile.fname", NO_FREE, |
9598 | ANNOT2("nfile.fname","nfile.next"); | 9595 | new->nfile.next, "nfile.next", NO_FREE); |
9599 | break; | 9596 | break; |
9600 | case NTOFD: | 9597 | case NTOFD: |
9601 | case NFROMFD: | 9598 | case NFROMFD: |
@@ -9603,21 +9600,20 @@ copynode(union node *n) | |||
9603 | new->ndup.dupfd = n->ndup.dupfd; | 9600 | new->ndup.dupfd = n->ndup.dupfd; |
9604 | new->ndup.fd = n->ndup.fd; | 9601 | new->ndup.fd = n->ndup.fd; |
9605 | new->ndup.next = copynode(n->ndup.next); | 9602 | new->ndup.next = copynode(n->ndup.next); |
9606 | SAVE_PTR2(new->ndup.vname,new->ndup.next); | 9603 | SAVE_PTR2(new->ndup.vname, "ndup.vname", NO_FREE, |
9607 | ANNOT2("ndup.vname","ndup.next"); | 9604 | new->ndup.next, "ndup.next", NO_FREE); |
9608 | break; | 9605 | break; |
9609 | case NHERE: | 9606 | case NHERE: |
9610 | case NXHERE: | 9607 | case NXHERE: |
9611 | new->nhere.doc = copynode(n->nhere.doc); | 9608 | new->nhere.doc = copynode(n->nhere.doc); |
9612 | new->nhere.fd = n->nhere.fd; | 9609 | new->nhere.fd = n->nhere.fd; |
9613 | new->nhere.next = copynode(n->nhere.next); | 9610 | new->nhere.next = copynode(n->nhere.next); |
9614 | SAVE_PTR2(new->nhere.doc,new->nhere.next); | 9611 | SAVE_PTR2(new->nhere.doc, "nhere.doc", NO_FREE, |
9615 | ANNOT2("nhere.doc","nhere.next"); | 9612 | new->nhere.next, "nhere.next", NO_FREE); |
9616 | break; | 9613 | break; |
9617 | case NNOT: | 9614 | case NNOT: |
9618 | new->nnot.com = copynode(n->nnot.com); | 9615 | new->nnot.com = copynode(n->nnot.com); |
9619 | SAVE_PTR(new->nnot.com); | 9616 | SAVE_PTR(new->nnot.com, "nnot.com", NO_FREE); |
9620 | ANNOT("nnot.com"); | ||
9621 | break; | 9617 | break; |
9622 | }; | 9618 | }; |
9623 | new->type = n->type; | 9619 | new->type = n->type; |
@@ -9638,7 +9634,7 @@ copyfunc(union node *n) | |||
9638 | f = ckzalloc(blocksize /* + funcstringsize */); | 9634 | f = ckzalloc(blocksize /* + funcstringsize */); |
9639 | funcblock = (char *) f + offsetof(struct funcnode, n); | 9635 | funcblock = (char *) f + offsetof(struct funcnode, n); |
9640 | funcstring_end = (char *) f + blocksize; | 9636 | funcstring_end = (char *) f + blocksize; |
9641 | IF_PLATFORM_MINGW32(nodeptr = NULL); | 9637 | IF_PLATFORM_MINGW32(relocate = NULL); |
9642 | copynode(n); | 9638 | copynode(n); |
9643 | /* f->count = 0; - ckzalloc did it */ | 9639 | /* f->count = 0; - ckzalloc did it */ |
9644 | return f; | 9640 | return f; |
@@ -15494,24 +15490,32 @@ spawn_forkshell(struct forkshell *fs, struct job *jp, union node *n, int mode) | |||
15494 | * forkshell_prepare() and friends | 15490 | * forkshell_prepare() and friends |
15495 | * | 15491 | * |
15496 | * The sequence is as follows: | 15492 | * The sequence is as follows: |
15497 | * - funcblocksize, nodeptrcount are initialized | 15493 | * - funcblocksize is initialized |
15498 | * - forkshell_size(fs) is called to calculate the exact memory needed | 15494 | * - forkshell_size(fs) is called to calculate the exact memory needed |
15499 | * - a new struct is allocated | 15495 | * - a new struct is allocated |
15500 | * - funcblock, funcstring, nodeptr are initialized from the new block | 15496 | * - funcblock, funcstring, relocate are initialized from the new block |
15501 | * - forkshell_copy(fs) is called to copy recursively everything over | 15497 | * - forkshell_copy(fs) is called to copy recursively everything over |
15502 | * it will record all pointers along the way, to nodeptr | 15498 | * it will record all relocations along the way |
15503 | * | 15499 | * |
15504 | * When this memory is mapped elsewhere, pointer fixup will be needed | 15500 | * When this memory is mapped elsewhere, pointer fixup will be needed |
15505 | */ | 15501 | */ |
15506 | 15502 | ||
15507 | /* redefine without test that nodeptr is non-NULL */ | 15503 | /* redefine without test that relocate is non-NULL */ |
15508 | #undef SAVE_PTR | 15504 | #undef SAVE_PTR |
15509 | #undef SAVE_PTR2 | 15505 | #undef SAVE_PTR2 |
15510 | #undef SAVE_PTR3 | 15506 | #undef SAVE_PTR3 |
15511 | #define SAVE_PTR(dst) {*nodeptr++ = (char **)&(dst);} | 15507 | # define SAVE_PTR(dst,note,flag) { \ |
15512 | #define SAVE_PTR2(dst1,dst2) {SAVE_PTR(dst1); SAVE_PTR(dst2);} | 15508 | MARK_PTR(dst,flag); ANNOT(dst,note); \ |
15513 | #define SAVE_PTR3(dst1,dst2,dst3) {SAVE_PTR2(dst1,dst2); SAVE_PTR(dst3);} | 15509 | } |
15514 | #define SAVE_PTR4(dst1,dst2,dst3,dst4) {SAVE_PTR2(dst1,dst2); SAVE_PTR2(dst3,dst4);} | 15510 | # define SAVE_PTR2(dst1,note1,flag1,dst2,note2,flag2) { \ |
15511 | MARK_PTR(dst1,flag1); ANNOT(dst1,note1); \ | ||
15512 | MARK_PTR(dst2,flag2); ANNOT(dst2,note2); \ | ||
15513 | } | ||
15514 | # define SAVE_PTR3(dst1,note1,flag1,dst2,note2,flag2,dst3,note3,flag3) { \ | ||
15515 | MARK_PTR(dst1,flag1); ANNOT(dst1,note1); \ | ||
15516 | MARK_PTR(dst2,flag2); ANNOT(dst2,note2); \ | ||
15517 | MARK_PTR(dst3,flag3); ANNOT(dst3,note3); \ | ||
15518 | } | ||
15515 | 15519 | ||
15516 | static int align_len(const char *s) | 15520 | static int align_len(const char *s) |
15517 | { | 15521 | { |
@@ -15526,7 +15530,6 @@ name(int funcblocksize, type *p) \ | |||
15526 | funcblocksize += sizeof(type); | 15530 | funcblocksize += sizeof(type); |
15527 | /* do something here with p */ | 15531 | /* do something here with p */ |
15528 | #define SLIST_SIZE_END() \ | 15532 | #define SLIST_SIZE_END() \ |
15529 | nodeptrcount++; \ | ||
15530 | p = p->next; \ | 15533 | p = p->next; \ |
15531 | } \ | 15534 | } \ |
15532 | return funcblocksize; \ | 15535 | return funcblocksize; \ |
@@ -15544,8 +15547,7 @@ name(type *vp) \ | |||
15544 | funcblock = (char *) funcblock + sizeof(type); | 15547 | funcblock = (char *) funcblock + sizeof(type); |
15545 | /* do something here with vpp and vp */ | 15548 | /* do something here with vpp and vp */ |
15546 | #define SLIST_COPY_END() \ | 15549 | #define SLIST_COPY_END() \ |
15547 | SAVE_PTR((*vpp)->next); \ | 15550 | SAVE_PTR((*vpp)->next, "(*vpp)->next", NO_FREE); \ |
15548 | ANNOT("(*vpp)->next"); \ | ||
15549 | vp = vp->next; \ | 15551 | vp = vp->next; \ |
15550 | vpp = &(*vpp)->next; \ | 15552 | vpp = &(*vpp)->next; \ |
15551 | } \ | 15553 | } \ |
@@ -15558,15 +15560,13 @@ name(type *vp) \ | |||
15558 | */ | 15560 | */ |
15559 | SLIST_SIZE_BEGIN(var_size,struct var) | 15561 | SLIST_SIZE_BEGIN(var_size,struct var) |
15560 | funcblocksize += align_len(p->var_text); | 15562 | funcblocksize += align_len(p->var_text); |
15561 | nodeptrcount++; /* p->text */ | ||
15562 | SLIST_SIZE_END() | 15563 | SLIST_SIZE_END() |
15563 | 15564 | ||
15564 | SLIST_COPY_BEGIN(var_copy,struct var) | 15565 | SLIST_COPY_BEGIN(var_copy,struct var) |
15565 | (*vpp)->var_text = nodeckstrdup(vp->var_text); | 15566 | (*vpp)->var_text = nodeckstrdup(vp->var_text); |
15566 | (*vpp)->flags = vp->flags; | 15567 | (*vpp)->flags = vp->flags; |
15567 | (*vpp)->var_func = NULL; | 15568 | (*vpp)->var_func = NULL; |
15568 | SAVE_PTR((*vpp)->var_text); | 15569 | SAVE_PTR((*vpp)->var_text, xasprintf("(*vpp)->var_text '%s'", vp->var_text ?: "NULL"), FREE); |
15569 | ANNOT_NO_DUP(xasprintf("(*vpp)->var_text '%s'", vp->var_text ?: "NULL")); | ||
15570 | SLIST_COPY_END() | 15570 | SLIST_COPY_END() |
15571 | 15571 | ||
15572 | /* | 15572 | /* |
@@ -15574,13 +15574,11 @@ SLIST_COPY_END() | |||
15574 | */ | 15574 | */ |
15575 | SLIST_SIZE_BEGIN(strlist_size,struct strlist) | 15575 | SLIST_SIZE_BEGIN(strlist_size,struct strlist) |
15576 | funcblocksize += align_len(p->text); | 15576 | funcblocksize += align_len(p->text); |
15577 | nodeptrcount++; /* p->text */ | ||
15578 | SLIST_SIZE_END() | 15577 | SLIST_SIZE_END() |
15579 | 15578 | ||
15580 | SLIST_COPY_BEGIN(strlist_copy,struct strlist) | 15579 | SLIST_COPY_BEGIN(strlist_copy,struct strlist) |
15581 | (*vpp)->text = nodeckstrdup(vp->text); | 15580 | (*vpp)->text = nodeckstrdup(vp->text); |
15582 | SAVE_PTR((*vpp)->text); | 15581 | SAVE_PTR((*vpp)->text, xasprintf("(*vpp)->text '%s'", vp->text ?: "NULL"), FREE); |
15583 | ANNOT_NO_DUP(xasprintf("(*vpp)->text '%s'", vp->text ?: "NULL")); | ||
15584 | SLIST_COPY_END() | 15582 | SLIST_COPY_END() |
15585 | 15583 | ||
15586 | /* | 15584 | /* |
@@ -15595,9 +15593,7 @@ tblentry_size(int funcblocksize, struct tblentry *tep) | |||
15595 | if (tep->cmdtype == CMDFUNCTION) { | 15593 | if (tep->cmdtype == CMDFUNCTION) { |
15596 | funcblocksize += offsetof(struct funcnode, n); | 15594 | funcblocksize += offsetof(struct funcnode, n); |
15597 | funcblocksize = calcsize(funcblocksize, &tep->param.func->n); | 15595 | funcblocksize = calcsize(funcblocksize, &tep->param.func->n); |
15598 | nodeptrcount++; /* tep->param.func */ | ||
15599 | } | 15596 | } |
15600 | nodeptrcount++; /* tep->next */ | ||
15601 | tep = tep->next; | 15597 | tep = tep->next; |
15602 | } | 15598 | } |
15603 | return funcblocksize; | 15599 | return funcblocksize; |
@@ -15626,14 +15622,12 @@ tblentry_copy(struct tblentry *tep) | |||
15626 | (*newp)->param.func = funcblock; | 15622 | (*newp)->param.func = funcblock; |
15627 | funcblock = (char *) funcblock + offsetof(struct funcnode, n); | 15623 | funcblock = (char *) funcblock + offsetof(struct funcnode, n); |
15628 | copynode(&tep->param.func->n); | 15624 | copynode(&tep->param.func->n); |
15629 | SAVE_PTR((*newp)->param.func); | 15625 | SAVE_PTR((*newp)->param.func, "param.func", NO_FREE); |
15630 | ANNOT("param.func"); | ||
15631 | break; | 15626 | break; |
15632 | default: | 15627 | default: |
15633 | break; | 15628 | break; |
15634 | } | 15629 | } |
15635 | SAVE_PTR((*newp)->next); | 15630 | SAVE_PTR((*newp)->next, xasprintf("cmdname '%s'", tep->cmdname), FREE); |
15636 | ANNOT_NO_DUP(xasprintf("cmdname '%s'", tep->cmdname)); | ||
15637 | tep = tep->next; | 15631 | tep = tep->next; |
15638 | newp = &(*newp)->next; | 15632 | newp = &(*newp)->next; |
15639 | } | 15633 | } |
@@ -15645,7 +15639,6 @@ static int | |||
15645 | cmdtable_size(int funcblocksize, struct tblentry **cmdtablep) | 15639 | cmdtable_size(int funcblocksize, struct tblentry **cmdtablep) |
15646 | { | 15640 | { |
15647 | int i; | 15641 | int i; |
15648 | nodeptrcount += CMDTABLESIZE; | ||
15649 | funcblocksize += sizeof(struct tblentry *)*CMDTABLESIZE; | 15642 | funcblocksize += sizeof(struct tblentry *)*CMDTABLESIZE; |
15650 | for (i = 0; i < CMDTABLESIZE; i++) | 15643 | for (i = 0; i < CMDTABLESIZE; i++) |
15651 | funcblocksize = tblentry_size(funcblocksize, cmdtablep[i]); | 15644 | funcblocksize = tblentry_size(funcblocksize, cmdtablep[i]); |
@@ -15661,8 +15654,7 @@ cmdtable_copy(struct tblentry **cmdtablep) | |||
15661 | funcblock = (char *) funcblock + sizeof(struct tblentry *)*CMDTABLESIZE; | 15654 | funcblock = (char *) funcblock + sizeof(struct tblentry *)*CMDTABLESIZE; |
15662 | for (i = 0; i < CMDTABLESIZE; i++) { | 15655 | for (i = 0; i < CMDTABLESIZE; i++) { |
15663 | new[i] = tblentry_copy(cmdtablep[i]); | 15656 | new[i] = tblentry_copy(cmdtablep[i]); |
15664 | SAVE_PTR(new[i]); | 15657 | SAVE_PTR(new[i], xasprintf("cmdtable[%d]", i), FREE); |
15665 | ANNOT_NO_DUP(xasprintf("cmdtablep[%d]", i)); | ||
15666 | } | 15658 | } |
15667 | return new; | 15659 | return new; |
15668 | } | 15660 | } |
@@ -15674,24 +15666,20 @@ cmdtable_copy(struct tblentry **cmdtablep) | |||
15674 | SLIST_SIZE_BEGIN(alias_size,struct alias) | 15666 | SLIST_SIZE_BEGIN(alias_size,struct alias) |
15675 | funcblocksize += align_len(p->name); | 15667 | funcblocksize += align_len(p->name); |
15676 | funcblocksize += align_len(p->val); | 15668 | funcblocksize += align_len(p->val); |
15677 | nodeptrcount += 2; | ||
15678 | SLIST_SIZE_END() | 15669 | SLIST_SIZE_END() |
15679 | 15670 | ||
15680 | SLIST_COPY_BEGIN(alias_copy,struct alias) | 15671 | SLIST_COPY_BEGIN(alias_copy,struct alias) |
15681 | (*vpp)->name = nodeckstrdup(vp->name); | 15672 | (*vpp)->name = nodeckstrdup(vp->name); |
15682 | (*vpp)->val = nodeckstrdup(vp->val); | 15673 | (*vpp)->val = nodeckstrdup(vp->val); |
15683 | (*vpp)->flag = vp->flag; | 15674 | (*vpp)->flag = vp->flag; |
15684 | SAVE_PTR((*vpp)->name); | 15675 | SAVE_PTR((*vpp)->name, xasprintf("(*vpp)->name '%s'", vp->name ?: "NULL"), FREE); |
15685 | ANNOT_NO_DUP(xasprintf("(*vpp)->name '%s'", vp->name ?: "NULL")); | 15676 | SAVE_PTR((*vpp)->val, xasprintf("(*vpp)->val '%s'", vp->val ?: "NULL"), FREE); |
15686 | SAVE_PTR((*vpp)->val); | ||
15687 | ANNOT_NO_DUP(xasprintf("(*vpp)->val '%s'", vp->val ?: "NULL")); | ||
15688 | SLIST_COPY_END() | 15677 | SLIST_COPY_END() |
15689 | 15678 | ||
15690 | static int | 15679 | static int |
15691 | atab_size(int funcblocksize, struct alias **atabp) | 15680 | atab_size(int funcblocksize, struct alias **atabp) |
15692 | { | 15681 | { |
15693 | int i; | 15682 | int i; |
15694 | nodeptrcount += ATABSIZE; | ||
15695 | funcblocksize += sizeof(struct alias *)*ATABSIZE; | 15683 | funcblocksize += sizeof(struct alias *)*ATABSIZE; |
15696 | for (i = 0; i < ATABSIZE; i++) | 15684 | for (i = 0; i < ATABSIZE; i++) |
15697 | funcblocksize = alias_size(funcblocksize, atabp[i]); | 15685 | funcblocksize = alias_size(funcblocksize, atabp[i]); |
@@ -15707,8 +15695,7 @@ atab_copy(struct alias **atabp) | |||
15707 | funcblock = (char *) funcblock + sizeof(struct alias *)*ATABSIZE; | 15695 | funcblock = (char *) funcblock + sizeof(struct alias *)*ATABSIZE; |
15708 | for (i = 0; i < ATABSIZE; i++) { | 15696 | for (i = 0; i < ATABSIZE; i++) { |
15709 | new[i] = alias_copy(atabp[i]); | 15697 | new[i] = alias_copy(atabp[i]); |
15710 | SAVE_PTR(new[i]); | 15698 | SAVE_PTR(new[i], xasprintf("atab[%d]", i), FREE); |
15711 | ANNOT_NO_DUP(xasprintf("atabp[%d]", i)); | ||
15712 | } | 15699 | } |
15713 | return new; | 15700 | return new; |
15714 | } | 15701 | } |
@@ -15723,7 +15710,6 @@ argv_size(int funcblocksize, char **p) | |||
15723 | while (p && *p) { | 15710 | while (p && *p) { |
15724 | funcblocksize += sizeof(char *); | 15711 | funcblocksize += sizeof(char *); |
15725 | funcblocksize += align_len(*p); | 15712 | funcblocksize += align_len(*p); |
15726 | nodeptrcount++; | ||
15727 | p++; | 15713 | p++; |
15728 | } | 15714 | } |
15729 | funcblocksize += sizeof(char *); | 15715 | funcblocksize += sizeof(char *); |
@@ -15742,8 +15728,7 @@ argv_copy(char **p) | |||
15742 | new = funcblock; | 15728 | new = funcblock; |
15743 | funcblock = (char *) funcblock + sizeof(char *); | 15729 | funcblock = (char *) funcblock + sizeof(char *); |
15744 | *new = nodeckstrdup(*p); | 15730 | *new = nodeckstrdup(*p); |
15745 | SAVE_PTR(*new); | 15731 | SAVE_PTR(*new, xasprintf("argv[%d] '%s'", i++, *p), FREE); |
15746 | ANNOT_NO_DUP(xasprintf("argv[%d] '%s'", i++, *p)); | ||
15747 | p++; | 15732 | p++; |
15748 | } | 15733 | } |
15749 | new = funcblock; | 15734 | new = funcblock; |
@@ -15762,7 +15747,6 @@ history_size(int funcblocksize, line_input_t *st) | |||
15762 | for (i = 0; i < st->cnt_history; i++) { | 15747 | for (i = 0; i < st->cnt_history; i++) { |
15763 | funcblocksize += align_len(st->history[i]); | 15748 | funcblocksize += align_len(st->history[i]); |
15764 | } | 15749 | } |
15765 | nodeptrcount += st->cnt_history; | ||
15766 | return funcblocksize; | 15750 | return funcblocksize; |
15767 | } | 15751 | } |
15768 | 15752 | ||
@@ -15776,8 +15760,7 @@ history_copy(line_input_t *st) | |||
15776 | new = funcblock; | 15760 | new = funcblock; |
15777 | funcblock = (char *) funcblock + sizeof(char *); | 15761 | funcblock = (char *) funcblock + sizeof(char *); |
15778 | *new = nodeckstrdup(st->history[i]); | 15762 | *new = nodeckstrdup(st->history[i]); |
15779 | SAVE_PTR(*new); | 15763 | SAVE_PTR(*new, xasprintf("history[%d] '%s'", i, st->history[i]), FREE); |
15780 | ANNOT_NO_DUP(xasprintf("history[%d] '%s'", i, st->history[i])); | ||
15781 | } | 15764 | } |
15782 | return start; | 15765 | return start; |
15783 | } | 15766 | } |
@@ -15792,7 +15775,6 @@ redirtab_size(int funcblocksize, struct redirtab *rdtp) | |||
15792 | while (rdtp) { | 15775 | while (rdtp) { |
15793 | funcblocksize += sizeof(*rdtp)+sizeof(rdtp->two_fd[0])*rdtp->pair_count; | 15776 | funcblocksize += sizeof(*rdtp)+sizeof(rdtp->two_fd[0])*rdtp->pair_count; |
15794 | rdtp = rdtp->next; | 15777 | rdtp = rdtp->next; |
15795 | nodeptrcount++; /* rdtp->next */ | ||
15796 | } | 15778 | } |
15797 | return funcblocksize; | 15779 | return funcblocksize; |
15798 | } | 15780 | } |
@@ -15809,8 +15791,7 @@ redirtab_copy(struct redirtab *rdtp) | |||
15809 | *vpp = funcblock; | 15791 | *vpp = funcblock; |
15810 | funcblock = (char *) funcblock + size; | 15792 | funcblock = (char *) funcblock + size; |
15811 | memcpy(*vpp, rdtp, size); | 15793 | memcpy(*vpp, rdtp, size); |
15812 | SAVE_PTR((*vpp)->next); | 15794 | SAVE_PTR((*vpp)->next, "(*vpp)->next", NO_FREE); |
15813 | ANNOT("(*vpp)->next"); | ||
15814 | rdtp = rdtp->next; | 15795 | rdtp = rdtp->next; |
15815 | vpp = &(*vpp)->next; | 15796 | vpp = &(*vpp)->next; |
15816 | } | 15797 | } |
@@ -15831,8 +15812,6 @@ globals_var_size(int funcblocksize, struct globals_var *gvp) | |||
15831 | funcblocksize = redirtab_size(funcblocksize, gvp->redirlist); | 15812 | funcblocksize = redirtab_size(funcblocksize, gvp->redirlist); |
15832 | for (i = 0; i < VTABSIZE; i++) | 15813 | for (i = 0; i < VTABSIZE; i++) |
15833 | funcblocksize = var_size(funcblocksize, gvp->vartab[i]); | 15814 | funcblocksize = var_size(funcblocksize, gvp->vartab[i]); |
15834 | /* gvp->redirlist, gvp->shellparam.p, vartab */ | ||
15835 | nodeptrcount += 2 + VTABSIZE; | ||
15836 | return funcblocksize; | 15815 | return funcblocksize; |
15837 | } | 15816 | } |
15838 | 15817 | ||
@@ -15849,17 +15828,14 @@ globals_var_copy(struct globals_var *gvp) | |||
15849 | /* shparam */ | 15828 | /* shparam */ |
15850 | new->shellparam.malloced = 0; | 15829 | new->shellparam.malloced = 0; |
15851 | new->shellparam.p = argv_copy(gvp->shellparam.p); | 15830 | new->shellparam.p = argv_copy(gvp->shellparam.p); |
15852 | SAVE_PTR(new->shellparam.p); | 15831 | SAVE_PTR(new->shellparam.p, "shellparam.p", NO_FREE); |
15853 | ANNOT("shellparam.p"); | ||
15854 | 15832 | ||
15855 | new->redirlist = redirtab_copy(gvp->redirlist); | 15833 | new->redirlist = redirtab_copy(gvp->redirlist); |
15856 | SAVE_PTR(new->redirlist); | 15834 | SAVE_PTR(new->redirlist, "redirlist", NO_FREE); |
15857 | ANNOT("redirlist"); | ||
15858 | 15835 | ||
15859 | for (i = 0; i < VTABSIZE; i++) { | 15836 | for (i = 0; i < VTABSIZE; i++) { |
15860 | new->vartab[i] = var_copy(gvp->vartab[i]); | 15837 | new->vartab[i] = var_copy(gvp->vartab[i]); |
15861 | SAVE_PTR(new->vartab[i]); | 15838 | SAVE_PTR(new->vartab[i], xasprintf("vartab[%d]", i), FREE); |
15862 | ANNOT_NO_DUP(xasprintf("vartab[%d]", i)); | ||
15863 | } | 15839 | } |
15864 | 15840 | ||
15865 | return new; | 15841 | return new; |
@@ -15882,7 +15858,6 @@ globals_misc_size(int funcblocksize, struct globals_misc *p) | |||
15882 | funcblocksize += align_len(p->physdir); | 15858 | funcblocksize += align_len(p->physdir); |
15883 | funcblocksize += align_len(p->arg0); | 15859 | funcblocksize += align_len(p->arg0); |
15884 | funcblocksize += align_len(p->commandname); | 15860 | funcblocksize += align_len(p->commandname); |
15885 | nodeptrcount += 5; /* minusc, curdir, physdir, arg0, commandname */ | ||
15886 | return funcblocksize; | 15861 | return funcblocksize; |
15887 | } | 15862 | } |
15888 | 15863 | ||
@@ -15899,19 +15874,22 @@ globals_misc_copy(struct globals_misc *p) | |||
15899 | new->physdir = p->physdir != p->nullstr ? nodeckstrdup(p->physdir) : new->nullstr; | 15874 | new->physdir = p->physdir != p->nullstr ? nodeckstrdup(p->physdir) : new->nullstr; |
15900 | new->arg0 = nodeckstrdup(p->arg0); | 15875 | new->arg0 = nodeckstrdup(p->arg0); |
15901 | new->commandname = nodeckstrdup(p->commandname); | 15876 | new->commandname = nodeckstrdup(p->commandname); |
15902 | SAVE_PTR4(new->minusc, new->curdir, new->physdir, new->arg0); | 15877 | SAVE_PTR3( |
15903 | SAVE_PTR(new->commandname); | 15878 | new->minusc, xasprintf("minusc '%s'", p->minusc ?: "NULL"), FREE, |
15904 | ANNOT_NO_DUP(xasprintf("minusc '%s'", p->minusc ?: "NULL")); | 15879 | new->curdir, xasprintf("curdir '%s'", new->curdir ?: "NULL"), FREE, |
15905 | ANNOT_NO_DUP(xasprintf("curdir '%s'", new->curdir ?: "NULL")); | 15880 | new->physdir, xasprintf("physdir '%s'", new->physdir ?: "NULL"), FREE); |
15906 | ANNOT_NO_DUP(xasprintf("physdir '%s'", new->physdir ?: "NULL")); | 15881 | SAVE_PTR2( |
15907 | ANNOT_NO_DUP(xasprintf("arg0 '%s'", p->arg0 ?: "NULL");) | 15882 | new->arg0, xasprintf("arg0 '%s'", p->arg0 ?: "NULL"), FREE, |
15908 | ANNOT_NO_DUP(xasprintf("commandname '%s'", p->commandname ?: "NULL")); | 15883 | new->commandname, |
15884 | xasprintf("commandname '%s'", p->commandname ?: "NULL"), FREE); | ||
15909 | return new; | 15885 | return new; |
15910 | } | 15886 | } |
15911 | 15887 | ||
15912 | static int | 15888 | static int |
15913 | forkshell_size(int funcblocksize, struct forkshell *fs) | 15889 | forkshell_size(struct forkshell *fs) |
15914 | { | 15890 | { |
15891 | int funcblocksize = 0; | ||
15892 | |||
15915 | funcblocksize = globals_var_size(funcblocksize, fs->gvp); | 15893 | funcblocksize = globals_var_size(funcblocksize, fs->gvp); |
15916 | funcblocksize = globals_misc_size(funcblocksize, fs->gmp); | 15894 | funcblocksize = globals_misc_size(funcblocksize, fs->gmp); |
15917 | funcblocksize = cmdtable_size(funcblocksize, fs->cmdtable); | 15895 | funcblocksize = cmdtable_size(funcblocksize, fs->cmdtable); |
@@ -15926,16 +15904,9 @@ forkshell_size(int funcblocksize, struct forkshell *fs) | |||
15926 | funcblocksize += align_len(fs->path); | 15904 | funcblocksize += align_len(fs->path); |
15927 | funcblocksize = strlist_size(funcblocksize, fs->varlist); | 15905 | funcblocksize = strlist_size(funcblocksize, fs->varlist); |
15928 | 15906 | ||
15929 | #if ENABLE_ASH_ALIAS | ||
15930 | nodeptrcount += 8; /* gvp, gmp, cmdtable, atab, n, argv, string, strlist */ | ||
15931 | #else | ||
15932 | nodeptrcount += 7; /* gvp, gmp, cmdtable, n, argv, string, strlist */ | ||
15933 | #endif | ||
15934 | |||
15935 | #if MAX_HISTORY | 15907 | #if MAX_HISTORY |
15936 | if (line_input_state) { | 15908 | if (line_input_state) { |
15937 | funcblocksize = history_size(funcblocksize, line_input_state); | 15909 | funcblocksize = history_size(funcblocksize, line_input_state); |
15938 | nodeptrcount++; /* history */ | ||
15939 | } | 15910 | } |
15940 | #endif | 15911 | #endif |
15941 | return funcblocksize; | 15912 | return funcblocksize; |
@@ -15948,29 +15919,28 @@ forkshell_copy(struct forkshell *fs, struct forkshell *new) | |||
15948 | new->gvp = globals_var_copy(fs->gvp); | 15919 | new->gvp = globals_var_copy(fs->gvp); |
15949 | new->gmp = globals_misc_copy(fs->gmp); | 15920 | new->gmp = globals_misc_copy(fs->gmp); |
15950 | new->cmdtable = cmdtable_copy(fs->cmdtable); | 15921 | new->cmdtable = cmdtable_copy(fs->cmdtable); |
15922 | SAVE_PTR3(new->gvp, "gvp", NO_FREE, | ||
15923 | new->gmp, "gmp", NO_FREE, | ||
15924 | new->cmdtable, "cmdtable", NO_FREE); | ||
15925 | |||
15951 | #if ENABLE_ASH_ALIAS | 15926 | #if ENABLE_ASH_ALIAS |
15952 | new->atab = atab_copy(fs->atab); | 15927 | new->atab = atab_copy(fs->atab); |
15953 | SAVE_PTR4(new->gvp, new->gmp, new->cmdtable, new->atab); | 15928 | SAVE_PTR(new->atab, "atab", NO_FREE); |
15954 | ANNOT4("gvp", "gmp", "cmdtable", "atab"); | ||
15955 | #else | ||
15956 | SAVE_PTR3(new->gvp, new->gmp, new->cmdtable); | ||
15957 | ANNOT3("gvp", "gmp", "cmdtable"); | ||
15958 | #endif | 15929 | #endif |
15959 | 15930 | ||
15960 | new->n = copynode(fs->n); | 15931 | new->n = copynode(fs->n); |
15961 | new->argv = argv_copy(fs->argv); | 15932 | new->argv = argv_copy(fs->argv); |
15962 | new->path = nodeckstrdup(fs->path); | 15933 | new->path = nodeckstrdup(fs->path); |
15963 | new->varlist = strlist_copy(fs->varlist); | 15934 | new->varlist = strlist_copy(fs->varlist); |
15964 | SAVE_PTR4(new->n, new->argv, new->path, new->varlist); | 15935 | SAVE_PTR2( new->n, "n", NO_FREE, |
15965 | ANNOT2("n", "argv"); | 15936 | new->argv, "argv", NO_FREE); |
15966 | ANNOT_NO_DUP(xasprintf("path '%s'", fs->path ?: "NULL")); | 15937 | SAVE_PTR2(new->path, xasprintf("path '%s'", fs->path ?: "NULL"), FREE, |
15967 | ANNOT("varlist"); | 15938 | new->varlist, "varlist", NO_FREE); |
15968 | 15939 | ||
15969 | #if MAX_HISTORY | 15940 | #if MAX_HISTORY |
15970 | if (line_input_state) { | 15941 | if (line_input_state) { |
15971 | new->history = history_copy(line_input_state); | 15942 | new->history = history_copy(line_input_state); |
15972 | SAVE_PTR(new->history); | 15943 | SAVE_PTR(new->history, "history", NO_FREE); |
15973 | ANNOT("history"); | ||
15974 | new->cnt_history = line_input_state->cnt_history; | 15944 | new->cnt_history = line_input_state->cnt_history; |
15975 | } | 15945 | } |
15976 | #endif | 15946 | #endif |
@@ -15979,14 +15949,14 @@ forkshell_copy(struct forkshell *fs, struct forkshell *new) | |||
15979 | #if FORKSHELL_DEBUG | 15949 | #if FORKSHELL_DEBUG |
15980 | /* fp and notes can each be NULL */ | 15950 | /* fp and notes can each be NULL */ |
15981 | static void | 15951 | static void |
15982 | forkshell_print(FILE *fp0, struct forkshell *fs, char **notes) | 15952 | forkshell_print(FILE *fp0, struct forkshell *fs, const char **notes) |
15983 | { | 15953 | { |
15984 | FILE *fp; | 15954 | FILE *fp; |
15985 | void *lfuncblock; | 15955 | void *lfuncblock; |
15986 | char *lfuncstring; | 15956 | char *lfuncstring; |
15987 | char ***lnodeptr; | 15957 | char *lrelocate; |
15988 | char *s; | 15958 | char *s; |
15989 | int count; | 15959 | int count, i; |
15990 | int size_gvp, size_gmp, size_cmdtable, size_atab, size_history, total; | 15960 | int size_gvp, size_gmp, size_cmdtable, size_atab, size_history, total; |
15991 | 15961 | ||
15992 | if (fp0 != NULL) { | 15962 | if (fp0 != NULL) { |
@@ -16000,13 +15970,15 @@ forkshell_print(FILE *fp0, struct forkshell *fs, char **notes) | |||
16000 | return; | 15970 | return; |
16001 | } | 15971 | } |
16002 | 15972 | ||
16003 | fprintf(fp, "size %d = %d + %d*%d + %d + %d\n", fs->size, | 15973 | total = sizeof(struct forkshell) + fs->funcblocksize + |
16004 | (int)sizeof(struct forkshell), fs->nodeptrcount, | 15974 | fs->funcstringsize + fs->relocatesize; |
16005 | (int)sizeof(char *), fs->funcblocksize, fs->funcstringsize); | 15975 | fprintf(fp, "total size %6d = %d + %d + %d + %d = %d\n", 2*fs->size, |
15976 | (int)sizeof(struct forkshell), fs->funcblocksize, | ||
15977 | fs->funcstringsize, fs->relocatesize, total); | ||
16006 | 15978 | ||
16007 | lnodeptr = fs->nodeptr; | 15979 | lfuncblock = (char *)(fs + 1); |
16008 | lfuncblock = (char *)lnodeptr + (fs->nodeptrcount+1)*sizeof(char *); | ||
16009 | lfuncstring = (char *)lfuncblock + fs->funcblocksize; | 15980 | lfuncstring = (char *)lfuncblock + fs->funcblocksize; |
15981 | lrelocate = (char *)lfuncstring + fs->funcstringsize; | ||
16010 | 15982 | ||
16011 | size_gvp = (int)((char *)fs->gmp-(char *)fs->gvp); | 15983 | size_gvp = (int)((char *)fs->gmp-(char *)fs->gvp); |
16012 | size_gmp = (int)((char *)fs->cmdtable-(char *)fs->gmp); | 15984 | size_gmp = (int)((char *)fs->cmdtable-(char *)fs->gmp); |
@@ -16040,33 +16012,21 @@ forkshell_print(FILE *fp0, struct forkshell *fs, char **notes) | |||
16040 | size_history = 0; | 16012 | size_history = 0; |
16041 | #endif | 16013 | #endif |
16042 | total = size_gvp + size_gmp + size_cmdtable + size_atab + size_history; | 16014 | total = size_gvp + size_gmp + size_cmdtable + size_atab + size_history; |
16043 | fprintf(fp, "funcblocksize %d = %d + %d + %d + %d + %d = %d\n\n", | 16015 | fprintf(fp, "funcblocksize %6d = %d + %d + %d + %d + %d = %d\n\n", |
16044 | fs->funcblocksize, size_gvp, size_gmp, size_cmdtable, | 16016 | fs->funcblocksize, size_gvp, size_gmp, size_cmdtable, |
16045 | size_atab, size_history, total); | 16017 | size_atab, size_history, total); |
16046 | 16018 | ||
16047 | fprintf(fp, "--- nodeptr ---\n"); | 16019 | fprintf(fp, "--- relocate ---\n"); |
16048 | count = 0; | 16020 | count = 0; |
16049 | if (notes == NULL) { | 16021 | for (i = 0; i < fs->relocatesize; ++i) { |
16050 | while (*lnodeptr) { | 16022 | if (lrelocate[i]) { |
16051 | fprintf(fp, "%p ", *lnodeptr++); | 16023 | char **ptr = (char **)((char *)fs + i); |
16052 | if ((count&3) == 3) | 16024 | fprintf(fp, "%p %p %s\n", ptr, *ptr, |
16053 | fprintf(fp, "\n"); | 16025 | notes && notes[i] ? notes[i] : ""); |
16054 | ++count; | 16026 | ++count; |
16055 | } | 16027 | } |
16056 | if (((count-1)&3) != 3) | ||
16057 | fprintf(fp, "\n"); | ||
16058 | } | ||
16059 | else { | ||
16060 | while (*lnodeptr) { | ||
16061 | fprintf(fp, "%p %p %s\n", *lnodeptr, **lnodeptr, notes[count++]); | ||
16062 | lnodeptr++; | ||
16063 | } | ||
16064 | } | 16028 | } |
16065 | if (count != fs->nodeptrcount) | 16029 | fprintf(fp, "--- %d relocations ---\n\n", count); |
16066 | fprintf(fp, "--- %d pointers (expected %d) ---\n\n", count, | ||
16067 | fs->nodeptrcount); | ||
16068 | else | ||
16069 | fprintf(fp, "--- %d pointers ---\n\n", count); | ||
16070 | 16030 | ||
16071 | fprintf(fp, "--- funcstring ---\n"); | 16031 | fprintf(fp, "--- funcstring ---\n"); |
16072 | count = 0; | 16032 | count = 0; |
@@ -16090,13 +16050,11 @@ forkshell_print(FILE *fp0, struct forkshell *fs, char **notes) | |||
16090 | static struct forkshell * | 16050 | static struct forkshell * |
16091 | forkshell_prepare(struct forkshell *fs) | 16051 | forkshell_prepare(struct forkshell *fs) |
16092 | { | 16052 | { |
16093 | int funcblocksize; | ||
16094 | struct forkshell *new; | 16053 | struct forkshell *new; |
16095 | int size; | 16054 | int size; |
16096 | HANDLE h; | 16055 | HANDLE h; |
16097 | SECURITY_ATTRIBUTES sa; | 16056 | SECURITY_ATTRIBUTES sa; |
16098 | #if FORKSHELL_DEBUG | 16057 | #if FORKSHELL_DEBUG |
16099 | void *fb0; | ||
16100 | char name[32]; | 16058 | char name[32]; |
16101 | FILE *fp; | 16059 | FILE *fp; |
16102 | #endif | 16060 | #endif |
@@ -16109,37 +16067,32 @@ forkshell_prepare(struct forkshell *fs) | |||
16109 | fs->atab = atab; | 16067 | fs->atab = atab; |
16110 | #endif | 16068 | #endif |
16111 | 16069 | ||
16112 | /* | 16070 | /* calculate size of structure, funcblock and funcstring */ |
16113 | * Careful: much scope for off-by-one errors. nodeptrcount is the | 16071 | size = sizeof(struct forkshell) + forkshell_size(fs); |
16114 | * number of actual pointers. There's also a terminating NULL pointer. | ||
16115 | * The array in the forkshell structure gives us one element for free. | ||
16116 | */ | ||
16117 | nodeptrcount = 0; | ||
16118 | funcblocksize = forkshell_size(0, fs); | ||
16119 | size = sizeof(struct forkshell) + nodeptrcount*sizeof(char *) + | ||
16120 | funcblocksize; | ||
16121 | 16072 | ||
16122 | /* Allocate, initialize pointers */ | 16073 | /* Allocate shared memory region. We allocate twice 'size' to allow |
16074 | * for the relocation map. This is an overestimate as the relocation | ||
16075 | * map only needs to cover the forkshell structure and funcblock but | ||
16076 | * the size of funcstring isn't known separately at this point. */ | ||
16123 | memset(&sa, 0, sizeof(sa)); | 16077 | memset(&sa, 0, sizeof(sa)); |
16124 | sa.nLength = sizeof(sa); | 16078 | sa.nLength = sizeof(sa); |
16125 | sa.lpSecurityDescriptor = NULL; | 16079 | sa.lpSecurityDescriptor = NULL; |
16126 | sa.bInheritHandle = TRUE; | 16080 | sa.bInheritHandle = TRUE; |
16127 | h = CreateFileMapping(INVALID_HANDLE_VALUE, &sa, PAGE_READWRITE, 0, size, NULL); | 16081 | h = CreateFileMapping(INVALID_HANDLE_VALUE, &sa, PAGE_READWRITE, 0, 2*size, NULL); |
16082 | |||
16083 | /* Initialise pointers */ | ||
16128 | new = (struct forkshell *)MapViewOfFile(h, FILE_MAP_WRITE, 0,0, 0); | 16084 | new = (struct forkshell *)MapViewOfFile(h, FILE_MAP_WRITE, 0,0, 0); |
16129 | nodeptr = new->nodeptr; | 16085 | fs_start = new; |
16130 | funcblock = (char *)nodeptr + (nodeptrcount+1)*sizeof(char *); | 16086 | funcblock = (char *)(new + 1); |
16131 | funcstring_end = (char *)new + size; | 16087 | funcstring_end = relocate = (char *)new + size; |
16132 | #if FORKSHELL_DEBUG | 16088 | #if FORKSHELL_DEBUG |
16133 | fb0 = funcblock; | 16089 | annot = (const char **)xzalloc(sizeof(char *)*size); |
16134 | annot = xmalloc(sizeof(char *)*nodeptrcount); | ||
16135 | annot_count = 0; | ||
16136 | #endif | 16090 | #endif |
16137 | 16091 | ||
16138 | /* Now pack them all */ | 16092 | /* Now pack them all */ |
16139 | forkshell_copy(fs, new); | 16093 | forkshell_copy(fs, new); |
16140 | 16094 | ||
16141 | /* Finish it up */ | 16095 | /* Finish it up */ |
16142 | *nodeptr = NULL; | ||
16143 | new->size = size; | 16096 | new->size = size; |
16144 | new->old_base = (char *)new; | 16097 | new->old_base = (char *)new; |
16145 | new->hMapFile = h; | 16098 | new->hMapFile = h; |
@@ -16148,35 +16101,34 @@ forkshell_prepare(struct forkshell *fs) | |||
16148 | if ((fp=fopen(name, "w")) != NULL) { | 16101 | if ((fp=fopen(name, "w")) != NULL) { |
16149 | int i; | 16102 | int i; |
16150 | 16103 | ||
16151 | /* perform some sanity checks on pointers */ | 16104 | new->funcblocksize = (char *)funcblock - (char *)(new + 1); |
16152 | fprintf(fp, "%p start of forkshell struct\n", new); | 16105 | new->funcstringsize = (char *)new + size - funcstring_end; |
16153 | fprintf(fp, "%p start of nodeptr\n", new->nodeptr); | 16106 | new->relocatesize = size; |
16154 | fprintf(fp, "%p start of funcblock", fb0); | ||
16155 | if ((char *)(nodeptr+1) != (char *)fb0) | ||
16156 | fprintf(fp, " != end nodeptr block + 1 %p\n", nodeptr+1); | ||
16157 | else | ||
16158 | fprintf(fp, "\n"); | ||
16159 | 16107 | ||
16160 | fprintf(fp, "%p start of funcstring", funcstring_end); | 16108 | /* perform some sanity checks on pointers */ |
16109 | fprintf(fp, "forkshell %p %6d\n", new, (int)sizeof(*new)); | ||
16110 | fprintf(fp, "funcblock %p %6d\n", new+1, new->funcblocksize); | ||
16111 | fprintf(fp, "funcstring %p %6d\n", funcstring_end, | ||
16112 | new->funcstringsize); | ||
16161 | if ((char *)funcblock != funcstring_end) | 16113 | if ((char *)funcblock != funcstring_end) |
16162 | fprintf(fp, " != end funcblock + 1 %p\n\n", funcblock); | 16114 | fprintf(fp, " funcstring != end funcblock + 1 %p\n", funcblock); |
16163 | else | 16115 | fprintf(fp, "relocate %p %6d\n\n", relocate, new->relocatesize); |
16164 | fprintf(fp, "\n\n"); | ||
16165 | 16116 | ||
16166 | if (nodeptrcount != annot_count) | 16117 | forkshell_print(fp, new, annot); |
16167 | fprintf(fp, "nodeptrcount (%d) != annot_count (%d)\n\n", | ||
16168 | nodeptrcount, annot_count); | ||
16169 | |||
16170 | new->nodeptrcount = nodeptrcount; | ||
16171 | new->funcblocksize = (char *)funcblock - (char *)fb0; | ||
16172 | new->funcstringsize = (char *)new + size - funcstring_end; | ||
16173 | forkshell_print(fp, new, nodeptrcount == annot_count ? annot : NULL); | ||
16174 | 16118 | ||
16175 | for (i = 0; i < annot_count; ++i) | 16119 | for (i = 0; i < size; ++i) { |
16176 | free(annot[i]); | 16120 | if (relocate[i] == FREE) { |
16121 | free((void *)annot[i]); | ||
16122 | } | ||
16123 | /* check relocations are only present for structure and funcblock */ | ||
16124 | if (i >= sizeof(*new)+new->funcblocksize && annot[i] != NULL) { | ||
16125 | fprintf(fp, "\nnon-NULL annotation at offset %d (> %d)\n", | ||
16126 | i, (int)sizeof(*new)+new->funcblocksize); | ||
16127 | break; | ||
16128 | } | ||
16129 | } | ||
16177 | free(annot); | 16130 | free(annot); |
16178 | annot = NULL; | 16131 | annot = NULL; |
16179 | annot_count = 0; | ||
16180 | fclose(fp); | 16132 | fclose(fp); |
16181 | } | 16133 | } |
16182 | #endif | 16134 | #endif |
@@ -16197,6 +16149,7 @@ forkshell_init(const char *idstr) | |||
16197 | struct globals_misc **gmpp; | 16149 | struct globals_misc **gmpp; |
16198 | int i; | 16150 | int i; |
16199 | char **ptr; | 16151 | char **ptr; |
16152 | char *lrelocate; | ||
16200 | 16153 | ||
16201 | if (sscanf(idstr, "%p", &map_handle) != 1) | 16154 | if (sscanf(idstr, "%p", &map_handle) != 1) |
16202 | bb_error_msg_and_die("invalid forkshell ID"); | 16155 | bb_error_msg_and_die("invalid forkshell ID"); |
@@ -16211,10 +16164,13 @@ forkshell_init(const char *idstr) | |||
16211 | sticky_mem_end = (char *) fs + fs->size; | 16164 | sticky_mem_end = (char *) fs + fs->size; |
16212 | 16165 | ||
16213 | /* pointer fixup */ | 16166 | /* pointer fixup */ |
16214 | for ( i=0; fs->nodeptr[i]; ++i ) { | 16167 | lrelocate = (char *)fs + fs->size; |
16215 | ptr = (char **)((char *)fs + ((char *)fs->nodeptr[i] - fs->old_base)); | 16168 | for (i = 0; i < fs->size; i++) { |
16216 | if (*ptr) | 16169 | if (lrelocate[i]) { |
16217 | *ptr = (char *)fs + (*ptr - fs->old_base); | 16170 | ptr = (char **)((char *)fs + i); |
16171 | if (*ptr) | ||
16172 | *ptr = (char *)fs + (*ptr - fs->old_base); | ||
16173 | } | ||
16218 | } | 16174 | } |
16219 | 16175 | ||
16220 | /* Now fix up stuff that can't be transferred */ | 16176 | /* Now fix up stuff that can't be transferred */ |