diff options
Diffstat (limited to 'src/cmd/6l/pass.c')
-rw-r--r-- | src/cmd/6l/pass.c | 50 |
1 files changed, 44 insertions, 6 deletions
diff --git a/src/cmd/6l/pass.c b/src/cmd/6l/pass.c index e5b948a6e..7a95f7427 100644 --- a/src/cmd/6l/pass.c +++ b/src/cmd/6l/pass.c @@ -638,6 +638,9 @@ dostkoff(void) q = P; q1 = P; + if((p->from.scale & NOSPLIT) && autoffset >= StackSmall) + diag("nosplit func likely to overflow stack"); + if(!(p->from.scale & NOSPLIT)) { if(debug['K']) { // 6l -K means check not only for stack @@ -792,8 +795,44 @@ dostkoff(void) if(q != P) q->pcond = p; } - deltasp = autoffset; + + if(debug['K'] > 1 && autoffset) { + // 6l -KK means double-check for stack overflow + // even after calling morestack and even if the + // function is marked as nosplit. + p = appendp(p); + p->as = AMOVQ; + p->from.type = D_INDIR+D_R15; + p->from.offset = 0; + p->to.type = D_BX; + + p = appendp(p); + p->as = ASUBQ; + p->from.type = D_CONST; + p->from.offset = StackSmall+32; + p->to.type = D_BX; + + p = appendp(p); + p->as = ACMPQ; + p->from.type = D_SP; + p->to.type = D_BX; + + p = appendp(p); + p->as = AJHI; + p->to.type = D_BRANCH; + q1 = p; + + p = appendp(p); + p->as = AINT; + p->from.type = D_CONST; + p->from.offset = 3; + + p = appendp(p); + p->as = ANOP; + q1->pcond = p; + q1 = P; + } } pcsize = p->mode/8; a = p->from.type; @@ -844,13 +883,12 @@ dostkoff(void) goto become; if(autoffset) { - q = p; + p->as = AADJSP; + p->from.type = D_CONST; + p->from.offset = -autoffset; + p = appendp(p); p->as = ARET; - - q->as = AADJSP; - q->from.type = D_CONST; - q->from.offset = -autoffset; } continue; |