aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2020-01-16 14:26:53 +0000
committerRon Yorston <rmy@pobox.com>2020-01-16 14:26:53 +0000
commitdf87b596a3c4f404a06b3e902f9e085980ca62e0 (patch)
tree36bdd3062fa6cf5ce3f54351f6ff4126a63a9705
parent2ffcb860ea478d4b8d553fe59af5982c5939f7fa (diff)
downloadbusybox-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.c414
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
389enum { 386enum {
@@ -405,7 +402,7 @@ static void sticky_free(void *p);
405static void spawn_forkshell(struct forkshell *fs, struct job *jp, 402static 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
408static void forkshell_print(FILE *fp0, struct forkshell *fs, char **notes); 405static 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)
9283static void *funcblock; /* block to allocate function from */ 9280static void *funcblock; /* block to allocate function from */
9284static char *funcstring_end; /* end of block to allocate strings from */ 9281static char *funcstring_end; /* end of block to allocate strings from */
9285#if ENABLE_PLATFORM_MINGW32 9282#if ENABLE_PLATFORM_MINGW32
9286static int nodeptrcount; 9283static char *relocate;
9287static char ***nodeptr; 9284static void *fs_start;
9288# if FORKSHELL_DEBUG 9285# if FORKSHELL_DEBUG
9289static int annot_count; 9286static const char **annot;
9290static 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
9450static union node *copynode(union node *); 9431static 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
9476static struct nodelist * 9469static 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
15516static int align_len(const char *s) 15520static 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 */
15559SLIST_SIZE_BEGIN(var_size,struct var) 15561SLIST_SIZE_BEGIN(var_size,struct var)
15560funcblocksize += align_len(p->var_text); 15562funcblocksize += align_len(p->var_text);
15561nodeptrcount++; /* p->text */
15562SLIST_SIZE_END() 15563SLIST_SIZE_END()
15563 15564
15564SLIST_COPY_BEGIN(var_copy,struct var) 15565SLIST_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;
15568SAVE_PTR((*vpp)->var_text); 15569SAVE_PTR((*vpp)->var_text, xasprintf("(*vpp)->var_text '%s'", vp->var_text ?: "NULL"), FREE);
15569ANNOT_NO_DUP(xasprintf("(*vpp)->var_text '%s'", vp->var_text ?: "NULL"));
15570SLIST_COPY_END() 15570SLIST_COPY_END()
15571 15571
15572/* 15572/*
@@ -15574,13 +15574,11 @@ SLIST_COPY_END()
15574 */ 15574 */
15575SLIST_SIZE_BEGIN(strlist_size,struct strlist) 15575SLIST_SIZE_BEGIN(strlist_size,struct strlist)
15576funcblocksize += align_len(p->text); 15576funcblocksize += align_len(p->text);
15577nodeptrcount++; /* p->text */
15578SLIST_SIZE_END() 15577SLIST_SIZE_END()
15579 15578
15580SLIST_COPY_BEGIN(strlist_copy,struct strlist) 15579SLIST_COPY_BEGIN(strlist_copy,struct strlist)
15581(*vpp)->text = nodeckstrdup(vp->text); 15580(*vpp)->text = nodeckstrdup(vp->text);
15582SAVE_PTR((*vpp)->text); 15581SAVE_PTR((*vpp)->text, xasprintf("(*vpp)->text '%s'", vp->text ?: "NULL"), FREE);
15583ANNOT_NO_DUP(xasprintf("(*vpp)->text '%s'", vp->text ?: "NULL"));
15584SLIST_COPY_END() 15582SLIST_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
15645cmdtable_size(int funcblocksize, struct tblentry **cmdtablep) 15639cmdtable_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)
15674SLIST_SIZE_BEGIN(alias_size,struct alias) 15666SLIST_SIZE_BEGIN(alias_size,struct alias)
15675funcblocksize += align_len(p->name); 15667funcblocksize += align_len(p->name);
15676funcblocksize += align_len(p->val); 15668funcblocksize += align_len(p->val);
15677nodeptrcount += 2;
15678SLIST_SIZE_END() 15669SLIST_SIZE_END()
15679 15670
15680SLIST_COPY_BEGIN(alias_copy,struct alias) 15671SLIST_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;
15684SAVE_PTR((*vpp)->name); 15675SAVE_PTR((*vpp)->name, xasprintf("(*vpp)->name '%s'", vp->name ?: "NULL"), FREE);
15685ANNOT_NO_DUP(xasprintf("(*vpp)->name '%s'", vp->name ?: "NULL")); 15676SAVE_PTR((*vpp)->val, xasprintf("(*vpp)->val '%s'", vp->val ?: "NULL"), FREE);
15686SAVE_PTR((*vpp)->val);
15687ANNOT_NO_DUP(xasprintf("(*vpp)->val '%s'", vp->val ?: "NULL"));
15688SLIST_COPY_END() 15677SLIST_COPY_END()
15689 15678
15690static int 15679static int
15691atab_size(int funcblocksize, struct alias **atabp) 15680atab_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
15912static int 15888static int
15913forkshell_size(int funcblocksize, struct forkshell *fs) 15889forkshell_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 */
15981static void 15951static void
15982forkshell_print(FILE *fp0, struct forkshell *fs, char **notes) 15952forkshell_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)
16090static struct forkshell * 16050static struct forkshell *
16091forkshell_prepare(struct forkshell *fs) 16051forkshell_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 */