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*);
void splitclean(void);
Node* ncon(uint32 i);
void gtrack(Sym*);
void gargsize(int32);
/*
* obj.c
......
......@@ -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);
......
......@@ -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)
{
......
......@@ -1199,6 +1199,7 @@ copyu(Prog *p, Adr *v, Adr *s)
case ALOCALS: /* funny */
case ANPTRS:
case APTRS:
case APCDATA:
return 0;
}
}
......
......@@ -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
......
......@@ -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);
......
......@@ -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)
{
......
......@@ -151,7 +151,7 @@ void split64(Node*, Node*, Node*);
void splitclean(void);
void nswap(Node*, Node*);
void gtrack(Sym*);
void gargsize(int32);
/*
* cplx.c
*/
......
......@@ -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);
......
......@@ -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)
{
......
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