Commit 037a1a9f authored by Carl Shapiro's avatar Carl Shapiro

cmd/ld, runtime: emit pointer maps for nosplits identified by the linker

A nosplits was assumed to have no argument information and no
pointer map.  However, nosplits created by the linker often
have both.  This change uses the pointer map size as an
alternate source of argument size when processing a nosplit.

In addition, the symbol table construction pointer map size
and argument size consistency check is strengthened.  If a
nptrs is greater than 0 it must be equal to the number of
argument words.

R=golang-dev, khr, khr
CC=golang-dev
https://golang.org/cl/9666047
parent 5d081792
......@@ -296,21 +296,15 @@ pointermap(Node *fn)
walktype(inargtype, bv);
if(outargtype != nil)
walktype(outargtype, bv);
if(bvisempty(bv)) {
prog = gins(ANPTRS, N, N);
prog = gins(ANPTRS, N, N);
prog->to.type = D_CONST;
prog->to.offset = bv->n;
for(i = 0; i < bv->n; i += 32) {
prog = gins(APTRS, N, N);
prog->from.type = D_CONST;
prog->from.offset = i / 32;
prog->to.type = D_CONST;
prog->to.offset = 0;
} else {
prog = gins(ANPTRS, N, N);
prog->to.type = D_CONST;
prog->to.offset = bv->n;
for(i = 0; i < bv->n; i += 32) {
prog = gins(APTRS, N, N);
prog->from.type = D_CONST;
prog->from.offset = i / 32;
prog->to.type = D_CONST;
prog->to.offset = bv->b[i / 32];
}
prog->to.offset = bv->b[i / 32];
}
free(bv);
}
......
......@@ -1914,7 +1914,11 @@ genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*))
/* frame, locals, args, auto, param and pointers after */
put(nil, ".frame", 'm', (uint32)s->text->to.offset+PtrSize, 0, 0, 0);
put(nil, ".locals", 'm', s->locals, 0, 0, 0);
if(s->text->textflag & NOSPLIT)
if((s->text->textflag & NOSPLIT) && (s->args == 0) && (s->nptrs < 0))
// This might be a vararg function and have no
// predetermined argument size. This check is
// approximate and will also match 0 argument
// nosplit functions compiled by 6c.
put(nil, ".args", 'm', ArgsSizeUnknown, 0, 0, 0);
else
put(nil, ".args", 'm', s->args, 0, 0, 0);
......
......@@ -234,8 +234,8 @@ dofunc(Sym *sym)
func[nfunc-1].args = sym->value;
else if(runtime·strcmp(sym->name, (byte*)".nptrs") == 0) {
// TODO(cshapiro): use a dense representation for gc information
if(sym->value > func[nfunc-1].args/sizeof(uintptr)) {
runtime·printf("more pointer map entries than argument words\n");
if(sym->value != func[nfunc-1].args/sizeof(uintptr)) {
runtime·printf("pointer map size and argument size disagree\n");
runtime·throw("mangled symbol table");
}
cap = ROUND(sym->value, 32) / 32;
......
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