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
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);
}
/* 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);
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;