Commit f466617a authored by Carl Shapiro's avatar Carl Shapiro

cmd/5g, cmd/5l, cmd/6l, cmd/8l, cmd/gc, cmd/ld, runtime: accurate args and locals information

Previously, the func structure contained an inaccurate value for
the args member and a 0 value for the locals member.

This change populates the func structure with args and locals
values computed by the compiler.  The number of args was
already available in the ATEXT instruction.  The number of
locals is now passed through in the new ALOCALS instruction.

This change also switches the unit of args and locals to be
bytes, just like the frame member, instead of 32-bit words.

R=golang-dev, bradfitz, cshapiro, dave, rsc
CC=golang-dev
https://golang.org/cl/7399045
parent fb21bca0
......@@ -1189,6 +1189,9 @@ copyu(Prog *p, Adr *v, Adr *s)
if(v->reg == (uchar)REGARG)
return 3;
return 0;
case ALOCALS: /* funny */
return 0;
}
}
......
......@@ -197,6 +197,7 @@ enum as
AMULAWB,
AUSEFIELD,
ALOCALS,
ALAST,
};
......
......@@ -147,6 +147,8 @@ struct Sym
int32 size;
int32 align; // if non-zero, required alignment in bytes
int32 elfsym;
int32 locals; // size of stack frame locals area
int32 args; // size of stack frame incoming arguments area
uchar special;
uchar fnptr; // used as fn ptr
uchar stkcheck;
......
......@@ -573,6 +573,11 @@ loop:
pc++;
break;
case ALOCALS:
cursym->locals = p->to.offset;
pc++;
break;
case ATEXT:
if(cursym != nil && cursym->text) {
histtoauto();
......@@ -610,6 +615,7 @@ loop:
s->type = STEXT;
s->text = p;
s->value = pc;
s->args = p->to.offset2;
lastp = p;
p->pc = pc;
pc++;
......
......@@ -830,6 +830,7 @@ buildop(void)
case ARFE:
case ATEXT:
case AUSEFIELD:
case ALOCALS:
case ACASE:
case ABCASE:
break;
......
......@@ -758,6 +758,7 @@ enum as
APSHUFD,
AUSEFIELD,
ALOCALS,
ALAST
};
......
......@@ -154,6 +154,8 @@ struct Sym
int32 got;
int32 align; // if non-zero, required alignment in bytes
int32 elfsym;
int32 locals; // size of stack frame locals area
int32 args; // size of stack frame incoming arguments area
Sym* hash; // in hash table
Sym* allsym; // in all symbol list
Sym* next; // in text or data list
......
......@@ -586,6 +586,11 @@ loop:
pc++;
goto loop;
case ALOCALS:
cursym->locals = p->to.offset;
pc++;
goto loop;
case ATEXT:
s = p->from.sym;
if(s->text != nil) {
......@@ -629,6 +634,7 @@ loop:
}
s->type = STEXT;
s->value = pc;
s->args = p->to.offset >> 32;
lastp = p;
p->pc = pc++;
goto loop;
......
......@@ -1316,6 +1316,7 @@ Optab optab[] =
{ APSHUFD, yaes2, Pq, 0x70,(0) },
{ AUSEFIELD, ynop, Px, 0,0 },
{ ALOCALS },
{ AEND },
0
......
......@@ -568,6 +568,7 @@ enum as
AXORPS,
AUSEFIELD,
ALOCALS,
ALAST
};
......
......@@ -138,6 +138,8 @@ struct Sym
int32 got;
int32 align; // if non-zero, required alignment in bytes
int32 elfsym;
int32 locals; // size of stack frame locals area
int32 args; // size of stack frame incoming arguments area
Sym* hash; // in hash table
Sym* allsym; // in all symbol list
Sym* next; // in text or data list
......
......@@ -595,6 +595,11 @@ loop:
pc++;
goto loop;
case ALOCALS:
cursym->locals = p->to.offset;
pc++;
goto loop;
case ATEXT:
s = p->from.sym;
if(s->text != nil) {
......@@ -633,6 +638,7 @@ loop:
}
s->type = STEXT;
s->value = pc;
s->args = p->to.offset2;
lastp = p;
p->pc = pc++;
goto loop;
......
......@@ -961,6 +961,7 @@ Optab optab[] =
{ AXORPS, yxm, Pm, 0x57 },
{ AUSEFIELD, ynop, Px, 0,0 },
{ ALOCALS },
0
};
......@@ -14,7 +14,7 @@ compile(Node *fn)
{
Plist *pl;
Node nod1, *n;
Prog *ptxt;
Prog *plocals, *ptxt;
int32 lno;
Type *t;
Iter save;
......@@ -87,6 +87,8 @@ compile(Node *fn)
ginit();
plocals = gins(ALOCALS, N, N);
for(t=curfn->paramfld; t; t=t->down)
gtrack(tracksym(t->type));
......@@ -132,6 +134,9 @@ compile(Node *fn)
oldstksize = stksize;
allocauto(ptxt);
plocals->to.offset = stksize;
if(0)
print("allocauto: %lld to %lld\n", oldstksize, (vlong)stksize);
......
......@@ -1626,8 +1626,10 @@ genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*))
put(s, s->name, 'T', s->value, s->size, s->version, s->gotype);
/* frame, auto and param after */
/* frame, locals, args, auto and param after */
put(nil, ".frame", 'm', s->text->to.offset+PtrSize, 0, 0, 0);
put(nil, ".locals", 'm', s->locals, 0, 0, 0);
put(nil, ".args", 'm', s->args, 0, 0, 0);
for(a=s->autom; a; a=a->link)
if(a->type == D_AUTO)
......
......@@ -42,8 +42,8 @@ type Func struct { // Keep in sync with runtime.h:struct Func
pc0 uintptr // starting pc, ln for table
ln0 int32
frame int32 // stack frame size
args int32 // number of 32-bit in/out args
locals int32 // number of 32-bit locals
args int32 // in/out args size
locals int32 // locals size
}
// FuncForPC returns a *Func describing the function that contains the
......
......@@ -353,8 +353,8 @@ struct Func
uintptr pc0; // starting pc, ln for table
int32 ln0;
int32 frame; // stack frame size
int32 args; // number of 32-bit in/out args
int32 locals; // number of 32-bit locals
int32 args; // in/out args size
int32 locals; // locals size
};
// layout of Itab known to compilers
......
......@@ -124,17 +124,17 @@ dofunc(Sym *sym)
f->frame = -sizeof(uintptr);
break;
case 'm':
if(nfunc > 0 && func != nil)
func[nfunc-1].frame += sym->value;
if(nfunc <= 0 || func == nil)
break;
case 'p':
if(nfunc > 0 && func != nil) {
f = &func[nfunc-1];
// args counts 32-bit words.
// sym->value is the arg's offset.
// don't know width of this arg, so assume it is 64 bits.
if(f->args < sym->value/4 + 2)
f->args = sym->value/4 + 2;
if(runtime·strcmp(sym->name, (byte*)".frame") == 0)
func[nfunc-1].frame = sym->value;
else if(runtime·strcmp(sym->name, (byte*)".locals") == 0)
func[nfunc-1].locals = sym->value;
else if(runtime·strcmp(sym->name, (byte*)".args") == 0)
func[nfunc-1].args = sym->value;
else {
runtime·printf("invalid 'm' symbol named '%s'\n", sym->name);
runtime·throw("mangled symbol table");
}
break;
case 'f':
......
......@@ -128,7 +128,7 @@ runtime·gentraceback(byte *pc0, byte *sp, byte *lr0, G *gp, int32 skip, uintptr
if(m->throwing && gp == m->curg)
runtime·printf("[fp=%p] ", fp);
runtime·printf("%S(", f->name);
for(i = 0; i < f->args; i++) {
for(i = 0; i < f->args/sizeof(uintptr); i++) {
if(i != 0)
runtime·prints(", ");
runtime·printhex(((uintptr*)fp)[1+i]);
......
......@@ -130,7 +130,7 @@ runtime·gentraceback(byte *pc0, byte *sp, byte *lr0, G *gp, int32 skip, uintptr
if(m->throwing && gp == m->curg)
runtime·printf("[fp=%p] ", fp);
runtime·printf("%S(", f->name);
for(i = 0; i < f->args; i++) {
for(i = 0; i < f->args/sizeof(uintptr); i++) {
if(i != 0)
runtime·prints(", ");
runtime·printhex(((uintptr*)fp)[i]);
......
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