Commit 7b3c8b7a authored by Russ Cox's avatar Russ Cox

cmd/5g, cmd/6g, cmd/8g: insert arg size annotations on runtime calls

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
parent 4e141145
...@@ -146,6 +146,7 @@ void split64(Node*, Node*, Node*); ...@@ -146,6 +146,7 @@ void split64(Node*, Node*, Node*);
void splitclean(void); void splitclean(void);
Node* ncon(uint32 i); Node* ncon(uint32 i);
void gtrack(Sym*); void gtrack(Sym*);
void gargsize(int32);
/* /*
* obj.c * obj.c
......
...@@ -73,9 +73,23 @@ fixautoused(Prog* p) ...@@ -73,9 +73,23 @@ fixautoused(Prog* p)
void void
ginscall(Node *f, int proc) ginscall(Node *f, int proc)
{ {
int32 arg;
Prog *p; Prog *p;
Node n1, r, r1, con; 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) { switch(proc) {
default: default:
fatal("ginscall: bad proc %d", proc); fatal("ginscall: bad proc %d", proc);
...@@ -170,6 +184,9 @@ ginscall(Node *f, int proc) ...@@ -170,6 +184,9 @@ ginscall(Node *f, int proc)
} }
break; break;
} }
if(arg != -1)
gargsize(-1);
} }
/* /*
...@@ -239,14 +256,11 @@ cgen_callinter(Node *n, Node *res, int proc) ...@@ -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] p->from.type = D_CONST; // REG = &(20+offset(REG)) -- i.tab->fun[f]
} }
// BOTCH nodr.type = fntype;
nodr.type = n->left->type; nodr.type = n->left->type;
ginscall(&nodr, proc); ginscall(&nodr, proc);
regfree(&nodr); regfree(&nodr);
regfree(&nodo); regfree(&nodo);
setmaxarg(n->left->type);
} }
/* /*
...@@ -274,8 +288,6 @@ cgen_call(Node *n, int proc) ...@@ -274,8 +288,6 @@ cgen_call(Node *n, int proc)
genlist(n->list); // assign the args genlist(n->list); // assign the args
t = n->left->type; t = n->left->type;
setmaxarg(t);
// call tempname pointer // call tempname pointer
if(n->left->ullman >= UINF) { if(n->left->ullman >= UINF) {
regalloc(&nod, types[tptr], N); regalloc(&nod, types[tptr], N);
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <u.h> #include <u.h>
#include <libc.h> #include <libc.h>
#include "gg.h" #include "gg.h"
#include "../../pkg/runtime/funcdata.h"
// TODO(rsc): Can make this bigger if we move // TODO(rsc): Can make this bigger if we move
// the text segment up higher in 5l for all GOOS. // the text segment up higher in 5l for all GOOS.
...@@ -209,6 +210,16 @@ ggloblnod(Node *nam) ...@@ -209,6 +210,16 @@ ggloblnod(Node *nam)
p->reg |= NOPTR; 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 void
ggloblsym(Sym *s, int32 width, int dupok, int rodata) ggloblsym(Sym *s, int32 width, int dupok, int rodata)
{ {
......
...@@ -1199,6 +1199,7 @@ copyu(Prog *p, Adr *v, Adr *s) ...@@ -1199,6 +1199,7 @@ copyu(Prog *p, Adr *v, Adr *s)
case ALOCALS: /* funny */ case ALOCALS: /* funny */
case ANPTRS: case ANPTRS:
case APTRS: case APTRS:
case APCDATA:
return 0; return 0;
} }
} }
......
...@@ -131,6 +131,7 @@ int sudoaddable(int, Node*, Addr*); ...@@ -131,6 +131,7 @@ int sudoaddable(int, Node*, Addr*);
void afunclit(Addr*, Node*); void afunclit(Addr*, Node*);
void nodfconst(Node*, Type*, Mpflt*); void nodfconst(Node*, Type*, Mpflt*);
void gtrack(Sym*); void gtrack(Sym*);
void gargsize(vlong);
/* /*
* cplx.c * cplx.c
......
...@@ -70,10 +70,24 @@ fixautoused(Prog *p) ...@@ -70,10 +70,24 @@ fixautoused(Prog *p)
void void
ginscall(Node *f, int proc) ginscall(Node *f, int proc)
{ {
int32 arg;
Prog *p; Prog *p;
Node reg, con; Node reg, con;
Node r1; 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) { switch(proc) {
default: default:
fatal("ginscall: bad proc %d", proc); fatal("ginscall: bad proc %d", proc);
...@@ -143,6 +157,9 @@ ginscall(Node *f, int proc) ...@@ -143,6 +157,9 @@ ginscall(Node *f, int proc)
} }
break; break;
} }
if(arg != -1)
gargsize(-1);
} }
/* /*
...@@ -202,14 +219,11 @@ cgen_callinter(Node *n, Node *res, int proc) ...@@ -202,14 +219,11 @@ cgen_callinter(Node *n, Node *res, int proc)
gins(ALEAQ, &nodo, &nodr); // REG = &(32+offset(REG)) -- i.tab->fun[f] gins(ALEAQ, &nodo, &nodr); // REG = &(32+offset(REG)) -- i.tab->fun[f]
} }
// BOTCH nodr.type = fntype;
nodr.type = n->left->type; nodr.type = n->left->type;
ginscall(&nodr, proc); ginscall(&nodr, proc);
regfree(&nodr); regfree(&nodr);
regfree(&nodo); regfree(&nodo);
setmaxarg(n->left->type);
} }
/* /*
...@@ -237,8 +251,6 @@ cgen_call(Node *n, int proc) ...@@ -237,8 +251,6 @@ cgen_call(Node *n, int proc)
genlist(n->list); // assign the args genlist(n->list); // assign the args
t = n->left->type; t = n->left->type;
setmaxarg(t);
// call tempname pointer // call tempname pointer
if(n->left->ullman >= UINF) { if(n->left->ullman >= UINF) {
regalloc(&nod, types[tptr], N); regalloc(&nod, types[tptr], N);
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <u.h> #include <u.h>
#include <libc.h> #include <libc.h>
#include "gg.h" #include "gg.h"
#include "../../pkg/runtime/funcdata.h"
// TODO(rsc): Can make this bigger if we move // TODO(rsc): Can make this bigger if we move
// the text segment up higher in 6l for all GOOS. // the text segment up higher in 6l for all GOOS.
...@@ -218,6 +219,16 @@ gtrack(Sym *s) ...@@ -218,6 +219,16 @@ gtrack(Sym *s)
p->from.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 void
ggloblsym(Sym *s, int32 width, int dupok, int rodata) ggloblsym(Sym *s, int32 width, int dupok, int rodata)
{ {
......
...@@ -151,7 +151,7 @@ void split64(Node*, Node*, Node*); ...@@ -151,7 +151,7 @@ void split64(Node*, Node*, Node*);
void splitclean(void); void splitclean(void);
void nswap(Node*, Node*); void nswap(Node*, Node*);
void gtrack(Sym*); void gtrack(Sym*);
void gargsize(int32);
/* /*
* cplx.c * cplx.c
*/ */
......
...@@ -115,9 +115,23 @@ clearfat(Node *nl) ...@@ -115,9 +115,23 @@ clearfat(Node *nl)
void void
ginscall(Node *f, int proc) ginscall(Node *f, int proc)
{ {
int32 arg;
Prog *p; Prog *p;
Node reg, r1, con; 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) { switch(proc) {
default: default:
fatal("ginscall: bad proc %d", proc); fatal("ginscall: bad proc %d", proc);
...@@ -177,6 +191,9 @@ ginscall(Node *f, int proc) ...@@ -177,6 +191,9 @@ ginscall(Node *f, int proc)
} }
break; break;
} }
if(arg != -1)
gargsize(-1);
} }
/* /*
...@@ -237,14 +254,11 @@ cgen_callinter(Node *n, Node *res, int proc) ...@@ -237,14 +254,11 @@ cgen_callinter(Node *n, Node *res, int proc)
gins(ALEAL, &nodo, &nodr); // REG = &(20+offset(REG)) -- i.tab->fun[f] gins(ALEAL, &nodo, &nodr); // REG = &(20+offset(REG)) -- i.tab->fun[f]
} }
// BOTCH nodr.type = fntype;
nodr.type = n->left->type; nodr.type = n->left->type;
ginscall(&nodr, proc); ginscall(&nodr, proc);
regfree(&nodr); regfree(&nodr);
regfree(&nodo); regfree(&nodo);
setmaxarg(n->left->type);
} }
/* /*
...@@ -272,8 +286,6 @@ cgen_call(Node *n, int proc) ...@@ -272,8 +286,6 @@ cgen_call(Node *n, int proc)
genlist(n->list); // assign the args genlist(n->list); // assign the args
t = n->left->type; t = n->left->type;
setmaxarg(t);
// call tempname pointer // call tempname pointer
if(n->left->ullman >= UINF) { if(n->left->ullman >= UINF) {
regalloc(&nod, types[tptr], N); regalloc(&nod, types[tptr], N);
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <u.h> #include <u.h>
#include <libc.h> #include <libc.h>
#include "gg.h" #include "gg.h"
#include "../../pkg/runtime/funcdata.h"
// TODO(rsc): Can make this bigger if we move // TODO(rsc): Can make this bigger if we move
// the text segment up higher in 8l for all GOOS. // the text segment up higher in 8l for all GOOS.
...@@ -208,6 +209,16 @@ ggloblnod(Node *nam) ...@@ -208,6 +209,16 @@ ggloblnod(Node *nam)
p->from.scale |= NOPTR; 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 void
ggloblsym(Sym *s, int32 width, int dupok, int rodata) ggloblsym(Sym *s, int32 width, int dupok, int rodata)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment