From 36c5c5bf4079bd12d669f6b2ce772227b12aa23a Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Thu, 4 Mar 2010 15:34:25 -0800 Subject: [PATCH] cc: disallow ... argument unless NOSPLIT is set. check that NOSPLIT functions don't use too much stack. correct some missing NOSPLITs in the runtime library. Fixes bug reported in https://groups.google.com/group/golang-nuts/t/efff68b73941eccf R=ken2 CC=golang-dev https://golang.org/cl/236041 --- src/cmd/5c/sgen.c | 10 +++++++++- src/cmd/6c/sgen.c | 8 ++++++-- src/cmd/8c/sgen.c | 10 +++++++++- src/cmd/cc/pgen.c | 1 + src/pkg/runtime/chan.c | 8 ++++++++ src/pkg/runtime/hashmap.c | 6 ++++++ src/pkg/runtime/print.c | 1 + src/pkg/runtime/proc.c | 10 ++++++---- 8 files changed, 46 insertions(+), 8 deletions(-) diff --git a/src/cmd/5c/sgen.c b/src/cmd/5c/sgen.c index 1584ecff33..92a0f64f83 100644 --- a/src/cmd/5c/sgen.c +++ b/src/cmd/5c/sgen.c @@ -34,9 +34,17 @@ Prog* gtext(Sym *s, int32 stkoff) { + int32 a; + + a = 0; + if(!(textflag & NOSPLIT)) + a = argsize(); + else if(stkoff >= 128) + yyerror("stack frame too large for NOSPLIT function"); + gpseudo(ATEXT, s, nodconst(stkoff)); p->to.type = D_CONST2; - p->to.offset2 = argsize(); + p->to.offset2 = a; return p; } diff --git a/src/cmd/6c/sgen.c b/src/cmd/6c/sgen.c index 1a5987f099..b8247a1b70 100644 --- a/src/cmd/6c/sgen.c +++ b/src/cmd/6c/sgen.c @@ -34,9 +34,13 @@ Prog* gtext(Sym *s, int32 stkoff) { vlong v; - - v = argsize() << 32; + + v = 0; + if(!(textflag & NOSPLIT)) + v |= argsize() << 32; v |= stkoff & 0xffffffff; + if((textflag & NOSPLIT) && stkoff >= 128) + yyerror("stack frame too large for NOSPLIT function"); gpseudo(ATEXT, s, nodgconst(v, types[TVLONG])); return p; diff --git a/src/cmd/8c/sgen.c b/src/cmd/8c/sgen.c index c4f91987ca..b0f2bc544c 100644 --- a/src/cmd/8c/sgen.c +++ b/src/cmd/8c/sgen.c @@ -33,9 +33,17 @@ Prog* gtext(Sym *s, int32 stkoff) { + int32 a; + + a = 0; + if(!(textflag & NOSPLIT)) + a = argsize(); + else if(stkoff >= 128) + yyerror("stack frame too large for NOSPLIT function"); + gpseudo(ATEXT, s, nodconst(stkoff)); p->to.type = D_CONST2; - p->to.offset2 = argsize(); + p->to.offset2 = a; return p; } diff --git a/src/cmd/cc/pgen.c b/src/cmd/cc/pgen.c index d430ec91b9..cd6fffc578 100644 --- a/src/cmd/cc/pgen.c +++ b/src/cmd/cc/pgen.c @@ -43,6 +43,7 @@ argsize(void) case TVOID: break; case TDOT: + yyerror("function takes ... without textflag NOSPLIT"); s += 64; break; default: diff --git a/src/pkg/runtime/chan.c b/src/pkg/runtime/chan.c index bee033fa11..ea3b493b62 100644 --- a/src/pkg/runtime/chan.c +++ b/src/pkg/runtime/chan.c @@ -393,6 +393,7 @@ closed: } // chansend1(hchan *chan any, elem any); +#pragma textflag 7 void ·chansend1(Hchan* c, ...) { @@ -405,6 +406,7 @@ void } // chansend2(hchan *chan any, elem any) (pres bool); +#pragma textflag 7 void ·chansend2(Hchan* c, ...) { @@ -420,6 +422,7 @@ void } // chanrecv1(hchan *chan any) (elem any); +#pragma textflag 7 void ·chanrecv1(Hchan* c, ...) { @@ -433,6 +436,7 @@ void } // chanrecv2(hchan *chan any) (elem any, pres bool); +#pragma textflag 7 void ·chanrecv2(Hchan* c, ...) { @@ -448,6 +452,7 @@ void } // newselect(size uint32) (sel *byte); +#pragma textflag 7 void ·newselect(int32 size, ...) { @@ -476,6 +481,7 @@ void } // selectsend(sel *byte, hchan *chan any, elem any) (selected bool); +#pragma textflag 7 void ·selectsend(Select *sel, Hchan *c, ...) { @@ -521,6 +527,7 @@ void } // selectrecv(sel *byte, hchan *chan any, elem *any) (selected bool); +#pragma textflag 7 void ·selectrecv(Select *sel, Hchan *c, ...) { @@ -563,6 +570,7 @@ void // selectdefaul(sel *byte) (selected bool); +#pragma textflag 7 void ·selectdefault(Select *sel, ...) { diff --git a/src/pkg/runtime/hashmap.c b/src/pkg/runtime/hashmap.c index 848aa650c9..281601fbc7 100644 --- a/src/pkg/runtime/hashmap.c +++ b/src/pkg/runtime/hashmap.c @@ -758,6 +758,7 @@ mapaccess(Hmap *h, byte *ak, byte *av, bool *pres) } // mapaccess1(hmap *map[any]any, key any) (val any); +#pragma textflag 7 void ·mapaccess1(Hmap *h, ...) { @@ -785,6 +786,7 @@ void } // mapaccess2(hmap *map[any]any, key any) (val any, pres bool); +#pragma textflag 7 void ·mapaccess2(Hmap *h, ...) { @@ -844,6 +846,7 @@ mapassign(Hmap *h, byte *ak, byte *av) } // mapassign1(hmap *map[any]any, key any, val any); +#pragma textflag 7 void ·mapassign1(Hmap *h, ...) { @@ -856,6 +859,7 @@ void } // mapassign2(hmap *map[any]any, key any, val any, pres bool); +#pragma textflag 7 void ·mapassign2(Hmap *h, ...) { @@ -934,6 +938,7 @@ mapiternext(struct hash_iter *it) } // mapiter1(hiter *any) (key any); +#pragma textflag 7 void ·mapiter1(struct hash_iter *it, ...) { @@ -973,6 +978,7 @@ mapiterkey(struct hash_iter *it, void *ak) } // mapiter2(hiter *any) (key any, val any); +#pragma textflag 7 void ·mapiter2(struct hash_iter *it, ...) { diff --git a/src/pkg/runtime/print.c b/src/pkg/runtime/print.c index d721f39535..92f49fba96 100644 --- a/src/pkg/runtime/print.c +++ b/src/pkg/runtime/print.c @@ -157,6 +157,7 @@ vprintf(int8 *s, byte *arg) // unlock(&debuglock); } +#pragma textflag 7 void ·printf(String s, ...) { diff --git a/src/pkg/runtime/proc.c b/src/pkg/runtime/proc.c index 9b4e34f6f7..c85e347e20 100644 --- a/src/pkg/runtime/proc.c +++ b/src/pkg/runtime/proc.c @@ -666,6 +666,7 @@ oldstack(void) uint32 args; byte *sp; G *g1; + static int32 goid; //printf("oldstack m->cret=%p\n", m->cret); @@ -678,6 +679,7 @@ oldstack(void) sp -= args; mcpy(top->fp, sp, args); } + goid = old.gobuf.g->goid; // fault if g is bad, before gogo stackfree(g1->stackguard - StackGuard); g1->stackbase = old.stackbase; @@ -765,9 +767,9 @@ malg(int32 stacksize) */ #pragma textflag 7 void -·newproc(int32 siz, byte* fn, byte* arg0) +·newproc(int32 siz, byte* fn, ...) { - newproc1(fn, (byte*)&arg0, siz, 0); + newproc1(fn, (byte*)(&fn+1), siz, 0); } void @@ -815,13 +817,13 @@ newproc1(byte *fn, byte *argp, int32 narg, int32 nret) #pragma textflag 7 void -·deferproc(int32 siz, byte* fn, byte* arg0) +·deferproc(int32 siz, byte* fn, ...) { Defer *d; d = malloc(sizeof(*d) + siz - sizeof(d->args)); d->fn = fn; - d->sp = (byte*)&arg0; + d->sp = (byte*)(&fn+1); d->siz = siz; mcpy(d->args, d->sp, d->siz);