]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/5g, cmd/6g, cmd/8g: insert arg size annotations on runtime calls
authorRuss Cox <rsc@golang.org>
Tue, 16 Jul 2013 20:25:10 +0000 (16:25 -0400)
committerRuss Cox <rsc@golang.org>
Tue, 16 Jul 2013 20:25:10 +0000 (16:25 -0400)
If calling a function in package runtime, emit argument size
information around the call in case the call is to a variadic C function.

R=ken2
CC=golang-dev
https://golang.org/cl/11371043

src/cmd/5g/gg.h
src/cmd/5g/ggen.c
src/cmd/5g/gsubr.c
src/cmd/5g/peep.c
src/cmd/6g/gg.h
src/cmd/6g/ggen.c
src/cmd/6g/gsubr.c
src/cmd/8g/gg.h
src/cmd/8g/ggen.c
src/cmd/8g/gsubr.c

index 5d78915926014b7adaa23c55f4832261f57669e4..90fcbe394c977105ebef29607b6744094c219286 100644 (file)
@@ -146,6 +146,7 @@ void        split64(Node*, Node*, Node*);
 void   splitclean(void);
 Node*  ncon(uint32 i);
 void   gtrack(Sym*);
+void   gargsize(int32);
 
 /*
  * obj.c
index eb027c6a67ddcd3890fd5af5765b72527cef48f9..6e4f564618751152ffe47ce6d94fbff6b886f209 100644 (file)
@@ -73,9 +73,23 @@ fixautoused(Prog* p)
 void
 ginscall(Node *f, int proc)
 {
+       int32 arg;
        Prog *p;
        Node n1, r, r1, con;
 
+       if(f->type != T)
+               setmaxarg(f->type);
+
+       arg = -1;
+       if(f->type != T && ((f->sym != S && f->sym->pkg == runtimepkg) || proc == 1 || proc == 2)) {
+               arg = f->type->argwid;
+               if(proc == 1 || proc == 2)
+                       arg += 3*widthptr;
+       }
+
+       if(arg != -1)
+               gargsize(arg);
+
        switch(proc) {
        default:
                fatal("ginscall: bad proc %d", proc);
@@ -170,6 +184,9 @@ ginscall(Node *f, int proc)
                }
                break;
        }
+       
+       if(arg != -1)
+               gargsize(-1);
 }
 
 /*
@@ -239,14 +256,11 @@ cgen_callinter(Node *n, Node *res, int proc)
                p->from.type = D_CONST; // REG = &(20+offset(REG)) -- i.tab->fun[f]
        }
 
-       // BOTCH nodr.type = fntype;
        nodr.type = n->left->type;
        ginscall(&nodr, proc);
 
        regfree(&nodr);
        regfree(&nodo);
-
-       setmaxarg(n->left->type);
 }
 
 /*
@@ -274,8 +288,6 @@ cgen_call(Node *n, int proc)
        genlist(n->list);               // assign the args
        t = n->left->type;
 
-       setmaxarg(t);
-
        // call tempname pointer
        if(n->left->ullman >= UINF) {
                regalloc(&nod, types[tptr], N);
index 56b27da1361ecd776ac92da82480adfe584690b0..be4b7df5036f413c0f5ad32817eb76171ae1e9a0 100644 (file)
@@ -31,6 +31,7 @@
 #include <u.h>
 #include <libc.h>
 #include "gg.h"
+#include "../../pkg/runtime/funcdata.h"
 
 // TODO(rsc): Can make this bigger if we move
 // the text segment up higher in 5l for all GOOS.
@@ -209,6 +210,16 @@ ggloblnod(Node *nam)
                p->reg |= NOPTR;
 }
 
+void
+gargsize(int32 size)
+{
+       Node n1, n2;
+       
+       nodconst(&n1, types[TINT32], PCDATA_ArgSize);
+       nodconst(&n2, types[TINT32], size);
+       gins(APCDATA, &n1, &n2);
+}
+
 void
 ggloblsym(Sym *s, int32 width, int dupok, int rodata)
 {
index 01d4a1bbf2b719b3f8ec5480734b2d85d543bf3a..87afa86a8c0d8af3dbe7ff8b5d033356ecd6b98a 100644 (file)
@@ -1199,6 +1199,7 @@ copyu(Prog *p, Adr *v, Adr *s)
        case ALOCALS:   /* funny */
        case ANPTRS:
        case APTRS:
+       case APCDATA:
                return 0;
        }
 }
index d5b67283762a18a0c23e95a26f576d7f857f7583..74382a248f17da2f19c7f2450c948fe9123e350e 100644 (file)
@@ -131,6 +131,7 @@ int sudoaddable(int, Node*, Addr*);
 void   afunclit(Addr*, Node*);
 void   nodfconst(Node*, Type*, Mpflt*);
 void   gtrack(Sym*);
+void   gargsize(vlong);
 
 /*
  * cplx.c
index 36d9dce4669b2923edd45d30369bc8d956293998..7883dad593d07decfc0e824df5881f693b25302b 100644 (file)
@@ -70,10 +70,24 @@ fixautoused(Prog *p)
 void
 ginscall(Node *f, int proc)
 {
+       int32 arg;
        Prog *p;
        Node reg, con;
        Node r1;
 
+       if(f->type != T)
+               setmaxarg(f->type);
+
+       arg = -1;
+       if(f->type != T && ((f->sym != S && f->sym->pkg == runtimepkg) || proc == 1 || proc == 2)) {
+               arg = f->type->argwid;
+               if(proc == 1 || proc == 2)
+                       arg += 2*widthptr;
+       }
+
+       if(arg != -1)
+               gargsize(arg);
+
        switch(proc) {
        default:
                fatal("ginscall: bad proc %d", proc);
@@ -143,6 +157,9 @@ ginscall(Node *f, int proc)
                }
                break;
        }
+
+       if(arg != -1)
+               gargsize(-1);
 }
 
 /*
@@ -202,14 +219,11 @@ cgen_callinter(Node *n, Node *res, int proc)
                gins(ALEAQ, &nodo, &nodr);      // REG = &(32+offset(REG)) -- i.tab->fun[f]
        }
 
-       // BOTCH nodr.type = fntype;
        nodr.type = n->left->type;
        ginscall(&nodr, proc);
 
        regfree(&nodr);
        regfree(&nodo);
-
-       setmaxarg(n->left->type);
 }
 
 /*
@@ -237,8 +251,6 @@ cgen_call(Node *n, int proc)
        genlist(n->list);               // assign the args
        t = n->left->type;
 
-       setmaxarg(t);
-
        // call tempname pointer
        if(n->left->ullman >= UINF) {
                regalloc(&nod, types[tptr], N);
index c49421544215d497b5253442672a2701f3ae5337..88b1687922b892c275893a4b4c42b924ecb9aee8 100644 (file)
@@ -31,6 +31,7 @@
 #include <u.h>
 #include <libc.h>
 #include "gg.h"
+#include "../../pkg/runtime/funcdata.h"
 
 // TODO(rsc): Can make this bigger if we move
 // the text segment up higher in 6l for all GOOS.
@@ -218,6 +219,16 @@ gtrack(Sym *s)
        p->from.sym = s;
 }
 
+void
+gargsize(vlong size)
+{
+       Node n1, n2;
+       
+       nodconst(&n1, types[TINT32], PCDATA_ArgSize);
+       nodconst(&n2, types[TINT32], size);
+       gins(APCDATA, &n1, &n2);
+}
+
 void
 ggloblsym(Sym *s, int32 width, int dupok, int rodata)
 {
index 5e31159773e53ba63a3910f5996da275fcea7287..6907d7ebb4f370137708e8ede4bcaeaf8bec35bb 100644 (file)
@@ -151,7 +151,7 @@ void        split64(Node*, Node*, Node*);
 void   splitclean(void);
 void   nswap(Node*, Node*);
 void   gtrack(Sym*);
-
+void   gargsize(int32);
 /*
  * cplx.c
  */
index 4dec3c808268f562ade76f11b502347de47f9753..1095d5e441d5911e8d0a1a641130e911f6b56665 100644 (file)
@@ -115,9 +115,23 @@ clearfat(Node *nl)
 void
 ginscall(Node *f, int proc)
 {
+       int32 arg;
        Prog *p;
        Node reg, r1, con;
 
+       if(f->type != T)
+               setmaxarg(f->type);
+
+       arg = -1;
+       if(f->type != T && ((f->sym != S && f->sym->pkg == runtimepkg) || proc == 1 || proc == 2)) {
+               arg = f->type->argwid;
+               if(proc == 1 || proc == 2)
+                       arg += 2*widthptr;
+       }
+
+       if(arg != -1)
+               gargsize(arg);
+
        switch(proc) {
        default:
                fatal("ginscall: bad proc %d", proc);
@@ -177,6 +191,9 @@ ginscall(Node *f, int proc)
                }
                break;
        }
+       
+       if(arg != -1)
+               gargsize(-1);
 }
 
 /*
@@ -237,14 +254,11 @@ cgen_callinter(Node *n, Node *res, int proc)
                gins(ALEAL, &nodo, &nodr);      // REG = &(20+offset(REG)) -- i.tab->fun[f]
        }
 
-       // BOTCH nodr.type = fntype;
        nodr.type = n->left->type;
        ginscall(&nodr, proc);
 
        regfree(&nodr);
        regfree(&nodo);
-
-       setmaxarg(n->left->type);
 }
 
 /*
@@ -272,8 +286,6 @@ cgen_call(Node *n, int proc)
        genlist(n->list);               // assign the args
        t = n->left->type;
 
-       setmaxarg(t);
-
        // call tempname pointer
        if(n->left->ullman >= UINF) {
                regalloc(&nod, types[tptr], N);
index 7ffc77a26810af747a4647cb50949a384719e086..703a0b5c126dbabf38b1e13b254671f90f01fa1f 100644 (file)
@@ -31,6 +31,7 @@
 #include <u.h>
 #include <libc.h>
 #include "gg.h"
+#include "../../pkg/runtime/funcdata.h"
 
 // TODO(rsc): Can make this bigger if we move
 // the text segment up higher in 8l for all GOOS.
@@ -208,6 +209,16 @@ ggloblnod(Node *nam)
                p->from.scale |= NOPTR;
 }
 
+void
+gargsize(int32 size)
+{
+       Node n1, n2;
+       
+       nodconst(&n1, types[TINT32], PCDATA_ArgSize);
+       nodconst(&n2, types[TINT32], size);
+       gins(APCDATA, &n1, &n2);
+}
+
 void
 ggloblsym(Sym *s, int32 width, int dupok, int rodata)
 {