mirror of
https://github.com/golang/go
synced 2024-11-12 06:30:21 -07:00
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
This commit is contained in:
parent
5d081792b6
commit
037a1a9f31
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user